tdf#129845 vcl: avoid expensive system caching of trivial lines & polygons
Interestingly the cache map lookup is rather expensive; why:
polyline output for some trivial impress edits:
count # of polylines
2 2134
3 141
4 41
9 4
polypolygon output for some trivial impress edits:
count # of polypolygons geometry.
3 54 all single polygon
4 583 ~all single
9 52 ~ all paired with a 4 node polygon
13 2 both single
32 22 all single
Change-Id: I15c0053a84399eaf153b2119b2c28d1f168f16b1
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/86314
Tested-by: Jenkins
Reviewed-by: Michael Meeks <michael.meeks@collabora.com>
diff --git a/vcl/headless/svpgdi.cxx b/vcl/headless/svpgdi.cxx
index 1bd5510..c792bb9 100644
--- a/vcl/headless/svpgdi.cxx
+++ b/vcl/headless/svpgdi.cxx
@@ -119,6 +119,18 @@
aDamageRect.intersect(getClipBox(cr));
return aDamageRect;
}
// The caching logic is surprsingly expensive - so avoid it sometimes.
inline bool isTrivial(const basegfx::B2DPolyPolygon& rPolyPolygon)
{
return rPolyPolygon.count() == 1 && rPolyPolygon.begin()->count() <= 4;
}
// The caching logic is surprsingly expensive - so avoid it sometimes.
inline bool isTrivial(const basegfx::B2DPolygon& rPolyLine)
{
return rPolyLine.count() <= 4;
}
}
bool SvpSalGraphics::blendBitmap( const SalTwoRect&, const SalBitmap& /*rBitmap*/ )
@@ -1279,29 +1291,37 @@
cairo_set_line_width(cr, aLineWidths.getX());
cairo_set_miter_limit(cr, fMiterLimit);
// try to access buffered data
std::shared_ptr<SystemDependentData_CairoPath> pSystemDependentData_CairoPath(
rPolyLine.getSystemDependentData<SystemDependentData_CairoPath>());
bool bDone = false;
bool bIsTrivial = isTrivial(rPolyLine);
if(pSystemDependentData_CairoPath)
if (!bIsTrivial)
{
// check data validity
if(nullptr == pSystemDependentData_CairoPath->getCairoPath()
|| pSystemDependentData_CairoPath->getNoJoin() != bNoJoin
|| pSystemDependentData_CairoPath->getAntiAliasB2DDraw() != bAntiAliasB2DDraw
|| bPixelSnapHairline /*tdf#124700*/ )
// try to access buffered data
std::shared_ptr<SystemDependentData_CairoPath> pSystemDependentData_CairoPath(
rPolyLine.getSystemDependentData<SystemDependentData_CairoPath>());
if(pSystemDependentData_CairoPath)
{
// data invalid, forget
pSystemDependentData_CairoPath.reset();
// check data validity
if(nullptr == pSystemDependentData_CairoPath->getCairoPath()
|| pSystemDependentData_CairoPath->getNoJoin() != bNoJoin
|| pSystemDependentData_CairoPath->getAntiAliasB2DDraw() != bAntiAliasB2DDraw
|| bPixelSnapHairline /*tdf#124700*/ )
{
// data invalid, forget
pSystemDependentData_CairoPath.reset();
}
}
if(pSystemDependentData_CairoPath)
{
// re-use data
cairo_append_path(cr, pSystemDependentData_CairoPath->getCairoPath());
bDone = true;
}
}
if(pSystemDependentData_CairoPath)
{
// re-use data
cairo_append_path(cr, pSystemDependentData_CairoPath->getCairoPath());
}
else
if (!bDone)
{
// create data
if (!bNoJoin)
@@ -1344,9 +1364,9 @@
}
// copy and add to buffering mechanism
if (!bPixelSnapHairline /*tdf#124700*/)
if (!bIsTrivial && !bPixelSnapHairline /*tdf#124700*/)
{
pSystemDependentData_CairoPath = rPolyLine.addOrReplaceSystemDependentData<SystemDependentData_CairoPath>(
rPolyLine.addOrReplaceSystemDependentData<SystemDependentData_CairoPath>(
ImplGetSystemDependentDataManager(),
cairo_copy_path(cr),
bNoJoin,
@@ -1397,16 +1417,24 @@
{
void add_polygon_path(cairo_t* cr, const basegfx::B2DPolyPolygon& rPolyPolygon, const basegfx::B2DHomMatrix& rObjectToDevice, bool bPixelSnap)
{
// try to access buffered data
std::shared_ptr<SystemDependentData_CairoPath> pSystemDependentData_CairoPath(
rPolyPolygon.getSystemDependentData<SystemDependentData_CairoPath>());
bool bDone = false;
bool bIsTrivial = isTrivial(rPolyPolygon);
if(pSystemDependentData_CairoPath)
if (!bIsTrivial)
{
// re-use data
cairo_append_path(cr, pSystemDependentData_CairoPath->getCairoPath());
// try to access buffered data
std::shared_ptr<SystemDependentData_CairoPath> pSystemDependentData_CairoPath(
rPolyPolygon.getSystemDependentData<SystemDependentData_CairoPath>());
if(pSystemDependentData_CairoPath)
{
// re-use data
cairo_append_path(cr, pSystemDependentData_CairoPath->getCairoPath());
bDone = true;
}
}
else
if (!bDone)
{
// create data
for (const auto & rPoly : rPolyPolygon)
@@ -1421,13 +1449,16 @@
false);
}
// copy and add to buffering mechanism
// for decisions how/what to buffer, see Note in WinSalGraphicsImpl::drawPolyPolygon
pSystemDependentData_CairoPath = rPolyPolygon.addOrReplaceSystemDependentData<SystemDependentData_CairoPath>(
ImplGetSystemDependentDataManager(),
cairo_copy_path(cr),
false,
false);
if (!bIsTrivial)
{
// copy and add to buffering mechanism
// for decisions how/what to buffer, see Note in WinSalGraphicsImpl::drawPolyPolygon
rPolyPolygon.addOrReplaceSystemDependentData<SystemDependentData_CairoPath>(
ImplGetSystemDependentDataManager(),
cairo_copy_path(cr),
false,
false);
}
}
}
}