#include <async_texture_manager.h>
Nevrax France
Definition at line 53 of file async_texture_manager.h.
Public Member Functions | |
uint | addTextureRef (const std::string &textName, CMeshBaseInstance *instance, const NLMISC::CVector &position) |
CAsyncTextureManager () | |
Constructor. | |
const NLMISC::CBitmap * | getCoarseBitmap (uint id) const |
uint | getLastTextureSizeGot () const |
get what the system really allows | |
uint | getTotalTextureSizeAsked () const |
get the async texture Size asked (ie maybe bigger than MaxTotalTextureSize). | |
bool | isTextureUpLoaded (uint id) const |
tells if a texture is loaded in the driver (ie ready to use) | |
void | releaseTexture (uint id, CMeshBaseInstance *instance) |
release a texture-instance tuple. the texture is released if no more instance use it. | |
void | setupLod (uint baseLevel, uint maxLevel) |
void | setupMaxHLSColoringPerFrame (uint maxCol) |
Setup max texture HLS Coloring per update() call (in bytes). Default to 20K. | |
void | setupMaxTotalTextureSize (uint maxText) |
Setup max total texture size allowed. Default is 10Mo. | |
void | setupMaxUploadPerFrame (uint maxup) |
Setup max texture upload in driver per update() call (in bytes). Default to 64K. | |
void | update (IDriver *pDriver) |
~CAsyncTextureManager () | |
Data Fields | |
CHLSTextureManager | HLSManager |
User is free to add bank to this manager. Other methods are used by the async manager. | |
Private Types | |
typedef TTextureEntryMap::iterator | ItTextureEntryMap |
typedef std::map< std::string, uint > | TTextureEntryMap |
Private Member Functions | |
void | deleteTexture (uint id) |
void | getNextTextureToUpLoad (uint &nTotalColored, IDriver *pDriver) |
void | updateTextureLodSystem (IDriver *pDriver) |
bool | uploadTexturePart (ITexture *pText, IDriver *pDriver, uint &nTotalUpload) |
Static Private Member Functions | |
bool | validDXTCMipMap (ITexture *pText) |
Private Attributes | |
uint | _BaseLodLevel |
CTextureLod * | _CurrentTextureLodLoaded |
CTextureBase * | _CurrentUploadTexture |
uint | _CurrentUploadTextureLine |
uint | _CurrentUploadTextureMipMap |
std::vector< uint > | _FreeTextureIds |
uint | _LastTextureSizeGot |
uint | _MaxHLSColoringPerFrame |
uint | _MaxLodLevel |
uint | _MaxTotalTextureSize |
uint | _MaxUploadPerFrame |
std::vector< CTextureEntry * > | _TextureEntries |
TTextureEntryMap | _TextureEntryMap |
uint | _TotalTextureSizeAsked |
std::vector< uint > | _WaitingTextures |
|
Definition at line 122 of file async_texture_manager.h. Referenced by addTextureRef(). |
|
Definition at line 121 of file async_texture_manager.h. |
|
Constructor.
Definition at line 104 of file async_texture_manager.cpp. References _BaseLodLevel, _CurrentTextureLodLoaded, _CurrentUploadTexture, _LastTextureSizeGot, _MaxHLSColoringPerFrame, _MaxLodLevel, _MaxTotalTextureSize, _MaxUploadPerFrame, and _TotalTextureSizeAsked.
00105 { 00106 _BaseLodLevel= 3; 00107 _MaxLodLevel= 1; 00108 _MaxUploadPerFrame= 65536; 00109 _MaxHLSColoringPerFrame= 20*1024; 00110 _CurrentUploadTexture= NULL; 00111 _MaxTotalTextureSize= 10*1024*1024; 00112 _TotalTextureSizeAsked= 0; 00113 _LastTextureSizeGot= 0; 00114 00115 // Do not share this texture, to force uploading of the lods. 00116 _CurrentTextureLodLoaded= NULL; 00117 } |
|
Definition at line 89 of file async_texture_manager.cpp. References _CurrentTextureLodLoaded, _CurrentUploadTexture, _TextureEntries, _TextureEntryMap, _WaitingTextures, deleteTexture(), nlassert, and uint.
00090 { 00091 // For all remaining textures, delete them. 00092 for(uint i=0;i<_TextureEntries.size();i++) 00093 { 00094 if(_TextureEntries[i]) 00095 deleteTexture(i); 00096 } 00097 00098 // there must be no waitting textures, nor map, nor current upload texture 00099 nlassert(_WaitingTextures.empty() && _TextureEntryMap.empty() && _CurrentUploadTexture==NULL 00100 && _CurrentTextureLodLoaded==NULL); 00101 } |
|
Add a reference to a texture owned by an instance. If the texture still exist, only the refcount is incremented Else If texture is found in the HLSTextureManager, it is builded (async) from it, else Begin Async loading ThereFore, only CTextureFile are possible. Note also that the texture is uploaded with mipmap by default, and UpLoadFormat is also default (say ITexture::Auto) If the texture file is not a DDS with mipmap, this is an error. But the system doens't fail and the file is entirely loaded and uploaded. The problem is that upload is not cut according to maxUpLoadPerFrame, so some freeze may occur. Definition at line 151 of file async_texture_manager.cpp. References NL3D::CMeshBaseInstance::_AsyncTextureToLoadRefCount, _BaseLodLevel, _FreeTextureIds, _TextureEntries, _TextureEntryMap, _WaitingTextures, NL3D::CHLSTextureManager::findTexture(), HLSManager, NL3D::CAsyncTextureManager::CTextureEntry::Instances, ItTextureEntryMap, sint, NLMISC::strlwr(), NL3D::CAsyncTextureManager::CTextureBase::Texture, uint, and NL3D::CAsyncTextureManager::CTextureEntry::UpLoaded. Referenced by NL3D::CMeshBaseInstance::startAsyncTextureLoading().
00152 { 00153 uint ret; 00154 00155 // strlwr name 00156 string textName= textNameNotLwr; 00157 strlwr(textName); 00158 00159 // find the texture in map 00160 ItTextureEntryMap it; 00161 it= _TextureEntryMap.find(textName); 00162 00163 // not found, create. 00164 if(it==_TextureEntryMap.end()) 00165 { 00166 // search a free id. 00167 uint i= _TextureEntries.size(); 00168 if(!_FreeTextureIds.empty()) 00169 { 00170 i= _FreeTextureIds.back(); 00171 _FreeTextureIds.pop_back(); 00172 } 00173 // resize if needed. 00174 if(i>=_TextureEntries.size()) 00175 { 00176 _TextureEntries.push_back(NULL); 00177 _FreeTextureIds.reserve(_TextureEntries.capacity()); 00178 } 00179 00180 // alloc new. 00181 CTextureEntry *text= new CTextureEntry(); 00182 _TextureEntries[i]= text; 00183 text->Texture= new CTextureFile; 00184 // Do not allow degradation. 00185 text->Texture->setAllowDegradation(false); 00186 00187 // add to map. 00188 it= _TextureEntryMap.insert(make_pair(textName, i)).first; 00189 // bkup the it for deletion 00190 text->ItMap= it; 00191 00192 // Start Color or Async loading. 00193 text->Texture->setFileName(textName); 00194 // First try with the HLSManager 00195 sint colorTextId= HLSManager.findTexture(textName); 00196 // If found 00197 if(colorTextId!=-1) 00198 { 00199 // Mark the texture as Loaded, and ready to colorize (done in update()). 00200 text->Loaded= true; 00201 text->BuildFromHLSManager= true; 00202 text->HLSManagerTextId= colorTextId; 00203 } 00204 // else must async load it. 00205 else 00206 { 00207 // start to load a small DDS version if possible 00208 text->Texture->setMipMapSkipAtLoad(_BaseLodLevel); 00209 // load it async. 00210 CAsyncFileManager3D::getInstance().loadTexture(text->Texture, &text->Loaded, position); 00211 } 00212 // Add to a list so we can check each frame if it has ended. 00213 _WaitingTextures.push_back(i); 00214 } 00215 00216 // get the id of the text entry. 00217 ret= it->second; 00218 00219 // add this instance to the list of ones which use this texture. 00220 CTextureEntry *text= _TextureEntries[ret]; 00221 text->Instances.push_back(instance); 00222 00223 // if the texture is not yet ready, must increment the instance refCount. 00224 if(!text->UpLoaded) 00225 instance->_AsyncTextureToLoadRefCount++; 00226 00227 return ret; 00228 } |
|
Definition at line 232 of file async_texture_manager.cpp. References _CurrentTextureLodLoaded, _CurrentUploadTexture, _FreeTextureIds, _TextureEntries, _TextureEntryMap, _TotalTextureSizeAsked, _WaitingTextures, NL3D::CAsyncTextureManager::CTextureEntry::HDLod, NL3D::CAsyncTextureManager::CTextureEntry::Instances, NL3D::CAsyncTextureManager::CTextureEntry::ItMap, NL3D::CAsyncTextureManager::CTextureLod::Loaded, NL3D::CAsyncTextureManager::CTextureEntry::Loaded, NL3D::CAsyncTextureManager::CTextureBase::Texture, NL3D::CAsyncTextureManager::CTextureEntry::TotalTextureSizeAsked, uint, and NL3D::CAsyncTextureManager::CTextureEntry::UpLoaded. Referenced by releaseTexture(), and ~CAsyncTextureManager().
00233 { 00234 CTextureEntry *text= _TextureEntries[id]; 00235 00236 00237 // **** Stop AsyncLoading/UpLoading of main texture. 00238 00239 // stop async loading if not ended 00240 if(!text->Loaded) 00241 { 00242 CAsyncFileManager3D::getInstance().cancelLoadTexture(text->Texture); 00243 } 00244 00245 // remove map entry 00246 _TextureEntryMap.erase(text->ItMap); 00247 00248 // remove in list of waiting textures 00249 vector<uint>::iterator itWait= find(_WaitingTextures.begin(),_WaitingTextures.end(), id); 00250 if(itWait!=_WaitingTextures.end()) 00251 _WaitingTextures.erase(itWait); 00252 00253 // If it was the currently uploaded one, abort 00254 if(_CurrentUploadTexture==text) 00255 { 00256 _CurrentUploadTexture= NULL; 00257 } 00258 00259 // If not uploaded. 00260 if(!text->UpLoaded) 00261 { 00262 // For all its remainding instances, dec refcount 00263 for(uint i=0;i<text->Instances.size();i++) 00264 { 00265 text->Instances[i]->_AsyncTextureToLoadRefCount--; 00266 } 00267 } 00268 00269 // remove from bench 00270 _TotalTextureSizeAsked-= text->TotalTextureSizeAsked; 00271 00272 00273 // **** Stop AsyncLoading/UpLoading of HDLod 's texture. 00274 00275 // Check if must stop TextureLod loading/uploading. 00276 CTextureLod *textLod= &text->HDLod; 00277 if(textLod==_CurrentTextureLodLoaded) 00278 { 00279 // stop the async loading if not ended. 00280 if(!textLod->Loaded) 00281 { 00282 CAsyncFileManager3D::getInstance().cancelLoadTexture(textLod->Texture); 00283 } 00284 // stop uploading if was me 00285 if(_CurrentUploadTexture==textLod) 00286 { 00287 _CurrentUploadTexture= NULL; 00288 } 00289 // stop loading me. 00290 _CurrentTextureLodLoaded= NULL; 00291 } 00292 00293 // At last delete texture entry. 00294 delete text; 00295 _TextureEntries[id]= NULL; 00296 // add a new free id. 00297 _FreeTextureIds.push_back(id); 00298 } |
|
get the RAM LowDef version of a texture. Used For CLodCharacters return NULL if bad Id or if the texture is still not loaded. The bitmap returned has no mipmaps and should be in DXTC1 (not guaranteed). Definition at line 343 of file async_texture_manager.cpp. References _TextureEntries, NL3D::CAsyncTextureManager::CTextureEntry::CoarseBitmap, uint, and NL3D::CAsyncTextureManager::CTextureEntry::UpLoaded. Referenced by NL3D::CSkeletonModel::computeLodTexture().
00344 { 00345 if(id>=_TextureEntries.size()) 00346 return NULL; 00347 CTextureEntry *textEntry= _TextureEntries[id]; 00348 if(!textEntry) 00349 return NULL; 00350 00351 // if the textEntry not uploaded, return NULL 00352 if(!textEntry->UpLoaded) 00353 return NULL; 00354 00355 // ok return the CoarseBitmap 00356 return &textEntry->CoarseBitmap; 00357 } |
|
get what the system really allows
Definition at line 115 of file async_texture_manager.h. References _LastTextureSizeGot, and uint. Referenced by NL3D::CDriverUser::getLastAsyncTextureSizeGot().
00115 {return _LastTextureSizeGot;} |
|
Definition at line 553 of file async_texture_manager.cpp. References _CurrentTextureLodLoaded, _CurrentUploadTexture, _CurrentUploadTextureLine, _CurrentUploadTextureMipMap, _MaxHLSColoringPerFrame, _TextureEntries, _WaitingTextures, NL3D::CAsyncTextureManager::CTextureEntry::BuildFromHLSManager, NL3D::CHLSTextureManager::buildTexture(), HLSManager, NL3D::CAsyncTextureManager::CTextureEntry::HLSManagerTextId, NL3D::CAsyncTextureManager::CTextureLod::Loaded, NL3D::CAsyncTextureManager::CTextureEntry::Loaded, nlverify, size, NL3D::CAsyncTextureManager::CTextureBase::Texture, uint, and updateTextureLodSystem(). Referenced by update().
00554 { 00555 // Reset texture uploading 00556 _CurrentUploadTexture= NULL; 00557 _CurrentUploadTextureMipMap= 0; 00558 _CurrentUploadTextureLine= 0; 00559 00560 // Search in WaitingTextures if one has ended async loading 00561 vector<uint>::iterator it; 00562 for(it=_WaitingTextures.begin();it!=_WaitingTextures.end();it++) 00563 { 00564 CTextureEntry *text= _TextureEntries[*it]; 00565 // If Async loading done. 00566 if(text->Loaded) 00567 { 00568 // Is it a "texture to color" with HLSManager? yes=> color it now. 00569 if(text->BuildFromHLSManager) 00570 { 00571 // If not beyond the max coloring texture 00572 if(nTotalColored<_MaxHLSColoringPerFrame) 00573 { 00574 // Build the texture directly in the TextureFile. 00575 nlverify(HLSManager.buildTexture(text->HLSManagerTextId, *text->Texture)); 00576 // Must validate the textureFile generation. NB: little weird since this is not really a textureFile. 00577 // But it is the easier way to do it. 00578 text->Texture->validateGenerateFlag(); 00579 // compute the texture size (approx). NB: DXTC5 means 1 pixel==1 byte. 00580 uint size= (uint)(text->Texture->getSize(0)*1.33); 00581 // Add it to the num of colorised texture done in current update(). 00582 nTotalColored+= size; 00583 } 00584 // Else must quit and don't update any more texture this frame (_CurrentUploadTexture==NULL) 00585 else 00586 return; 00587 } 00588 00589 // upload this one 00590 _CurrentUploadTexture= text; 00591 // remove it from list of waiting textures 00592 _WaitingTextures.erase(it); 00593 // found => end. 00594 return; 00595 } 00596 } 00597 00598 // If here, and if no more waiting textures, update the Lod system. 00599 if(_WaitingTextures.empty()) 00600 { 00601 // if end to load the current lod. 00602 if(_CurrentTextureLodLoaded && _CurrentTextureLodLoaded->Loaded) 00603 { 00604 // upload this one 00605 _CurrentUploadTexture= _CurrentTextureLodLoaded; 00606 return; 00607 } 00608 00609 // if no Lod texture currently loading, try to load/unload one 00610 if(_CurrentTextureLodLoaded == NULL) 00611 { 00612 updateTextureLodSystem(pDriver); 00613 } 00614 } 00615 } |
|
get the async texture Size asked (ie maybe bigger than MaxTotalTextureSize).
Definition at line 113 of file async_texture_manager.h. References _TotalTextureSizeAsked, and uint. Referenced by NL3D::CDriverUser::getTotalAsyncTextureSizeAsked().
00113 {return _TotalTextureSizeAsked;} |
|
tells if a texture is loaded in the driver (ie ready to use)
Definition at line 334 of file async_texture_manager.cpp. References _TextureEntries, nlassert, and uint.
00335 { 00336 nlassert(id<_TextureEntries.size()); 00337 nlassert(_TextureEntries[id]); 00338 return _TextureEntries[id]->UpLoaded; 00339 } |
|
release a texture-instance tuple. the texture is released if no more instance use it.
Definition at line 302 of file async_texture_manager.cpp. References _TextureEntries, deleteTexture(), NL3D::CAsyncTextureManager::CTextureEntry::Instances, nlassert, uint, and NL3D::CAsyncTextureManager::CTextureEntry::UpLoaded. Referenced by NL3D::CMeshBaseInstance::releaseCurrentAsyncTextures().
00303 { 00304 nlassert(id<_TextureEntries.size()); 00305 nlassert(_TextureEntries[id]); 00306 00307 // find an instance in this texture an remove it. 00308 CTextureEntry *text= _TextureEntries[id]; 00309 uint instSize= text->Instances.size(); 00310 for(uint i=0;i<instSize;i++) 00311 { 00312 if(text->Instances[i]== instance) 00313 { 00314 // Must first release the refCount if the texture is not uploaded 00315 if(!text->UpLoaded) 00316 text->Instances[i]->_AsyncTextureToLoadRefCount--; 00317 // remove it by swapping with last texture 00318 text->Instances[i]= text->Instances[instSize-1]; 00319 text->Instances.pop_back(); 00320 // must stop: remove only the first occurence of instance. 00321 break; 00322 } 00323 } 00324 00325 // if no more instance occurence, the texture is no more used => release it. 00326 if(text->Instances.empty()) 00327 { 00328 // do all the good stuff 00329 deleteTexture(id); 00330 } 00331 } |
|
setup the mipMap levels. When the texture is first added, it is loaded skipping the baseLevel first mipmap During time, furhter mipmap are loaded, according to instance position etc... maxLevel tells where to stop. If 0, the texture will finally be entirely uploaded. Default is 3,1. Definition at line 121 of file async_texture_manager.cpp. References _BaseLodLevel, _MaxLodLevel, nlassert, and uint. Referenced by NL3D::CDriverUser::setupAsyncTextureLod().
00122 { 00123 nlassert(baseLevel>=maxLevel); 00124 _BaseLodLevel= baseLevel; 00125 _MaxLodLevel= maxLevel; 00126 } |
|
Setup max texture HLS Coloring per update() call (in bytes). Default to 20K.
Definition at line 137 of file async_texture_manager.cpp. References _MaxHLSColoringPerFrame, and uint. Referenced by NL3D::CDriverUser::setupMaxHLSColoringPerFrame().
00138 { 00139 if(maxCol>0) 00140 _MaxHLSColoringPerFrame= maxCol; 00141 } |
|
Setup max total texture size allowed. Default is 10Mo.
Definition at line 144 of file async_texture_manager.cpp. References _MaxTotalTextureSize, and uint. Referenced by NL3D::CDriverUser::setupMaxTotalAsyncTextureSize().
00145 { 00146 _MaxTotalTextureSize= maxText; 00147 } |
|
Setup max texture upload in driver per update() call (in bytes). Default to 64K.
Definition at line 130 of file async_texture_manager.cpp. References _MaxUploadPerFrame, and uint. Referenced by NL3D::CDriverUser::setupAsyncTextureMaxUploadPerFrame().
00131 { 00132 if(maxup>0) 00133 _MaxUploadPerFrame= maxup; 00134 } |
|
update the manager. New loaded texture are uploaded. Instances are updated to know if all their pending textures have been uploaded. Definition at line 361 of file async_texture_manager.cpp. References _BaseLodLevel, _CurrentTextureLodLoaded, _CurrentUploadTexture, _MaxLodLevel, _TotalTextureSizeAsked, NL3D::CAsyncTextureManager::CTextureEntry::BaseSize, NL3D::CAsyncTextureManager::CTextureEntry::CanHaveLOD, NL3D::CAsyncTextureManager::CTextureEntry::createCoarseBitmap(), NL3D::CAsyncTextureManager::CTextureLod::ExtraSize, getNextTextureToUpLoad(), NLMISC::CBitmap::getPixelFormat(), NLMISC::CBitmap::getSize(), NL3D::CAsyncTextureManager::CTextureEntry::HDLod, NL3D::CAsyncTextureManager::CTextureEntry::Instances, NL3D::CAsyncTextureManager::CTextureBase::isTextureEntry(), NL3D::CAsyncTextureManager::CTextureLod::Level, NL3D::CAsyncTextureManager::CTextureLod::Loaded, NL3D::ITexture::release(), NL3D::IDriver::swapTextureHandle(), NL3D::CAsyncTextureManager::CTextureBase::Texture, NL3D::CAsyncTextureManager::CTextureLod::TextureEntry, NL3D::CAsyncTextureManager::CTextureEntry::TotalTextureSizeAsked, uint, NL3D::CAsyncTextureManager::CTextureLod::UpLoaded, NL3D::CAsyncTextureManager::CTextureEntry::UpLoaded, uploadTexturePart(), and validDXTCMipMap(). Referenced by NL3D::CDriverUser::updateAsyncTexture().
00362 { 00363 uint nTotalUploaded = 0; 00364 uint nTotalColored = 0; 00365 00366 // if no texture to upload, get the next one 00367 if(_CurrentUploadTexture==NULL) 00368 getNextTextureToUpLoad(nTotalColored, pDriver); 00369 00370 // while some texture to upload 00371 while(_CurrentUploadTexture) 00372 { 00373 ITexture *pText= _CurrentUploadTexture->Texture; 00374 if(uploadTexturePart(pText, pDriver, nTotalUploaded)) 00375 { 00376 // Stuff for TextureEntry 00377 if(_CurrentUploadTexture->isTextureEntry()) 00378 { 00379 uint i; 00380 CTextureEntry *textEntry= static_cast<CTextureEntry*>(_CurrentUploadTexture); 00381 // If we are here, the texture is finally entirely uploaded. Compile it! 00382 textEntry->UpLoaded= true; 00383 // Can Have lod if texture is DXTC and have mipMaps! Also disalbe if system disable it 00384 textEntry->CanHaveLOD= validDXTCMipMap(pText) && _BaseLodLevel>_MaxLodLevel; 00385 // compute the size it takes in VRAM 00386 uint baseMipMapSize= pText->getSize(0)*CBitmap::bitPerPixels[pText->getPixelFormat()]/8; 00387 // full size with mipmap 00388 textEntry->BaseSize= (uint)(baseMipMapSize*1.33f); 00389 // UpLoaded !! => signal all instances. 00390 for(i=0;i<textEntry->Instances.size();i++) 00391 { 00392 textEntry->Instances[i]->_AsyncTextureToLoadRefCount--; 00393 } 00394 00395 // Create the coarse bitmap with the text (NB: still in memory here) 00396 textEntry->createCoarseBitmap(); 00397 00398 // If CanHaveLOD, create now the lods entries. 00399 if(textEntry->CanHaveLOD) 00400 { 00401 /* Allow only the MaxLod to be loaded async 00402 This is supposed to be faster since a fseek is much longer than a texture Read. 00403 Then it is more intelligent to read only One texture (the High Def), than to try to 00404 read intermediate ones (512, 256, 128) because this made 3 more fseek. 00405 */ 00406 // create only the MaxLod possible entry 00407 CTextureLod &textLod= textEntry->HDLod; 00408 // fill textLod 00409 textLod.TextureEntry= textEntry; 00410 textLod.Level= _MaxLodLevel; 00411 // extra size of the lod only (important for LoadBalacing in updateTextureLodSystem()) 00412 textLod.ExtraSize= textEntry->BaseSize*(1<<(2*(_BaseLodLevel-_MaxLodLevel))) - textEntry->BaseSize; 00413 // not yet loaded/upLoaded 00414 textLod.Loaded= false; 00415 textLod.UpLoaded= false; 00416 } 00417 00418 // compute texture size for bench 00419 textEntry->TotalTextureSizeAsked= textEntry->BaseSize + textEntry->HDLod.ExtraSize; 00420 00421 // Add texture size to global texture size 00422 _TotalTextureSizeAsked+= textEntry->TotalTextureSizeAsked; 00423 } 00424 // else, stuff for textureLod. 00425 else 00426 { 00427 CTextureLod *textLod= static_cast<CTextureLod*>(_CurrentUploadTexture); 00428 // Swap the uploaded Driver Handle with the Main texture. 00429 pDriver->swapTextureHandle(*textLod->Texture, *textLod->TextureEntry->Texture); 00430 // Flag the Lod. 00431 textLod->UpLoaded= true; 00432 // Ok, ended to completly load this textureLod. 00433 _CurrentTextureLodLoaded= NULL; 00434 } 00435 00436 // finally uploaded in VRAM, can release the RAM texture memory 00437 pText->release(); 00438 00439 // if not break because can't upload all parts, get next texture to upload 00440 _CurrentUploadTexture= NULL; 00441 getNextTextureToUpLoad(nTotalColored, pDriver); 00442 } 00443 else 00444 // Fail to upload all, abort. 00445 return; 00446 } 00447 } |
|
Definition at line 629 of file async_texture_manager.cpp. References _CurrentTextureLodLoaded, _LastTextureSizeGot, _MaxTotalTextureSize, _TextureEntries, NL3D::CAsyncTextureManager::CTextureEntry::BaseSize, NL3D::CAsyncTextureManager::CTextureEntry::CanHaveLOD, NL3D::CAsyncTextureManager::CTextureEntry::HDLod, NL3D::CAsyncTextureManager::CTextureEntry::Instances, NL3D::CAsyncTextureManager::CTextureLod::Level, NL3D::CAsyncTextureManager::CTextureLod::Loaded, NL3D::CAsyncTextureManager::CTextureLodToSort::Lod, NL3D::CAsyncTextureManager::CTextureEntry::MinDistance, NL3D::CAsyncTextureManager::CTextureEntry::MinPosition, NL3D_ATM_MIN_DISTANCE, nlassert, NL3D::CAsyncTextureManager::CTextureLodToSort::Position, sint, NL3D::IDriver::swapTextureHandle(), NL3D::CAsyncTextureManager::CTextureBase::Texture, NL3D::CAsyncTextureManager::CTextureLod::TextureEntry, uint, NL3D::CAsyncTextureManager::CTextureLod::UpLoaded, and NL3D::CAsyncTextureManager::CTextureLod::Weight. Referenced by getNextTextureToUpLoad().
00630 { 00631 sint i; 00632 00633 // the array to sort 00634 static vector<CTextureLodToSort> lodArray; 00635 lodArray.clear(); 00636 uint reserveSize= 0; 00637 00638 // for each texture entry compute min distance of use 00639 //============= 00640 uint currentBaseSize= 0; 00641 for(i=0;i<(sint)_TextureEntries.size();i++) 00642 { 00643 if(!_TextureEntries[i]) 00644 continue; 00645 CTextureEntry &text= *_TextureEntries[i]; 00646 // do it only for Lodable textures 00647 if(text.CanHaveLOD) 00648 { 00649 text.MinDistance= FLT_MAX; 00650 // for all instances. 00651 for(uint j=0;j<text.Instances.size();j++) 00652 { 00653 float instDist= text.Instances[j]->getAsyncTextureDistance(); 00654 00655 if (instDist<text.MinDistance) 00656 { 00657 text.MinPosition = text.Instances[j]->getPos(); 00658 text.MinDistance = instDist; 00659 } 00660 } 00661 00662 // avoid /0 00663 text.MinDistance= max(NL3D_ATM_MIN_DISTANCE, text.MinDistance); 00664 00665 // how many textLods to add 00666 reserveSize++; 00667 00668 // the minimum mem size the system take with base lod. 00669 currentBaseSize+= text.BaseSize; 00670 } 00671 } 00672 // reserve space 00673 lodArray.reserve(reserveSize); 00674 00675 00676 // for each texture lod compute weight, and append 00677 //============= 00678 for(i=0;i<(sint)_TextureEntries.size();i++) 00679 { 00680 if(!_TextureEntries[i]) 00681 continue; 00682 CTextureEntry &text= *_TextureEntries[i]; 00683 // do it only for Lodable textures 00684 if(text.CanHaveLOD) 00685 { 00686 // This Weight is actually a screen Pixel Ratio! (divide by distance) 00687 CTextureLod *textLod= &text.HDLod; 00688 textLod->Weight= (1<<textLod->Level) / text.MinDistance; 00689 // add to array 00690 CTextureLodToSort toSort; 00691 toSort.Lod = textLod; 00692 toSort.Position = text.MinPosition; 00693 lodArray.push_back(toSort); 00694 } 00695 } 00696 00697 00698 // sort 00699 //============= 00700 sort(lodArray.begin(), lodArray.end()); 00701 00702 00703 // Compute lod to load/unload 00704 //============= 00705 // Compute Pivot, ie what lods have to be loaded, and what lods do not 00706 uint pivot= 0; 00707 uint currentWantedSize= currentBaseSize; 00708 uint currentLoadedSize= currentBaseSize; 00709 for(i=lodArray.size()-1;i>=0;i--) 00710 { 00711 uint lodSize= lodArray[i].Lod->ExtraSize; 00712 currentWantedSize+= lodSize; 00713 if(lodArray[i].Lod->UpLoaded) 00714 currentLoadedSize+= lodSize; 00715 // if > max allowed, stop the pivot here. NB: the pivot is included in the "must load them" part. 00716 if(currentWantedSize > _MaxTotalTextureSize) 00717 { 00718 pivot= i; 00719 break; 00720 } 00721 } 00722 // continue to count currentLoadedSize 00723 for(;i>=0;i--) 00724 { 00725 if(lodArray[i].Lod->UpLoaded) 00726 currentLoadedSize+= lodArray[i].Lod->ExtraSize; 00727 } 00728 // save bench. 00729 _LastTextureSizeGot= currentLoadedSize; 00730 00731 00732 // if the loadedSize is inferior to the wanted size, we can load a new LOD 00733 CTextureLodToSort *textLod= NULL; 00734 bool unload; 00735 if(currentLoadedSize<currentWantedSize) 00736 { 00737 unload= false; 00738 // search from end of the list to pivot (included), the first LOD (ie the most important) to load. 00739 for(i=lodArray.size()-1;i>=(sint)pivot;i--) 00740 { 00741 if(!lodArray[i].Lod->UpLoaded) 00742 { 00743 textLod= &(lodArray[i]); 00744 break; 00745 } 00746 } 00747 // One must have been found, since currentLoadedSize<currentWantedSize 00748 nlassert(textLod); 00749 } 00750 else 00751 { 00752 unload= true; 00753 // search from start to pivot (exclued), the first LOD (ie the less important) to unload. 00754 for(i=0;i<(sint)pivot;i++) 00755 { 00756 if(lodArray[i].Lod->UpLoaded) 00757 { 00758 textLod= &(lodArray[i]); 00759 break; 00760 } 00761 } 00762 // it is possible that not found here. It means that All is Ok!! 00763 if(textLod==NULL) 00764 // no-op. 00765 return; 00766 } 00767 00768 00769 // load/unload 00770 //============= 00771 if(!unload) 00772 { 00773 // create a new TextureFile, with no sharing system. 00774 nlassert(textLod->Lod->Texture==NULL); 00775 textLod->Lod->Texture= new CTextureFile; 00776 // Do not allow degradation. 00777 textLod->Lod->Texture->setAllowDegradation(false); 00778 textLod->Lod->Texture->enableSharing(false); 00779 textLod->Lod->Texture->setFileName(textLod->Lod->TextureEntry->Texture->getFileName()); 00780 textLod->Lod->Texture->setMipMapSkipAtLoad(textLod->Lod->Level); 00781 // setup async loading 00782 _CurrentTextureLodLoaded= textLod->Lod; 00783 // load it async. 00784 CAsyncFileManager3D::getInstance().loadTexture(textLod->Lod->Texture, &textLod->Lod->Loaded, textLod->Position); 00785 } 00786 else 00787 { 00788 // Swap now the lod. 00789 nlassert(textLod->Lod->Texture!=NULL); 00790 // Swap the uploaded Driver Handle with the Main texture (ot get the Ugly one) 00791 pDriver->swapTextureHandle(*textLod->Lod->Texture, *textLod->Lod->TextureEntry->Texture); 00792 // Flag the Lod. 00793 textLod->Lod->UpLoaded= false; 00794 textLod->Lod->Loaded= false; 00795 // Release completly the texture in driver. (SmartPtr delete) 00796 textLod->Lod->Texture= NULL; 00797 } 00798 00799 } |
|
Definition at line 451 of file async_texture_manager.cpp. References _CurrentUploadTextureLine, _CurrentUploadTextureMipMap, _MaxUploadPerFrame, NLMISC::CBitmap::getHeight(), NLMISC::CBitmap::getMipMapCount(), NLMISC::CBitmap::getPixelFormat(), NL3D::ITexture::getReleasable(), NLMISC::CBitmap::getSize(), NLMISC::CBitmap::getWidth(), min, NLMISC::CRect::set(), NL3D::ITexture::setReleasable(), NL3D::IDriver::setupTextureEx(), uint, uint32, uint8, NL3D::IDriver::uploadTexture(), and validDXTCMipMap(). Referenced by update().
00452 { 00453 uint nMipMap; 00454 nMipMap = pText->getMipMapCount(); 00455 00456 00457 // If this is the start of uploading, setup the texture in driver. 00458 if(_CurrentUploadTextureMipMap==0 && _CurrentUploadTextureLine==0) 00459 { 00460 // If the texture is not a valid DXTC with mipmap 00461 if(!validDXTCMipMap(pText)) 00462 { 00463 /* For now, prefer do nothing, because this may be an error (texture not found) 00464 and the texture may not be used at all, so don't take VRAM for nothing. 00465 => if the texture is used, it will be loaded synchronously by the caller later in the process 00466 => frame freeze. 00467 */ 00468 /* 00469 // upload All now. 00470 // MipMap generation and compression may be done here => Maybe Big Freeze. 00471 // approximate*2 instead of *1.33 for mipmaps. 00472 uint nWeight = pText->getSize (0) * 2; 00473 nWeight= (nWeight*CBitmap::bitPerPixels[pText->getPixelFormat()])/8; 00474 nTotalUploaded+= nWeight; 00475 pDriver->setupTexture(*pText); 00476 return true;*/ 00477 return true; 00478 } 00479 else 00480 { 00481 // Create the texture only and do not upload anything 00482 bool isRel = pText->getReleasable (); 00483 pText->setReleasable (false); 00484 bool isAllUploaded = false; 00485 /* Even if the shared texture is still referenced and so still exist in driver, we MUST recreate with good size 00486 the texture. This is important for Texture Memory Load Balancing 00487 (this may means that is used elsewhere than in the CAsyncTextureManager) 00488 Hence: bMustRecreateSharedTexture==true 00489 */ 00490 pDriver->setupTextureEx (*pText, false, isAllUploaded, true); 00491 pText->setReleasable (isRel); 00492 // if the texture is already uploaded, abort partial uploading. 00493 if (isAllUploaded) 00494 return true; 00495 } 00496 } 00497 00498 00499 // try to upload all mipmap 00500 for(; _CurrentUploadTextureMipMap<nMipMap; _CurrentUploadTextureMipMap++) 00501 { 00502 CRect zeRect; 00503 uint nMM= _CurrentUploadTextureMipMap; 00504 00505 // What is left to upload ? 00506 uint nWeight = pText->getSize (nMM) - _CurrentUploadTextureLine*pText->getWidth(nMM); 00507 nWeight= (nWeight*CBitmap::bitPerPixels[pText->getPixelFormat()])/8; 00508 00509 if ((nTotalUploaded + nWeight) > _MaxUploadPerFrame) 00510 { 00511 // We cannot upload the whole mipmap -> we have to cut it 00512 uint nSizeToUpload = _MaxUploadPerFrame - nTotalUploaded ; 00513 // DXTC => min block of 4x4 00514 uint nLineWeight = (max(pText->getWidth(nMM), (uint32)4)*CBitmap::bitPerPixels[pText->getPixelFormat()])/8; 00515 uint nNbLineToUpload = nSizeToUpload / nLineWeight; 00516 // Upload 4 line by 4 line, and upload at leat one 4*line. 00517 nNbLineToUpload = nNbLineToUpload / 4; 00518 nNbLineToUpload= max(nNbLineToUpload, 1U); 00519 nNbLineToUpload *= 4; 00520 // comput rect to upload 00521 uint32 nNewLine = _CurrentUploadTextureLine + nNbLineToUpload; 00522 nNewLine= min(nNewLine, pText->getHeight(nMM)); 00523 zeRect.set (0, _CurrentUploadTextureLine, pText->getWidth(nMM), nNewLine); 00524 _CurrentUploadTextureLine = nNewLine; 00525 // if fill all the mipmap, must go to next 00526 if (_CurrentUploadTextureLine == pText->getHeight(nMM)) 00527 { 00528 _CurrentUploadTextureLine = 0; 00529 _CurrentUploadTextureMipMap++; 00530 } 00531 } 00532 else 00533 { 00534 // We can upload the whole mipmap (or the whole rest of the mipmap) 00535 zeRect.set (0, _CurrentUploadTextureLine, pText->getWidth(nMM), pText->getHeight(nMM)); 00536 _CurrentUploadTextureLine= 0; 00537 } 00538 00539 // upload the texture 00540 pDriver->uploadTexture (*pText, zeRect, (uint8)nMM); 00541 00542 nTotalUploaded += nWeight; 00543 // If outpass max allocated upload, abort. 00544 if (nTotalUploaded > _MaxUploadPerFrame) 00545 return false; 00546 } 00547 00548 return true; 00549 } |
|
Definition at line 619 of file async_texture_manager.cpp. References NLMISC::CBitmap::getMipMapCount(), and NLMISC::CBitmap::getPixelFormat(). Referenced by update(), and uploadTexturePart().
00620 {
00621 return pText->getMipMapCount()>1 && (
00622 pText->getPixelFormat() == CBitmap::DXTC1 ||
00623 pText->getPixelFormat() == CBitmap::DXTC1Alpha ||
00624 pText->getPixelFormat() == CBitmap::DXTC3 ||
00625 pText->getPixelFormat() == CBitmap::DXTC5 );
00626 }
|
|
Definition at line 213 of file async_texture_manager.h. Referenced by addTextureRef(), CAsyncTextureManager(), setupLod(), and update(). |
|
Definition at line 232 of file async_texture_manager.h. Referenced by CAsyncTextureManager(), deleteTexture(), getNextTextureToUpLoad(), update(), updateTextureLodSystem(), and ~CAsyncTextureManager(). |
|
Definition at line 227 of file async_texture_manager.h. Referenced by CAsyncTextureManager(), deleteTexture(), getNextTextureToUpLoad(), update(), and ~CAsyncTextureManager(). |
|
Definition at line 229 of file async_texture_manager.h. Referenced by getNextTextureToUpLoad(), and uploadTexturePart(). |
|
Definition at line 228 of file async_texture_manager.h. Referenced by getNextTextureToUpLoad(), and uploadTexturePart(). |
|
Definition at line 222 of file async_texture_manager.h. Referenced by addTextureRef(), and deleteTexture(). |
|
Definition at line 218 of file async_texture_manager.h. Referenced by CAsyncTextureManager(), getLastTextureSizeGot(), and updateTextureLodSystem(). |
|
Definition at line 215 of file async_texture_manager.h. Referenced by CAsyncTextureManager(), getNextTextureToUpLoad(), and setupMaxHLSColoringPerFrame(). |
|
Definition at line 213 of file async_texture_manager.h. Referenced by CAsyncTextureManager(), setupLod(), and update(). |
|
Definition at line 216 of file async_texture_manager.h. Referenced by CAsyncTextureManager(), setupMaxTotalTextureSize(), and updateTextureLodSystem(). |
|
Definition at line 214 of file async_texture_manager.h. Referenced by CAsyncTextureManager(), setupMaxUploadPerFrame(), and uploadTexturePart(). |
|
Definition at line 221 of file async_texture_manager.h. Referenced by addTextureRef(), deleteTexture(), getCoarseBitmap(), getNextTextureToUpLoad(), isTextureUpLoaded(), releaseTexture(), updateTextureLodSystem(), and ~CAsyncTextureManager(). |
|
Definition at line 223 of file async_texture_manager.h. Referenced by addTextureRef(), deleteTexture(), and ~CAsyncTextureManager(). |
|
Definition at line 217 of file async_texture_manager.h. Referenced by CAsyncTextureManager(), deleteTexture(), getTotalTextureSizeAsked(), and update(). |
|
Definition at line 224 of file async_texture_manager.h. Referenced by addTextureRef(), deleteTexture(), getNextTextureToUpLoad(), and ~CAsyncTextureManager(). |
|
User is free to add bank to this manager. Other methods are used by the async manager.
Definition at line 57 of file async_texture_manager.h. Referenced by addTextureRef(), getNextTextureToUpLoad(), and NL3D::CDriverUser::loadHLSBank(). |