summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiklos Vajna <vmiklos@collabora.co.uk>2015-07-30 15:51:34 +0200
committerMiklos Vajna <vmiklos@collabora.co.uk>2015-07-30 16:32:19 +0200
commitea5e83abcfa1406c401b8a1ec91efda65373b74b (patch)
treec92f347319c7872eb508745ea26c8072306c4fdd
parent6dd913da63a74907499d492f8169c581803c5893 (diff)
tdf#92982 vcl: stop creating/disposing the paint buffer in PaintHelper
Instead: - create it early in Window::ImplInit(), except for the default window (that one is a chicken-and-egg problem, as creating a VirtualDevice invokes ImplGetDefaultWindow(), but creating the default window then would create a VirtualDevice) - only erase the painted area of the buffer, don't create it - use a separate bool in the frame state to track if we're in the middle of a (possibly recursive) buffered paint And with that, rename CreateBuffer() to StartBufferedPaint(), as it does not create the buffer anymore. Change-Id: Ib33e8afa36977aa809f0ea2158a369f288cba8c7
-rw-r--r--vcl/inc/window.h1
-rw-r--r--vcl/source/window/paint.cxx33
-rw-r--r--vcl/source/window/window.cxx3
3 files changed, 23 insertions, 14 deletions
diff --git a/vcl/inc/window.h b/vcl/inc/window.h
index 39b94c0f4d13..f4976f281060 100644
--- a/vcl/inc/window.h
+++ b/vcl/inc/window.h
@@ -180,6 +180,7 @@ struct ImplFrameData
bool mbInternalDragGestureRecognizer;
VclPtr<VirtualDevice> mpBuffer; ///< Buffer for the double-buffering
+ bool mbInBufferedPaint; ///< PaintHelper is in the process of painting into this buffer.
};
struct ImplAccessibleInfos
diff --git a/vcl/source/window/paint.cxx b/vcl/source/window/paint.cxx
index a94e3d08645c..29aaa2d9fd2d 100644
--- a/vcl/source/window/paint.cxx
+++ b/vcl/source/window/paint.cxx
@@ -85,8 +85,8 @@ public:
}
void DoPaint(const vcl::Region* pRegion);
- /// Create the buffer, and set it up to have the same settings as m_pWindow.
- void CreateBuffer();
+ /// Start buffered paint: set it up to have the same settings as m_pWindow.
+ void StartBufferedPaint();
/// Setup the buffer according to the settings of the current m_pWindow.
void SetupBuffer();
@@ -107,12 +107,17 @@ PaintHelper::PaintHelper(vcl::Window *pWindow, sal_uInt16 nPaintFlags)
{
}
-void PaintHelper::CreateBuffer()
+void PaintHelper::StartBufferedPaint()
{
ImplFrameData* pFrameData = m_pWindow->mpWindowImpl->mpFrameData;
- assert(!pFrameData->mpBuffer);
+ assert(!pFrameData->mbInBufferedPaint);
- pFrameData->mpBuffer = VclPtrInstance<VirtualDevice>();
+ // Instead of creating a new VirtualDevice, just erase the area we'll be
+ // painting over, as VirtualDevice::ImplInitVirDev() would do.
+ pFrameData->mpBuffer->SetBackground(Wallpaper(Color(COL_WHITE)));
+ pFrameData->mpBuffer->Erase(m_aPaintRect);
+
+ pFrameData->mbInBufferedPaint = true;
m_bCreatedBuffer = true;
SetupBuffer();
@@ -164,7 +169,7 @@ void PaintHelper::SetupBuffer()
void PaintHelper::PaintBuffer()
{
ImplFrameData* pFrameData = m_pWindow->mpWindowImpl->mpFrameData;
- assert(pFrameData->mpBuffer);
+ assert(pFrameData->mbInBufferedPaint);
assert(m_bCreatedBuffer);
pFrameData->mpBuffer->mnOutOffX = 0;
@@ -178,7 +183,7 @@ void PaintHelper::PaintBuffer()
if (!getenv("VCL_DOUBLEBUFFERING_AVOID_PAINT"))
{
// The map mode of m_pWindow and/or the buffer may have changed since
- // CreateBuffer(), set it back to what it was, otherwise unwanted
+ // StartBufferedPaint(), set it back to what it was, otherwise unwanted
// scaling or translating may happen.
m_pWindow->SetMapMode(m_aPaintRectMapMode);
pFrameData->mpBuffer->SetMapMode(m_aPaintRectMapMode);
@@ -204,7 +209,7 @@ void PaintHelper::DoPaint(const vcl::Region* pRegion)
WindowImpl* pWindowImpl = m_pWindow->ImplGetWindowImpl();
vcl::Region* pWinChildClipRegion = m_pWindow->ImplGetWinChildClipRegion();
ImplFrameData* pFrameData = m_pWindow->mpWindowImpl->mpFrameData;
- if (pWindowImpl->mnPaintFlags & IMPL_PAINT_PAINTALL || pFrameData->mpBuffer)
+ if (pWindowImpl->mnPaintFlags & IMPL_PAINT_PAINTALL || pFrameData->mbInBufferedPaint)
{
pWindowImpl->maInvalidateRegion = *pWinChildClipRegion;
}
@@ -231,16 +236,16 @@ void PaintHelper::DoPaint(const vcl::Region* pRegion)
m_pWindow->BeginPaint();
// double-buffering: setup the buffer if it does not exist
- if (!pFrameData->mpBuffer && m_pWindow->SupportsDoubleBuffering())
- CreateBuffer();
+ if (!pFrameData->mbInBufferedPaint && m_pWindow->SupportsDoubleBuffering())
+ StartBufferedPaint();
// double-buffering: if this window does not support double-buffering,
// but we are in the middle of double-buffered paint, we might be
// losing information
- if (pFrameData->mpBuffer && !m_pWindow->SupportsDoubleBuffering())
+ if (pFrameData->mbInBufferedPaint && !m_pWindow->SupportsDoubleBuffering())
SAL_WARN("vcl.doublebuffering", "non-double buffered window in the double-buffered hierarchy, painting directly: " << typeid(*m_pWindow.get()).name());
- if (pFrameData->mpBuffer && m_pWindow->SupportsDoubleBuffering())
+ if (pFrameData->mbInBufferedPaint && m_pWindow->SupportsDoubleBuffering())
{
// double-buffering
SetupBuffer();
@@ -518,10 +523,10 @@ PaintHelper::~PaintHelper()
// double-buffering: paint in case we created the buffer, the children are
// already painted inside
- if (m_bCreatedBuffer && pFrameData->mpBuffer)
+ if (m_bCreatedBuffer && pFrameData->mbInBufferedPaint)
{
PaintBuffer();
- pFrameData->mpBuffer.disposeAndClear();
+ pFrameData->mbInBufferedPaint = false;
}
// #98943# draw toolbox selection
diff --git a/vcl/source/window/window.cxx b/vcl/source/window/window.cxx
index fc35c6f48457..4cfffbb49128 100644
--- a/vcl/source/window/window.cxx
+++ b/vcl/source/window/window.cxx
@@ -1074,6 +1074,9 @@ void Window::ImplInit( vcl::Window* pParent, WinBits nStyle, SystemParentData* p
mpWindowImpl->mpFrameData->maResizeIdle.SetIdleHdl( LINK( this, Window, ImplHandleResizeTimerHdl ) );
mpWindowImpl->mpFrameData->maResizeIdle.SetDebugName( "vcl::Window maResizeIdle" );
mpWindowImpl->mpFrameData->mbInternalDragGestureRecognizer = false;
+ if (!(nStyle & WB_DEFAULTWIN) && SupportsDoubleBuffering())
+ mpWindowImpl->mpFrameData->mpBuffer = VclPtrInstance<VirtualDevice>();
+ mpWindowImpl->mpFrameData->mbInBufferedPaint = false;
if ( pRealParent && IsTopWindow() )
{