From 19d638eaedf84cefadf55d561c3c36df33fed6fe Mon Sep 17 00:00:00 2001 From: Noel Grandin Date: Tue, 21 Sep 2021 10:01:03 +0200 Subject: [PATCH] reduce cost of BasePrimitive2D (tdf#125892) the default WeakComponentImplHelper wants to allocate two child objects (osl::Mutex and BroadcastHelper). So use a custom re-implemenation that does not need to allocate any child objects. Change-Id: I288e58558398e39daa0d4b11e0b60a924445240d Reviewed-on: https://gerrit.libreoffice.org/c/core/+/122381 Tested-by: Jenkins Reviewed-by: Noel Grandin --- .../BufferedDecompositionPrimitive2D.cxx | 2 +- .../backgroundcolorprimitive2d.cxx | 2 +- .../source/primitive2d/baseprimitive2d.cxx | 66 +++++++++++++++++-- .../source/primitive2d/controlprimitive2d.cxx | 2 +- .../primitive2d/embedded3dprimitive2d.cxx | 2 +- .../primitive2d/fillhatchprimitive2d.cxx | 2 +- .../source/primitive2d/gridprimitive2d.cxx | 2 +- .../primitive2d/helplineprimitive2d.cxx | 2 +- .../source/primitive2d/polygonprimitive2d.cxx | 2 +- .../source/primitive2d/primitivetools2d.cxx | 8 +-- .../source/primitive2d/sceneprimitive2d.cxx | 4 +- .../primitive2d/texteffectprimitive2d.cxx | 2 +- .../primitive2d/baseprimitive2d.hxx | 41 ++++++++++-- 13 files changed, 113 insertions(+), 24 deletions(-) diff --git a/drawinglayer/source/primitive2d/BufferedDecompositionPrimitive2D.cxx b/drawinglayer/source/primitive2d/BufferedDecompositionPrimitive2D.cxx index 896f85d81f1e..301d501e6e32 100644 --- a/drawinglayer/source/primitive2d/BufferedDecompositionPrimitive2D.cxx +++ b/drawinglayer/source/primitive2d/BufferedDecompositionPrimitive2D.cxx @@ -33,7 +33,7 @@ void BufferedDecompositionPrimitive2D::get2DDecomposition( Primitive2DDecompositionVisitor& rVisitor, const geometry::ViewInformation2D& rViewInformation) const { - ::osl::MutexGuard aGuard(m_aMutex); + std::unique_lock aGuard(m_aMutex); if (getBuffered2DDecomposition().empty()) { diff --git a/drawinglayer/source/primitive2d/backgroundcolorprimitive2d.cxx b/drawinglayer/source/primitive2d/backgroundcolorprimitive2d.cxx index 90ff831da005..f13b92bc4ddb 100644 --- a/drawinglayer/source/primitive2d/backgroundcolorprimitive2d.cxx +++ b/drawinglayer/source/primitive2d/backgroundcolorprimitive2d.cxx @@ -67,7 +67,7 @@ namespace drawinglayer::primitive2d void BackgroundColorPrimitive2D::get2DDecomposition(Primitive2DDecompositionVisitor& rVisitor, const geometry::ViewInformation2D& rViewInformation) const { - ::osl::MutexGuard aGuard( m_aMutex ); + std::unique_lock aGuard( m_aMutex ); if(!getBuffered2DDecomposition().empty() && (maLastViewport != rViewInformation.getViewport())) { diff --git a/drawinglayer/source/primitive2d/baseprimitive2d.cxx b/drawinglayer/source/primitive2d/baseprimitive2d.cxx index 61cd0923ad3d..71a13346beff 100644 --- a/drawinglayer/source/primitive2d/baseprimitive2d.cxx +++ b/drawinglayer/source/primitive2d/baseprimitive2d.cxx @@ -24,15 +24,73 @@ #include #include #include +#include using namespace css; +BasePrimitive2DImplBase::~BasePrimitive2DImplBase() {} + +css::uno::Any BasePrimitive2DImplBase::queryInterface(css::uno::Type const& rType) +{ + css::uno::Any aReturn = ::cppu::queryInterface( + rType, static_cast(this), static_cast(this), + static_cast(this), static_cast(this), + static_cast(this)); + if (aReturn.hasValue()) + return aReturn; + return OWeakObject::queryInterface(rType); +} + +void BasePrimitive2DImplBase::acquire() noexcept { OWeakObject::acquire(); } + +void BasePrimitive2DImplBase::release() noexcept +{ + if (osl_atomic_decrement(&m_refCount) != 0) + return; + + // ensure no other references are created, via the weak connection point, from now on + disposeWeakConnectionPoint(); + // restore reference count: + osl_atomic_increment(&m_refCount); + // if (! rBHelper.bDisposed) { + // try { + // dispose(); + // } + // catch (RuntimeException const& exc) { // don't break throw () + // SAL_WARN( "cppuhelper", exc ); + // } + // OSL_ASSERT( rBHelper.bDisposed ); + // } + OWeakObject::release(); +} + +void BasePrimitive2DImplBase::dispose() {} + +void BasePrimitive2DImplBase::addEventListener( + css::uno::Reference const&) +{ + assert(false); +} +void BasePrimitive2DImplBase::removeEventListener( + css::uno::Reference const&) +{ + assert(false); +} + +css::uno::Sequence BasePrimitive2DImplBase::getTypes() +{ + static const css::uno::Sequence aTypeList{ + cppu::UnoType::get(), cppu::UnoType::get(), + cppu::UnoType::get(), cppu::UnoType::get(), + cppu::UnoType::get() + }; + + return aTypeList; +} + namespace drawinglayer::primitive2d { -BasePrimitive2D::BasePrimitive2D() - : BasePrimitive2DImplBase(m_aMutex) -{ -} +BasePrimitive2D::BasePrimitive2D() {} BasePrimitive2D::~BasePrimitive2D() {} diff --git a/drawinglayer/source/primitive2d/controlprimitive2d.cxx b/drawinglayer/source/primitive2d/controlprimitive2d.cxx index c5ece360e5e8..92f0ed5cf464 100644 --- a/drawinglayer/source/primitive2d/controlprimitive2d.cxx +++ b/drawinglayer/source/primitive2d/controlprimitive2d.cxx @@ -317,7 +317,7 @@ namespace drawinglayer::primitive2d { // this primitive is view-dependent related to the scaling. If scaling has changed, // destroy existing decomposition. To detect change, use size of unit size in view coordinates - ::osl::MutexGuard aGuard( m_aMutex ); + std::unique_lock aGuard( m_aMutex ); const basegfx::B2DVector aNewScaling(rViewInformation.getObjectToViewTransformation() * basegfx::B2DVector(1.0, 1.0)); if(!getBuffered2DDecomposition().empty()) diff --git a/drawinglayer/source/primitive2d/embedded3dprimitive2d.cxx b/drawinglayer/source/primitive2d/embedded3dprimitive2d.cxx index fd2510915811..0b217adf6b49 100644 --- a/drawinglayer/source/primitive2d/embedded3dprimitive2d.cxx +++ b/drawinglayer/source/primitive2d/embedded3dprimitive2d.cxx @@ -35,7 +35,7 @@ namespace drawinglayer::primitive2d { bool Embedded3DPrimitive2D::impGetShadow3D() const { - osl::MutexGuard aGuard( m_aMutex ); + std::unique_lock aGuard( m_aMutex ); // create on demand if(!mbShadow3DChecked && !getChildren3D().empty()) diff --git a/drawinglayer/source/primitive2d/fillhatchprimitive2d.cxx b/drawinglayer/source/primitive2d/fillhatchprimitive2d.cxx index d527b9cf2539..666f5459ed39 100644 --- a/drawinglayer/source/primitive2d/fillhatchprimitive2d.cxx +++ b/drawinglayer/source/primitive2d/fillhatchprimitive2d.cxx @@ -173,7 +173,7 @@ namespace drawinglayer::primitive2d void FillHatchPrimitive2D::get2DDecomposition(Primitive2DDecompositionVisitor& rVisitor, const geometry::ViewInformation2D& rViewInformation) const { - ::osl::MutexGuard aGuard( m_aMutex ); + std::unique_lock aGuard( m_aMutex ); bool bAdaptDistance(0 != getFillHatch().getMinimalDiscreteDistance()); if(bAdaptDistance) diff --git a/drawinglayer/source/primitive2d/gridprimitive2d.cxx b/drawinglayer/source/primitive2d/gridprimitive2d.cxx index a43e8af9fb71..64816b076862 100644 --- a/drawinglayer/source/primitive2d/gridprimitive2d.cxx +++ b/drawinglayer/source/primitive2d/gridprimitive2d.cxx @@ -305,7 +305,7 @@ namespace drawinglayer::primitive2d void GridPrimitive2D::get2DDecomposition(Primitive2DDecompositionVisitor& rVisitor, const geometry::ViewInformation2D& rViewInformation) const { - ::osl::MutexGuard aGuard( m_aMutex ); + std::unique_lock aGuard( m_aMutex ); if(!getBuffered2DDecomposition().empty()) { diff --git a/drawinglayer/source/primitive2d/helplineprimitive2d.cxx b/drawinglayer/source/primitive2d/helplineprimitive2d.cxx index 71b372d36164..0db4f37470c2 100644 --- a/drawinglayer/source/primitive2d/helplineprimitive2d.cxx +++ b/drawinglayer/source/primitive2d/helplineprimitive2d.cxx @@ -155,7 +155,7 @@ namespace drawinglayer::primitive2d void HelplinePrimitive2D::get2DDecomposition(Primitive2DDecompositionVisitor& rVisitor, const geometry::ViewInformation2D& rViewInformation) const { - ::osl::MutexGuard aGuard( m_aMutex ); + std::unique_lock aGuard( m_aMutex ); if(!getBuffered2DDecomposition().empty()) { diff --git a/drawinglayer/source/primitive2d/polygonprimitive2d.cxx b/drawinglayer/source/primitive2d/polygonprimitive2d.cxx index 9919658940e1..184f72fdb810 100644 --- a/drawinglayer/source/primitive2d/polygonprimitive2d.cxx +++ b/drawinglayer/source/primitive2d/polygonprimitive2d.cxx @@ -165,7 +165,7 @@ void PolygonMarkerPrimitive2D::get2DDecomposition( Primitive2DDecompositionVisitor& rVisitor, const geometry::ViewInformation2D& rViewInformation) const { - ::osl::MutexGuard aGuard(m_aMutex); + std::unique_lock aGuard(m_aMutex); bool bNeedNewDecomposition(false); if (!getBuffered2DDecomposition().empty()) diff --git a/drawinglayer/source/primitive2d/primitivetools2d.cxx b/drawinglayer/source/primitive2d/primitivetools2d.cxx index da0a378a0089..61e060e5ecfa 100644 --- a/drawinglayer/source/primitive2d/primitivetools2d.cxx +++ b/drawinglayer/source/primitive2d/primitivetools2d.cxx @@ -26,7 +26,7 @@ namespace drawinglayer::primitive2d { void DiscreteMetricDependentPrimitive2D::get2DDecomposition(Primitive2DDecompositionVisitor& rVisitor, const geometry::ViewInformation2D& rViewInformation) const { - ::osl::MutexGuard aGuard( m_aMutex ); + std::unique_lock aGuard( m_aMutex ); // get the current DiscreteUnit, look at X and Y and use the maximum const basegfx::B2DVector aDiscreteVector(rViewInformation.getInverseObjectToViewTransformation() * basegfx::B2DVector(1.0, 1.0)); @@ -53,7 +53,7 @@ namespace drawinglayer::primitive2d void ViewportDependentPrimitive2D::get2DDecomposition(Primitive2DDecompositionVisitor& rVisitor, const geometry::ViewInformation2D& rViewInformation) const { - ::osl::MutexGuard aGuard( m_aMutex ); + std::unique_lock aGuard( m_aMutex ); // get the current Viewport const basegfx::B2DRange& rViewport = rViewInformation.getViewport(); @@ -76,7 +76,7 @@ namespace drawinglayer::primitive2d void ViewTransformationDependentPrimitive2D::get2DDecomposition(Primitive2DDecompositionVisitor& rVisitor, const geometry::ViewInformation2D& rViewInformation) const { - ::osl::MutexGuard aGuard( m_aMutex ); + std::unique_lock aGuard( m_aMutex ); // get the current ViewTransformation const basegfx::B2DHomMatrix& rViewTransformation = rViewInformation.getViewTransformation(); @@ -99,7 +99,7 @@ namespace drawinglayer::primitive2d void ObjectAndViewTransformationDependentPrimitive2D::get2DDecomposition(Primitive2DDecompositionVisitor& rVisitor, const geometry::ViewInformation2D& rViewInformation) const { - ::osl::MutexGuard aGuard( m_aMutex ); + std::unique_lock aGuard( m_aMutex ); // get the current ViewTransformation const basegfx::B2DHomMatrix& rViewTransformation = rViewInformation.getViewTransformation(); diff --git a/drawinglayer/source/primitive2d/sceneprimitive2d.cxx b/drawinglayer/source/primitive2d/sceneprimitive2d.cxx index a1a38aa735af..cde119d514ba 100644 --- a/drawinglayer/source/primitive2d/sceneprimitive2d.cxx +++ b/drawinglayer/source/primitive2d/sceneprimitive2d.cxx @@ -128,7 +128,7 @@ namespace drawinglayer::primitive2d { bool ScenePrimitive2D::impGetShadow3D() const { - ::osl::MutexGuard aGuard( m_aMutex ); + std::unique_lock aGuard( m_aMutex ); // create on demand if(!mbShadow3DChecked && !getChildren3D().empty()) @@ -626,7 +626,7 @@ namespace drawinglayer::primitive2d void ScenePrimitive2D::get2DDecomposition(Primitive2DDecompositionVisitor& rVisitor, const geometry::ViewInformation2D& rViewInformation) const { - ::osl::MutexGuard aGuard( m_aMutex ); + std::unique_lock aGuard( m_aMutex ); // get the involved ranges (see helper method calculateDiscreteSizes for details) basegfx::B2DRange aDiscreteRange; diff --git a/drawinglayer/source/primitive2d/texteffectprimitive2d.cxx b/drawinglayer/source/primitive2d/texteffectprimitive2d.cxx index e68be6b28391..5d6425fc77e5 100644 --- a/drawinglayer/source/primitive2d/texteffectprimitive2d.cxx +++ b/drawinglayer/source/primitive2d/texteffectprimitive2d.cxx @@ -213,7 +213,7 @@ void TextEffectPrimitive2D::get2DDecomposition( Primitive2DDecompositionVisitor& rVisitor, const geometry::ViewInformation2D& rViewInformation) const { - ::osl::MutexGuard aGuard(m_aMutex); + std::unique_lock aGuard(m_aMutex); if (!getBuffered2DDecomposition().empty()) { diff --git a/include/drawinglayer/primitive2d/baseprimitive2d.hxx b/include/drawinglayer/primitive2d/baseprimitive2d.hxx index 7d648d9b6845..f76c3e5a1520 100644 --- a/include/drawinglayer/primitive2d/baseprimitive2d.hxx +++ b/include/drawinglayer/primitive2d/baseprimitive2d.hxx @@ -29,17 +29,49 @@ #include #include #include +#include namespace drawinglayer::geometry { class ViewInformation2D; } +/** This is a custom re-implementation of cppu::WeakComponentImplHelper which uses + std::recursive_mutex and skips parts of the XComponent stuff. +*/ +class DRAWINGLAYER_DLLPUBLIC BasePrimitive2DImplBase : public cppu::OWeakObject, + public css::lang::XComponent, + public css::lang::XTypeProvider, + public css::graphic::XPrimitive2D, + public css::util::XAccounting +{ +public: + virtual ~BasePrimitive2DImplBase() override; + + virtual void SAL_CALL acquire() noexcept override; + virtual void SAL_CALL release() noexcept override; + virtual css::uno::Any SAL_CALL queryInterface(css::uno::Type const& aType) override; + + // css::lang::XComponent + virtual void SAL_CALL dispose() override; + virtual void SAL_CALL + addEventListener(css::uno::Reference const& xListener) override; + virtual void SAL_CALL + removeEventListener(css::uno::Reference const& xListener) override; + + // css::lang::XTypeProvider + virtual css::uno::Sequence SAL_CALL getTypes() override; + virtual css::uno::Sequence SAL_CALL getImplementationId() override + { + return css::uno::Sequence(); + } + +protected: + mutable std::recursive_mutex m_aMutex; +}; + namespace drawinglayer::primitive2d { -typedef cppu::WeakComponentImplHelper - BasePrimitive2DImplBase; - /** BasePrimitive2D class Baseclass for all C++ implementations of css::graphic::XPrimitive2D @@ -113,8 +145,7 @@ typedef cppu::WeakComponentImplHelper