From 30d01e908676de7197f572d69f46be90c3a5bb74 Mon Sep 17 00:00:00 2001 From: Sekkmer Date: Wed, 16 Apr 2025 18:33:27 +0200 Subject: [PATCH 1/5] Fix object and HUD clicking in mouselook mode Adjusts pick coordinates to use the center of the screen in mouselook mode, resolving an issue where objects and HUDs were unclickable due to incorrect picking based on the hidden cursor position. --- indra/newview/llviewerwindow.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index de3444ba0c..22caa84b77 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -5426,6 +5426,14 @@ LLPickInfo LLViewerWindow::pickImmediate(S32 x, S32 y_from_bot, bool pick_transp pick_transparent = true; } + // Pick from center of screen in mouselook + if (gAgentCamera.getCameraMode() == CAMERA_MODE_MOUSELOOK) + { + x = gViewerWindow->getWorldViewRectScaled().getWidth() / 2; + y_from_bot = gViewerWindow->getWorldViewRectScaled().getHeight() / 2; + } + // + // shortcut queueing in mPicks and just update mLastPick in place MASK key_mask = gKeyboard->currentMask(true); mLastPick = LLPickInfo(LLCoordGL(x, y_from_bot), key_mask, pick_transparent, pick_rigged, pick_particle, pick_reflection_probe, true, false, NULL); From 9b531e01ebb746426602a6f1da7f68e131d6066e Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Mon, 21 Apr 2025 15:56:01 +0300 Subject: [PATCH 2/5] #3488 Reduce locking 1. 'sActive' variables are atomic, no locks needed 2. Fix trylocks. There are internal locks inside loadMeshLOD so without checking locks 3 and 4 viewer would be locked on each loadMeshLOD, potentially making main thread wait for threads to unlock. --- indra/newview/llmeshrepository.cpp | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp index b947038ba7..f8b7cf593e 100644 --- a/indra/newview/llmeshrepository.cpp +++ b/indra/newview/llmeshrepository.cpp @@ -1891,42 +1891,36 @@ bool LLMeshRepoThread::fetchMeshPhysicsShape(const LLUUID& mesh_id) //static void LLMeshRepoThread::incActiveLODRequests() { - LLMutexLock lock(gMeshRepo.mThread->mMutex); ++LLMeshRepoThread::sActiveLODRequests; } //static void LLMeshRepoThread::decActiveLODRequests() { - LLMutexLock lock(gMeshRepo.mThread->mMutex); --LLMeshRepoThread::sActiveLODRequests; } //static void LLMeshRepoThread::incActiveHeaderRequests() { - LLMutexLock lock(gMeshRepo.mThread->mMutex); ++LLMeshRepoThread::sActiveHeaderRequests; } //static void LLMeshRepoThread::decActiveHeaderRequests() { - LLMutexLock lock(gMeshRepo.mThread->mMutex); --LLMeshRepoThread::sActiveHeaderRequests; } //static void LLMeshRepoThread::incActiveSkinRequests() { - LLMutexLock lock(gMeshRepo.mThread->mMutex); ++LLMeshRepoThread::sActiveSkinRequests; } //static void LLMeshRepoThread::decActiveSkinRequests() { - LLMutexLock lock(gMeshRepo.mThread->mMutex); --LLMeshRepoThread::sActiveSkinRequests; } @@ -4634,13 +4628,20 @@ void LLMeshRepository::notifyLoadedMeshes() { LLMutexTrylock lock1(mMeshMutex); LLMutexTrylock lock2(mThread->mMutex); + LLMutexTrylock lock3(mThread->mHeaderMutex); + LLMutexTrylock lock4(mThread->mPendingMutex); static U32 hold_offs(0); - if (! lock1.isLocked() || ! lock2.isLocked()) + if (! lock1.isLocked() || ! lock2.isLocked() || ! lock3.isLocked() || ! lock4.isLocked()) { // If we can't get the locks, skip and pick this up later. + // Eventually thread queue will be free enough ++hold_offs; sMaxLockHoldoffs = llmax(sMaxLockHoldoffs, hold_offs); + if (hold_offs > 4) + { + LL_WARNS_ONCE() << "High mesh thread holdoff" << LL_ENDL; + } return; } hold_offs = 0; @@ -4751,8 +4752,6 @@ void LLMeshRepository::notifyLoadedMeshes() std::partial_sort(mPendingRequests.begin(), mPendingRequests.begin() + push_count, mPendingRequests.end(), PendingRequestBase::CompareScoreGreater()); } - LLMutexTrylock lock3(mThread->mHeaderMutex); - LLMutexTrylock lock4(mThread->mPendingMutex); while (!mPendingRequests.empty() && push_count > 0) { std::unique_ptr& req_p = mPendingRequests.front(); From af9254e3e3fbb7ea2d23ef2d9e7ff265051e5f0d Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Mon, 21 Apr 2025 16:59:29 +0300 Subject: [PATCH 3/5] #3870 Added joint initialization for LLVOAvatarSelf Sometimes mesh thread crashes when allocating joints --- indra/newview/llmeshrepository.cpp | 1 + indra/newview/llvoavatar.cpp | 10 ++++++++++ indra/newview/llvoavatar.h | 1 + indra/newview/llvoavatarself.cpp | 2 ++ 4 files changed, 14 insertions(+) diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp index f8b7cf593e..0ca6ee2a32 100644 --- a/indra/newview/llmeshrepository.cpp +++ b/indra/newview/llmeshrepository.cpp @@ -4702,6 +4702,7 @@ void LLMeshRepository::notifyLoadedMeshes() if (mPendingRequests.size() > push_count) { + LL_PROFILE_ZONE_NAMED("Mesh score_map"); // More requests than the high-water limit allows so // sort and forward the most important. diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index ae9e4f980f..d63ab008ba 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -7370,6 +7370,16 @@ LLJoint *LLVOAvatar::getJoint( S32 joint_num ) return pJoint; } +void LLVOAvatar::initAllJoints() +{ + getJointAliases(); + for (auto& alias : mJointAliasMap) + { + mJointMap[alias.first] = mRoot->findJoint(alias.second); + } + // ignore mScreen and mRoot +} + //----------------------------------------------------------------------------- // getRiggedMeshID // diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h index 18be18a3d6..95a09cf006 100644 --- a/indra/newview/llvoavatar.h +++ b/indra/newview/llvoavatar.h @@ -210,6 +210,7 @@ public: LLJoint* getJoint( const std::string &name ) { return getJoint( JointKey::construct( name ) ); } // LLJoint* getJoint(S32 num); + void initAllJoints(); //if you KNOW joint_num is a valid animated joint index, use getSkeletonJoint for efficiency inline LLJoint* getSkeletonJoint(S32 joint_num) { return mSkeleton[joint_num]; } diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp index bd0405e37f..e527bf5c4e 100644 --- a/indra/newview/llvoavatarself.cpp +++ b/indra/newview/llvoavatarself.cpp @@ -272,6 +272,8 @@ void LLVOAvatarSelf::initInstance() doPeriodically(check_for_unsupported_baked_appearance, 120.0); doPeriodically(boost::bind(&LLVOAvatarSelf::checkStuckAppearance, this), 30.0); + initAllJoints(); // mesh thread uses LLVOAvatarSelf as a joint source + mInitFlags |= 1<<2; } From 82673191e24c22f0e1705e2b73a064facbb5e275 Mon Sep 17 00:00:00 2001 From: Ansariel Date: Tue, 22 Apr 2025 12:51:27 +0200 Subject: [PATCH 4/5] Adjust join changes --- indra/newview/llvoavatar.cpp | 15 +++++++++++---- indra/newview/llvoavatar.h | 6 +++--- indra/newview/llvoavatarself.cpp | 4 ++-- indra/newview/llvoavatarself.h | 4 ++-- 4 files changed, 18 insertions(+), 11 deletions(-) diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index d63ab008ba..2ff56d3da8 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -7268,8 +7268,8 @@ const LLUUID& LLVOAvatar::getID() const //----------------------------------------------------------------------------- // RN: avatar joints are multi-rooted to include screen-based attachments // Query by JointKey rather than just a string, the key can be a U32 index for faster lookup -//LLJoint *LLVOAvatar::getJoint( const std::string &name ) -LLJoint *LLVOAvatar::getJoint( const JointKey &name ) +//LLJoint *LLVOAvatar::getJoint(const std::string &name) +LLJoint *LLVOAvatar::getJoint(const JointKey &name) // { LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR; @@ -7373,10 +7373,17 @@ LLJoint *LLVOAvatar::getJoint( S32 joint_num ) void LLVOAvatar::initAllJoints() { getJointAliases(); - for (auto& alias : mJointAliasMap) + // Lookup performance changes + //for (auto& alias : mJointAliasMap) + //{ + // mJointMap[alias.first] = mRoot->findJoint(alias.second); + // mJointMap[JointKey::construct(alias.first).mKey] = mRoot->findJoint(alias.second); + //} + for (const auto& alias : mJointAliasMap) { - mJointMap[alias.first] = mRoot->findJoint(alias.second); + mJointMap[JointKey::construct(alias.first).mKey] = mRoot->findJoint(alias.second); } + // // ignore mScreen and mRoot } diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h index 95a09cf006..5beff6d393 100644 --- a/indra/newview/llvoavatar.h +++ b/indra/newview/llvoavatar.h @@ -205,9 +205,9 @@ public: void dumpAnimationState(); // Query by JointKey rather than just a string, the key can be a U32 index for faster lookup - //virtual LLJoint* getJoint( const std::string &name ); - virtual LLJoint* getJoint( const JointKey &name ); - LLJoint* getJoint( const std::string &name ) { return getJoint( JointKey::construct( name ) ); } + //virtual LLJoint* getJoint(const std::string &name); + virtual LLJoint* getJoint(const JointKey& name); + LLJoint* getJoint(const std::string& name) { return getJoint(JointKey::construct(name)); } // LLJoint* getJoint(S32 num); void initAllJoints(); diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp index e527bf5c4e..1b609e9ffd 100644 --- a/indra/newview/llvoavatarself.cpp +++ b/indra/newview/llvoavatarself.cpp @@ -1030,8 +1030,8 @@ void LLVOAvatarSelf::idleUpdate(LLAgent &agent, const F64 &time) // virtual // Query by JointKey rather than just a string, the key can be a U32 index for faster lookup -//LLJoint *LLVOAvatarSelf::getJoint( const std::string &name ) -LLJoint *LLVOAvatarSelf::getJoint( const JointKey &name ) +//LLJoint *LLVOAvatarSelf::getJoint(const std::string &name) +LLJoint *LLVOAvatarSelf::getJoint(const JointKey& name) // { std::lock_guard lock(mJointMapMutex); diff --git a/indra/newview/llvoavatarself.h b/indra/newview/llvoavatarself.h index de8a435be9..b57b601940 100644 --- a/indra/newview/llvoavatarself.h +++ b/indra/newview/llvoavatarself.h @@ -92,8 +92,8 @@ public: /*virtual*/ void requestStopMotion(LLMotion* motion); // Query by JointKey rather than just a string, the key can be a U32 index for faster lookup -// /*virtual*/ LLJoint* getJoint( const std::string &name ); - /*virtual*/ LLJoint* getJoint( const JointKey &name ); +// /*virtual*/ LLJoint* getJoint(const std::string &name); + /*virtual*/ LLJoint* getJoint(const JointKey& name); // /*virtual*/ void renderJoints(); From 096e32ff03236eb4eda9d766ab5b8bd3d2ef5b91 Mon Sep 17 00:00:00 2001 From: Ansariel Date: Tue, 22 Apr 2025 13:53:58 +0200 Subject: [PATCH 5/5] Update FMOD Studio to 2.03.07 on Windows --- autobuild.xml | 6 ++---- indra/llaudio/llaudioengine_fmodstudio.cpp | 12 ++++++------ 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index c342ffddaa..f71cba29e3 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -950,11 +950,9 @@ archive hash - 595e7aa51f2161b8d11c3afcc88e2197 - hash_algorithm - md5 + 4a0da36b4a31332df62dadf6438f935e url - file:///c:/cygwin/opt/firestorm/fmodstudio-2.02.26-windows64-243641704.tar.bz2 + file:///c:/cygwin/opt/firestorm/fmodstudio-2.03.07-windows64-251121127.tar.bz2 name windows64 diff --git a/indra/llaudio/llaudioengine_fmodstudio.cpp b/indra/llaudio/llaudioengine_fmodstudio.cpp index 02d3408497..e9996b93e0 100644 --- a/indra/llaudio/llaudioengine_fmodstudio.cpp +++ b/indra/llaudio/llaudioengine_fmodstudio.cpp @@ -44,9 +44,9 @@ #include "sound_ids.h" -const U32 EXTRA_SOUND_CHANNELS = 10; +constexpr U32 EXTRA_SOUND_CHANNELS = 10; -FMOD_RESULT F_CALLBACK windCallback(FMOD_DSP_STATE *dsp_state, float *inbuffer, float *outbuffer, unsigned int length, int inchannels, int *outchannels); +FMOD_RESULT F_CALL windCallback(FMOD_DSP_STATE *dsp_state, float *inbuffer, float *outbuffer, unsigned int length, int inchannels, int *outchannels); FMOD::ChannelGroup *LLAudioEngine_FMODSTUDIO::mChannelGroups[LLAudioEngine::AUDIO_TYPE_COUNT] = {0}; @@ -69,13 +69,13 @@ static inline bool Check_FMOD_Error(FMOD_RESULT result, const char *string) return true; } -LLUUID FMOD_GUID_to_LLUUID(FMOD_GUID guid) +static LLUUID FMOD_GUID_to_LLUUID(FMOD_GUID guid) { return LLUUID(llformat("%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x", guid.Data1, guid.Data2, guid.Data3, guid.Data4[0], guid.Data4[1], guid.Data4[2], guid.Data4[3], guid.Data4[4], guid.Data4[5], guid.Data4[6], guid.Data4[7])); } -void set_device(FMOD::System* system, const LLUUID& device_uuid) +static void set_device(FMOD::System* system, const LLUUID& device_uuid) { LL_INFOS() << "LLAudioEngine_FMODSTUDIO::setDevice with device_uuid=" << device_uuid << LL_ENDL; @@ -113,7 +113,7 @@ void set_device(FMOD::System* system, const LLUUID& device_uuid) } } -FMOD_RESULT F_CALLBACK systemCallback(FMOD_SYSTEM *system, FMOD_SYSTEM_CALLBACK_TYPE type, void *commanddata1, void *commanddata2, void* userdata) +FMOD_RESULT F_CALL systemCallback(FMOD_SYSTEM *system, FMOD_SYSTEM_CALLBACK_TYPE type, void *commanddata1, void *commanddata2, void* userdata) { FMOD::System* sys = (FMOD::System*)system; LLAudioEngine_FMODSTUDIO* audio_engine = (LLAudioEngine_FMODSTUDIO*)userdata; @@ -881,7 +881,7 @@ void LLAudioChannelFMODSTUDIO::set3DMode(bool use3d) // not the main thread. May have implications for callees or audio // engine shutdown. -FMOD_RESULT F_CALLBACK windCallback(FMOD_DSP_STATE *dsp_state, float *inbuffer, float *outbuffer, unsigned int length, int inchannels, int *outchannels) +FMOD_RESULT F_CALL windCallback(FMOD_DSP_STATE *dsp_state, float *inbuffer, float *outbuffer, unsigned int length, int inchannels, int *outchannels) { // inbuffer = fmod's original mixbuffer. // outbuffer = the buffer passed from the previous DSP unit.