diff options
author | Miklos Vajna <vmiklos@collabora.co.uk> | 2015-07-30 15:51:34 +0200 |
---|---|---|
committer | Miklos Vajna <vmiklos@collabora.co.uk> | 2015-07-30 16:32:19 +0200 |
commit | ea5e83abcfa1406c401b8a1ec91efda65373b74b (patch) | |
tree | c92f347319c7872eb508745ea26c8072306c4fdd | |
parent | 6dd913da63a74907499d492f8169c581803c5893 (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.h | 1 | ||||
-rw-r--r-- | vcl/source/window/paint.cxx | 33 | ||||
-rw-r--r-- | vcl/source/window/window.cxx | 3 |
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() ) { |