separate "low res loaded on startup" and "low res loaded on demand" banner modes

This commit is contained in:
Glenn Maynard
2005-03-08 01:39:32 +00:00
parent bd7f89455d
commit eadd3b3edb
9 changed files with 118 additions and 31 deletions
+74 -17
View File
@@ -1,11 +1,13 @@
#include "global.h"
#include "arch/arch.h"
#include "Foreach.h"
#include "RageDisplay.h"
#include "RageUtil.h"
#include "RageLog.h"
#include "RageSurface_Load.h"
#include "BannerCache.h"
#include "SongCacheIndex.h"
#include "Sprite.h"
#include "PrefsManager.h"
#include "RageDisplay.h"
@@ -46,17 +48,66 @@ BannerCache *BANNERCACHE;
static map<CString,RageSurface *> g_BannerPathToImage;
static int g_iDemandRefcount = 0;
CString BannerCache::GetBannerCachePath( CString BannerPath )
{
/* Use GetHashForString, not ForFile, since we don't want to spend time
* checking the file size and date. */
return ssprintf( CACHE_DIR "Banners/%u", GetHashForString(BannerPath) );
return SongCacheIndex::GetCacheFilePath( "Banners", BannerPath );
}
/* If in on-demand mode, load all cached banners. This must be fast, so
* cache files will not be created if they don't exist; that should be done
* by CacheBanner or LoadBanner on startup. */
void BannerCache::Demand()
{
++g_iDemandRefcount;
if( g_iDemandRefcount > 1 )
return;
if( PREFSMAN->m_iBannerCache != PrefsManager::BNCACHE_LOW_RES_LOAD_ON_DEMAND )
return;
FOREACH_Child( &BannerData, p )
{
CString sBannerPath = p->m_sName;
if( g_BannerPathToImage.find(sBannerPath) != g_BannerPathToImage.end() )
continue; /* already loaded */
const CString CachePath = GetBannerCachePath(sBannerPath);
RageSurface *img = RageSurfaceUtils::LoadSurface( CachePath );
if( img == NULL )
{
continue; /* doesn't exist */
}
g_BannerPathToImage[sBannerPath] = img;
}
}
/* Release banners loaded on demand. */
void BannerCache::Undemand()
{
--g_iDemandRefcount;
if( g_iDemandRefcount != 0 )
return;
if( PREFSMAN->m_iBannerCache != PrefsManager::BNCACHE_LOW_RES_LOAD_ON_DEMAND )
return;
UnloadAllBanners();
}
/* If in a low-res banner mode, load a low-res banner into memory, creating
* the cache file if necessary. Unlike CacheBanner(), the original file will
* not be examined unless the cached banner doesn't exist, so the banner will
* not be updated if the original file changes, for efficiency. */
void BannerCache::LoadBanner( CString BannerPath )
{
if( PREFSMAN->m_iBannerCache != PrefsManager::BNCACHE_LOW_RES || BannerPath == "" )
if( BannerPath == "" )
return; // nothing to do
if( PREFSMAN->m_iBannerCache != PrefsManager::BNCACHE_LOW_RES_PRELOAD &&
PREFSMAN->m_iBannerCache != PrefsManager::BNCACHE_LOW_RES_LOAD_ON_DEMAND )
return;
/* Load it. */
@@ -205,6 +256,7 @@ struct BannerTexture: public RageTexture
}
};
/* If a banner is cached, get its ID for use. */
RageTextureID BannerCache::LoadCachedBanner( CString BannerPath )
{
RageTextureID ID( GetBannerCachePath(BannerPath) );
@@ -272,11 +324,12 @@ static inline int closest( int num, int n1, int n2 )
return n1;
}
/* We write the cache even if we won't use it, so we don't have to recache everything
* if the memory or settings change. */
/* Create or update the banner cache file as necessary. If in preload mode,
* load the cache file, too. (This is done at startup.) */
void BannerCache::CacheBanner( CString BannerPath )
{
if( PREFSMAN->m_iBannerCache != PrefsManager::BNCACHE_LOW_RES )
if( PREFSMAN->m_iBannerCache != PrefsManager::BNCACHE_LOW_RES_PRELOAD &&
PREFSMAN->m_iBannerCache != PrefsManager::BNCACHE_LOW_RES_LOAD_ON_DEMAND )
return;
CHECKPOINT_M( BannerPath );
@@ -293,12 +346,16 @@ void BannerCache::CacheBanner( CString BannerPath )
if( BannerData.GetValue( BannerPath, "FullHash", CurFullHash ) &&
CurFullHash == FullHash )
{
/* It's identical. Just load it. */
LoadBanner( BannerPath );
/* It's identical. Just load it, if in preload. */
if( PREFSMAN->m_iBannerCache == PrefsManager::BNCACHE_LOW_RES_PRELOAD )
LoadBanner( BannerPath );
return;
}
}
/* The cache file doesn't exist, or is out of date. Cache it. This
* will also load the cache into memory if in PRELOAD. */
CacheBannerInternal( BannerPath );
}
@@ -412,16 +469,16 @@ void BannerCache::CacheBannerInternal( CString BannerPath )
const CString CachePath = GetBannerCachePath(BannerPath);
RageSurfaceUtils::SaveSurface( img, CachePath );
if( PREFSMAN->m_iBannerCache == PrefsManager::BNCACHE_LOW_RES )
/* If an old image is loaded, free it. */
if( g_BannerPathToImage.find(BannerPath) != g_BannerPathToImage.end() )
{
/* If an old image is loaded, free it. */
if( g_BannerPathToImage.find(BannerPath) != g_BannerPathToImage.end() )
{
RageSurface *oldimg = g_BannerPathToImage[BannerPath];
delete oldimg;
g_BannerPathToImage.erase(BannerPath);
}
RageSurface *oldimg = g_BannerPathToImage[BannerPath];
delete oldimg;
g_BannerPathToImage.erase(BannerPath);
}
if( PREFSMAN->m_iBannerCache == PrefsManager::BNCACHE_LOW_RES_PRELOAD )
{
/* Keep it; we're just going to load it anyway. */
g_BannerPathToImage[BannerPath] = img;
}
+4 -2
View File
@@ -22,10 +22,12 @@ public:
~BannerCache();
RageTextureID LoadCachedBanner( CString BannerPath );
void CacheBanner( CString BannerPath );
void UncacheBanner( CString BannerPath );
void LoadBanner( CString BannerPath );
void Demand();
void Undemand();
void OutputStats() const;
};
+1 -1
View File
@@ -88,7 +88,7 @@ PrefsManager::PrefsManager() :
m_bTexturePreload ( Options, "TexturePreload", false ),
m_bDelayedScreenLoad ( Options, "DelayedScreenLoad", false ),
m_bDelayedModelDelete ( Options, "DelayedModelDelete", false ),
m_iBannerCache ( Options, "BannerCache", BNCACHE_LOW_RES ),
m_iBannerCache ( Options, "BannerCache", BNCACHE_LOW_RES_PRELOAD ),
m_bPalettedBannerCache ( Options, "PalettedBannerCache", false ),
m_bFastLoad ( Options, "FastLoad", true ),
+4 -1
View File
@@ -43,7 +43,10 @@ public:
Preference<bool> m_bTexturePreload;
Preference<bool> m_bDelayedScreenLoad;
Preference<bool> m_bDelayedModelDelete;
enum { BNCACHE_OFF, BNCACHE_LOW_RES, BNCACHE_FULL };
enum { BNCACHE_OFF,
BNCACHE_LOW_RES_PRELOAD, // preload low-res on start
BNCACHE_LOW_RES_LOAD_ON_DEMAND, // preload low-res on screen load
BNCACHE_FULL };
Preference<int> m_iBannerCache;
Preference<bool> m_bPalettedBannerCache;
Preference<bool> m_bFastLoad;
+25 -8
View File
@@ -27,6 +27,7 @@
#include "PlayerState.h"
#include "Command.h"
#include "CommonMetrics.h"
#include "BannerCache.h"
const int NUM_SCORE_DIGITS = 9;
@@ -89,6 +90,9 @@ void ScreenSelectMusic::Init()
if( GAMESTATE->m_PlayMode == PLAY_MODE_INVALID )
RageException::Throw( "The PlayMode has not been set. A theme must set the PlayMode before loading ScreenSelectMusic." );
/* Load low-res banners, if needed. */
BANNERCACHE->Demand();
m_MusicWheel.Load();
// pop'n music has this under the songwheel...
@@ -341,6 +345,7 @@ void ScreenSelectMusic::Init()
ScreenSelectMusic::~ScreenSelectMusic()
{
LOG->Trace( "ScreenSelectMusic::~ScreenSelectMusic()" );
BANNERCACHE->Undemand();
}
@@ -681,18 +686,25 @@ void ScreenSelectMusic::CheckBackgroundRequests()
if( g_bBannerWaiting )
{
float HighQualTime = m_Banner.GetFadeSeconds();
if( g_StartedLoadingAt.Ago() < HighQualTime )
return;
CString sPath;
if( g_StartedLoadingAt.Ago() >= HighQualTime && m_BackgroundLoader.IsCacheFileFinished(g_sBannerPath, sPath) )
if( TEXTUREMAN->IsTextureRegistered( Sprite::SongBannerTexture(g_sBannerPath) ) )
{
g_bBannerWaiting = false;
RageTimer foo;
m_Banner.Load( sPath );
m_BackgroundLoader.FinishedWithCachedFile( g_sBannerPath );
/* If the file is already loaded into a texture, it's finished,
* and we only do this to honor the HighQualTime value. */
sPath = g_sBannerPath;
}
else
return;
{
if( !m_BackgroundLoader.IsCacheFileFinished( g_sBannerPath, sPath ) )
return;
m_BackgroundLoader.FinishedWithCachedFile( g_sBannerPath );
}
g_bBannerWaiting = false;
m_Banner.Load( sPath );
}
/* Nothing else is going. Start the music, if we havn't yet. */
@@ -1679,7 +1691,12 @@ void ScreenSelectMusic::AfterMusicChange()
LOG->Trace("LoadFromCachedBanner(%s)",g_sBannerPath .c_str());
if( m_Banner.LoadFromCachedBanner( g_sBannerPath ) )
{
m_BackgroundLoader.CacheFile( g_sBannerPath );
/* If the high-res banner is already loaded, just
* delay before loading it, so the low-res one has
* time to fade in. */
if( !TEXTUREMAN->IsTextureRegistered( Sprite::SongBannerTexture(g_sBannerPath) ) )
m_BackgroundLoader.CacheFile( g_sBannerPath );
g_bBannerWaiting = true;
}
}
+1 -1
View File
@@ -147,7 +147,7 @@ CString Song::GetBackgroundAtBeat( float fBeat ) const
CString Song::GetCacheFilePath() const
{
return ssprintf( CACHE_DIR "Songs/%u", GetHashForString(m_sSongDir) );
return SongCacheIndex::GetCacheFilePath( "Songs", m_sSongDir );
}
/* Get a path to the SM containing data for this song. It might
+7
View File
@@ -29,6 +29,13 @@
SongCacheIndex *SONGINDEX;
CString SongCacheIndex::GetCacheFilePath( const CString &sGroup, const CString &sPath )
{
/* Use GetHashForString, not ForFile, since we don't want to spend time
* checking the file size and date. */
return ssprintf( "%s/%s/%u", CACHE_DIR, sGroup.c_str(), GetHashForString(sPath) );
}
SongCacheIndex::SongCacheIndex()
{
ReadCacheIndex();
+1
View File
@@ -11,6 +11,7 @@ class SongCacheIndex
public:
SongCacheIndex();
~SongCacheIndex();
static CString GetCacheFilePath( const CString &sGroup, const CString &sPath );
void ReadCacheIndex();
void AddCacheIndex( const CString &path, unsigned hash );
+1 -1
View File
@@ -355,7 +355,7 @@ static void CheckSettings()
/* Preloaded banners takes about 9k per song. Although it's smaller than the
* actual song data, it still adds up with a lot of songs. Disable it for 64-meg
* systems. */
PREFSMAN->m_iBannerCache = LowMemory ? PrefsManager::BNCACHE_OFF:PrefsManager::BNCACHE_LOW_RES;
PREFSMAN->m_iBannerCache = LowMemory ? PrefsManager::BNCACHE_OFF:PrefsManager::BNCACHE_LOW_RES_PRELOAD;
PREFSMAN->SaveGlobalPrefsToDisk();
#endif