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(sourceBuffer, HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY, 
00163                 true);
00164         }
00165         else
00166         {
00167             // Allocate existing copy
00168             vbuf = vbmi->second->back();
00169             vbmi->second->pop_back();
00170         }
00171 
00172         // Copy data?
00173         if (copyData)
00174         {
00175             vbuf->copyData(*(sourceBuffer.get()), 0, 0, sourceBuffer->getSizeInBytes(), true);
00176         }
00177         // Insert copy into licensee list
00178         mTempVertexBufferLicenses.push_back(
00179             VertexBufferLicense(sourceBuffer.getPointer(), licenseType, vbuf, licensee));
00180 
00181         return vbuf;
00182     }
00183     //-----------------------------------------------------------------------
00184     void HardwareBufferManager::releaseVertexBufferCopy(
00185         const HardwareVertexBufferSharedPtr& bufferCopy)
00186     {
00187         TemporaryVertexBufferLicenseList::iterator i, iend;
00188         iend = mTempVertexBufferLicenses.end();
00189         for (i = mTempVertexBufferLicenses.begin(); i != iend; ++i)
00190         {
00191             const VertexBufferLicense& vbl = *i;
00192             if (vbl.buffer.getPointer() == bufferCopy.getPointer())
00193             {
00194 
00195                 FreeTemporaryVertexBufferMap::iterator vbi =
00196                     mFreeTempVertexBufferMap.find(vbl.originalBufferPtr);
00197                 assert (vbi != mFreeTempVertexBufferMap.end());
00198 
00199                 vbi->second->push_back(vbl.buffer);
00200                 mTempVertexBufferLicenses.erase(i);
00201                 break;
00202 
00203             }
00204         }
00205 
00206     }
00207     //-----------------------------------------------------------------------
00208     void HardwareBufferManager::_releaseBufferCopies(void)
00209     {
00210         TemporaryVertexBufferLicenseList::iterator i;
00211         i = mTempVertexBufferLicenses.begin(); 
00212 
00213         while (i != mTempVertexBufferLicenses.end()) 
00214         {
00215 
00216             const VertexBufferLicense& vbl = *i;
00217             if (vbl.licenseType == BLT_AUTOMATIC_RELEASE)
00218             {
00219 
00220                 FreeTemporaryVertexBufferMap::iterator vbi =
00221                     mFreeTempVertexBufferMap.find(vbl.originalBufferPtr);
00222                 assert (vbi != mFreeTempVertexBufferMap.end());
00223 
00224                 vbi->second->push_back(vbl.buffer);
00225                 i = mTempVertexBufferLicenses.erase(i);
00226 
00227             }
00228             else
00229             {
00230                 ++i;
00231             }
00232         }
00233     }
00234     //-----------------------------------------------------------------------
00235     void HardwareBufferManager::_forceReleaseBufferCopies(
00236         const HardwareVertexBufferSharedPtr& sourceBuffer)
00237     {
00238         TemporaryVertexBufferLicenseList::iterator i;
00239         i = mTempVertexBufferLicenses.begin(); 
00240     
00241         // Erase the copies which are licensed out
00242         while (i != mTempVertexBufferLicenses.end()) 
00243         {
00244             const VertexBufferLicense& vbl = *i;
00245             if (vbl.originalBufferPtr == sourceBuffer.get())
00246             {
00247                 // Just tell the owner that this is being released
00248                 vbl.licensee->licenseExpired(vbl.buffer.get());
00249                 i = mTempVertexBufferLicenses.erase(i);
00250             }
00251             else
00252             {
00253                 ++i;
00254             }
00255         }
00256         // Erase the free copies
00257         FreeTemporaryVertexBufferMap::iterator fi =
00258             mFreeTempVertexBufferMap.begin();
00259         while (fi != mFreeTempVertexBufferMap.end())
00260         {
00261             if (fi->first == sourceBuffer.get())
00262             {
00263                 delete fi->second;
00264                 FreeTemporaryVertexBufferMap::iterator deli = fi++;
00265                 mFreeTempVertexBufferMap.erase(deli);
00266             }
00267             else
00268             {
00269                 ++fi;
00270             }
00271         }
00272     }
00273 
00274     //-----------------------------------------------------------------------
00275     HardwareVertexBufferSharedPtr 
00276     HardwareBufferManager::makeBufferCopy(
00277         const HardwareVertexBufferSharedPtr& source,
00278         HardwareBuffer::Usage usage, bool useShadowBuffer)
00279     {
00280         return this->createVertexBuffer(
00281             source->getVertexSize(), 
00282             source->getNumVertices(),
00283             usage, useShadowBuffer);
00284     }
00285     //-----------------------------------------------------------------------------
00286     void TempBlendedBufferInfo::checkoutTempCopies(bool positions, bool normals)
00287     {
00288         bindPositions = positions;
00289         bindNormals = normals;
00290         HardwareBufferManager &mgr = HardwareBufferManager::getSingleton();
00291         if (bindPositions)
00292         {
00293             destPositionBuffer = mgr.allocateVertexBufferCopy(srcPositionBuffer, 
00294                 HardwareBufferManager::BLT_AUTOMATIC_RELEASE, this);
00295         }
00296         if (bindNormals && !srcNormalBuffer.isNull() && !posNormalShareBuffer)
00297         {
00298             destNormalBuffer = mgr.allocateVertexBufferCopy(srcNormalBuffer, 
00299                 HardwareBufferManager::BLT_AUTOMATIC_RELEASE, this);
00300         }
00301     }
00302     //-----------------------------------------------------------------------------
00303     void TempBlendedBufferInfo::bindTempCopies(VertexData* targetData, bool suppressHardwareUpload)
00304     {
00305         this->destPositionBuffer->suppressHardwareUpdate(suppressHardwareUpload);
00306         targetData->vertexBufferBinding->setBinding(
00307             this->posBindIndex, this->destPositionBuffer);
00308         if (bindNormals && !posNormalShareBuffer)
00309         {
00310             this->destNormalBuffer->suppressHardwareUpdate(suppressHardwareUpload);
00311             targetData->vertexBufferBinding->setBinding(
00312                 this->normBindIndex, this->destNormalBuffer);
00313         }
00314     }
00315     //-----------------------------------------------------------------------------
00316     void TempBlendedBufferInfo::licenseExpired(HardwareBuffer* buffer)
00317     {
00318         if (buffer == destPositionBuffer.get())
00319             destPositionBuffer.release();
00320         if (buffer == destNormalBuffer.get())
00321             destNormalBuffer.release();
00322 
00323     }
00324 
00325 }

Copyright © 2002-2003 by The OGRE Team
Last modified Fri May 14 23:22:16 2004