From 2456cf8306be22e32130e789ab939c059e5e79e5 Mon Sep 17 00:00:00 2001 From: Michael Meeks Date: Mon, 7 Sep 2015 22:21:15 +0100 Subject: tdf#94006 - re-factor to use rtl::Reference for OpenGLContexts. Don't use rtl::Reference for the global / list state, so the ref-count reflects the number of real users. Hold a reference during ~OpenGLContext. Change-Id: I4e57a7246159acd58ae7d5a0dfc8704b9795c894 --- vcl/inc/opengl/salbmp.hxx | 4 ++-- vcl/inc/opengl/win/gdiimpl.hxx | 7 +++--- vcl/inc/opengl/x11/gdiimpl.hxx | 4 ++-- vcl/inc/openglgdiimpl.hxx | 10 ++++---- vcl/inc/salgdi.hxx | 2 +- vcl/opengl/gdiimpl.cxx | 47 +++++++++++------------------------- vcl/opengl/salbmp.cxx | 16 +++++++------ vcl/opengl/texture.cxx | 6 ++--- vcl/opengl/win/gdiimpl.cxx | 10 ++++---- vcl/opengl/x11/gdiimpl.cxx | 10 ++++---- vcl/source/app/svdata.cxx | 12 +++------- vcl/source/gdi/salgdilayout.cxx | 2 +- vcl/source/opengl/OpenGLContext.cxx | 48 +++++++++---------------------------- vcl/unx/generic/window/salframe.cxx | 4 ++-- vcl/workben/vcldemo.cxx | 10 ++++---- 15 files changed, 71 insertions(+), 121 deletions(-) (limited to 'vcl') diff --git a/vcl/inc/opengl/salbmp.hxx b/vcl/inc/opengl/salbmp.hxx index f189ea8bc204..1c425dae488b 100644 --- a/vcl/inc/opengl/salbmp.hxx +++ b/vcl/inc/opengl/salbmp.hxx @@ -39,7 +39,7 @@ class BitmapPalette; class VCL_PLUGIN_PUBLIC OpenGLSalBitmap : public SalBitmap { private: - OpenGLContext* mpContext; + rtl::Reference mpContext; OpenGLTexture maTexture; bool mbDirtyTexture; BitmapPalette maPalette; @@ -89,7 +89,7 @@ public: bool Create( const OpenGLTexture& rTex, long nX, long nY, long nWidth, long nHeight ); OpenGLTexture& GetTexture() const; - static OpenGLContext* GetBitmapContext(); + static rtl::Reference GetBitmapContext(); private: diff --git a/vcl/inc/opengl/win/gdiimpl.hxx b/vcl/inc/opengl/win/gdiimpl.hxx index e1fa195286a6..04bb15194de6 100644 --- a/vcl/inc/opengl/win/gdiimpl.hxx +++ b/vcl/inc/opengl/win/gdiimpl.hxx @@ -14,8 +14,7 @@ #include "openglgdiimpl.hxx" #include "win/salgdi.h" - -class OpenGLContext; +#include class WinOpenGLSalGraphicsImpl : public OpenGLSalGraphicsImpl { @@ -31,8 +30,8 @@ public: SalGeometryProvider *mpProvider); protected: - virtual OpenGLContext* CreateWinContext() SAL_OVERRIDE; - virtual bool UseContext( OpenGLContext* pContext ) SAL_OVERRIDE; + virtual rtl::Reference CreateWinContext() SAL_OVERRIDE; + virtual bool UseContext( const rtl::Reference &pContext ) SAL_OVERRIDE; public: virtual void copyBits( const SalTwoRect& rPosAry, SalGraphics* pSrcGraphics ) SAL_OVERRIDE; diff --git a/vcl/inc/opengl/x11/gdiimpl.hxx b/vcl/inc/opengl/x11/gdiimpl.hxx index a87a9dec2de2..19804a8aff17 100644 --- a/vcl/inc/opengl/x11/gdiimpl.hxx +++ b/vcl/inc/opengl/x11/gdiimpl.hxx @@ -28,8 +28,8 @@ public: virtual ~X11OpenGLSalGraphicsImpl(); protected: - virtual OpenGLContext* CreateWinContext() SAL_OVERRIDE; - virtual bool UseContext( OpenGLContext* pContext ) SAL_OVERRIDE; + virtual rtl::Reference CreateWinContext() SAL_OVERRIDE; + virtual bool UseContext( const rtl::Reference &pContext ) SAL_OVERRIDE; bool RenderPixmap(X11Pixmap* pPixmap, X11Pixmap* pMask, int nX, int nY, TextureCombo& rCombo); diff --git a/vcl/inc/openglgdiimpl.hxx b/vcl/inc/openglgdiimpl.hxx index 62a51e1b6df1..71a9e803c8da 100644 --- a/vcl/inc/openglgdiimpl.hxx +++ b/vcl/inc/openglgdiimpl.hxx @@ -52,7 +52,7 @@ class VCL_DLLPUBLIC OpenGLSalGraphicsImpl : public SalGraphicsImpl friend class OpenGLTests; protected: - OpenGLContext* mpContext; + rtl::Reference mpContext; SalGraphics& mrParent; /// Pointer to the SalFrame or SalVirtualDevice SalGeometryProvider* mpProvider; @@ -137,19 +137,19 @@ protected: bool ReleaseContext(); // retrieve the default context for offscreen rendering - static OpenGLContext* GetDefaultContext(); + static rtl::Reference GetDefaultContext(); // create a new context for window rendering - virtual OpenGLContext* CreateWinContext() = 0; + virtual rtl::Reference CreateWinContext() = 0; // check whether the given context can be used by this instance - virtual bool UseContext( OpenGLContext* pContext ) = 0; + virtual bool UseContext( const rtl::Reference &pContext ) = 0; public: OpenGLSalGraphicsImpl(SalGraphics& pParent, SalGeometryProvider *pProvider); virtual ~OpenGLSalGraphicsImpl (); - OpenGLContext* GetOpenGLContext(); + rtl::Reference GetOpenGLContext(); virtual void Init() SAL_OVERRIDE; diff --git a/vcl/inc/salgdi.hxx b/vcl/inc/salgdi.hxx index 16864276e357..033404991e38 100644 --- a/vcl/inc/salgdi.hxx +++ b/vcl/inc/salgdi.hxx @@ -93,7 +93,7 @@ public: virtual SalGraphicsImpl* GetImpl() const = 0; /// Check that our mpImpl is OpenGL and return the context, otherwise NULL. - OpenGLContext* GetOpenGLContext() const; + rtl::Reference GetOpenGLContext() const; void setAntiAliasB2DDraw(bool bNew) { m_bAntiAliasB2DDraw = bNew; } bool getAntiAliasB2DDraw() const { return m_bAntiAliasB2DDraw; } diff --git a/vcl/opengl/gdiimpl.cxx b/vcl/opengl/gdiimpl.cxx index 9a2d72e447b2..54873479b991 100644 --- a/vcl/opengl/gdiimpl.cxx +++ b/vcl/opengl/gdiimpl.cxx @@ -61,14 +61,14 @@ OpenGLSalGraphicsImpl::~OpenGLSalGraphicsImpl() ReleaseContext(); } -OpenGLContext* OpenGLSalGraphicsImpl::GetOpenGLContext() +rtl::Reference OpenGLSalGraphicsImpl::GetOpenGLContext() { if( !AcquireContext() ) return NULL; return mpContext; } -OpenGLContext* OpenGLSalGraphicsImpl::GetDefaultContext() +rtl::Reference OpenGLSalGraphicsImpl::GetDefaultContext() { return ImplGetDefaultWindow()->GetGraphics()->GetOpenGLContext(); } @@ -77,19 +77,14 @@ bool OpenGLSalGraphicsImpl::AcquireContext( ) { ImplSVData* pSVData = ImplGetSVData(); - if( mpContext ) + if( mpContext.is() ) { if( mpContext->isInitialized() ) return true; -#ifdef DBG_UTIL - mpContext->DeRef(this); -#else - mpContext->DeRef(); -#endif + mpContext.clear(); } - - OpenGLContext* pContext = pSVData->maGDIData.mpLastContext; + OpenGLContext *pContext = pSVData->maGDIData.mpLastContext; while( pContext ) { // check if this context can be used by this SalGraphicsImpl instance @@ -99,31 +94,17 @@ bool OpenGLSalGraphicsImpl::AcquireContext( ) } if( pContext ) - { -#ifdef DBG_UTIL - pContext->AddRef(this); -#else - pContext->AddRef(); -#endif - } + mpContext = pContext; else - pContext = mbOffscreen ? GetDefaultContext() : CreateWinContext(); + mpContext = mbOffscreen ? GetDefaultContext() : CreateWinContext(); - mpContext = pContext; - return (mpContext != NULL); + return mpContext.is(); } bool OpenGLSalGraphicsImpl::ReleaseContext() { - if( mpContext ) - { -#ifdef DBG_UTIL - mpContext->DeRef(this); -#else - mpContext->DeRef(); -#endif - } - mpContext = NULL; + mpContext.clear(); + return true; } @@ -132,7 +113,7 @@ void OpenGLSalGraphicsImpl::Init() mbOffscreen = IsOffscreen(); // check if we can simply re-use the same context - if( mpContext ) + if( mpContext.is() ) { if( !UseContext( mpContext ) ) ReleaseContext(); @@ -143,7 +124,7 @@ void OpenGLSalGraphicsImpl::Init() maOffscreenTex.GetWidth() != GetWidth() || maOffscreenTex.GetHeight() != GetHeight() ) { - if( mpContext ) // valid context + if( mpContext.is() ) // valid context mpContext->ReleaseFramebuffer( maOffscreenTex ); maOffscreenTex = OpenGLTexture(); } @@ -158,7 +139,7 @@ void OpenGLSalGraphicsImpl::DeInit() // let it know. Other eg. VirtualDevice contexts which have // references on and rely on this context continuing to work will // get a shiny new context in AcquireContext:: next PreDraw. - if( mpContext && !IsOffscreen() ) + if( mpContext.is() && !IsOffscreen() ) mpContext->reset(); } @@ -216,7 +197,7 @@ void OpenGLSalGraphicsImpl::ApplyProgramMatrices(float fPixelOffset) void OpenGLSalGraphicsImpl::freeResources() { // TODO Delete shaders, programs and textures if not shared - if( mbOffscreen && mpContext && mpContext->isInitialized() ) + if( mbOffscreen && mpContext.is() && mpContext->isInitialized() ) { mpContext->makeCurrent(); mpContext->ReleaseFramebuffer( maOffscreenTex ); diff --git a/vcl/opengl/salbmp.cxx b/vcl/opengl/salbmp.cxx index 9084ae17dcde..fefa3817b8b2 100644 --- a/vcl/opengl/salbmp.cxx +++ b/vcl/opengl/salbmp.cxx @@ -595,7 +595,7 @@ void OpenGLSalBitmap::updateChecksum() const OpenGLSalBitmap* pThis = const_cast(this); - if (!mpContext) + if (!mpContext.is()) { pThis->CreateTexture(); } @@ -614,7 +614,7 @@ void OpenGLSalBitmap::updateChecksum() const } } -OpenGLContext* OpenGLSalBitmap::GetBitmapContext() +rtl::Reference OpenGLSalBitmap::GetBitmapContext() { return ImplGetDefaultWindow()->GetGraphics()->GetOpenGLContext(); } @@ -624,12 +624,14 @@ void OpenGLSalBitmap::makeCurrent() ImplSVData* pSVData = ImplGetSVData(); // TODO: make sure we can really use the last used context - mpContext = pSVData->maGDIData.mpLastContext; - while( mpContext && !mpContext->isInitialized() ) - mpContext = mpContext->mpPrevContext; - if( !mpContext ) + OpenGLContext *pContext = pSVData->maGDIData.mpLastContext; + while( pContext && !pContext->isInitialized() ) + pContext = pContext->mpPrevContext; + if( pContext ) + mpContext = pContext; + else mpContext = GetBitmapContext(); - assert(mpContext && "Couldn't get an OpenGL context"); + assert(mpContext.is() && "Couldn't get an OpenGL context"); mpContext->makeCurrent(); } diff --git a/vcl/opengl/texture.cxx b/vcl/opengl/texture.cxx index 57bd7a60a946..9b3c60592ea5 100644 --- a/vcl/opengl/texture.cxx +++ b/vcl/opengl/texture.cxx @@ -113,8 +113,8 @@ ImplOpenGLTexture::~ImplOpenGLTexture() // Check we have been correctly un-bound from all framebuffers. ImplSVData* pSVData = ImplGetSVData(); - OpenGLContext* pContext = pSVData->maGDIData.mpLastContext; - if (pContext) + rtl::Reference pContext = pSVData->maGDIData.mpLastContext; + if (pContext.is()) pContext->UnbindTextureFromFramebuffers( mnTexture ); glDeleteTextures( 1, &mnTexture ); @@ -375,7 +375,7 @@ void OpenGLTexture::Read( GLenum nFormat, GLenum nType, sal_uInt8* pData ) { // Retrieve current context ImplSVData* pSVData = ImplGetSVData(); - OpenGLContext* pContext = pSVData->maGDIData.mpLastContext; + rtl::Reference pContext = pSVData->maGDIData.mpLastContext; OpenGLFramebuffer* pFramebuffer; pFramebuffer = pContext->AcquireFramebuffer( *this ); diff --git a/vcl/opengl/win/gdiimpl.cxx b/vcl/opengl/win/gdiimpl.cxx index 6896a024ec7d..30088a9deb88 100644 --- a/vcl/opengl/win/gdiimpl.cxx +++ b/vcl/opengl/win/gdiimpl.cxx @@ -29,21 +29,21 @@ void WinOpenGLSalGraphicsImpl::copyBits( const SalTwoRect& rPosAry, SalGraphics* OpenGLSalGraphicsImpl::DoCopyBits( rPosAry, *pImpl ); } -OpenGLContext* WinOpenGLSalGraphicsImpl::CreateWinContext() +rtl::Reference WinOpenGLSalGraphicsImpl::CreateWinContext() { - OpenGLContext* pContext = new OpenGLContext(); + rtl::Reference pContext = OpenGLContext::Create(); pContext->requestSingleBufferedRendering(); pContext->init( mrParent.mhLocalDC, mrParent.mhWnd ); return pContext; } -bool WinOpenGLSalGraphicsImpl::UseContext( OpenGLContext* pContext ) +bool WinOpenGLSalGraphicsImpl::UseContext( const rtl::Reference &pContext ) { - if( !pContext || !pContext->isInitialized() ) + if( !pContext.is() || !pContext->isInitialized() ) return false; if( IsOffscreen() ) return true; - return ( pContext->getOpenGLWindow().hWnd == mrParent.mhWnd ); + return pContext->getOpenGLWindow().hWnd == mrParent.mhWnd; } namespace diff --git a/vcl/opengl/x11/gdiimpl.cxx b/vcl/opengl/x11/gdiimpl.cxx index 4c592842d9d8..65b279b43f11 100644 --- a/vcl/opengl/x11/gdiimpl.cxx +++ b/vcl/opengl/x11/gdiimpl.cxx @@ -44,7 +44,7 @@ void X11OpenGLSalGraphicsImpl::Init() OpenGLSalGraphicsImpl::Init(); } -OpenGLContext* X11OpenGLSalGraphicsImpl::CreateWinContext() +rtl::Reference X11OpenGLSalGraphicsImpl::CreateWinContext() { X11WindowProvider *pProvider = dynamic_cast(mrParent.m_pFrame); @@ -52,13 +52,13 @@ OpenGLContext* X11OpenGLSalGraphicsImpl::CreateWinContext() return NULL; Window aWin = pProvider->GetX11Window(); - OpenGLContext* pContext = new OpenGLContext(); + rtl::Reference pContext = OpenGLContext::Create(); pContext->init( mrParent.GetXDisplay(), aWin, mrParent.m_nXScreen.getXScreen() ); return pContext; } -bool X11OpenGLSalGraphicsImpl::UseContext( OpenGLContext* pContext ) +bool X11OpenGLSalGraphicsImpl::UseContext( const rtl::Reference &pContext ) { X11WindowProvider *pProvider = dynamic_cast(mrParent.m_pFrame); @@ -66,9 +66,9 @@ bool X11OpenGLSalGraphicsImpl::UseContext( OpenGLContext* pContext ) return false; if( !pProvider ) - return ( pContext->getOpenGLWindow().win != None ); + return pContext->getOpenGLWindow().win != None; else - return ( pContext->getOpenGLWindow().win == pProvider->GetX11Window() ); + return pContext->getOpenGLWindow().win == pProvider->GetX11Window(); } void X11OpenGLSalGraphicsImpl::copyBits( const SalTwoRect& rPosAry, SalGraphics* pSrcGraphics ) diff --git a/vcl/source/app/svdata.cxx b/vcl/source/app/svdata.cxx index bfc2bb402ee7..ca815a2f3103 100644 --- a/vcl/source/app/svdata.cxx +++ b/vcl/source/app/svdata.cxx @@ -140,15 +140,9 @@ vcl::Window* ImplGetDefaultWindow() pSVData->mpDefaultWin->SetText( OUString( "VCL ImplGetDefaultWindow" ) ); // Add a reference to the default context so it never gets deleted - OpenGLContext* pContext = pSVData->mpDefaultWin->GetGraphics()->GetOpenGLContext(); - if( pContext ) - { -#ifdef DBG_UTIL - pContext->AddRef(NULL); -#else - pContext->AddRef(); -#endif - } + rtl::Reference pContext = pSVData->mpDefaultWin->GetGraphics()->GetOpenGLContext(); + if( pContext.is() ) + pContext->acquire(); } Application::GetSolarMutex().release(); } diff --git a/vcl/source/gdi/salgdilayout.cxx b/vcl/source/gdi/salgdilayout.cxx index 46f76ffb33cc..945f7ae9f687 100644 --- a/vcl/source/gdi/salgdilayout.cxx +++ b/vcl/source/gdi/salgdilayout.cxx @@ -76,7 +76,7 @@ SalGraphics::~SalGraphics() { } -OpenGLContext* SalGraphics::GetOpenGLContext() const +rtl::Reference SalGraphics::GetOpenGLContext() const { OpenGLSalGraphicsImpl *pImpl = dynamic_cast(GetImpl()); if (pImpl) diff --git a/vcl/source/opengl/OpenGLContext.cxx b/vcl/source/opengl/OpenGLContext.cxx index df8c6a60c18b..d070e3fb3b6b 100644 --- a/vcl/source/opengl/OpenGLContext.cxx +++ b/vcl/source/opengl/OpenGLContext.cxx @@ -58,7 +58,7 @@ OpenGLContext::OpenGLContext(): mpWindow(NULL), m_pChildWindow(NULL), mbInitialized(false), - mnRefCount(1), + mnRefCount(0), mbRequestLegacyContext(false), mbUseDoubleBufferedRendering(true), mnFramebufferCount(0), @@ -93,6 +93,9 @@ OpenGLContext::OpenGLContext(): OpenGLContext::~OpenGLContext() { VCL_GL_INFO("vcl.opengl", "delete context: " << this); + assert (mnRefCount == 0); + + mnRefCount = 1; // guard the shutdown paths. reset(); ImplSVData* pSVData = ImplGetSVData(); @@ -106,42 +109,13 @@ OpenGLContext::~OpenGLContext() pSVData->maGDIData.mpLastContext = mpPrevContext; m_pChildWindow.disposeAndClear(); + assert (mnRefCount == 1); } -#ifdef DBG_UTIL -void OpenGLContext::AddRef(SalGraphicsImpl* pImpl) -{ - assert(mnRefCount > 0); - mnRefCount++; - - maParents.insert(pImpl); -} - -void OpenGLContext::DeRef(SalGraphicsImpl* pImpl) +rtl::Reference OpenGLContext::Create() { - - auto it = maParents.find(pImpl); - if(it != maParents.end()) - maParents.erase(it); - - assert(mnRefCount > 0); - if( --mnRefCount == 0 ) - delete this; + return rtl::Reference(new OpenGLContext); } -#else -void OpenGLContext::AddRef() -{ - assert(mnRefCount > 0); - mnRefCount++; -} - -void OpenGLContext::DeRef() -{ - assert(mnRefCount > 0); - if( --mnRefCount == 0 ) - delete this; -} -#endif void OpenGLContext::requestLegacyContext() { @@ -1337,8 +1311,8 @@ void OpenGLContext::clearCurrent() // release all framebuffers from the old context so we can re-attach the // texture in the new context - OpenGLContext* pCurrentCtx = pSVData->maGDIData.mpLastContext; - if( pCurrentCtx && pCurrentCtx->isCurrent() ) + rtl::Reference pCurrentCtx = pSVData->maGDIData.mpLastContext; + if( pCurrentCtx.is() && pCurrentCtx->isCurrent() ) pCurrentCtx->ReleaseFramebuffers(); } @@ -1348,9 +1322,9 @@ void OpenGLContext::prepareForYield() // release all framebuffers from the old context so we can re-attach the // texture in the new context - OpenGLContext* pCurrentCtx = pSVData->maGDIData.mpLastContext; + rtl::Reference pCurrentCtx = pSVData->maGDIData.mpLastContext; - if ( !pCurrentCtx ) + if ( !pCurrentCtx.is() ) return; // Not using OpenGL SAL_INFO("vcl.opengl", "Unbinding contexts in preparation for yield"); diff --git a/vcl/unx/generic/window/salframe.cxx b/vcl/unx/generic/window/salframe.cxx index 2693580071a9..965d3b80f2c6 100644 --- a/vcl/unx/generic/window/salframe.cxx +++ b/vcl/unx/generic/window/salframe.cxx @@ -893,8 +893,8 @@ X11SalFrame::~X11SalFrame() } // reset all OpenGL contexts using this window - OpenGLContext* pContext = ImplGetSVData()->maGDIData.mpLastContext; - while( pContext ) + rtl::Reference pContext = ImplGetSVData()->maGDIData.mpLastContext; + while( pContext.is() ) { if( pContext->getOpenGLWindow().win == mhWindow ) pContext->reset(); diff --git a/vcl/workben/vcldemo.cxx b/vcl/workben/vcldemo.cxx index b6c96e280a0e..b3c6c86f63b3 100644 --- a/vcl/workben/vcldemo.cxx +++ b/vcl/workben/vcldemo.cxx @@ -1657,8 +1657,8 @@ class OpenGLTests VclPtr mxWinB; OpenGLSalGraphicsImpl *mpImplA; OpenGLSalGraphicsImpl *mpImplB; - OpenGLContext *mpA; - OpenGLContext *mpB; + rtl::Reference mpA; + rtl::Reference mpB; static OpenGLSalGraphicsImpl *getImpl(const VclPtr &xOut) { @@ -1682,7 +1682,7 @@ public: mpA = mpImplA->GetOpenGLContext(); mpB = mpImplB->GetOpenGLContext(); - assert (mpA && mpB); + assert (mpA.is() && mpB.is()); assert (mpA != mpB); } ~OpenGLTests() @@ -1715,9 +1715,9 @@ public: // get some other guys to leach off this context VclPtrInstance xVDev; - OpenGLContext *pContext = getImpl(xVDev)->GetOpenGLContext(); + rtl::Reference pContext = getImpl(xVDev)->GetOpenGLContext(); VclPtrInstance xVDev2; - OpenGLContext *pContext2 = getImpl(xVDev)->GetOpenGLContext(); + rtl::Reference pContext2 = getImpl(xVDev)->GetOpenGLContext(); // sharing the same off-screen context. assert(pContext == pContext2); -- cgit