From bfceb557efcd607ef018ae35fc73f8d61a9b9a4e Mon Sep 17 00:00:00 2001 From: Michael Meeks Date: Wed, 16 Sep 2015 09:17:37 +0100 Subject: GL paint-flushing guard re-work. Unfortunately, since we can have 2x SalGraphics' on a OutputDevice, and one of these can be a printer - things got very confused around which context to glFlush. This de-tangles the various reference-counts. Change-Id: I1062be0b02a91fc9009deaa3ec29c5dbb227df20 Reviewed-on: https://gerrit.libreoffice.org/18604 Reviewed-by: Michael Meeks Tested-by: Michael Meeks --- include/vcl/outdev.hxx | 18 ++++++++++++--- vcl/inc/generic/genpspgraphics.h | 3 --- vcl/inc/headless/svpgdi.hxx | 3 --- vcl/inc/openglgdiimpl.hxx | 3 +-- vcl/inc/quartz/salgdi.h | 3 --- vcl/inc/salgdi.hxx | 3 +-- vcl/inc/salgdiimpl.hxx | 4 ++-- vcl/inc/unx/salgdi.h | 3 +-- vcl/inc/win/salgdi.h | 3 +-- vcl/opengl/gdiimpl.cxx | 28 +++++------------------ vcl/source/opengl/OpenGLHelper.cxx | 46 +++++++++++++++++++++++++++++++++++++- vcl/source/outdev/outdev.cxx | 12 ---------- vcl/source/window/paint.cxx | 16 ++++--------- vcl/unx/generic/gdi/gdiimpl.hxx | 3 --- vcl/unx/generic/gdi/salgdi.cxx | 7 +----- vcl/win/source/gdi/gdiimpl.hxx | 3 --- vcl/win/source/gdi/salgdi.cxx | 7 +----- 17 files changed, 77 insertions(+), 88 deletions(-) diff --git a/include/vcl/outdev.hxx b/include/vcl/outdev.hxx index c8ba06a112fe..20bd81ae197f 100644 --- a/include/vcl/outdev.hxx +++ b/include/vcl/outdev.hxx @@ -606,9 +606,21 @@ public: const Point& rSrcPt, const Size& rSrcSize, bool bWindowInvalidate = false ); - // Call before and after a paint operation to reduce flushing - void BeginPaint(); - void EndPaint(); + /** + * Instantiate across a paint operation to defer flushing + * to the end. + * + * NB. holding a handle avoids problems with + * the underlying SalGraphics and it's implementation + * changing. + */ + class PaintScope { + void *pHandle; + public: + PaintScope(OutputDevice *); + ~PaintScope(); + void flush(); + }; protected: diff --git a/vcl/inc/generic/genpspgraphics.h b/vcl/inc/generic/genpspgraphics.h index baa6b1d1e4a7..68bc0fb7543f 100644 --- a/vcl/inc/generic/genpspgraphics.h +++ b/vcl/inc/generic/genpspgraphics.h @@ -214,9 +214,6 @@ public: virtual SystemFontData GetSysFontData( int nFallbacklevel ) const SAL_OVERRIDE; #endif // ENABLE_CAIRO_CANVAS - - virtual void BeginPaint() SAL_OVERRIDE { }; - virtual void EndPaint() SAL_OVERRIDE { }; }; #endif // INCLUDED_VCL_INC_GENERIC_GENPSPGRAPHICS_H diff --git a/vcl/inc/headless/svpgdi.hxx b/vcl/inc/headless/svpgdi.hxx index 0903d6e23565..6e98ff3449d3 100644 --- a/vcl/inc/headless/svpgdi.hxx +++ b/vcl/inc/headless/svpgdi.hxx @@ -212,9 +212,6 @@ public: void clipRegion(cairo_t* cr); #endif // ENABLE_CAIRO_CANVAS - - virtual void BeginPaint() SAL_OVERRIDE { }; - virtual void EndPaint() SAL_OVERRIDE { }; }; #endif diff --git a/vcl/inc/openglgdiimpl.hxx b/vcl/inc/openglgdiimpl.hxx index 71a9e803c8da..e3bec4431ef9 100644 --- a/vcl/inc/openglgdiimpl.hxx +++ b/vcl/inc/openglgdiimpl.hxx @@ -320,8 +320,7 @@ public: virtual bool drawGradient(const tools::PolyPolygon& rPolygon, const Gradient& rGradient) SAL_OVERRIDE; - virtual void beginPaint() SAL_OVERRIDE; - virtual void endPaint() SAL_OVERRIDE; + virtual OpenGLContext *beginPaint() SAL_OVERRIDE; private: }; diff --git a/vcl/inc/quartz/salgdi.h b/vcl/inc/quartz/salgdi.h index 72cd424f1c0b..98ebd87384df 100644 --- a/vcl/inc/quartz/salgdi.h +++ b/vcl/inc/quartz/salgdi.h @@ -413,9 +413,6 @@ public: virtual SystemGraphicsData GetGraphicsData() const SAL_OVERRIDE; - virtual void BeginPaint() SAL_OVERRIDE { }; - virtual void EndPaint() SAL_OVERRIDE { }; - private: // differences between VCL, Quartz and kHiThemeOrientation coordinate systems // make some graphics seem to be vertically-mirrored from a VCL perspective diff --git a/vcl/inc/salgdi.hxx b/vcl/inc/salgdi.hxx index 033404991e38..0c284bd328c1 100644 --- a/vcl/inc/salgdi.hxx +++ b/vcl/inc/salgdi.hxx @@ -438,8 +438,7 @@ public: sal_uInt8 nTransparency, const OutputDevice *pOutDev ); - virtual void BeginPaint() = 0; - virtual void EndPaint() = 0; + virtual OpenGLContext *BeginPaint() { return NULL; } virtual SystemGraphicsData GetGraphicsData() const = 0; diff --git a/vcl/inc/salgdiimpl.hxx b/vcl/inc/salgdiimpl.hxx index 15dd11ba705b..86575a4cbc4b 100644 --- a/vcl/inc/salgdiimpl.hxx +++ b/vcl/inc/salgdiimpl.hxx @@ -36,6 +36,7 @@ class SalGraphics; class SalBitmap; class SalFrame; class Gradient; +class OpenGLContext; class SalVirtualDevice; class VCL_PLUGIN_PUBLIC SalGraphicsImpl @@ -211,8 +212,7 @@ public: virtual bool drawGradient(const tools::PolyPolygon& rPolygon, const Gradient& rGradient) = 0; - virtual void beginPaint() = 0; - virtual void endPaint() = 0; + virtual OpenGLContext *beginPaint() { return NULL; } }; #endif diff --git a/vcl/inc/unx/salgdi.h b/vcl/inc/unx/salgdi.h index 3e80153640ba..e35946d66722 100644 --- a/vcl/inc/unx/salgdi.h +++ b/vcl/inc/unx/salgdi.h @@ -264,8 +264,7 @@ public: virtual css::uno::Any GetNativeSurfaceHandle(cairo::SurfaceSharedPtr& rSurface, const basegfx::B2ISize& rSize) const SAL_OVERRIDE; virtual SystemFontData GetSysFontData( int nFallbackLevel ) const SAL_OVERRIDE; - virtual void BeginPaint() SAL_OVERRIDE; - virtual void EndPaint() SAL_OVERRIDE; + virtual OpenGLContext *BeginPaint() SAL_OVERRIDE; bool TryRenderCachedNativeControl(ControlCacheKey& aControlCacheKey, int nX, int nY); diff --git a/vcl/inc/win/salgdi.h b/vcl/inc/win/salgdi.h index 33fc4b1e2dd0..01cb43235d46 100644 --- a/vcl/inc/win/salgdi.h +++ b/vcl/inc/win/salgdi.h @@ -436,8 +436,7 @@ public: virtual SystemGraphicsData GetGraphicsData() const SAL_OVERRIDE; - virtual void BeginPaint() SAL_OVERRIDE; - virtual void EndPaint() SAL_OVERRIDE; + virtual OpenGLContext *BeginPaint() SAL_OVERRIDE; /// Update settings based on the platform values static void updateSettingsNative( AllSettings& rSettings ); diff --git a/vcl/opengl/gdiimpl.cxx b/vcl/opengl/gdiimpl.cxx index c092f0317b1b..e92d86480c9e 100644 --- a/vcl/opengl/gdiimpl.cxx +++ b/vcl/opengl/gdiimpl.cxx @@ -1862,30 +1862,12 @@ bool OpenGLSalGraphicsImpl::drawGradient(const tools::PolyPolygon& rPolyPoly, return true; } -void OpenGLSalGraphicsImpl::beginPaint() +OpenGLContext *OpenGLSalGraphicsImpl::beginPaint() { - if( !AcquireContext() ) - return; - - mpContext->mnPainting++; -} - -void OpenGLSalGraphicsImpl::endPaint() -{ - if( !AcquireContext() ) - return; - - mpContext->mnPainting--; - assert( mpContext->mnPainting >= 0 ); - if( mpContext->mnPainting == 0 && !mbOffscreen ) - { - mpContext->makeCurrent(); - mpContext->AcquireDefaultFramebuffer(); - glFlush(); - mpContext->swapBuffers(); - - CHECK_GL_ERROR(); - } + if( mbOffscreen || !AcquireContext() ) + return NULL; + else + return mpContext.get(); } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/source/opengl/OpenGLHelper.cxx b/vcl/source/opengl/OpenGLHelper.cxx index 5d4b8f77a9c1..114251ce24f4 100644 --- a/vcl/source/opengl/OpenGLHelper.cxx +++ b/vcl/source/opengl/OpenGLHelper.cxx @@ -32,7 +32,7 @@ #include #include "svdata.hxx" - +#include "salgdi.hxx" #include "salinst.hxx" #include "opengl/zone.hxx" #include "opengl/watchdog.hxx" @@ -1070,4 +1070,48 @@ GLXFBConfig OpenGLHelper::GetPixmapFBConfig( Display* pDisplay, bool& bInverted #endif +OutputDevice::PaintScope::PaintScope(OutputDevice *pDev) + : pHandle( NULL ) +{ + if( pDev->mpGraphics || pDev->AcquireGraphics() ) + { + OpenGLContext *pContext = pDev->mpGraphics->BeginPaint(); + if( pContext ) + { + assert( pContext->mnPainting >= 0 ); + pContext->mnPainting++; + pContext->acquire(); + pHandle = static_cast( pContext ); + } + } +} + +/** + * Flush all the queued rendering commands to the screen for this context. + */ +void OutputDevice::PaintScope::flush() +{ + if( pHandle ) + { + OpenGLContext *pContext = static_cast( pHandle ); + pHandle = NULL; + pContext->mnPainting--; + assert( pContext->mnPainting >= 0 ); + if( pContext->mnPainting == 0 ) + { + pContext->makeCurrent(); + pContext->AcquireDefaultFramebuffer(); + glFlush(); + pContext->swapBuffers(); + CHECK_GL_ERROR(); + } + pContext->release(); + } +} + +OutputDevice::PaintScope::~PaintScope() +{ + flush(); +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/source/outdev/outdev.cxx b/vcl/source/outdev/outdev.cxx index 17fa19607647..4f13a3d86902 100644 --- a/vcl/source/outdev/outdev.cxx +++ b/vcl/source/outdev/outdev.cxx @@ -845,16 +845,4 @@ bool OutputDevice::DrawEPS( const Point& rPoint, const Size& rSize, return bDrawn; } -void OutputDevice::BeginPaint() -{ - if( mpGraphics || AcquireGraphics() ) - mpGraphics->BeginPaint(); -} - -void OutputDevice::EndPaint() -{ - if( mpGraphics || AcquireGraphics() ) - mpGraphics->EndPaint(); -} - /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/source/window/paint.cxx b/vcl/source/window/paint.cxx index 429711ee7ab9..af1422756a7c 100644 --- a/vcl/source/window/paint.cxx +++ b/vcl/source/window/paint.cxx @@ -276,7 +276,7 @@ void PaintHelper::DoPaint(const vcl::Region* pRegion) VCL_GL_INFO("vcl.opengl", "PaintHelper::DoPaint on " << typeid( *m_pWindow ).name() << " '" << m_pWindow->GetText() << "' begin"); - m_pWindow->BeginPaint(); + OutputDevice::PaintScope aScope( m_pWindow ); // double-buffering: setup the buffer if it does not exist if (!pFrameData->mbInBufferedPaint && m_pWindow->SupportsDoubleBuffering()) @@ -306,8 +306,6 @@ void PaintHelper::DoPaint(const vcl::Region* pRegion) m_pWindow->Paint(*m_pWindow, m_aPaintRect); } - m_pWindow->EndPaint(); - VCL_GL_INFO("vcl.opengl", "PaintHelper::DoPaint end on " << typeid( *m_pWindow ).name() << " '" << m_pWindow->GetText() << "'"); } @@ -629,10 +627,8 @@ void Window::ImplCallOverlapPaint() { // - RTL - notify ImplCallPaint to check for re-mirroring (CHECKRTL) // because we were called from the Sal layer - OutputDevice *pOutDev = GetOutDev(); - pOutDev->BeginPaint(); + OutputDevice::PaintScope aScope( GetOutDev() ); ImplCallPaint(NULL, mpWindowImpl->mnPaintFlags /*| IMPL_PAINT_CHECKRTL */); - pOutDev->EndPaint(); } } @@ -651,7 +647,7 @@ IMPL_LINK_NOARG_TYPED(Window, ImplHandlePaintHdl, Idle *, void) return; } - BeginPaint(); + OutputDevice::PaintScope aScope(this); // save paint events until resizing or initial sizing done if (!ImplDoTiledRendering() && mpWindowImpl->mbFrame && @@ -664,15 +660,13 @@ IMPL_LINK_NOARG_TYPED(Window, ImplHandlePaintHdl, Idle *, void) { ImplCallOverlapPaint(); } - - EndPaint(); } IMPL_LINK_NOARG_TYPED(Window, ImplHandleResizeTimerHdl, Idle *, void) { if( mpWindowImpl->mbReallyVisible ) { - BeginPaint(); + OutputDevice::PaintScope aScope(this); ImplCallResize(); if( ImplDoTiledRendering() ) @@ -684,8 +678,6 @@ IMPL_LINK_NOARG_TYPED(Window, ImplHandleResizeTimerHdl, Idle *, void) mpWindowImpl->mpFrameData->maPaintIdle.Stop(); mpWindowImpl->mpFrameData->maPaintIdle.GetIdleHdl().Call( NULL ); } - - EndPaint(); } } diff --git a/vcl/unx/generic/gdi/gdiimpl.hxx b/vcl/unx/generic/gdi/gdiimpl.hxx index 3059dc4a790a..24173c787ddf 100644 --- a/vcl/unx/generic/gdi/gdiimpl.hxx +++ b/vcl/unx/generic/gdi/gdiimpl.hxx @@ -270,9 +270,6 @@ public: virtual bool drawGradient(const tools::PolyPolygon& rPolygon, const Gradient& rGradient) SAL_OVERRIDE; - virtual void beginPaint() SAL_OVERRIDE { } - virtual void endPaint() SAL_OVERRIDE { } - public: // implementation of X11GraphicsImpl diff --git a/vcl/unx/generic/gdi/salgdi.cxx b/vcl/unx/generic/gdi/salgdi.cxx index 13c85b99190c..699dab03a5b5 100644 --- a/vcl/unx/generic/gdi/salgdi.cxx +++ b/vcl/unx/generic/gdi/salgdi.cxx @@ -556,16 +556,11 @@ bool X11SalGraphics::drawGradient(const tools::PolyPolygon& rPoly, const Gradien return mxImpl->drawGradient(rPoly, rGradient); } -void X11SalGraphics::BeginPaint() +OpenGLContext *X11SalGraphics::BeginPaint() { return mxImpl->beginPaint(); } -void X11SalGraphics::EndPaint() -{ - return mxImpl->endPaint(); -} - SalGeometryProvider *X11SalGraphics::GetGeometryProvider() const { if (m_pFrame) diff --git a/vcl/win/source/gdi/gdiimpl.hxx b/vcl/win/source/gdi/gdiimpl.hxx index c22d0bfce4a0..006d34dc40e6 100644 --- a/vcl/win/source/gdi/gdiimpl.hxx +++ b/vcl/win/source/gdi/gdiimpl.hxx @@ -220,9 +220,6 @@ public: virtual bool drawGradient(const tools::PolyPolygon& rPolygon, const Gradient& rGradient) SAL_OVERRIDE; - virtual void beginPaint() SAL_OVERRIDE { } - virtual void endPaint() SAL_OVERRIDE { } - virtual bool TryRenderCachedNativeControl(ControlCacheKey& rControlCacheKey, int nX, int nY); virtual bool RenderAndCacheNativeControl(OpenGLCompatibleDC& rWhite, OpenGLCompatibleDC& rBlack, diff --git a/vcl/win/source/gdi/salgdi.cxx b/vcl/win/source/gdi/salgdi.cxx index 58c0f7e0ca91..64bb1fc01328 100644 --- a/vcl/win/source/gdi/salgdi.cxx +++ b/vcl/win/source/gdi/salgdi.cxx @@ -1070,14 +1070,9 @@ SystemGraphicsData WinSalGraphics::GetGraphicsData() const return aRes; } -void WinSalGraphics::BeginPaint() +OpenGLContext *WinSalGraphics::BeginPaint() { return mpImpl->beginPaint(); } -void WinSalGraphics::EndPaint() -{ - return mpImpl->endPaint(); -} - /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ -- cgit