source: OGRE/trunk/ogrenew/OgreMain/src/OgreHardwareBufferManager.cpp @ 657

Revision 657, 14.3 KB checked in by mattausch, 18 years ago (diff)

added ogre dependencies and patched ogre sources

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-2005 The OGRE Team
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-----------------------------------------------------------------------------
24*/
25#include "OgreStableHeaders.h"
26#include "OgreHardwareBufferManager.h"
27#include "OgreVertexIndexData.h"
28
29
30namespace Ogre {
31
32    //-----------------------------------------------------------------------
33    template<> HardwareBufferManager* Singleton<HardwareBufferManager>::ms_Singleton = 0;
34    HardwareBufferManager* HardwareBufferManager::getSingletonPtr(void)
35    {
36        return ms_Singleton;
37    }
38    HardwareBufferManager& HardwareBufferManager::getSingleton(void)
39    { 
40        assert( ms_Singleton );  return ( *ms_Singleton ); 
41    }
42    //-----------------------------------------------------------------------
43    HardwareBufferManager::HardwareBufferManager()
44    {
45    }
46    //-----------------------------------------------------------------------
47    HardwareBufferManager::~HardwareBufferManager()
48    {
49        // Destroy everything
50        destroyAllDeclarations();
51        destroyAllBindings();
52        // No need to destroy main buffers - they will be destroyed by removal of bindings
53
54        // Destroy temp buffers
55        FreeTemporaryVertexBufferMap::iterator i, iend;
56        iend = mFreeTempVertexBufferMap.end();
57        for (i = mFreeTempVertexBufferMap.begin(); i != iend; ++i)
58        {
59            delete i->second;
60        }
61    }
62    //-----------------------------------------------------------------------
63    VertexDeclaration* HardwareBufferManager::createVertexDeclaration(void)
64    {
65        VertexDeclaration* decl = new VertexDeclaration();
66        mVertexDeclarations.push_back(decl);
67        return decl;
68       
69    }
70    //-----------------------------------------------------------------------
71    void HardwareBufferManager::destroyVertexDeclaration(VertexDeclaration* decl)
72    {
73        mVertexDeclarations.remove(decl);
74        delete decl;
75    }
76    //-----------------------------------------------------------------------
77        VertexBufferBinding* HardwareBufferManager::createVertexBufferBinding(void)
78        {
79                VertexBufferBinding* ret = new VertexBufferBinding();
80                mVertexBufferBindings.push_back(ret);
81                return ret;
82        }
83    //-----------------------------------------------------------------------
84        void HardwareBufferManager::destroyVertexBufferBinding(VertexBufferBinding* binding)
85        {
86                mVertexBufferBindings.remove(binding);
87                delete binding;
88        }
89    //-----------------------------------------------------------------------
90    void HardwareBufferManager::destroyAllDeclarations(void)
91    {
92        VertexDeclarationList::iterator decl;
93        for (decl = mVertexDeclarations.begin(); decl != mVertexDeclarations.end(); ++decl)
94        {
95            delete *decl;
96        }
97        mVertexDeclarations.clear();
98
99    }
100    //-----------------------------------------------------------------------
101    void HardwareBufferManager::destroyAllBindings(void)
102    {
103        VertexBufferBindingList::iterator bind;
104        for (bind = mVertexBufferBindings.begin(); bind != mVertexBufferBindings.end(); ++bind)
105        {
106            delete *bind;
107        }
108        mVertexBufferBindings.clear();
109    }
110        //-----------------------------------------------------------------------
111    void HardwareBufferManager::registerVertexBufferSourceAndCopy(
112                        const HardwareVertexBufferSharedPtr& sourceBuffer,
113                        const HardwareVertexBufferSharedPtr& copy)
114        {
115        // Locate source buffer copy in free list
116        FreeTemporaryVertexBufferMap::iterator vbmi =
117            mFreeTempVertexBufferMap.find(sourceBuffer.getPointer());
118
119        if (vbmi == mFreeTempVertexBufferMap.end())
120        {
121            // Add new entry
122            FreeTemporaryVertexBufferList *newList = new FreeTemporaryVertexBufferList();
123            std::pair<FreeTemporaryVertexBufferMap::iterator, bool> retPair =
124                mFreeTempVertexBufferMap.insert(
125                    FreeTemporaryVertexBufferMap::value_type(
126                        sourceBuffer.getPointer(), newList));
127            assert(retPair.second && "Error inserting buffer list");
128            vbmi = retPair.first;
129        }
130
131                // Add copy to free list
132                vbmi->second->push_back(copy);
133        }
134        //-----------------------------------------------------------------------
135    HardwareVertexBufferSharedPtr
136    HardwareBufferManager::allocateVertexBufferCopy(
137        const HardwareVertexBufferSharedPtr& sourceBuffer,
138        BufferLicenseType licenseType, HardwareBufferLicensee* licensee,
139        bool copyData)
140    {
141        // Locate existing buffer copy in free list
142        FreeTemporaryVertexBufferMap::iterator vbmi =
143            mFreeTempVertexBufferMap.find(sourceBuffer.getPointer());
144
145        if (vbmi == mFreeTempVertexBufferMap.end())
146        {
147            // Add new entry
148            FreeTemporaryVertexBufferList *newList = new FreeTemporaryVertexBufferList();
149            std::pair<FreeTemporaryVertexBufferMap::iterator, bool> retPair =
150                mFreeTempVertexBufferMap.insert(
151                    FreeTemporaryVertexBufferMap::value_type(
152                        sourceBuffer.getPointer(), newList));
153            assert(retPair.second && "Error inserting buffer list");
154            vbmi = retPair.first;
155        }
156
157        HardwareVertexBufferSharedPtr vbuf;
158        // Are there any free buffers?
159        if (vbmi->second->empty())
160        {
161            // copy buffer, use shadow buffer and make dynamic
162            vbuf = makeBufferCopy(
163                sourceBuffer,
164                HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY_DISCARDABLE,
165                true);
166        }
167        else
168        {
169            // Allocate existing copy
170            vbuf = vbmi->second->back();
171            vbmi->second->pop_back();
172        }
173
174        // Copy data?
175        if (copyData)
176        {
177            vbuf->copyData(*(sourceBuffer.get()), 0, 0, sourceBuffer->getSizeInBytes(), true);
178        }
179        // Insert copy into licensee list
180        mTempVertexBufferLicenses.push_back(
181            VertexBufferLicense(sourceBuffer.getPointer(), licenseType, vbuf, licensee));
182
183        return vbuf;
184    }
185    //-----------------------------------------------------------------------
186    void HardwareBufferManager::releaseVertexBufferCopy(
187        const HardwareVertexBufferSharedPtr& bufferCopy)
188    {
189        TemporaryVertexBufferLicenseList::iterator i, iend;
190        iend = mTempVertexBufferLicenses.end();
191        for (i = mTempVertexBufferLicenses.begin(); i != iend; ++i)
192        {
193            const VertexBufferLicense& vbl = *i;
194            if (vbl.buffer.getPointer() == bufferCopy.getPointer())
195            {
196
197                FreeTemporaryVertexBufferMap::iterator vbi =
198                    mFreeTempVertexBufferMap.find(vbl.originalBufferPtr);
199                assert (vbi != mFreeTempVertexBufferMap.end());
200                                vbl.licensee->licenseExpired(vbl.buffer.get());
201
202                vbi->second->push_back(vbl.buffer);
203                mTempVertexBufferLicenses.erase(i);
204                break;
205
206            }
207        }
208
209    }
210    //-----------------------------------------------------------------------
211    void HardwareBufferManager::_releaseBufferCopies(void)
212    {
213        TemporaryVertexBufferLicenseList::iterator i;
214        i = mTempVertexBufferLicenses.begin();
215
216        while (i != mTempVertexBufferLicenses.end())
217        {
218
219            const VertexBufferLicense& vbl = *i;
220            if (vbl.licenseType == BLT_AUTOMATIC_RELEASE)
221            {
222
223                FreeTemporaryVertexBufferMap::iterator vbi =
224                    mFreeTempVertexBufferMap.find(vbl.originalBufferPtr);
225                assert (vbi != mFreeTempVertexBufferMap.end());
226                                vbl.licensee->licenseExpired(vbl.buffer.get());
227
228                vbi->second->push_back(vbl.buffer);
229                i = mTempVertexBufferLicenses.erase(i);
230
231            }
232            else
233            {
234                ++i;
235            }
236        }
237    }
238    //-----------------------------------------------------------------------
239    void HardwareBufferManager::_forceReleaseBufferCopies(
240        HardwareVertexBuffer* sourceBuffer)
241    {
242        TemporaryVertexBufferLicenseList::iterator i;
243        i = mTempVertexBufferLicenses.begin();
244   
245        // Erase the copies which are licensed out
246        while (i != mTempVertexBufferLicenses.end())
247        {
248            const VertexBufferLicense& vbl = *i;
249            if (vbl.originalBufferPtr == sourceBuffer)
250            {
251                // Just tell the owner that this is being released
252                vbl.licensee->licenseExpired(vbl.buffer.get());
253                i = mTempVertexBufferLicenses.erase(i);
254            }
255            else
256            {
257                ++i;
258            }
259        }
260        // Erase the free copies
261        // locate the source buffer entry in the FreeTemporaryVertexBufferMap
262        // if there is an entry for this source buffer there will only be one
263        FreeTemporaryVertexBufferMap::iterator fi =
264            mFreeTempVertexBufferMap.find(sourceBuffer);
265        if (fi != mFreeTempVertexBufferMap.end())
266        {
267            // an entry was found so delete it
268            delete fi->second;
269            mFreeTempVertexBufferMap.erase(fi);
270        }
271    }
272        //-----------------------------------------------------------------------
273        void HardwareBufferManager::_notifyVertexBufferDestroyed(HardwareVertexBuffer* buf)
274        {
275                VertexBufferList::iterator i = mVertexBuffers.find(buf);
276                if (i != mVertexBuffers.end())
277                {
278            // release vertex buffer copies
279                        mVertexBuffers.erase(i);
280            _forceReleaseBufferCopies(buf);
281                }
282        }
283        //-----------------------------------------------------------------------
284        void HardwareBufferManager::_notifyIndexBufferDestroyed(HardwareIndexBuffer* buf)
285        {
286                IndexBufferList::iterator i = mIndexBuffers.find(buf);
287                if (i != mIndexBuffers.end())
288                {
289                        mIndexBuffers.erase(i);
290                }
291        }
292    //-----------------------------------------------------------------------
293    HardwareVertexBufferSharedPtr
294    HardwareBufferManager::makeBufferCopy(
295        const HardwareVertexBufferSharedPtr& source,
296        HardwareBuffer::Usage usage, bool useShadowBuffer)
297    {
298        return this->createVertexBuffer(
299            source->getVertexSize(),
300            source->getNumVertices(),
301            usage, useShadowBuffer);
302    }
303    //-----------------------------------------------------------------------------
304    //-----------------------------------------------------------------------------
305    //-----------------------------------------------------------------------------
306    TempBlendedBufferInfo::~TempBlendedBufferInfo(void)
307    {
308        // check that temp buffers have been released
309        HardwareBufferManager &mgr = HardwareBufferManager::getSingleton();
310        if (!destPositionBuffer.isNull())
311            mgr.releaseVertexBufferCopy(destPositionBuffer);
312        if (!destNormalBuffer.isNull())
313            mgr.releaseVertexBufferCopy(destNormalBuffer);
314
315    }
316    //-----------------------------------------------------------------------------
317    void TempBlendedBufferInfo::checkoutTempCopies(bool positions, bool normals)
318    {
319        bindPositions = positions;
320        bindNormals = normals;
321
322        HardwareBufferManager &mgr = HardwareBufferManager::getSingleton();
323
324        if (!destPositionBuffer.isNull())
325        {
326            mgr.releaseVertexBufferCopy(destPositionBuffer);
327            destPositionBuffer.setNull();
328        }
329        if (!destNormalBuffer.isNull())
330        {
331            mgr.releaseVertexBufferCopy(destNormalBuffer);
332            destNormalBuffer.setNull();
333        }
334
335        if (bindPositions)
336        {
337            destPositionBuffer = mgr.allocateVertexBufferCopy(srcPositionBuffer,
338                HardwareBufferManager::BLT_AUTOMATIC_RELEASE, this);
339        }
340        if (bindNormals && !srcNormalBuffer.isNull() && !posNormalShareBuffer)
341        {
342            destNormalBuffer = mgr.allocateVertexBufferCopy(srcNormalBuffer,
343                HardwareBufferManager::BLT_AUTOMATIC_RELEASE, this);
344        }
345    }
346    //-----------------------------------------------------------------------------
347    void TempBlendedBufferInfo::bindTempCopies(VertexData* targetData, bool suppressHardwareUpload)
348    {
349        this->destPositionBuffer->suppressHardwareUpdate(suppressHardwareUpload);
350        targetData->vertexBufferBinding->setBinding(
351            this->posBindIndex, this->destPositionBuffer);
352        if (bindNormals && !posNormalShareBuffer && !destNormalBuffer.isNull())
353        {
354            this->destNormalBuffer->suppressHardwareUpdate(suppressHardwareUpload);
355            targetData->vertexBufferBinding->setBinding(
356                this->normBindIndex, this->destNormalBuffer);
357        }
358    }
359    //-----------------------------------------------------------------------------
360    void TempBlendedBufferInfo::licenseExpired(HardwareBuffer* buffer)
361    {
362        assert(buffer == destPositionBuffer.get()
363            || buffer == destNormalBuffer.get());
364
365        if (buffer == destPositionBuffer.get())
366            destPositionBuffer.setNull();
367        if (buffer == destNormalBuffer.get())
368            destNormalBuffer.setNull();
369
370    }
371
372}
Note: See TracBrowser for help on using the repository browser.