diff options
| author | cosmic-linden <111533034+cosmic-linden@users.noreply.github.com> | 2024-08-28 11:37:56 -0700 | 
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-08-28 11:37:56 -0700 | 
| commit | 6a4d7b2de622503e00ff58de6a2fc7742ff4df21 (patch) | |
| tree | cf6de765652b2b6a9de51f104604ba0682605825 | |
| parent | 9d689c6145cefcc86b228462279859dfb726429d (diff) | |
| parent | 1f58884db9c026c1a74f693fc84e37a2f66830e3 (diff) | |
Merge pull request #2441 from secondlife/2438-eliminate-execution-time-outliers-for-updateimagedecodepriority
#2438 Address frame stalls in updateImageDecodePriority
| -rw-r--r-- | indra/newview/llface.cpp | 4 | ||||
| -rw-r--r-- | indra/newview/llface.h | 6 | ||||
| -rw-r--r-- | indra/newview/llviewertexturelist.cpp | 129 | ||||
| -rw-r--r-- | indra/newview/llvovolume.cpp | 1 | 
4 files changed, 78 insertions, 62 deletions
| diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp index a8001699fe..df08dcf503 100644 --- a/indra/newview/llface.cpp +++ b/indra/newview/llface.cpp @@ -2143,7 +2143,7 @@ F32 LLFace::getTextureVirtualSize()          face_area =  mPixelArea / llclamp(texel_area, 0.015625f, 128.f);      } -    face_area = LLFace::adjustPixelArea(mImportanceToCamera, face_area) ; +    face_area = LLFace::adjustPixelArea(mImportanceToCamera, face_area);      if(face_area > LLViewerTexture::sMinLargeImageSize) //if is large image, shrink face_area by considering the partial overlapping.      {          if(mImportanceToCamera > LEAST_IMPORTANCE_FOR_LARGE_IMAGE && mTexture[LLRender::DIFFUSE_MAP].notNull() && mTexture[LLRender::DIFFUSE_MAP]->isLargeImage()) @@ -2161,7 +2161,6 @@ bool LLFace::calcPixelArea(F32& cos_angle_to_view_dir, F32& radius)  {      LL_PROFILE_ZONE_SCOPED_CATEGORY_FACE; -    //VECTORIZE THIS      //get area of circle around face      LLVector4a center; @@ -2286,6 +2285,7 @@ const F32 FACE_IMPORTANCE_TO_CAMERA_OVER_ANGLE[FACE_IMPORTANCE_LEVEL][2] =    //  //static  F32 LLFace::calcImportanceToCamera(F32 cos_angle_to_view_dir, F32 dist)  { +    LL_PROFILE_ZONE_SCOPED_CATEGORY_FACE;      F32 importance = 0.f ;      if(cos_angle_to_view_dir > LLViewerCamera::getInstance()->getCosHalfFov() && diff --git a/indra/newview/llface.h b/indra/newview/llface.h index 7cf256f731..99642016f7 100644 --- a/indra/newview/llface.h +++ b/indra/newview/llface.h @@ -209,7 +209,6 @@ public:      void        setDrawInfo(LLDrawInfo* draw_info);      F32         getTextureVirtualSize() ; -    F32         getImportanceToCamera()const {return mImportanceToCamera ;}      void        resetVirtualSize();      void        setHasMedia(bool has_media)  { mHasMedia = has_media ;} @@ -265,6 +264,11 @@ public:      // return mSkinInfo->mHash or 0 if mSkinInfo is null      U64 getSkinHash(); +    // true if face was recently in the main camera frustum according to LLViewerTextureList updates +    bool mInFrustum = false; +    // value of gFrameCount the last time the face was touched by LLViewerTextureList::updateImageDecodePriority +    U32 mLastTextureUpdate = 0; +  private:      LLPointer<LLVertexBuffer> mVertexBuffer;      LLPointer<LLVertexBuffer> mVertexBufferGLTF; diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp index 53b054cb24..2df60dbf6c 100644 --- a/indra/newview/llviewertexturelist.cpp +++ b/indra/newview/llviewertexturelist.cpp @@ -889,79 +889,90 @@ void LLViewerTextureList::updateImageDecodePriority(LLViewerFetchedTexture* imag  {      llassert(!gCubeSnapshot); -    static LLCachedControl<F32> bias_distance_scale(gSavedSettings, "TextureBiasDistanceScale", 1.f); -    static LLCachedControl<F32> texture_scale_min(gSavedSettings, "TextureScaleMinAreaFactor", 0.04f); -    static LLCachedControl<F32> texture_scale_max(gSavedSettings, "TextureScaleMaxAreaFactor", 25.f); +    if (imagep->getBoostLevel() < LLViewerFetchedTexture::BOOST_HIGH)  // don't bother checking face list for boosted textures +    { +        static LLCachedControl<F32> bias_distance_scale(gSavedSettings, "TextureBiasDistanceScale", 1.f); +        static LLCachedControl<F32> texture_scale_min(gSavedSettings, "TextureScaleMinAreaFactor", 0.04f); +        static LLCachedControl<F32> texture_scale_max(gSavedSettings, "TextureScaleMaxAreaFactor", 25.f); +        F32 max_vsize = 0.f; +        bool on_screen = false; -    F32 max_vsize = 0.f; -    bool on_screen = false; +        U32 face_count = 0; -    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) -        { -            LLFace* face = (*(imagep->getFaceList(i)))[fi]; +        F32 bias = (F32) llroundf(powf(4, LLViewerTexture::sDesiredDiscardBias - 1.f)); -            if (face && face->getViewerObject()) +        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)              { -                F32 radius; -                F32 cos_angle_to_view_dir; -                static LLCachedControl<F32> bias_unimportant_threshold(gSavedSettings, "TextureBiasUnimportantFactor", 0.25f); -                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 -                // shows one letter at a time -                // -                // Maximum usage examples: huge chunk of terrain repeats texture -                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; - -                // 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; -                } +                LLFace* face = (*(imagep->getFaceList(i)))[fi]; -                if (apply_bias) +                if (face && face->getViewerObject())                  { -                    F32 bias = powf(4, LLViewerTexture::sDesiredDiscardBias - 1.f); -                    bias = (F32) llround(bias); -                    vsize /= bias; +                    ++face_count; +                    F32 radius; +                    F32 cos_angle_to_view_dir; +                    static LLCachedControl<F32> bias_unimportant_threshold(gSavedSettings, "TextureBiasUnimportantFactor", 0.25f); + +                    if ((gFrameCount - face->mLastTextureUpdate) > 10) +                    { // only call calcPixelArea at most once every 10 frames for a given face +                        // this helps eliminate redundant calls to calcPixelArea for faces that have multiple textures +                        // assigned to them, such as is the case with GLTF materials or Blinn-Phong materials +                        face->mInFrustum = face->calcPixelArea(cos_angle_to_view_dir, radius); +                        face->mLastTextureUpdate = gFrameCount; +                    } + +                    F32 vsize = face->getPixelArea(); + +                    on_screen = face->mInFrustum; + +                    // 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 +                    // TODO: make this work with the GLTF texture transforms +                    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; + +                    // apply bias to offscreen faces all the time, but only to onscreen faces when bias is large +                    if (!face->mInFrustum || LLViewerTexture::sDesiredDiscardBias > 2.f) +                    { +                        vsize /= bias; +                    } + +                    max_vsize = llmax(max_vsize, 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; +        if (face_count > 1024) +        { // this texture is used in so many places we should just boost it and not bother checking its vsize +            // this is especially important because the above is not time sliced and can hit multiple ms for a single texture +            imagep->setBoostLevel(LLViewerFetchedTexture::BOOST_HIGH);          } -    } +        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); +        imagep->addTextureStats(max_vsize); +    }  #if 0      imagep->setDebugText(llformat("%d/%d - %d/%d -- %d/%d", diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index dcaf85b894..b7738b9135 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -3219,6 +3219,7 @@ void LLVOVolume::updateSpotLightPriority()      {          return;      } +    LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME;      F32 r = getLightRadius();      LLVector3 pos = mDrawable->getPositionAgent(); | 
