From ab87978cbc71cd4c83648627998055a010700f05 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Thu, 27 Jun 2024 13:12:43 -0500 Subject: 1836 dont store texture in system memory unless absolutely necessary (#1843) * #1836 Texture memory usage overhaul. Much decrufting - don't keep a copy of textures in system memory - use GPU to downrez textures instead of reloading from cache - use GPU to generate brightness/darkness bumpmaps --- indra/newview/llviewertexturelist.cpp | 24 +++++++++--------------- 1 file changed, 9 insertions(+), 15 deletions(-) (limited to 'indra/newview/llviewertexturelist.cpp') diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp index b90c1868fc..4d8fd8ddd5 100644 --- a/indra/newview/llviewertexturelist.cpp +++ b/indra/newview/llviewertexturelist.cpp @@ -296,7 +296,7 @@ void LLViewerTextureList::shutdown() // Write out list of currently loaded textures for precaching on startup typedef std::set > image_area_list_t; image_area_list_t image_area_list; - for (image_priority_list_t::iterator iter = mImageList.begin(); + for (image_list_t::iterator iter = mImageList.begin(); iter != mImageList.end(); ++iter) { LLViewerFetchedTexture* image = *iter; @@ -367,7 +367,7 @@ void LLViewerTextureList::dump() { LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; LL_INFOS() << "LLViewerTextureList::dump()" << LL_ENDL; - for (image_priority_list_t::iterator it = mImageList.begin(); it != mImageList.end(); ++it) + for (image_list_t::iterator it = mImageList.begin(); it != mImageList.end(); ++it) { LLViewerFetchedTexture* image = *it; @@ -381,15 +381,9 @@ void LLViewerTextureList::dump() } } -void LLViewerTextureList::destroyGL(bool save_state) +void LLViewerTextureList::destroyGL() { - LLImageGL::destroyGL(save_state); -} - -void LLViewerTextureList::restoreGL() -{ - llassert_always(mInitialized) ; - LLImageGL::restoreGL(); + LLImageGL::destroyGL(); } /* Vertical tab container button image IDs @@ -895,7 +889,7 @@ void LLViewerTextureList::clearFetchingRequests() LLAppViewer::getTextureFetch()->deleteAllRequests(); - for (image_priority_list_t::iterator iter = mImageList.begin(); + for (image_list_t::iterator iter = mImageList.begin(); iter != mImageList.end(); ++iter) { LLViewerFetchedTexture* imagep = *iter; @@ -1208,7 +1202,7 @@ void LLViewerTextureList::updateImagesUpdateStats() LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; if (mForceResetTextureStats) { - for (image_priority_list_t::iterator iter = mImageList.begin(); + for (image_list_t::iterator iter = mImageList.begin(); iter != mImageList.end(); ) { LLViewerFetchedTexture* imagep = *iter++; @@ -1228,7 +1222,7 @@ void LLViewerTextureList::decodeAllImages(F32 max_time) // Update texture stats and priorities std::vector > image_list; - for (image_priority_list_t::iterator iter = mImageList.begin(); + for (image_list_t::iterator iter = mImageList.begin(); iter != mImageList.end(); ) { LLViewerFetchedTexture* imagep = *iter++; @@ -1248,7 +1242,7 @@ void LLViewerTextureList::decodeAllImages(F32 max_time) image_list.clear(); // Update fetch (decode) - for (image_priority_list_t::iterator iter = mImageList.begin(); + for (image_list_t::iterator iter = mImageList.begin(); iter != mImageList.end(); ) { LLViewerFetchedTexture* imagep = *iter++; @@ -1275,7 +1269,7 @@ void LLViewerTextureList::decodeAllImages(F32 max_time) } } // Update fetch again - for (image_priority_list_t::iterator iter = mImageList.begin(); + for (image_list_t::iterator iter = mImageList.begin(); iter != mImageList.end(); ) { LLViewerFetchedTexture* imagep = *iter++; -- cgit v1.2.3 From 475d0df4c152972665c978f7b0991f8726def03a Mon Sep 17 00:00:00 2001 From: Beq Janus Date: Tue, 2 Jul 2024 18:57:39 +0100 Subject: Experimental fix for blurry textures (#1875) This change removes the distance based bias (which is a large contributor to premature blurring) but adds a check using the importance factor to give some balance. importance should be between 0 and 1 and is higher when the texture is facing the camera, lower when it is side on, The unimportance setting defines the cutoff vaklue below which we'll consider the textures worth "down scaling" by the bias factor. The setting is inplace to allow us to play with this, 0.25 is current default. Note this change moves the calcPixelArea() call to the top BEFORE we user getPixelArea(). Either that call is entirely redundant (i.e. if calc was called earlier in the frame) or we were using the stale pixelArea (one frame behind). If the former is true then it might be faster to just do an AABB frustum check. --- indra/newview/llviewertexturelist.cpp | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) (limited to 'indra/newview/llviewertexturelist.cpp') diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp index 4d8fd8ddd5..2f685474e1 100644 --- a/indra/newview/llviewertexturelist.cpp +++ b/indra/newview/llviewertexturelist.cpp @@ -931,6 +931,10 @@ void LLViewerTextureList::updateImageDecodePriority(LLViewerFetchedTexture* imag if (face && face->getViewerObject() && face->getTextureEntry()) { + F32 radius; + F32 cos_angle_to_view_dir; + BOOL in_frustum = face->calcPixelArea(cos_angle_to_view_dir, radius); + static LLCachedControl bias_unimportant_threshold(gSavedSettings, "TextureBiasUnimportantFactor", 0.25f); F32 vsize = face->getPixelArea(); // Scale desired texture resolution higher or lower depending on texture scale @@ -944,13 +948,7 @@ void LLViewerTextureList::updateImageDecodePriority(LLViewerFetchedTexture* imag min_scale = llclamp(min_scale*min_scale, texture_scale_min(), texture_scale_max()); vsize /= min_scale; - vsize /= LLViewerTexture::sDesiredDiscardBias; - vsize /= llmax(1.f, (LLViewerTexture::sDesiredDiscardBias-1.f) * (1.f + face->getDrawable()->mDistanceWRTCamera * bias_distance_scale)); - - F32 radius; - F32 cos_angle_to_view_dir; - bool in_frustum = face->calcPixelArea(cos_angle_to_view_dir, radius); - if (!in_frustum || !face->getDrawable()->isVisible()) + if (!in_frustum || !face->getDrawable()->isVisible() || face->getImportanceToCamera() < bias_unimportant_threshold) { // further reduce by discard bias when off screen or occluded vsize /= LLViewerTexture::sDesiredDiscardBias; } -- cgit v1.2.3 From 08b933a0c67463f06f124420f16c8a3f7dc83f1f Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Wed, 3 Jul 2024 17:42:24 -0500 Subject: #1870 Tune up for better experience on integrated intel with low memory (#1872) * More deterministic vsize calculation. Add control for choosing downscale method. * Quick hack to make GLTF preview work again --- indra/newview/llviewertexturelist.cpp | 173 ++++++++++++++++++++++------------ 1 file changed, 113 insertions(+), 60 deletions(-) (limited to 'indra/newview/llviewertexturelist.cpp') diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp index 2f685474e1..c436566297 100644 --- a/indra/newview/llviewertexturelist.cpp +++ b/indra/newview/llviewertexturelist.cpp @@ -70,6 +70,8 @@ S32 LLViewerTextureList::sNumImages = 0; LLViewerTextureList gTextureList; +extern LLGLSLShader gCopyProgram; + ETexListType get_element_type(S32 priority) { return (priority == LLViewerFetchedTexture::BOOST_ICON || priority == LLViewerFetchedTexture::BOOST_THUMBNAIL) ? TEX_LIST_SCALE : TEX_LIST_STANDARD; @@ -352,8 +354,11 @@ void LLViewerTextureList::shutdown() mCallbackList.clear(); // Flush all of the references - mLoadingStreamList.clear(); - mCreateTextureList.clear(); + while (!mCreateTextureList.empty()) + { + mCreateTextureList.front()->mCreatePending = false; + mCreateTextureList.pop(); + } mFastCacheList.clear(); mUUIDMap.clear(); @@ -897,14 +902,6 @@ void LLViewerTextureList::clearFetchingRequests() } } -static void touch_texture(LLViewerFetchedTexture* tex, F32 vsize) -{ - if (tex) - { - tex->addTextureStats(vsize); - } -} - extern bool gCubeSnapshot; void LLViewerTextureList::updateImageDecodePriority(LLViewerFetchedTexture* imagep) @@ -921,58 +918,67 @@ void LLViewerTextureList::updateImageDecodePriority(LLViewerFetchedTexture* imag static LLCachedControl texture_scale_min(gSavedSettings, "TextureScaleMinAreaFactor", 0.04f); static LLCachedControl texture_scale_max(gSavedSettings, "TextureScaleMaxAreaFactor", 25.f); + if (imagep->getType() == LLViewerTexture::LOD_TEXTURE && imagep->getBoostLevel() == LLViewerTexture::BOOST_NONE) + { // reset max virtual size for unboosted LOD_TEXTURES + // this is an alternative to decaying mMaxVirtualSize over time + // that keeps textures from continously downrezzing and uprezzing in the background + imagep->mMaxVirtualSize = 0.f; + } + LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE + for (U32 i = 0; i < LLRender::NUM_TEXTURE_CHANNELS; ++i) { - for (U32 i = 0; i < LLRender::NUM_TEXTURE_CHANNELS; ++i) + for (S32 fi = 0; fi < imagep->getNumFaces(i); ++fi) { - for (S32 fi = 0; fi < imagep->getNumFaces(i); ++fi) + LLFace* face = (*(imagep->getFaceList(i)))[fi]; + + if (face && face->getViewerObject()) { - LLFace* face = (*(imagep->getFaceList(i)))[fi]; + F32 radius; + F32 cos_angle_to_view_dir; + bool in_frustum = face->calcPixelArea(cos_angle_to_view_dir, radius); + static LLCachedControl bias_unimportant_threshold(gSavedSettings, "TextureBiasUnimportantFactor", 0.25f); + F32 vsize = face->getPixelArea(); + + // Scale desired texture resolution higher or lower depending on texture scale + // + // Minimum usage examples: a 1024x1024 texture with aplhabet, runing string + // shows one letter at a time + // + // Maximum usage examples: huge chunk of terrain repeats texture + const LLTextureEntry* te = face->getTextureEntry(); + F32 min_scale = te ? llmin(fabsf(te->getScaleS()), fabsf(te->getScaleT())) : 1.f; + min_scale = llclamp(min_scale * min_scale, texture_scale_min(), texture_scale_max()); + vsize /= min_scale; + + // if bias is > 2, apply to on-screen textures as well + bool apply_bias = LLViewerTexture::sDesiredDiscardBias > 2.f; + + // apply bias to off screen objects or objects that are small on screen all the time + if (!in_frustum || !face->getDrawable()->isVisible() || face->getImportanceToCamera() < bias_unimportant_threshold) + { // further reduce by discard bias when off screen or occluded + apply_bias = true; + } - if (face && face->getViewerObject() && face->getTextureEntry()) + if (apply_bias) { - F32 radius; - F32 cos_angle_to_view_dir; - BOOL in_frustum = face->calcPixelArea(cos_angle_to_view_dir, radius); - static LLCachedControl bias_unimportant_threshold(gSavedSettings, "TextureBiasUnimportantFactor", 0.25f); - F32 vsize = face->getPixelArea(); - - // Scale desired texture resolution higher or lower depending on texture scale - // - // Minimum usage examples: a 1024x1024 texture with aplhabet, runing string - // shows one letter at a time - // - // Maximum usage examples: huge chunk of terrain repeats texture - const LLTextureEntry* te = face->getTextureEntry(); - F32 min_scale = te ? llmin(fabsf(te->getScaleS()), fabsf(te->getScaleT())) : 1.f; - min_scale = llclamp(min_scale*min_scale, texture_scale_min(), texture_scale_max()); - - vsize /= min_scale; - if (!in_frustum || !face->getDrawable()->isVisible() || face->getImportanceToCamera() < bias_unimportant_threshold) - { // further reduce by discard bias when off screen or occluded - vsize /= LLViewerTexture::sDesiredDiscardBias; - } - // if a GLTF material is present, ignore that face - // as far as this texture stats go, but update the GLTF material - // stats - LLFetchedGLTFMaterial* mat = te ? (LLFetchedGLTFMaterial*)te->getGLTFRenderMaterial() : nullptr; - llassert(mat == nullptr || dynamic_cast(te->getGLTFRenderMaterial()) != nullptr); - if (mat) - { - touch_texture(mat->mBaseColorTexture, vsize); - touch_texture(mat->mNormalTexture, vsize); - touch_texture(mat->mMetallicRoughnessTexture, vsize); - touch_texture(mat->mEmissiveTexture, vsize); - } - else - { - imagep->addTextureStats(vsize); - } + F32 bias = powf(4, LLViewerTexture::sDesiredDiscardBias - 1.f); + bias = llround(bias); + vsize /= bias; } + + imagep->addTextureStats(vsize); } } } + // make sure to addTextureStats for any spotlights that are using this texture + for (S32 vi = 0; vi < imagep->getNumVolumes(LLRender::LIGHT_TEX); ++vi) + { + LLVOVolume* volume = (*imagep->getVolumeList(LLRender::LIGHT_TEX))[vi]; + volume->updateSpotLightPriority(); + } + //imagep->setDebugText(llformat("%.3f - %d", sqrtf(imagep->getMaxVirtualSize()), imagep->getBoostLevel())); F32 lazy_flush_timeout = 30.f; // stop decoding @@ -1066,22 +1072,65 @@ F32 LLViewerTextureList::updateImagesCreateTextures(F32 max_time) // LLTimer create_timer; - image_list_t::iterator enditer = mCreateTextureList.begin(); - for (image_list_t::iterator iter = mCreateTextureList.begin(); - iter != mCreateTextureList.end();) + + if (!mDownScaleQueue.empty() && gPipeline.mDownResMap.isComplete()) { - image_list_t::iterator curiter = iter++; - enditer = iter; - LLViewerFetchedTexture *imagep = *curiter; + // just in case we downres textures, bind downresmap and copy program + gPipeline.mDownResMap.bindTarget(); + gCopyProgram.bind(); + gPipeline.mScreenTriangleVB->setBuffer(); + + // give time to downscaling first -- if mDownScaleQueue is not empty, we're running out of memory and need + // to free up memory by discarding off screen textures quickly + + // do at least 5 and make sure we don't get too far behind even if it violates + // the time limit. If we don't downscale quickly the viewer will hit swap and may + // freeze. + S32 min_count = (S32)mCreateTextureList.size() / 20 + 5; + + while (!mDownScaleQueue.empty()) + { + LLViewerFetchedTexture* image = mDownScaleQueue.front(); + llassert(image->mDownScalePending); + + LLImageGL* img = image->getGLTexture(); + if (img && img->getHasGLTexture()) + { + img->scaleDown(image->getDesiredDiscardLevel()); + } + + image->mDownScalePending = false; + mDownScaleQueue.pop(); + + if (create_timer.getElapsedTimeF32() > max_time && --min_count <= 0) + { + break; + } + } + + gCopyProgram.unbind(); + gPipeline.mDownResMap.flush(); + } + + // do at least 5 and make sure we don't get too far behind even if it violates + // the time limit. Textures pending creation have a copy of their texture data + // in system memory, so we don't want to let them pile up. + S32 min_count = (S32) mCreateTextureList.size() / 20 + 5; + + while (!mCreateTextureList.empty()) + { + LLViewerFetchedTexture *imagep = mCreateTextureList.front(); + llassert(imagep->mCreatePending); imagep->createTexture(); imagep->postCreateTexture(); + imagep->mCreatePending = false; + mCreateTextureList.pop(); - if (create_timer.getElapsedTimeF32() > max_time) + if (create_timer.getElapsedTimeF32() > max_time && --min_count <= 0) { break; } } - mCreateTextureList.erase(mCreateTextureList.begin(), enditer); return create_timer.getElapsedTimeF32(); } @@ -1124,7 +1173,10 @@ void LLViewerTextureList::forceImmediateUpdate(LLViewerFetchedTexture* imagep) removeImageFromList(imagep); } - imagep->processTextureStats(); + if (!gCubeSnapshot) + { // never call processTextureStats in a cube snapshot + imagep->processTextureStats(); + } imagep->sMaxVirtualSize = LLViewerFetchedTexture::sMaxVirtualSize; addImageToList(imagep); @@ -1134,6 +1186,7 @@ void LLViewerTextureList::forceImmediateUpdate(LLViewerFetchedTexture* imagep) F32 LLViewerTextureList::updateImagesFetchTextures(F32 max_time) { LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; + typedef std::vector > entries_list_t; entries_list_t entries; -- cgit v1.2.3 From 9fdca96f8bd2211a99fe88e57b70cbecefa20b6d Mon Sep 17 00:00:00 2001 From: Ansariel Date: Mon, 8 Jul 2024 20:27:14 +0200 Subject: Re-enable compiler warnings C4244 and C4396 except for lltracerecording.h and llunittype.h for now --- indra/newview/llviewertexturelist.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'indra/newview/llviewertexturelist.cpp') diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp index c436566297..b03a9a8f15 100644 --- a/indra/newview/llviewertexturelist.cpp +++ b/indra/newview/llviewertexturelist.cpp @@ -833,7 +833,7 @@ void LLViewerTextureList::updateImages(F32 max_time) } cleared = false; - LLAppViewer::getTextureFetch()->setTextureBandwidth(LLTrace::get_frame_recording().getPeriodMeanPerSec(LLStatViewer::TEXTURE_NETWORK_DATA_RECEIVED).value()); + LLAppViewer::getTextureFetch()->setTextureBandwidth((F32)LLTrace::get_frame_recording().getPeriodMeanPerSec(LLStatViewer::TEXTURE_NETWORK_DATA_RECEIVED).value()); { using namespace LLStatViewer; @@ -963,7 +963,7 @@ void LLViewerTextureList::updateImageDecodePriority(LLViewerFetchedTexture* imag if (apply_bias) { F32 bias = powf(4, LLViewerTexture::sDesiredDiscardBias - 1.f); - bias = llround(bias); + bias = (F32)llround(bias); vsize /= bias; } -- cgit v1.2.3 From 2a7030992faa12c362d3eb9365080efd8265e15f Mon Sep 17 00:00:00 2001 From: Rye Mutt Date: Tue, 9 Jul 2024 17:53:43 -0400 Subject: Update tracy profiler to 0.10 (#1946) --- indra/newview/llviewertexturelist.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/newview/llviewertexturelist.cpp') diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp index b03a9a8f15..e486449b4d 100644 --- a/indra/newview/llviewertexturelist.cpp +++ b/indra/newview/llviewertexturelist.cpp @@ -925,7 +925,7 @@ void LLViewerTextureList::updateImageDecodePriority(LLViewerFetchedTexture* imag imagep->mMaxVirtualSize = 0.f; } - LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE + LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; for (U32 i = 0; i < LLRender::NUM_TEXTURE_CHANNELS; ++i) { for (S32 fi = 0; fi < imagep->getNumFaces(i); ++fi) -- cgit v1.2.3 From 27a2531c5bf375ed208d8fd5764a8797f08ce831 Mon Sep 17 00:00:00 2001 From: TommyTheTerrible <81168766+TommyTheTerrible@users.noreply.github.com> Date: Sat, 13 Jul 2024 17:39:09 -0400 Subject: Fix: Stop textures from being set as inactive if still on a face. (#2017) Textures were being set to Inactive even if still in scene, causing them to be deleted and re-decoded in a loop. --- indra/newview/llviewertexturelist.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'indra/newview/llviewertexturelist.cpp') diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp index e486449b4d..d31c53d000 100644 --- a/indra/newview/llviewertexturelist.cpp +++ b/indra/newview/llviewertexturelist.cpp @@ -926,6 +926,7 @@ void LLViewerTextureList::updateImageDecodePriority(LLViewerFetchedTexture* imag } LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; + bool onFace = false; for (U32 i = 0; i < LLRender::NUM_TEXTURE_CHANNELS; ++i) { for (S32 fi = 0; fi < imagep->getNumFaces(i); ++fi) @@ -934,6 +935,7 @@ void LLViewerTextureList::updateImageDecodePriority(LLViewerFetchedTexture* imag if (face && face->getViewerObject()) { + onFace = true; F32 radius; F32 cos_angle_to_view_dir; bool in_frustum = face->calcPixelArea(cos_angle_to_view_dir, radius); @@ -1031,7 +1033,8 @@ void LLViewerTextureList::updateImageDecodePriority(LLViewerFetchedTexture* imag imagep->getLastReferencedTimer()->reset(); //reset texture state. - imagep->setInactive(); + if(!onFace) + imagep->setInactive(); } } -- cgit v1.2.3 From beb177bb23af4885b2a6f16798a62d1ca9ac0a02 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Wed, 31 Jul 2024 17:26:27 +0300 Subject: viewer#2153 Crash at LLViewerTextureList::updateImageDecodePriority Crash at getTextureEntry which calls getTE(mTEOffset) --- indra/newview/llviewertexturelist.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'indra/newview/llviewertexturelist.cpp') diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp index d31c53d000..115934282f 100644 --- a/indra/newview/llviewertexturelist.cpp +++ b/indra/newview/llviewertexturelist.cpp @@ -948,7 +948,9 @@ void LLViewerTextureList::updateImageDecodePriority(LLViewerFetchedTexture* imag // shows one letter at a time // // Maximum usage examples: huge chunk of terrain repeats texture - const LLTextureEntry* te = face->getTextureEntry(); + S32 te_offset = face->getTEOffset(); // offset is -1 if not inited + LLViewerObject* objp = face->getViewerObject(); + const LLTextureEntry* te = (te_offset < 0 || te_offset >= objp->getNumTEs()) ? nullptr : objp->getTE(te_offset); F32 min_scale = te ? llmin(fabsf(te->getScaleS()), fabsf(te->getScaleT())) : 1.f; min_scale = llclamp(min_scale * min_scale, texture_scale_min(), texture_scale_max()); vsize /= min_scale; -- cgit v1.2.3 From 793f5ac3411882a53a49916f031090d1b6c72335 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Thu, 1 Aug 2024 19:55:16 +0300 Subject: Crash at LLViewerTexture::updateClass() --- indra/newview/llviewertexturelist.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'indra/newview/llviewertexturelist.cpp') diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp index 115934282f..865805f9bf 100644 --- a/indra/newview/llviewertexturelist.cpp +++ b/indra/newview/llviewertexturelist.cpp @@ -904,7 +904,7 @@ void LLViewerTextureList::clearFetchingRequests() extern bool gCubeSnapshot; -void LLViewerTextureList::updateImageDecodePriority(LLViewerFetchedTexture* imagep) +void LLViewerTextureList::updateImageDecodePriority(LLViewerFetchedTexture* imagep, bool flush_images) { if (imagep->isInDebug() || imagep->isUnremovable()) { @@ -993,7 +993,7 @@ void LLViewerTextureList::updateImageDecodePriority(LLViewerFetchedTexture* imag // Flush formatted images using a lazy flush // S32 num_refs = imagep->getNumRefs(); - if (num_refs == min_refs) + if (num_refs == min_refs && flush_images) { if (imagep->getLastReferencedTimer()->getElapsedTimeF32() > lazy_flush_timeout) { -- cgit v1.2.3