[Libreoffice-commits] core.git: basegfx/source include/basegfx vcl/headless vcl/source vcl/unx vcl/win

Libreoffice Gerrit user logerrit at kemper.freedesktop.org
Fri Sep 21 18:12:35 UTC 2018


 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.Grand at cib.de>
AuthorDate: Fri Sep 21 16:42:01 2018 +0200
Commit:     Armin Le Grand <Armin.Le.Grand at 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.Grand at 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,


More information about the Libreoffice-commits mailing list