summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArmin Le Grand <Armin.Le.Grand@cib.de>2018-09-21 16:42:01 +0200
committerArmin Le Grand <Armin.Le.Grand@cib.de>2018-09-21 20:12:09 +0200
commit80b287ad0322afcbf8f80b0507e212870dcf0f98 (patch)
tree7710bc62dfc82d4b77d2f1de3beb55599c4e3527
parentRelated: tdf#120028 PPTX import: fix font size of multi-col shape text (diff)
downloadcore-80b287ad0322afcbf8f80b0507e212870dcf0f98.tar.gz
core-80b287ad0322afcbf8f80b0507e212870dcf0f98.zip
Support buffering SystemDependent GraphicData
Started to make the buffering more flexible by adding virtual methods virtual sal_uInt32 getHoldCyclesInSeconds() const; virtual sal_Int64 estimateUsageInBytes() const; to class SystemDependentData. This will allow to add more sensitive buffering/caching. Also fine-tuned Linux-derived classes actively used for buffering to be more sensitive when and where to reuse the buffered data Change-Id: Ifc69c318ade0209aff071d76001869d9f4eeb10d Reviewed-on: https://gerrit.libreoffice.org/60881 Tested-by: Jenkins Reviewed-by: Armin Le Grand <Armin.Le.Grand@cib.de>
-rw-r--r--basegfx/source/tools/systemdependentdata.cxx18
-rw-r--r--include/basegfx/utils/systemdependentdata.hxx20
-rw-r--r--vcl/headless/svpgdi.cxx37
-rw-r--r--vcl/source/app/svdata.cxx4
-rw-r--r--vcl/unx/generic/gdi/gdiimpl.cxx48
-rw-r--r--vcl/win/gdi/gdiimpl.cxx31
6 files changed, 113 insertions, 45 deletions
diff --git a/basegfx/source/tools/systemdependentdata.cxx b/basegfx/source/tools/systemdependentdata.cxx
index 45f2efba5012..4153d35f7d55 100644
--- a/basegfx/source/tools/systemdependentdata.cxx
+++ b/basegfx/source/tools/systemdependentdata.cxx
@@ -61,16 +61,26 @@ namespace basegfx
namespace basegfx
{
SystemDependentData::SystemDependentData(
- SystemDependentDataManager& rSystemDependentDataManager,
- sal_uInt32 nHoldCycles)
- : mrSystemDependentDataManager(rSystemDependentDataManager),
- mnHoldCycles(nHoldCycles)
+ SystemDependentDataManager& rSystemDependentDataManager)
+ : mrSystemDependentDataManager(rSystemDependentDataManager)
{
}
SystemDependentData::~SystemDependentData()
{
}
+
+ sal_uInt32 SystemDependentData::getHoldCyclesInSeconds() const
+ {
+ // default implementation returns 60(s)
+ return 60;
+ }
+
+ sal_Int64 SystemDependentData::estimateUsageInBytes() const
+ {
+ // default implementation has no idea
+ return 0;
+ }
} // namespace basegfx
namespace basegfx
diff --git a/include/basegfx/utils/systemdependentdata.hxx b/include/basegfx/utils/systemdependentdata.hxx
index 6d4a90d10cda..920a55043870 100644
--- a/include/basegfx/utils/systemdependentdata.hxx
+++ b/include/basegfx/utils/systemdependentdata.hxx
@@ -89,14 +89,9 @@ namespace basegfx
// a single, globally used one, but not necessarily
SystemDependentDataManager& mrSystemDependentDataManager;
- // number of cycles a SystemDependentDataManager should/might
- // hold this instance - does not have to be used, but should be
- sal_uInt32 mnHoldCycles;
-
public:
SystemDependentData(
- SystemDependentDataManager& rSystemDependentDataManager,
- sal_uInt32 nHoldCycles = 60);
+ SystemDependentDataManager& rSystemDependentDataManager);
// CAUTION! It is VERY important to keep this base class
// virtual, else typeid(class).hash_code() from derived classes
@@ -108,8 +103,17 @@ namespace basegfx
// using getSystemDependentDataManager()
SystemDependentDataManager& getSystemDependentDataManager() { return mrSystemDependentDataManager; }
- // number of cycles to hold data
- sal_uInt32 getHoldCycles() const { return mnHoldCycles; }
+ // Number of cycles a SystemDependentDataManager should/might
+ // hold this instance in seconds - does not have to be used,
+ // but should be. Default implementation returns 60(s). Override to
+ // offer useful data if you want to have better caching.
+ virtual sal_uInt32 getHoldCyclesInSeconds() const;
+
+ // Size estimation of the entry in bytes - does not have to
+ // be used, but should be. Default returns zero what
+ // means there is no size estimation available. Override to
+ // offer useful data if you want to have better caching.
+ virtual sal_Int64 estimateUsageInBytes() const;
};
} // end of namespace basegfx
diff --git a/vcl/headless/svpgdi.cxx b/vcl/headless/svpgdi.cxx
index ea70321ff2fa..e12c7a32c8bd 100644
--- a/vcl/headless/svpgdi.cxx
+++ b/vcl/headless/svpgdi.cxx
@@ -1036,27 +1036,36 @@ void SvpSalGraphics::drawLine( long nX1, long nY1, long nX2, long nY2 )
class SystemDependentData_CairoPath : public basegfx::SystemDependentData
{
private:
+ // the path data itself
cairo_path_t* mpCairoPath;
- bool mbPixelSnapHairline;
+
+ // all other values the path data is based on and
+ // need to be compared with to check for data validity
+ bool mbNoJoin;
+ bool mbAntiAliasB2DDraw;
public:
SystemDependentData_CairoPath(
basegfx::SystemDependentDataManager& rSystemDependentDataManager,
- cairo_path_t* pCairoPath);
+ cairo_path_t* pCairoPath,
+ bool bNoJoin,
+ bool bAntiAliasB2DDraw);
virtual ~SystemDependentData_CairoPath() override;
cairo_path_t* getCairoPath() { return mpCairoPath; }
-
- bool getPixelSnapHairline() const { return mbPixelSnapHairline; }
- void setPixelSnapHairline(bool bNew) { mbPixelSnapHairline = bNew; }
+ bool getNoJoin() const { return mbNoJoin; }
+ bool getAntiAliasB2DDraw() const { return mbAntiAliasB2DDraw; }
};
SystemDependentData_CairoPath::SystemDependentData_CairoPath(
basegfx::SystemDependentDataManager& rSystemDependentDataManager,
- cairo_path_t* pCairoPath)
+ cairo_path_t* pCairoPath,
+ bool bNoJoin,
+ bool bAntiAliasB2DDraw)
: basegfx::SystemDependentData(rSystemDependentDataManager),
mpCairoPath(pCairoPath),
- mbPixelSnapHairline(false)
+ mbNoJoin(bNoJoin),
+ mbAntiAliasB2DDraw(bAntiAliasB2DDraw)
{
}
@@ -1246,7 +1255,8 @@ bool SvpSalGraphics::drawPolyLine(
{
// check data validity
if(nullptr == pSystemDependentData_CairoPath->getCairoPath()
- || pSystemDependentData_CairoPath->getPixelSnapHairline() != bPixelSnapHairline)
+ || pSystemDependentData_CairoPath->getNoJoin() != bNoJoin
+ || pSystemDependentData_CairoPath->getAntiAliasB2DDraw() != bAntiAliasB2DDraw)
{
// data invalid, forget
pSystemDependentData_CairoPath.reset();
@@ -1303,10 +1313,9 @@ bool SvpSalGraphics::drawPolyLine(
// copy and add to buffering mechanism
pSystemDependentData_CairoPath = rPolyLine.addOrReplaceSystemDependentData<SystemDependentData_CairoPath>(
ImplGetSystemDependentDataManager(),
- cairo_copy_path(cr));
-
- // fill data of buffered data
- pSystemDependentData_CairoPath->setPixelSnapHairline(bPixelSnapHairline);
+ cairo_copy_path(cr),
+ bNoJoin,
+ bAntiAliasB2DDraw);
}
// extract extents
@@ -1416,7 +1425,9 @@ bool SvpSalGraphics::drawPolyPolygon(
// for decisions how/what to buffer, see Note in WinSalGraphicsImpl::drawPolyPolygon
pSystemDependentData_CairoPath = rPolyPolygon.addOrReplaceSystemDependentData<SystemDependentData_CairoPath>(
ImplGetSystemDependentDataManager(),
- cairo_copy_path(cr));
+ cairo_copy_path(cr),
+ false,
+ false);
}
// To make releaseCairoContext work, use empty extents
diff --git a/vcl/source/app/svdata.cxx b/vcl/source/app/svdata.cxx
index 251da9e6b1a5..d0a0cee244b0 100644
--- a/vcl/source/app/svdata.cxx
+++ b/vcl/source/app/svdata.cxx
@@ -139,7 +139,7 @@ namespace
maTimer->Start();
}
- maEntries[rData] = rData->getHoldCycles();
+ maEntries[rData] = rData->getHoldCyclesInSeconds();
}
}
@@ -166,7 +166,7 @@ namespace
if(aFound != maEntries.end())
{
- aFound->second = rData->getHoldCycles();
+ aFound->second = rData->getHoldCyclesInSeconds();
}
}
diff --git a/vcl/unx/generic/gdi/gdiimpl.cxx b/vcl/unx/generic/gdi/gdiimpl.cxx
index 8b0742b4ec68..582c3c147efe 100644
--- a/vcl/unx/generic/gdi/gdiimpl.cxx
+++ b/vcl/unx/generic/gdi/gdiimpl.cxx
@@ -1651,26 +1651,45 @@ bool X11SalGraphicsImpl::drawFilledTriangles(
class SystemDependentData_Triangulation : public basegfx::SystemDependentData
{
private:
+ // the triangulation itself
basegfx::triangulator::B2DTriangleVector maTriangles;
+
+ // all other values the triangulation is based on and
+ // need to be compared with to check for data validity
basegfx::B2DVector maLineWidth;
+ basegfx::B2DLineJoin meJoin;
+ css::drawing::LineCap meCap;
+ double mfMiterMinimumAngle;
public:
SystemDependentData_Triangulation(
basegfx::SystemDependentDataManager& rSystemDependentDataManager,
const basegfx::triangulator::B2DTriangleVector& rTriangles,
- const basegfx::B2DVector& rLineWidth);
+ const basegfx::B2DVector& rLineWidth,
+ basegfx::B2DLineJoin eJoin,
+ css::drawing::LineCap eCap,
+ double fMiterMinimumAngle);
const basegfx::triangulator::B2DTriangleVector& getTriangles() const { return maTriangles; }
const basegfx::B2DVector& getLineWidth() const { return maLineWidth; }
+ const basegfx::B2DLineJoin& getJoin() const { return meJoin; }
+ const css::drawing::LineCap& getCap() const { return meCap; }
+ double getMiterMinimumAngle() const { return mfMiterMinimumAngle; }
};
SystemDependentData_Triangulation::SystemDependentData_Triangulation(
basegfx::SystemDependentDataManager& rSystemDependentDataManager,
const basegfx::triangulator::B2DTriangleVector& rTriangles,
- const basegfx::B2DVector& rLineWidth)
+ const basegfx::B2DVector& rLineWidth,
+ basegfx::B2DLineJoin eJoin,
+ css::drawing::LineCap eCap,
+ double fMiterMinimumAngle)
: basegfx::SystemDependentData(rSystemDependentDataManager),
maTriangles(rTriangles),
- maLineWidth(rLineWidth)
+ maLineWidth(rLineWidth),
+ meJoin(eJoin),
+ meCap(eCap),
+ mfMiterMinimumAngle(fMiterMinimumAngle)
{
}
@@ -1716,7 +1735,19 @@ bool X11SalGraphicsImpl::drawPolyLine(
if(pSystemDependentData_Triangulation)
{
- // check data validity
+ // check data validity (I)
+ if(pSystemDependentData_Triangulation->getJoin() != eLineJoin
+ || pSystemDependentData_Triangulation->getCap() != eLineCap
+ || pSystemDependentData_Triangulation->getMiterMinimumAngle() != fMiterMinimumAngle)
+ {
+ // data invalid, forget
+ pSystemDependentData_Triangulation.reset();
+ }
+ }
+
+ if(pSystemDependentData_Triangulation)
+ {
+ // check data validity (II)
if(pSystemDependentData_Triangulation->getLineWidth() != aLineWidth)
{
// sometimes small inconsistencies, use a percentage tolerance
@@ -1774,11 +1805,16 @@ bool X11SalGraphicsImpl::drawPolyLine(
if(!aTriangles.empty())
{
- // add to buffering mechanism
+ // Add to buffering mechanism
+ // Add all values the triangulation is based off, too, to check for
+ // validity (see above)
pSystemDependentData_Triangulation = rPolygon.addOrReplaceSystemDependentData<SystemDependentData_Triangulation>(
ImplGetSystemDependentDataManager(),
aTriangles,
- aLineWidth);
+ aLineWidth,
+ eLineJoin,
+ eLineCap,
+ fMiterMinimumAngle);
}
}
diff --git a/vcl/win/gdi/gdiimpl.cxx b/vcl/win/gdi/gdiimpl.cxx
index 0fde7b510486..017431ed7107 100644
--- a/vcl/win/gdi/gdiimpl.cxx
+++ b/vcl/win/gdi/gdiimpl.cxx
@@ -1954,24 +1954,31 @@ void impAddB2DPolygonToGDIPlusGraphicsPathReal(
class SystemDependentData_GraphicsPath : public basegfx::SystemDependentData
{
private:
+ // the path data itself
Gdiplus::GraphicsPath maGraphicsPath;
- bool mbPixelSnapHairline;
+
+ // all other values the triangulation is based on and
+ // need to be compared with to check for data validity
+ bool mbNoLineJoin;
public:
SystemDependentData_GraphicsPath(
- basegfx::SystemDependentDataManager& rSystemDependentDataManager);
-
+ basegfx::SystemDependentDataManager& rSystemDependentDataManager,
+ bool bNoLineJoin);
+ // non-const getter to allow manipulation. That way, we do not need
+ // to copy it (with unknown costs)
Gdiplus::GraphicsPath& getGraphicsPath() { return maGraphicsPath; }
- bool getPixelSnapHairline() const { return mbPixelSnapHairline; }
- void setPixelSnapHairline(bool bNew) { mbPixelSnapHairline = bNew; }
+ // other data-validity access
+ bool getNoLineJoin() const { return mbNoLineJoin; }
};
SystemDependentData_GraphicsPath::SystemDependentData_GraphicsPath(
- basegfx::SystemDependentDataManager& rSystemDependentDataManager)
+ basegfx::SystemDependentDataManager& rSystemDependentDataManager,
+ bool bNoLineJoin)
: basegfx::SystemDependentData(rSystemDependentDataManager),
maGraphicsPath(),
- mbPixelSnapHairline(false)
+ mbNoLineJoin(bNoLineJoin)
{
}
@@ -2019,7 +2026,8 @@ bool WinSalGraphicsImpl::drawPolyPolygon(
{
// add to buffering mechanism
pSystemDependentData_GraphicsPath = rPolyPolygon.addOrReplaceSystemDependentData<SystemDependentData_GraphicsPath>(
- ImplGetSystemDependentDataManager());
+ ImplGetSystemDependentDataManager(),
+ false);
// Note: In principle we could use the same buffered geometry at line
// and fill polygons. Checked that in a first try, used
@@ -2221,7 +2229,7 @@ bool WinSalGraphicsImpl::drawPolyLine(
if(pSystemDependentData_GraphicsPath)
{
// check data validity
- if(pSystemDependentData_GraphicsPath->getPixelSnapHairline() != bPixelSnapHairline)
+ if(pSystemDependentData_GraphicsPath->getNoLineJoin() != bNoLineJoin)
{
// data invalid, forget
pSystemDependentData_GraphicsPath.reset();
@@ -2232,11 +2240,10 @@ bool WinSalGraphicsImpl::drawPolyLine(
{
// add to buffering mechanism
pSystemDependentData_GraphicsPath = rPolygon.addOrReplaceSystemDependentData<SystemDependentData_GraphicsPath>(
- ImplGetSystemDependentDataManager());
+ ImplGetSystemDependentDataManager(),
+ bNoLineJoin);
// fill data of buffered data
- pSystemDependentData_GraphicsPath->setPixelSnapHairline(bPixelSnapHairline);
-
impAddB2DPolygonToGDIPlusGraphicsPathReal(
pSystemDependentData_GraphicsPath->getGraphicsPath(),
rPolygon,