diff options
author | Nat Goodspeed <nat@lindenlab.com> | 2021-11-23 21:23:45 -0500 |
---|---|---|
committer | Nat Goodspeed <nat@lindenlab.com> | 2021-11-23 21:23:45 -0500 |
commit | d71e0a6d4778d4c67b8793ba569fee2db226bc8e (patch) | |
tree | dce713230aa611dbada3c6f78903d988b1ae06a4 /indra/llrender/llimagegl.cpp | |
parent | 67ace0df9953ce3264048c3946720a9df492edfa (diff) | |
parent | 8852cb9cbd25df8d25fa43cf39b222ab8381ebd6 (diff) |
SL-16094, SL-16400: Merge branch 'DRTVWR-546' into glthread
Diffstat (limited to 'indra/llrender/llimagegl.cpp')
-rw-r--r-- | indra/llrender/llimagegl.cpp | 89 |
1 files changed, 74 insertions, 15 deletions
diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp index 894eb8c773..ed0e3fb345 100644 --- a/indra/llrender/llimagegl.cpp +++ b/indra/llrender/llimagegl.cpp @@ -172,19 +172,31 @@ BOOL is_little_endian() return (*c == 0x78) ; } +LLImageGLThread* LLImageGLThread::sInstance = nullptr; + //static void LLImageGL::initClass(LLWindow* window, S32 num_catagories, BOOL skip_analyze_alpha /* = false */) { LL_PROFILE_ZONE_SCOPED; sSkipAnalyzeAlpha = skip_analyze_alpha; - LLImageGLThread::createInstance(window); + LLImageGLThread::sInstance = new LLImageGLThread(window); + LLImageGLThread::sInstance->start(); +} + +//static +void LLImageGL::updateClass() +{ + LL_PROFILE_ZONE_SCOPED; + LLImageGLThread::sInstance->executeCallbacks(); } //static void LLImageGL::cleanupClass() { LL_PROFILE_ZONE_SCOPED; - LLImageGLThread::deleteSingleton(); + LLImageGLThread::sInstance->mFunctionQueue.close(); + delete LLImageGLThread::sInstance; + LLImageGLThread::sInstance = nullptr; } //static @@ -492,9 +504,6 @@ void LLImageGL::init(BOOL usemipmaps) #endif mCategory = -1; - - // Sometimes we have to post work for the main thread. - mMainQueue = LL::WorkQueue::getInstance("mainloop"); } void LLImageGL::cleanup() @@ -1527,7 +1536,8 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_ } //if we're on the image loading thread, be sure to delete old_texname and update mTexName on the main thread - if (! on_main_thread()) + if (LLImageGLThread::sInstance != nullptr && + LLThread::currentID() == LLImageGLThread::sInstance->getID()) { { LL_PROFILE_ZONE_NAMED("cglt - sync"); @@ -1544,9 +1554,7 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_ } ref(); - LL::WorkQueue::postMaybe( - mMainQueue, - [=]() + LLImageGLThread::sInstance->postCallback([=]() { LL_PROFILE_ZONE_NAMED("cglt - delete callback"); if (old_texname != 0) @@ -2251,11 +2259,7 @@ void LLImageGL::resetCurTexSizebar() */ LLImageGLThread::LLImageGLThread(LLWindow* window) - // We want exactly one thread, but a very large capacity: we never want - // anyone, especially inner-loop render code, to have to block on post() - // because we're full. - : ThreadPool("LLImageGL", 1, 1024*1024) - , mWindow(window) + : LLThread("LLImageGL"), mWindow(window) { LL_PROFILE_ZONE_SCOPED; mFinished = false; @@ -2264,6 +2268,61 @@ LLImageGLThread::LLImageGLThread(LLWindow* window) ThreadPool::start(); } +// post a function to be executed on the LLImageGL background thread + +bool LLImageGLThread::post(const std::function<void()>& func) +{ + try + { + mFunctionQueue.post(func); + } + catch (LLThreadSafeQueueInterrupt e) + { + return false; + } + + return true; +} + +//post a callback to be executed on the main thread + +bool LLImageGLThread::postCallback(const std::function<void()>& callback) +{ + try + { + if (!mCallbackQueue.tryPost(callback)) + { + mPendingCallbackQ.push(callback); + } + } + catch (LLThreadSafeQueueInterrupt e) + { + //thread is closing, drop request + return false; + } + + return true; +} + +void LLImageGLThread::executeCallbacks() +{ + LL_PROFILE_ZONE_SCOPED; + //executed from main thread + mCallbackQueue.runPending(); + + while (!mPendingCallbackQ.empty()) + { + if (mCallbackQueue.tryPost(mPendingCallbackQ.front())) + { + mPendingCallbackQ.pop(); + } + else + { + break; + } + } +} + void LLImageGLThread::run() { LL_PROFILE_ZONE_SCOPED; @@ -2271,7 +2330,7 @@ void LLImageGLThread::run() // WorkQueue, likewise cleanup afterwards. mWindow->makeContextCurrent(mContext); gGL.init(); - ThreadPool::run(); + mFunctionQueue.runUntilClose(); gGL.shutdown(); mWindow->destroySharedContext(mContext); } |