summaryrefslogtreecommitdiff
path: root/include/drawinglayer
diff options
context:
space:
mode:
authorArmin Le Grand (allotropia) <armin.le.grand.extern@allotropia.de>2023-12-18 18:23:37 +0100
committerArmin Le Grand <Armin.Le.Grand@me.com>2023-12-19 11:04:08 +0100
commit0d512011a695da8dafe9467ec0ff7f564dfe8c88 (patch)
treea703243d25cc9e453794cba2307a9e6b48e18831 /include/drawinglayer
parente8248b5e4b19df8ba469d1ca3a762960c1a053b5 (diff)
Add flush mechanism to buffered Primitives
There are the classes BufferedDecompositionPrimitive2D and BufferedDecompositionGroupPrimitive2D that offer a unified mechanism to preserve/buffer the decomposition of a Primitive, independent of the complexity. This may include e.g. the pixel representation of a 3D Scene, for Charts/CustomShapes and others. Until now these were refreshed when the objects change, or when the buffered decomposition decides that it is necessary, but there was no general mechanism in place to clean these up while the Primitive owning them was alive/used. This is not a big thing in Draw/Impress since this would only be relevant when zooming deep into a SdrPage, so the non-vislible parts would still hold data that would not be needed. But for Calc and Writer this is more relevant: A 3D Chart on the 1st page of a Writer document would be held buffered all the time a user would work on pages below that. This is good for guaranteeing fast re-visualization when scrolling up again, but until then would just block memory. So I added this general mechanism that allows activating flushing timer-based, on Seconds. The default is null seconds, thus deactivated. It should only be used for Primitives that can get expensive, not for all. NOTE: I checked activating for all Primitives to be on the safe side, works. It is now (initially) activated for: - GlowPrimitive2D - GraphicPrimitive2D - MetafilePrimitive2D - ScenePrimitive2D - ShadowPrimitive2D (softShadow) - SoftEdgePrimitive2D - SdrCustomShapePrimitive2D - SdrGrafPrimitive2D These are the usual suspects that may use some memory to buffer their decomposition (for good reasons, each repaint uses it). Other Primitives which may show need to be treated this way can easily be added, just by calling setCallbackSeconds(s) in their constructor. This is true for all Primitives derived from the two classes mentioned above. NOTE: Too short buffering times are *not* useful - e.g. for a expensive-to-be-recreated 3D chart representation this may not pay out, so I chose times in a way that try to respect this. NOTE: This change needs 7397fa7cdfc33f5a079df42e4d6cfa59ae9e062d to work correctly (thanks to sberg for this). Without this the office hangs/does not terminate regularly in trying to destroy the 'TimerManager'. Change-Id: Id4802afcb6d12480bb2935cc1ef67fe443b3b788 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/160926 Tested-by: Jenkins Reviewed-by: Armin Le Grand <Armin.Le.Grand@me.com>
Diffstat (limited to 'include/drawinglayer')
-rw-r--r--include/drawinglayer/primitive2d/BufferedDecompositionGroupPrimitive2D.hxx24
-rw-r--r--include/drawinglayer/primitive2d/BufferedDecompositionPrimitive2D.hxx27
2 files changed, 34 insertions, 17 deletions
diff --git a/include/drawinglayer/primitive2d/BufferedDecompositionGroupPrimitive2D.hxx b/include/drawinglayer/primitive2d/BufferedDecompositionGroupPrimitive2D.hxx
index a1cfee38798f..c3bc54e5fca3 100644
--- a/include/drawinglayer/primitive2d/BufferedDecompositionGroupPrimitive2D.hxx
+++ b/include/drawinglayer/primitive2d/BufferedDecompositionGroupPrimitive2D.hxx
@@ -21,6 +21,7 @@
#include <drawinglayer/drawinglayerdllapi.h>
#include <drawinglayer/primitive2d/groupprimitive2d.hxx>
+#include <salhelper/timer.hxx>
namespace drawinglayer::primitive2d
{
@@ -35,25 +36,32 @@ namespace drawinglayer::primitive2d
class DRAWINGLAYER_DLLPUBLIC BufferedDecompositionGroupPrimitive2D : public GroupPrimitive2D
{
private:
+ // exclusive helper for Primitive2DFlusher
+ friend void flushBufferedDecomposition(BufferedDecompositionGroupPrimitive2D&);
+
/// a sequence used for buffering the last create2DDecomposition() result
Primitive2DContainer maBuffered2DDecomposition;
+ /// offer callback mechanism to flush buffered content timer-based
+ ::rtl::Reference<::salhelper::Timer> maCallbackTimer;
+ sal_uInt16 maCallbackSeconds;
+
protected:
/// identical to BufferedDecompositionPrimitive2D, see there please
- const Primitive2DContainer& getBuffered2DDecomposition() const
- {
- return maBuffered2DDecomposition;
- }
- void setBuffered2DDecomposition(Primitive2DContainer&& rNew)
- {
- maBuffered2DDecomposition = std::move(rNew);
- }
+ const Primitive2DContainer& getBuffered2DDecomposition() const;
+ void setBuffered2DDecomposition(Primitive2DContainer&& rNew);
/// method which is to be used to implement the local decomposition of a 2D group primitive.
virtual void
create2DDecomposition(Primitive2DContainer& rContainer,
const geometry::ViewInformation2D& rViewInformation) const = 0;
+ // when changing from null (which is inactive) to a count of seconds, the
+ // callback mechanism to flush buffered content timer-based will be activated.
+ // it is protected since the idea is that this gets called in the constructor
+ // of derived classes.
+ void setCallbackSeconds(sal_uInt16 nNew) { maCallbackSeconds = nNew; }
+
public:
/// constructor/destructor. For GroupPrimitive2D we need the child parameter, too.
BufferedDecompositionGroupPrimitive2D(Primitive2DContainer&& aChildren);
diff --git a/include/drawinglayer/primitive2d/BufferedDecompositionPrimitive2D.hxx b/include/drawinglayer/primitive2d/BufferedDecompositionPrimitive2D.hxx
index 8087a6544dc0..68d40e006a6f 100644
--- a/include/drawinglayer/primitive2d/BufferedDecompositionPrimitive2D.hxx
+++ b/include/drawinglayer/primitive2d/BufferedDecompositionPrimitive2D.hxx
@@ -22,6 +22,7 @@
#include <drawinglayer/drawinglayerdllapi.h>
#include <drawinglayer/primitive2d/Primitive2DContainer.hxx>
#include <drawinglayer/primitive2d/baseprimitive2d.hxx>
+#include <salhelper/timer.hxx>
namespace drawinglayer::geometry
{
@@ -62,35 +63,43 @@ namespace drawinglayer::primitive2d
class DRAWINGLAYERCORE_DLLPUBLIC BufferedDecompositionPrimitive2D : public BasePrimitive2D
{
private:
+ // exclusive helper for Primitive2DFlusher
+ friend void flushBufferedDecomposition(BufferedDecompositionPrimitive2D&);
+
/// a sequence used for buffering the last create2DDecomposition() result
Primitive2DContainer maBuffered2DDecomposition;
+ /// offer callback mechanism to flush buffered content timer-based
+ ::rtl::Reference<::salhelper::Timer> maCallbackTimer;
+ sal_uInt16 maCallbackSeconds;
+
/// When a shadow wraps a list of primitives, this primitive wants to influence the transparency
/// of the shadow.
- sal_uInt16 mnTransparenceForShadow = 0;
+ sal_uInt16 mnTransparenceForShadow;
protected:
/** access methods to maBuffered2DDecomposition. The usage of this methods may allow
later thread-safe stuff to be added if needed. Only to be used by getDecomposition()
implementations for buffering the last decomposition.
*/
- const Primitive2DContainer& getBuffered2DDecomposition() const
- {
- return maBuffered2DDecomposition;
- }
- void setBuffered2DDecomposition(Primitive2DContainer&& rNew)
- {
- maBuffered2DDecomposition = std::move(rNew);
- }
+ const Primitive2DContainer& getBuffered2DDecomposition() const;
+ void setBuffered2DDecomposition(Primitive2DContainer&& rNew);
/** method which is to be used to implement the local decomposition of a 2D primitive. */
virtual void
create2DDecomposition(Primitive2DContainer& rContainer,
const geometry::ViewInformation2D& rViewInformation) const = 0;
+ // when changing from null (which is inactive) to a count of seconds, the
+ // callback mechanism to flush buffered content timer-based will be activated.
+ // it is protected since the idea is that this gets called in the constructor
+ // of derived classes.
+ void setCallbackSeconds(sal_uInt16 nNew) { maCallbackSeconds = nNew; }
+
public:
// constructor/destructor
BufferedDecompositionPrimitive2D();
+ virtual ~BufferedDecompositionPrimitive2D();
/** The getDecomposition default implementation will on demand use create2DDecomposition() if
maBuffered2DDecomposition is empty. It will set maBuffered2DDecomposition to this obtained decomposition