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