diff --git a/indra/llappearance/llavatarjoint.cpp b/indra/llappearance/llavatarjoint.cpp index 29642be099..381665a1d5 100644 --- a/indra/llappearance/llavatarjoint.cpp +++ b/indra/llappearance/llavatarjoint.cpp @@ -181,7 +181,11 @@ BOOL LLAvatarJoint::updateLOD(F32 pixel_area, BOOL activate) for (child_list_t::iterator iter = mChildren.begin(); iter != mChildren.end(); ++iter) { - LLAvatarJoint* joint = dynamic_cast(*iter); +// Make this s static cast. The dynamic cast must be working or it would have been crashing on the nullptr in the next line. +// LLAvatarJoint* joint = dynamic_cast(*iter); + LLAvatarJoint* joint = static_cast(*iter); +// + F32 jointLOD = joint->getLOD(); if (found_lod || jointLOD == DEFAULT_AVATAR_JOINT_LOD) diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 54507531e9..f5a074903a 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -3869,6 +3869,28 @@ Value 3 + AvatarExtentRefreshPeriodBatch + + Comment + how many frames do we spread over by default when refreshing extents (default is 4) + Persist + 1 + Type + S32 + Value + 4 + + AvatarExtentRefreshMaxPerBatch + + Comment + how many avatars do we want to handle in total per batch (default is 5) + Persist + 1 + Type + S32 + Value + 5 + DebugAvatarAppearanceMessage Comment diff --git a/indra/newview/lldrawable.cpp b/indra/newview/lldrawable.cpp index d0c3dafc94..46c195c47c 100644 --- a/indra/newview/lldrawable.cpp +++ b/indra/newview/lldrawable.cpp @@ -53,6 +53,7 @@ #include "llvocache.h" #include "llcontrolavatar.h" #include "lldrawpoolavatar.h" +#include "llskinningutil.h" const F32 MIN_INTERPOLATE_DISTANCE_SQUARED = 0.001f * 0.001f; const F32 MAX_INTERPOLATE_DISTANCE_SQUARED = 10.f * 10.f; @@ -94,7 +95,10 @@ void LLDrawable::incrementVisible() LLDrawable::LLDrawable(LLViewerObject *vobj, bool new_entry) : LLViewerOctreeEntryData(LLViewerOctreeEntry::LLDRAWABLE), LLTrace::MemTrackable("LLDrawable"), - mVObjp(vobj) + mVObjp(vobj), + mSkinningMatCache(nullptr), + mLastSkinningMatCacheFrame(0), + mCacheSize(0) { init(new_entry); } @@ -140,7 +144,7 @@ void LLDrawable::init(bool new_entry) llassert(!vo_entry->getGroup()); //not in the object cache octree. } - + llassert(!vo_entry || vo_entry->getEntry() == mEntry); initVisible(sCurVisible - 2);//invisible for the current frame and the last frame. @@ -164,7 +168,10 @@ void LLDrawable::unload() } facep->clearState(LLFace::RIGGED); } - + // ckinning matrix caching + delete[] mSkinningMatCache; + mSkinningMatCache = nullptr; + // pVVol->markForUpdate(TRUE); } diff --git a/indra/newview/lldrawable.h b/indra/newview/lldrawable.h index c65ccb78b7..46ec3ba15d 100644 --- a/indra/newview/lldrawable.h +++ b/indra/newview/lldrawable.h @@ -66,7 +66,9 @@ class LLDrawable public: LLDrawable(const LLDrawable& rhs) : LLTrace::MemTrackable("LLDrawable"), - LLViewerOctreeEntryData(rhs) + LLViewerOctreeEntryData(rhs), + mLastSkinningMatCacheFrame(0), + mCacheSize(0) { *this = rhs; } @@ -79,6 +81,12 @@ public: static void initClass(); + // per frame matrix cache + U32 mLastSkinningMatCacheFrame; + LLMatrix4a* mSkinningMatCache; + U32 mCacheSize; + // + LLDrawable(LLViewerObject *vobj, bool new_entry = false); void markDead(); // Mark this drawable as dead diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp index f7f86dbf26..47bcce45ac 100644 --- a/indra/newview/lldrawpoolavatar.cpp +++ b/indra/newview/lldrawpoolavatar.cpp @@ -1864,9 +1864,13 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer( LLVector4a* norm = has_normal ? (LLVector4a*) normal.get() : NULL; //build matrix palette - LLMatrix4a mat[LL_MAX_JOINTS_PER_MESH_OBJECT]; - U32 count = LLSkinningUtil::getMeshJointCount(skin); - LLSkinningUtil::initSkinningMatrixPalette((LLMatrix4*)mat, count, skin, avatar); + // per frame cache of skinning matrices + //LLMatrix4a mat[LL_MAX_JOINTS_PER_MESH_OBJECT]; + //U32 count = LLSkinningUtil::getMeshJointCount(skin); + //LLSkinningUtil::initSkinningMatrixPalette(mat, count, skin, avatar); + U32 count = LLSkinningUtil::getMeshJointCount(skin); + auto mat = getCacheSkinningMats(drawable, skin, count, avatar); + // LLSkinningUtil::checkSkinWeights(weights, buffer->getNumVerts(), skin); LLMatrix4a bind_shape_matrix; @@ -1902,6 +1906,32 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer( } } +// cache per frame Skinning mats +LLMatrix4a* LLDrawPoolAvatar::getCacheSkinningMats(LLDrawable* drawable, const LLMeshSkinInfo* skin, + U32 count, LLVOAvatar* avatar) +{ + if (drawable->mCacheSize < count || !drawable->mSkinningMatCache) + { + delete[](drawable->mSkinningMatCache); + drawable->mCacheSize = count; + drawable->mSkinningMatCache = new LLMatrix4a[count]; + } + + if (drawable->mSkinningMatCache && LLFrameTimer::getFrameCount() != drawable->mLastSkinningMatCacheFrame) + { +// LL_DEBUGS("Skinning") << "Call InitSkinningMatrixPalette for drawable @" << (U64)drawable << LL_ENDL; + // add caching of matrix pallette as high up the stack as we can + drawable->mLastSkinningMatCacheFrame = LLFrameTimer::getFrameCount(); + LLSkinningUtil::initSkinningMatrixPalette(drawable->mSkinningMatCache, count, skin, avatar); + } + else + { +// LL_DEBUGS("Skinning") << "Avoiding InitSkinningMatrixPalette for drawable @" << (U64)drawable << LL_ENDL; + } + return drawable->mSkinningMatCache; +} +// + void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow) { if (!avatar->shouldRenderRigged()) @@ -1956,11 +1986,16 @@ void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow) { if (sShaderLevel > 0) { - // upload matrix palette to shader - LLMatrix4a mat[LL_MAX_JOINTS_PER_MESH_OBJECT]; - U32 count = LLSkinningUtil::getMeshJointCount(skin); - LLSkinningUtil::initSkinningMatrixPalette((LLMatrix4*)mat, count, skin, avatar); + // upload matrix palette to shader + // per frame cache of skinning matrices + //LLMatrix4a mat[LL_MAX_JOINTS_PER_MESH_OBJECT]; + //U32 count = LLSkinningUtil::getMeshJointCount(skin); + //LLSkinningUtil::initSkinningMatrixPalette(mat, count, skin, avatar); + U32 count = LLSkinningUtil::getMeshJointCount(skin); + auto mat = getCacheSkinningMats(drawable, skin, count, avatar); + // + stop_glerror(); F32 mp[LL_MAX_JOINTS_PER_MESH_OBJECT*12]; @@ -2152,9 +2187,14 @@ void LLDrawPoolAvatar::renderRiggedShadows(LLVOAvatar* avatar) if (sShaderLevel > 0) { // upload matrix palette to shader - LLMatrix4a mat[LL_MAX_JOINTS_PER_MESH_OBJECT]; + + // per frame cache of skinning matrices + //LLMatrix4a mat[LL_MAX_JOINTS_PER_MESH_OBJECT]; + //U32 count = LLSkinningUtil::getMeshJointCount(skin); + //LLSkinningUtil::initSkinningMatrixPalette(mat, count, skin, avatar); U32 count = LLSkinningUtil::getMeshJointCount(skin); - LLSkinningUtil::initSkinningMatrixPalette((LLMatrix4*)mat, count, skin, avatar); + auto mat = getCacheSkinningMats(drawable, skin, count, avatar); + // stop_glerror(); diff --git a/indra/newview/lldrawpoolavatar.h b/indra/newview/lldrawpoolavatar.h index 5959631b85..41bf13edfa 100644 --- a/indra/newview/lldrawpoolavatar.h +++ b/indra/newview/lldrawpoolavatar.h @@ -28,6 +28,7 @@ #define LL_LLDRAWPOOLAVATAR_H #include "lldrawpool.h" +#include "fsareasearch.h" class LLVOAvatar; class LLGLSLShader; @@ -64,7 +65,10 @@ public: /*virtual*/ BOOL isDead(); static LLMatrix4& getModelView(); - + // per frame cache + static LLMatrix4a* getCacheSkinningMats(LLDrawable* drawable, const LLMeshSkinInfo* skin, U32 count, + LLVOAvatar* avatar); + // /*virtual*/ LLDrawPool *instancePool(); /*virtual*/ S32 getNumPasses(); diff --git a/indra/newview/llface.h b/indra/newview/llface.h index 945a44c814..993437f031 100644 --- a/indra/newview/llface.h +++ b/indra/newview/llface.h @@ -39,6 +39,7 @@ #include "llvertexbuffer.h" #include "llviewertexture.h" #include "lldrawable.h" +#include "lljoint.h" class LLFacePool; class LLVolume; @@ -267,7 +268,6 @@ public: private: LLPointer mVertexBuffer; - U32 mState; LLFacePool* mDrawPoolp; U32 mPoolType; diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp index c743275dc8..26692a5f8d 100644 --- a/indra/newview/llfloatermodelpreview.cpp +++ b/indra/newview/llfloatermodelpreview.cpp @@ -4318,12 +4318,16 @@ BOOL LLModelPreview::render() //quick 'n dirty software vertex skinning //build matrix palette - + // use Mat4a part of the caching changes, no point in using the cache itself in the preview though. + //LLMatrix4 mat[LL_MAX_JOINTS_PER_MESH_OBJECT]; LLMatrix4a mat[LL_MAX_JOINTS_PER_MESH_OBJECT]; - const LLMeshSkinInfo *skin = &model->mSkinInfo; + const LLMeshSkinInfo *skin = &model->mSkinInfo; U32 count = LLSkinningUtil::getMeshJointCount(skin); - LLSkinningUtil::initSkinningMatrixPalette((LLMatrix4*)mat, count, - skin, getPreviewAvatar()); + //LLSkinningUtil::initSkinningMatrixPalette((LLMatrix4*)mat, count, + // skin, getPreviewAvatar()); + LLSkinningUtil::initSkinningMatrixPalette(mat, count, + skin, getPreviewAvatar()); + // LLMatrix4a bind_shape_matrix; bind_shape_matrix.loadu(skin->mBindShapeMatrix); U32 max_joints = LLSkinningUtil::getMaxJointCount(); diff --git a/indra/newview/llskinningutil.cpp b/indra/newview/llskinningutil.cpp index 70ef135665..1573a77bf6 100644 --- a/indra/newview/llskinningutil.cpp +++ b/indra/newview/llskinningutil.cpp @@ -128,49 +128,100 @@ void LLSkinningUtil::scrubInvalidJoints(LLVOAvatar *avatar, LLMeshSkinInfo* skin skin->mInvalidJointsScrubbed = true; } +// Per frame SkinningMatrix Caching +//void LLSkinningUtil::initSkinningMatrixPalette( +// LLMatrix4* mat, +// S32 count, +// const LLMeshSkinInfo* skin, +// LLVOAvatar *avatar) +//{ +// initJointNums(const_cast(skin), avatar); +// for (U32 j = 0; j < count; ++j) +// { +// LLJoint *joint = avatar->getJoint(skin->mJointNums[j]); +// if (joint) +// { +//#define MAT_USE_SSE +//#ifdef MAT_USE_SSE +// LLMatrix4a bind, world, res; +// bind.loadu(skin->mInvBindMatrix[j]); +// world.loadu(joint->getWorldMatrix()); +// matMul(bind, world, res); +// memcpy(mat[j].mMatrix, res.mMatrix, 16 * sizeof(float)); +//#else +// mat[j] = skin->mInvBindMatrix[j]; +// mat[j] *= joint->getWorldMatrix(); +//#endif +// } +// else +// { +// mat[j] = skin->mInvBindMatrix[j]; +// // This shouldn't happen - in mesh upload, skinned +// // rendering should be disabled unless all joints are +// // valid. In other cases of skinned rendering, invalid +// // joints should already have been removed during scrubInvalidJoints(). +// LL_WARNS_ONCE("Avatar") << avatar->getFullname() +// << " rigged to invalid joint name " << skin->mJointNames[j] +// << " num " << skin->mJointNums[j] << LL_ENDL; +// LL_WARNS_ONCE("Avatar") << avatar->getFullname() +// << " avatar build state: isBuilt() " << avatar->isBuilt() +// << " mInitFlags " << avatar->mInitFlags << LL_ENDL; +//#if 0 +// dump_avatar_and_skin_state("initSkinningMatrixPalette joint not found", avatar, skin); +//#endif +// } +// } +//} + +#ifndef LL_RELEASE_FOR_DOWNLOAD +static LLTrace::BlockTimerStatHandle FTM_SKINNING_INIT("Init Skinning Mats"); +#endif + void LLSkinningUtil::initSkinningMatrixPalette( - LLMatrix4* mat, + LLMatrix4a* mat, S32 count, const LLMeshSkinInfo* skin, LLVOAvatar *avatar) { - initJointNums(const_cast(skin), avatar); - for (U32 j = 0; j < count; ++j) +#ifndef LL_RELEASE_FOR_DOWNLOAD + // This timer is too hot for normal use (though better now with caching) + LL_RECORD_BLOCK_TIME(FTM_SKINNING_INIT); +#endif + LLMatrix4a bind[LL_MAX_JOINTS_PER_MESH_OBJECT]; + LLMatrix4a world[LL_MAX_JOINTS_PER_MESH_OBJECT]; + + initJointNums(const_cast(skin), avatar); +// TODO: Refactored to encourage the compiler to optimise better but it's too old and stubborn. Need to hand tool the SIMD. +// TODO: There are two overheads in this function casued by the unaligned loads. use Matrix4a +// TODO: getWorldMatrix forces a reverse recursion up through the skelly. Check if this is happening efficiently. + for (S32 j = 0; j < count; ++j) { LLJoint *joint = avatar->getJoint(skin->mJointNums[j]); - if (joint) - { -#define MAT_USE_SSE -#ifdef MAT_USE_SSE - LLMatrix4a bind, world, res; - bind.loadu(skin->mInvBindMatrix[j]); - world.loadu(joint->getWorldMatrix()); - matMul(bind,world,res); - memcpy(mat[j].mMatrix,res.mMatrix,16*sizeof(float)); -#else - mat[j] = skin->mInvBindMatrix[j]; - mat[j] *= joint->getWorldMatrix(); -#endif - } - else - { - mat[j] = skin->mInvBindMatrix[j]; - // This shouldn't happen - in mesh upload, skinned - // rendering should be disabled unless all joints are - // valid. In other cases of skinned rendering, invalid - // joints should already have been removed during scrubInvalidJoints(). - LL_WARNS_ONCE("Avatar") << avatar->getFullname() - << " rigged to invalid joint name " << skin->mJointNames[j] - << " num " << skin->mJointNums[j] << LL_ENDL; - LL_WARNS_ONCE("Avatar") << avatar->getFullname() - << " avatar build state: isBuilt() " << avatar->isBuilt() - << " mInitFlags " << avatar->mInitFlags << LL_ENDL; -#if 0 - dump_avatar_and_skin_state("initSkinningMatrixPalette joint not found", avatar, skin); -#endif - } + if (joint != nullptr){ + bind[j].loadu(skin->mInvBindMatrix[j]); + world[j].loadu(joint->getWorldMatrix()); + matMul(bind[j], world[j], mat[j]); + } + else + { + mat[j].loadu(skin->mInvBindMatrix[j]); + // This shouldn't happen - in mesh upload, skinned + // rendering should be disabled unless all joints are + // valid. In other cases of skinned rendering, invalid + // joints should already have been removed during scrubInvalidJoints(). + // Beq note - Oct 2018 Animesh - Many rigged meshes still fail here. ('mElbowLeeft' typo in the rigging data) + LL_WARNS_ONCE("Avatar") << avatar->getFullname() + << " rigged to invalid joint name " << skin->mJointNames[j] + << " num " << skin->mJointNums[j] << LL_ENDL; + LL_WARNS_ONCE("Avatar") << avatar->getFullname() + << " avatar build state: isBuilt() " << avatar->isBuilt() + << " mInitFlags " << avatar->mInitFlags << LL_ENDL; + + } +//LL_DEBUGS("Skinning") << "[" << avatar->getFullname() << "] joint(" << skin->mJointNames[j] << ") matices bind(" << bind << ") world(" << world << ")" << LL_ENDL; } } +// void LLSkinningUtil::checkSkinWeights(LLVector4a* weights, U32 num_vertices, const LLMeshSkinInfo* skin) { diff --git a/indra/newview/llskinningutil.h b/indra/newview/llskinningutil.h index 104743a378..d626655abd 100644 --- a/indra/newview/llskinningutil.h +++ b/indra/newview/llskinningutil.h @@ -38,8 +38,11 @@ namespace LLSkinningUtil U32 getMaxJointCount(); U32 getMeshJointCount(const LLMeshSkinInfo *skin); void scrubInvalidJoints(LLVOAvatar *avatar, LLMeshSkinInfo* skin); - void initSkinningMatrixPalette(LLMatrix4* mat, S32 count, const LLMeshSkinInfo* skin, LLVOAvatar *avatar); - void checkSkinWeights(LLVector4a* weights, U32 num_vertices, const LLMeshSkinInfo* skin); + // Per frame SkinningMatrix Caching + //void initSkinningMatrixPalette(LLMatrix4* mat, S32 count, const LLMeshSkinInfo* skin, LLVOAvatar* avatar); + void initSkinningMatrixPalette(LLMatrix4a* mat, S32 count, const LLMeshSkinInfo* skin, LLVOAvatar* avatar); + // + void checkSkinWeights(LLVector4a* weights, U32 num_vertices, const LLMeshSkinInfo* skin); void scrubSkinWeights(LLVector4a* weights, U32 num_vertices, const LLMeshSkinInfo* skin); void getPerVertexSkinMatrix(F32* weights, LLMatrix4a* mat, bool handle_bad_scale, LLMatrix4a& final_mat, U32 max_joints); void initJointNums(LLMeshSkinInfo* skin, LLVOAvatar *avatar); diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp index 2e04022892..9b70d85d11 100644 --- a/indra/newview/llviewerobjectlist.cpp +++ b/indra/newview/llviewerobjectlist.cpp @@ -1001,7 +1001,9 @@ void LLViewerObjectList::update(LLAgent &agent) static std::vector idle_list; U32 idle_count = 0; - + // need avatar count for dynamic BB load balancing + mNumAvatars = 0; + // { LL_RECORD_BLOCK_TIME(FTM_IDLE_COPY); @@ -1020,6 +1022,10 @@ void LLViewerObjectList::update(LLAgent &agent) idle_list[idle_count] = objectp; } ++idle_count; +// need avatar count for dynamic BB load balancing + if (objectp->isAvatar()) + mNumAvatars++; +// } else { // There shouldn't be any NULL pointers in the list, but they have caused diff --git a/indra/newview/llviewerobjectlist.h b/indra/newview/llviewerobjectlist.h index 597847278a..4bbfbbf6af 100644 --- a/indra/newview/llviewerobjectlist.h +++ b/indra/newview/llviewerobjectlist.h @@ -152,7 +152,6 @@ public: boost::signals2::connection setNewObjectCallback(new_object_callback_t cb); new_object_signal_t mNewObjectSignal; // - //////////////////////////////////////////// // // Only accessed by markDead in LLViewerObject @@ -162,6 +161,10 @@ public: S32 getOrphanParentCount() const { return (S32) mOrphanParents.size(); } S32 getOrphanCount() const { return mNumOrphans; } + // need avatar count for dynamic BB load balancing + S32 getAvatarCount() const { return mNumAvatars; } + // + void orphanize(LLViewerObject *childp, U32 parent_id, U32 ip, U32 port); void findOrphans(LLViewerObject* objectp, U32 ip, U32 port); @@ -208,6 +211,9 @@ protected: std::vector mOrphanParents; // LocalID/ip,port of orphaned objects std::vector mOrphanChildren; // UUID's of orphaned objects S32 mNumOrphans; + // need avatar count for dynamic BB load balancing + S32 mNumAvatars; + // typedef std::vector > vobj_list_t; diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 48639e849a..e205d4831d 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -1390,9 +1390,10 @@ static LLTrace::BlockTimerStatHandle FTM_AVATAR_EXTENT_UPDATE("Av Upd Extent"); void LLVOAvatar::calculateSpatialExtents(LLVector4a& newMin, LLVector4a& newMax) { LL_RECORD_BLOCK_TIME(FTM_AVATAR_EXTENT_UPDATE); - - S32 box_detail = gSavedSettings.getS32("AvatarBoundingBoxComplexity"); - +// not called as often as it used to be but still no harm in optimising +// S32 box_detail = gSavedSettings.getS32("AvatarBoundingBoxComplexity"); + static const LLCachedControl box_detail(gSavedSettings, "AvatarBoundingBoxComplexity"); +// // FIXME the update_min_max function used below assumes there is a // known starting point, but in general there isn't. Ideally the // box update logic should be modified to handle the no-point-yet @@ -2569,7 +2570,21 @@ void LLVOAvatar::idleUpdate(LLAgent &agent, const F64 &time) } // Update should be happening max once per frame. - const S32 upd_freq = 4; // force update every upd_freq frames. + // enable dynamic spreading of the BB calculations + //const S32 upd_freq = 4; // force update every upd_freq frames. + static LLCachedControl refreshPeriod(gSavedSettings, "AvatarExtentRefreshPeriodBatch"); + static LLCachedControl refreshMaxPerPeriod(gSavedSettings, "AvatarExtentRefreshMaxPerBatch"); + static S32 upd_freq = refreshPeriod; // initialise to a reasonable defauilt of 1 batch + static S32 lastRecalibrationFrame{ 0 }; + + const S32 thisFrame = LLDrawable::getCurrentFrame(); + if (thisFrame - lastRecalibrationFrame >= upd_freq) + { + // Only update at the start of a cycle. . + upd_freq = (((gObjectList.getAvatarCount() - 1) / refreshMaxPerPeriod) + 1)*refreshPeriod; + lastRecalibrationFrame = thisFrame; + } + // if ((mLastAnimExtents[0]==LLVector3())|| (mLastAnimExtents[1])==LLVector3()) { @@ -2577,7 +2592,10 @@ void LLVOAvatar::idleUpdate(LLAgent &agent, const F64 &time) } else { - mNeedsExtentUpdate = ((LLDrawable::getCurrentFrame()+mID.mData[0])%upd_freq==0); + // enable dynamic spreading of the BB calculations + //mNeedsExtentUpdate = ((LLDrawable::getCurrentFrame()+mID.mData[0]) % upd_freq == 0); + mNeedsExtentUpdate = ((thisFrame + mID.mData[0]) % upd_freq == 0); + // } LLScopedContextString str("avatar_idle_update " + getFullname()); @@ -10661,8 +10679,10 @@ void LLVOAvatar::updateRiggingInfo() //LL_INFOS() << "done update rig count is " << countRigInfoTab(mJointRiggingInfoTab) << LL_ENDL; //LL_DEBUGS("RigSpammish") << getFullname() << " after update rig tab:" << LL_ENDL; // Performance tweak - S32 joint_count, box_count; - showRigInfoTabExtents(this, mJointRiggingInfoTab, joint_count, box_count); + // remove debug only stuff on hot path + //S32 joint_count, box_count; + //showRigInfoTabExtents(this, mJointRiggingInfoTab, joint_count, box_count); + // //LL_DEBUGS("RigSpammish") << "uses " << joint_count << " joints " << " nonzero boxes: " << box_count << LL_ENDL; // Performance tweak } diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 0cb2b5adab..9e88ed506b 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -1641,7 +1641,11 @@ BOOL LLVOVolume::updateLOD() if (lod_changed) { - if (debugLoggingEnabled("AnimatedObjectsLinkset")) + // avoid unfortunate sleep during trylock by static check + //if(debugLoggingEnabled("AnimatedObjectsLinkset")) + static auto debug_logging_on = debugLoggingEnabled("AnimatedObjectsLinkset"); + if (debug_logging_on) + // { if (isAnimatedObject() && isRiggedMesh()) { @@ -4615,8 +4619,12 @@ const LLMatrix4& LLVOVolume::getWorldMatrix(LLXformMatrix* xform) const void LLVOVolume::markForUpdate(BOOL priority) { - if (debugLoggingEnabled("AnimatedObjectsLinkset")) - { + // avoid unfortunate sleep during trylock by static check + //if(debugLoggingEnabled("AnimatedObjectsLinkset")) + static auto debug_logging_on = debugLoggingEnabled("AnimatedObjectsLinkset"); + if (debug_logging_on) + // + { if (isAnimatedObject() && isRiggedMesh()) { std::string vobj_name = llformat("Vol%p", this); @@ -4941,6 +4949,7 @@ static LLTrace::BlockTimerStatHandle FTM_RIGGED_OCTREE("Octree"); void LLRiggedVolume::update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, const LLVolume* volume) { + bool copy = false; if (volume->getNumVolumeFaces() != getNumVolumeFaces()) { @@ -4982,7 +4991,10 @@ void LLRiggedVolume::update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, cons LLMatrix4a mat[kMaxJoints]; U32 maxJoints = LLSkinningUtil::getMeshJointCount(skin); - LLSkinningUtil::initSkinningMatrixPalette((LLMatrix4*)mat, maxJoints, skin, avatar); + // Skinning Matrix caching + //LLSkinningUtil::initSkinningMatrixPalette((LLMatrix4)mat, maxJoints, skin, avatar); + LLSkinningUtil::initSkinningMatrixPalette(mat, maxJoints, skin, avatar); + // S32 rigged_vert_count = 0; S32 rigged_face_count = 0; @@ -5669,7 +5681,10 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) continue; } - std::string vobj_name = llformat("Vol%p", vobj); +// Stop doing stupid stuff we don;t need to. +// Moving this inside a debug enabled check +// std::string vobj_name = llformat("Vol%p", vobj); +// if (vobj->isMesh() && ((vobj->getVolume() && !vobj->getVolume()->isMeshAssetLoaded()) || !gMeshRepo.meshRezEnabled())) @@ -5683,26 +5698,37 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) const LLVector3& scale = vobj->getScale(); group->mSurfaceArea += volume->getSurfaceArea() * llmax(llmax(scale.mV[0], scale.mV[1]), scale.mV[2]); } - - bool is_mesh = vobj->isMesh(); - F32 est_tris = vobj->getEstTrianglesMax(); +// Stop doing stupid stuff we don;t need on the critical path + //bool is_mesh = vobj->isMesh(); + //F32 est_tris = vobj->getEstTrianglesMax(); vobj->updateControlAvatar(); - - LL_DEBUGS("AnimatedObjectsLinkset") << vobj_name << " rebuilding, isAttachment: " << (U32) vobj->isAttachment() - << " is_mesh " << is_mesh - << " est_tris " << est_tris - << " is_animated " << vobj->isAnimatedObject() - << " can_animate " << vobj->canBeAnimatedObject() - << " cav " << vobj->getControlAvatar() - << " lod " << vobj->getLOD() - << " drawable rigged " << (drawablep->isState(LLDrawable::RIGGED)) - << " drawable state " << drawablep->getState() - << " playing " << (U32) (vobj->getControlAvatar() ? vobj->getControlAvatar()->mPlaying : false) - << " frame " << LLFrameTimer::getFrameCount() - << LL_ENDL; + // Also avoid unfortunate sleep during trylock by static check + //if(debugLoggingEnabled("AnimatedObjectsLinkset")) + static auto debug_logging_on = debugLoggingEnabled("AnimatedObjectsLinkset"); + if (debug_logging_on) + // + { + std::string vobj_name = llformat("Vol%p", vobj); + bool is_mesh = vobj->isMesh(); + F32 est_tris = vobj->getEstTrianglesMax(); + + LL_DEBUGS("AnimatedObjectsLinkset") << vobj_name << " rebuilding, isAttachment: " << (U32) vobj->isAttachment() + << " is_mesh " << is_mesh + << " est_tris " << est_tris + << " is_animated " << vobj->isAnimatedObject() + << " can_animate " << vobj->canBeAnimatedObject() + << " cav " << vobj->getControlAvatar() + << " lod " << vobj->getLOD() + << " drawable rigged " << (drawablep->isState(LLDrawable::RIGGED)) + << " drawable state " << drawablep->getState() + << " playing " << (U32) (vobj->getControlAvatar() ? vobj->getControlAvatar()->mPlaying : false) + << " frame " << LLFrameTimer::getFrameCount() + << LL_ENDL; + } + // Pointless. We already checked this and have used it. + //llassert_always(vobj); - llassert_always(vobj); // Z's protection auto-derender code if (enableVolumeSAPProtection()) @@ -6242,8 +6268,12 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group) if (drawablep && !drawablep->isDead() && drawablep->isState(LLDrawable::REBUILD_ALL) && !drawablep->isState(LLDrawable::RIGGED) ) { LLVOVolume* vobj = drawablep->getVOVolume(); - if (debugLoggingEnabled("AnimatedObjectsLinkset")) - { + // avoid unfortunate sleep during trylock by static check + //if(debugLoggingEnabled("AnimatedObjectsLinkset")) + static auto debug_logging_on = debugLoggingEnabled("AnimatedObjectsLinkset"); + if (debug_logging_on) + // + { if (vobj->isAnimatedObject() && vobj->isRiggedMesh()) { std::string vobj_name = llformat("Vol%p", vobj); diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 24074386e7..8c7fc16023 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -3480,8 +3480,12 @@ void LLPipeline::markRebuild(LLDrawable *drawablep, LLDrawable::EDrawableFlags f { if (drawablep && !drawablep->isDead() && assertInitialized()) { - if (debugLoggingEnabled("AnimatedObjectsLinkset")) - { + // avoid unfortunate sleep during trylock by static check + //if(debugLoggingEnabled("AnimatedObjectsLinkset")) + static auto debug_logging_on = debugLoggingEnabled("AnimatedObjectsLinkset"); + if (debug_logging_on) + // + { LLVOVolume *vol_obj = drawablep->getVOVolume(); if (vol_obj && vol_obj->isAnimatedObject() && vol_obj->isRiggedMesh()) {