diff options
| author | Dave Parks <davep@lindenlab.com> | 2024-08-23 16:35:52 -0500 | 
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-08-23 16:35:52 -0500 | 
| commit | 0edf6e230e4580fc61917bc823f82d983d807ccf (patch) | |
| tree | 230bb535d848844155948f29958846c8c61c2489 | |
| parent | 1adf2d00ebd340dca72532585276279cb6911dfb (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.cpp | 7 | ||||
| -rw-r--r-- | indra/newview/llviewertexture.cpp | 32 | ||||
| -rw-r--r-- | indra/newview/llviewertexture.h | 11 | ||||
| -rw-r--r-- | indra/newview/llviewertexturelist.cpp | 54 | 
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)  | 
