Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/RenderSystems/GL/src/OgreGLHardwareBufferManager.cpp @ 3

Last change on this file since 3 was 3, checked in by anonymous, 17 years ago

=update

File size: 7.7 KB
Line 
1/*
2-----------------------------------------------------------------------------
3This source file is part of OGRE
4    (Object-oriented Graphics Rendering Engine)
5For the latest info, see http://www.ogre3d.org/
6
7Copyright (c) 2000-2006 Torus Knot Software Ltd
8Also see acknowledgements in Readme.html
9
10This program is free software; you can redistribute it and/or modify it under
11the terms of the GNU Lesser General Public License as published by the Free Software
12Foundation; either version 2 of the License, or (at your option) any later
13version.
14
15This program is distributed in the hope that it will be useful, but WITHOUT
16ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
18
19You should have received a copy of the GNU Lesser General Public License along with
20this program; if not, write to the Free Software Foundation, Inc., 59 Temple
21Place - Suite 330, Boston, MA 02111-1307, USA, or go to
22http://www.gnu.org/copyleft/lesser.txt.
23
24You may alternatively use this source under the terms of a specific version of
25the OGRE Unrestricted License provided you have obtained such a license from
26Torus Knot Software Ltd.
27-----------------------------------------------------------------------------
28*/
29#include "OgreGLHardwareBufferManager.h"
30#include "OgreGLHardwareVertexBuffer.h"
31#include "OgreGLHardwareIndexBuffer.h"
32#include "OgreHardwareBuffer.h"
33#include "OgreAlignedAllocator.h"
34
35namespace Ogre {
36    //-----------------------------------------------------------------------
37        // Scratch pool management (32 bit structure)
38        struct GLScratchBufferAlloc
39        {
40                /// Size in bytes
41                uint32 size: 31;
42                /// Free? (pack with size)
43                uint32 free: 1;
44        };
45        #define SCRATCH_POOL_SIZE 1 * 1024 * 1024
46        //---------------------------------------------------------------------
47    GLHardwareBufferManager::GLHardwareBufferManager()
48    {
49                // Init scratch pool
50                // TODO make it a configurable size?
51                // 32-bit aligned buffer
52                mScratchBufferPool = static_cast<char*>(AlignedMemory::allocate(SCRATCH_POOL_SIZE, 32));
53                GLScratchBufferAlloc* ptrAlloc = (GLScratchBufferAlloc*)mScratchBufferPool;
54                ptrAlloc->size = SCRATCH_POOL_SIZE - sizeof(GLScratchBufferAlloc);
55                ptrAlloc->free = 1;
56    }
57    //-----------------------------------------------------------------------
58    GLHardwareBufferManager::~GLHardwareBufferManager()
59    {
60        destroyAllDeclarations();
61        destroyAllBindings();
62
63                AlignedMemory::deallocate(mScratchBufferPool);
64    }
65    //-----------------------------------------------------------------------
66    HardwareVertexBufferSharedPtr GLHardwareBufferManager::createVertexBuffer(
67        size_t vertexSize, size_t numVerts, HardwareBuffer::Usage usage, bool useShadowBuffer)
68    {
69                GLHardwareVertexBuffer* buf = 
70                        new GLHardwareVertexBuffer(vertexSize, numVerts, usage, useShadowBuffer);
71                {
72                        OGRE_LOCK_MUTEX(mVertexBuffersMutex)
73                        mVertexBuffers.insert(buf);
74                }
75                return HardwareVertexBufferSharedPtr(buf);
76    }
77    //-----------------------------------------------------------------------
78    HardwareIndexBufferSharedPtr
79    GLHardwareBufferManager::createIndexBuffer(
80        HardwareIndexBuffer::IndexType itype, size_t numIndexes, 
81        HardwareBuffer::Usage usage, bool useShadowBuffer)
82    {
83                GLHardwareIndexBuffer* buf = 
84                        new GLHardwareIndexBuffer(itype, numIndexes, usage, useShadowBuffer);
85                {
86                        OGRE_LOCK_MUTEX(mIndexBuffersMutex)
87                        mIndexBuffers.insert(buf);
88                }
89                return HardwareIndexBufferSharedPtr(buf);
90    }
91    //---------------------------------------------------------------------
92    GLenum GLHardwareBufferManager::getGLUsage(unsigned int usage)
93    {
94        switch(usage)
95        {
96        case HardwareBuffer::HBU_STATIC:
97        case HardwareBuffer::HBU_STATIC_WRITE_ONLY:
98            return GL_STATIC_DRAW_ARB;
99        case HardwareBuffer::HBU_DYNAMIC:
100        case HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY:
101            return GL_DYNAMIC_DRAW_ARB;
102        case HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY_DISCARDABLE:
103            return GL_STREAM_DRAW_ARB;
104        default:
105            return GL_DYNAMIC_DRAW_ARB;
106        };
107    }
108    //---------------------------------------------------------------------
109    GLenum GLHardwareBufferManager::getGLType(unsigned int type)
110    {
111        switch(type)
112        {
113            case VET_FLOAT1:
114            case VET_FLOAT2:
115            case VET_FLOAT3:
116            case VET_FLOAT4:
117                return GL_FLOAT;
118            case VET_SHORT1:
119            case VET_SHORT2:
120            case VET_SHORT3:
121            case VET_SHORT4:
122                return GL_SHORT;
123            case VET_COLOUR:
124                        case VET_COLOUR_ABGR:
125                        case VET_COLOUR_ARGB:
126            case VET_UBYTE4:
127                return GL_UNSIGNED_BYTE;
128            default:
129                return 0;
130        };
131    }
132        //---------------------------------------------------------------------
133        //---------------------------------------------------------------------
134        void* GLHardwareBufferManager::allocateScratch(uint32 size)
135        {
136                // simple forward link search based on alloc sizes
137                // not that fast but the list should never get that long since not many
138                // locks at once (hopefully)
139                OGRE_LOCK_MUTEX(mScratchMutex)
140
141
142                // Alignment - round up the size to 32 bits
143                // control blocks are 32 bits too so this packs nicely
144                if (size % 4 != 0)
145                {
146                        size += 4 - (size % 4);
147                }
148
149                uint32 bufferPos = 0;
150                while (bufferPos < SCRATCH_POOL_SIZE)
151                {
152                        GLScratchBufferAlloc* pNext = (GLScratchBufferAlloc*)(mScratchBufferPool + bufferPos);
153                        // Big enough?
154                        if (pNext->free && pNext->size >= size)
155                        {
156                                // split? And enough space for control block
157                                if(pNext->size > size + sizeof(GLScratchBufferAlloc))
158                                {
159                                        uint32 offset = sizeof(GLScratchBufferAlloc) + size;
160
161                                        GLScratchBufferAlloc* pSplitAlloc = (GLScratchBufferAlloc*)
162                                                (mScratchBufferPool + bufferPos + offset);
163                                        pSplitAlloc->free = 1;
164                                        // split size is remainder minus new control block
165                                        pSplitAlloc->size = pNext->size - size - sizeof(GLScratchBufferAlloc);
166
167                                        // New size of current
168                                        pNext->size = size;
169                                }
170                                // allocate and return
171                                pNext->free = 0;
172
173                                // return pointer just after this control block (++ will do that for us)
174                                return ++pNext;
175
176                        }
177
178                        bufferPos += sizeof(GLScratchBufferAlloc) + pNext->size;
179
180                }
181
182                // no available alloc
183                return 0;
184
185        }
186        //---------------------------------------------------------------------
187        void GLHardwareBufferManager::deallocateScratch(void* ptr)
188        {
189                OGRE_LOCK_MUTEX(mScratchMutex)
190
191                // Simple linear search dealloc
192                uint32 bufferPos = 0;
193                GLScratchBufferAlloc* pLast = 0;
194                while (bufferPos < SCRATCH_POOL_SIZE)
195                {
196                        GLScratchBufferAlloc* pCurrent = (GLScratchBufferAlloc*)(mScratchBufferPool + bufferPos);
197                       
198                        // Pointers match?
199                        if ((mScratchBufferPool + bufferPos + sizeof(GLScratchBufferAlloc))
200                                == ptr)
201                        {
202                                // dealloc
203                                pCurrent->free = 1;
204                               
205                                // merge with previous
206                                if (pLast && pLast->free)
207                                {
208                                        // adjust buffer pos
209                                        bufferPos -= (pLast->size + sizeof(GLScratchBufferAlloc));
210                                        // merge free space
211                                        pLast->size += pCurrent->size + sizeof(GLScratchBufferAlloc);
212                                        pCurrent = pLast;
213                                }
214
215                                // merge with next
216                                uint32 offset = bufferPos + pCurrent->size + sizeof(GLScratchBufferAlloc);
217                                if (offset < SCRATCH_POOL_SIZE)
218                                {
219                                        GLScratchBufferAlloc* pNext = (GLScratchBufferAlloc*)(
220                                                mScratchBufferPool + offset);
221                                        if (pNext->free)
222                                        {
223                                                pCurrent->size += pNext->size + sizeof(GLScratchBufferAlloc);
224                                        }
225                                }
226
227                                // done
228                                return;
229                        }
230
231                        bufferPos += sizeof(GLScratchBufferAlloc) + pCurrent->size;
232                        pLast = pCurrent;
233
234                }
235
236                // Should never get here unless there's a corruption
237                assert (false && "Memory deallocation error");
238
239
240        }
241}
Note: See TracBrowser for help on using the repository browser.