From eec2ba3623f0ad74e3f6747c9dcb959d28321edd Mon Sep 17 00:00:00 2001 From: Mads Buvik Sandvei Date: Fri, 18 Dec 2020 18:15:14 +0000 Subject: [PATCH] Loading screen initialdrawcallback 4th time's the charm --- apps/openmw/mwgui/loadingscreen.cpp | 34 ++++++++++++++++++++++++----- apps/openmw/mwgui/loadingscreen.hpp | 1 + 2 files changed, 30 insertions(+), 5 deletions(-) diff --git a/apps/openmw/mwgui/loadingscreen.cpp b/apps/openmw/mwgui/loadingscreen.cpp index 5f0e9f33a3..7ddc8c5507 100644 --- a/apps/openmw/mwgui/loadingscreen.cpp +++ b/apps/openmw/mwgui/loadingscreen.cpp @@ -46,6 +46,7 @@ namespace MWGui , mProgress(0) , mShowWallpaper(true) , mOldCallback(nullptr) + , mHasCallback(false) { mMainWidget->setSize(MyGUI::RenderManager::getInstance().getViewSize()); @@ -139,13 +140,19 @@ namespace MWGui { public: CopyFramebufferToTextureCallback(osg::Texture2D* texture) - : mTexture(texture) - , mOneshot(true) + : mOneshot(true) + , mTexture(texture) { } void operator () (osg::RenderInfo& renderInfo) const override { + { + std::unique_lock lock(mMutex); + mOneshot = false; + } + mSignal.notify_all(); + int w = renderInfo.getCurrentCamera()->getViewport()->width(); int h = renderInfo.getCurrentCamera()->getViewport()->height(); mTexture->copyTexImage2D(*renderInfo.getState(), 0, 0, w, h); @@ -164,6 +171,18 @@ namespace MWGui mSignal.wait(lock); } + void waitUntilInvoked() + { + std::unique_lock lock(mMutex); + while (mOneshot) + mSignal.wait(lock); + } + + void reset() + { + mOneshot = true; + } + private: mutable bool mOneshot; mutable std::mutex mMutex; @@ -349,6 +368,8 @@ namespace MWGui mOldCallback = mViewer->getCamera()->getInitialDrawCallback(); mViewer->getCamera()->setInitialDrawCallback(mCopyFramebufferToTextureCallback); #endif + mCopyFramebufferToTextureCallback->reset(); + mHasCallback = true; mBackgroundImage->setBackgroundImage(""); mBackgroundImage->setVisible(false); @@ -391,16 +412,19 @@ namespace MWGui mViewer->renderingTraversals(); mViewer->advance(mViewer->getFrameStamp()->getSimulationTime()); - if (mCopyFramebufferToTextureCallback) + if (mHasCallback) { - mCopyFramebufferToTextureCallback->wait(); + mCopyFramebufferToTextureCallback->waitUntilInvoked(); + + // Note that we are removing the callback before the draw thread has returned from it. + // This is OK as we are retaining the ref_ptr. #if OSG_VERSION_GREATER_OR_EQUAL(3, 5, 10) mViewer->getCamera()->removeInitialDrawCallback(mCopyFramebufferToTextureCallback); #else // TODO: Remove once we officially end support for OSG versions pre 3.5.10 mViewer->getCamera()->setInitialDrawCallback(mOldCallback); #endif - mCopyFramebufferToTextureCallback = nullptr; + mHasCallback = false; } mLastRenderTime = mTimer.time_m(); diff --git a/apps/openmw/mwgui/loadingscreen.hpp b/apps/openmw/mwgui/loadingscreen.hpp index d58899eae4..5d86ed3896 100644 --- a/apps/openmw/mwgui/loadingscreen.hpp +++ b/apps/openmw/mwgui/loadingscreen.hpp @@ -88,6 +88,7 @@ namespace MWGui osg::ref_ptr mTexture; osg::ref_ptr mCopyFramebufferToTextureCallback; osg::ref_ptr mOldCallback; + bool mHasCallback; std::unique_ptr mGuiTexture; void changeWallpaper();