vcl: Use std::list to manage OpenGLContexts in ImplSVGDIData
... instead of manually implementing a doubly-linked list. (All entries are non-null, so no need for keeping null checks where they were previously only used to check whether there is a previous/next element.) Change-Id: Iff56b21e36b705803718b594e6d9ec66a85fa698 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/202455 Reviewed-by: Michael Weghorn <m.weghorn@posteo.de> Tested-by: Jenkins
This commit is contained in:
@@ -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: */
|
||||
|
||||
+2
-1
@@ -51,6 +51,7 @@
|
||||
#include "displayconnectiondispatch.hxx"
|
||||
|
||||
#include <atomic>
|
||||
#include <list>
|
||||
#include <mutex>
|
||||
#include <optional>
|
||||
#include <vector>
|
||||
@@ -229,7 +230,7 @@ struct ImplSVGDIData
|
||||
VclPtr<Printer> mpFirstPrnGraphics; // First OutputDevice with an InfoPrinter Graphics
|
||||
VclPtr<Printer> mpLastPrnGraphics; // Last OutputDevice with an InfoPrinter Graphics
|
||||
VclPtr<VirtualDevice> mpFirstVirDev; // First VirtualDevice
|
||||
OpenGLContext* mpLastContext = nullptr; // Last OpenGLContext
|
||||
std::list<OpenGLContext*> maOpenGLContexts; // OpenGL contexts
|
||||
VclPtr<Printer> mpFirstPrinter; // First Printer
|
||||
std::unique_ptr<ImplPrnQueueList> mpPrinterQueueList; // List of all printer queue
|
||||
std::shared_ptr<vcl::font::PhysicalFontCollection> mxScreenFontList; // Screen-Font-List
|
||||
|
||||
@@ -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<OpenGLContext> 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<OpenGLContext> 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()
|
||||
|
||||
@@ -814,12 +814,11 @@ X11SalFrame::~X11SalFrame()
|
||||
pFreeGraphics_.reset();
|
||||
|
||||
// reset all OpenGL contexts using this window
|
||||
rtl::Reference<OpenGLContext> pContext = ImplGetSVData()->maGDIData.mpLastContext;
|
||||
while( pContext.is() )
|
||||
const std::list<OpenGLContext*>& rContexts = ImplGetSVData()->maGDIData.maOpenGLContexts;
|
||||
for (auto aContextIt = rContexts.rbegin(); aContextIt != rContexts.rend(); ++aContextIt)
|
||||
{
|
||||
if (static_cast<const GLX11Window&>(pContext->getOpenGLWindow()).win == mhWindow)
|
||||
pContext->reset();
|
||||
pContext = pContext->mpPrevContext;
|
||||
if (static_cast<const GLX11Window&>((*aContextIt)->getOpenGLWindow()).win == mhWindow)
|
||||
(*aContextIt)->reset();
|
||||
}
|
||||
|
||||
if (mpSurface)
|
||||
|
||||
Reference in New Issue
Block a user