From d662fcdc646c2c4b1bc734350ac4c28115b43a24 Mon Sep 17 00:00:00 2001 From: Luboš Luňák Date: Tue, 12 Nov 2019 10:57:30 +0100 Subject: avoid repeated SkSurface recreating because of X11 being asynchronous Sometimes VCL and X11 (and thus Skia) will have a different idea about what the size of a window is. Check for the mismatch and avoid recreating if it wouldn't do anything. Change-Id: Icf3ebba9589cc6f12612e5f280840346cb0edaeb --- vcl/inc/skia/gdiimpl.hxx | 2 ++ vcl/inc/skia/x11/gdiimpl.hxx | 1 + vcl/skia/gdiimpl.cxx | 13 ++++++++----- vcl/skia/x11/gdiimpl.cxx | 22 ++++++++++++++++++---- 4 files changed, 29 insertions(+), 9 deletions(-) (limited to 'vcl') diff --git a/vcl/inc/skia/gdiimpl.hxx b/vcl/inc/skia/gdiimpl.hxx index 8225e76d27ff..04f96cb7bd11 100644 --- a/vcl/inc/skia/gdiimpl.hxx +++ b/vcl/inc/skia/gdiimpl.hxx @@ -208,6 +208,8 @@ protected: void checkSurface(); void recreateSurface(); void destroySurface(); + // Reimplemented for X11. + virtual bool avoidRecreateByResize() const { return false; } void privateDrawAlphaRect(long nX, long nY, long nWidth, long nHeight, double nTransparency, bool blockAA = false); diff --git a/vcl/inc/skia/x11/gdiimpl.hxx b/vcl/inc/skia/x11/gdiimpl.hxx index 1c40aa6b2c28..1dc5064e6667 100644 --- a/vcl/inc/skia/x11/gdiimpl.hxx +++ b/vcl/inc/skia/x11/gdiimpl.hxx @@ -37,6 +37,7 @@ public: protected: virtual void createSurface() override; virtual void performFlush() override; + virtual bool avoidRecreateByResize() const override; private: std::unique_ptr mWindowContext; diff --git a/vcl/skia/gdiimpl.cxx b/vcl/skia/gdiimpl.cxx index 6215317b18ee..776e44216c45 100644 --- a/vcl/skia/gdiimpl.cxx +++ b/vcl/skia/gdiimpl.cxx @@ -267,11 +267,14 @@ void SkiaSalGraphicsImpl::checkSurface() } else if (GetWidth() != mSurface->width() || GetHeight() != mSurface->height()) { - Size oldSize(mSurface->width(), mSurface->height()); - recreateSurface(); - SAL_INFO("vcl.skia", "recreate(" << this << "): old " << oldSize << " new " - << Size(mSurface->width(), mSurface->height()) - << " requested " << Size(GetWidth(), GetHeight())); + if (!avoidRecreateByResize()) + { + Size oldSize(mSurface->width(), mSurface->height()); + recreateSurface(); + SAL_INFO("vcl.skia", "recreate(" << this << "): old " << oldSize << " new " + << Size(mSurface->width(), mSurface->height()) + << " requested " << Size(GetWidth(), GetHeight())); + } } } diff --git a/vcl/skia/x11/gdiimpl.cxx b/vcl/skia/x11/gdiimpl.cxx index 72fc311f7aaa..e349074e70e1 100644 --- a/vcl/skia/x11/gdiimpl.cxx +++ b/vcl/skia/x11/gdiimpl.cxx @@ -73,10 +73,6 @@ void X11SkiaSalGraphicsImpl::createSurface() assert(winInfo.fDisplay && winInfo.fWindow != None); winInfo.fFBConfig = nullptr; // not used winInfo.fVisualInfo = const_cast(&mX11Parent.GetVisual()); - // TODO Vulkan does not use these dimensions, instead it uses dimensions of the actual - // drawable, which may lead to repeated createSurface() calls from checkSurface() - // if the window is being resized and VCL already knows the new size but Vulkan doesn't. - // Avoid this somehow. winInfo.fWidth = GetWidth(); winInfo.fHeight = GetHeight(); switch (renderMethodToUse()) @@ -100,6 +96,24 @@ void X11SkiaSalGraphicsImpl::createSurface() #endif } +bool X11SkiaSalGraphicsImpl::avoidRecreateByResize() const +{ + if (!mSurface) + return false; + // Skia's WindowContext uses actual dimensions of the X window, which due to X11 being + // asynchronous may be temporarily different from what VCL thinks are the dimensions. + // That can lead to us repeatedly calling recreateSurface() because of "incorrect" + // size, and we otherwise need to check for size changes, because VCL does not inform us. + // Avoid the problem here by checking the size of the X window and bail out if Skia + // would just return the same size as it is now. + Window r; + int x, y; + unsigned int w, h, border, depth; + XGetGeometry(mX11Parent.GetXDisplay(), mX11Parent.GetDrawable(), &r, &x, &y, &w, &h, &border, + &depth); + return mSurface->width() == int(w) && mSurface->height() == int(h); +} + void X11SkiaSalGraphicsImpl::DeInit() { SkiaSalGraphicsImpl::DeInit(); -- cgit v1.2.3