vcl/inc/window.h | 1 + vcl/source/window/paint.cxx | 33 +++++++++++++++++++-------------- vcl/source/window/window.cxx | 3 +++ 3 files changed, 23 insertions(+), 14 deletions(-)
New commits: commit ea5e83abcfa1406c401b8a1ec91efda65373b74b Author: Miklos Vajna <vmik...@collabora.co.uk> Date: Thu Jul 30 15:51:34 2015 +0200 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 diff --git a/vcl/inc/window.h b/vcl/inc/window.h index 39b94c0..f4976f2 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 a94e3d0..29aaa2d 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 fc35c6f4..4cfffbb 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() ) { _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits