NL3D::CAsyncTextureManager Class Reference

#include <async_texture_manager.h>


Detailed Description

Async Loader of textures and Texture Load Balancer. Additionaly, store in RAM for each texture load a very low, DXTC1 compressed version of the texture. Used for some Lod systems.
Author:
Lionel Berenguier

Nevrax France

Date:
2002

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::CBitmapgetCoarseBitmap (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


Member Typedef Documentation

typedef TTextureEntryMap::iterator NL3D::CAsyncTextureManager::ItTextureEntryMap [private]
 

Definition at line 122 of file async_texture_manager.h.

Referenced by addTextureRef().

typedef std::map<std::string, uint> NL3D::CAsyncTextureManager::TTextureEntryMap [private]
 

Definition at line 121 of file async_texture_manager.h.


Constructor & Destructor Documentation

NL3D::CAsyncTextureManager::CAsyncTextureManager  ) 
 

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 }

NL3D::CAsyncTextureManager::~CAsyncTextureManager  ) 
 

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 }


Member Function Documentation

uint NL3D::CAsyncTextureManager::addTextureRef const std::string &  textName,
CMeshBaseInstance instance,
const NLMISC::CVector position
 

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 }

void NL3D::CAsyncTextureManager::deleteTexture uint  id  )  [private]
 

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 }

const NLMISC::CBitmap * NL3D::CAsyncTextureManager::getCoarseBitmap uint  id  )  const
 

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 }

uint NL3D::CAsyncTextureManager::getLastTextureSizeGot  )  const [inline]
 

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;}

void NL3D::CAsyncTextureManager::getNextTextureToUpLoad uint nTotalColored,
IDriver pDriver
[private]
 

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 }

uint NL3D::CAsyncTextureManager::getTotalTextureSizeAsked  )  const [inline]
 

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;}

bool NL3D::CAsyncTextureManager::isTextureUpLoaded uint  id  )  const
 

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 }

void NL3D::CAsyncTextureManager::releaseTexture uint  id,
CMeshBaseInstance instance
 

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 }

void NL3D::CAsyncTextureManager::setupLod uint  baseLevel,
uint  maxLevel
 

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 }

void NL3D::CAsyncTextureManager::setupMaxHLSColoringPerFrame uint  maxCol  ) 
 

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 }

void NL3D::CAsyncTextureManager::setupMaxTotalTextureSize uint  maxText  ) 
 

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 }

void NL3D::CAsyncTextureManager::setupMaxUploadPerFrame uint  maxup  ) 
 

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 }

void NL3D::CAsyncTextureManager::update IDriver pDriver  ) 
 

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 }

void NL3D::CAsyncTextureManager::updateTextureLodSystem IDriver pDriver  )  [private]
 

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 }

bool NL3D::CAsyncTextureManager::uploadTexturePart ITexture pText,
IDriver pDriver,
uint nTotalUpload
[private]
 

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 }

bool NL3D::CAsyncTextureManager::validDXTCMipMap ITexture pText  )  [static, private]
 

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 }


Field Documentation

uint NL3D::CAsyncTextureManager::_BaseLodLevel [private]
 

Definition at line 213 of file async_texture_manager.h.

Referenced by addTextureRef(), CAsyncTextureManager(), setupLod(), and update().

CTextureLod* NL3D::CAsyncTextureManager::_CurrentTextureLodLoaded [private]
 

Definition at line 232 of file async_texture_manager.h.

Referenced by CAsyncTextureManager(), deleteTexture(), getNextTextureToUpLoad(), update(), updateTextureLodSystem(), and ~CAsyncTextureManager().

CTextureBase* NL3D::CAsyncTextureManager::_CurrentUploadTexture [private]
 

Definition at line 227 of file async_texture_manager.h.

Referenced by CAsyncTextureManager(), deleteTexture(), getNextTextureToUpLoad(), update(), and ~CAsyncTextureManager().

uint NL3D::CAsyncTextureManager::_CurrentUploadTextureLine [private]
 

Definition at line 229 of file async_texture_manager.h.

Referenced by getNextTextureToUpLoad(), and uploadTexturePart().

uint NL3D::CAsyncTextureManager::_CurrentUploadTextureMipMap [private]
 

Definition at line 228 of file async_texture_manager.h.

Referenced by getNextTextureToUpLoad(), and uploadTexturePart().

std::vector<uint> NL3D::CAsyncTextureManager::_FreeTextureIds [private]
 

Definition at line 222 of file async_texture_manager.h.

Referenced by addTextureRef(), and deleteTexture().

uint NL3D::CAsyncTextureManager::_LastTextureSizeGot [private]
 

Definition at line 218 of file async_texture_manager.h.

Referenced by CAsyncTextureManager(), getLastTextureSizeGot(), and updateTextureLodSystem().

uint NL3D::CAsyncTextureManager::_MaxHLSColoringPerFrame [private]
 

Definition at line 215 of file async_texture_manager.h.

Referenced by CAsyncTextureManager(), getNextTextureToUpLoad(), and setupMaxHLSColoringPerFrame().

uint NL3D::CAsyncTextureManager::_MaxLodLevel [private]
 

Definition at line 213 of file async_texture_manager.h.

Referenced by CAsyncTextureManager(), setupLod(), and update().

uint NL3D::CAsyncTextureManager::_MaxTotalTextureSize [private]
 

Definition at line 216 of file async_texture_manager.h.

Referenced by CAsyncTextureManager(), setupMaxTotalTextureSize(), and updateTextureLodSystem().

uint NL3D::CAsyncTextureManager::_MaxUploadPerFrame [private]
 

Definition at line 214 of file async_texture_manager.h.

Referenced by CAsyncTextureManager(), setupMaxUploadPerFrame(), and uploadTexturePart().

std::vector<CTextureEntry*> NL3D::CAsyncTextureManager::_TextureEntries [private]
 

Definition at line 221 of file async_texture_manager.h.

Referenced by addTextureRef(), deleteTexture(), getCoarseBitmap(), getNextTextureToUpLoad(), isTextureUpLoaded(), releaseTexture(), updateTextureLodSystem(), and ~CAsyncTextureManager().

TTextureEntryMap NL3D::CAsyncTextureManager::_TextureEntryMap [private]
 

Definition at line 223 of file async_texture_manager.h.

Referenced by addTextureRef(), deleteTexture(), and ~CAsyncTextureManager().

uint NL3D::CAsyncTextureManager::_TotalTextureSizeAsked [private]
 

Definition at line 217 of file async_texture_manager.h.

Referenced by CAsyncTextureManager(), deleteTexture(), getTotalTextureSizeAsked(), and update().

std::vector<uint> NL3D::CAsyncTextureManager::_WaitingTextures [private]
 

Definition at line 224 of file async_texture_manager.h.

Referenced by addTextureRef(), deleteTexture(), getNextTextureToUpLoad(), and ~CAsyncTextureManager().

CHLSTextureManager NL3D::CAsyncTextureManager::HLSManager
 

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().


The documentation for this class was generated from the following files:
Generated on Tue Mar 16 06:44:33 2004 for NeL by doxygen 1.3.6