diff options
author | Michael Meeks <michael.meeks@collabora.com> | 2015-09-16 09:17:37 +0100 |
---|---|---|
committer | Andras Timar <andras.timar@collabora.com> | 2015-09-19 21:32:19 +0200 |
commit | 90a3ecb8aa0a2c07d7c3b0a2c64bca502e12bf0f (patch) | |
tree | aab6556b88a950fa6a5223b262e45621bbbe05d6 | |
parent | fba72931db258ff3aa464932a2d75c55d340281f (diff) |
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.
Conflicts:
vcl/inc/generic/genpspgraphics.h
vcl/win/source/gdi/salgdi.cxx
Change-Id: I1062be0b02a91fc9009deaa3ec29c5dbb227df20
Reviewed-on: https://gerrit.libreoffice.org/18611
Reviewed-by: Tor Lillqvist <tml@collabora.com>
Tested-by: Tor Lillqvist <tml@collabora.com>
-rw-r--r-- | include/vcl/outdev.hxx | 18 | ||||
-rw-r--r-- | vcl/inc/generic/genpspgraphics.h | 3 | ||||
-rw-r--r-- | vcl/inc/headless/svpgdi.hxx | 3 | ||||
-rw-r--r-- | vcl/inc/openglgdiimpl.hxx | 3 | ||||
-rw-r--r-- | vcl/inc/quartz/salgdi.h | 3 | ||||
-rw-r--r-- | vcl/inc/salgdi.hxx | 3 | ||||
-rw-r--r-- | vcl/inc/salgdiimpl.hxx | 4 | ||||
-rw-r--r-- | vcl/inc/unx/salgdi.h | 3 | ||||
-rw-r--r-- | vcl/inc/win/salgdi.h | 3 | ||||
-rw-r--r-- | vcl/opengl/gdiimpl.cxx | 28 | ||||
-rw-r--r-- | vcl/source/opengl/OpenGLHelper.cxx | 46 | ||||
-rw-r--r-- | vcl/source/outdev/outdev.cxx | 12 | ||||
-rw-r--r-- | vcl/source/window/paint.cxx | 16 | ||||
-rw-r--r-- | vcl/unx/generic/gdi/gdiimpl.hxx | 3 | ||||
-rw-r--r-- | vcl/unx/generic/gdi/salgdi.cxx | 7 | ||||
-rw-r--r-- | vcl/win/source/gdi/gdiimpl.hxx | 3 | ||||
-rw-r--r-- | 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 f0057b3b54c0..dbd57e6ad339 100644 --- a/include/vcl/outdev.hxx +++ b/include/vcl/outdev.hxx @@ -608,9 +608,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 8b78faa8d0b1..2049e26aa651 100644 --- a/vcl/inc/generic/genpspgraphics.h +++ b/vcl/inc/generic/genpspgraphics.h @@ -208,9 +208,6 @@ 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 { }; }; #endif // INCLUDED_VCL_INC_GENERIC_GENPSPGRAPHICS_H diff --git a/vcl/inc/headless/svpgdi.hxx b/vcl/inc/headless/svpgdi.hxx index 9b8a25a6c414..f4503e8f9824 100644 --- a/vcl/inc/headless/svpgdi.hxx +++ b/vcl/inc/headless/svpgdi.hxx @@ -215,9 +215,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 e16dd611dd77..55f2e7039471 100644 --- a/vcl/inc/openglgdiimpl.hxx +++ b/vcl/inc/openglgdiimpl.hxx @@ -326,8 +326,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 12c314482bba..518390ccf994 100644 --- a/vcl/inc/quartz/salgdi.h +++ b/vcl/inc/quartz/salgdi.h @@ -421,9 +421,6 @@ 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 { }; - 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 f00aae421d13..afd3b429fcdc 100644 --- a/vcl/inc/salgdi.hxx +++ b/vcl/inc/salgdi.hxx @@ -433,8 +433,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 b29405d73f5f..97daa8081040 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 @@ -216,8 +217,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 a44ef1edfa72..84f1e8ff14eb 100644 --- a/vcl/inc/unx/salgdi.h +++ b/vcl/inc/unx/salgdi.h @@ -269,8 +269,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 f499a31d4e8e..18b7ecfb3c2e 100644 --- a/vcl/inc/win/salgdi.h +++ b/vcl/inc/win/salgdi.h @@ -445,8 +445,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; /// 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 9ea8a7c87fc8..d452f5d18cd8 100644 --- a/vcl/opengl/gdiimpl.cxx +++ b/vcl/opengl/gdiimpl.cxx @@ -1873,30 +1873,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 1b48fec9216a..58408538dcf7 100644 --- a/vcl/source/opengl/OpenGLHelper.cxx +++ b/vcl/source/opengl/OpenGLHelper.cxx @@ -27,7 +27,7 @@ #include <vector> #include "svdata.hxx" - +#include "salgdi.hxx" #include "salinst.hxx" #include "opengl/zone.hxx" #include "opengl/watchdog.hxx" @@ -816,4 +816,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<void *>( pContext ); + } + } +} + +/** + * Flush all the queued rendering commands to the screen for this context. + */ +void OutputDevice::PaintScope::flush() +{ + if( pHandle ) + { + OpenGLContext *pContext = static_cast<OpenGLContext *>( 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 0d9842de39dc..1c295599af19 100644 --- a/vcl/source/outdev/outdev.cxx +++ b/vcl/source/outdev/outdev.cxx @@ -870,16 +870,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 ae846ae59a54..79aa1ed37438 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 2cf40f9ce701..6e8a2788daf7 100644 --- a/vcl/unx/generic/gdi/gdiimpl.hxx +++ b/vcl/unx/generic/gdi/gdiimpl.hxx @@ -275,9 +275,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 e9262e13e311..e2a25b5de4b6 100644 --- a/vcl/unx/generic/gdi/salgdi.cxx +++ b/vcl/unx/generic/gdi/salgdi.cxx @@ -548,16 +548,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 82a8333eb49f..8e7d7f8b427c 100644 --- a/vcl/win/source/gdi/gdiimpl.hxx +++ b/vcl/win/source/gdi/gdiimpl.hxx @@ -225,9 +225,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 99cebeee5fbf..3ed0c073c05c 100644 --- a/vcl/win/source/gdi/salgdi.cxx +++ b/vcl/win/source/gdi/salgdi.cxx @@ -1210,14 +1210,9 @@ css::uno::Any WinSalGraphics::GetNativeSurfaceHandle(cairo::SurfaceSharedPtr& rS return css::uno::Any( args ); } -void WinSalGraphics::BeginPaint() +OpenGLContext *WinSalGraphics::BeginPaint() { return mpImpl->beginPaint(); } -void WinSalGraphics::EndPaint() -{ - return mpImpl->endPaint(); -} - /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |