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 From 50e05c70d38c0e9da654cbc0f1758809e7159744 Mon Sep 17 00:00:00 2001 From: Beq Janus Date: Mon, 12 Aug 2024 19:01:34 +0100 Subject: Interim fix for particles no longer rezzing properly. (#2227) In a previous PR, I noted: 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. It turns out that by moving the calcPixelArea to the "correct place", we break the rezzing of particles which are then being downsampled as a result. Moving this back to the "incorrect" location undoes the immediate effect but this whole scenario may need to be re-examined. --- 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 865805f9bf..7047ce7d29 100644 --- a/indra/newview/llviewertexturelist.cpp +++ b/indra/newview/llviewertexturelist.cpp @@ -938,9 +938,9 @@ void LLViewerTextureList::updateImageDecodePriority(LLViewerFetchedTexture* imag onFace = true; 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(); + bool in_frustum = face->calcPixelArea(cos_angle_to_view_dir, radius); // Scale desired texture resolution higher or lower depending on texture scale // -- cgit v1.2.3 From ed6732eda8c80d17e05bbc6563b6ce08ef6b8c72 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Tue, 20 Aug 2024 06:59:07 -0500 Subject: #2315 Ensure textures are deleted when they are no longer referenced. (#2343) * #2315 WIP -- Clean up deletion rules in texture list. Incidental decruft. * Touch up assertions. * Move mLastReferencedTimer to LLViewerMediaTexture since it's no longer used by LLViewerTexture --- indra/newview/llviewertexturelist.cpp | 117 +++++----------------------------- 1 file changed, 15 insertions(+), 102 deletions(-) (limited to 'indra/newview/llviewertexturelist.cpp') diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp index 7047ce7d29..1ac97a20cf 100644 --- a/indra/newview/llviewertexturelist.cpp +++ b/indra/newview/llviewertexturelist.cpp @@ -187,13 +187,6 @@ void LLViewerTextureList::doPreloadImages() image->setAddressMode(LLTexUnit::TAM_CLAMP); mImagePreloads.insert(image); } - - LLPointer img_blak_square_tex(new LLImageRaw(2, 2, 3)); - memset(img_blak_square_tex->getData(), 0, img_blak_square_tex->getDataSize()); - LLPointer img_blak_square(new LLViewerFetchedTexture(img_blak_square_tex, FTT_DEFAULT, false)); - gBlackSquareID = img_blak_square->getID(); - img_blak_square->setUnremovable(true); - addImage(img_blak_square, TEX_LIST_STANDARD); } static std::string get_texture_list_name() @@ -725,6 +718,7 @@ void LLViewerTextureList::removeImageFromList(LLViewerFetchedTexture *image) size_t count = 0; if (image->isInImageList()) { + image->setInImageList(false); count = mImageList.erase(image) ; if(count != 1) { @@ -761,8 +755,6 @@ void LLViewerTextureList::removeImageFromList(LLViewerFetchedTexture *image) << LL_ENDL; } } - - image->setInImageList(false) ; } void LLViewerTextureList::addImage(LLViewerFetchedTexture *new_image, ETexListType tex_type) @@ -808,15 +800,6 @@ void LLViewerTextureList::deleteImage(LLViewerFetchedTexture *image) /////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////// - -void LLViewerTextureList::dirtyImage(LLViewerFetchedTexture *image) -{ - mDirtyTextureList.insert(image); -} - -//////////////////////////////////////////////////////////////////////////// - void LLViewerTextureList::updateImages(F32 max_time) { LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; @@ -857,12 +840,6 @@ void LLViewerTextureList::updateImages(F32 max_time) //handle results from decode threads updateImagesCreateTextures(remaining_time); - if (!mDirtyTextureList.empty()) - { - gPipeline.dirtyPoolObjectTextures(mDirtyTextureList); - mDirtyTextureList.clear(); - } - bool didone = false; for (image_list_t::iterator iter = mCallbackList.begin(); iter != mCallbackList.end(); ) @@ -906,12 +883,6 @@ extern bool gCubeSnapshot; void LLViewerTextureList::updateImageDecodePriority(LLViewerFetchedTexture* imagep, bool flush_images) { - if (imagep->isInDebug() || imagep->isUnremovable()) - { - //update_counter--; - return; //is in debug, ignore. - } - llassert(!gCubeSnapshot); static LLCachedControl bias_distance_scale(gSavedSettings, "TextureBiasDistanceScale", 1.f); @@ -926,7 +897,6 @@ 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) @@ -935,7 +905,6 @@ void LLViewerTextureList::updateImageDecodePriority(LLViewerFetchedTexture* imag if (face && face->getViewerObject()) { - onFace = true; F32 radius; F32 cos_angle_to_view_dir; static LLCachedControl bias_unimportant_threshold(gSavedSettings, "TextureBiasUnimportantFactor", 0.25f); @@ -983,24 +952,17 @@ void LLViewerTextureList::updateImageDecodePriority(LLViewerFetchedTexture* imag volume->updateSpotLightPriority(); } - //imagep->setDebugText(llformat("%.3f - %d", sqrtf(imagep->getMaxVirtualSize()), imagep->getBoostLevel())); - - F32 lazy_flush_timeout = 30.f; // stop decoding - F32 max_inactive_time = 20.f; // actually delete - S32 min_refs = 3; // 1 for mImageList, 1 for mUUIDMap, 1 for local reference + F32 max_inactive_time = 20.f; // inactive time before deleting saved raw image + S32 min_refs = 3; // 1 for mImageList, 1 for mUUIDMap, and 1 for "entries" in updateImagesFetchTextures // // Flush formatted images using a lazy flush // S32 num_refs = imagep->getNumRefs(); - if (num_refs == min_refs && flush_images) + if (num_refs <= min_refs && flush_images) { - if (imagep->getLastReferencedTimer()->getElapsedTimeF32() > lazy_flush_timeout) - { - // Remove the unused image from the image list - deleteImage(imagep); - imagep = NULL; // should destroy the image - } + // Remove the unused image from the image list + deleteImage(imagep); return; } else @@ -1017,27 +979,6 @@ void LLViewerTextureList::updateImageDecodePriority(LLViewerFetchedTexture* imag { return; } - else if (imagep->isDeletionCandidate()) - { - imagep->destroyTexture(); - return; - } - else if (imagep->isInactive()) - { - if (imagep->getLastReferencedTimer()->getElapsedTimeF32() > max_inactive_time) - { - imagep->setDeletionCandidate(); - } - return; - } - else - { - imagep->getLastReferencedTimer()->reset(); - - //reset texture state. - if(!onFace) - imagep->setInactive(); - } } if (!imagep->isInImageList()) @@ -1052,20 +993,6 @@ void LLViewerTextureList::updateImageDecodePriority(LLViewerFetchedTexture* imag imagep->processTextureStats(); } -void LLViewerTextureList::setDebugFetching(LLViewerFetchedTexture* tex, S32 debug_level) -{ - LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; - if(!tex->setDebugFetching(debug_level)) - { - return; - } - - const F32 DEBUG_PRIORITY = 100000.f; - removeImageFromList(tex); - tex->mMaxVirtualSize = DEBUG_PRIORITY; - addImageToList(tex); -} - F32 LLViewerTextureList::updateImagesCreateTextures(F32 max_time) { LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; @@ -1169,21 +1096,12 @@ F32 LLViewerTextureList::updateImagesLoadingFastCache(F32 max_time) void LLViewerTextureList::forceImmediateUpdate(LLViewerFetchedTexture* imagep) { LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; - if(!imagep) + if(!imagep || gCubeSnapshot) { return ; } - if(imagep->isInImageList()) - { - removeImageFromList(imagep); - } - if (!gCubeSnapshot) - { // never call processTextureStats in a cube snapshot - imagep->processTextureStats(); - } - imagep->sMaxVirtualSize = LLViewerFetchedTexture::sMaxVirtualSize; - addImageToList(imagep); + imagep->processTextureStats(); return ; } @@ -1198,12 +1116,15 @@ F32 LLViewerTextureList::updateImagesFetchTextures(F32 max_time) // update N textures at beginning of mImageList U32 update_count = 0; static const S32 MIN_UPDATE_COUNT = gSavedSettings.getS32("TextureFetchUpdateMinCount"); // default: 32 - // WIP -- dumb code here + + // NOTE: a texture may be deleted as a side effect of some of these updates + // Deletion rules check ref count, so be careful not to hold any LLPointer references to the textures here other than the one in entries. + //update MIN_UPDATE_COUNT or 5% of other textures, whichever is greater update_count = llmax((U32) MIN_UPDATE_COUNT, (U32) mUUIDMap.size()/20); update_count = llmin(update_count, (U32) mUUIDMap.size()); - { + { // copy entries out of UUID map to avoid iterator invalidation from deletion inside updateImageDecodeProiroty or updateFetch below LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("vtluift - copy"); // copy entries out of UUID map for updating @@ -1226,30 +1147,22 @@ F32 LLViewerTextureList::updateImagesFetchTextures(F32 max_time) LLTimer timer; - LLPointer last_imagep = nullptr; - for (auto& imagep : entries) { - if (imagep->getNumRefs() > 1) // make sure this image hasn't been deleted before attempting to update (may happen as a side effect of some other image updating) + mLastUpdateKey = LLTextureKey(imagep->getID(), (ETexListType)imagep->getTextureListType()); + if (imagep->getNumRefs() > 1) // make sure this image hasn't been deleted before attempting to update (may happen as a side effect of some other image updating) { updateImageDecodePriority(imagep); imagep->updateFetch(); } - last_imagep = imagep; - if (timer.getElapsedTimeF32() > max_time) { break; } } - if (last_imagep) - { - mLastUpdateKey = LLTextureKey(last_imagep->getID(), (ETexListType)last_imagep->getTextureListType()); - } - return timer.getElapsedTimeF32(); } -- cgit v1.2.3 From 0edf6e230e4580fc61917bc823f82d983d807ccf Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Fri, 23 Aug 2024 16:35:52 -0500 Subject: #2388 Texture downrezzing tune up. (#2414) - Hold onto unreferenced textures for 30 seconds. - Don't downres unless memory is low - Downres when viewer is backgrounded. --- indra/newview/llviewertexturelist.cpp | 54 ++++++++++++++++++++++++++++------- 1 file changed, 43 insertions(+), 11 deletions(-) (limited to 'indra/newview/llviewertexturelist.cpp') diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp index 1ac97a20cf..a5700ab264 100644 --- a/indra/newview/llviewertexturelist.cpp +++ b/indra/newview/llviewertexturelist.cpp @@ -889,12 +889,9 @@ 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; - } + + F32 max_vsize = 0.f; + bool on_screen = false; LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; for (U32 i = 0; i < LLRender::NUM_TEXTURE_CHANNELS; ++i) @@ -911,6 +908,8 @@ void LLViewerTextureList::updateImageDecodePriority(LLViewerFetchedTexture* imag F32 vsize = face->getPixelArea(); bool in_frustum = face->calcPixelArea(cos_angle_to_view_dir, radius); + on_screen = in_frustum; + // Scale desired texture resolution higher or lower depending on texture scale // // Minimum usage examples: a 1024x1024 texture with aplhabet, runing string @@ -936,15 +935,40 @@ void LLViewerTextureList::updateImageDecodePriority(LLViewerFetchedTexture* imag if (apply_bias) { F32 bias = powf(4, LLViewerTexture::sDesiredDiscardBias - 1.f); - bias = (F32)llround(bias); + bias = (F32) llround(bias); vsize /= bias; } - imagep->addTextureStats(vsize); + max_vsize = llmax(max_vsize, vsize); } } } + if (imagep->getType() == LLViewerTexture::LOD_TEXTURE && imagep->getBoostLevel() == LLViewerTexture::BOOST_NONE) + { // conditionally 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 + + if (LLViewerTexture::sDesiredDiscardBias > 2.f || + (!on_screen && LLViewerTexture::sDesiredDiscardBias > 1.f)) + { + imagep->mMaxVirtualSize = 0.f; + } + } + + + imagep->addTextureStats(max_vsize); + +#if 0 + imagep->setDebugText(llformat("%d/%d - %d/%d -- %d/%d", + (S32)sqrtf(max_vsize), + (S32)sqrtf(imagep->mMaxVirtualSize), + imagep->getDiscardLevel(), + imagep->getDesiredDiscardLevel(), + imagep->getWidth(), + imagep->getFullWidth())); +#endif + // make sure to addTextureStats for any spotlights that are using this texture for (S32 vi = 0; vi < imagep->getNumVolumes(LLRender::LIGHT_TEX); ++vi) { @@ -955,18 +979,26 @@ void LLViewerTextureList::updateImageDecodePriority(LLViewerFetchedTexture* imag F32 max_inactive_time = 20.f; // inactive time before deleting saved raw image S32 min_refs = 3; // 1 for mImageList, 1 for mUUIDMap, and 1 for "entries" in updateImagesFetchTextures + F32 lazy_flush_timeout = 30.f; // delete unused images after 30 seconds + // // Flush formatted images using a lazy flush // S32 num_refs = imagep->getNumRefs(); if (num_refs <= min_refs && flush_images) { - // Remove the unused image from the image list - deleteImage(imagep); - return; + if (imagep->getLastReferencedTimer()->getElapsedTimeF32() > lazy_flush_timeout) + { + // Remove the unused image from the image list + deleteImage(imagep); + return; + } } else { + // still referenced outside of image list, reset timer + imagep->getLastReferencedTimer()->reset(); + if (imagep->hasSavedRawImage()) { if (imagep->getElapsedLastReferencedSavedRawImageTime() > max_inactive_time) -- cgit v1.2.3