summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArmin Le Grand <Armin.Le.Grand@cib.de>2018-10-03 15:55:29 +0200
committerArmin Le Grand <Armin.Le.Grand@cib.de>2018-10-06 20:31:22 +0200
commite650279db77281fe98aaff28e31c2269611c31e4 (patch)
tree2e497016dbe882d7557c4ee7ff66bb8b5d582dc2
parentdd36db168c658ebe588396255ad61363cc4ea7af (diff)
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@cib.de>
-rw-r--r--basegfx/source/tools/systemdependentdata.cxx47
-rw-r--r--include/basegfx/utils/systemdependentdata.hxx12
-rw-r--r--vcl/headless/svpgdi.cxx18
-rw-r--r--vcl/source/app/svdata.cxx4
-rw-r--r--vcl/unx/generic/gdi/gdiimpl.cxx14
-rw-r--r--vcl/win/gdi/gdiimpl.cxx96
-rw-r--r--vcl/win/gdi/salbmp.cxx88
7 files changed, 236 insertions, 43 deletions
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;