basegfx/source/tools/systemdependentdata.cxx | 18 +++++++-- include/basegfx/utils/systemdependentdata.hxx | 20 ++++++---- vcl/headless/svpgdi.cxx | 37 +++++++++++++------- vcl/source/app/svdata.cxx | 4 +- vcl/unx/generic/gdi/gdiimpl.cxx | 48 ++++++++++++++++++++++---- vcl/win/gdi/gdiimpl.cxx | 31 ++++++++++------ 6 files changed, 113 insertions(+), 45 deletions(-)
New commits: commit 80b287ad0322afcbf8f80b0507e212870dcf0f98 Author: Armin Le Grand <armin.le.gr...@cib.de> AuthorDate: Fri Sep 21 16:42:01 2018 +0200 Commit: Armin Le Grand <armin.le.gr...@cib.de> CommitDate: Fri Sep 21 20:12:09 2018 +0200 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.gr...@cib.de> 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, _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits