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: