Skip to content
Snippets Groups Projects
Commit 09540c8c authored by andreykproductengine's avatar andreykproductengine
Browse files

SL-775 SL-11418 Texture cache purge stalls viewer

parent 24fedef5
No related branches found
No related tags found
No related merge requests found
...@@ -53,6 +53,7 @@ const F32 TEXTURE_CACHE_PURGE_AMOUNT = .20f; // % amount to reduce the cache by ...@@ -53,6 +53,7 @@ const F32 TEXTURE_CACHE_PURGE_AMOUNT = .20f; // % amount to reduce the cache by
const F32 TEXTURE_CACHE_LRU_SIZE = .10f; // % amount for LRU list (low overhead to regenerate) const F32 TEXTURE_CACHE_LRU_SIZE = .10f; // % amount for LRU list (low overhead to regenerate)
const S32 TEXTURE_FAST_CACHE_ENTRY_OVERHEAD = sizeof(S32) * 4; //w, h, c, level const S32 TEXTURE_FAST_CACHE_ENTRY_OVERHEAD = sizeof(S32) * 4; //w, h, c, level
const S32 TEXTURE_FAST_CACHE_ENTRY_SIZE = 16 * 16 * 4 + TEXTURE_FAST_CACHE_ENTRY_OVERHEAD; const S32 TEXTURE_FAST_CACHE_ENTRY_SIZE = 16 * 16 * 4 + TEXTURE_FAST_CACHE_ENTRY_OVERHEAD;
const F32 TEXTURE_LAZY_PURGE_TIME_LIMIT = .005f; // 5ms
class LLTextureCacheWorker : public LLWorkerClass class LLTextureCacheWorker : public LLWorkerClass
{ {
...@@ -1669,6 +1670,90 @@ void LLTextureCache::purgeAllTextures(bool purge_directories) ...@@ -1669,6 +1670,90 @@ void LLTextureCache::purgeAllTextures(bool purge_directories)
LL_INFOS() << "The entire texture cache is cleared." << LL_ENDL ; LL_INFOS() << "The entire texture cache is cleared." << LL_ENDL ;
} }
void LLTextureCache::purgeTexturesLazy(F32 time_limit_sec)
{
if (mReadOnly)
{
return;
}
if (!mThreaded)
{
LLAppViewer::instance()->pauseMainloopTimeout();
}
// time_limit doesn't account for lock time
LLMutexLock lock(&mHeaderMutex);
if (mPurgeEntryList.empty())
{
// Read the entries list and form list of textures to purge
std::vector<Entry> entries;
U32 num_entries = openAndReadEntries(entries);
if (!num_entries)
{
return; // nothing to purge
}
// Use mTexturesSizeMap to collect UUIDs of textures with bodies
typedef std::set<std::pair<U32, S32> > time_idx_set_t;
std::set<std::pair<U32, S32> > time_idx_set;
for (size_map_t::iterator iter1 = mTexturesSizeMap.begin();
iter1 != mTexturesSizeMap.end(); ++iter1)
{
if (iter1->second > 0)
{
id_map_t::iterator iter2 = mHeaderIDMap.find(iter1->first);
if (iter2 != mHeaderIDMap.end())
{
S32 idx = iter2->second;
time_idx_set.insert(std::make_pair(entries[idx].mTime, idx));
}
else
{
LL_ERRS("TextureCache") << "mTexturesSizeMap / mHeaderIDMap corrupted." << LL_ENDL;
}
}
}
S64 cache_size = mTexturesSizeTotal;
S64 purged_cache_size = (sCacheMaxTexturesSize * (S64)((1.f - TEXTURE_CACHE_PURGE_AMOUNT) * 100)) / 100;
for (time_idx_set_t::iterator iter = time_idx_set.begin();
iter != time_idx_set.end(); ++iter)
{
S32 idx = iter->second;
if (cache_size >= purged_cache_size)
{
cache_size -= entries[idx].mBodySize;
mPurgeEntryList.push_back(std::pair<S32, Entry>(idx, entries[idx]));
}
else
{
break;
}
}
LL_DEBUGS("TextureCache") << "Formed Purge list of " << mPurgeEntryList.size() << " entries" << LL_ENDL;
}
else
{
// Remove collected entried
LLTimer timer;
while (!mPurgeEntryList.empty() && timer.getElapsedTimeF32() < time_limit_sec)
{
S32 idx = mPurgeEntryList.back().first;
Entry entry = mPurgeEntryList.back().second;
mPurgeEntryList.pop_back();
// make sure record is still valid
id_map_t::iterator iter_header = mHeaderIDMap.find(entry.mID);
if (iter_header != mHeaderIDMap.end() && iter_header->second == idx)
{
removeEntry(idx, entry, getTextureFileName(entry.mID));
writeEntryToHeaderImmediately(idx, entry);
}
}
}
}
void LLTextureCache::purgeTextures(bool validate) void LLTextureCache::purgeTextures(bool validate)
{ {
if (mReadOnly) if (mReadOnly)
...@@ -1928,11 +2013,10 @@ LLTextureCache::handle_t LLTextureCache::writeToCache(const LLUUID& id, U32 prio ...@@ -1928,11 +2013,10 @@ LLTextureCache::handle_t LLTextureCache::writeToCache(const LLUUID& id, U32 prio
} }
if (mDoPurge) if (mDoPurge)
{ {
// NOTE: This may cause an occasional hiccup, // NOTE: Needs to be done on the control thread
// but it really needs to be done on the control thread // (i.e. here)
// (i.e. here) purgeTexturesLazy(TEXTURE_LAZY_PURGE_TIME_LIMIT);
purgeTextures(false); mDoPurge = !mPurgeEntryList.empty();
mDoPurge = FALSE;
} }
LLMutexLock lock(&mWorkersMutex); LLMutexLock lock(&mWorkersMutex);
LLTextureCacheWorker* worker = new LLTextureCacheRemoteWorker(this, priority, id, LLTextureCacheWorker* worker = new LLTextureCacheRemoteWorker(this, priority, id,
......
...@@ -155,6 +155,7 @@ class LLTextureCache : public LLWorkerThread ...@@ -155,6 +155,7 @@ class LLTextureCache : public LLWorkerThread
void readHeaderCache(); void readHeaderCache();
void clearCorruptedCache(); void clearCorruptedCache();
void purgeAllTextures(bool purge_directories); void purgeAllTextures(bool purge_directories);
void purgeTexturesLazy(F32 time_limit_sec);
void purgeTextures(bool validate); void purgeTextures(bool validate);
LLAPRFile* openHeaderEntriesFile(bool readonly, S32 offset); LLAPRFile* openHeaderEntriesFile(bool readonly, S32 offset);
void closeHeaderEntriesFile(); void closeHeaderEntriesFile();
...@@ -225,6 +226,8 @@ class LLTextureCache : public LLWorkerThread ...@@ -225,6 +226,8 @@ class LLTextureCache : public LLWorkerThread
typedef std::map<S32, Entry> idx_entry_map_t; typedef std::map<S32, Entry> idx_entry_map_t;
idx_entry_map_t mUpdatedEntryMap; idx_entry_map_t mUpdatedEntryMap;
typedef std::vector<std::pair<S32, Entry>> idx_entry_vector_t;
idx_entry_vector_t mPurgeEntryList;
// Statics // Statics
static F32 sHeaderCacheVersion; static F32 sHeaderCacheVersion;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment