SL-16202: Streamline WorkQueues in LLImageGLThread.

Use the new WorkQueue::postIfOpen() method in LLImageGLThread::post(). That
makes the LLImageGLThread method a trivial wrapper, which can accept templated
work items and pass them through to the WorkQueue method, eliminating double
indirection due to multiple layers of std::function.

Eliminate LLImageGLThread's WorkQueue intended for work on the main queue.
Since the main loop already has a WorkQueue of its own, post work directly to
that WorkQueue instead of using a separate WorkQueue misleadingly embedded in
LLImageGLThread.

Instead of looking up the main thread's WorkQueue every time, capture a
pointer in LLImageGL's constructor.

We no longer need a fallback queue for when the main thread's WorkQueue is
full. We no longer need the main loop to poll LLImageGL to service the local
main-thread-targeted WorkQueue, or to copy work from the fallback queue to the
main queue. That eliminates LLImageGLThread::postCallback(), mCallbackQueue,
mPendingCallbackQ, executeCallbacks() -- and even LLImageGL::updateClass() and
LLAppViewer's call to it.

Change LLViewerFetchedTexture::scheduleCreateTexture() to post work to the
main thread's WorkQueue instead of calling LLImageGLThread::postCallback().
meow-7.2.2
Nat Goodspeed 2021-11-04 16:50:31 -04:00
parent 89f2169e9d
commit d848d9e888
4 changed files with 13 additions and 77 deletions

View File

@ -183,13 +183,6 @@ void LLImageGL::initClass(LLWindow* window, S32 num_catagories, BOOL skip_analyz
LLImageGLThread::sInstance->start();
}
//static
void LLImageGL::updateClass()
{
LL_PROFILE_ZONE_SCOPED;
LLImageGLThread::sInstance->executeCallbacks();
}
//static
void LLImageGL::cleanupClass()
{
@ -504,6 +497,9 @@ 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()
@ -1554,7 +1550,9 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_
}
ref();
LLImageGLThread::sInstance->postCallback([=]()
LL::WorkQueue::postMaybe(
mMainQueue,
[=]()
{
LL_PROFILE_ZONE_NAMED("cglt - delete callback");
if (old_texname != 0)
@ -2266,61 +2264,6 @@ LLImageGLThread::LLImageGLThread(LLWindow* window)
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()
{
mWindow->makeContextCurrent(mContext);

View File

@ -198,6 +198,7 @@ private:
void freePickMask();
LLPointer<LLImageRaw> mSaveData; // used for destroyGL/restoreGL
LL::WorkQueue::weak_t mMainQueue;
U8* mPickMask; //downsampled bitmap approximation of alpha channel. NULL if no alpha channel
U16 mPickMaskWidth;
U16 mPickMaskHeight;
@ -271,7 +272,6 @@ public:
public:
static void initClass(LLWindow* window, S32 num_catagories, BOOL skip_analyze_alpha = false);
static void updateClass();
static void cleanupClass() ;
private:
@ -313,27 +313,21 @@ public:
LLImageGLThread(LLWindow* window);
// post a function to be executed on the LLImageGL background thread
bool post(const std::function<void()>& func);
//post a callback to be executed on the main thread
bool postCallback(const std::function<void()>& callback);
void executeCallbacks();
template <typename CALLABLE>
bool post(CALLABLE&& func)
{
return mFunctionQueue.postIfOpen(std::forward<CALLABLE>(func));
}
void run() override;
// Work Queue for background thread
LL::WorkQueue mFunctionQueue;
// Work Queue for main thread (run from updateClass)
LL::WorkQueue mCallbackQueue;
LLWindow* mWindow;
void* mContext;
LLAtomicBool mFinished;
std::queue<std::function<void()>> mPendingCallbackQ;
static LLImageGLThread* sInstance;
};

View File

@ -4848,7 +4848,6 @@ void LLAppViewer::idle()
LLNotificationsUI::LLToast::updateClass();
LLSmoothInterpolation::updateInterpolants();
LLMortician::updateClass();
LLImageGL::updateClass();
LLFilePickerThread::clearDead(); //calls LLFilePickerThread::notify()
LLDirPickerThread::clearDead();
F32 dt_raw = idle_timer.getElapsedTimeAndResetF32();

View File

@ -1626,7 +1626,7 @@ void LLViewerFetchedTexture::scheduleCreateTexture()
{
//actually create the texture on a background thread
createTexture();
LLImageGLThread::sInstance->postCallback([this]()
LL::WorkQueue::getInstance("mainloop")->post([this]()
{
//finalize on main thread
postCreateTexture();