CairoSDPR: Force keeping CairoSurfaceHelper for huge PixelData

If we have a really 'big' pixel-based graphic the cost for creating
the mip-map entries is high. If that is the case, force keeping this
entry alive and not getting flushed by using a large number of
seconds. In that case the local MipMap is more important than the
memory kept allocated for fast repaints.

To detect 'big' graphics, compare to an assumed ScreenSize (may also
be fetched from real screen if needed). To react, create a buffer
residing time of one hour (increase if needed).

NOTE: This will increase MemoryFootPrint if isCairoCompatible
is false by holding the local cairo_surface_t in CairoSurfaceHelper
longer than before.

Change-Id: I1cf726f00d459bc0cb19bb1d202e64e010061426
Reviewed-on: https://gerrit.collaboraoffice.com/c/core/+/1134
Tested-by: Jenkins CPCI <releng@collaboraoffice.com>
Reviewed-by: Tomaž Vajngerl <tomaz.vajngerl@collabora.com>
(cherry picked from commit 2e1b0a51a745e615ed7e2f22666cc4aa4e005451)
(cherry picked from commit c2c58c177ae822906fe2c558546851643fe54247)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/205988
Tested-by: Xisco Fauli <xiscofauli@libreoffice.org>
Reviewed-by: Xisco Fauli <xiscofauli@libreoffice.org>
This commit is contained in:
Armin Le Grand (collabora)
2026-06-05 08:42:55 +02:00
committed by Xisco Fauli
parent a5d6499fd2
commit 66a0927a68
2 changed files with 42 additions and 1 deletions
@@ -693,9 +693,46 @@ public:
return mpCairoSurfaceHelper;
}
virtual sal_uInt32 calculateCombinedHoldCyclesInSeconds() const override;
virtual sal_Int64 estimateUsageInBytes() const override;
};
sal_uInt32 SystemDependentData_CairoSurface::calculateCombinedHoldCyclesInSeconds() const
{
if (0 == getCombinedHoldCyclesInSeconds() && nullptr != mpCairoSurfaceHelper)
{
// if we have a really 'big' pixel-based graphic the cost for creating
// the mip-map entries is high. If that is the case, force keeping this
// entry alive and not getting flushed by using a large number of
// seconds. In that case the local MipMap is more important than the
// memory kept allocated for fast repaints.
// NOTE: It would be nice to only do that if true == isCairoCompatible,
// but is not avaliable here. Thus, if not, the mem footprint held extra
// will include the locally created cairo_surface_t mpCairoSurface.
// To detect 'big' graphics, compare to an assumed ScreenSize (may also
// be fetched from real screen if needed). To react, create a buffer
// residing time of one hour (increase if needed).
cairo_surface_t* pSurface(mpCairoSurfaceHelper->getCairoSurface());
const tools::Long nStride(cairo_image_surface_get_stride(pSurface));
const tools::Long nHeight(cairo_image_surface_get_height(pSurface));
// use a common big screen and assume 1/2 size of a graphic as 'big'
const sal_Int64 nBigGraphicPixels((2560 * 1440) / 2);
if (nStride * nHeight > nBigGraphicPixels)
{
// return number of seconds for 1 hour to force this not to be
// flushed.
return 60 * 60;
}
}
// use parent implementation which makes seconds dependent of graphic size
return basegfx::SystemDependentData::calculateCombinedHoldCyclesInSeconds();
}
sal_Int64 SystemDependentData_CairoSurface::estimateUsageInBytes() const
{
sal_Int64 nRetval(0);
@@ -91,7 +91,11 @@ namespace basegfx
// getHoldCyclesInSeconds and estimateUsageInBytes, the
// result is created once on-demand and buffered in
// mnCalculatedCycles
sal_uInt32 calculateCombinedHoldCyclesInSeconds() const;
virtual sal_uInt32 calculateCombinedHoldCyclesInSeconds() const;
// Allow read access to the calculated cycles in seconds, this
// can be e.g. used to determine if this instance got added
sal_uInt32 getCombinedHoldCyclesInSeconds() const { return mnCalculatedCycles; }
// Size estimation of the entry in bytes - does not have to
// be used, but should be. Default returns zero what