diff options
author | Mnikolenko Productengine <mnikolenko@productengine.com> | 2020-11-12 20:44:17 +0200 |
---|---|---|
committer | Mnikolenko Productengine <mnikolenko@productengine.com> | 2020-11-12 20:44:17 +0200 |
commit | 27117cd8e4a94542994764ac23d555b919d270b8 (patch) | |
tree | 2c43c81fd002e87a6349967b1757f45cb6be6886 | |
parent | 9b1d9150c23ac378623e6222c742753d6dc39070 (diff) |
SL-14269 FIXED Textures are corrupt after reducing the cache size.
-rw-r--r-- | indra/newview/lltexturecache.cpp | 46 |
1 files changed, 18 insertions, 28 deletions
diff --git a/indra/newview/lltexturecache.cpp b/indra/newview/lltexturecache.cpp index 6211d0ce3b..963e942375 100644 --- a/indra/newview/lltexturecache.cpp +++ b/indra/newview/lltexturecache.cpp @@ -54,6 +54,7 @@ const F32 TEXTURE_CACHE_LRU_SIZE = .10f; // % amount for LRU list (low overhead 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 F32 TEXTURE_LAZY_PURGE_TIME_LIMIT = .004f; // 4ms. Would be better to autoadjust, but there is a major cache rework in progress. +const F32 TEXTURE_PRUNING_MAX_TIME = 15.f; class LLTextureCacheWorker : public LLWorkerClass { @@ -1550,7 +1551,6 @@ void LLTextureCache::readHeaderCache() if (num_entries - empty_entries > sCacheMaxEntries) { // Special case: cache size was reduced, need to remove entries - // Note: After we prune entries, we will call this again and create the LRU U32 entries_to_purge = (num_entries - empty_entries) - sCacheMaxEntries; LL_INFOS() << "Texture Cache Entries: " << num_entries << " Max: " << sCacheMaxEntries << " Empty: " << empty_entries << " Purging: " << entries_to_purge << LL_ENDL; // We can exit the following loop with the given condition, since if we'd reach the end of the lru set we'd have: @@ -1563,7 +1563,7 @@ void LLTextureCache::readHeaderCache() ++iter; } } - else + { S32 lru_entries = (S32)((F32)sCacheMaxEntries * TEXTURE_CACHE_LRU_SIZE); for (std::set<lru_data_t>::iterator iter = lru.begin(); iter != lru.end(); ++iter) @@ -1577,30 +1577,19 @@ void LLTextureCache::readHeaderCache() if (purge_list.size() > 0) { + LLTimer timer; for (std::set<U32>::iterator iter = purge_list.begin(); iter != purge_list.end(); ++iter) { std::string tex_filename = getTextureFileName(entries[*iter].mID); removeEntry((S32)*iter, entries[*iter], tex_filename); - } - // If we removed any entries, we need to rebuild the entries list, - // write the header, and call this again - std::vector<Entry> new_entries; - for (U32 i=0; i<num_entries; i++) - { - const Entry& entry = entries[i]; - if (entry.mImageSize > 0) + + //make sure that pruning entries doesn't take too much time + if (timer.getElapsedTimeF32() > TEXTURE_PRUNING_MAX_TIME) { - new_entries.push_back(entry); + break; } } - mFreeList.clear(); // recreating list, no longer valid. - llassert_always(new_entries.size() <= sCacheMaxEntries); - mHeaderEntriesInfo.mEntries = new_entries.size(); - writeEntriesHeader(); - writeEntriesAndClose(new_entries); - mHeaderMutex.unlock(); // unlock the mutex before calling again - readHeaderCache(); // repeat with new entries file - mHeaderMutex.lock(); + writeEntriesAndClose(entries); } else { @@ -1723,7 +1712,7 @@ void LLTextureCache::purgeTexturesLazy(F32 time_limit_sec) } S64 cache_size = mTexturesSizeTotal; - S64 purged_cache_size = (sCacheMaxTexturesSize * (S64)((1.f - TEXTURE_CACHE_PURGE_AMOUNT) * 100)) / 100; + S64 purged_cache_size = (llmax(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) { @@ -1819,21 +1808,26 @@ void LLTextureCache::purgeTextures(bool validate) } S64 cache_size = mTexturesSizeTotal; - S64 purged_cache_size = (sCacheMaxTexturesSize * (S64)((1.f-TEXTURE_CACHE_PURGE_AMOUNT)*100)) / 100; + S64 purged_cache_size = (llmax(cache_size, sCacheMaxTexturesSize) * (S64)((1.f - TEXTURE_CACHE_PURGE_AMOUNT) * 100)) / 100; S32 purge_count = 0; for (time_idx_set_t::iterator iter = time_idx_set.begin(); iter != time_idx_set.end(); ++iter) { S32 idx = iter->second; bool purge_entry = false; - if (validate) + + if (cache_size >= purged_cache_size) + { + purge_entry = true; + } + else if (validate) { // make sure file exists and is the correct size U32 uuididx = entries[idx].mID.mData[0]; if (uuididx == validate_idx) { - std::string filename = getTextureFileName(entries[idx].mID); - LL_DEBUGS("TextureCache") << "Validating: " << filename << "Size: " << entries[idx].mBodySize << LL_ENDL; + std::string filename = getTextureFileName(entries[idx].mID); + LL_DEBUGS("TextureCache") << "Validating: " << filename << "Size: " << entries[idx].mBodySize << LL_ENDL; // mHeaderAPRFilePoolp because this is under header mutex in main thread S32 bodysize = LLAPRFile::size(filename, mHeaderAPRFilePoolp); if (bodysize != entries[idx].mBodySize) @@ -1843,10 +1837,6 @@ void LLTextureCache::purgeTextures(bool validate) } } } - else if (cache_size >= purged_cache_size) - { - purge_entry = true; - } else { break; |