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

Libreoffice Gerrit user logerrit at kemper.freedesktop.org
Sat Oct 6 18:31:42 UTC 2018


 basegfx/source/tools/systemdependentdata.cxx  |   47 ++++++++++++
 include/basegfx/utils/systemdependentdata.hxx |   12 +++
 vcl/headless/svpgdi.cxx                       |   18 ++++
 vcl/source/app/svdata.cxx                     |    4 -
 vcl/unx/generic/gdi/gdiimpl.cxx               |   14 +++
 vcl/win/gdi/gdiimpl.cxx                       |   96 +++++++++++++++++++-------
 vcl/win/gdi/salbmp.cxx                        |   88 +++++++++++++++++++----
 7 files changed, 236 insertions(+), 43 deletions(-)

New commits:
commit e650279db77281fe98aaff28e31c2269611c31e4
Author:     Armin Le Grand <Armin.Le.Grand at cib.de>
AuthorDate: Wed Oct 3 15:55:29 2018 +0200
Commit:     Armin Le Grand <Armin.Le.Grand at cib.de>
CommitDate: Sat Oct 6 20:31:22 2018 +0200

    Support estimateUsageInBytes for SystemDependentData
    
    Change-Id: I6074035ed8f90e452915e9ecffdbe9363375e126
    Reviewed-on: https://gerrit.libreoffice.org/61306
    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 4153d35f7d55..c727462c7191 100644
--- a/basegfx/source/tools/systemdependentdata.cxx
+++ b/basegfx/source/tools/systemdependentdata.cxx
@@ -8,6 +8,7 @@
  */
 
 #include <basegfx/utils/systemdependentdata.hxx>
+#include <math.h>
 
 namespace basegfx
 {
@@ -62,7 +63,8 @@ namespace basegfx
 {
     SystemDependentData::SystemDependentData(
         SystemDependentDataManager& rSystemDependentDataManager)
-    :   mrSystemDependentDataManager(rSystemDependentDataManager)
+    :   mrSystemDependentDataManager(rSystemDependentDataManager),
+        mnCalculatedCycles(0)
     {
     }
 
@@ -70,6 +72,49 @@ namespace basegfx
     {
     }
 
+    sal_uInt32 SystemDependentData::calculateCombinedHoldCyclesInSeconds() const
+    {
+        if(0 == mnCalculatedCycles)
+        {
+            const sal_Int64 nBytes(estimateUsageInBytes());
+            const sal_uInt32 nSeconds(getHoldCyclesInSeconds());
+
+            // default is Seconds (minimal is one)
+            sal_uInt32 nResult(0 == nSeconds ? 1 : nSeconds);
+
+            if(0 != nBytes)
+            {
+                // use sqrt to get some curved shape. With a default of 60s we get
+                // a single second at 3600 byte. To get close to 10mb, multiply by
+                // a corresponding scaling factor
+                const double fScaleToMB(3600.0 / (1024.0 * 1024.0 * 10.0));
+
+                // also use a multiplier to move the start point higer
+                const double fMultiplierSeconds(10.0);
+
+                // calculate
+                nResult = static_cast<sal_uInt32>((fMultiplierSeconds * nSeconds) / sqrt(nBytes * fScaleToMB));
+
+                // minimal value is 1
+                if(nResult < 1)
+                {
+                    nResult = 1;
+                }
+
+                // maximal value is nSeconds
+                if(nResult > nSeconds)
+                {
+                    nResult = nSeconds;
+                }
+            }
+
+            // set locally (once, on-demand created, non-zero)
+            const_cast<SystemDependentData*>(this)->mnCalculatedCycles = nResult < 1 ? 1 : nResult;
+        }
+
+        return mnCalculatedCycles;
+    }
+
     sal_uInt32 SystemDependentData::getHoldCyclesInSeconds() const
     {
         // default implementation returns 60(s)
diff --git a/include/basegfx/utils/systemdependentdata.hxx b/include/basegfx/utils/systemdependentdata.hxx
index 920a55043870..d5cc8d645eb6 100644
--- a/include/basegfx/utils/systemdependentdata.hxx
+++ b/include/basegfx/utils/systemdependentdata.hxx
@@ -89,6 +89,12 @@ namespace basegfx
         // a single, globally used one, but not necessarily
         SystemDependentDataManager&     mrSystemDependentDataManager;
 
+        // Buffered CalculatedCycles, result of estimations using
+        // getHoldCyclesInSeconds and estimateUsageInBytes, executed
+        // using getHoldCyclesInSeconds. StartValue is 0 to detect
+        // not-yet-calculated state
+        sal_uInt32                      mnCalculatedCycles;
+
     public:
         SystemDependentData(
             SystemDependentDataManager& rSystemDependentDataManager);
@@ -103,6 +109,12 @@ namespace basegfx
         // using getSystemDependentDataManager()
         SystemDependentDataManager& getSystemDependentDataManager() { return mrSystemDependentDataManager; }
 
+        // Calculate HoldCyclesInSeconds based on using
+        // getHoldCyclesInSeconds and estimateUsageInBytes, the
+        // result is crated once on-demand and buffered in
+        // mnCalculatedCycles
+        sal_uInt32 calculateCombinedHoldCyclesInSeconds() const;
+
         // 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
diff --git a/vcl/headless/svpgdi.cxx b/vcl/headless/svpgdi.cxx
index b1f622904b5f..e42eb3ed3eaa 100644
--- a/vcl/headless/svpgdi.cxx
+++ b/vcl/headless/svpgdi.cxx
@@ -1056,6 +1056,8 @@ public:
     cairo_path_t* getCairoPath() { return mpCairoPath; }
     bool getNoJoin() const { return mbNoJoin; }
     bool getAntiAliasB2DDraw() const { return mbAntiAliasB2DDraw; }
+
+    virtual sal_Int64 estimateUsageInBytes() const override;
 };
 
 SystemDependentData_CairoPath::SystemDependentData_CairoPath(
@@ -1079,6 +1081,22 @@ SystemDependentData_CairoPath::~SystemDependentData_CairoPath()
     }
 }
 
+sal_Int64 SystemDependentData_CairoPath::estimateUsageInBytes() const
+{
+    sal_Int64 nRetval(0);
+
+    if(nullptr != mpCairoPath)
+    {
+        // per node
+        // - num_data incarnations of
+        // - sizeof(cairo_path_data_t) which is a union of defines and point data
+        //   thus may 2 x sizeof(double)
+        nRetval = mpCairoPath->num_data * sizeof(cairo_path_data_t);
+    }
+
+    return nRetval;
+}
+
 bool SvpSalGraphics::drawPolyLine(
     const basegfx::B2DHomMatrix& rObjectToDevice,
     const basegfx::B2DPolygon& rPolyLine,
diff --git a/vcl/source/app/svdata.cxx b/vcl/source/app/svdata.cxx
index d0a0cee244b0..edbcc3b4e870 100644
--- a/vcl/source/app/svdata.cxx
+++ b/vcl/source/app/svdata.cxx
@@ -139,7 +139,7 @@ namespace
                     maTimer->Start();
                 }
 
-                maEntries[rData] = rData->getHoldCyclesInSeconds();
+                maEntries[rData] = rData->calculateCombinedHoldCyclesInSeconds();
             }
         }
 
@@ -166,7 +166,7 @@ namespace
 
             if(aFound != maEntries.end())
             {
-                aFound->second = rData->getHoldCyclesInSeconds();
+                aFound->second = rData->calculateCombinedHoldCyclesInSeconds();
             }
         }
 
diff --git a/vcl/unx/generic/gdi/gdiimpl.cxx b/vcl/unx/generic/gdi/gdiimpl.cxx
index 0bfe098e7ef4..7ed38cc6eab5 100644
--- a/vcl/unx/generic/gdi/gdiimpl.cxx
+++ b/vcl/unx/generic/gdi/gdiimpl.cxx
@@ -1675,6 +1675,8 @@ public:
     const basegfx::B2DLineJoin& getJoin() const { return meJoin; }
     const css::drawing::LineCap& getCap() const { return meCap; }
     double getMiterMinimumAngle() const { return mfMiterMinimumAngle; }
+
+    virtual sal_Int64 estimateUsageInBytes() const override;
 };
 
 SystemDependentData_Triangulation::SystemDependentData_Triangulation(
@@ -1693,6 +1695,18 @@ SystemDependentData_Triangulation::SystemDependentData_Triangulation(
 {
 }
 
+sal_Int64 SystemDependentData_Triangulation::estimateUsageInBytes() const
+{
+    sal_Int64 nRetval(0);
+
+    if(!maTriangles.empty())
+    {
+        nRetval = maTriangles.size() * sizeof(basegfx::triangulator::B2DTriangle);
+    }
+
+    return nRetval;
+}
+
 bool X11SalGraphicsImpl::drawPolyLine(
     const basegfx::B2DHomMatrix& rObjectToDevice,
     const basegfx::B2DPolygon& rPolygon,
diff --git a/vcl/win/gdi/gdiimpl.cxx b/vcl/win/gdi/gdiimpl.cxx
index d446ec877a98..a77e26f0e180 100644
--- a/vcl/win/gdi/gdiimpl.cxx
+++ b/vcl/win/gdi/gdiimpl.cxx
@@ -1955,33 +1955,57 @@ class SystemDependentData_GraphicsPath : public basegfx::SystemDependentData
 {
 private:
     // the path data itself
-    Gdiplus::GraphicsPath           maGraphicsPath;
+    std::shared_ptr<Gdiplus::GraphicsPath>  mpGraphicsPath;
 
     // all other values the triangulation is based on and
     // need to be compared with to check for data validity
-    bool                            mbNoLineJoin;
+    bool                                    mbNoLineJoin;
 
 public:
     SystemDependentData_GraphicsPath(
         basegfx::SystemDependentDataManager& rSystemDependentDataManager,
+        std::shared_ptr<Gdiplus::GraphicsPath>& rpGraphicsPath,
         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; }
+
+    // read access to Gdiplus::GraphicsPath
+    std::shared_ptr<Gdiplus::GraphicsPath>& getGraphicsPath() { return mpGraphicsPath; }
 
     // other data-validity access
     bool getNoLineJoin() const { return mbNoLineJoin; }
+
+    virtual sal_Int64 estimateUsageInBytes() const override;
 };
 
 SystemDependentData_GraphicsPath::SystemDependentData_GraphicsPath(
     basegfx::SystemDependentDataManager& rSystemDependentDataManager,
+    std::shared_ptr<Gdiplus::GraphicsPath>& rpGraphicsPath,
     bool bNoLineJoin)
 :   basegfx::SystemDependentData(rSystemDependentDataManager),
-    maGraphicsPath(),
+    mpGraphicsPath(rpGraphicsPath),
     mbNoLineJoin(bNoLineJoin)
 {
 }
 
+sal_Int64 SystemDependentData_GraphicsPath::estimateUsageInBytes() const
+{
+    sal_Int64 nRetval(0);
+
+    if(mpGraphicsPath)
+    {
+        const INT nPointCount(mpGraphicsPath->GetPointCount());
+
+        if(0 != nPointCount)
+        {
+            // Each point has
+            // - 2 x sizeof(Gdiplus::REAL)
+            // - 1 byte (see GetPathTypes in docu)
+            nRetval = nPointCount * ((2 * sizeof(Gdiplus::REAL)) + 1);
+        }
+    }
+
+    return nRetval;
+}
+
 bool WinSalGraphicsImpl::drawPolyPolygon(
     const basegfx::B2DHomMatrix& rObjectToDevice,
     const basegfx::B2DPolyPolygon& rPolyPolygon,
@@ -2018,17 +2042,20 @@ bool WinSalGraphicsImpl::drawPolyPolygon(
         aGraphics.SetTransform(&aMatrix);
     }
 
+    // prepare local instabce of Gdiplus::GraphicsPath
+    std::shared_ptr<Gdiplus::GraphicsPath> pGraphicsPath;
+
     // try to access buffered data
     std::shared_ptr<SystemDependentData_GraphicsPath> pSystemDependentData_GraphicsPath(
         rPolyPolygon.getSystemDependentData<SystemDependentData_GraphicsPath>());
 
-    if(!pSystemDependentData_GraphicsPath)
+    if(pSystemDependentData_GraphicsPath)
+    {
+        // copy buffered data
+        pGraphicsPath = pSystemDependentData_GraphicsPath->getGraphicsPath();
+    }
+    else
     {
-        // add to buffering mechanism
-        pSystemDependentData_GraphicsPath = rPolyPolygon.addOrReplaceSystemDependentData<SystemDependentData_GraphicsPath>(
-            ImplGetSystemDependentDataManager(),
-            false);
-
         // Note: In principle we could use the same buffered geometry at line
         // and fill polygons. Checked that in a first try, used
         // GraphicsPath::AddPath from Gdiplus combined with below used
@@ -2056,23 +2083,31 @@ bool WinSalGraphicsImpl::drawPolyPolygon(
         // (at least for now...)
 
         // create data
+        pGraphicsPath.reset(new Gdiplus::GraphicsPath());
+
         for(sal_uInt32 a(0); a < nCount; a++)
         {
             if(0 != a)
             {
                 // #i101491# not needed for first run
-                pSystemDependentData_GraphicsPath->getGraphicsPath().StartFigure();
+                pGraphicsPath->StartFigure();
             }
 
             impAddB2DPolygonToGDIPlusGraphicsPathReal(
-                pSystemDependentData_GraphicsPath->getGraphicsPath(),
+                *pGraphicsPath,
                 rPolyPolygon.getB2DPolygon(a),
                 rObjectToDevice, // not used due to the two 'false' values below, but to not forget later
                 false,
                 false);
 
-            pSystemDependentData_GraphicsPath->getGraphicsPath().CloseFigure();
+            pGraphicsPath->CloseFigure();
         }
+
+        // add to buffering mechanism
+        rPolyPolygon.addOrReplaceSystemDependentData<SystemDependentData_GraphicsPath>(
+            ImplGetSystemDependentDataManager(),
+            pGraphicsPath,
+            false);
     }
 
     if(mrParent.getAntiAliasB2DDraw())
@@ -2122,7 +2157,7 @@ bool WinSalGraphicsImpl::drawPolyPolygon(
     // use created or buffered data
     aGraphics.FillPath(
         &aSolidBrush,
-        &pSystemDependentData_GraphicsPath->getGraphicsPath());
+        &(*pGraphicsPath));
 
     return true;
 }
@@ -2222,6 +2257,9 @@ bool WinSalGraphicsImpl::drawPolyLine(
         }
     }
 
+    // prepare local instabce of Gdiplus::GraphicsPath
+    std::shared_ptr<Gdiplus::GraphicsPath> pGraphicsPath;
+
     // try to access buffered data
     std::shared_ptr<SystemDependentData_GraphicsPath> pSystemDependentData_GraphicsPath(
         rPolygon.getSystemDependentData<SystemDependentData_GraphicsPath>());
@@ -2236,16 +2274,18 @@ bool WinSalGraphicsImpl::drawPolyLine(
         }
     }
 
-    if(!pSystemDependentData_GraphicsPath)
+    if(pSystemDependentData_GraphicsPath)
+    {
+        // copy buffered data
+        pGraphicsPath = pSystemDependentData_GraphicsPath->getGraphicsPath();
+    }
+    else
     {
-        // add to buffering mechanism
-        pSystemDependentData_GraphicsPath = rPolygon.addOrReplaceSystemDependentData<SystemDependentData_GraphicsPath>(
-            ImplGetSystemDependentDataManager(),
-            bNoLineJoin);
-
         // fill data of buffered data
+        pGraphicsPath.reset(new Gdiplus::GraphicsPath());
+
         impAddB2DPolygonToGDIPlusGraphicsPathReal(
-            pSystemDependentData_GraphicsPath->getGraphicsPath(),
+            *pGraphicsPath,
             rPolygon,
             rObjectToDevice,
             bNoLineJoin,
@@ -2254,8 +2294,14 @@ bool WinSalGraphicsImpl::drawPolyLine(
         if(rPolygon.isClosed() && !bNoLineJoin)
         {
             // #i101491# needed to create the correct line joins
-            pSystemDependentData_GraphicsPath->getGraphicsPath().CloseFigure();
+            pGraphicsPath->CloseFigure();
         }
+
+        // add to buffering mechanism
+        rPolygon.addOrReplaceSystemDependentData<SystemDependentData_GraphicsPath>(
+            ImplGetSystemDependentDataManager(),
+            pGraphicsPath,
+            bNoLineJoin);
     }
 
     if(mrParent.getAntiAliasB2DDraw())
@@ -2269,7 +2315,7 @@ bool WinSalGraphicsImpl::drawPolyLine(
 
     aGraphics.DrawPath(
         &aPen,
-        &pSystemDependentData_GraphicsPath->getGraphicsPath());
+        &(*pGraphicsPath));
 
     return true;
 }
diff --git a/vcl/win/gdi/salbmp.cxx b/vcl/win/gdi/salbmp.cxx
index 4d21fde79da9..fcdd4b984e1d 100644
--- a/vcl/win/gdi/salbmp.cxx
+++ b/vcl/win/gdi/salbmp.cxx
@@ -98,21 +98,77 @@ private:
 
 public:
     SystemDependentData_GdiPlusBitmap(
-        basegfx::SystemDependentDataManager& rSystemDependentDataManager);
+        basegfx::SystemDependentDataManager& rSystemDependentDataManager,
+        const std::shared_ptr<Gdiplus::Bitmap>& rGdiPlusBitmap,
+        const WinSalBitmap* pAssociatedAlpha);
 
     const WinSalBitmap* getAssociatedAlpha() const { return mpAssociatedAlpha; }
-    void setAssociatedAlpha(const WinSalBitmap* pNew) { mpAssociatedAlpha = pNew; }
-
     const std::shared_ptr<Gdiplus::Bitmap>& getGdiPlusBitmap() const { return mpGdiPlusBitmap; }
-    void setGdiPlusBitmap(const std::shared_ptr<Gdiplus::Bitmap>& rNew) { mpGdiPlusBitmap = rNew; }
+
+    virtual sal_Int64 estimateUsageInBytes() const override;
 };
 
 SystemDependentData_GdiPlusBitmap::SystemDependentData_GdiPlusBitmap(
-    basegfx::SystemDependentDataManager& rSystemDependentDataManager)
+    basegfx::SystemDependentDataManager& rSystemDependentDataManager,
+    const std::shared_ptr<Gdiplus::Bitmap>& rGdiPlusBitmap,
+    const WinSalBitmap* pAssociatedAlpha)
 :   basegfx::SystemDependentData(rSystemDependentDataManager),
-    mpGdiPlusBitmap(),
-    mpAssociatedAlpha(nullptr)
+    mpGdiPlusBitmap(rGdiPlusBitmap),
+    mpAssociatedAlpha(pAssociatedAlpha)
+{
+}
+
+sal_Int64 SystemDependentData_GdiPlusBitmap::estimateUsageInBytes() const
 {
+    sal_Int64 nRetval(0);
+
+    if(mpGdiPlusBitmap)
+    {
+        const UINT nWidth(mpGdiPlusBitmap->GetWidth());
+        const UINT nHeight(mpGdiPlusBitmap->GetHeight());
+
+        if(0 != nWidth && 0 != nHeight)
+        {
+            nRetval = nWidth * nHeight;
+
+            switch(mpGdiPlusBitmap->GetPixelFormat())
+            {
+                case PixelFormat1bppIndexed:
+                    nRetval /= 8;
+                    break;
+                case PixelFormat4bppIndexed:
+                    nRetval /= 4;
+                    break;
+                case PixelFormat16bppGrayScale:
+                case PixelFormat16bppRGB555:
+                case PixelFormat16bppRGB565:
+                case PixelFormat16bppARGB1555:
+                    nRetval *= 2;
+                    break;
+                case PixelFormat24bppRGB:
+                    nRetval *= 3;
+                    break;
+                case PixelFormat32bppRGB:
+                case PixelFormat32bppARGB:
+                case PixelFormat32bppPARGB:
+                case PixelFormat32bppCMYK:
+                    nRetval *= 4;
+                    break;
+                case PixelFormat48bppRGB:
+                    nRetval *= 6;
+                    break;
+                case PixelFormat64bppARGB:
+                case PixelFormat64bppPARGB:
+                    nRetval *= 8;
+                    break;
+                default:
+                case PixelFormat8bppIndexed:
+                    break;
+            }
+        }
+    }
+
+    return nRetval;
 }
 
 std::shared_ptr< Gdiplus::Bitmap > WinSalBitmap::ImplGetGdiPlusBitmap(const WinSalBitmap* pAlphaSource) const
@@ -144,23 +200,25 @@ std::shared_ptr< Gdiplus::Bitmap > WinSalBitmap::ImplGetGdiPlusBitmap(const WinS
     }
     else if(maSize.Width() > 0 && maSize.Height() > 0)
     {
-        // add to buffering mechanism
-        pSystemDependentData_GdiPlusBitmap = addOrReplaceSystemDependentData<SystemDependentData_GdiPlusBitmap>(
-            ImplGetSystemDependentDataManager());
-
         // create and set data
+        const WinSalBitmap* pAssociatedAlpha(nullptr);
+
         if(pAlphaSource)
         {
             aRetval.reset(const_cast< WinSalBitmap* >(this)->ImplCreateGdiPlusBitmap(*pAlphaSource));
-            pSystemDependentData_GdiPlusBitmap->setGdiPlusBitmap(aRetval);
-            pSystemDependentData_GdiPlusBitmap->setAssociatedAlpha(pAlphaSource);
+            pAssociatedAlpha = pAlphaSource;
         }
         else
         {
             aRetval.reset(const_cast< WinSalBitmap* >(this)->ImplCreateGdiPlusBitmap());
-            pSystemDependentData_GdiPlusBitmap->setGdiPlusBitmap(aRetval);
-            pSystemDependentData_GdiPlusBitmap->setAssociatedAlpha(nullptr);
+            pAssociatedAlpha = nullptr;
         }
+
+        // add to buffering mechanism
+        addOrReplaceSystemDependentData<SystemDependentData_GdiPlusBitmap>(
+            ImplGetSystemDependentDataManager(),
+            aRetval,
+            pAssociatedAlpha);
     }
 
     return aRetval;


More information about the Libreoffice-commits mailing list