summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDave Parks <davep@lindenlab.com>2024-08-23 16:35:52 -0500
committerGitHub <noreply@github.com>2024-08-23 16:35:52 -0500
commit0edf6e230e4580fc61917bc823f82d983d807ccf (patch)
tree230bb535d848844155948f29958846c8c61c2489
parent1adf2d00ebd340dca72532585276279cb6911dfb (diff)
#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.
-rw-r--r--indra/newview/llface.cpp7
-rw-r--r--indra/newview/llviewertexture.cpp32
-rw-r--r--indra/newview/llviewertexture.h11
-rw-r--r--indra/newview/llviewertexturelist.cpp54
4 files changed, 78 insertions, 26 deletions
diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp
index 4dec4d5641..c69d74ad1b 100644
--- a/indra/newview/llface.cpp
+++ b/indra/newview/llface.cpp
@@ -2212,13 +2212,6 @@ bool LLFace::calcPixelArea(F32& cos_angle_to_view_dir, F32& radius)
F32 dist = lookAt.getLength3().getF32();
dist = llmax(dist-size.getLength3().getF32(), 0.001f);
- //ramp down distance for nearby objects
- if (dist < 16.f)
- {
- dist /= 16.f;
- dist *= dist;
- dist *= 16.f;
- }
lookAt.normalize3fast() ;
diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp
index eab564a856..452d6f2c04 100644
--- a/indra/newview/llviewertexture.cpp
+++ b/indra/newview/llviewertexture.cpp
@@ -548,7 +548,37 @@ void LLViewerTexture::updateClass()
was_low = is_low;
- sDesiredDiscardBias = llclamp(sDesiredDiscardBias, 1.f, 3.f);
+
+ // set to max discard bias if the window has been backgrounded for a while
+ static bool was_backgrounded = false;
+ static LLFrameTimer backgrounded_timer;
+
+ bool in_background = (gViewerWindow && !gViewerWindow->getWindow()->getVisible()) || !gFocusMgr.getAppHasFocus();
+
+ if (in_background)
+ {
+ if (backgrounded_timer.getElapsedTimeF32() > 10.f)
+ {
+ if (!was_backgrounded)
+ {
+ LL_INFOS() << "Viewer is backgrounded, freeing up video memory." << LL_ENDL;
+ }
+ was_backgrounded = true;
+ sDesiredDiscardBias = 4.f;
+ }
+ }
+ else
+ {
+ backgrounded_timer.reset();
+ if (was_backgrounded)
+ { // if the viewer was backgrounded
+ LL_INFOS() << "Viewer is no longer backgrounded, resuming normal texture usage." << LL_ENDL;
+ was_backgrounded = false;
+ sDesiredDiscardBias = 1.f;
+ }
+ }
+
+ sDesiredDiscardBias = llclamp(sDesiredDiscardBias, 1.f, 4.f);
LLViewerTexture::sFreezeImageUpdates = false;
}
diff --git a/indra/newview/llviewertexture.h b/indra/newview/llviewertexture.h
index 9046daeab2..3866c898a6 100644
--- a/indra/newview/llviewertexture.h
+++ b/indra/newview/llviewertexture.h
@@ -146,6 +146,8 @@ public:
virtual F32 getMaxVirtualSize() ;
+ LLFrameTimer* getLastReferencedTimer() { return &mLastReferencedTimer; }
+
S32 getFullWidth() const { return mFullWidth; }
S32 getFullHeight() const { return mFullHeight; }
/*virtual*/ void setKnownDrawSize(S32 width, S32 height);
@@ -195,6 +197,7 @@ protected:
mutable F32 mMaxVirtualSize = 0.f; // The largest virtual size of the image, in pixels - how much data to we need?
mutable S32 mMaxVirtualSizeResetCounter;
mutable S32 mMaxVirtualSizeResetInterval;
+ LLFrameTimer mLastReferencedTimer;
ll_face_list_t mFaceList[LLRender::NUM_TEXTURE_CHANNELS]; //reverse pointer pointing to the faces using this image as texture
U32 mNumFaces[LLRender::NUM_TEXTURE_CHANNELS];
@@ -571,10 +574,7 @@ public:
/*virtual*/ void addFace(U32 ch, LLFace* facep) ;
/*virtual*/ void removeFace(U32 ch, LLFace* facep) ;
- /*virtual*/ F32 getMaxVirtualSize() ;
-
- // get the timer that tracks the last time reinit was called
- LLFrameTimer* getLastReferencedTimer() { return &mLastReferencedTimer; }
+ /*virtual*/ F32 getMaxVirtualSize();
private:
void switchTexture(U32 ch, LLFace* facep) ;
@@ -596,9 +596,6 @@ private:
bool mIsPlaying ;
U32 mUpdateVirtualSizeTime ;
- // tracks last time reinit was called
- LLFrameTimer mLastReferencedTimer;
-
public:
static void updateClass() ;
static void cleanUpClass() ;
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<F32> texture_scale_min(gSavedSettings, "TextureScaleMinAreaFactor", 0.04f);
static LLCachedControl<F32> 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)