From 996887f40fb89c1e95bf7e4ed0af1406fe2b6428 Mon Sep 17 00:00:00 2001 From: Mihai Moldovan Date: Sat, 27 Apr 2019 05:14:42 +0200 Subject: When using XRENDER, create Xlib-based offscreen image surfaces. Mozilla tried to enable XRENDER support with backends other than Cairo in 286348:e13aaaaf1962 / https://hg.mozilla.org/mozilla-central/rev/e13aaaaf1962 - at least until they decided to completely remove XRENDER support. The change looked innocent enough, but actually turned out to do exactly the opposite: it forcefully enabled image offscreen surfaces with GTK2 when it was previously disabled (since gfxPrefs::UseImageOffscreenSurfaces() will always return true) and, by extension, disabled the XRENDER-based functionality by creating a non-Xlib surface. Interestingly, a previously enabled double buffering check was also disabled by this, but since the comment for this was diverging with the code, that behavior just sounds like yet another bug. Instead of disabling image offscreen surfaces (at least when using the GTK2 backend), let's force the creation of Xlib-based image surfaces when XRENDER support is enabled. This will let UXP use the more common/modern code paths, but also make scrolling much faster again. Too fast scrolling may induce tearing (if not smoothed), but on the other hand performs much better in remote computing contexts. As an added benefit, GTK3-based builds should roughly behave the same way. Further tests with the GTK3-backend enabled will be required in the future. --- gfx/thebes/gfxPlatformGtk.cpp | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/gfx/thebes/gfxPlatformGtk.cpp b/gfx/thebes/gfxPlatformGtk.cpp index be75332d65..6b55935248 100644 --- a/gfx/thebes/gfxPlatformGtk.cpp +++ b/gfx/thebes/gfxPlatformGtk.cpp @@ -156,7 +156,7 @@ gfxPlatformGtk::CreateOffscreenSurface(const IntSize& aSize, if (gdkScreen) { // When forcing PaintedLayers to use image surfaces for content, // force creation of gfxImageSurface surfaces. - if (gfxVars::UseXRender() && !UseImageOffscreenSurfaces()) { + if (gfxVars::UseXRender()) { Screen *screen = gdk_x11_screen_get_xscreen(gdkScreen); XRenderPictFormat* xrenderFormat = gfxXlibSurface::FindRenderFormat(DisplayOfScreen(screen), @@ -166,13 +166,6 @@ gfxPlatformGtk::CreateOffscreenSurface(const IntSize& aSize, newSurface = gfxXlibSurface::Create(screen, xrenderFormat, aSize); } - } else { - // We're not going to use XRender, so we don't need to - // search for a render format - newSurface = new gfxImageSurface(aSize, aFormat); - // The gfxImageSurface ctor zeroes this for us, no need to - // waste time clearing again - needsClear = false; } } #endif @@ -182,6 +175,10 @@ gfxPlatformGtk::CreateOffscreenSurface(const IntSize& aSize, // e.g., no display, no RENDER, bad size, etc. // Fall back to image surface for the data. newSurface = new gfxImageSurface(aSize, aFormat); + + // The gfxImageSurface ctor zeroes this for us, no need to + // waste time clearing again + needsClear = false; } if (newSurface->CairoStatus()) { -- cgit v1.2.3