From d4b4187e4757e05466a1e6bad5d48afe90fb8994 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev <117672381+akleshchev@users.noreply.github.com> Date: Tue, 4 Aug 2026 21:15:49 +0300 Subject: #6071 Validity checks for LLViewerJointMesh::drawShape --- indra/newview/lltoolmorph.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'indra/newview/lltoolmorph.cpp') diff --git a/indra/newview/lltoolmorph.cpp b/indra/newview/lltoolmorph.cpp index 8ce9a8b632..5312ca752f 100644 --- a/indra/newview/lltoolmorph.cpp +++ b/indra/newview/lltoolmorph.cpp @@ -148,7 +148,7 @@ bool LLVisualParamHint::needsRender() void LLVisualParamHint::preRender(bool clear_depth) { - LLViewerWearable* wearable = (LLViewerWearable*)mWearablePtr; + LLViewerWearable* wearable = dynamic_cast(mWearablePtr); if (wearable) { wearable->setVolatile(true); @@ -258,7 +258,7 @@ bool LLVisualParamHint::render() gAgentAvatarp->setVisualParamWeight(mVisualParam->getID(), mLastParamWeight); mWearablePtr->setVisualParamWeight(mVisualParam->getID(), mLastParamWeight); - LLViewerWearable* wearable = (LLViewerWearable*)mWearablePtr; + LLViewerWearable* wearable = dynamic_cast(mWearablePtr); if (wearable) { wearable->setVolatile(false); -- cgit v1.3 From 0d11c7ff40396906a3438a562cdc694afdda572b Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev <117672381+akleshchev@users.noreply.github.com> Date: Tue, 4 Aug 2026 23:55:35 +0300 Subject: #6071 Software skinning was removed a while back remove dead code --- indra/newview/lldrawpoolavatar.cpp | 35 ++++++------ indra/newview/lltoolmorph.cpp | 2 + indra/newview/llviewerjointmesh.cpp | 103 ++---------------------------------- indra/newview/llviewerjointmesh.h | 5 -- indra/newview/llviewershadermgr.cpp | 39 ++++---------- indra/newview/llviewershadermgr.h | 1 - 6 files changed, 32 insertions(+), 153 deletions(-) (limited to 'indra/newview/lltoolmorph.cpp') diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp index f0f589e7f4..61f0e3e365 100644 --- a/indra/newview/lldrawpoolavatar.cpp +++ b/indra/newview/lldrawpoolavatar.cpp @@ -595,7 +595,15 @@ void LLDrawPoolAvatar::beginSkinned() { LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR; - // used for preview only + // Used for preview only, like LLVisualParamHint + // Uses deprecated logic!!! + if (!gAvatarProgram.isComplete()) + { + llassert(false); // Avatar shader shouldn't have failed if deferred shader loaded + sVertexProgram = nullptr; + LLGLSLShader::unbind(); + return; + } sVertexProgram = &gAvatarProgram; @@ -609,25 +617,18 @@ void LLDrawPoolAvatar::endSkinned() { LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR; - // if we're in software-blending, remember to set the fence _after_ we draw so we wait till this rendering is done - if (sShaderLevel > 0) - { - sRenderingSkinned = false; - sVertexProgram->disableTexture(LLViewerShaderMgr::BUMP_MAP); - gGL.getTexUnit(0)->activate(); - sVertexProgram->unbind(); - sShaderLevel = mShaderLevel; - } - else + if (sVertexProgram == nullptr) { - if(gPipeline.shadersLoaded()) - { - // software skinning, use a basic shader for windlight. - // TODO: find a better fallback method for software skinning. - sVertexProgram->unbind(); - } + return; } + // if we're in software-blending, remember to set the fence _after_ we draw so we wait till this rendering is done + sRenderingSkinned = false; + sVertexProgram->disableTexture(LLViewerShaderMgr::BUMP_MAP); + gGL.getTexUnit(0)->activate(); + sVertexProgram->unbind(); + sShaderLevel = mShaderLevel; + gGL.getTexUnit(0)->activate(); } diff --git a/indra/newview/lltoolmorph.cpp b/indra/newview/lltoolmorph.cpp index 5312ca752f..d2b32f8e23 100644 --- a/indra/newview/lltoolmorph.cpp +++ b/indra/newview/lltoolmorph.cpp @@ -143,6 +143,8 @@ void LLVisualParamHint::requestHintUpdates( LLVisualParamHint* exception1, LLVis bool LLVisualParamHint::needsRender() { + // needsRender gets called once per frame from + // LLViewerDynamicTexture::updateAllInstances() return mNeedsUpdate && mDelayFrames-- <= 0 && !gAgentAvatarp->getIsAppearanceAnimating() && mAllowsUpdates; } diff --git a/indra/newview/llviewerjointmesh.cpp b/indra/newview/llviewerjointmesh.cpp index 3306042826..42aed5906b 100644 --- a/indra/newview/llviewerjointmesh.cpp +++ b/indra/newview/llviewerjointmesh.cpp @@ -96,7 +96,6 @@ const S32 NUM_AXES = 3; // pivot parent 0-n -- child = n+1 static LLMatrix4 gJointMatUnaligned[LL_CHARACTER_MAX_JOINTS_PER_MESH]; -static LLMatrix4a gJointMatAligned[LL_CHARACTER_MAX_JOINTS_PER_MESH]; static LLMatrix3 gJointRotUnaligned[LL_CHARACTER_MAX_JOINTS_PER_MESH]; static LLVector4 gJointPivot[LL_CHARACTER_MAX_JOINTS_PER_MESH]; @@ -107,8 +106,6 @@ void LLViewerJointMesh::uploadJointMatrices() { S32 joint_num; LLPolyMesh *reference_mesh = mMesh->getReferenceMesh(); - LLDrawPool *poolp = mFace ? mFace->getPool() : NULL; - bool hardware_skinning = (poolp && poolp->getShaderLevel() > 0); //calculate joint matrices size_t num_joints = llmin(reference_mesh->mJointRenderData.size(), LL_CHARACTER_MAX_JOINTS_PER_MESH); @@ -116,10 +113,7 @@ void LLViewerJointMesh::uploadJointMatrices() { LLMatrix4 joint_mat = *reference_mesh->mJointRenderData[joint_num]->mWorldMatrix; - if (hardware_skinning) - { - joint_mat *= LLDrawPoolAvatar::getModelView(); - } + joint_mat *= LLDrawPoolAvatar::getModelView(); gJointMatUnaligned[joint_num] = joint_mat; gJointRotUnaligned[joint_num] = joint_mat.getMat3(); } @@ -171,8 +165,6 @@ void LLViewerJointMesh::uploadJointMatrices() } // upload matrices - if (hardware_skinning) - { GLfloat mat[45*4]; memset(mat, 0, sizeof(GLfloat)*45*4); @@ -193,15 +185,6 @@ void LLViewerJointMesh::uploadJointMatrices() LLGLSLShader::sCurBoundShaderPtr->uniform4fv(LLViewerShaderMgr::AVATAR_MATRIX, 45, mat); } stop_glerror(); - } - else - { - //load gJointMatUnaligned into gJointMatAligned - for (joint_num = 0; joint_num < num_joints; ++joint_num) - { - gJointMatAligned[joint_num].loadu(gJointMatUnaligned[joint_num]); - } - } } //-------------------------------------------------------------------- @@ -302,13 +285,9 @@ U32 LLViewerJointMesh::drawShape( F32 pixelArea, bool first_pass, bool is_dummy) if (mMesh->hasWeights()) { - LLDrawPool* poolp = mFace->getPool(); - if (poolp && (poolp->getShaderLevel() > 0)) + if (first_pass) { - if (first_pass) - { - uploadJointMatrices(); - } + uploadJointMatrices(); } buff->setBuffer(); @@ -368,15 +347,6 @@ void LLViewerJointMesh::updateFaceData(LLFace *face, F32 pixel_area, bool damp_w return; } - LLDrawPool *poolp = mFace->getPool(); - bool hardware_skinning = (poolp && poolp->getShaderLevel() > 0); - - if (!hardware_skinning && terse_update) - { //no need to do terse updates if we're doing software vertex skinning - // since mMesh is being copied into mVertexBuffer every frame - return; - } - LL_PROFILE_ZONE_SCOPED; LLStrider verticesp; @@ -460,75 +430,8 @@ bool LLViewerJointMesh::updateLOD(F32 pixel_area, bool activate) return (valid != activate); } -// static -void LLViewerJointMesh::updateGeometry(LLFace *mFace, LLPolyMesh *mMesh) -{ - LLStrider o_vertices; - LLStrider o_normals; - - //get vertex and normal striders - LLVertexBuffer* buffer = mFace->getVertexBuffer(); - buffer->getVertexStrider(o_vertices, 0); - buffer->getNormalStrider(o_normals, 0); - - F32* __restrict vert = o_vertices[0].mV; - F32* __restrict norm = o_normals[0].mV; - - const F32* __restrict weights = mMesh->getWeights(); - const LLVector4a* __restrict coords = (LLVector4a*) mMesh->getCoords(); - const LLVector4a* __restrict normals = (LLVector4a*) mMesh->getNormals(); - - U32 offset = mMesh->mFaceVertexOffset*4; - vert += offset; - norm += offset; - - for (U32 index = 0; index < mMesh->getNumVertices(); index++) - { - // equivalent to joint = floorf(weights[index]); - S32 joint = _mm_cvtt_ss2si(_mm_load_ss(weights+index)); - F32 w = weights[index] - joint; - - LLMatrix4a gBlendMat; - - if (w != 0.f) - { - // blend between matrices and apply - gBlendMat.setLerp(gJointMatAligned[joint+0], - gJointMatAligned[joint+1], w); - - LLVector4a res; - gBlendMat.affineTransform(coords[index], res); - res.store4a(vert+index*4); - gBlendMat.rotate(normals[index], res); - res.store4a(norm+index*4); - } - else - { // No lerp required in this case. - LLVector4a res; - gJointMatAligned[joint].affineTransform(coords[index], res); - res.store4a(vert+index*4); - gJointMatAligned[joint].rotate(normals[index], res); - res.store4a(norm+index*4); - } - } - - buffer->unmapBuffer(); -} - void LLViewerJointMesh::updateJointGeometry() { - if (!(mValid - && mMesh - && mFace - && mMesh->hasWeights() - && mFace->getVertexBuffer() - && LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_AVATAR) == 0)) - { - return; - } - - uploadJointMatrices(); - updateGeometry(mFace, mMesh); } void LLViewerJointMesh::dump() diff --git a/indra/newview/llviewerjointmesh.h b/indra/newview/llviewerjointmesh.h index cfe8ecdb67..1365c1ee48 100644 --- a/indra/newview/llviewerjointmesh.h +++ b/indra/newview/llviewerjointmesh.h @@ -67,11 +67,6 @@ public: void dump() override; bool isAnimatable() const override { return false; } - -private: - - //copy mesh into given face's vertex buffer, applying current animation pose - static void updateGeometry(LLFace* face, LLPolyMesh* mesh); }; #endif // LL_LLVIEWERJOINTMESH_H diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp index 27865f7598..6bbea54e43 100644 --- a/indra/newview/llviewershadermgr.cpp +++ b/indra/newview/llviewershadermgr.cpp @@ -128,7 +128,6 @@ LLGLSLShader gPathfindingNoNormalsProgram; //avatar shader handles LLGLSLShader gAvatarProgram; -LLGLSLShader gAvatarEyeballProgram; LLGLSLShader gImpostorProgram; // Effects Shaders @@ -413,7 +412,6 @@ void LLViewerShaderMgr::finalizeShaderList() //ONLY shaders that need WL Param management should be added here mShaderList.push_back(&gAvatarProgram); mShaderList.push_back(&gWaterProgram); - mShaderList.push_back(&gAvatarEyeballProgram); mShaderList.push_back(&gImpostorProgram); mShaderList.push_back(&gObjectBumpProgram); mShaderList.push_back(&gObjectFullbrightAlphaMaskProgram); @@ -699,7 +697,7 @@ void LLViewerShaderMgr::setShaders() if (loadShadersObject()) { //hardware skinning is enabled and rigged attachment shaders loaded correctly // cloth is a class3 shader - S32 avatar_class = 1; + constexpr S32 avatar_class = 1; // Set the actual level mShaderLevel[SHADER_AVATAR] = avatar_class; @@ -708,8 +706,11 @@ void LLViewerShaderMgr::setShaders() llassert(loaded); } else - { //hardware skinning not possible, neither is deferred rendering - llassert(false); // SHOULD NOT BE POSSIBLE + { + // SHOULD NOT BE POSSIBLE + // Hardware skinning not possible, neither is deferred rendering + // but both are a hard requirement, viewer will crash without them + LL_ERRS() << "Failed to load object shaders, cannot continue." << LL_ENDL; } } @@ -3104,14 +3105,6 @@ bool LLViewerShaderMgr::loadShadersAvatar() LL_PROFILE_ZONE_SCOPED; #if 1 // DEPRECATED -- forward rendering is deprecated bool success = true; - - if (mShaderLevel[SHADER_AVATAR] == 0) - { - gAvatarProgram.unload(); - gAvatarEyeballProgram.unload(); - return true; - } - if (success) { gAvatarProgram.mName = "Avatar Shader"; @@ -3135,27 +3128,13 @@ bool LLViewerShaderMgr::loadShadersAvatar() } } - if (success) - { - gAvatarEyeballProgram.mName = "Avatar Eyeball Program"; - gAvatarEyeballProgram.mFeatures.calculatesLighting = true; - gAvatarEyeballProgram.mFeatures.isSpecular = true; - gAvatarEyeballProgram.mFeatures.calculatesAtmospherics = true; - gAvatarEyeballProgram.mFeatures.hasGamma = true; - gAvatarEyeballProgram.mFeatures.hasAtmospherics = true; - gAvatarEyeballProgram.mFeatures.hasLighting = true; - gAvatarEyeballProgram.mFeatures.hasAlphaMask = true; - gAvatarEyeballProgram.mShaderFiles.clear(); - gAvatarEyeballProgram.mShaderFiles.push_back(make_pair("avatar/eyeballV.glsl", GL_VERTEX_SHADER)); - gAvatarEyeballProgram.mShaderFiles.push_back(make_pair("avatar/eyeballF.glsl", GL_FRAGMENT_SHADER)); - gAvatarEyeballProgram.mShaderLevel = mShaderLevel[SHADER_AVATAR]; - success = gAvatarEyeballProgram.createShader(); - } - if( !success ) { + // This isn't supposed to fail, otherwise defferred shaders would have failed. + // Is only used for avatar previews (like LLVisualParamHint) mShaderLevel[SHADER_AVATAR] = 0; mMaxAvatarShaderLevel = 0; + LL_WARNS() << "Failed to create avatar shader!" << LL_ENDL; return false; } #endif diff --git a/indra/newview/llviewershadermgr.h b/indra/newview/llviewershadermgr.h index 46da30017d..3efd23ad79 100644 --- a/indra/newview/llviewershadermgr.h +++ b/indra/newview/llviewershadermgr.h @@ -208,7 +208,6 @@ extern LLGLSLShader gPathfindingNoNormalsProgram; // avatar shader handles extern LLGLSLShader gAvatarProgram; -extern LLGLSLShader gAvatarEyeballProgram; extern LLGLSLShader gImpostorProgram; // Post Process Shaders -- cgit v1.3 From 0af5e55312bfc907cd3ab0a0711d3197f7527f14 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev <117672381+akleshchev@users.noreply.github.com> Date: Wed, 5 Aug 2026 15:33:44 +0300 Subject: #6071 Fix LLVisualParamHint's background image --- indra/newview/lltoolmorph.cpp | 15 +++++++++++++++ indra/newview/lltoolmorph.h | 1 + 2 files changed, 16 insertions(+) (limited to 'indra/newview/lltoolmorph.cpp') diff --git a/indra/newview/lltoolmorph.cpp b/indra/newview/lltoolmorph.cpp index d2b32f8e23..1f3115ef29 100644 --- a/indra/newview/lltoolmorph.cpp +++ b/indra/newview/lltoolmorph.cpp @@ -93,6 +93,20 @@ LLVisualParamHint::LLVisualParamHint( { LLVisualParamHint::sInstances.insert( this ); mBackgroundp = LLUI::getUIImage("avatar_thumb_bkgrnd.png"); + if (mBackgroundp) + { + LLViewerFetchedTexture* tex = dynamic_cast(mBackgroundp->getImage().get()); + if (tex) + { + tex->setKnownDrawSize(width, height); + } + + mBackgroundLoadedConnection = mBackgroundp->addLoadedCallback([this]() + { + mNeedsUpdate = true; + mDelayFrames = 0; + }); + } llassert(width != 0); llassert(height != 0); @@ -104,6 +118,7 @@ LLVisualParamHint::LLVisualParamHint( LLVisualParamHint::~LLVisualParamHint() { LLVisualParamHint::sInstances.erase( this ); + mBackgroundLoadedConnection.disconnect(); } //virtual diff --git a/indra/newview/lltoolmorph.h b/indra/newview/lltoolmorph.h index fb62ba9bba..9f4b5f6fe9 100644 --- a/indra/newview/lltoolmorph.h +++ b/indra/newview/lltoolmorph.h @@ -95,6 +95,7 @@ protected: LLJoint* mCamTargetJoint; // joint to target with preview camera LLUIImagePtr mBackgroundp; + boost::signals2::scoped_connection mBackgroundLoadedConnection; typedef std::set< LLVisualParamHint* > instance_list_t; static instance_list_t sInstances; -- cgit v1.3 From 68b08e47e98337c48705bfbd9b1f675ec3045bf3 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev <117672381+akleshchev@users.noreply.github.com> Date: Thu, 6 Aug 2026 22:36:32 +0300 Subject: #6071 Exra logging and guards for LLVisualParamHint --- indra/newview/lldrawpoolavatar.cpp | 2 ++ indra/newview/lltoolmorph.cpp | 29 ++++++++++++++++++++++++++++- indra/newview/llviewerjoint.cpp | 1 + indra/newview/llvoavatar.h | 1 + 4 files changed, 32 insertions(+), 1 deletion(-) (limited to 'indra/newview/lltoolmorph.cpp') diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp index 61f0e3e365..9386206e76 100644 --- a/indra/newview/lldrawpoolavatar.cpp +++ b/indra/newview/lldrawpoolavatar.cpp @@ -611,6 +611,7 @@ void LLDrawPoolAvatar::beginSkinned() sVertexProgram->bind(); sVertexProgram->setMinimumAlpha(LLDrawPoolAvatar::sMinimumAlpha); + sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP); } void LLDrawPoolAvatar::endSkinned() @@ -624,6 +625,7 @@ void LLDrawPoolAvatar::endSkinned() // if we're in software-blending, remember to set the fence _after_ we draw so we wait till this rendering is done sRenderingSkinned = false; + sVertexProgram->disableTexture(LLViewerShaderMgr::DIFFUSE_MAP); sVertexProgram->disableTexture(LLViewerShaderMgr::BUMP_MAP); gGL.getTexUnit(0)->activate(); sVertexProgram->unbind(); diff --git a/indra/newview/lltoolmorph.cpp b/indra/newview/lltoolmorph.cpp index 1f3115ef29..a545d32d12 100644 --- a/indra/newview/lltoolmorph.cpp +++ b/indra/newview/lltoolmorph.cpp @@ -165,6 +165,13 @@ bool LLVisualParamHint::needsRender() void LLVisualParamHint::preRender(bool clear_depth) { + LL_DEBUGS("ParamHint") << "preRender: param=" << mVisualParam->getName() + << " id=" << mVisualParam->getID() + << " weight=" << mVisualParamWeight + << " dirtyMesh=" << gAgentAvatarp->mDirtyMesh + << " pixelArea=" << gAgentAvatarp->mAdjustedPixelArea + << " appearanceAnimating=" << gAgentAvatarp->getIsAppearanceAnimating() + << LL_ENDL; LLViewerWearable* wearable = dynamic_cast(mWearablePtr); if (wearable) { @@ -184,6 +191,19 @@ void LLVisualParamHint::preRender(bool clear_depth) { gAgentAvatarp->updateGeometry(gAgentAvatarp->mDrawable); gAgentAvatarp->updateLOD(); + + if (gAgentAvatarp->mDrawable->isState(LLDrawable::REBUILD_GEOMETRY)) + { + LL_WARNS_ONCE("ParamHint") << "preRender: clearing REBUILD_GEOMETRY after updateGeometry/updateLOD" + << " param=" << mVisualParam->getName() + << " dirtyMesh=" << gAgentAvatarp->mDirtyMesh + << LL_ENDL; + // Clear REBUILD_GEOMETRY so that renderSkinned inside generateImpostor + // does not re-run updateMeshData() with a partially consistent mesh state, + // which would reassign mFace pointers on some meshes while others are + // mid-draw with stale vertex offsets. + gAgentAvatarp->mDrawable->clearState(LLDrawable::REBUILD_GEOMETRY); + } } else { @@ -263,8 +283,15 @@ bool LLVisualParamHint::render() LLViewerCamera::getInstance()->setPerspective(false, mOrigin.mX, mOrigin.mY, mFullWidth, mFullHeight, false); - if (gAgentAvatarp->mDrawable.notNull()) + llassert(!LLPipeline::sImpostorRender); // We are rendering this from UI, shouldn't be set + if (gAgentAvatarp->mDrawable.notNull() && !LLPipeline::sImpostorRender) { + LL_DEBUGS("ParamHint") << "render: generating impostor" + << " param=" << mVisualParam->getName() + << " drawableState=0x" << std::hex << gAgentAvatarp->mDrawable->getState() << std::dec + << " dirtyMesh=" << gAgentAvatarp->mDirtyMesh + << " mMeshValid=" << gAgentAvatarp->mMeshValid + << LL_ENDL; LLGLDepthTest gls_depth(GL_TRUE, GL_TRUE); gGL.flush(); gGL.setSceneBlendType(LLRender::BT_REPLACE); diff --git a/indra/newview/llviewerjoint.cpp b/indra/newview/llviewerjoint.cpp index 3c5c4752df..125465f326 100644 --- a/indra/newview/llviewerjoint.cpp +++ b/indra/newview/llviewerjoint.cpp @@ -145,6 +145,7 @@ U32 LLViewerJoint::render( F32 pixelArea, bool first_pass, bool is_dummy ) { // LLViewerJoint is derived from LLAvatarJoint, // all children of LLAvatarJoint are assumed to be LLAvatarJoint + // LLJoint is not used directly and is always LLAvatarJoint LLAvatarJoint* joint = static_cast(j); F32 jointLOD = joint->getLOD(); if (pixelArea >= jointLOD || sDisableLOD) diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h index 3457e7bb6a..0ac4db8fcf 100644 --- a/indra/newview/llvoavatar.h +++ b/indra/newview/llvoavatar.h @@ -95,6 +95,7 @@ class LLVOAvatar : public: friend class LLVOAvatarSelf; friend class LLAvatarCheckImpostorMode; + friend class LLVisualParamHint; /******************************************************************************** ** ** -- cgit v1.3 From e7768343db0b80f6f68bef767779816aea5ad516 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev <117672381+akleshchev@users.noreply.github.com> Date: Mon, 10 Aug 2026 22:28:07 +0300 Subject: #6071 Fix WT_SKIRT not being rendered --- indra/newview/lltoolmorph.cpp | 11 +++++++---- indra/newview/llvoavatar.cpp | 10 ++++------ 2 files changed, 11 insertions(+), 10 deletions(-) (limited to 'indra/newview/lltoolmorph.cpp') diff --git a/indra/newview/lltoolmorph.cpp b/indra/newview/lltoolmorph.cpp index a545d32d12..11dd26309e 100644 --- a/indra/newview/lltoolmorph.cpp +++ b/indra/newview/lltoolmorph.cpp @@ -192,17 +192,20 @@ void LLVisualParamHint::preRender(bool clear_depth) gAgentAvatarp->updateGeometry(gAgentAvatarp->mDrawable); gAgentAvatarp->updateLOD(); - if (gAgentAvatarp->mDrawable->isState(LLDrawable::REBUILD_GEOMETRY)) + if (gAgentAvatarp->mDrawable->isState(LLDrawable::REBUILD_GEOMETRY) + || gAgentAvatarp->mDirtyMesh > 0) { - LL_WARNS_ONCE("ParamHint") << "preRender: clearing REBUILD_GEOMETRY after updateGeometry/updateLOD" + // updateLOD marks meshes for an update. + LL_DEBUGS("ParamHint") << "preRender: updateMeshData" << " param=" << mVisualParam->getName() << " dirtyMesh=" << gAgentAvatarp->mDirtyMesh + << " rebuildGeom=" << gAgentAvatarp->mDrawable->isState(LLDrawable::REBUILD_GEOMETRY) << LL_ENDL; - // Clear REBUILD_GEOMETRY so that renderSkinned inside generateImpostor + // Clear states and force update so that renderSkinned inside generateImpostor // does not re-run updateMeshData() with a partially consistent mesh state, // which would reassign mFace pointers on some meshes while others are // mid-draw with stale vertex offsets. - gAgentAvatarp->mDrawable->clearState(LLDrawable::REBUILD_GEOMETRY); + gAgentAvatarp->updateMeshData(); } } else diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 89ee5ede2a..78d9c1fa4c 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -2583,6 +2583,10 @@ void LLVOAvatar::updateMeshData() f_num++ ; } } + + mDirtyMesh = 0; + mNeedsSkin = true; + mDrawable->clearState(LLDrawable::REBUILD_GEOMETRY); } } @@ -5217,9 +5221,6 @@ U32 LLVOAvatar::renderSkinned() if (needs_rebuild || mDirtyMesh >= 2 || mVisibilityRank <= 4) { updateMeshData(); - mDirtyMesh = 0; - mNeedsSkin = true; - mDrawable->clearState(LLDrawable::REBUILD_GEOMETRY); } } @@ -10803,9 +10804,6 @@ bool LLVOAvatar::updateLOD() if (mDirtyMesh >= 2 || mDrawable->isState(LLDrawable::REBUILD_GEOMETRY)) { //LOD changed or new mesh created, allocate new vertex buffer if needed updateMeshData(); - mDirtyMesh = 0; - mNeedsSkin = true; - mDrawable->clearState(LLDrawable::REBUILD_GEOMETRY); } updateVisibility(); -- cgit v1.3