From a3312328bfd211998e32985e0c4b0ff242b8c8cf Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Tue, 28 Jun 2022 10:00:52 -0700 Subject: SL-17510: Fix frequently updating meshes (ex: sculpties) causing expensive octree updates by removing them from the static octree via makeActive --- indra/newview/llvovolume.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'indra/newview/llvovolume.cpp') diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index bae3d540e3..eee3bbc9cc 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -230,6 +230,7 @@ LLVOVolume::LLVOVolume(const LLUUID &id, const LLPCode pcode, LLViewerRegion *re mMediaImplList.resize(getNumTEs()); mLastFetchedMediaVersion = -1; + mServerVolumeUpdateCount = 0; memset(&mIndexInTex, 0, sizeof(S32) * LLRender::NUM_VOLUME_TEXTURE_CHANNELS); mMDCImplCount = 0; mLastRiggingInfoLOD = -1; @@ -400,6 +401,7 @@ U32 LLVOVolume::processUpdateMessage(LLMessageSystem *mesgsys, if (setVolume(volume_params, 0)) { markForUpdate(TRUE); + onVolumeUpdateFromServer(); } } @@ -436,6 +438,7 @@ U32 LLVOVolume::processUpdateMessage(LLMessageSystem *mesgsys, if (setVolume(volume_params, 0)) { markForUpdate(TRUE); + onVolumeUpdateFromServer(); } S32 res2 = unpackTEMessage(*dp); if (TEM_INVALID == res2) @@ -551,6 +554,15 @@ U32 LLVOVolume::processUpdateMessage(LLMessageSystem *mesgsys, return retval; } +void LLVOVolume::onVolumeUpdateFromServer() +{ + constexpr U32 UPDATES_UNTIL_ACTIVE = 8; + ++mServerVolumeUpdateCount; + if (mDrawable && !mDrawable->isActive() && mServerVolumeUpdateCount > UPDATES_UNTIL_ACTIVE) + { + mDrawable->makeActive(); + } +} void LLVOVolume::animateTextures() { -- cgit v1.3 From 21d581ed389fe8a23967332b77e213403a51f908 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Thu, 30 Jun 2022 15:23:53 -0700 Subject: SL-17448: Fix LOD/octree update feedback loops causing LOD fluctuations. May also fix octree updates on mere material changes due to general refactoring. --- indra/newview/llvovolume.cpp | 39 ++++++++++++++++++--------------------- indra/newview/llvovolume.h | 4 ++-- 2 files changed, 20 insertions(+), 23 deletions(-) (limited to 'indra/newview/llvovolume.cpp') diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index eee3bbc9cc..074ad35af4 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -1758,17 +1758,6 @@ BOOL LLVOVolume::genBBoxes(BOOL force_global) } } - bool rigged = false; - - if (!isAnimatedObject()) - { - rigged = isRiggedMesh() && isAttachment(); - } - else - { - rigged = isRiggedMesh() && getControlAvatar() && getControlAvatar()->mPlaying; - } - if (any_valid_boxes) { if (rebuild) @@ -1933,7 +1922,7 @@ void LLVOVolume::updateRelativeXform(bool force_identity) } } -bool LLVOVolume::lodOrSculptChanged(LLDrawable *drawable, BOOL &compiled) +bool LLVOVolume::lodOrSculptChanged(LLDrawable *drawable, BOOL &compiled, BOOL &should_update_octree_bounds) { LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME; bool regen_faces = false; @@ -1965,6 +1954,9 @@ bool LLVOVolume::lodOrSculptChanged(LLDrawable *drawable, BOOL &compiled) } compiled = TRUE; + // new_lod > old_lod breaks a feedback loop between LOD updates and + // bounding box updates. + should_update_octree_bounds = should_update_octree_bounds || mSculptChanged || new_lod > old_lod; sNumLODChanges += new_num_faces; if ((S32)getNumTEs() != getVolume()->getNumFaces()) @@ -2024,8 +2016,6 @@ BOOL LLVOVolume::updateGeometry(LLDrawable *drawable) group->dirtyMesh(); } - BOOL compiled = FALSE; - updateRelativeXform(); if (mDrawable.isNull()) // Not sure why this is happening, but it is... @@ -2033,49 +2023,56 @@ BOOL LLVOVolume::updateGeometry(LLDrawable *drawable) return TRUE; // No update to complete } + BOOL compiled = FALSE; + BOOL should_update_octree_bounds = bool(getRiggedVolume()); + if (mVolumeChanged || mFaceMappingChanged) { dirtySpatialGroup(drawable->isState(LLDrawable::IN_REBUILD_Q1)); bool was_regen_faces = false; + should_update_octree_bounds = true; if (mVolumeChanged) { - was_regen_faces = lodOrSculptChanged(drawable, compiled); + was_regen_faces = lodOrSculptChanged(drawable, compiled, should_update_octree_bounds); drawable->setState(LLDrawable::REBUILD_VOLUME); } else if (mSculptChanged || mLODChanged || mColorChanged) { compiled = TRUE; - was_regen_faces = lodOrSculptChanged(drawable, compiled); + was_regen_faces = lodOrSculptChanged(drawable, compiled, should_update_octree_bounds); } if (!was_regen_faces) { regenFaces(); } - - genBBoxes(FALSE); } else if (mLODChanged || mSculptChanged || mColorChanged) { dirtySpatialGroup(drawable->isState(LLDrawable::IN_REBUILD_Q1)); compiled = TRUE; - lodOrSculptChanged(drawable, compiled); + lodOrSculptChanged(drawable, compiled, should_update_octree_bounds); if(drawable->isState(LLDrawable::REBUILD_RIGGED | LLDrawable::RIGGED)) { updateRiggedVolume(false); } - genBBoxes(FALSE); } // it has its own drawable (it's moved) or it has changed UVs or it has changed xforms from global<->local else { compiled = TRUE; // All it did was move or we changed the texture coordinate offset - genBBoxes(FALSE); } + if (should_update_octree_bounds || !mDrawable->getSpatialExtents()->isFinite3()) + { + // Generate bounding boxes if needed, and update the object's size in the + // octree + genBBoxes(FALSE); + } + // Update face flags updateFaceFlags(); diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h index cbc7735968..8009c92702 100644 --- a/indra/newview/llvovolume.h +++ b/indra/newview/llvovolume.h @@ -233,7 +233,7 @@ public: void updateFaceFlags(); void regenFaces(); - BOOL genBBoxes(BOOL force_global); + BOOL genBBoxes(BOOL force_global); void preRebuild(); virtual void updateSpatialExtents(LLVector4a& min, LLVector4a& max); virtual F32 getBinRadius(); @@ -393,7 +393,7 @@ protected: void removeMediaImpl(S32 texture_index) ; private: - bool lodOrSculptChanged(LLDrawable *drawable, BOOL &compiled); + bool lodOrSculptChanged(LLDrawable *drawable, BOOL &compiled, BOOL &shouldUpdateOctreeBounds); public: -- cgit v1.3 From 65fb1c26f1266c68b1c6c663c49e25d9a5d62028 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 1 Jul 2022 14:52:31 -0700 Subject: SL-17448: Be more thorough about generating bounding boxes that don't affect the octree --- indra/newview/llvovolume.cpp | 14 ++++++-------- indra/newview/llvovolume.h | 2 +- 2 files changed, 7 insertions(+), 9 deletions(-) (limited to 'indra/newview/llvovolume.cpp') diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 074ad35af4..d86e135116 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -1682,7 +1682,7 @@ void LLVOVolume::regenFaces() } } -BOOL LLVOVolume::genBBoxes(BOOL force_global) +BOOL LLVOVolume::genBBoxes(BOOL force_global, BOOL should_update_octree_bounds) { LL_PROFILE_ZONE_SCOPED; BOOL res = TRUE; @@ -1760,7 +1760,7 @@ BOOL LLVOVolume::genBBoxes(BOOL force_global) if (any_valid_boxes) { - if (rebuild) + if (rebuild && should_update_octree_bounds) { //get the Avatar associated with this object if it's rigged LLVOAvatar* avatar = nullptr; @@ -2066,12 +2066,10 @@ BOOL LLVOVolume::updateGeometry(LLDrawable *drawable) // All it did was move or we changed the texture coordinate offset } - if (should_update_octree_bounds || !mDrawable->getSpatialExtents()->isFinite3()) - { - // Generate bounding boxes if needed, and update the object's size in the - // octree - genBBoxes(FALSE); - } + should_update_octree_bounds = should_update_octree_bounds || !mDrawable->getSpatialExtents()->isFinite3(); + // Generate bounding boxes if needed, and update the object's size in the + // octree + genBBoxes(FALSE, should_update_octree_bounds); // Update face flags updateFaceFlags(); diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h index 8009c92702..ce6c155883 100644 --- a/indra/newview/llvovolume.h +++ b/indra/newview/llvovolume.h @@ -233,7 +233,7 @@ public: void updateFaceFlags(); void regenFaces(); - BOOL genBBoxes(BOOL force_global); + BOOL genBBoxes(BOOL force_global, BOOL should_update_octree_bounds = FALSE); void preRebuild(); virtual void updateSpatialExtents(LLVector4a& min, LLVector4a& max); virtual F32 getBinRadius(); -- cgit v1.3 From f74a17ca7240363c23990649df98b2cc7ab17d62 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Tue, 5 Jul 2022 16:10:16 -0700 Subject: SL-17448: Also update the octree box if there is a position rebuild --- indra/newview/llvovolume.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'indra/newview/llvovolume.cpp') diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index d86e135116..eb8ff29aca 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -2024,7 +2024,9 @@ BOOL LLVOVolume::updateGeometry(LLDrawable *drawable) } BOOL compiled = FALSE; - BOOL should_update_octree_bounds = bool(getRiggedVolume()); + // This should be true in most cases, unless we're sure no octree update is + // needed. + BOOL should_update_octree_bounds = bool(getRiggedVolume()) || mDrawable->isState(LLDrawable::REBUILD_POSITION) || !mDrawable->getSpatialExtents()->isFinite3(); if (mVolumeChanged || mFaceMappingChanged) { @@ -2066,7 +2068,6 @@ BOOL LLVOVolume::updateGeometry(LLDrawable *drawable) // All it did was move or we changed the texture coordinate offset } - should_update_octree_bounds = should_update_octree_bounds || !mDrawable->getSpatialExtents()->isFinite3(); // Generate bounding boxes if needed, and update the object's size in the // octree genBBoxes(FALSE, should_update_octree_bounds); -- cgit v1.3 From 0aaf52c77c6c65258ca580557b6fd0766011471c Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 8 Jul 2022 16:25:21 -0700 Subject: SL-17691: Make objects active if there are too many material updates from the server --- indra/newview/llvovolume.cpp | 21 +++++++++++++++------ indra/newview/llvovolume.h | 4 ++-- 2 files changed, 17 insertions(+), 8 deletions(-) (limited to 'indra/newview/llvovolume.cpp') diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index eb8ff29aca..367d8e328d 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -230,7 +230,7 @@ LLVOVolume::LLVOVolume(const LLUUID &id, const LLPCode pcode, LLViewerRegion *re mMediaImplList.resize(getNumTEs()); mLastFetchedMediaVersion = -1; - mServerVolumeUpdateCount = 0; + mServerDrawableUpdateCount = 0; memset(&mIndexInTex, 0, sizeof(S32) * LLRender::NUM_VOLUME_TEXTURE_CHANNELS); mMDCImplCount = 0; mLastRiggingInfoLOD = -1; @@ -388,6 +388,7 @@ U32 LLVOVolume::processUpdateMessage(LLMessageSystem *mesgsys, } gPipeline.markTextured(mDrawable); + onDrawableUpdateFromServer(); mFaceMappingChanged = TRUE; mTexAnimMode = 0; } @@ -401,7 +402,7 @@ U32 LLVOVolume::processUpdateMessage(LLMessageSystem *mesgsys, if (setVolume(volume_params, 0)) { markForUpdate(TRUE); - onVolumeUpdateFromServer(); + onDrawableUpdateFromServer(); } } @@ -412,6 +413,7 @@ U32 LLVOVolume::processUpdateMessage(LLMessageSystem *mesgsys, // S32 result = unpackTEMessage(mesgsys, _PREHASH_ObjectData, (S32) block_num); + onDrawableUpdateFromServer(); if (result & teDirtyBits) { updateTEData(); @@ -438,9 +440,10 @@ U32 LLVOVolume::processUpdateMessage(LLMessageSystem *mesgsys, if (setVolume(volume_params, 0)) { markForUpdate(TRUE); - onVolumeUpdateFromServer(); + onDrawableUpdateFromServer(); } S32 res2 = unpackTEMessage(*dp); + onDrawableUpdateFromServer(); if (TEM_INVALID == res2) { // There's something bogus in the data that we're unpacking. @@ -501,6 +504,7 @@ U32 LLVOVolume::processUpdateMessage(LLMessageSystem *mesgsys, } gPipeline.markTextured(mDrawable); + onDrawableUpdateFromServer(); mFaceMappingChanged = TRUE; mTexAnimMode = 0; } @@ -519,6 +523,7 @@ U32 LLVOVolume::processUpdateMessage(LLMessageSystem *mesgsys, LLDataPackerBinaryBuffer tdp(tdpbuffer, 1024); mesgsys->getBinaryDataFast(_PREHASH_ObjectData, _PREHASH_TextureEntry, tdpbuffer, 0, block_num, 1024); S32 result = unpackTEMessage(tdp); + onDrawableUpdateFromServer(); if (result & teDirtyBits) { updateTEData(); @@ -554,11 +559,15 @@ U32 LLVOVolume::processUpdateMessage(LLMessageSystem *mesgsys, return retval; } -void LLVOVolume::onVolumeUpdateFromServer() +// Called when a volume, material, etc is updated by the server, possibly by a +// script. If this occurs too often for this object, mark it as active so that +// it doesn't disrupt the octree/render batches, thereby potentially causing a +// big performance penalty. +void LLVOVolume::onDrawableUpdateFromServer() { constexpr U32 UPDATES_UNTIL_ACTIVE = 8; - ++mServerVolumeUpdateCount; - if (mDrawable && !mDrawable->isActive() && mServerVolumeUpdateCount > UPDATES_UNTIL_ACTIVE) + ++mServerDrawableUpdateCount; + if (mDrawable && !mDrawable->isActive() && mServerDrawableUpdateCount > UPDATES_UNTIL_ACTIVE) { mDrawable->makeActive(); } diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h index 66c87494df..71ac152490 100644 --- a/indra/newview/llvovolume.h +++ b/indra/newview/llvovolume.h @@ -170,7 +170,6 @@ public: const LLMatrix4& getWorldMatrix(LLXformMatrix* xform) const; void markForUpdate(BOOL priority); - void onVolumeUpdateFromServer(); void markForUnload() { LLViewerObject::markForUnload(TRUE); mVolumeChanged = TRUE; } void faceMappingChanged() { mFaceMappingChanged=TRUE; }; @@ -387,6 +386,7 @@ protected: static S32 mRenderComplexity_last; static S32 mRenderComplexity_current; + void onDrawableUpdateFromServer(); void requestMediaDataUpdate(bool isNew); void cleanUpMediaImpls(); void addMediaImpl(LLViewerMediaImpl* media_impl, S32 texture_index) ; @@ -425,7 +425,7 @@ private: LLPointer mLightTexture; media_list_t mMediaImplList; S32 mLastFetchedMediaVersion; // as fetched from the server, starts as -1 - U64 mServerVolumeUpdateCount; + U64 mServerDrawableUpdateCount; S32 mIndexInTex[LLRender::NUM_VOLUME_TEXTURE_CHANNELS]; S32 mMDCImplCount; -- cgit v1.3 From 1614e4390b514de33609ea94835e75c6ddf9b316 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Tue, 12 Jul 2022 14:43:31 -0700 Subject: SL-17691: Consolidate calls to onDrawableUpdateFromServer to reduce false positives, change mServerDrawableUpdateCount from U64->U32 --- indra/newview/llvovolume.cpp | 19 ++++++++++++------- indra/newview/llvovolume.h | 2 +- 2 files changed, 13 insertions(+), 8 deletions(-) (limited to 'indra/newview/llvovolume.cpp') diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 367d8e328d..f4a938e57d 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -326,6 +326,9 @@ U32 LLVOVolume::processUpdateMessage(LLMessageSystem *mesgsys, LLColor4U color; const S32 teDirtyBits = (TEM_CHANGE_TEXTURE|TEM_CHANGE_COLOR|TEM_CHANGE_MEDIA); + const bool previously_volume_changed = mVolumeChanged; + const bool previously_face_mapping_changed = mFaceMappingChanged; + const bool previously_color_changed = mColorChanged; // Do base class updates... U32 retval = LLViewerObject::processUpdateMessage(mesgsys, user_data, block_num, update_type, dp); @@ -388,7 +391,6 @@ U32 LLVOVolume::processUpdateMessage(LLMessageSystem *mesgsys, } gPipeline.markTextured(mDrawable); - onDrawableUpdateFromServer(); mFaceMappingChanged = TRUE; mTexAnimMode = 0; } @@ -402,7 +404,6 @@ U32 LLVOVolume::processUpdateMessage(LLMessageSystem *mesgsys, if (setVolume(volume_params, 0)) { markForUpdate(TRUE); - onDrawableUpdateFromServer(); } } @@ -413,7 +414,6 @@ U32 LLVOVolume::processUpdateMessage(LLMessageSystem *mesgsys, // S32 result = unpackTEMessage(mesgsys, _PREHASH_ObjectData, (S32) block_num); - onDrawableUpdateFromServer(); if (result & teDirtyBits) { updateTEData(); @@ -440,10 +440,8 @@ U32 LLVOVolume::processUpdateMessage(LLMessageSystem *mesgsys, if (setVolume(volume_params, 0)) { markForUpdate(TRUE); - onDrawableUpdateFromServer(); } S32 res2 = unpackTEMessage(*dp); - onDrawableUpdateFromServer(); if (TEM_INVALID == res2) { // There's something bogus in the data that we're unpacking. @@ -504,7 +502,6 @@ U32 LLVOVolume::processUpdateMessage(LLMessageSystem *mesgsys, } gPipeline.markTextured(mDrawable); - onDrawableUpdateFromServer(); mFaceMappingChanged = TRUE; mTexAnimMode = 0; } @@ -523,7 +520,6 @@ U32 LLVOVolume::processUpdateMessage(LLMessageSystem *mesgsys, LLDataPackerBinaryBuffer tdp(tdpbuffer, 1024); mesgsys->getBinaryDataFast(_PREHASH_ObjectData, _PREHASH_TextureEntry, tdpbuffer, 0, block_num, 1024); S32 result = unpackTEMessage(tdp); - onDrawableUpdateFromServer(); if (result & teDirtyBits) { updateTEData(); @@ -556,6 +552,15 @@ U32 LLVOVolume::processUpdateMessage(LLMessageSystem *mesgsys, // ...and clean up any media impls cleanUpMediaImpls(); + if (( + (mVolumeChanged && !previously_volume_changed) || + (mFaceMappingChanged && !previously_face_mapping_changed) || + (mColorChanged && !previously_color_changed) + ) + && !mLODChanged) { + onDrawableUpdateFromServer(); + } + return retval; } diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h index 71ac152490..4136c13315 100644 --- a/indra/newview/llvovolume.h +++ b/indra/newview/llvovolume.h @@ -425,7 +425,7 @@ private: LLPointer mLightTexture; media_list_t mMediaImplList; S32 mLastFetchedMediaVersion; // as fetched from the server, starts as -1 - U64 mServerDrawableUpdateCount; + U32 mServerDrawableUpdateCount; S32 mIndexInTex[LLRender::NUM_VOLUME_TEXTURE_CHANNELS]; S32 mMDCImplCount; -- cgit v1.3