diff options
author | RunitaiLinden <davep@lindenlab.com> | 2024-08-28 13:14:58 -0500 |
---|---|---|
committer | RunitaiLinden <davep@lindenlab.com> | 2024-08-28 13:14:58 -0500 |
commit | 1f58884db9c026c1a74f693fc84e37a2f66830e3 (patch) | |
tree | cf6de765652b2b6a9de51f104604ba0682605825 | |
parent | 9d689c6145cefcc86b228462279859dfb726429d (diff) |
#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(); |