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