diff options
author | RunitaiLinden <davep@lindenlab.com> | 2024-05-02 10:59:29 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-05-02 10:59:29 -0500 |
commit | e8219cb0509d5aacc75cf862c6b8cad026590958 (patch) | |
tree | bfd85d36db258f46b74aa9989c1615d9bd7faf72 /indra | |
parent | a701cce8e0959503156a010683f6d0d57beaae36 (diff) | |
parent | 7fc5f7e649c564fa8479a72a45459d0cc427d0f8 (diff) |
Merge branch 'project/gltf_development' into 1357-gltf-asset-prototype
Diffstat (limited to 'indra')
30 files changed, 198 insertions, 161 deletions
diff --git a/indra/llcommon/llcommon.cpp b/indra/llcommon/llcommon.cpp index 6e988260a9..30aefa3134 100644 --- a/indra/llcommon/llcommon.cpp +++ b/indra/llcommon/llcommon.cpp @@ -128,8 +128,7 @@ void LLCommon::initClass() sAprInitialized = TRUE; } LLTimer::initClass(); - LLThreadSafeRefCount::initThreadSafeRefCount(); - assert_main_thread(); // Make sure we record the main thread + assert_main_thread(); // Make sure we record the main thread if (!sMasterThreadRecorder) { sMasterThreadRecorder = new LLTrace::ThreadRecorder(); @@ -143,7 +142,6 @@ void LLCommon::cleanupClass() delete sMasterThreadRecorder; sMasterThreadRecorder = NULL; LLTrace::set_master_thread_recorder(NULL); - LLThreadSafeRefCount::cleanupThreadSafeRefCount(); SUBSYSTEM_CLEANUP_DBG(LLTimer); if (sAprInitialized) { diff --git a/indra/llcommon/llcoros.cpp b/indra/llcommon/llcoros.cpp index c13900f74a..219c65fbb8 100644 --- a/indra/llcommon/llcoros.cpp +++ b/indra/llcommon/llcoros.cpp @@ -61,6 +61,23 @@ #include <excpt.h> #endif +// static +bool LLCoros::on_main_coro() +{ + if (!LLCoros::instanceExists() || LLCoros::getName().empty()) + { + return true; + } + + return false; +} + +// static +bool LLCoros::on_main_thread_main_coro() +{ + return on_main_coro() && on_main_thread(); +} + // static LLCoros::CoroData& LLCoros::get_CoroData(const std::string& caller) { diff --git a/indra/llcommon/llcoros.h b/indra/llcommon/llcoros.h index fd878f20ad..00650a2454 100644 --- a/indra/llcommon/llcoros.h +++ b/indra/llcommon/llcoros.h @@ -94,6 +94,16 @@ class LL_COMMON_API LLCoros: public LLSingleton<LLCoros> void cleanupSingleton() override; public: + // For debugging, return true if on the main coroutine for the current thread + // Code that should not be executed from a coroutine should be protected by + // llassert(LLCoros::on_main_coro()) + static bool on_main_coro(); + + // For debugging, return true if on the main thread and not in a coroutine + // Non-thread-safe code in the main loop should be protected by + // llassert(LLCoros::on_main_thread_main_coro()) + static bool on_main_thread_main_coro(); + /// The viewer's use of the term "coroutine" became deeply embedded before /// the industry term "fiber" emerged to distinguish userland threads from /// simpler, more transient kinds of coroutines. Semantically they've diff --git a/indra/llcommon/llerror.cpp b/indra/llcommon/llerror.cpp index 0f48ce16b2..74b138a53b 100644 --- a/indra/llcommon/llerror.cpp +++ b/indra/llcommon/llerror.cpp @@ -506,7 +506,7 @@ namespace LLError::TimeFunction mTimeFunction; Recorders mRecorders; - LLMutex mRecorderMutex; + LLCoros::Mutex mRecorderMutex; int mShouldLogCallCounter; @@ -1044,7 +1044,7 @@ namespace LLError return; } SettingsConfigPtr s = Globals::getInstance()->getSettingsConfig(); - LLMutexLock lock(&s->mRecorderMutex); + LLCoros::LockType lock(s->mRecorderMutex); s->mRecorders.push_back(recorder); } @@ -1055,7 +1055,7 @@ namespace LLError return; } SettingsConfigPtr s = Globals::getInstance()->getSettingsConfig(); - LLMutexLock lock(&s->mRecorderMutex); + LLCoros::LockType lock(s->mRecorderMutex); s->mRecorders.erase(std::remove(s->mRecorders.begin(), s->mRecorders.end(), recorder), s->mRecorders.end()); } @@ -1104,7 +1104,7 @@ namespace LLError std::shared_ptr<RECORDER> findRecorder() { SettingsConfigPtr s = Globals::getInstance()->getSettingsConfig(); - LLMutexLock lock(&s->mRecorderMutex); + LLCoros::LockType lock(s->mRecorderMutex); return findRecorderPos<RECORDER>(s).first; } @@ -1115,7 +1115,7 @@ namespace LLError bool removeRecorder() { SettingsConfigPtr s = Globals::getInstance()->getSettingsConfig(); - LLMutexLock lock(&s->mRecorderMutex); + LLCoros::LockType lock(s->mRecorderMutex); auto found = findRecorderPos<RECORDER>(s); if (found.first) { @@ -1221,7 +1221,7 @@ namespace std::string escaped_message; - LLMutexLock lock(&s->mRecorderMutex); + LLCoros::LockType lock(s->mRecorderMutex); for (LLError::RecorderPtr& r : s->mRecorders) { if (!r->enabled()) diff --git a/indra/llcommon/llevents.cpp b/indra/llcommon/llevents.cpp index 70931f3a65..8006f9d059 100644 --- a/indra/llcommon/llevents.cpp +++ b/indra/llcommon/llevents.cpp @@ -382,7 +382,7 @@ std::string LLEventPump::inventName(const std::string& pfx) void LLEventPump::clear() { - LLMutexLock lock(&mConnectionListMutex); + LLCoros::LockType lock(mConnectionListMutex); // Destroy the original LLStandardSignal instance, replacing it with a // whole new one. mSignal = std::make_shared<LLStandardSignal>(); @@ -394,7 +394,7 @@ void LLEventPump::reset() { // Resetting mSignal is supposed to disconnect everything on its own // But due to crash on 'reset' added explicit cleanup to get more data - LLMutexLock lock(&mConnectionListMutex); + LLCoros::LockType lock(mConnectionListMutex); ConnectionMap::const_iterator iter = mConnections.begin(); ConnectionMap::const_iterator end = mConnections.end(); while (iter!=end) @@ -419,7 +419,7 @@ LLBoundListener LLEventPump::listen_impl(const std::string& name, const LLEventL return LLBoundListener(); } - LLMutexLock lock(&mConnectionListMutex); + LLCoros::LockType lock(mConnectionListMutex); float nodePosition = 1.0; @@ -582,7 +582,7 @@ LLBoundListener LLEventPump::listen_impl(const std::string& name, const LLEventL LLBoundListener LLEventPump::getListener(const std::string& name) { - LLMutexLock lock(&mConnectionListMutex); + LLCoros::LockType lock(mConnectionListMutex); ConnectionMap::const_iterator found = mConnections.find(name); if (found != mConnections.end()) { @@ -594,7 +594,7 @@ LLBoundListener LLEventPump::getListener(const std::string& name) void LLEventPump::stopListening(const std::string& name) { - LLMutexLock lock(&mConnectionListMutex); + LLCoros::LockType lock(mConnectionListMutex); ConnectionMap::iterator found = mConnections.find(name); if (found != mConnections.end()) { diff --git a/indra/llcommon/llevents.h b/indra/llcommon/llevents.h index bebcfacdcb..df54a6546d 100644 --- a/indra/llcommon/llevents.h +++ b/indra/llcommon/llevents.h @@ -61,6 +61,7 @@ #include "llstl.h" #include "llexception.h" #include "llhandle.h" +#include "llcoros.h" /*==========================================================================*| // override this to allow binding free functions with more parameters @@ -601,7 +602,7 @@ private: LLHandle<LLEventPumps> mRegistry; std::string mName; - LLMutex mConnectionListMutex; + LLCoros::Mutex mConnectionListMutex; protected: virtual LLBoundListener listen_impl(const std::string& name, const LLEventListener&, diff --git a/indra/llcommon/llfixedbuffer.h b/indra/llcommon/llfixedbuffer.h index 554cf48a4c..b3bef7520b 100644 --- a/indra/llcommon/llfixedbuffer.h +++ b/indra/llcommon/llfixedbuffer.h @@ -33,6 +33,7 @@ #include "llstring.h" #include "llthread.h" #include "llerrorcontrol.h" +#include "llcoros.h" // fixed buffer implementation class LL_COMMON_API LLFixedBuffer : public LLLineBuffer @@ -58,7 +59,7 @@ protected: void addWLine(const LLWString& line); protected: - LLMutex mMutex ; + LLCoros::Mutex mMutex ; }; #endif //LL_FIXED_BUFFER_H diff --git a/indra/llcommon/llmutex.cpp b/indra/llcommon/llmutex.cpp index 0273dd5970..5d93d6e72b 100644 --- a/indra/llcommon/llmutex.cpp +++ b/indra/llcommon/llmutex.cpp @@ -28,6 +28,7 @@ #include "llmutex.h" #include "llthread.h" #include "lltimer.h" +#include "llcoros.h" //============================================================================ @@ -44,7 +45,17 @@ LLMutex::~LLMutex() void LLMutex::lock() { - LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD + LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD; + + // LLMutex is not coroutine aware and should not be used from a coroutine + // If your code is running in a coroutine, you should use LLCoros::Mutex instead + // NOTE: If the stack trace you're staring at contains non-thread-safe code, + // you should use LLAppViewer::instance().postToMainThread() to shuttle execution + // back to the main loop. + // NOTE: If you got here from seeing this assert in your log and you're not seeing + // a stack trace that points here, put a breakpoint in on_main_coro and try again. + llassert(LLCoros::on_main_coro()); + if(isSelfLocked()) { //redundant lock mCount++; @@ -66,7 +77,8 @@ void LLMutex::lock() void LLMutex::unlock() { - LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD + LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD; + if (mCount > 0) { //not the root unlock mCount--; @@ -111,7 +123,7 @@ LLThread::id_t LLMutex::lockingThread() const bool LLMutex::trylock() { - LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD + LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD; if(isSelfLocked()) { //redundant lock mCount++; diff --git a/indra/llcommon/llrefcount.h b/indra/llcommon/llrefcount.h index 15e7175fc8..109c29c0c9 100644 --- a/indra/llcommon/llrefcount.h +++ b/indra/llcommon/llrefcount.h @@ -89,13 +89,6 @@ private: class LL_COMMON_API LLThreadSafeRefCount { -public: - static void initThreadSafeRefCount(); // creates sMutex - static void cleanupThreadSafeRefCount(); // destroys sMutex - -private: - static LLMutex* sMutex; - protected: virtual ~LLThreadSafeRefCount(); // use unref() diff --git a/indra/llcommon/llthread.cpp b/indra/llcommon/llthread.cpp index cd4975d9d3..ef66c36827 100644 --- a/indra/llcommon/llthread.cpp +++ b/indra/llcommon/llthread.cpp @@ -421,30 +421,6 @@ void LLThread::unlockData() //============================================================================ -//---------------------------------------------------------------------------- - -//static -LLMutex* LLThreadSafeRefCount::sMutex = 0; - -//static -void LLThreadSafeRefCount::initThreadSafeRefCount() -{ - if (!sMutex) - { - sMutex = new LLMutex(); - } -} - -//static -void LLThreadSafeRefCount::cleanupThreadSafeRefCount() -{ - delete sMutex; - sMutex = NULL; -} - - -//---------------------------------------------------------------------------- - LLThreadSafeRefCount::LLThreadSafeRefCount() : mRef(0) { diff --git a/indra/llmessage/llavatarnamecache.cpp b/indra/llmessage/llavatarnamecache.cpp index f7a9f55685..314e7f0217 100644 --- a/indra/llmessage/llavatarnamecache.cpp +++ b/indra/llmessage/llavatarnamecache.cpp @@ -45,6 +45,7 @@ #include "llcorehttputil.h" #include "llexception.h" #include "stringize.h" +#include "workqueue.h" #include <map> #include <set> @@ -179,19 +180,26 @@ void LLAvatarNameCache::requestAvatarNameCache_(std::string url, std::vector<LLU if (LLAvatarNameCache::instanceExists()) { - if (!success) - { // on any sort of failure add dummy records for any agent IDs - // in this request that we do not have cached already - std::vector<LLUUID>::const_iterator it = agentIds.begin(); - for (; it != agentIds.end(); ++it) - { - const LLUUID& agent_id = *it; - LLAvatarNameCache::getInstance()->handleAgentError(agent_id); - } - return; - } + // dispatch handler execution back to mainloop + auto workqueue = LL::WorkQueue::getInstance("mainloop"); - LLAvatarNameCache::getInstance()->handleAvNameCacheSuccess(results, httpResults); + if (workqueue) + { + workqueue->post([=]() + { + if (!success) + { // on any sort of failure add dummy records for any agent IDs + // in this request that we do not have cached already + for (const auto& agent_id : agentIds) + { + LLAvatarNameCache::getInstance()->handleAgentError(agent_id); + } + return; + } + + LLAvatarNameCache::getInstance()->handleAvNameCacheSuccess(results, httpResults); + }); + } } } catch (const LLCoros::Stop&) diff --git a/indra/llplugin/llpluginprocessparent.cpp b/indra/llplugin/llpluginprocessparent.cpp index f5966b71de..a28f6c648f 100644 --- a/indra/llplugin/llpluginprocessparent.cpp +++ b/indra/llplugin/llpluginprocessparent.cpp @@ -34,7 +34,6 @@ #include "llpluginmessageclasses.h" #include "llsdserialize.h" #include "stringize.h" - #include "llapr.h" //virtual @@ -46,7 +45,7 @@ LLPluginProcessParentOwner::~LLPluginProcessParentOwner() bool LLPluginProcessParent::sUseReadThread = false; apr_pollset_t *LLPluginProcessParent::sPollSet = NULL; bool LLPluginProcessParent::sPollsetNeedsRebuild = false; -LLMutex *LLPluginProcessParent::sInstancesMutex; +LLCoros::Mutex *LLPluginProcessParent::sInstancesMutex; LLPluginProcessParent::mapInstances_t LLPluginProcessParent::sInstances; LLThread *LLPluginProcessParent::sReadThread = NULL; @@ -106,7 +105,7 @@ LLPluginProcessParent::LLPluginProcessParent(LLPluginProcessParentOwner *owner): { if(!sInstancesMutex) { - sInstancesMutex = new LLMutex(); + sInstancesMutex = new LLCoros::Mutex(); } mOwner = owner; @@ -176,7 +175,7 @@ LLPluginProcessParent::ptr_t LLPluginProcessParent::create(LLPluginProcessParent // Don't add to the global list until fully constructed. { - LLMutexLock lock(sInstancesMutex); + LLCoros::LockType lock(*sInstancesMutex); sInstances.insert(mapInstances_t::value_type(that.get(), that)); } @@ -186,7 +185,7 @@ LLPluginProcessParent::ptr_t LLPluginProcessParent::create(LLPluginProcessParent /*static*/ void LLPluginProcessParent::shutdown() { - LLMutexLock lock(sInstancesMutex); + LLCoros::LockType lock(*sInstancesMutex); mapInstances_t::iterator it; for (it = sInstances.begin(); it != sInstances.end(); ++it) @@ -244,7 +243,7 @@ bool LLPluginProcessParent::pollTick() { // this grabs a copy of the smart pointer to ourselves to ensure that we do not // get destroyed until after this method returns. - LLMutexLock lock(sInstancesMutex); + LLCoros::LockType lock(*sInstancesMutex); mapInstances_t::iterator it = sInstances.find(this); if (it != sInstances.end()) that = (*it).second; @@ -263,7 +262,7 @@ void LLPluginProcessParent::removeFromProcessing() // Remove from the global list before beginning destruction. { // Make sure to get the global mutex _first_ here, to avoid a possible deadlock against LLPluginProcessParent::poll() - LLMutexLock lock(sInstancesMutex); + LLCoros::LockType lock(*sInstancesMutex); { LLMutexLock lock2(&mIncomingQueueMutex); sInstances.erase(this); @@ -845,7 +844,7 @@ void LLPluginProcessParent::updatePollset() return; } - LLMutexLock lock(sInstancesMutex); + LLCoros::LockType lock(*sInstancesMutex); if(sPollSet) { @@ -968,7 +967,7 @@ void LLPluginProcessParent::poll(F64 timeout) mapInstances_t::iterator it; { - LLMutexLock lock(sInstancesMutex); + LLCoros::LockType lock(*sInstancesMutex); it = sInstances.find(thatId); if (it != sInstances.end()) that = (*it).second; diff --git a/indra/llplugin/llpluginprocessparent.h b/indra/llplugin/llpluginprocessparent.h index 01627925d7..2f9dc921ea 100644 --- a/indra/llplugin/llpluginprocessparent.h +++ b/indra/llplugin/llpluginprocessparent.h @@ -207,7 +207,7 @@ private: apr_pollfd_t mPollFD; static apr_pollset_t *sPollSet; static bool sPollsetNeedsRebuild; - static LLMutex *sInstancesMutex; + static LLCoros::Mutex *sInstancesMutex; static mapInstances_t sInstances; static void dirtyPollSet(); static void updatePollset(); diff --git a/indra/llrender/llshadermgr.cpp b/indra/llrender/llshadermgr.cpp index 0b20ff6230..636e13719a 100644 --- a/indra/llrender/llshadermgr.cpp +++ b/indra/llrender/llshadermgr.cpp @@ -328,7 +328,7 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader) return FALSE; } } - shader->mFeatures.mIndexedTextureChannels = llmax(LLGLSLShader::sIndexedTextureChannels-1, 1); + shader->mFeatures.mIndexedTextureChannels = llmax(LLGLSLShader::sIndexedTextureChannels, 1); } } diff --git a/indra/llui/llconsole.cpp b/indra/llui/llconsole.cpp index 8fc2978bdd..6a44108741 100644 --- a/indra/llui/llconsole.cpp +++ b/indra/llui/llconsole.cpp @@ -380,7 +380,7 @@ void LLConsole::updateClass() void LLConsole::update() { { - LLMutexLock lock(&mMutex); + LLCoros::LockType lock(mMutex); while (!mLines.empty()) { diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index e42906e78b..e1eeefa755 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -10712,38 +10712,49 @@ <integer>3</integer> </map> <key>RenderReflectionRes</key> - <map> - <key>Comment</key> - <string>Reflection map resolution.</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>S32</string> - <key>Value</key> - <integer>64</integer> - </map> - <key>RenderResolutionDivisor</key> - <map> - <key>Comment</key> - <string>Divisor for rendering 3D scene at reduced resolution.</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>U32</string> - <key>Value</key> - <integer>1</integer> - </map> - <key>RenderShaderLightingMaxLevel</key> - <map> - <key>Comment</key> - <string>Max lighting level to use in the shader (class 3 is default, 2 is less lights, 1 is sun/moon only. Works around shader compiler bugs on certain platforms.)</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>S32</string> - <key>Value</key> - <integer>3</integer> - </map> + <map> + <key>Comment</key> + <string>Reflection map resolution.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>S32</string> + <key>Value</key> + <integer>64</integer> + </map> + <key>RenderReservedTextureIndices</key> + <map> + <key>Comment</key> + <string>Count of texture indices to reserve for shadow and reflection maps when using indexed texture rendering. Probably only want to set from the login screen.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>S32</string> + <key>Value</key> + <integer>14</integer> + </map> + <key>RenderResolutionDivisor</key> + <map> + <key>Comment</key> + <string>Divisor for rendering 3D scene at reduced resolution.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>U32</string> + <key>Value</key> + <integer>1</integer> + </map> + <key>RenderShaderLightingMaxLevel</key> + <map> + <key>Comment</key> + <string>Max lighting level to use in the shader (class 3 is default, 2 is less lights, 1 is sun/moon only. Works around shader compiler bugs on certain platforms.)</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>S32</string> + <key>Value</key> + <integer>3</integer> + </map> <key>RenderSkyAutoAdjustLegacy</key> <map> <key>Comment</key> diff --git a/indra/newview/app_settings/shaders/class1/deferred/moonF.glsl b/indra/newview/app_settings/shaders/class1/deferred/moonF.glsl index 183354b9bd..6ef556d7e8 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/moonF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/moonF.glsl @@ -55,7 +55,7 @@ void main() frag_data[0] = vec4(0); frag_data[1] = vec4(0.0); - frag_data[2] = vec4(0.0, 0.0, 0.0, GBUFFER_FLAG_HAS_ATMOS); + frag_data[2] = vec4(0.0, 0.0, 0.0, GBUFFER_FLAG_SKIP_ATMOS); frag_data[3] = vec4(c.rgb, c.a); // Added and commented out for a ground truth. Do not uncomment - Geenz diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 90f9b38f2d..c966f9cbcc 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -5200,6 +5200,11 @@ void LLAppViewer::updateNameLookupUrl(const LLViewerRegion * regionp) } } +void LLAppViewer::postToMainCoro(const LL::WorkQueue::Work& work) +{ + gMainloopWork.post(work); +} + void LLAppViewer::idleNameCache() { // Neither old nor new name cache can function before agent has a region diff --git a/indra/newview/llappviewer.h b/indra/newview/llappviewer.h index 9352dba06d..92976a70af 100644 --- a/indra/newview/llappviewer.h +++ b/indra/newview/llappviewer.h @@ -226,6 +226,9 @@ public: void updateNameLookupUrl(const LLViewerRegion* regionp); + // post given work to the "mainloop" work queue for handling on the main thread + void postToMainCoro(const LL::WorkQueue::Work& work); + protected: virtual bool initWindow(); // Initialize the viewer's window. virtual void initLoggingAndGetLastDuration(); // Initialize log files, logging system diff --git a/indra/newview/llavatarrenderinfoaccountant.cpp b/indra/newview/llavatarrenderinfoaccountant.cpp index b95b971890..ba9ba4dc64 100644 --- a/indra/newview/llavatarrenderinfoaccountant.cpp +++ b/indra/newview/llavatarrenderinfoaccountant.cpp @@ -236,8 +236,6 @@ void LLAvatarRenderInfoAccountant::avatarRenderInfoReportCoro(std::string url, U !avatar->isControlAvatar() && // Not part of an animated object avatar->getObjectHost() == regionp->getHost()) // Ensure it's on the same region { - avatar->calculateUpdateRenderComplexity(); // Make sure the numbers are up-to-date - LLSD info = LLSD::emptyMap(); U32 avatar_complexity = avatar->getVisualComplexity(); if (avatar_complexity > 0) diff --git a/indra/newview/lldrawpoolalpha.cpp b/indra/newview/lldrawpoolalpha.cpp index 9418cead76..fd27010877 100644 --- a/indra/newview/lldrawpoolalpha.cpp +++ b/indra/newview/lldrawpoolalpha.cpp @@ -478,7 +478,7 @@ bool LLDrawPoolAlpha::TexSetup(LLDrawInfo* draw, bool use_material) } } } - + return tex_setup; } @@ -668,7 +668,7 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, bool depth_only, bool rigged) LLSpatialGroup::drawmap_elem_t& draw_info = rigged ? group->mDrawMap[LLRenderPass::PASS_ALPHA_RIGGED] : group->mDrawMap[LLRenderPass::PASS_ALPHA]; - for (LLSpatialGroup::drawmap_elem_t::iterator k = draw_info.begin(); k != draw_info.end(); ++k) + for (LLSpatialGroup::drawmap_elem_t::iterator k = draw_info.begin(); k != draw_info.end(); ++k) { LLDrawInfo& params = **k; if ((bool)params.mAvatar != rigged) @@ -814,9 +814,10 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, bool depth_only, bool rigged) current_shader->setMinimumAlpha(0.f); reset_minimum_alpha = true; } - + params.mVertexBuffer->setBuffer(); params.mVertexBuffer->drawRange(LLRender::TRIANGLES, params.mStart, params.mEnd, params.mCount, params.mOffset); + stop_glerror(); if (reset_minimum_alpha) { diff --git a/indra/newview/lldrawpoolbump.cpp b/indra/newview/lldrawpoolbump.cpp index 24df11c158..518310476b 100644 --- a/indra/newview/lldrawpoolbump.cpp +++ b/indra/newview/lldrawpoolbump.cpp @@ -699,6 +699,8 @@ void LLBumpImageList::addTextureStats(U8 bump, const LLUUID& base_image_id, F32 void LLBumpImageList::updateImages() { + llassert(LLCoros::on_main_thread_main_coro()); // This code is not thread safe + for (bump_image_map_t::iterator iter = mBrightnessEntries.begin(); iter != mBrightnessEntries.end(); ) { LLViewerTexture* image = iter->second; diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp index 69e43bb458..ccee57cf69 100644 --- a/indra/newview/llface.cpp +++ b/indra/newview/llface.cpp @@ -1855,7 +1855,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, S32* vp = (S32*) &val; *vp = index; - llassert(index <= LLGLSLShader::sIndexedTextureChannels-1); + llassert(index < LLGLSLShader::sIndexedTextureChannels); LLVector4Logical mask; mask.clear(); diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index a0324ca82a..486b652f07 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -334,10 +334,18 @@ void update_texture_fetch() void set_flags_and_update_appearance() { - LLAppearanceMgr::instance().setAttachmentInvLinkEnable(true); - LLAppearanceMgr::instance().updateAppearanceFromCOF(true, true, no_op); + // this may be called from a coroutine but has many side effects + // in non-thread-safe classes, post to main loop + auto work = []() + { + LLAppearanceMgr::instance().setAttachmentInvLinkEnable(true); + LLAppearanceMgr::instance().updateAppearanceFromCOF(true, true, no_op); + + LLInventoryModelBackgroundFetch::instance().start(); + }; + + LLAppViewer::instance()->postToMainCoro(work); - LLInventoryModelBackgroundFetch::instance().start(); } // Returns false to skip other idle processing. Should only return diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp index 02108e861a..85891744ef 100644 --- a/indra/newview/llviewermedia.cpp +++ b/indra/newview/llviewermedia.cpp @@ -1667,7 +1667,7 @@ void LLViewerMediaImpl::destroyMediaSource() cancelMimeTypeProbe(); { - LLMutexLock lock(&mLock); // Delay tear-down while bg thread is updating + LLCoros::LockType lock(mLock); // Delay tear-down while bg thread is updating if(mMediaSource) { mMediaSource->setDeleteOK(true) ; @@ -2968,7 +2968,7 @@ bool LLViewerMediaImpl::preMediaTexUpdate(LLViewerMediaTexture*& media_tex, U8*& void LLViewerMediaImpl::doMediaTexUpdate(LLViewerMediaTexture* media_tex, U8* data, S32 data_width, S32 data_height, S32 x_pos, S32 y_pos, S32 width, S32 height, bool sync) { LL_PROFILE_ZONE_SCOPED_CATEGORY_MEDIA; - LLMutexLock lock(&mLock); // don't allow media source tear-down during update + LLCoros::LockType lock(mLock); // don't allow media source tear-down during update // wrap "data" in an LLImageRaw but do NOT make a copy LLPointer<LLImageRaw> raw = new LLImageRaw(data, media_tex->getWidth(), media_tex->getHeight(), media_tex->getComponents(), true); diff --git a/indra/newview/llviewermedia.h b/indra/newview/llviewermedia.h index 03899b6b8f..378297bf91 100644 --- a/indra/newview/llviewermedia.h +++ b/indra/newview/llviewermedia.h @@ -182,7 +182,7 @@ private: // Implementation functions not exported into header file class LLViewerMediaImpl - : public LLMouseHandler, public LLRefCount, public LLPluginClassMediaOwner, public LLViewerMediaEventEmitter, public LLEditMenuHandler + : public LLMouseHandler, public LLThreadSafeRefCount, public LLPluginClassMediaOwner, public LLViewerMediaEventEmitter, public LLEditMenuHandler { LOG_CLASS(LLViewerMediaImpl); public: @@ -432,7 +432,7 @@ private: private: // a single media url with some data and an impl. std::shared_ptr<LLPluginClassMedia> mMediaSource; - LLMutex mLock; + LLCoros::Mutex mLock; F64 mZoomFactor; LLUUID mTextureId; bool mMovieImageHasMips; diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index 29dce088f5..210d5f84bd 100755 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -2498,11 +2498,8 @@ void LLViewerRegion::setSimulatorFeatures(const LLSD& sim_features) } }; - auto workqueue = LL::WorkQueue::getInstance("mainloop"); - if (workqueue) - { - LL::WorkQueue::postMaybe(workqueue, work); - } + + LLAppViewer::instance()->postToMainCoro(work); } //this is called when the parent is not cacheable. diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp index 289c0d7567..5144b28ce9 100644 --- a/indra/newview/llviewershadermgr.cpp +++ b/indra/newview/llviewershadermgr.cpp @@ -423,7 +423,10 @@ void LLViewerShaderMgr::setShaders() static LLCachedControl<U32> max_texture_index(gSavedSettings, "RenderMaxTextureIndex", 16); // when using indexed texture rendering, leave some texture units available for shadow and reflection maps - LLGLSLShader::sIndexedTextureChannels = llmax(llmin(gGLManager.mNumTextureImageUnits-12, (S32) max_texture_index), 1); + static LLCachedControl<S32> reserved_texture_units(gSavedSettings, "RenderReservedTextureIndices", 14); + + LLGLSLShader::sIndexedTextureChannels = + llclamp<S32>(max_texture_index, 1, gGLManager.mNumTextureImageUnits-reserved_texture_units); reentrance = true; diff --git a/indra/newview/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp index 310c9ee297..9a0aae944c 100644 --- a/indra/newview/llvoicevivox.cpp +++ b/indra/newview/llvoicevivox.cpp @@ -6437,37 +6437,43 @@ void LLVivoxVoiceClient::notifyStatusObservers(LLVoiceClientStatusObserver::ESta } } } - + LL_DEBUGS("Voice") << " " << LLVoiceClientStatusObserver::status2string(status) << ", session URI " << getAudioSessionURI() << ", proximal is " << inSpatialChannel() << LL_ENDL; - for (status_observer_set_t::iterator it = mStatusObservers.begin(); - it != mStatusObservers.end(); - ) - { - LLVoiceClientStatusObserver* observer = *it; - observer->onChange(status, getAudioSessionURI(), inSpatialChannel()); - // In case onError() deleted an entry. - it = mStatusObservers.upper_bound(observer); - } + // this function is called from a coroutine, shuttle application hook back to main loop + auto work = [=]() + { + for (status_observer_set_t::iterator it = mStatusObservers.begin(); + it != mStatusObservers.end(); + ) + { + LLVoiceClientStatusObserver* observer = *it; + observer->onChange(status, getAudioSessionURI(), inSpatialChannel()); + // In case onError() deleted an entry. + it = mStatusObservers.upper_bound(observer); + } - // skipped to avoid speak button blinking - if ( status != LLVoiceClientStatusObserver::STATUS_JOINING - && status != LLVoiceClientStatusObserver::STATUS_LEFT_CHANNEL - && status != LLVoiceClientStatusObserver::STATUS_VOICE_DISABLED) - { - bool voice_status = LLVoiceClient::getInstance()->voiceEnabled() && LLVoiceClient::getInstance()->isVoiceWorking(); + // skipped to avoid speak button blinking + if (status != LLVoiceClientStatusObserver::STATUS_JOINING + && status != LLVoiceClientStatusObserver::STATUS_LEFT_CHANNEL + && status != LLVoiceClientStatusObserver::STATUS_VOICE_DISABLED) + { + bool voice_status = LLVoiceClient::getInstance()->voiceEnabled() && LLVoiceClient::getInstance()->isVoiceWorking(); - gAgent.setVoiceConnected(voice_status); + gAgent.setVoiceConnected(voice_status); - if (voice_status) - { - LLFirstUse::speak(true); - } - } + if (voice_status) + { + LLFirstUse::speak(true); + } + } + }; + + LLAppViewer::instance()->postToMainCoro(work); } void LLVivoxVoiceClient::addObserver(LLFriendObserver* observer) diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index b886b922de..1b816b88fb 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -6248,19 +6248,7 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace LLViewerTexture* last_tex = NULL; - S32 texture_index_channels = 1; - - if (gGLManager.mGLSLVersionMajor > 1 || gGLManager.mGLSLVersionMinor >= 30) - { - texture_index_channels = LLGLSLShader::sIndexedTextureChannels-1; //always reserve one for shiny for now just for simplicity; - } - - if (distance_sort) - { - texture_index_channels = gDeferredAlphaProgram.mFeatures.mIndexedTextureChannels; - } - - texture_index_channels = LLGLSLShader::sIndexedTextureChannels; + S32 texture_index_channels = LLGLSLShader::sIndexedTextureChannels; bool flexi = false; |