summaryrefslogtreecommitdiff
path: root/drawinglayer/source/primitive2d/BufferedDecompositionPrimitive2D.cxx
diff options
context:
space:
mode:
authorNoel Grandin <noelgrandin@gmail.com>2025-03-13 18:37:54 +0200
committerNoel Grandin <noel.grandin@collabora.co.uk>2025-03-17 07:15:15 +0100
commit8a17b7f0a679ebf21bcfb425186b205d996d129b (patch)
treeab0b3f405b3a14ba51496b1ffbe6ef7106784883 /drawinglayer/source/primitive2d/BufferedDecompositionPrimitive2D.cxx
parentf382c1a267a93539f3c169530780889336d20b25 (diff)
tdf#131595 Improve drawinglayer flushing mechanism.
Which dramatically speeds up switching between sheets in the referenced document. The problem here is that we have a timer for each buffered primitive. And we have a lot of primitives here. And the TimerManager does not scale well to lots and lots of timer, because it uses a linked list. So this change modifies the flushing mechanism, trading off some precision for some speed. Change-Id: I66a744f06af9b08d4e9b797d11db8d22f4060789 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/182876 Tested-by: Jenkins Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
Diffstat (limited to 'drawinglayer/source/primitive2d/BufferedDecompositionPrimitive2D.cxx')
-rw-r--r--drawinglayer/source/primitive2d/BufferedDecompositionPrimitive2D.cxx131
1 files changed, 37 insertions, 94 deletions
diff --git a/drawinglayer/source/primitive2d/BufferedDecompositionPrimitive2D.cxx b/drawinglayer/source/primitive2d/BufferedDecompositionPrimitive2D.cxx
index b04905744b50..f9e476021e44 100644
--- a/drawinglayer/source/primitive2d/BufferedDecompositionPrimitive2D.cxx
+++ b/drawinglayer/source/primitive2d/BufferedDecompositionPrimitive2D.cxx
@@ -21,136 +21,79 @@
#include <drawinglayer/primitive2d/BufferedDecompositionPrimitive2D.hxx>
#include <drawinglayer/geometry/viewinformation2d.hxx>
-
-namespace
-{
-class LocalCallbackTimer : public salhelper::Timer
-{
-protected:
- drawinglayer::primitive2d::BufferedDecompositionPrimitive2D* pCustomer;
-
-public:
- explicit LocalCallbackTimer(
- drawinglayer::primitive2d::BufferedDecompositionPrimitive2D& rCustomer)
- : pCustomer(&rCustomer)
- {
- }
-
- void clearCallback() { pCustomer = nullptr; }
-
-protected:
- virtual void SAL_CALL onShot() override;
-};
-
-void SAL_CALL LocalCallbackTimer::onShot()
-{
- if (nullptr != pCustomer)
- flushBufferedDecomposition(*pCustomer);
-}
-}
+#include <drawinglayer/primitive2d/BufferedDecompositionFlusher.hxx>
namespace drawinglayer::primitive2d
{
-void flushBufferedDecomposition(BufferedDecompositionPrimitive2D& rTarget)
-{
- rTarget.acquire();
- rTarget.setBuffered2DDecomposition(nullptr);
- rTarget.release();
-}
-
bool BufferedDecompositionPrimitive2D::hasBuffered2DDecomposition() const
{
- if (0 != maCallbackSeconds)
+ if (!mbFlushOnTimer)
+ return maBuffered2DDecomposition.is();
+ else
{
std::lock_guard Guard(maCallbackLock);
return maBuffered2DDecomposition.is();
}
- else
- return maBuffered2DDecomposition.is();
}
void BufferedDecompositionPrimitive2D::setBuffered2DDecomposition(Primitive2DReference rNew)
{
- if (0 == maCallbackSeconds)
+ if (!mbFlushOnTimer)
{
// no flush used, just set
maBuffered2DDecomposition = std::move(rNew);
- return;
}
-
- if (maCallbackTimer.is())
- {
- if (!rNew)
- {
- // stop timer
- maCallbackTimer->stop();
- }
- else
- {
- // decomposition changed, touch
- maCallbackTimer->setRemainingTime(salhelper::TTimeValue(maCallbackSeconds, 0));
- if (!maCallbackTimer->isTicking())
- maCallbackTimer->start();
- }
- }
- else if (rNew)
+ else
{
- // decomposition defined/set/changed, init & start timer
- maCallbackTimer.set(new LocalCallbackTimer(*this));
- maCallbackTimer->setRemainingTime(salhelper::TTimeValue(maCallbackSeconds, 0));
- maCallbackTimer->start();
- }
+ // decomposition changed, touch
+ maLastAccess = std::chrono::steady_clock::now();
+ BufferedDecompositionFlusher::update(this);
- // tdf#158913 need to secure change when flush/multithreading is in use
- std::lock_guard Guard(maCallbackLock);
- maBuffered2DDecomposition = std::move(rNew);
+ // tdf#158913 need to secure change when flush/multithreading is in use
+ std::lock_guard Guard(maCallbackLock);
+ maBuffered2DDecomposition = std::move(rNew);
+ }
}
BufferedDecompositionPrimitive2D::BufferedDecompositionPrimitive2D()
: maBuffered2DDecomposition()
- , maCallbackTimer()
, maCallbackLock()
- , maCallbackSeconds(0)
+ , mbFlushOnTimer(false)
{
}
-BufferedDecompositionPrimitive2D::~BufferedDecompositionPrimitive2D()
-{
- if (maCallbackTimer.is())
- {
- // no more decomposition, end callback
- static_cast<LocalCallbackTimer*>(maCallbackTimer.get())->clearCallback();
- maCallbackTimer->stop();
- }
-}
+BufferedDecompositionPrimitive2D::~BufferedDecompositionPrimitive2D() {}
void BufferedDecompositionPrimitive2D::get2DDecomposition(
Primitive2DDecompositionVisitor& rVisitor,
const geometry::ViewInformation2D& rViewInformation) const
{
- if (!hasBuffered2DDecomposition())
- {
- Primitive2DReference aNew = create2DDecomposition(rViewInformation);
- const_cast<BufferedDecompositionPrimitive2D*>(this)->setBuffered2DDecomposition(
- std::move(aNew));
- }
-
- if (0 == maCallbackSeconds)
+ if (!mbFlushOnTimer)
{
// no flush/multithreading is in use, just call
+ if (!maBuffered2DDecomposition)
+ maBuffered2DDecomposition = create2DDecomposition(rViewInformation);
rVisitor.visit(maBuffered2DDecomposition);
- return;
}
-
- // decomposition was used, touch/restart time
- if (maCallbackTimer)
- maCallbackTimer->setRemainingTime(salhelper::TTimeValue(maCallbackSeconds, 0));
-
- // tdf#158913 need to secure 'visit' when flush/multithreading is in use,
- // so that the local non-ref-Counted instance of the decomposition gets not
- // manipulated (e.g. deleted)
- std::lock_guard Guard(maCallbackLock);
- rVisitor.visit(maBuffered2DDecomposition);
+ else
+ {
+ // tdf#158913 need to secure 'visit' when flush/multithreading is in use,
+ // so that the local non-ref-Counted instance of the decomposition gets not
+ // manipulated (e.g. deleted)
+ Primitive2DReference xTmp;
+ {
+ // only hold the lock for long enough to get a valid reference
+ std::lock_guard Guard(maCallbackLock);
+ maLastAccess = std::chrono::steady_clock::now();
+ if (!maBuffered2DDecomposition)
+ {
+ maBuffered2DDecomposition = create2DDecomposition(rViewInformation);
+ BufferedDecompositionFlusher::update(this);
+ }
+ xTmp = maBuffered2DDecomposition;
+ }
+ rVisitor.visit(xTmp);
+ }
}
} // end of namespace drawinglayer::primitive2d