From 6f0f4ee720ef1e8262731f59f254b83d5bdd058c Mon Sep 17 00:00:00 2001 From: Michael Meeks Date: Tue, 15 Sep 2015 14:07:27 +0100 Subject: tdf#94213 - release offscreen texture properly on re-size. We need to ensure that we use an initialized context, and that (when we re-parent) we DeInit and so reset the previous OpenGLContext. Make UseContext more paranoid as well for good measure. Change-Id: Ia45334222045e5d2f48da47560fab8511223a9a5 Reviewed-on: https://gerrit.libreoffice.org/18601 Tested-by: Jenkins Reviewed-by: Michael Meeks --- vcl/inc/opengl/win/gdiimpl.hxx | 1 + vcl/opengl/gdiimpl.cxx | 9 +++++++-- vcl/opengl/win/gdiimpl.cxx | 18 +++++++++++++++++- vcl/source/opengl/OpenGLContext.cxx | 3 +++ vcl/win/source/window/salframe.cxx | 2 +- 5 files changed, 29 insertions(+), 4 deletions(-) (limited to 'vcl') diff --git a/vcl/inc/opengl/win/gdiimpl.hxx b/vcl/inc/opengl/win/gdiimpl.hxx index 04bb15194de6..5c91727f3800 100644 --- a/vcl/inc/opengl/win/gdiimpl.hxx +++ b/vcl/inc/opengl/win/gdiimpl.hxx @@ -34,6 +34,7 @@ protected: virtual bool UseContext( const rtl::Reference &pContext ) SAL_OVERRIDE; public: + virtual void Init() SAL_OVERRIDE; virtual void copyBits( const SalTwoRect& rPosAry, SalGraphics* pSrcGraphics ) SAL_OVERRIDE; diff --git a/vcl/opengl/gdiimpl.cxx b/vcl/opengl/gdiimpl.cxx index 6580f43f556a..943e1b43fe21 100644 --- a/vcl/opengl/gdiimpl.cxx +++ b/vcl/opengl/gdiimpl.cxx @@ -115,7 +115,8 @@ void OpenGLSalGraphicsImpl::Init() // check if we can simply re-use the same context if( mpContext.is() ) { - if( !UseContext( mpContext ) ) + if( !mpContext->isInitialized() || + !UseContext( mpContext ) ) ReleaseContext(); } @@ -124,8 +125,12 @@ void OpenGLSalGraphicsImpl::Init() maOffscreenTex.GetWidth() != GetWidth() || maOffscreenTex.GetHeight() != GetHeight() ) { - if( mpContext.is() ) // valid context + if( maOffscreenTex && // don't work to release empty textures + mpContext.is() ) // valid context + { + mpContext->makeCurrent(); mpContext->ReleaseFramebuffer( maOffscreenTex ); + } maOffscreenTex = OpenGLTexture(); } } diff --git a/vcl/opengl/win/gdiimpl.cxx b/vcl/opengl/win/gdiimpl.cxx index 30088a9deb88..3ba269487ea9 100644 --- a/vcl/opengl/win/gdiimpl.cxx +++ b/vcl/opengl/win/gdiimpl.cxx @@ -43,7 +43,23 @@ bool WinOpenGLSalGraphicsImpl::UseContext( const rtl::Reference & return false; if( IsOffscreen() ) return true; - return pContext->getOpenGLWindow().hWnd == mrParent.mhWnd; + return pContext->getOpenGLWindow().hWnd == mrParent.mhWnd && + pContext->getOpenGLWindow().hDC == mrParent.mhLocalDC; +} + +void WinOpenGLSalGraphicsImpl::Init() +{ + if ( !IsOffscreen() && mpContext.is() && mpContext->isInitialized() && + ( mpContext->getOpenGLWindow().hWnd != mrParent.mhWnd || + mpContext->getOpenGLWindow().hDC == mrParent.mhLocalDC ) ) + { + // This can legitimiately happen, SalFrame keeps 2x + // SalGraphics which share the same hWnd and hDC. + // The shape 'Area' dialog does reparenting to trigger this. + SAL_WARN("vcl.opengl", "Unusual: Windows handle / DC changed without DeInit"); + } + + OpenGLSalGraphicsImpl::Init(); } namespace diff --git a/vcl/source/opengl/OpenGLContext.cxx b/vcl/source/opengl/OpenGLContext.cxx index bfbd8a7b9607..1aab588565f1 100644 --- a/vcl/source/opengl/OpenGLContext.cxx +++ b/vcl/source/opengl/OpenGLContext.cxx @@ -1602,6 +1602,9 @@ void OpenGLContext::ReleaseFramebuffer( const OpenGLTexture& rTexture ) { OpenGLZone aZone; + if (!rTexture) // no texture to release. + return; + OpenGLFramebuffer* pFramebuffer = mpLastFramebuffer; while( pFramebuffer ) diff --git a/vcl/win/source/window/salframe.cxx b/vcl/win/source/window/salframe.cxx index 42681731817d..d2bb24015457 100644 --- a/vcl/win/source/window/salframe.cxx +++ b/vcl/win/source/window/salframe.cxx @@ -1493,7 +1493,7 @@ static void ImplSetParentFrame( WinSalFrame* pThis, HWND hNewParentWnd, bool bAs { if ( pThis->mpGraphics->getDefPal() ) SelectPalette( pThis->mpGraphics->getHDC(), pThis->mpGraphics->getDefPal(), TRUE ); - pThis->mpGraphics->InitGraphics(); + pThis->mpGraphics->DeInitGraphics(); ReleaseDC( pThis->mhWnd, pThis->mpGraphics->getHDC() ); } -- cgit