aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--ChangeLog.txt7
-rw-r--r--linden/indra/newview/lltexturecache.cpp65
-rw-r--r--linden/indra/newview/lltexturecache.h5
3 files changed, 71 insertions, 6 deletions
diff --git a/ChangeLog.txt b/ChangeLog.txt
index e69de29..da78f78 100644
--- a/ChangeLog.txt
+++ b/ChangeLog.txt
@@ -0,0 +1,7 @@
12008-09-16 Nicholaz Beresford <nicholaz@blueflash.cc>
2
3 * linden/indra/newview/lltexturecache.cpp:
4 VWR-3878: Purging cache textures causes viewer to pause for many
5 seconds, with heavy disk activity.
6 * linden/indra/newview/lltexturecache.h:
7 Ditto.
diff --git a/linden/indra/newview/lltexturecache.cpp b/linden/indra/newview/lltexturecache.cpp
index 22cb6c1..0fbb3d9 100644
--- a/linden/indra/newview/lltexturecache.cpp
+++ b/linden/indra/newview/lltexturecache.cpp
@@ -881,6 +881,8 @@ LLTextureCache::LLTextureCache(bool threaded)
881 881
882LLTextureCache::~LLTextureCache() 882LLTextureCache::~LLTextureCache()
883{ 883{
884 purgeTextureFilesTimeSliced(TRUE); // force-flush all pending file deletes
885
884 apr_pool_destroy(mFileAPRPool); 886 apr_pool_destroy(mFileAPRPool);
885} 887}
886 888
@@ -1187,7 +1189,7 @@ void LLTextureCache::purgeTextures(bool validate)
1187 return; 1189 return;
1188 } 1190 }
1189 1191
1190 LL_DEBUGS("TextureCache") << "TEXTURE CACHE: Reading Entries..." << LL_ENDL; 1192 LL_DEBUGS("TextureCache") << "TEXTURE CACHE: Reading " << num_entries << " Entries from " << mTexturesDirEntriesFileName << LL_ENDL;
1191 1193
1192 std::map<LLUUID, S32> entry_idx_map; 1194 std::map<LLUUID, S32> entry_idx_map;
1193 S64 total_size = 0; 1195 S64 total_size = 0;
@@ -1216,7 +1218,7 @@ void LLTextureCache::purgeTextures(bool validate)
1216 LL_DEBUGS("TextureCache") << "TEXTURE CACHE: Validating: " << validate_idx << LL_ENDL; 1218 LL_DEBUGS("TextureCache") << "TEXTURE CACHE: Validating: " << validate_idx << LL_ENDL;
1217 } 1219 }
1218 1220
1219 S64 min_cache_size = (sCacheMaxTexturesSize * 9) / 10; 1221 S64 min_cache_size = sCacheMaxTexturesSize / 100 * 95;
1220 S32 purge_count = 0; 1222 S32 purge_count = 0;
1221 S32 next_idx = 0; 1223 S32 next_idx = 0;
1222 for (S32 idx=0; idx<num_entries; idx++) 1224 for (S32 idx=0; idx<num_entries; idx++)
@@ -1250,8 +1252,8 @@ void LLTextureCache::purgeTextures(bool validate)
1250 if (purge_entry) 1252 if (purge_entry)
1251 { 1253 {
1252 purge_count++; 1254 purge_count++;
1253 LL_DEBUGS("TextureCache") << "PURGING: " << filename << LL_ENDL; 1255 LL_DEBUGS("TextureCache") << "PURGING: " << filename << LL_ENDL;
1254 ll_apr_file_remove(filename, NULL); 1256 mFilesToDelete.push_back(filename);
1255 total_size -= entries[idx].mSize; 1257 total_size -= entries[idx].mSize;
1256 entries[idx].mSize = 0; 1258 entries[idx].mSize = 0;
1257 } 1259 }
@@ -1266,7 +1268,11 @@ void LLTextureCache::purgeTextures(bool validate)
1266 } 1268 }
1267 num_entries = next_idx; 1269 num_entries = next_idx;
1268 1270
1269 LL_DEBUGS("TextureCache") << "TEXTURE CACHE: Writing Entries: " << num_entries << LL_ENDL; 1271 mTimeLastFileDelete.reset();
1272
1273 LL_DEBUGS("TextureCache") << "TEXTURE CACHE: Writing Entries: "
1274 << num_entries << " (" << num_entries*sizeof(Entry)/1024 << "KB)"
1275 << LL_ENDL;
1270 1276
1271 ll_apr_file_remove(mTexturesDirEntriesFileName, NULL); 1277 ll_apr_file_remove(mTexturesDirEntriesFileName, NULL);
1272 ll_apr_file_write_ex(mTexturesDirEntriesFileName, NULL, 1278 ll_apr_file_write_ex(mTexturesDirEntriesFileName, NULL,
@@ -1289,10 +1295,53 @@ void LLTextureCache::purgeTextures(bool validate)
1289 LL_INFOS("TextureCache") << "TEXTURE CACHE:" 1295 LL_INFOS("TextureCache") << "TEXTURE CACHE:"
1290 << " PURGED: " << purge_count 1296 << " PURGED: " << purge_count
1291 << " ENTRIES: " << num_entries 1297 << " ENTRIES: " << num_entries
1292 << " CACHE SIZE: " << total_size / 1024*1024 << " MB" 1298 << " CACHE SIZE: " << total_size/1024/1024 << " MB"
1293 << llendl; 1299 << llendl;
1294} 1300}
1295 1301
1302
1303void LLTextureCache::purgeTextureFilesTimeSliced(BOOL force_all)
1304{
1305 LLMutexLock lock(&mHeaderMutex);
1306
1307 F32 delay_between_passes = 1.0f; // seconds
1308 F32 max_time_per_pass = 0.1f; // seconds
1309
1310 if (!force_all && mTimeLastFileDelete.getElapsedTimeF32() <= delay_between_passes)
1311 {
1312 return;
1313 }
1314
1315 LLTimer timer;
1316 S32 howmany = 0;
1317
1318 llinfos << "TEXTURE CACHE: " << mFilesToDelete.size() << " files scheduled for deletion" << llendl;
1319
1320 for (LLTextureCache::filename_list_t::iterator iter = mFilesToDelete.begin(); iter!=mFilesToDelete.end(); )
1321 {
1322 LLTextureCache::filename_list_t::iterator iter2 = iter++;
1323 ll_apr_file_remove(*iter2, NULL);
1324 mFilesToDelete.erase(iter2);
1325 howmany++;
1326
1327 if (!force_all && timer.getElapsedTimeF32() > max_time_per_pass)
1328 {
1329 break;
1330 }
1331 }
1332
1333 if (!mFilesToDelete.empty())
1334 {
1335 llinfos << "TEXTURE CACHE: "<< howmany << " files deleted ("
1336 << mFilesToDelete.size() << " files left for next pass)"
1337 << llendl;
1338 }
1339
1340 mTimeLastFileDelete.reset();
1341}
1342
1343
1344
1296////////////////////////////////////////////////////////////////////////////// 1345//////////////////////////////////////////////////////////////////////////////
1297 1346
1298// call lockWorkers() first! 1347// call lockWorkers() first!
@@ -1462,6 +1511,10 @@ LLTextureCache::handle_t LLTextureCache::writeToCache(const LLUUID& id, U32 prio
1462 purgeTextures(false); 1511 purgeTextures(false);
1463 mDoPurge = FALSE; 1512 mDoPurge = FALSE;
1464 } 1513 }
1514
1515 purgeTextureFilesTimeSliced(); // purge textures from cache in a non-hiccup-way
1516
1517
1465 if (datasize >= TEXTURE_CACHE_ENTRY_SIZE) 1518 if (datasize >= TEXTURE_CACHE_ENTRY_SIZE)
1466 { 1519 {
1467 LLMutexLock lock(&mWorkersMutex); 1520 LLMutexLock lock(&mWorkersMutex);
diff --git a/linden/indra/newview/lltexturecache.h b/linden/indra/newview/lltexturecache.h
index f083dd0..e15a88b 100644
--- a/linden/indra/newview/lltexturecache.h
+++ b/linden/indra/newview/lltexturecache.h
@@ -119,6 +119,7 @@ private:
119 void readHeaderCache(apr_pool_t* poolp = NULL); 119 void readHeaderCache(apr_pool_t* poolp = NULL);
120 void purgeAllTextures(bool purge_directories); 120 void purgeAllTextures(bool purge_directories);
121 void purgeTextures(bool validate); 121 void purgeTextures(bool validate);
122 void purgeTextureFilesTimeSliced(BOOL force_all = FALSE);
122 S32 getHeaderCacheEntry(const LLUUID& id, bool touch, S32* imagesize = NULL); 123 S32 getHeaderCacheEntry(const LLUUID& id, bool touch, S32* imagesize = NULL);
123 bool removeHeaderCacheEntry(const LLUUID& id); 124 bool removeHeaderCacheEntry(const LLUUID& id);
124 void lockHeaders() { mHeaderMutex.lock(); } 125 void lockHeaders() { mHeaderMutex.lock(); }
@@ -140,6 +141,10 @@ private:
140 141
141 typedef std::vector<std::pair<LLPointer<Responder>, bool> > responder_list_t; 142 typedef std::vector<std::pair<LLPointer<Responder>, bool> > responder_list_t;
142 responder_list_t mCompletedList; 143 responder_list_t mCompletedList;
144
145 typedef std::list<std::string> filename_list_t;
146 filename_list_t mFilesToDelete;
147 LLTimer mTimeLastFileDelete;
143 148
144 BOOL mReadOnly; 149 BOOL mReadOnly;
145 150