drawinglayer/source/primitive2d/BufferedDecompositionPrimitive2D.cxx | 22 +++++----- drawinglayer/source/primitive2d/backgroundcolorprimitive2d.cxx | 4 - drawinglayer/source/primitive2d/controlprimitive2d.cxx | 4 - drawinglayer/source/primitive2d/gridprimitive2d.cxx | 4 - drawinglayer/source/primitive2d/helplineprimitive2d.cxx | 4 - drawinglayer/source/primitive2d/polygonprimitive2d.cxx | 4 - drawinglayer/source/primitive2d/primitivetools2d.cxx | 18 ++++---- drawinglayer/source/primitive2d/sceneprimitive2d.cxx | 4 - drawinglayer/source/primitive2d/texteffectprimitive2d.cxx | 4 - include/drawinglayer/primitive2d/BufferedDecompositionPrimitive2D.hxx | 2 svx/source/sdr/primitive2d/sdrdecompositiontools.cxx | 4 - svx/source/sdr/primitive2d/sdrframeborderprimitive2d.cxx | 2 svx/source/sdr/primitive2d/sdrtextprimitive2d.cxx | 4 - 13 files changed, 42 insertions(+), 38 deletions(-)
New commits: commit 303e5631f8119ef69c8ff515e7e47d4cf6ab74c6 Author: Noel Grandin <noel.gran...@collabora.co.uk> AuthorDate: Fri Mar 14 11:50:51 2025 +0200 Commit: Noel Grandin <noel.gran...@collabora.co.uk> CommitDate: Fri Mar 14 12:47:18 2025 +0100 use mutex before touching maBuffered2DDecomposition (tdf#131595 related) Otherwise we could be reading stale data. And change it to return a bool, the call-sites only care if we have/dont-have the data, and returning a value of a field that should only be accessed under a lock is dodgy. And move the the setRemainingTime call to get2DDecomposition(), because that where we really "use" the data ie. paint with it. Change-Id: I44b5d41fee68985213ecc7d11b4ce1bdcfd119b3 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/182909 Tested-by: Jenkins Reviewed-by: Noel Grandin <noel.gran...@collabora.co.uk> diff --git a/drawinglayer/source/primitive2d/BufferedDecompositionPrimitive2D.cxx b/drawinglayer/source/primitive2d/BufferedDecompositionPrimitive2D.cxx index ba8a4606cc83..b04905744b50 100644 --- a/drawinglayer/source/primitive2d/BufferedDecompositionPrimitive2D.cxx +++ b/drawinglayer/source/primitive2d/BufferedDecompositionPrimitive2D.cxx @@ -58,15 +58,15 @@ void flushBufferedDecomposition(BufferedDecompositionPrimitive2D& rTarget) rTarget.release(); } -const Primitive2DReference& BufferedDecompositionPrimitive2D::getBuffered2DDecomposition() const +bool BufferedDecompositionPrimitive2D::hasBuffered2DDecomposition() const { - if (0 != maCallbackSeconds && maCallbackTimer.is()) + if (0 != maCallbackSeconds) { - // decomposition was used, touch/restart time - maCallbackTimer->setRemainingTime(salhelper::TTimeValue(maCallbackSeconds, 0)); + std::lock_guard Guard(maCallbackLock); + return maBuffered2DDecomposition.is(); } - - return maBuffered2DDecomposition; + else + return maBuffered2DDecomposition.is(); } void BufferedDecompositionPrimitive2D::setBuffered2DDecomposition(Primitive2DReference rNew) @@ -128,7 +128,7 @@ void BufferedDecompositionPrimitive2D::get2DDecomposition( Primitive2DDecompositionVisitor& rVisitor, const geometry::ViewInformation2D& rViewInformation) const { - if (!getBuffered2DDecomposition()) + if (!hasBuffered2DDecomposition()) { Primitive2DReference aNew = create2DDecomposition(rViewInformation); const_cast<BufferedDecompositionPrimitive2D*>(this)->setBuffered2DDecomposition( @@ -138,15 +138,19 @@ void BufferedDecompositionPrimitive2D::get2DDecomposition( if (0 == maCallbackSeconds) { // no flush/multithreading is in use, just call - rVisitor.visit(getBuffered2DDecomposition()); + 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(getBuffered2DDecomposition()); + rVisitor.visit(maBuffered2DDecomposition); } } // end of namespace drawinglayer::primitive2d diff --git a/drawinglayer/source/primitive2d/backgroundcolorprimitive2d.cxx b/drawinglayer/source/primitive2d/backgroundcolorprimitive2d.cxx index a155e6472e24..7d73cdbee4d1 100644 --- a/drawinglayer/source/primitive2d/backgroundcolorprimitive2d.cxx +++ b/drawinglayer/source/primitive2d/backgroundcolorprimitive2d.cxx @@ -87,13 +87,13 @@ namespace drawinglayer::primitive2d void BackgroundColorPrimitive2D::get2DDecomposition(Primitive2DDecompositionVisitor& rVisitor, const geometry::ViewInformation2D& rViewInformation) const { - if(getBuffered2DDecomposition() && (maLastViewport != rViewInformation.getViewport())) + if(hasBuffered2DDecomposition() && (maLastViewport != rViewInformation.getViewport())) { // conditions of last local decomposition have changed, delete const_cast< BackgroundColorPrimitive2D* >(this)->setBuffered2DDecomposition(nullptr); } - if(!getBuffered2DDecomposition()) + if(!hasBuffered2DDecomposition()) { // remember ViewRange const_cast< BackgroundColorPrimitive2D* >(this)->maLastViewport = rViewInformation.getViewport(); diff --git a/drawinglayer/source/primitive2d/controlprimitive2d.cxx b/drawinglayer/source/primitive2d/controlprimitive2d.cxx index eb8759bb2169..81af256a88bb 100644 --- a/drawinglayer/source/primitive2d/controlprimitive2d.cxx +++ b/drawinglayer/source/primitive2d/controlprimitive2d.cxx @@ -333,7 +333,7 @@ namespace drawinglayer::primitive2d // destroy existing decomposition. To detect change, use size of unit size in view coordinates const basegfx::B2DVector aNewScaling(rViewInformation.getObjectToViewTransformation() * basegfx::B2DVector(1.0, 1.0)); - if(getBuffered2DDecomposition()) + if(hasBuffered2DDecomposition()) { if(!maLastViewScaling.equal(aNewScaling)) { @@ -342,7 +342,7 @@ namespace drawinglayer::primitive2d } } - if(!getBuffered2DDecomposition()) + if(!hasBuffered2DDecomposition()) { // remember ViewTransformation const_cast< ControlPrimitive2D* >(this)->maLastViewScaling = aNewScaling; diff --git a/drawinglayer/source/primitive2d/gridprimitive2d.cxx b/drawinglayer/source/primitive2d/gridprimitive2d.cxx index 1a996188f03c..80bc56e2250c 100644 --- a/drawinglayer/source/primitive2d/gridprimitive2d.cxx +++ b/drawinglayer/source/primitive2d/gridprimitive2d.cxx @@ -309,7 +309,7 @@ namespace drawinglayer::primitive2d void GridPrimitive2D::get2DDecomposition(Primitive2DDecompositionVisitor& rVisitor, const geometry::ViewInformation2D& rViewInformation) const { - if(getBuffered2DDecomposition()) + if(hasBuffered2DDecomposition()) { if(maLastViewport != rViewInformation.getViewport() || maLastObjectToViewTransformation != rViewInformation.getObjectToViewTransformation()) { @@ -318,7 +318,7 @@ namespace drawinglayer::primitive2d } } - if(!getBuffered2DDecomposition()) + if(!hasBuffered2DDecomposition()) { // remember ViewRange and ViewTransformation const_cast< GridPrimitive2D* >(this)->maLastObjectToViewTransformation = rViewInformation.getObjectToViewTransformation(); diff --git a/drawinglayer/source/primitive2d/helplineprimitive2d.cxx b/drawinglayer/source/primitive2d/helplineprimitive2d.cxx index 047084eb1469..e09c4db606d0 100644 --- a/drawinglayer/source/primitive2d/helplineprimitive2d.cxx +++ b/drawinglayer/source/primitive2d/helplineprimitive2d.cxx @@ -159,7 +159,7 @@ namespace drawinglayer::primitive2d void HelplinePrimitive2D::get2DDecomposition(Primitive2DDecompositionVisitor& rVisitor, const geometry::ViewInformation2D& rViewInformation) const { - if(getBuffered2DDecomposition()) + if(hasBuffered2DDecomposition()) { if(maLastViewport != rViewInformation.getViewport() || maLastObjectToViewTransformation != rViewInformation.getObjectToViewTransformation()) { @@ -168,7 +168,7 @@ namespace drawinglayer::primitive2d } } - if(!getBuffered2DDecomposition()) + if(!hasBuffered2DDecomposition()) { // remember ViewRange and ViewTransformation const_cast< HelplinePrimitive2D* >(this)->maLastObjectToViewTransformation = rViewInformation.getObjectToViewTransformation(); diff --git a/drawinglayer/source/primitive2d/polygonprimitive2d.cxx b/drawinglayer/source/primitive2d/polygonprimitive2d.cxx index 77800ed45417..329911541d4e 100644 --- a/drawinglayer/source/primitive2d/polygonprimitive2d.cxx +++ b/drawinglayer/source/primitive2d/polygonprimitive2d.cxx @@ -298,7 +298,7 @@ void PolygonMarkerPrimitive2D::get2DDecomposition( { bool bNeedNewDecomposition(false); - if (getBuffered2DDecomposition()) + if (hasBuffered2DDecomposition()) { if (rViewInformation.getInverseObjectToViewTransformation() != maLastInverseObjectToViewTransformation) @@ -313,7 +313,7 @@ void PolygonMarkerPrimitive2D::get2DDecomposition( const_cast<PolygonMarkerPrimitive2D*>(this)->setBuffered2DDecomposition(nullptr); } - if (!getBuffered2DDecomposition()) + if (!hasBuffered2DDecomposition()) { // remember last used InverseObjectToViewTransformation PolygonMarkerPrimitive2D* pThat = const_cast<PolygonMarkerPrimitive2D*>(this); diff --git a/drawinglayer/source/primitive2d/primitivetools2d.cxx b/drawinglayer/source/primitive2d/primitivetools2d.cxx index 04a91fe9b55b..cf98fd9b26c0 100644 --- a/drawinglayer/source/primitive2d/primitivetools2d.cxx +++ b/drawinglayer/source/primitive2d/primitivetools2d.cxx @@ -30,13 +30,13 @@ namespace drawinglayer::primitive2d const basegfx::B2DVector aDiscreteVector(rViewInformation.getInverseObjectToViewTransformation() * basegfx::B2DVector(1.0, 1.0)); const double fDiscreteUnit(std::min(fabs(aDiscreteVector.getX()), fabs(aDiscreteVector.getY()))); - if(getBuffered2DDecomposition() && !basegfx::fTools::equal(fDiscreteUnit, getDiscreteUnit())) + if(hasBuffered2DDecomposition() && !basegfx::fTools::equal(fDiscreteUnit, getDiscreteUnit())) { // conditions of last local decomposition have changed, delete const_cast< DiscreteMetricDependentPrimitive2D* >(this)->setBuffered2DDecomposition(nullptr); } - if(!getBuffered2DDecomposition()) + if(!hasBuffered2DDecomposition()) { // remember new valid DiscreteUnit const_cast< DiscreteMetricDependentPrimitive2D* >(this)->mfDiscreteUnit = fDiscreteUnit; @@ -54,13 +54,13 @@ namespace drawinglayer::primitive2d // get the current Viewport const basegfx::B2DRange& rViewport = rViewInformation.getViewport(); - if(getBuffered2DDecomposition() && !rViewport.equal(getViewport())) + if(hasBuffered2DDecomposition() && !rViewport.equal(getViewport())) { // conditions of last local decomposition have changed, delete const_cast< ViewportDependentPrimitive2D* >(this)->setBuffered2DDecomposition(nullptr); } - if(!getBuffered2DDecomposition()) + if(!hasBuffered2DDecomposition()) { // remember new valid DiscreteUnit const_cast< ViewportDependentPrimitive2D* >(this)->maViewport = rViewport; @@ -75,13 +75,13 @@ namespace drawinglayer::primitive2d // get the current ViewTransformation const basegfx::B2DHomMatrix& rViewTransformation = rViewInformation.getViewTransformation(); - if(getBuffered2DDecomposition() && rViewTransformation != getViewTransformation()) + if(hasBuffered2DDecomposition() && rViewTransformation != getViewTransformation()) { // conditions of last local decomposition have changed, delete const_cast< ViewTransformationDependentPrimitive2D* >(this)->setBuffered2DDecomposition(nullptr); } - if(!getBuffered2DDecomposition()) + if(!hasBuffered2DDecomposition()) { // remember new valid ViewTransformation const_cast< ViewTransformationDependentPrimitive2D* >(this)->maViewTransformation = rViewTransformation; @@ -96,7 +96,7 @@ namespace drawinglayer::primitive2d // get the current ViewTransformation const basegfx::B2DHomMatrix& rViewTransformation = rViewInformation.getViewTransformation(); - if(getBuffered2DDecomposition() && rViewTransformation != getViewTransformation()) + if(hasBuffered2DDecomposition() && rViewTransformation != getViewTransformation()) { // conditions of last local decomposition have changed, delete const_cast< ObjectAndViewTransformationDependentPrimitive2D* >(this)->setBuffered2DDecomposition(nullptr); @@ -105,13 +105,13 @@ namespace drawinglayer::primitive2d // get the current ObjectTransformation const basegfx::B2DHomMatrix& rObjectTransformation = rViewInformation.getObjectTransformation(); - if(getBuffered2DDecomposition() && rObjectTransformation != getObjectTransformation()) + if(hasBuffered2DDecomposition() && rObjectTransformation != getObjectTransformation()) { // conditions of last local decomposition have changed, delete const_cast< ObjectAndViewTransformationDependentPrimitive2D* >(this)->setBuffered2DDecomposition(nullptr); } - if(!getBuffered2DDecomposition()) + if(!hasBuffered2DDecomposition()) { // remember new valid ViewTransformation, and ObjectTransformation const_cast< ObjectAndViewTransformationDependentPrimitive2D* >(this)->maViewTransformation = rViewTransformation; diff --git a/drawinglayer/source/primitive2d/sceneprimitive2d.cxx b/drawinglayer/source/primitive2d/sceneprimitive2d.cxx index 11807e459b7f..5300e8d82e05 100644 --- a/drawinglayer/source/primitive2d/sceneprimitive2d.cxx +++ b/drawinglayer/source/primitive2d/sceneprimitive2d.cxx @@ -687,7 +687,7 @@ namespace drawinglayer::primitive2d bool bNeedNewDecomposition(false); bool bDiscreteSizesAreCalculated(false); - if(getBuffered2DDecomposition()) + if(hasBuffered2DDecomposition()) { basegfx::B2DRange aVisibleDiscreteRange; calculateDiscreteSizes(rViewInformation, aDiscreteRange, aVisibleDiscreteRange, aUnitVisibleRange); @@ -718,7 +718,7 @@ namespace drawinglayer::primitive2d const_cast< ScenePrimitive2D* >(this)->setBuffered2DDecomposition(nullptr); } - if(!getBuffered2DDecomposition()) + if(!hasBuffered2DDecomposition()) { if(!bDiscreteSizesAreCalculated) { diff --git a/drawinglayer/source/primitive2d/texteffectprimitive2d.cxx b/drawinglayer/source/primitive2d/texteffectprimitive2d.cxx index bd123d34315d..e1893ec0fd38 100644 --- a/drawinglayer/source/primitive2d/texteffectprimitive2d.cxx +++ b/drawinglayer/source/primitive2d/texteffectprimitive2d.cxx @@ -214,7 +214,7 @@ void TextEffectPrimitive2D::get2DDecomposition( Primitive2DDecompositionVisitor& rVisitor, const geometry::ViewInformation2D& rViewInformation) const { - if (getBuffered2DDecomposition()) + if (hasBuffered2DDecomposition()) { if (maLastObjectToViewTransformation != rViewInformation.getObjectToViewTransformation()) { @@ -223,7 +223,7 @@ void TextEffectPrimitive2D::get2DDecomposition( } } - if (!getBuffered2DDecomposition()) + if (!hasBuffered2DDecomposition()) { // remember ViewRange and ViewTransformation const_cast<TextEffectPrimitive2D*>(this)->maLastObjectToViewTransformation diff --git a/include/drawinglayer/primitive2d/BufferedDecompositionPrimitive2D.hxx b/include/drawinglayer/primitive2d/BufferedDecompositionPrimitive2D.hxx index 427c6d4c19f7..3fbfb1e1e00c 100644 --- a/include/drawinglayer/primitive2d/BufferedDecompositionPrimitive2D.hxx +++ b/include/drawinglayer/primitive2d/BufferedDecompositionPrimitive2D.hxx @@ -79,7 +79,7 @@ protected: later thread-safe stuff to be added if needed. Only to be used by getDecomposition() implementations for buffering the last decomposition. */ - const Primitive2DReference& getBuffered2DDecomposition() const; + bool hasBuffered2DDecomposition() const; void setBuffered2DDecomposition(Primitive2DReference rNew); /** method which is to be used to implement the local decomposition of a 2D primitive. */ diff --git a/svx/source/sdr/primitive2d/sdrdecompositiontools.cxx b/svx/source/sdr/primitive2d/sdrdecompositiontools.cxx index 617dcba30631..78daae6c4c5e 100644 --- a/svx/source/sdr/primitive2d/sdrdecompositiontools.cxx +++ b/svx/source/sdr/primitive2d/sdrdecompositiontools.cxx @@ -322,7 +322,7 @@ void SlideBackgroundFillPrimitive2D::get2DDecomposition( basegfx::B2DVector aPageSize; drawinglayer::attribute::SdrFillAttribute aFill; - if(getBuffered2DDecomposition()) + if(hasBuffered2DDecomposition()) { aFill = getMasterPageFillAttribute(rViewInformation, aPageSize); @@ -333,7 +333,7 @@ void SlideBackgroundFillPrimitive2D::get2DDecomposition( } } - if(!getBuffered2DDecomposition()) + if(!hasBuffered2DDecomposition()) { // remember last Fill const_cast< SlideBackgroundFillPrimitive2D* >(this)->maLastFill = std::move(aFill); diff --git a/svx/source/sdr/primitive2d/sdrframeborderprimitive2d.cxx b/svx/source/sdr/primitive2d/sdrframeborderprimitive2d.cxx index 9e34a385ba9e..bdf7b520f025 100644 --- a/svx/source/sdr/primitive2d/sdrframeborderprimitive2d.cxx +++ b/svx/source/sdr/primitive2d/sdrframeborderprimitive2d.cxx @@ -896,7 +896,7 @@ namespace drawinglayer::primitive2d { // conditions of last local decomposition have changed, delete // possible content - if(getBuffered2DDecomposition()) + if(hasBuffered2DDecomposition()) { const_cast< SdrFrameBorderPrimitive2D* >(this)->setBuffered2DDecomposition(nullptr); } diff --git a/svx/source/sdr/primitive2d/sdrtextprimitive2d.cxx b/svx/source/sdr/primitive2d/sdrtextprimitive2d.cxx index 516103aaccfd..cc1e850ccb68 100644 --- a/svx/source/sdr/primitive2d/sdrtextprimitive2d.cxx +++ b/svx/source/sdr/primitive2d/sdrtextprimitive2d.cxx @@ -144,7 +144,7 @@ namespace drawinglayer::primitive2d sal_Int16 nCurrentlyValidPageNumber(0); sal_Int16 nCurrentlyValidPageCount(0); - if(getBuffered2DDecomposition()) + if(hasBuffered2DDecomposition()) { bool bDoDelete(false); @@ -202,7 +202,7 @@ namespace drawinglayer::primitive2d } } - if(!getBuffered2DDecomposition()) + if(!hasBuffered2DDecomposition()) { if(!bCurrentlyVisualizingPageIsSet && mbContainsPageField) {