diff --git a/include/vcl/opengl/OpenGLContext.hxx b/include/vcl/opengl/OpenGLContext.hxx index b8748bdc0f49..0a5a978736bd 100644 --- a/include/vcl/opengl/OpenGLContext.hxx +++ b/include/vcl/opengl/OpenGLContext.hxx @@ -117,12 +117,6 @@ protected: bool mbInitialized; int mnRefCount; bool mbRequestLegacyContext; - -public: - - // Don't hold references to ourselves: - OpenGLContext *mpPrevContext; - OpenGLContext *mpNextContext; }; /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/inc/svdata.hxx b/vcl/inc/svdata.hxx index 8a61b6059f92..fa9fd2b3d649 100644 --- a/vcl/inc/svdata.hxx +++ b/vcl/inc/svdata.hxx @@ -51,6 +51,7 @@ #include "displayconnectiondispatch.hxx" #include +#include #include #include #include @@ -229,7 +230,7 @@ struct ImplSVGDIData VclPtr mpFirstPrnGraphics; // First OutputDevice with an InfoPrinter Graphics VclPtr mpLastPrnGraphics; // Last OutputDevice with an InfoPrinter Graphics VclPtr mpFirstVirDev; // First VirtualDevice - OpenGLContext* mpLastContext = nullptr; // Last OpenGLContext + std::list maOpenGLContexts; // OpenGL contexts VclPtr mpFirstPrinter; // First Printer std::unique_ptr mpPrinterQueueList; // List of all printer queue std::shared_ptr mxScreenFontList; // Screen-Font-List diff --git a/vcl/source/opengl/OpenGLContext.cxx b/vcl/source/opengl/OpenGLContext.cxx index d79f7064c704..5c1aff916cd6 100644 --- a/vcl/source/opengl/OpenGLContext.cxx +++ b/vcl/source/opengl/OpenGLContext.cxx @@ -45,19 +45,12 @@ OpenGLContext::OpenGLContext(): m_pChildWindow(nullptr), mbInitialized(false), mnRefCount(0), - mbRequestLegacyContext(false), - mpPrevContext(nullptr), - mpNextContext(nullptr) + mbRequestLegacyContext(false) { VCL_GL_INFO("new context: " << this); ImplSVData* pSVData = ImplGetSVData(); - if( pSVData->maGDIData.mpLastContext ) - { - pSVData->maGDIData.mpLastContext->mpNextContext = this; - mpPrevContext = pSVData->maGDIData.mpLastContext; - } - pSVData->maGDIData.mpLastContext = this; + pSVData->maGDIData.maOpenGLContexts.push_back(this); // FIXME: better hope we call 'makeCurrent' soon to preserve // the invariant that the last item is the current context. @@ -72,13 +65,7 @@ OpenGLContext::~OpenGLContext() reset(); - ImplSVData* pSVData = ImplGetSVData(); - if( mpPrevContext ) - mpPrevContext->mpNextContext = mpNextContext; - if( mpNextContext ) - mpNextContext->mpPrevContext = mpPrevContext; - else - pSVData->maGDIData.mpLastContext = mpPrevContext; + ImplGetSVData()->maGDIData.maOpenGLContexts.remove(this); m_pChildWindow.disposeAndClear(); assert (mnRefCount == 1); @@ -379,8 +366,10 @@ bool OpenGLContext::isAnyCurrent() bool OpenGLContext::hasCurrent() { ImplSVData* pSVData = ImplGetSVData(); - rtl::Reference pCurrentCtx = pSVData->maGDIData.mpLastContext; - return pCurrentCtx.is() && pCurrentCtx->isAnyCurrent(); + if (pSVData->maGDIData.maOpenGLContexts.empty()) + return false; + + return pSVData->maGDIData.maOpenGLContexts.back()->isAnyCurrent(); } void OpenGLContext::prepareForYield() @@ -389,25 +378,22 @@ void OpenGLContext::prepareForYield() // release all framebuffers from the old context so we can re-attach the // texture in the new context - rtl::Reference pCurrentCtx = pSVData->maGDIData.mpLastContext; - - if ( !pCurrentCtx.is() ) - return; // Not using OpenGL + if (pSVData->maGDIData.maOpenGLContexts.empty()) + return; // Not using OpenGL SAL_INFO("vcl.opengl", "Unbinding contexts in preparation for yield"); // Find the first context that is current and reset it. // Usually the last context is the current, but not in case a new // OpenGLContext is created already but not yet initialized. - while (pCurrentCtx.is()) + for (auto aContextIt = pSVData->maGDIData.maOpenGLContexts.rbegin(); + aContextIt != pSVData->maGDIData.maOpenGLContexts.rend(); ++aContextIt) { - if (pCurrentCtx->isCurrent()) + if ((*aContextIt)->isCurrent()) { - pCurrentCtx->resetCurrent(); + (*aContextIt)->resetCurrent(); break; } - - pCurrentCtx = pCurrentCtx->mpPrevContext; } assert (!hasCurrent()); @@ -420,17 +406,8 @@ void OpenGLContext::registerAsCurrent() // move the context to the end of the contexts list static int nSwitch = 0; VCL_GL_INFO("******* CONTEXT SWITCH " << ++nSwitch << " *********"); - if( mpNextContext ) - { - if( mpPrevContext ) - mpPrevContext->mpNextContext = mpNextContext; - mpNextContext->mpPrevContext = mpPrevContext; - - mpPrevContext = pSVData->maGDIData.mpLastContext; - mpNextContext = nullptr; - pSVData->maGDIData.mpLastContext->mpNextContext = this; - pSVData->maGDIData.mpLastContext = this; - } + pSVData->maGDIData.maOpenGLContexts.remove(this); + pSVData->maGDIData.maOpenGLContexts.push_back(this); } void OpenGLContext::resetCurrent() diff --git a/vcl/unx/generic/window/salframe.cxx b/vcl/unx/generic/window/salframe.cxx index 845edd142e7d..793da9a47ad1 100644 --- a/vcl/unx/generic/window/salframe.cxx +++ b/vcl/unx/generic/window/salframe.cxx @@ -814,12 +814,11 @@ X11SalFrame::~X11SalFrame() pFreeGraphics_.reset(); // reset all OpenGL contexts using this window - rtl::Reference pContext = ImplGetSVData()->maGDIData.mpLastContext; - while( pContext.is() ) + const std::list& rContexts = ImplGetSVData()->maGDIData.maOpenGLContexts; + for (auto aContextIt = rContexts.rbegin(); aContextIt != rContexts.rend(); ++aContextIt) { - if (static_cast(pContext->getOpenGLWindow()).win == mhWindow) - pContext->reset(); - pContext = pContext->mpPrevContext; + if (static_cast((*aContextIt)->getOpenGLWindow()).win == mhWindow) + (*aContextIt)->reset(); } if (mpSurface)