drawinglayer/source/processor2d/vclhelperbufferdevice.cxx |    9 ++++++-
 vcl/skia/SkiaHelper.cxx                                   |   17 ++++++++++++--
 2 files changed, 23 insertions(+), 3 deletions(-)

New commits:
commit 8ca549ebc01a7aa0b288c521a9e60e76f4d8e97d
Author:     Luboš Luňák <l.lu...@collabora.com>
AuthorDate: Wed Jan 12 10:16:39 2022 +0100
Commit:     Luboš Luňák <l.lu...@collabora.com>
CommitDate: Mon Jan 24 14:40:22 2022 +0100

    avoid Skia GPU surfaces for small virtual devices (bsc#1183308)
    
    This is similar to the previous Cairo commit. Fetching pixels
    from the GPU is not as slow as fetching them from the XServer,
    but this still can make a visible difference. And small surfaces
    should not need fast GPU rendering that much, so hopefully this
    improves more cases than it regresses.
    
    Change-Id: Ida031b38cd1ce14ded464747c20a38c6d094c5a0
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/128310
    Tested-by: Jenkins
    Reviewed-by: Luboš Luňák <l.lu...@collabora.com>

diff --git a/drawinglayer/source/processor2d/vclhelperbufferdevice.cxx 
b/drawinglayer/source/processor2d/vclhelperbufferdevice.cxx
index 7f20d094b446..24e0c6a30bcb 100644
--- a/drawinglayer/source/processor2d/vclhelperbufferdevice.cxx
+++ b/drawinglayer/source/processor2d/vclhelperbufferdevice.cxx
@@ -33,6 +33,7 @@
 #include <cppuhelper/basemutex.hxx>
 #include <vcl/lazydelete.hxx>
 #include <vcl/dibtools.hxx>
+#include <vcl/skia/SkiaHelper.hxx>
 
 // buffered VDev usage
 
@@ -105,10 +106,17 @@ bool VDevBuffer::isSizeSuitable(const 
VclPtr<VirtualDevice>& device, const Size&
     if (device->GetOutputWidthPixel() >= rSizePixel.getWidth()
         && device->GetOutputHeightPixel() >= rSizePixel.getHeight())
     {
+        bool requireSmall = false;
 #if defined(UNX)
         // HACK: See the small size handling in 
SvpSalVirtualDevice::CreateSurface().
         // Make sure to not reuse a larger device when a small one should be 
preferred.
         if (device->GetRenderBackendName() == "svp")
+            requireSmall = true;
+#endif
+        // The same for Skia, see renderMethodToUseForSize().
+        if (SkiaHelper::isVCLSkiaEnabled())
+            requireSmall = true;
+        if (requireSmall)
         {
             if (rSizePixel.getWidth() <= 32 && rSizePixel.getHeight() <= 32
                 && (device->GetOutputWidthPixel() > 32 || 
device->GetOutputHeightPixel() > 32))
@@ -116,7 +124,6 @@ bool VDevBuffer::isSizeSuitable(const 
VclPtr<VirtualDevice>& device, const Size&
                 return false;
             }
         }
-#endif
         return true;
     }
     return false;
diff --git a/vcl/skia/SkiaHelper.cxx b/vcl/skia/SkiaHelper.cxx
index 8dc3827b097a..2642c4f4c8bc 100644
--- a/vcl/skia/SkiaHelper.cxx
+++ b/vcl/skia/SkiaHelper.cxx
@@ -467,12 +467,25 @@ static std::unique_ptr<sk_app::WindowContext> 
getTemporaryWindowContext()
 }
 #endif
 
+static RenderMethod renderMethodToUseForSize(const SkISize& size)
+{
+    // Do not use GPU for small surfaces. The problem is that due to the 
separate alpha hack
+    // we quite often may call GetBitmap() on VirtualDevice, which is 
relatively slow
+    // when the pixels need to be fetched from the GPU. And there are 
documents that use
+    // many tiny surfaces (bsc#1183308 for example), where this slowness adds 
up too much.
+    // This should be re-evaluated once the separate alpha hack is removed 
(SKIA_USE_BITMAP32)
+    // and we no longer (hopefully) fetch pixels that often.
+    if (size.width() <= 32 && size.height() <= 32)
+        return RenderRaster;
+    return renderMethodToUse();
+}
+
 sk_sp<SkSurface> createSkSurface(int width, int height, SkColorType type, 
SkAlphaType alpha)
 {
     SkiaZone zone;
     assert(type == kN32_SkColorType || type == kAlpha_8_SkColorType);
     sk_sp<SkSurface> surface;
-    switch (renderMethodToUse())
+    switch (renderMethodToUseForSize({ width, height }))
     {
         case RenderVulkan:
         case RenderMetal:
@@ -518,7 +531,7 @@ sk_sp<SkImage> createSkImage(const SkBitmap& bitmap)
 {
     SkiaZone zone;
     assert(bitmap.colorType() == kN32_SkColorType || bitmap.colorType() == 
kAlpha_8_SkColorType);
-    switch (renderMethodToUse())
+    switch (renderMethodToUseForSize(bitmap.dimensions()))
     {
         case RenderVulkan:
         case RenderMetal:

Reply via email to