summaryrefslogtreecommitdiff
path: root/indra/llrender/llimagegl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llrender/llimagegl.cpp')
-rw-r--r--indra/llrender/llimagegl.cpp91
1 files changed, 74 insertions, 17 deletions
diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp
index 1b6920fe3b..cbc5392882 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,24 +2259,73 @@ 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)
{
mFinished = false;
mContext = mWindow->createSharedContext();
}
+// 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()
{
- // We must perform setup on this thread before actually servicing our
- // WorkQueue, likewise cleanup afterwards.
mWindow->makeContextCurrent(mContext);
gGL.init();
- ThreadPool::run();
+ mFunctionQueue.runUntilClose();
gGL.shutdown();
mWindow->destroySharedContext(mContext);
}