drawinglayer/source/processor2d/cairopixelprocessor2d.cxx | 16 +++++++++++ include/vcl/bitmap.hxx | 5 +++ vcl/source/bitmap/bitmap.cxx | 20 ++++++++++++++ 3 files changed, 41 insertions(+)
New commits: commit d2accdad4b6d7c301c24b24c7b964183340746d4 Author: Armin Le Grand (allotropia) <[email protected]> AuthorDate: Thu Apr 17 00:37:27 2025 +0200 Commit: Noel Grandin <[email protected]> CommitDate: Sat Oct 25 09:30:35 2025 +0200 reduce memory usage when rendering cairo-backed Bitmaps Change-Id: I1353e8fb044203b377c2a1f17767f690a9796367 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/184301 Tested-by: Jenkins Reviewed-by: Noel Grandin <[email protected]> diff --git a/drawinglayer/source/processor2d/cairopixelprocessor2d.cxx b/drawinglayer/source/processor2d/cairopixelprocessor2d.cxx index fce75417ac0c..9fb4991ebb36 100644 --- a/drawinglayer/source/processor2d/cairopixelprocessor2d.cxx +++ b/drawinglayer/source/processor2d/cairopixelprocessor2d.cxx @@ -62,6 +62,7 @@ #include <unordered_map> #include <dlfcn.h> #include "vclhelperbufferdevice.hxx" +#include <iostream> using namespace com::sun::star; @@ -552,6 +553,13 @@ public: #endif } + /* constructor for when we are using the cairo data directly from the underlying SvpSalBitmap */ + CairoSurfaceHelper(cairo_surface_t* pCairoSurface) + : mpCairoSurface(pCairoSurface) + , maDownscaled() + { + } + ~CairoSurfaceHelper() { // cleanup surface @@ -704,6 +712,14 @@ sal_Int64 SystemDependentData_CairoSurface::estimateUsageInBytes() const std::shared_ptr<CairoSurfaceHelper> getOrCreateCairoSurfaceHelper(const Bitmap& rBitmap) { + // When using a cairo-backed Bitmap (i.e. SvpSalBitmap), we can avoid a lot of copying, + // which is beneficial for documents with lots of large images. + cairo_surface_t* pSurface(static_cast<cairo_surface_t*>(rBitmap.tryToGetCairoSurface())); + if (nullptr != pSurface) + { + return std::make_shared<CairoSurfaceHelper>(pSurface); + } + const basegfx::SystemDependentDataHolder* pHolder(rBitmap.accessSystemDependentDataHolder()); std::shared_ptr<SystemDependentData_CairoSurface> pSystemDependentData_CairoSurface; diff --git a/include/vcl/bitmap.hxx b/include/vcl/bitmap.hxx index b8704fe60095..e2f2f5853ffa 100644 --- a/include/vcl/bitmap.hxx +++ b/include/vcl/bitmap.hxx @@ -30,6 +30,7 @@ #include <vcl/mapmod.hxx> #include <vcl/region.hxx> #include <vcl/bitmap/BitmapTypes.hxx> +#include <config_vclplug.h> #include <o3tl/typed_flags_set.hxx> #include <com/sun/star/uno/Sequence.hxx> @@ -718,6 +719,10 @@ public: /// Dumps the pixels as PNG in bitmap.png. void DumpAsPng(const char* pFileName = nullptr) const; +#if USE_HEADLESS_CODE + void* tryToGetCairoSurface() const; +#endif + private: SAL_DLLPRIVATE bool ImplConvertUp(vcl::PixelFormat ePixelFormat, Color const* pExtColor = nullptr); SAL_DLLPRIVATE bool ImplConvertDown8BPP(Color const* pExtColor = nullptr); diff --git a/vcl/source/bitmap/bitmap.cxx b/vcl/source/bitmap/bitmap.cxx index f0404fa80a18..a157215f8597 100644 --- a/vcl/source/bitmap/bitmap.cxx +++ b/vcl/source/bitmap/bitmap.cxx @@ -64,6 +64,11 @@ #include <vcl/graphicfilter.hxx> #endif +#if USE_HEADLESS_CODE +#include <headless/svpbmp.hxx> +#include <headless/CairoCommon.hxx> +#endif + Bitmap::Bitmap() { } @@ -380,6 +385,21 @@ Bitmap& Bitmap::operator=( const Bitmap& rBitmap ) return *this; } +#if USE_HEADLESS_CODE +void* Bitmap::tryToGetCairoSurface() const +{ + SvpSalBitmap* pSvpSalBitmap(dynamic_cast<SvpSalBitmap*>(ImplGetSalBitmap().get())); + if (nullptr == pSvpSalBitmap) + return nullptr; + + const BitmapBuffer* pBitmapBuffer(pSvpSalBitmap->GetBuffer()); + if (nullptr == pBitmapBuffer) + return nullptr; + + return CairoCommon::createCairoSurface(pBitmapBuffer); +} +#endif + Bitmap& Bitmap::operator=( Bitmap&& rBitmap ) noexcept { maPrefSize = std::move(rBitmap.maPrefSize);
