summaryrefslogtreecommitdiff
path: root/vcl
diff options
context:
space:
mode:
authorLuboš Luňák <l.lunak@collabora.com>2020-07-27 12:18:55 +0200
committerLuboš Luňák <l.lunak@collabora.com>2020-07-27 14:48:29 +0200
commita9f68d9d9ae8d7c8f79152055795044993b252ea (patch)
treec695dad31992644b8310a03060d9c2d98e32d0c5 /vcl
parent3395e0baa6350e6f9e093fe5af51d283f45fede7 (diff)
don't duplicate large memory usage in SkiaSalBitmap (tdf#134342)
Since SkiaSalBitmap is required to support bitmap formats that Skia itself doesn't support (1bpp, 4bpp, 24bpp,etc.), it needs to store its own copy of the bitmap data and convert to SkImage for use. With huge images this can lead to large duplicated memory usage. Since the code can actually drop the buffer and create it if needed (which it normally is not), just drop large buffers after converting to SkImage. Ideally SalBitmap should be able to say which bitmap formats it supports and VCL code should oblige, which would allow reusing the same data. Change-Id: I98af62a51dde5d738cc8afcdd2fcdc25ff89952f Reviewed-on: https://gerrit.libreoffice.org/c/core/+/99476 Tested-by: Jenkins Reviewed-by: Luboš Luňák <l.lunak@collabora.com>
Diffstat (limited to 'vcl')
-rw-r--r--vcl/README.vars1
-rw-r--r--vcl/skia/salbmp.cxx18
2 files changed, 18 insertions, 1 deletions
diff --git a/vcl/README.vars b/vcl/README.vars
index 73c982ef7d3f..68361ce78d77 100644
--- a/vcl/README.vars
+++ b/vcl/README.vars
@@ -46,6 +46,7 @@ SAL_ENABLESKIA=1 - enable Skia, unless denylisted (and if the VCL backend suppor
SAL_FORCESKIA=1 - force using Skia, even if denylisted
SAL_SKIA=raster|vulkan - select Skia's drawing method, by default Vulkan is used
SAL_DISABLE_SKIA_CACHE=1 - disable caching of complex images
+SAL_SKIA_KEEP_BITMAP_BUFFER=1 - SkiaSalBitmap will keep its bitmap buffer even after storing in SkImage
OpenGL,Skia
-----------
diff --git a/vcl/skia/salbmp.cxx b/vcl/skia/salbmp.cxx
index 6373eeea405a..dda47b46fa25 100644
--- a/vcl/skia/salbmp.cxx
+++ b/vcl/skia/salbmp.cxx
@@ -586,7 +586,23 @@ const sk_sp<SkImage>& SkiaSalBitmap::GetSkImage() const
SkiaZone zone;
sk_sp<SkImage> image = SkiaHelper::createSkImage(GetAsSkBitmap());
assert(image);
- const_cast<sk_sp<SkImage>&>(mImage) = image;
+ SkiaSalBitmap* thisPtr = const_cast<SkiaSalBitmap*>(this);
+ thisPtr->mImage = image;
+ // The data is now stored both in the SkImage and in our mBuffer, which with large
+ // images can waste quite a lot of memory. Ideally we should store the data in Skia's
+ // SkBitmap, but LO wants us to support data formats that Skia doesn't support.
+ // So just drop our buffer, it usually won't be needed anyway, and it'll be converted
+ // back by EnsureBitmapData() if yes. Do this only with raster, to avoid GPU->CPU
+ // transfer in GPU mode. Also don't do this with paletted bitmaps, where EnsureBitmapData()
+ // would be expensive.
+ // Ideally SalBitmap should be able to say which bitmap formats it supports
+ // and VCL code should oblige, which would allow reusing the same data.
+ static bool keepBitmapBuffer = getenv("SAL_SKIA_KEEP_BITMAP_BUFFER") != nullptr;
+ constexpr long maxBufferSize = 2000 * 2000 * 4;
+ if (!keepBitmapBuffer && SkiaHelper::renderMethodToUse() == SkiaHelper::RenderRaster
+ && mPixelsSize.Height() * mScanlineSize > maxBufferSize
+ && (mBitCount > 8 || (mBitCount == 8 && mPalette.IsGreyPalette8Bit())))
+ thisPtr->ResetToSkImage(mImage);
SAL_INFO("vcl.skia.trace", "getskimage(" << this << ")");
return mImage;
}