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 <noel.grandin@collabora.co.uk>
diff --git a/drawinglayer/source/primitive2d/BufferedDecompositionPrimitive2D.cxx b/drawinglayer/source/primitive2d/BufferedDecompositionPrimitive2D.cxx
index 896f85d..301d501 100644
--- a/drawinglayer/source/primitive2d/BufferedDecompositionPrimitive2D.cxx
+++ b/drawinglayer/source/primitive2d/BufferedDecompositionPrimitive2D.cxx
@@ -33,7 +33,7 @@
    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 90ff831..f13b92b 100644
--- a/drawinglayer/source/primitive2d/backgroundcolorprimitive2d.cxx
+++ b/drawinglayer/source/primitive2d/backgroundcolorprimitive2d.cxx
@@ -67,7 +67,7 @@

        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 61cd092..71a1334 100644
--- a/drawinglayer/source/primitive2d/baseprimitive2d.cxx
+++ b/drawinglayer/source/primitive2d/baseprimitive2d.cxx
@@ -24,15 +24,73 @@
#include <drawinglayer/geometry/viewinformation2d.hxx>
#include <basegfx/utils/canvastools.hxx>
#include <comphelper/sequence.hxx>
#include <cppuhelper/queryinterface.hxx>

using namespace css;

BasePrimitive2DImplBase::~BasePrimitive2DImplBase() {}

css::uno::Any BasePrimitive2DImplBase::queryInterface(css::uno::Type const& rType)
{
    css::uno::Any aReturn = ::cppu::queryInterface(
        rType, static_cast<uno::XWeak*>(this), static_cast<lang::XComponent*>(this),
        static_cast<lang::XTypeProvider*>(this), static_cast<graphic::XPrimitive2D*>(this),
        static_cast<util::XAccounting*>(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<css::lang::XEventListener> const&)
{
    assert(false);
}
void BasePrimitive2DImplBase::removeEventListener(
    css::uno::Reference<css::lang::XEventListener> const&)
{
    assert(false);
}

css::uno::Sequence<css::uno::Type> BasePrimitive2DImplBase::getTypes()
{
    static const css::uno::Sequence<uno::Type> aTypeList{
        cppu::UnoType<uno::XWeak>::get(), cppu::UnoType<lang::XComponent>::get(),
        cppu::UnoType<lang::XTypeProvider>::get(), cppu::UnoType<graphic::XPrimitive2D>::get(),
        cppu::UnoType<util::XAccounting>::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 c5ece36..92f0ed5 100644
--- a/drawinglayer/source/primitive2d/controlprimitive2d.cxx
+++ b/drawinglayer/source/primitive2d/controlprimitive2d.cxx
@@ -317,7 +317,7 @@
        {
            // 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 fd25109..0b217ad 100644
--- a/drawinglayer/source/primitive2d/embedded3dprimitive2d.cxx
+++ b/drawinglayer/source/primitive2d/embedded3dprimitive2d.cxx
@@ -35,7 +35,7 @@
{
        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 d527b9c..666f545 100644
--- a/drawinglayer/source/primitive2d/fillhatchprimitive2d.cxx
+++ b/drawinglayer/source/primitive2d/fillhatchprimitive2d.cxx
@@ -173,7 +173,7 @@

        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 a43e8af..64816b0 100644
--- a/drawinglayer/source/primitive2d/gridprimitive2d.cxx
+++ b/drawinglayer/source/primitive2d/gridprimitive2d.cxx
@@ -305,7 +305,7 @@

        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 71b372d..0db4f37 100644
--- a/drawinglayer/source/primitive2d/helplineprimitive2d.cxx
+++ b/drawinglayer/source/primitive2d/helplineprimitive2d.cxx
@@ -155,7 +155,7 @@

        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 9919658..184f72f 100644
--- a/drawinglayer/source/primitive2d/polygonprimitive2d.cxx
+++ b/drawinglayer/source/primitive2d/polygonprimitive2d.cxx
@@ -165,7 +165,7 @@
    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 da0a378..61e060e5 100644
--- a/drawinglayer/source/primitive2d/primitivetools2d.cxx
+++ b/drawinglayer/source/primitive2d/primitivetools2d.cxx
@@ -26,7 +26,7 @@
{
        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 @@

        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 @@

        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 @@

        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 a1a38aa..cde119d 100644
--- a/drawinglayer/source/primitive2d/sceneprimitive2d.cxx
+++ b/drawinglayer/source/primitive2d/sceneprimitive2d.cxx
@@ -128,7 +128,7 @@
{
        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 @@

        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 e68be6b..5d6425f 100644
--- a/drawinglayer/source/primitive2d/texteffectprimitive2d.cxx
+++ b/drawinglayer/source/primitive2d/texteffectprimitive2d.cxx
@@ -213,7 +213,7 @@
    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 7d648d9..f76c3e5a 100644
--- a/include/drawinglayer/primitive2d/baseprimitive2d.hxx
+++ b/include/drawinglayer/primitive2d/baseprimitive2d.hxx
@@ -29,17 +29,49 @@
#include <cppuhelper/basemutex.hxx>
#include <basegfx/range/b2drange.hxx>
#include <com/sun/star/graphic/XPrimitive2D.hpp>
#include <mutex>

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<css::lang::XEventListener> const& xListener) override;
    virtual void SAL_CALL
    removeEventListener(css::uno::Reference<css::lang::XEventListener> const& xListener) override;

    // css::lang::XTypeProvider
    virtual css::uno::Sequence<css::uno::Type> SAL_CALL getTypes() override;
    virtual css::uno::Sequence<sal_Int8> SAL_CALL getImplementationId() override
    {
        return css::uno::Sequence<sal_Int8>();
    }

protected:
    mutable std::recursive_mutex m_aMutex;
};

namespace drawinglayer::primitive2d
{
typedef cppu::WeakComponentImplHelper<css::graphic::XPrimitive2D, css::util::XAccounting>
    BasePrimitive2DImplBase;

/** BasePrimitive2D class

    Baseclass for all C++ implementations of css::graphic::XPrimitive2D
@@ -113,8 +145,7 @@
    for view-independent primitives which are defined by not using ViewInformation2D
    in their get2DDecomposition/getB2DRange implementations.
*/
class DRAWINGLAYER_DLLPUBLIC BasePrimitive2D : protected cppu::BaseMutex,
                                               public BasePrimitive2DImplBase
class DRAWINGLAYER_DLLPUBLIC BasePrimitive2D : public BasePrimitive2DImplBase
{
    BasePrimitive2D(const BasePrimitive2D&) = delete;
    BasePrimitive2D& operator=(const BasePrimitive2D&) = delete;