Make texture policies explicit.
Never keep banner textures loaded. We'll be using enough memory with the preloads, and it's not needed.
This commit is contained in:
@@ -44,6 +44,7 @@ bool Banner::Load( RageTextureID ID )
|
|||||||
m_fPercentScrolling = 0;
|
m_fPercentScrolling = 0;
|
||||||
m_bScrolling = false;
|
m_bScrolling = false;
|
||||||
|
|
||||||
|
TEXTUREMAN->VolatileTexture( ID );
|
||||||
return CroppedSprite::Load( ID );
|
return CroppedSprite::Load( ID );
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -83,6 +83,8 @@ RageTexture::RageTexture( RageTextureID name ):
|
|||||||
// LOG->Trace( "RageTexture::RageTexture()" );
|
// LOG->Trace( "RageTexture::RageTexture()" );
|
||||||
|
|
||||||
m_iRefCount = 1;
|
m_iRefCount = 1;
|
||||||
|
m_Policy = TEX_DEFAULT;
|
||||||
|
m_bWasUsed = false;
|
||||||
|
|
||||||
// SetActualID();
|
// SetActualID();
|
||||||
m_iSourceWidth = m_iSourceHeight = 0;
|
m_iSourceWidth = m_iSourceHeight = 0;
|
||||||
|
|||||||
@@ -83,8 +83,10 @@ public:
|
|||||||
const RectF *GetTextureCoordRect( int frameNo ) const;
|
const RectF *GetTextureCoordRect( int frameNo ) const;
|
||||||
int GetNumFrames() const { return m_iFramesWide*m_iFramesHigh; }
|
int GetNumFrames() const { return m_iFramesWide*m_iFramesHigh; }
|
||||||
|
|
||||||
|
/* Used by RageTextureManager: */
|
||||||
|
enum TexPolicy { TEX_DEFAULT, TEX_CACHED, TEX_VOLATILE } m_Policy;
|
||||||
int m_iRefCount;
|
int m_iRefCount;
|
||||||
bool m_bCacheThis;
|
bool m_bWasUsed;
|
||||||
|
|
||||||
/* The ID that we were asked to load: */
|
/* The ID that we were asked to load: */
|
||||||
const RageTextureID &GetID() const { return m_ID; }
|
const RageTextureID &GetID() const { return m_ID; }
|
||||||
|
|||||||
@@ -10,17 +10,38 @@
|
|||||||
-----------------------------------------------------------------------------
|
-----------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* Texture policies:
|
||||||
|
*
|
||||||
|
* Default: When DelayedDelete is off, delete unused textures immediately.
|
||||||
|
* When on, only delete textures when we change themes, on DoDelayedDelete().
|
||||||
|
* This is what you get if you call LoadTexture() on a texture that isn't
|
||||||
|
* loaded.
|
||||||
|
*
|
||||||
|
* Cached: When DelayedDelete is off, delete unused textures when we change screens.
|
||||||
|
* When on, treat as Default. This is used to precache textures that aren't
|
||||||
|
* loaded immediately; use CacheTexture.
|
||||||
|
*
|
||||||
|
* Volatile: Delete unused textures once they've been used at least once. Ignore
|
||||||
|
* DelayedDelete.
|
||||||
|
*
|
||||||
|
* This is for banners. We don't want to load all low-quality banners in
|
||||||
|
* memory at once, since it might be ten megs of textures, and we don't
|
||||||
|
* *have* to, since we can reload them very quickly. We don't want to keep
|
||||||
|
* high quality textures in memory, either, although it's unlikely that a
|
||||||
|
* player could actually view all banners long enough to transition to them
|
||||||
|
* all in the course of one song select screen.
|
||||||
|
*
|
||||||
|
* If a texture is already loaded with a different policy, loading it again with
|
||||||
|
* Default is normal; keep the original policy. Other cases generally shouldn't
|
||||||
|
* happen, so warn and keep the original policy.
|
||||||
|
*/
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
// Includes
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
#include "RageTextureManager.h"
|
#include "RageTextureManager.h"
|
||||||
#include "RageBitmapTexture.h"
|
#include "RageBitmapTexture.h"
|
||||||
#include "arch/MovieTexture/MovieTexture.h"
|
#include "arch/MovieTexture/MovieTexture.h"
|
||||||
#include "RageUtil.h"
|
#include "RageUtil.h"
|
||||||
#include "RageLog.h"
|
#include "RageLog.h"
|
||||||
#include "RageException.h"
|
#include "RageException.h"
|
||||||
#include <time.h>
|
|
||||||
|
|
||||||
RageTextureManager* TEXTUREMAN = NULL;
|
RageTextureManager* TEXTUREMAN = NULL;
|
||||||
|
|
||||||
@@ -34,9 +55,6 @@ static CString GetExtension(const CString &fn)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
// constructor/destructor
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
RageTextureManager::RageTextureManager()
|
RageTextureManager::RageTextureManager()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@@ -94,7 +112,7 @@ void RageTextureManager::RegisterTexture( RageTextureID ID, RageTexture *pTextur
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Load and unload textures from disk.
|
// Load and unload textures from disk.
|
||||||
RageTexture* RageTextureManager::LoadTexture( RageTextureID ID )
|
RageTexture* RageTextureManager::LoadTextureInternal( RageTextureID ID )
|
||||||
{
|
{
|
||||||
Checkpoint( ssprintf( "RageTextureManager::LoadTexture(%s).", ID.filename.c_str() ) );
|
Checkpoint( ssprintf( "RageTextureManager::LoadTexture(%s).", ID.filename.c_str() ) );
|
||||||
|
|
||||||
@@ -127,10 +145,32 @@ RageTexture* RageTextureManager::LoadTexture( RageTextureID ID )
|
|||||||
return pTexture;
|
return pTexture;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Load a normal texture. Use this call to actually use a texture. */
|
||||||
|
RageTexture* RageTextureManager::LoadTexture( RageTextureID ID )
|
||||||
|
{
|
||||||
|
RageTexture* pTexture = LoadTextureInternal( ID );
|
||||||
|
if( pTexture )
|
||||||
|
pTexture->m_bWasUsed = true;
|
||||||
|
return pTexture;
|
||||||
|
}
|
||||||
|
|
||||||
void RageTextureManager::CacheTexture( RageTextureID ID )
|
void RageTextureManager::CacheTexture( RageTextureID ID )
|
||||||
{
|
{
|
||||||
RageTexture* pTexture = LoadTexture( ID );
|
RageTexture* pTexture = LoadTextureInternal( ID );
|
||||||
pTexture->m_bCacheThis |= true;
|
if( pTexture->m_Policy == RageTexture::TEX_DEFAULT )
|
||||||
|
pTexture->m_Policy = RageTexture::TEX_CACHED;
|
||||||
|
else if( pTexture->m_Policy != RageTexture::TEX_CACHED )
|
||||||
|
LOG->Warn( "RageTextureManager::CacheTexture(%s): texture is %i, which?", ID.filename.c_str());
|
||||||
|
UnloadTexture( pTexture );
|
||||||
|
}
|
||||||
|
|
||||||
|
void RageTextureManager::VolatileTexture( RageTextureID ID )
|
||||||
|
{
|
||||||
|
RageTexture* pTexture = LoadTextureInternal( ID );
|
||||||
|
if( pTexture->m_Policy == RageTexture::TEX_DEFAULT )
|
||||||
|
pTexture->m_Policy = RageTexture::TEX_VOLATILE;
|
||||||
|
else if( pTexture->m_Policy != RageTexture::TEX_VOLATILE )
|
||||||
|
LOG->Warn( "RageTextureManager::VolatileTexture(%s): texture is %i, which?", ID.filename.c_str());
|
||||||
UnloadTexture( pTexture );
|
UnloadTexture( pTexture );
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -153,10 +193,12 @@ void RageTextureManager::UnloadTexture( RageTexture *t )
|
|||||||
if( t->IsAMovie() )
|
if( t->IsAMovie() )
|
||||||
bDeleteThis = true;
|
bDeleteThis = true;
|
||||||
|
|
||||||
/* If m_bDelayedDelete, keep all textures around until we GC. If m_bCacheThis,
|
/* Delete normal textures immediately unless m_bDelayedDelete is is on. */
|
||||||
* keep this individual texture, even if m_bDelayedDelete is off. (Would
|
if( t->m_Policy == RageTexture::TEX_DEFAULT && !m_bDelayedDelete )
|
||||||
* "m_bDelayedDelete" be clearer as "m_bCacheAll"?) */
|
bDeleteThis = true;
|
||||||
if( !m_bDelayedDelete && !t->m_bCacheThis )
|
|
||||||
|
/* Delete volatile textures after they've been used at least once. */
|
||||||
|
if( t->m_bWasUsed )
|
||||||
bDeleteThis = true;
|
bDeleteThis = true;
|
||||||
|
|
||||||
if( bDeleteThis )
|
if( bDeleteThis )
|
||||||
@@ -200,8 +242,29 @@ void RageTextureManager::GarbageCollect( GCType type )
|
|||||||
continue; /* Can't unload textures that are still referenced. */
|
continue; /* Can't unload textures that are still referenced. */
|
||||||
|
|
||||||
bool bDeleteThis = false;
|
bool bDeleteThis = false;
|
||||||
if( type==cached_textures && !m_bDelayedDelete )
|
if( type==screen_changed )
|
||||||
|
{
|
||||||
|
switch( t->m_Policy )
|
||||||
|
{
|
||||||
|
case RageTexture::TEX_DEFAULT:
|
||||||
|
/* If m_bDelayedDelete, wait until delayed_delete. If !m_bDelayedDelete,
|
||||||
|
* it should have been deleted when it reached no references, but we
|
||||||
|
* might have just changed the preference. */
|
||||||
|
if( !m_bDelayedDelete )
|
||||||
bDeleteThis = true;
|
bDeleteThis = true;
|
||||||
|
break;
|
||||||
|
case RageTexture::TEX_CACHED:
|
||||||
|
if( !m_bDelayedDelete )
|
||||||
|
bDeleteThis = true;
|
||||||
|
break;
|
||||||
|
case RageTexture::TEX_VOLATILE:
|
||||||
|
bDeleteThis = true;
|
||||||
|
break;
|
||||||
|
default: ASSERT(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This happens when we change themes; free all textures. */
|
||||||
if( type==delayed_delete )
|
if( type==delayed_delete )
|
||||||
bDeleteThis = true;
|
bDeleteThis = true;
|
||||||
|
|
||||||
|
|||||||
@@ -15,9 +15,6 @@
|
|||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
// RageTextureManager Class Declarations
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
class RageTextureManager
|
class RageTextureManager
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -29,6 +26,7 @@ public:
|
|||||||
bool IsTextureRegistered( RageTextureID ID ) const;
|
bool IsTextureRegistered( RageTextureID ID ) const;
|
||||||
void RegisterTexture( RageTextureID ID, RageTexture *p );
|
void RegisterTexture( RageTextureID ID, RageTexture *p );
|
||||||
void CacheTexture( RageTextureID ID );
|
void CacheTexture( RageTextureID ID );
|
||||||
|
void VolatileTexture( RageTextureID ID );
|
||||||
void UnloadTexture( RageTexture *t );
|
void UnloadTexture( RageTexture *t );
|
||||||
void ReloadAll();
|
void ReloadAll();
|
||||||
|
|
||||||
@@ -38,7 +36,7 @@ public:
|
|||||||
int GetMaxTextureResolution() { return m_iMaxTextureResolution; };
|
int GetMaxTextureResolution() { return m_iMaxTextureResolution; };
|
||||||
|
|
||||||
// call this between Screens
|
// call this between Screens
|
||||||
void DeleteCachedTextures() { GarbageCollect(cached_textures); }
|
void DeleteCachedTextures() { GarbageCollect(screen_changed); }
|
||||||
|
|
||||||
// call this on switch theme
|
// call this on switch theme
|
||||||
void DoDelayedDelete() { GarbageCollect(delayed_delete); }
|
void DoDelayedDelete() { GarbageCollect(delayed_delete); }
|
||||||
@@ -50,13 +48,15 @@ public:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
void DeleteTexture( RageTexture *t );
|
void DeleteTexture( RageTexture *t );
|
||||||
enum GCType { cached_textures, delayed_delete };
|
enum GCType { screen_changed, delayed_delete };
|
||||||
void GarbageCollect( GCType type );
|
void GarbageCollect( GCType type );
|
||||||
|
|
||||||
int m_iTextureColorDepth;
|
int m_iTextureColorDepth;
|
||||||
bool m_bDelayedDelete;
|
bool m_bDelayedDelete;
|
||||||
int m_iMaxTextureResolution;
|
int m_iMaxTextureResolution;
|
||||||
|
|
||||||
|
RageTexture* LoadTextureInternal( RageTextureID ID );
|
||||||
|
|
||||||
std::map<RageTextureID, RageTexture*> m_mapPathToTexture;
|
std::map<RageTextureID, RageTexture*> m_mapPathToTexture;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user