Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages  

OgreHardwareBufferManager.cpp

Go to the documentation of this file.
00001 /*
00002 -----------------------------------------------------------------------------
00003 This source file is part of OGRE
00004     (Object-oriented Graphics Rendering Engine)
00005 For the latest info, see http://www.ogre3d.org/
00006 
00007 Copyright © 2000-2003 The OGRE Team
00008 Also see acknowledgements in Readme.html
00009 
00010 This program is free software; you can redistribute it and/or modify it under
00011 the terms of the GNU Lesser General Public License as published by the Free Software
00012 Foundation; either version 2 of the License, or (at your option) any later
00013 version.
00014 
00015 This program is distributed in the hope that it will be useful, but WITHOUT
00016 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
00017 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
00018 
00019 You should have received a copy of the GNU Lesser General Public License along with
00020 this program; if not, write to the Free Software Foundation, Inc., 59 Temple
00021 Place - Suite 330, Boston, MA 02111-1307, USA, or go to
00022 http://www.gnu.org/copyleft/lesser.txt.
00023 -----------------------------------------------------------------------------
00024 */
00025 #include "OgreStableHeaders.h"
00026 #include "OgreHardwareBufferManager.h"
00027 #include "OgreVertexIndexData.h"
00028 
00029 
00030 namespace Ogre {
00031 
00032     //-----------------------------------------------------------------------
00033     template<> HardwareBufferManager* Singleton<HardwareBufferManager>::ms_Singleton = 0;
00034     HardwareBufferManager* HardwareBufferManager::getSingletonPtr(void)
00035     {
00036         return ms_Singleton;
00037     }
00038     HardwareBufferManager& HardwareBufferManager::getSingleton(void)
00039     {  
00040         assert( ms_Singleton );  return ( *ms_Singleton );  
00041     }
00042     //-----------------------------------------------------------------------
00043     HardwareBufferManager::HardwareBufferManager()
00044     {
00045     }
00046     //-----------------------------------------------------------------------
00047     HardwareBufferManager::~HardwareBufferManager()
00048     {
00049         // Destroy everything
00050         destroyAllDeclarations();
00051         destroyAllBindings();
00052         // No need to destroy main buffers - they will be destroyed by removal of bindings
00053 
00054         // Destroy temp buffers
00055         FreeTemporaryVertexBufferMap::iterator i, iend;
00056         iend = mFreeTempVertexBufferMap.end();
00057         for (i = mFreeTempVertexBufferMap.begin(); i != iend; ++i)
00058         {
00059             delete i->second;
00060         }
00061     }
00062     //-----------------------------------------------------------------------
00063     VertexDeclaration* HardwareBufferManager::createVertexDeclaration(void)
00064     {
00065         VertexDeclaration* decl = new VertexDeclaration();
00066         mVertexDeclarations.push_back(decl);
00067         return decl;
00068         
00069     }
00070     //-----------------------------------------------------------------------
00071     void HardwareBufferManager::destroyVertexDeclaration(VertexDeclaration* decl)
00072     {
00073         mVertexDeclarations.remove(decl);
00074         delete decl;
00075     }
00076     //-----------------------------------------------------------------------
00077     VertexBufferBinding* HardwareBufferManager::createVertexBufferBinding(void)
00078     {
00079         VertexBufferBinding* ret = new VertexBufferBinding();
00080         mVertexBufferBindings.push_back(ret);
00081         return ret;
00082     }
00083     //-----------------------------------------------------------------------
00084     void HardwareBufferManager::destroyVertexBufferBinding(VertexBufferBinding* binding)
00085     {
00086         mVertexBufferBindings.remove(binding);
00087         delete binding;
00088     }
00089     //-----------------------------------------------------------------------
00090     void HardwareBufferManager::destroyAllDeclarations(void)
00091     {
00092         VertexDeclarationList::iterator decl;
00093         for (decl = mVertexDeclarations.begin(); decl != mVertexDeclarations.end(); ++decl)
00094         {
00095             delete *decl;
00096         }
00097         mVertexDeclarations.clear();
00098 
00099     }
00100     //-----------------------------------------------------------------------
00101     void HardwareBufferManager::destroyAllBindings(void)
00102     {
00103         VertexBufferBindingList::iterator bind;
00104         for (bind = mVertexBufferBindings.begin(); bind != mVertexBufferBindings.end(); ++bind)
00105         {
00106             delete *bind;
00107         }
00108         mVertexBufferBindings.clear();
00109     }
00110     //-----------------------------------------------------------------------
00111     void HardwareBufferManager::registerVertexBufferSourceAndCopy(
00112             const HardwareVertexBufferSharedPtr& sourceBuffer,
00113             const HardwareVertexBufferSharedPtr& copy)
00114     {
00115         // Locate source buffer copy in free list
00116         FreeTemporaryVertexBufferMap::iterator vbmi = 
00117             mFreeTempVertexBufferMap.find(sourceBuffer.getPointer());
00118 
00119         if (vbmi == mFreeTempVertexBufferMap.end())
00120         {
00121             // Add new entry
00122             FreeTemporaryVertexBufferList *newList = new FreeTemporaryVertexBufferList();
00123             std::pair<FreeTemporaryVertexBufferMap::iterator, bool> retPair = 
00124                 mFreeTempVertexBufferMap.insert(
00125                     FreeTemporaryVertexBufferMap::value_type(
00126                         sourceBuffer.getPointer(), newList));
00127             assert(retPair.second && "Error inserting buffer list");
00128             vbmi = retPair.first;
00129         }
00130 
00131         // Add copy to free list
00132         vbmi->second->push_back(copy);
00133     }
00134     //-----------------------------------------------------------------------
00135     HardwareVertexBufferSharedPtr 
00136     HardwareBufferManager::allocateVertexBufferCopy(
00137         const HardwareVertexBufferSharedPtr& sourceBuffer, 
00138         BufferLicenseType licenseType, HardwareBufferLicensee* licensee,
00139         bool copyData)
00140     {
00141         // Locate existing buffer copy in free list
00142         FreeTemporaryVertexBufferMap::iterator vbmi = 
00143             mFreeTempVertexBufferMap.find(sourceBuffer.getPointer());
00144 
00145         if (vbmi == mFreeTempVertexBufferMap.end())
00146         {
00147             // Add new entry
00148             FreeTemporaryVertexBufferList *newList = new FreeTemporaryVertexBufferList();
00149             std::pair<FreeTemporaryVertexBufferMap::iterator, bool> retPair = 
00150                 mFreeTempVertexBufferMap.insert(
00151                     FreeTemporaryVertexBufferMap::value_type(
00152                         sourceBuffer.getPointer(), newList));
00153             assert(retPair.second && "Error inserting buffer list");
00154             vbmi = retPair.first;
00155         }
00156 
00157         HardwareVertexBufferSharedPtr vbuf;
00158         // Are there any free buffers?
00159         if (vbmi->second->empty())
00160         {
00161             // copy buffer, use shadow buffer and make dynamic
00162             vbuf = makeBufferCopy(
00163                 sourceBuffer, 
00164                 HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY_DISCARDABLE, 
00165                 true);
00166         }
00167         else
00168         {
00169             // Allocate existing copy
00170             vbuf = vbmi->second->back();
00171             vbmi->second->pop_back();
00172         }
00173 
00174         // Copy data?
00175         if (copyData)
00176         {
00177             vbuf->copyData(*(sourceBuffer.get()), 0, 0, sourceBuffer->getSizeInBytes(), true);
00178         }
00179         // Insert copy into licensee list
00180         mTempVertexBufferLicenses.push_back(
00181             VertexBufferLicense(sourceBuffer.getPointer(), licenseType, vbuf, licensee));
00182 
00183         return vbuf;
00184     }
00185     //-----------------------------------------------------------------------
00186     void HardwareBufferManager::releaseVertexBufferCopy(
00187         const HardwareVertexBufferSharedPtr& bufferCopy)
00188     {
00189         TemporaryVertexBufferLicenseList::iterator i, iend;
00190         iend = mTempVertexBufferLicenses.end();
00191         for (i = mTempVertexBufferLicenses.begin(); i != iend; ++i)
00192         {
00193             const VertexBufferLicense& vbl = *i;
00194             if (vbl.buffer.getPointer() == bufferCopy.getPointer())
00195             {
00196 
00197                 FreeTemporaryVertexBufferMap::iterator vbi =
00198                     mFreeTempVertexBufferMap.find(vbl.originalBufferPtr);
00199                 assert (vbi != mFreeTempVertexBufferMap.end());
00200 
00201                 vbi->second->push_back(vbl.buffer);
00202                 mTempVertexBufferLicenses.erase(i);
00203                 break;
00204 
00205             }
00206         }
00207 
00208     }
00209     //-----------------------------------------------------------------------
00210     void HardwareBufferManager::_releaseBufferCopies(void)
00211     {
00212         TemporaryVertexBufferLicenseList::iterator i;
00213         i = mTempVertexBufferLicenses.begin(); 
00214 
00215         while (i != mTempVertexBufferLicenses.end()) 
00216         {
00217 
00218             const VertexBufferLicense& vbl = *i;
00219             if (vbl.licenseType == BLT_AUTOMATIC_RELEASE)
00220             {
00221 
00222                 FreeTemporaryVertexBufferMap::iterator vbi =
00223                     mFreeTempVertexBufferMap.find(vbl.originalBufferPtr);
00224                 assert (vbi != mFreeTempVertexBufferMap.end());
00225 
00226                 vbi->second->push_back(vbl.buffer);
00227                 i = mTempVertexBufferLicenses.erase(i);
00228 
00229             }
00230             else
00231             {
00232                 ++i;
00233             }
00234         }
00235     }
00236     //-----------------------------------------------------------------------
00237     void HardwareBufferManager::_forceReleaseBufferCopies(
00238         const HardwareVertexBufferSharedPtr& sourceBuffer)
00239     {
00240         TemporaryVertexBufferLicenseList::iterator i;
00241         i = mTempVertexBufferLicenses.begin(); 
00242     
00243         // Erase the copies which are licensed out
00244         while (i != mTempVertexBufferLicenses.end()) 
00245         {
00246             const VertexBufferLicense& vbl = *i;
00247             if (vbl.originalBufferPtr == sourceBuffer.get())
00248             {
00249                 // Just tell the owner that this is being released
00250                 vbl.licensee->licenseExpired(vbl.buffer.get());
00251                 i = mTempVertexBufferLicenses.erase(i);
00252             }
00253             else
00254             {
00255                 ++i;
00256             }
00257         }
00258         // Erase the free copies
00259         FreeTemporaryVertexBufferMap::iterator fi =
00260             mFreeTempVertexBufferMap.begin();
00261         while (fi != mFreeTempVertexBufferMap.end())
00262         {
00263             if (fi->first == sourceBuffer.get())
00264             {
00265                 delete fi->second;
00266                 FreeTemporaryVertexBufferMap::iterator deli = fi++;
00267                 mFreeTempVertexBufferMap.erase(deli);
00268             }
00269             else
00270             {
00271                 ++fi;
00272             }
00273         }
00274     }
00275 
00276     //-----------------------------------------------------------------------
00277     HardwareVertexBufferSharedPtr 
00278     HardwareBufferManager::makeBufferCopy(
00279         const HardwareVertexBufferSharedPtr& source,
00280         HardwareBuffer::Usage usage, bool useShadowBuffer)
00281     {
00282         return this->createVertexBuffer(
00283             source->getVertexSize(), 
00284             source->getNumVertices(),
00285             usage, useShadowBuffer);
00286     }
00287     //-----------------------------------------------------------------------------
00288     void TempBlendedBufferInfo::checkoutTempCopies(bool positions, bool normals)
00289     {
00290         bindPositions = positions;
00291         bindNormals = normals;
00292         HardwareBufferManager &mgr = HardwareBufferManager::getSingleton();
00293         if (bindPositions)
00294         {
00295             destPositionBuffer = mgr.allocateVertexBufferCopy(srcPositionBuffer, 
00296                 HardwareBufferManager::BLT_AUTOMATIC_RELEASE, this);
00297         }
00298         if (bindNormals && !srcNormalBuffer.isNull() && !posNormalShareBuffer)
00299         {
00300             destNormalBuffer = mgr.allocateVertexBufferCopy(srcNormalBuffer, 
00301                 HardwareBufferManager::BLT_AUTOMATIC_RELEASE, this);
00302         }
00303     }
00304     //-----------------------------------------------------------------------------
00305     void TempBlendedBufferInfo::bindTempCopies(VertexData* targetData, bool suppressHardwareUpload)
00306     {
00307         this->destPositionBuffer->suppressHardwareUpdate(suppressHardwareUpload);
00308         targetData->vertexBufferBinding->setBinding(
00309             this->posBindIndex, this->destPositionBuffer);
00310         if (bindNormals && !posNormalShareBuffer && !destNormalBuffer.isNull())
00311         {
00312             this->destNormalBuffer->suppressHardwareUpdate(suppressHardwareUpload);
00313             targetData->vertexBufferBinding->setBinding(
00314                 this->normBindIndex, this->destNormalBuffer);
00315         }
00316     }
00317     //-----------------------------------------------------------------------------
00318     void TempBlendedBufferInfo::licenseExpired(HardwareBuffer* buffer)
00319     {
00320         if (buffer == destPositionBuffer.get())
00321             destPositionBuffer.setNull();
00322         if (buffer == destNormalBuffer.get())
00323             destNormalBuffer.setNull();
00324 
00325     }
00326 
00327 }

Copyright © 2002-2003 by The OGRE Team
Last modified Sun Nov 28 19:48:29 2004