summaryrefslogtreecommitdiff
path: root/vcl
diff options
context:
space:
mode:
authorLuboš Luňák <l.lunak@collabora.com>2019-11-12 10:57:30 +0100
committerLuboš Luňák <l.lunak@collabora.com>2019-11-27 09:55:16 +0100
commitd662fcdc646c2c4b1bc734350ac4c28115b43a24 (patch)
tree15c2bd1432ada2e42501116c8d7c26011d42801e /vcl
parent805e75bd790cd9b3e49ace69beee96d21163f7a6 (diff)
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
Diffstat (limited to 'vcl')
-rw-r--r--vcl/inc/skia/gdiimpl.hxx2
-rw-r--r--vcl/inc/skia/x11/gdiimpl.hxx1
-rw-r--r--vcl/skia/gdiimpl.cxx13
-rw-r--r--vcl/skia/x11/gdiimpl.cxx22
4 files changed, 29 insertions, 9 deletions
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<sk_app::WindowContext> 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<SalVisual*>(&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();