summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorArmin Le Grand <Armin.Le.Grand@cib.de>2018-08-24 13:01:08 +0200
committerArmin Le Grand <Armin.Le.Grand@cib.de>2018-08-30 19:48:46 +0200
commitb9fa01a8d1137a95af9865a3e47995734c40da6e (patch)
tree6d1e0a3e44b1a96fe5302d779c00fbee55cf8d24 /include
parentf4a9ce33415a85d0b86ced3a0bf780f4ec61e25f (diff)
Support buffering SystemDependent GraphicData
This is a first step to allow buffering of system dependent data, especially (but not only) for the system-dependent implementations of graphic output. For example, for B2DPolygon and Win output, it allows buffering the Gdiplus::GraphicsPath instead of re- creating it all the time. To support that, the change includes forwarding the current transformation to the renderers in SalGraphics. The current state in VCL is to transform all and everything to device coordinates at every single paint. I have currently started to do this for ::drawPolyLine implementations. The fallbacks for all systems will at the start of that method just transform the data to device coordinates, so all works as before. This may also be done for FilledPolygon paint in a later step, but most urgent is FatLine painting. An arrangement of shared_ptr/weak_ptr is used so that either the instance buffering (in the example B2DPolygon) or the instance managing it can delete it. The instance managing it currently uses a 1s Timer and a cycle-lifetime management, but that can be extended in the future to e.g. include size hints, too. The mechanism it designed to support multiple Data per buffering element, e.g. for B2DPolygon at the same time system-dependent instances of Gdiplus and Cairo can be buffered, but also PDF-data. This is achieved semi-automatic by using typeid(class).hash_code() as key for organization. The mechanism will be used for now at B2DPolygon, but is not limited to. There is already a similar but less general buffer (see GdiPlusBuffer) that can and will be converted to use this new mechanism. Added vcl/headless Cairo renderer to support given ObjectToDevice transformation (not to transform given B2DPolygon) Added support for CairoPath buffered at B2DPolygon, seems to work well. Need to do more tests Moved usage to templates suggested by Noel Grandin (Noel Grandin <noelgrandin@gmail.com>), thanks for these suggestions. Adapted Win usage to that, too. Converted Win-specific GdiPlus BitmapBuffer to new mechanism, works well. Checked, the manager holds now a mix of bitmap and path data under Win Added a cleanup mechanism to flush all buffered data at DeInitVCL() using flushAll() at SystemDependentDataBuffer Adapted Linux-versions of ::drawPolyLine to support PixelSnapHairline, for now in a simplified version that still allows buffering. This will also be used (and use buffering) for the Cairo-fallback in X11SalGraphics Change-Id: I88d7e438a20b96ddab7707050893bdd590c098c7 Reviewed-on: https://gerrit.libreoffice.org/59555 Tested-by: Armin Le Grand <Armin.Le.Grand@cib.de> Reviewed-by: Armin Le Grand <Armin.Le.Grand@cib.de>
Diffstat (limited to 'include')
-rw-r--r--include/basegfx/polygon/b2dpolygon.hxx24
-rwxr-xr-xinclude/basegfx/utils/systemdependentdata.hxx139
-rw-r--r--include/vcl/outdev.hxx1
3 files changed, 164 insertions, 0 deletions
diff --git a/include/basegfx/polygon/b2dpolygon.hxx b/include/basegfx/polygon/b2dpolygon.hxx
index 714d2a1fd10d..353e7130f5ed 100644
--- a/include/basegfx/polygon/b2dpolygon.hxx
+++ b/include/basegfx/polygon/b2dpolygon.hxx
@@ -29,6 +29,7 @@
#include <basegfx/basegfxdllapi.h>
class ImplB2DPolygon;
+class SalGraphicsImpl;
namespace basegfx
{
@@ -37,6 +38,9 @@ namespace basegfx
class B2DVector;
class B2DHomMatrix;
class B2DCubicBezier;
+ class SystemDependentData;
+ class SystemDependentDataManager;
+ typedef std::shared_ptr<SystemDependentData> SystemDependentData_SharedPtr;
}
namespace basegfx
@@ -218,6 +222,26 @@ namespace basegfx
/// apply transformation given in matrix form
void transform(const basegfx::B2DHomMatrix& rMatrix);
+
+ // exclusive management op's for SystemDependentData at B2DPolygon
+ template<class T>
+ std::shared_ptr<T> getSystemDependentData() const
+ {
+ return std::static_pointer_cast<T>(getSystemDependantDataInternal(typeid(T).hash_code()));
+ }
+
+ template<class T, class... Args>
+ std::shared_ptr<T> addOrReplaceSystemDependentData(SystemDependentDataManager& manager, Args&&... args) const
+ {
+ std::shared_ptr<T> r = std::make_shared<T>(manager, std::forward<Args>(args)...);
+ basegfx::SystemDependentData_SharedPtr r2(r);
+ addOrReplaceSystemDependentDataInternal(r2);
+ return r;
+ }
+
+ private:
+ void addOrReplaceSystemDependentDataInternal(SystemDependentData_SharedPtr& rData) const;
+ SystemDependentData_SharedPtr getSystemDependantDataInternal(size_t hash_code) const;
};
// typedef for a vector of B2DPolygons
diff --git a/include/basegfx/utils/systemdependentdata.hxx b/include/basegfx/utils/systemdependentdata.hxx
new file mode 100755
index 000000000000..17a0ce44f815
--- /dev/null
+++ b/include/basegfx/utils/systemdependentdata.hxx
@@ -0,0 +1,139 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#ifndef INCLUDED_BASEGFX_SYSTEMDEPENDENTDATA_HXX
+#define INCLUDED_BASEGFX_SYSTEMDEPENDENTDATA_HXX
+
+#include <sal/types.h>
+#include <basegfx/basegfxdllapi.h>
+#include <memory>
+#include <map>
+#include <set>
+
+namespace basegfx
+{
+ class SystemDependentData;
+ typedef std::shared_ptr<SystemDependentData> SystemDependentData_SharedPtr;
+ typedef std::weak_ptr<SystemDependentData> SystemDependentData_WeakPtr;
+} // end of namespace basegfx
+
+namespace basegfx
+{
+ class BASEGFX_DLLPUBLIC SystemDependentDataManager
+ {
+ private:
+ // noncopyable
+ SystemDependentDataManager(const SystemDependentDataManager&) = delete;
+ SystemDependentDataManager& operator=(const SystemDependentDataManager&) = delete;
+
+ public:
+ SystemDependentDataManager();
+ virtual ~SystemDependentDataManager();
+
+ // call from (and with) SystemDependentData objects when start/end/touch
+ // usage is needed
+ virtual void startUsage(basegfx::SystemDependentData_SharedPtr& rData) = 0;
+ virtual void endUsage(basegfx::SystemDependentData_SharedPtr& rData) = 0;
+ virtual void touchUsage(basegfx::SystemDependentData_SharedPtr& rData) = 0;
+
+ // flush all buffred data (e.g. cleanup/shutdown)
+ virtual void flushAll() = 0;
+ };
+} // end of namespace basegfx
+
+namespace basegfx
+{
+ class BASEGFX_DLLPUBLIC MinimalSystemDependentDataManager : public SystemDependentDataManager
+ {
+ private:
+ // example of a minimal SystemDependentDataManager. It *needs to hold*
+ // a SystemDependentData_SharedPtr while SystemDependentDataHolder's will
+ // use a SystemDependentData_WeakPtr. When the held SystemDependentData_SharedPtr
+ // is deleted, the corresponding SystemDependentData_WeakPtr will get void.
+ // To make this work, a minimal SystemDependentDataManager *has* to hold at
+ // least that one SystemDependentData_SharedPtr.
+ // That SystemDependentData_SharedPtr may be (e.g. Timer-based or ressource-based)
+ // be freed then. This minimal implementation does never free it, so all stay valid.
+ // The instances may still be removed by endUsage calls, but there is no
+ // caching/buffering mechanism involved here at all. It's an example, but
+ // not used - better use an advanced derivation of SystemDependentDataManager
+ std::set< SystemDependentData_SharedPtr > maSystemDependentDataReferences;
+
+ public:
+ MinimalSystemDependentDataManager();
+ virtual ~MinimalSystemDependentDataManager() override;
+
+ virtual void startUsage(basegfx::SystemDependentData_SharedPtr& rData) override;
+ virtual void endUsage(basegfx::SystemDependentData_SharedPtr& rData) override;
+ virtual void touchUsage(basegfx::SystemDependentData_SharedPtr& rData) override;
+ virtual void flushAll() override;
+ };
+} // end of namespace basegfx
+
+namespace basegfx
+{
+ class BASEGFX_DLLPUBLIC SystemDependentData
+ {
+ private:
+ // noncopyable
+ SystemDependentData(const SystemDependentData&) = delete;
+ SystemDependentData& operator=(const SystemDependentData&) = delete;
+
+ // reference to a SystemDependentDataManager, probably
+ // 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);
+
+ // CAUTION! It is VERY important to keep this base class
+ // virtual, else typeid(class).hash_code() from derived classes
+ // will NOT work what is ESSENTIAL for the SystemDependentData
+ // mechanism to work properly. So DO NOT REMOVE virtual here, please.
+ virtual ~SystemDependentData();
+
+ // allow access to call startUsage/endUsage/touchUsage
+ // using getSystemDependentDataManager()
+ SystemDependentDataManager& getSystemDependentDataManager() { return mrSystemDependentDataManager; }
+
+ // number of cycles to hold data
+ sal_uInt32 getHoldCycles() const { return mnHoldCycles; }
+ };
+} // end of namespace basegfx
+
+namespace basegfx
+{
+ class BASEGFX_DLLPUBLIC SystemDependentDataHolder
+ {
+ private:
+ // Possibility to hold System-Dependent B2DPolygon-Representations
+ std::map< size_t, SystemDependentData_WeakPtr > maSystemDependentReferences;
+
+ // noncopyable
+ SystemDependentDataHolder(const SystemDependentDataHolder&) = delete;
+ SystemDependentDataHolder& operator=(const SystemDependentDataHolder&) = delete;
+
+ public:
+ SystemDependentDataHolder();
+ virtual ~SystemDependentDataHolder();
+
+ void addOrReplaceSystemDependentData(SystemDependentData_SharedPtr& rData);
+ SystemDependentData_SharedPtr getSystemDependentData(size_t hash_code) const;
+ };
+} // end of namespace basegfx
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/vcl/outdev.hxx b/include/vcl/outdev.hxx
index 54c22e6cc7fd..57bedf5b0635 100644
--- a/include/vcl/outdev.hxx
+++ b/include/vcl/outdev.hxx
@@ -800,6 +800,7 @@ public:
// #i101491#
// Helper who tries to use SalGDI's DrawPolyLine direct and returns it's bool.
bool DrawPolyLineDirect(
+ const basegfx::B2DHomMatrix& rObjectTransform,
const basegfx::B2DPolygon& rB2DPolygon,
double fLineWidth = 0.0,
double fTransparency = 0.0,