From 616f2b639bc6907e810664522304305337646292 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Mon, 6 Jun 2022 19:57:03 -0500 Subject: SL-17532 Potential fix for some rigged mesh draw order issues. --- indra/newview/llvovolume.cpp | 51 ++++++++++++++++++++++++++++++++++++++------ 1 file changed, 44 insertions(+), 7 deletions(-) (limited to 'indra/newview/llvovolume.cpp') diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 126a25115d..eb1e2cbd80 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -5480,7 +5480,7 @@ static inline void add_face(T*** list, U32* count, T* face) { if (count[1] < MAX_FACE_COUNT) { - face->setDrawOrderIndex(count[1]); + //face->setDrawOrderIndex(count[1]); list[1][count[1]++] = face; } } @@ -5488,15 +5488,40 @@ static inline void add_face(T*** list, U32* count, T* face) { if (count[0] < MAX_FACE_COUNT) { - face->setDrawOrderIndex(count[0]); + //face->setDrawOrderIndex(count[0]); list[0][count[0]++] = face; } } } +// return index into linkset for given object (0 for root prim) +U32 get_linkset_index(LLVOVolume* vobj) +{ + LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWABLE; + if (vobj->isRootEdit()) + { + return 0; + } + + LLViewerObject* root = vobj->getRootEdit(); + U32 idx = 1; + for (auto& child : root->getChildren()) + { + if (child == vobj) + { + return idx; + } + ++idx; + } + + llassert(false); + return idx; //should never get here +} + void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) { LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME; + if (group->changeLOD()) { group->mLastUpdateDistance = group->mDistance; @@ -5655,6 +5680,8 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) avatar->addAttachmentOverridesForObject(vobj, NULL, false); } + U32 linkset_index = get_linkset_index(vobj); + // Standard rigged mesh attachments: bool rigged = !vobj->isAnimatedObject() && skinInfo && vobj->isAttachment(); // Animated objects. Have to check for isRiggedMesh() to @@ -5674,6 +5701,9 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) continue; } + // order by linkset index first and face index second + facep->setDrawOrderIndex(linkset_index * 100 + i); + //ALWAYS null out vertex buffer on rebuild -- if the face lands in a render // batch, it will recover its vertex buffer reference from the spatial group facep->setVertexBuffer(NULL); @@ -5698,11 +5728,6 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) if (facep->isState(LLFace::RIGGED)) { //face is not rigged but used to be, remove from rigged face pool - LLDrawPoolAvatar* pool = (LLDrawPoolAvatar*) facep->getPool(); - if (pool) - { - pool->removeFace(facep); - } facep->clearState(LLFace::RIGGED); facep->mAvatar = NULL; facep->mSkinInfo = NULL; @@ -6158,6 +6183,13 @@ struct CompareBatchBreakerRigged } }; +struct CompareDrawOrder +{ + bool operator()(const LLFace* const& lhs, const LLFace* const& rhs) + { + return lhs->getDrawOrderIndex() < rhs->getDrawOrderIndex(); + } +}; U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace** faces, U32 face_count, BOOL distance_sort, BOOL batch_textures, BOOL rigged) { @@ -6202,6 +6234,11 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace //sort faces by things that break batches, including avatar and mesh id std::sort(faces, faces + face_count, CompareBatchBreakerRigged()); } + else + { + // preserve legacy draw order for rigged faces + std::sort(faces, faces + face_count, CompareDrawOrder()); + } } else if (!distance_sort) { -- cgit v1.2.3 From 3e1db1f18405d50a63d772722175c859c1952f92 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Tue, 7 Jun 2022 10:36:59 -0500 Subject: SL-17532 Cleanup from hasty commit (thanks to Henri for the prodding). --- indra/newview/llvovolume.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/newview/llvovolume.cpp') diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index eb1e2cbd80..f47fb6287c 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -5505,7 +5505,7 @@ U32 get_linkset_index(LLVOVolume* vobj) LLViewerObject* root = vobj->getRootEdit(); U32 idx = 1; - for (auto& child : root->getChildren()) + for (const auto& child : root->getChildren()) { if (child == vobj) { -- cgit v1.2.3 From 076a89506243e8d4037f34c2a78278ff6ee0f1f7 Mon Sep 17 00:00:00 2001 From: Maxim Nikolenko Date: Tue, 21 Jun 2022 17:55:29 +0300 Subject: SL-17635 remove unused variables --- indra/newview/llvovolume.cpp | 10 ---------- 1 file changed, 10 deletions(-) (limited to 'indra/newview/llvovolume.cpp') diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index f47fb6287c..832803ea6e 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -1748,16 +1748,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) { -- cgit v1.2.3 From 916da8cfb8b394239c523ee9b70c698dabb4ba98 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Tue, 19 Apr 2022 17:29:15 -0700 Subject: SL-17021: Fix triangle mesh overlays being generated twice when avatar animation is frozen --- indra/newview/llvovolume.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/newview/llvovolume.cpp') diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 832803ea6e..89056c64bb 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -4852,7 +4852,7 @@ void LLRiggedVolume::update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, cons if (is_paused) { S32 frames_paused = LLFrameTimer::getFrameCount() - avatar->getMotionController().getPausedFrame(); - if (frames_paused > 2) + if (frames_paused > 1) { return; } -- cgit v1.2.3 From 0a08645eb6a86a3279beb925ebba88393bb89936 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Wed, 20 Apr 2022 10:25:05 -0700 Subject: SL-17021: Do not do software skinning/octree building of a face during picking unless eligible for narrow-phase intersect check (fast broad-phase intersect pre-check not yet implemented) --- indra/newview/llvovolume.cpp | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) (limited to 'indra/newview/llvovolume.cpp') diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 89056c64bb..fce233969b 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -4585,7 +4585,7 @@ BOOL LLVOVolume::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& { if ((pick_rigged) || (getAvatar() && (getAvatar()->isSelf()) && (LLFloater::isVisible(gFloaterTools)))) { - updateRiggedVolume(true); + updateRiggedVolume(true, LLRiggedVolume::DO_NOT_UPDATE_FACES); volume = mRiggedVolume; transform = false; } @@ -4660,6 +4660,7 @@ BOOL LLVOVolume::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& continue; } + updateRiggedVolume(true, i); face_hit = volume->lineSegmentIntersect(local_start, local_end, i, &p, &tc, &n, &tn); @@ -4783,7 +4784,7 @@ void LLVOVolume::clearRiggedVolume() } } -void LLVOVolume::updateRiggedVolume(bool force_update) +void LLVOVolume::updateRiggedVolume(bool force_update, LLRiggedVolume::FaceIndex face_index) { LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME; //Update mRiggedVolume to match current animation frame of avatar. @@ -4818,10 +4819,10 @@ void LLVOVolume::updateRiggedVolume(bool force_update) updateRelativeXform(); } - mRiggedVolume->update(skin, avatar, volume); + mRiggedVolume->update(skin, avatar, volume, face_index); } -void LLRiggedVolume::update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, const LLVolume* volume) +void LLRiggedVolume::update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, const LLVolume* volume, FaceIndex face_index) { LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME; bool copy = false; @@ -4871,7 +4872,24 @@ void LLRiggedVolume::update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, cons S32 rigged_vert_count = 0; S32 rigged_face_count = 0; LLVector4a box_min, box_max; - for (S32 i = 0; i < volume->getNumVolumeFaces(); ++i) + S32 face_begin; + S32 face_end; + if (face_index == DO_NOT_UPDATE_FACES) + { + face_begin = 0; + face_end = 0; + } + else if (face_index == UPDATE_ALL_FACES) + { + face_begin = 0; + face_end = volume->getNumVolumeFaces(); + } + else + { + face_begin = face_index; + face_end = face_begin + 1; + } + for (S32 i = face_begin; i < face_end; ++i) { const LLVolumeFace& vol_face = volume->getVolumeFace(i); -- cgit v1.2.3 From 1d3b85356f516fa2f5a5d49572743dc2a03ac86a Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Wed, 20 Apr 2022 16:19:42 -0700 Subject: SL-17021: Only calculate the octree for a skinned mesh if intersection falls inside an on-the-fly calculated bounding box. Technically not a broadphase check, but better than calculating an octree for a bunch of meshes. --- indra/newview/llvovolume.cpp | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) (limited to 'indra/newview/llvovolume.cpp') diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index fce233969b..6a53e704c3 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -4660,7 +4660,9 @@ BOOL LLVOVolume::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& continue; } - updateRiggedVolume(true, i); + // This calculates the bounding box of the skinned mesh from scratch. It's actually quite expensive, but not nearly as expensive as building a full octree. + // rebuild_face_octrees = false because an octree for this face will be built later only if needed for narrow phase picking. + updateRiggedVolume(true, i, false); face_hit = volume->lineSegmentIntersect(local_start, local_end, i, &p, &tc, &n, &tn); @@ -4784,7 +4786,7 @@ void LLVOVolume::clearRiggedVolume() } } -void LLVOVolume::updateRiggedVolume(bool force_update, LLRiggedVolume::FaceIndex face_index) +void LLVOVolume::updateRiggedVolume(bool force_update, LLRiggedVolume::FaceIndex face_index, bool rebuild_face_octrees) { LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME; //Update mRiggedVolume to match current animation frame of avatar. @@ -4819,10 +4821,10 @@ void LLVOVolume::updateRiggedVolume(bool force_update, LLRiggedVolume::FaceIndex updateRelativeXform(); } - mRiggedVolume->update(skin, avatar, volume, face_index); + mRiggedVolume->update(skin, avatar, volume, face_index, rebuild_face_octrees); } -void LLRiggedVolume::update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, const LLVolume* volume, FaceIndex face_index) +void LLRiggedVolume::update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, const LLVolume* volume, FaceIndex face_index, bool rebuild_face_octrees) { LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME; bool copy = false; @@ -4974,15 +4976,12 @@ void LLRiggedVolume::update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, cons } + if (rebuild_face_octrees) { delete dst_face.mOctree; dst_face.mOctree = NULL; - LLVector4a size; - size.setSub(dst_face.mExtents[1], dst_face.mExtents[0]); - size.splat(size.getLength3().getF32()*0.5f); - - dst_face.createOctree(1.f); + dst_face.createOctree(); } } } -- cgit v1.2.3 From b97aec0da2e1ec97a8bfd408bdce61d91b4fcdab Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Wed, 20 Apr 2022 17:40:44 -0700 Subject: SL-17021: Change meaning of first argument to LLVOVolume::updateRiggedVolume from 'force_update' to 'foce_treat_as_rigged' --- indra/newview/llvovolume.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'indra/newview/llvovolume.cpp') diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 6a53e704c3..5440159eb3 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -1691,7 +1691,7 @@ BOOL LLVOVolume::genBBoxes(BOOL force_global) // updates needed, set REBUILD_RIGGED accordingly. // Without the flag, this will remove unused rigged volumes, which we are not currently very aggressive about. - updateRiggedVolume(); + updateRiggedVolume(false); } LLVolume* volume = mRiggedVolume; @@ -1983,7 +1983,7 @@ BOOL LLVOVolume::updateGeometry(LLDrawable *drawable) if (mDrawable->isState(LLDrawable::REBUILD_RIGGED)) { - updateRiggedVolume(); + updateRiggedVolume(false); genBBoxes(FALSE); mDrawable->clearState(LLDrawable::REBUILD_RIGGED); } @@ -4786,13 +4786,13 @@ void LLVOVolume::clearRiggedVolume() } } -void LLVOVolume::updateRiggedVolume(bool force_update, LLRiggedVolume::FaceIndex face_index, bool rebuild_face_octrees) +void LLVOVolume::updateRiggedVolume(bool force_treat_as_rigged, LLRiggedVolume::FaceIndex face_index, bool rebuild_face_octrees) { LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME; //Update mRiggedVolume to match current animation frame of avatar. //Also update position/size in octree. - if ((!force_update) && (!treatAsRigged())) + if ((!force_treat_as_rigged) && (!treatAsRigged())) { clearRiggedVolume(); @@ -5916,7 +5916,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) else { drawablep->clearState(LLDrawable::RIGGED); - vobj->updateRiggedVolume(); + vobj->updateRiggedVolume(false); } } } -- cgit v1.2.3 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.2.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 ++++++++++++++++++--------------------- 1 file changed, 18 insertions(+), 21 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(); -- cgit v1.2.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 ++++++-------- 1 file changed, 6 insertions(+), 8 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(); -- cgit v1.2.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.2.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 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 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(); } -- cgit v1.2.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 ++++++++++++------- 1 file changed, 12 insertions(+), 7 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; } -- cgit v1.2.3 From cdff7169083f054818bd54f43d602dc229a067c4 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Tue, 26 Jul 2022 10:36:58 -0700 Subject: SL-17801: Don't let external code delete the raw pointer to the picking octree --- indra/newview/llvovolume.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'indra/newview/llvovolume.cpp') diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index c4b51c474d..8bf9d12b33 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -4976,9 +4976,7 @@ void LLRiggedVolume::update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, cons if (rebuild_face_octrees) { - delete dst_face.mOctree; - dst_face.mOctree = NULL; - + dst_face.destroyOctree(); dst_face.createOctree(); } } -- cgit v1.2.3 From 7a8ac7689e37c90d61ccb3b9152304937950cc39 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Sat, 27 Aug 2022 00:45:37 +0300 Subject: SL-17779 Texture position changes were ignored on rigged meshes Since the performance overhaul project, there should be essentially no difference between rigged meshes and non-rigged as far as vertex buffer management is concerned. --- indra/newview/llvovolume.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'indra/newview/llvovolume.cpp') diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 56028e051f..e923115c43 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -6054,7 +6054,7 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group) { LLDrawable* drawablep = (LLDrawable*)(*drawable_iter)->getDrawable(); - if (drawablep && !drawablep->isDead() && drawablep->isState(LLDrawable::REBUILD_ALL) && !drawablep->isState(LLDrawable::RIGGED) ) + if (drawablep && !drawablep->isDead() && drawablep->isState(LLDrawable::REBUILD_ALL)) { LLVOVolume* vobj = drawablep->getVOVolume(); @@ -6088,8 +6088,6 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group) LLVertexBuffer* buff = face->getVertexBuffer(); if (buff) { - llassert(!face->isState(LLFace::RIGGED)); - if (!face->getGeometryVolume(*volume, face->getTEOffset(), vobj->getRelativeXform(), vobj->getRelativeXformInvTrans(), face->getGeomIndex())) { //something's gone wrong with the vertex buffer accounting, rebuild this group -- cgit v1.2.3 From 439aa79414edfe48f3bfa5d154987d741308bdbb Mon Sep 17 00:00:00 2001 From: Andrey Lihatskiy Date: Mon, 24 Oct 2022 22:14:20 +0300 Subject: SL-18432 Fix for alpha sorting --- indra/newview/llvovolume.cpp | 51 ++++++-------------------------------------- 1 file changed, 7 insertions(+), 44 deletions(-) (limited to 'indra/newview/llvovolume.cpp') diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index e923115c43..a4e0d367c8 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -5515,7 +5515,7 @@ static inline void add_face(T*** list, U32* count, T* face) { if (count[1] < MAX_FACE_COUNT) { - //face->setDrawOrderIndex(count[1]); + face->setDrawOrderIndex(count[1]); list[1][count[1]++] = face; } } @@ -5523,36 +5523,12 @@ static inline void add_face(T*** list, U32* count, T* face) { if (count[0] < MAX_FACE_COUNT) { - //face->setDrawOrderIndex(count[0]); + face->setDrawOrderIndex(count[0]); list[0][count[0]++] = face; } } } -// return index into linkset for given object (0 for root prim) -U32 get_linkset_index(LLVOVolume* vobj) -{ - LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWABLE; - if (vobj->isRootEdit()) - { - return 0; - } - - LLViewerObject* root = vobj->getRootEdit(); - U32 idx = 1; - for (const auto& child : root->getChildren()) - { - if (child == vobj) - { - return idx; - } - ++idx; - } - - llassert(false); - return idx; //should never get here -} - void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) { LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME; @@ -5714,8 +5690,6 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) { avatar->addAttachmentOverridesForObject(vobj, NULL, false); } - - U32 linkset_index = get_linkset_index(vobj); // Standard rigged mesh attachments: bool rigged = !vobj->isAnimatedObject() && skinInfo && vobj->isAttachment(); @@ -5736,9 +5710,6 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) continue; } - // order by linkset index first and face index second - facep->setDrawOrderIndex(linkset_index * 100 + i); - //ALWAYS null out vertex buffer on rebuild -- if the face lands in a render // batch, it will recover its vertex buffer reference from the spatial group facep->setVertexBuffer(NULL); @@ -5763,6 +5734,11 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) if (facep->isState(LLFace::RIGGED)) { //face is not rigged but used to be, remove from rigged face pool + LLDrawPoolAvatar* pool = (LLDrawPoolAvatar*)facep->getPool(); + if (pool) + { + pool->removeFace(facep); + } facep->clearState(LLFace::RIGGED); facep->mAvatar = NULL; facep->mSkinInfo = NULL; @@ -6216,14 +6192,6 @@ struct CompareBatchBreakerRigged } }; -struct CompareDrawOrder -{ - bool operator()(const LLFace* const& lhs, const LLFace* const& rhs) - { - return lhs->getDrawOrderIndex() < rhs->getDrawOrderIndex(); - } -}; - U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace** faces, U32 face_count, BOOL distance_sort, BOOL batch_textures, BOOL rigged) { LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME; @@ -6267,11 +6235,6 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace //sort faces by things that break batches, including avatar and mesh id std::sort(faces, faces + face_count, CompareBatchBreakerRigged()); } - else - { - // preserve legacy draw order for rigged faces - std::sort(faces, faces + face_count, CompareDrawOrder()); - } } else if (!distance_sort) { -- cgit v1.2.3