summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Meeks <michael.meeks@collabora.com>2015-09-16 09:17:37 +0100
committerAndras Timar <andras.timar@collabora.com>2015-09-19 21:32:19 +0200
commit90a3ecb8aa0a2c07d7c3b0a2c64bca502e12bf0f (patch)
treeaab6556b88a950fa6a5223b262e45621bbbe05d6
parentfba72931db258ff3aa464932a2d75c55d340281f (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.hxx18
-rw-r--r--vcl/inc/generic/genpspgraphics.h3
-rw-r--r--vcl/inc/headless/svpgdi.hxx3
-rw-r--r--vcl/inc/openglgdiimpl.hxx3
-rw-r--r--vcl/inc/quartz/salgdi.h3
-rw-r--r--vcl/inc/salgdi.hxx3
-rw-r--r--vcl/inc/salgdiimpl.hxx4
-rw-r--r--vcl/inc/unx/salgdi.h3
-rw-r--r--vcl/inc/win/salgdi.h3
-rw-r--r--vcl/opengl/gdiimpl.cxx28
-rw-r--r--vcl/source/opengl/OpenGLHelper.cxx46
-rw-r--r--vcl/source/outdev/outdev.cxx12
-rw-r--r--vcl/source/window/paint.cxx16
-rw-r--r--vcl/unx/generic/gdi/gdiimpl.hxx3
-rw-r--r--vcl/unx/generic/gdi/salgdi.cxx7
-rw-r--r--vcl/win/source/gdi/gdiimpl.hxx3
-rw-r--r--vcl/win/source/gdi/salgdi.cxx7
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: */