drawinglayer/source/processor2d/d2dpixelprocessor2d.cxx  |  596 +++++++--------
 include/drawinglayer/processor2d/d2dpixelprocessor2d.hxx |   21 
 2 files changed, 320 insertions(+), 297 deletions(-)

New commits:
commit 7e07225a1b48f3f987a818213256d3cbb9266d87
Author:     Armin Le Grand (Allotropia) <armin.le.gr...@me.com>
AuthorDate: Fri Jan 6 12:16:10 2023 +0100
Commit:     Armin Le Grand <armin.le.gr...@me.com>
CommitDate: Fri Jan 6 15:24:39 2023 +0000

    SDPR: Overhauled D2DRenderer to use sal::systools::COMReference
    
    All stuff used from MS with names starting with ID2D1* is COM
    API stuff, so referenced and interface-based. I thought about
    making this more safe since a while (shared/unique_ptr, ...)
    but found no good way to do it.
    Also did not want to use CComPtr from MS and expand the devenv
    we need on win, so was short before doing an own small smartptr
    class. Luckily I asked sberg and he pointed me to the already
    existing sal::systools::COMReference which exactly does what
    I need here - thanks!
    Unluckily I now had to change a lot of code - sigh. I wish
    I had known earlier :-/
    This change contains the renderer completely adapted to using
    that much safer and better ressource control.
    Plus I added (even more) comments to try to make more clear
    in many plasces what's going on, what is done and why.
    
    Change-Id: Ia2aa3223d0e5f7ec6569cde176cec1fadcd921dc
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/145142
    Tested-by: Jenkins
    Reviewed-by: Armin Le Grand <armin.le.gr...@me.com>

diff --git a/drawinglayer/source/processor2d/d2dpixelprocessor2d.cxx 
b/drawinglayer/source/processor2d/d2dpixelprocessor2d.cxx
index 2ed7ea526959..04c6b400039b 100644
--- a/drawinglayer/source/processor2d/d2dpixelprocessor2d.cxx
+++ b/drawinglayer/source/processor2d/d2dpixelprocessor2d.cxx
@@ -56,51 +56,44 @@ using namespace com::sun::star;
 
 namespace
 {
-class ID2D1FactoryProvider
+class ID2D1GlobalFactoryProvider
 {
-    ID2D1Factory* mpD2DFactory;
+    sal::systools::COMReference<ID2D1Factory> mpD2DFactory;
 
 public:
-    ID2D1FactoryProvider()
+    ID2D1GlobalFactoryProvider()
         : mpD2DFactory(nullptr)
     {
-        HRESULT hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, 
__uuidof(ID2D1Factory),
-                                       nullptr, 
reinterpret_cast<void**>(&mpD2DFactory));
+        const HRESULT hr(D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED,
+                                           __uuidof(ID2D1Factory), nullptr,
+                                           
reinterpret_cast<void**>(&mpD2DFactory)));
 
         if (!SUCCEEDED(hr))
-            mpD2DFactory = nullptr;
+            mpD2DFactory.clear();
     }
 
-    ~ID2D1FactoryProvider()
-    {
-        if (mpD2DFactory)
-            mpD2DFactory->Release();
-    }
+    ~ID2D1GlobalFactoryProvider() {}
 
-    ID2D1Factory* getID2D1Factory() const { return mpD2DFactory; }
+    sal::systools::COMReference<ID2D1Factory>& getID2D1Factory() { return 
mpD2DFactory; }
 };
 
-ID2D1FactoryProvider aID2D1FactoryProvider;
+ID2D1GlobalFactoryProvider aID2D1GlobalFactoryProvider;
 
 class ID2D1GlobalRenderTargetProvider
 {
-    ID2D1DCRenderTarget* mpID2D1DCRenderTarget;
+    sal::systools::COMReference<ID2D1DCRenderTarget> mpID2D1DCRenderTarget;
 
 public:
     ID2D1GlobalRenderTargetProvider()
-        : mpID2D1DCRenderTarget(nullptr)
+        : mpID2D1DCRenderTarget()
     {
     }
 
-    ~ID2D1GlobalRenderTargetProvider()
-    {
-        if (mpID2D1DCRenderTarget)
-            mpID2D1DCRenderTarget->Release();
-    }
+    ~ID2D1GlobalRenderTargetProvider() {}
 
-    ID2D1DCRenderTarget* getID2D1DCRenderTarget() const
+    sal::systools::COMReference<ID2D1DCRenderTarget>& getID2D1DCRenderTarget()
     {
-        if (nullptr == mpID2D1DCRenderTarget && 
aID2D1FactoryProvider.getID2D1Factory())
+        if (!mpID2D1DCRenderTarget && 
aID2D1GlobalFactoryProvider.getID2D1Factory())
         {
             const D2D1_RENDER_TARGET_PROPERTIES 
aRTProps(D2D1::RenderTargetProperties(
                 D2D1_RENDER_TARGET_TYPE_DEFAULT,
@@ -108,9 +101,8 @@ public:
                                   D2D1_ALPHA_MODE_IGNORE), 
//D2D1_ALPHA_MODE_PREMULTIPLIED),
                 0, 0, D2D1_RENDER_TARGET_USAGE_NONE, 
D2D1_FEATURE_LEVEL_DEFAULT));
 
-            const HRESULT 
hr(aID2D1FactoryProvider.getID2D1Factory()->CreateDCRenderTarget(
-                &aRTProps,
-                
&(const_cast<ID2D1GlobalRenderTargetProvider*>(this)->mpID2D1DCRenderTarget)));
+            const HRESULT 
hr(aID2D1GlobalFactoryProvider.getID2D1Factory()->CreateDCRenderTarget(
+                &aRTProps, &mpID2D1DCRenderTarget));
 
             // interestingly this ID2D1DCRenderTarget already works and can 
hold
             // created ID2D1Bitmap(s) in RenderTarget-specific form, *without*
@@ -119,7 +111,7 @@ public:
             // to have a HDC that is valid during LO's lifetime.
 
             if (!SUCCEEDED(hr))
-                
const_cast<ID2D1GlobalRenderTargetProvider*>(this)->mpID2D1DCRenderTarget = 
nullptr;
+                mpID2D1DCRenderTarget.clear();
         }
 
         return mpID2D1DCRenderTarget;
@@ -131,24 +123,20 @@ ID2D1GlobalRenderTargetProvider 
aID2D1GlobalRenderTargetProvider;
 class SystemDependentData_ID2D1PathGeometry : public 
basegfx::SystemDependentData
 {
 private:
-    ID2D1PathGeometry* mpID2D1PathGeometry;
+    sal::systools::COMReference<ID2D1PathGeometry> mpID2D1PathGeometry;
 
 public:
-    SystemDependentData_ID2D1PathGeometry(ID2D1PathGeometry* 
pID2D1PathGeometry)
+    SystemDependentData_ID2D1PathGeometry(
+        sal::systools::COMReference<ID2D1PathGeometry>& rID2D1PathGeometry)
         : 
basegfx::SystemDependentData(Application::GetSystemDependentDataManager())
-        , mpID2D1PathGeometry(pID2D1PathGeometry)
+        , mpID2D1PathGeometry(rID2D1PathGeometry)
     {
     }
 
-    ~SystemDependentData_ID2D1PathGeometry()
+    const sal::systools::COMReference<ID2D1PathGeometry>& 
getID2D1PathGeometry() const
     {
-        if (nullptr != getID2D1PathGeometry())
-        {
-            mpID2D1PathGeometry->Release();
-        }
+        return mpID2D1PathGeometry;
     }
-
-    ID2D1PathGeometry* getID2D1PathGeometry() const { return 
mpID2D1PathGeometry; }
     virtual sal_Int64 estimateUsageInBytes() const override;
 };
 
@@ -156,10 +144,10 @@ sal_Int64 
SystemDependentData_ID2D1PathGeometry::estimateUsageInBytes() const
 {
     sal_Int64 aRetval(0);
 
-    if (nullptr != getID2D1PathGeometry())
+    if (getID2D1PathGeometry())
     {
         UINT32 nCount(0);
-        HRESULT hr = getID2D1PathGeometry()->GetSegmentCount(&nCount);
+        const HRESULT hr(getID2D1PathGeometry()->GetSegmentCount(&nCount));
 
         if (SUCCEEDED(hr))
         {
@@ -212,7 +200,8 @@ basegfx::B2DPoint impPixelSnap(const basegfx::B2DPolygon& 
rPolygon,
     return rPolygon.getB2DPoint(nIndex);
 }
 
-void addB2DPolygonToPathGeometry(ID2D1GeometrySink* pSink, const 
basegfx::B2DPolygon& rPolygon,
+void 
addB2DPolygonToPathGeometry(sal::systools::COMReference<ID2D1GeometrySink>& 
rSink,
+                                 const basegfx::B2DPolygon& rPolygon,
                                  const 
drawinglayer::geometry::ViewInformation2D* pViewInformation)
 {
     const sal_uInt32 nPointCount(rPolygon.count());
@@ -230,7 +219,7 @@ void addB2DPolygonToPathGeometry(ID2D1GeometrySink* pSink, 
const basegfx::B2DPol
 
         if (aEdge.isBezier())
         {
-            pSink->AddBezier(
+            rSink->AddBezier(
                 
D2D1::BezierSegment(D2D1::Point2F(aEdge.getControlPointA().getX(),
                                                   
aEdge.getControlPointA().getY()), //C1
                                     
D2D1::Point2F(aEdge.getControlPointB().getX(),
@@ -239,7 +228,7 @@ void addB2DPolygonToPathGeometry(ID2D1GeometrySink* pSink, 
const basegfx::B2DPol
         }
         else
         {
-            pSink->AddLine(D2D1::Point2F(aEndPoint.getX(), aEndPoint.getY()));
+            rSink->AddLine(D2D1::Point2F(aEndPoint.getX(), aEndPoint.getY()));
         }
     }
 }
@@ -266,16 +255,17 @@ getOrCreatePathGeometry(const basegfx::B2DPolygon& 
rPolygon,
         }
     }
 
-    ID2D1PathGeometry* pID2D1PathGeometry(nullptr);
-    HRESULT hr = 
aID2D1FactoryProvider.getID2D1Factory()->CreatePathGeometry(&pID2D1PathGeometry);
+    sal::systools::COMReference<ID2D1PathGeometry> pID2D1PathGeometry;
+    HRESULT hr(
+        
aID2D1GlobalFactoryProvider.getID2D1Factory()->CreatePathGeometry(&pID2D1PathGeometry));
     const sal_uInt32 nPointCount(rPolygon.count());
 
     if (SUCCEEDED(hr) && nPointCount)
     {
-        ID2D1GeometrySink* pSink = nullptr;
+        sal::systools::COMReference<ID2D1GeometrySink> pSink;
         hr = pID2D1PathGeometry->Open(&pSink);
 
-        if (SUCCEEDED(hr))
+        if (SUCCEEDED(hr) && pSink)
         {
             const basegfx::B2DPoint 
aStart(rViewInformation.getPixelSnapHairline()
                                                ? rPolygon.getB2DPoint(0)
@@ -286,12 +276,11 @@ getOrCreatePathGeometry(const basegfx::B2DPolygon& 
rPolygon,
             addB2DPolygonToPathGeometry(pSink, rPolygon, &rViewInformation);
             pSink->EndFigure(rPolygon.isClosed() ? D2D1_FIGURE_END_CLOSED : 
D2D1_FIGURE_END_OPEN);
             pSink->Close();
-            pSink->Release();
         }
     }
 
     // add to buffering mechanism
-    if (nullptr != pID2D1PathGeometry)
+    if (pID2D1PathGeometry)
     {
         if (rViewInformation.getPixelSnapHairline() || nPointCount <= 4)
         {
@@ -321,16 +310,17 @@ getOrCreateFillGeometry(const basegfx::B2DPolyPolygon& 
rPolyPolygon)
         return pSystemDependentData_ID2D1PathGeometry;
     }
 
-    ID2D1PathGeometry* pID2D1PathGeometry(nullptr);
-    HRESULT hr = 
aID2D1FactoryProvider.getID2D1Factory()->CreatePathGeometry(&pID2D1PathGeometry);
+    sal::systools::COMReference<ID2D1PathGeometry> pID2D1PathGeometry;
+    HRESULT hr(
+        
aID2D1GlobalFactoryProvider.getID2D1Factory()->CreatePathGeometry(&pID2D1PathGeometry));
     const sal_uInt32 nCount(rPolyPolygon.count());
 
     if (SUCCEEDED(hr) && nCount)
     {
-        ID2D1GeometrySink* pSink = nullptr;
+        sal::systools::COMReference<ID2D1GeometrySink> pSink;
         hr = pID2D1PathGeometry->Open(&pSink);
 
-        if (SUCCEEDED(hr))
+        if (SUCCEEDED(hr) && pSink)
         {
             for (sal_uInt32 a(0); a < nCount; a++)
             {
@@ -349,12 +339,11 @@ getOrCreateFillGeometry(const basegfx::B2DPolyPolygon& 
rPolyPolygon)
             }
 
             pSink->Close();
-            pSink->Release();
         }
     }
 
     // add to buffering mechanism
-    if (nullptr != pID2D1PathGeometry)
+    if (pID2D1PathGeometry)
     {
         return 
rPolyPolygon.addOrReplaceSystemDependentData<SystemDependentData_ID2D1PathGeometry>(
             pID2D1PathGeometry);
@@ -366,27 +355,21 @@ getOrCreateFillGeometry(const basegfx::B2DPolyPolygon& 
rPolyPolygon)
 class SystemDependentData_ID2D1Bitmap : public basegfx::SystemDependentData
 {
 private:
-    ID2D1Bitmap* mpD2DBitmap;
+    sal::systools::COMReference<ID2D1Bitmap> mpD2DBitmap;
     const std::shared_ptr<SalBitmap> maAssociatedAlpha;
 
 public:
-    SystemDependentData_ID2D1Bitmap(ID2D1Bitmap* pD2DBitmap,
+    SystemDependentData_ID2D1Bitmap(sal::systools::COMReference<ID2D1Bitmap>& 
rD2DBitmap,
                                     const std::shared_ptr<SalBitmap>& 
rAssociatedAlpha)
         : 
basegfx::SystemDependentData(Application::GetSystemDependentDataManager())
-        , mpD2DBitmap(pD2DBitmap)
+        , mpD2DBitmap(rD2DBitmap)
         , maAssociatedAlpha(rAssociatedAlpha)
     {
     }
 
-    ~SystemDependentData_ID2D1Bitmap()
-    {
-        if (nullptr != getID2D1Bitmap())
-        {
-            mpD2DBitmap->Release();
-        }
-    }
+    ~SystemDependentData_ID2D1Bitmap() {}
 
-    ID2D1Bitmap* getID2D1Bitmap() const { return mpD2DBitmap; }
+    const sal::systools::COMReference<ID2D1Bitmap>& getID2D1Bitmap() const { 
return mpD2DBitmap; }
     const std::shared_ptr<SalBitmap>& getAssociatedAlpha() const { return 
maAssociatedAlpha; }
 
     virtual sal_Int64 estimateUsageInBytes() const override;
@@ -396,8 +379,9 @@ sal_Int64 
SystemDependentData_ID2D1Bitmap::estimateUsageInBytes() const
 {
     sal_Int64 aRetval(0);
 
-    if (nullptr != getID2D1Bitmap())
+    if (getID2D1Bitmap())
     {
+        // use factor 4 for RGBA_8 as estimation
         const D2D1_SIZE_U aSizePixel(getID2D1Bitmap()->GetPixelSize());
         aRetval = static_cast<sal_Int64>(aSizePixel.width)
                   * static_cast<sal_Int64>(aSizePixel.height) * 4;
@@ -406,7 +390,7 @@ sal_Int64 
SystemDependentData_ID2D1Bitmap::estimateUsageInBytes() const
     return aRetval;
 }
 
-ID2D1Bitmap* createB2DBitmap(const BitmapEx& rBitmapEx)
+sal::systools::COMReference<ID2D1Bitmap> createB2DBitmap(const BitmapEx& 
rBitmapEx)
 {
     const Size& rSizePixel(rBitmapEx.GetSizePixel());
     const bool bAlpha(rBitmapEx.IsAlpha());
@@ -453,35 +437,34 @@ ID2D1Bitmap* createB2DBitmap(const BitmapEx& rBitmapEx)
         }
     }
 
-    // use GlobalRenderTraget to allow usage combined with
+    // use GlobalRenderTarget to allow usage combined with
     // the Direct2D CreateSharedBitmap-mechanism. This is needed
     // since ID2D1Bitmap is a ID2D1RenderTarget-dependent resource
     // and thus - in principle - would have to be re-created for
     // *each* new ID2D1RenderTarget, that means for *each* new
     // target HDC, resp. OutputDevice
-    ID2D1DCRenderTarget* pGlobalRenderTraget(
-        aID2D1GlobalRenderTargetProvider.getID2D1DCRenderTarget());
-    ID2D1Bitmap* pID2D1Bitmap(nullptr);
+    sal::systools::COMReference<ID2D1Bitmap> pID2D1Bitmap;
 
-    if (nullptr != pGlobalRenderTraget)
+    if (aID2D1GlobalRenderTargetProvider.getID2D1DCRenderTarget())
     {
-        HRESULT hr = pGlobalRenderTraget->CreateBitmap(
+        const HRESULT 
hr(aID2D1GlobalRenderTargetProvider.getID2D1DCRenderTarget()->CreateBitmap(
             D2D1::SizeU(rSizePixel.Width(), rSizePixel.Height()), &aData[0],
             rSizePixel.Width() * sizeof(sal_uInt32),
             D2D1::BitmapProperties(
                 D2D1::PixelFormat(DXGI_FORMAT_B8G8R8A8_UNORM, // DXGI_FORMAT
                                   bAlpha ? D2D1_ALPHA_MODE_PREMULTIPLIED
                                          : D2D1_ALPHA_MODE_IGNORE)), // 
D2D1_ALPHA_MODE
-            &pID2D1Bitmap);
+            &pID2D1Bitmap));
 
         if (!SUCCEEDED(hr))
-            return nullptr;
+            pID2D1Bitmap.clear();
     }
 
     return pID2D1Bitmap;
 }
 
-ID2D1Bitmap* getOrCreateB2DBitmap(ID2D1RenderTarget& rRT, const BitmapEx& 
rBitmapEx)
+sal::systools::COMReference<ID2D1Bitmap>
+getOrCreateB2DBitmap(sal::systools::COMReference<ID2D1RenderTarget>& rRT, 
const BitmapEx& rBitmapEx)
 {
     const basegfx::SystemDependentDataHolder* pHolder(
         rBitmapEx.GetBitmap().accessSystemDependentDataHolder());
@@ -508,9 +491,9 @@ ID2D1Bitmap* getOrCreateB2DBitmap(ID2D1RenderTarget& rRT, 
const BitmapEx& rBitma
     if (!pSystemDependentData_ID2D1Bitmap)
     {
         // have to create newly
-        ID2D1Bitmap* pID2D1Bitmap(createB2DBitmap(rBitmapEx));
+        sal::systools::COMReference<ID2D1Bitmap> 
pID2D1Bitmap(createB2DBitmap(rBitmapEx));
 
-        if (nullptr != pID2D1Bitmap)
+        if (pID2D1Bitmap)
         {
             // creation worked, create SystemDependentData_ID2D1Bitmap
             pSystemDependentData_ID2D1Bitmap = 
std::make_shared<SystemDependentData_ID2D1Bitmap>(
@@ -527,21 +510,22 @@ ID2D1Bitmap* getOrCreateB2DBitmap(ID2D1RenderTarget& rRT, 
const BitmapEx& rBitma
         }
     }
 
+    sal::systools::COMReference<ID2D1Bitmap> pWrappedD2DBitmap;
+
     if (pSystemDependentData_ID2D1Bitmap)
     {
         // embed to CreateSharedBitmap, that makes it usable on
         // the specified RenderTarget
-        ID2D1Bitmap* pWrappedD2DBitmap(nullptr);
-        HRESULT hr(rRT.CreateSharedBitmap(
+        const HRESULT hr(rRT->CreateSharedBitmap(
             __uuidof(ID2D1Bitmap),
             
static_cast<void*>(pSystemDependentData_ID2D1Bitmap->getID2D1Bitmap()), nullptr,
             &pWrappedD2DBitmap));
 
-        if (SUCCEEDED(hr))
-            return pWrappedD2DBitmap;
+        if (!SUCCEEDED(hr))
+            pWrappedD2DBitmap.clear();
     }
 
-    return nullptr;
+    return pWrappedD2DBitmap;
 }
 
 // This is a simple local derivation of D2DPixelProcessor2D to be used
@@ -551,21 +535,19 @@ ID2D1Bitmap* getOrCreateB2DBitmap(ID2D1RenderTarget& rRT, 
const BitmapEx& rBitma
 // (you need to call process() with the primitives to be painted of
 // course). Then use the local helper getID2D1Bitmap() to access the
 // ID2D1Bitmap which was the target of that operation.
-// The class does not need to call mpBitmapRenderTarget->Release() since
-// mpRT of parent is set to it and that calls Release() already in its
-// destructor, so no destructor needed here.
 class D2DBitmapPixelProcessor2D final : public 
drawinglayer::processor2d::D2DPixelProcessor2D
 {
     // the local ID2D1BitmapRenderTarget
-    ID2D1BitmapRenderTarget* mpBitmapRenderTarget;
+    sal::systools::COMReference<ID2D1BitmapRenderTarget> mpBitmapRenderTarget;
 
 public:
     // helper class to create another instance of D2DPixelProcessor2D for
     // creating helper-ID2D1Bitmap's for a given ID2D1RenderTarget
     D2DBitmapPixelProcessor2D(const drawinglayer::geometry::ViewInformation2D& 
rViewInformation,
-                              sal_uInt32 nWidth, sal_uInt32 nHeight, 
ID2D1RenderTarget& rParent)
+                              sal_uInt32 nWidth, sal_uInt32 nHeight,
+                              sal::systools::COMReference<ID2D1RenderTarget>& 
rParent)
         : drawinglayer::processor2d::D2DPixelProcessor2D(rViewInformation)
-        , mpBitmapRenderTarget(nullptr)
+        , mpBitmapRenderTarget()
     {
         if (0 == nWidth || 0 == nHeight)
         {
@@ -577,7 +559,7 @@ public:
         {
             // Allocate compatible RGBA render target
             const D2D1_SIZE_U aRenderTargetSizePixel(D2D1::SizeU(nWidth, 
nHeight));
-            HRESULT hr(rParent.CreateCompatibleRenderTarget(
+            const HRESULT hr(rParent->CreateCompatibleRenderTarget(
                 nullptr, &aRenderTargetSizePixel, nullptr,
                 D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS_NONE, 
&mpBitmapRenderTarget));
 
@@ -588,30 +570,33 @@ public:
             }
             else
             {
-                setRenderTarget(mpBitmapRenderTarget);
+                sal::systools::COMReference<ID2D1RenderTarget> pRT;
+                
mpBitmapRenderTarget->QueryInterface(__uuidof(ID2D1RenderTarget),
+                                                     
reinterpret_cast<void**>(&pRT));
+                setRenderTarget(pRT);
             }
         }
 
         if (hasRenderTarget())
         {
             // clear as render preparation
-            getRenderTarget().BeginDraw();
-            getRenderTarget().Clear(D2D1::ColorF(0.0f, 0.0f, 0.0f, 0.0f));
-            getRenderTarget().EndDraw();
+            getRenderTarget()->BeginDraw();
+            getRenderTarget()->Clear(D2D1::ColorF(0.0f, 0.0f, 0.0f, 0.0f));
+            getRenderTarget()->EndDraw();
         }
     }
 
-    ID2D1Bitmap* getID2D1Bitmap() const
+    sal::systools::COMReference<ID2D1Bitmap> getID2D1Bitmap() const
     {
+        sal::systools::COMReference<ID2D1Bitmap> pResult;
+
         // access the resulting bitmap if exists
-        if (nullptr != mpBitmapRenderTarget)
+        if (mpBitmapRenderTarget)
         {
-            ID2D1Bitmap* pInBetweenResult(nullptr);
-            mpBitmapRenderTarget->GetBitmap(&pInBetweenResult);
-            return pInBetweenResult;
+            mpBitmapRenderTarget->GetBitmap(&pResult);
         }
 
-        return nullptr;
+        return pResult;
     }
 };
 }
@@ -621,7 +606,7 @@ namespace drawinglayer::processor2d
 D2DPixelProcessor2D::D2DPixelProcessor2D(const geometry::ViewInformation2D& 
rViewInformation)
     : BaseProcessor2D(rViewInformation)
     , maBColorModifierStack()
-    , mpRT(nullptr)
+    , mpRT()
     , mnRecursionCounter(0)
     , mnErrorCounter(0)
 {
@@ -631,11 +616,11 @@ D2DPixelProcessor2D::D2DPixelProcessor2D(const 
geometry::ViewInformation2D& rVie
                                          HDC aHdc)
     : BaseProcessor2D(rViewInformation)
     , maBColorModifierStack()
-    , mpRT(nullptr)
+    , mpRT()
     , mnRecursionCounter(0)
     , mnErrorCounter(0)
 {
-    ID2D1DCRenderTarget* pDCRT = nullptr;
+    sal::systools::COMReference<ID2D1DCRenderTarget> pDCRT;
     tools::Long aOutWidth(0), aOutHeight(0);
 
     if (aHdc)
@@ -644,7 +629,7 @@ D2DPixelProcessor2D::D2DPixelProcessor2D(const 
geometry::ViewInformation2D& rVie
         aOutHeight = GetDeviceCaps(aHdc, VERTRES);
     }
 
-    if (aOutWidth > 0 && aOutHeight > 0 && 
aID2D1FactoryProvider.getID2D1Factory())
+    if (aOutWidth > 0 && aOutHeight > 0 && 
aID2D1GlobalFactoryProvider.getID2D1Factory())
     {
         const D2D1_RENDER_TARGET_PROPERTIES 
aRTProps(D2D1::RenderTargetProperties(
             D2D1_RENDER_TARGET_TYPE_DEFAULT,
@@ -653,12 +638,10 @@ D2DPixelProcessor2D::D2DPixelProcessor2D(const 
geometry::ViewInformation2D& rVie
             0, 0, D2D1_RENDER_TARGET_USAGE_NONE, D2D1_FEATURE_LEVEL_DEFAULT));
 
         const HRESULT hr(
-            
aID2D1FactoryProvider.getID2D1Factory()->CreateDCRenderTarget(&aRTProps, 
&pDCRT));
+            
aID2D1GlobalFactoryProvider.getID2D1Factory()->CreateDCRenderTarget(&aRTProps, 
&pDCRT));
 
         if (!SUCCEEDED(hr))
-        {
-            pDCRT = nullptr;
-        }
+            pDCRT.clear();
     }
 
     if (pDCRT)
@@ -668,10 +651,7 @@ D2DPixelProcessor2D::D2DPixelProcessor2D(const 
geometry::ViewInformation2D& rVie
         const HRESULT hr(pDCRT->BindDC(aHdc, &rc));
 
         if (!SUCCEEDED(hr))
-        {
-            pDCRT->Release();
-            pDCRT = nullptr;
-        }
+            pDCRT.clear();
     }
 
     if (pDCRT)
@@ -701,7 +681,9 @@ D2DPixelProcessor2D::D2DPixelProcessor2D(const 
geometry::ViewInformation2D& rVie
 
     if (pDCRT)
     {
-        setRenderTarget(pDCRT);
+        sal::systools::COMReference<ID2D1RenderTarget> pRT;
+        pDCRT->QueryInterface(__uuidof(ID2D1RenderTarget), 
reinterpret_cast<void**>(&pRT));
+        setRenderTarget(pRT);
     }
     else
     {
@@ -709,19 +691,16 @@ D2DPixelProcessor2D::D2DPixelProcessor2D(const 
geometry::ViewInformation2D& rVie
     }
 }
 
-D2DPixelProcessor2D::~D2DPixelProcessor2D()
-{
-    if (hasRenderTarget())
-        getRenderTarget().Release();
-}
-
 void D2DPixelProcessor2D::processPolygonHairlinePrimitive2D(
     const primitive2d::PolygonHairlinePrimitive2D& rPolygonHairlinePrimitive2D)
 {
     const basegfx::B2DPolygon& 
rPolygon(rPolygonHairlinePrimitive2D.getB2DPolygon());
 
     if (!rPolygon.count())
+    {
+        // no geometry, done
         return;
+    }
 
     bool bDone(false);
     std::shared_ptr<SystemDependentData_ID2D1PathGeometry> 
pSystemDependentData_ID2D1PathGeometry(
@@ -729,41 +708,38 @@ void 
D2DPixelProcessor2D::processPolygonHairlinePrimitive2D(
 
     if (pSystemDependentData_ID2D1PathGeometry)
     {
-        ID2D1TransformedGeometry* pTransformedGeometry = nullptr;
+        sal::systools::COMReference<ID2D1TransformedGeometry> 
pTransformedGeometry;
         const double fAAOffset(getViewInformation2D().getUseAntiAliasing() ? 
0.5 : 0.0);
         const basegfx::B2DHomMatrix& rObjectToView(
             getViewInformation2D().getObjectToViewTransformation());
-        HRESULT hr = 
aID2D1FactoryProvider.getID2D1Factory()->CreateTransformedGeometry(
+        HRESULT 
hr(aID2D1GlobalFactoryProvider.getID2D1Factory()->CreateTransformedGeometry(
             pSystemDependentData_ID2D1PathGeometry->getID2D1PathGeometry(),
             D2D1::Matrix3x2F(rObjectToView.a(), rObjectToView.b(), 
rObjectToView.c(),
                              rObjectToView.d(), rObjectToView.e() + fAAOffset,
                              rObjectToView.f() + fAAOffset),
-            &pTransformedGeometry);
+            &pTransformedGeometry));
 
-        if (SUCCEEDED(hr))
+        if (SUCCEEDED(hr) && pTransformedGeometry)
         {
             const basegfx::BColor aHairlineColor(
                 
maBColorModifierStack.getModifiedColor(rPolygonHairlinePrimitive2D.getBColor()));
             const D2D1::ColorF aD2DColor(aHairlineColor.getRed(), 
aHairlineColor.getGreen(),
                                          aHairlineColor.getBlue());
-            ID2D1SolidColorBrush* pColorBrush(nullptr);
-            hr = getRenderTarget().CreateSolidColorBrush(aD2DColor, 
&pColorBrush);
+            sal::systools::COMReference<ID2D1SolidColorBrush> pColorBrush;
+            hr = getRenderTarget()->CreateSolidColorBrush(aD2DColor, 
&pColorBrush);
 
-            if (SUCCEEDED(hr))
+            if (SUCCEEDED(hr) && pColorBrush)
             {
-                getRenderTarget().SetTransform(D2D1::Matrix3x2F::Identity());
+                getRenderTarget()->SetTransform(D2D1::Matrix3x2F::Identity());
                 // TODO: Unfortunately Direct2D paint of one pixel wide lines 
does not
                 // correctly and completely blend 100% over the background. 
Experimenting
                 // shows that a value around/slightly below 2.0 is needed 
which hints that
                 // alpha blending the half-shifted lines (see fAAOffset above) 
is involved.
                 // To get correct blending I try to use just wider hairlines 
for now. This
                 // may need to be improved - or balanced (trying sqrt(2) 
now...)
-                getRenderTarget().DrawGeometry(pTransformedGeometry, 
pColorBrush, 1.44f);
+                getRenderTarget()->DrawGeometry(pTransformedGeometry, 
pColorBrush, 1.44f);
                 bDone = true;
-                pColorBrush->Release();
             }
-
-            pTransformedGeometry->Release();
         }
     }
 
@@ -778,7 +754,10 @@ void 
D2DPixelProcessor2D::processPolyPolygonColorPrimitive2D(
     const sal_uInt32 nCount(rPolyPolygon.count());
 
     if (!nCount)
+    {
+        // no geometry, done
         return;
+    }
 
     bool bDone(false);
     std::shared_ptr<SystemDependentData_ID2D1PathGeometry> 
pSystemDependentData_ID2D1PathGeometry(
@@ -786,36 +765,33 @@ void 
D2DPixelProcessor2D::processPolyPolygonColorPrimitive2D(
 
     if (pSystemDependentData_ID2D1PathGeometry)
     {
-        ID2D1TransformedGeometry* pTransformedGeometry = nullptr;
+        sal::systools::COMReference<ID2D1TransformedGeometry> 
pTransformedGeometry;
         const double fAAOffset(getViewInformation2D().getUseAntiAliasing() ? 
0.5 : 0.0);
         const basegfx::B2DHomMatrix& rObjectToView(
             getViewInformation2D().getObjectToViewTransformation());
-        HRESULT hr = 
aID2D1FactoryProvider.getID2D1Factory()->CreateTransformedGeometry(
+        HRESULT 
hr(aID2D1GlobalFactoryProvider.getID2D1Factory()->CreateTransformedGeometry(
             pSystemDependentData_ID2D1PathGeometry->getID2D1PathGeometry(),
             D2D1::Matrix3x2F(rObjectToView.a(), rObjectToView.b(), 
rObjectToView.c(),
                              rObjectToView.d(), rObjectToView.e() + fAAOffset,
                              rObjectToView.f() + fAAOffset),
-            &pTransformedGeometry);
+            &pTransformedGeometry));
 
-        if (SUCCEEDED(hr))
+        if (SUCCEEDED(hr) && pTransformedGeometry)
         {
             const basegfx::BColor aFillColor(
                 
maBColorModifierStack.getModifiedColor(rPolyPolygonColorPrimitive2D.getBColor()));
             const D2D1::ColorF aD2DColor(aFillColor.getRed(), 
aFillColor.getGreen(),
                                          aFillColor.getBlue());
 
-            ID2D1SolidColorBrush* pColorBrush(nullptr);
-            hr = getRenderTarget().CreateSolidColorBrush(aD2DColor, 
&pColorBrush);
+            sal::systools::COMReference<ID2D1SolidColorBrush> pColorBrush;
+            hr = getRenderTarget()->CreateSolidColorBrush(aD2DColor, 
&pColorBrush);
 
-            if (SUCCEEDED(hr))
+            if (SUCCEEDED(hr) && pColorBrush)
             {
-                getRenderTarget().SetTransform(D2D1::Matrix3x2F::Identity());
-                getRenderTarget().FillGeometry(pTransformedGeometry, 
pColorBrush);
+                getRenderTarget()->SetTransform(D2D1::Matrix3x2F::Identity());
+                getRenderTarget()->FillGeometry(pTransformedGeometry, 
pColorBrush);
                 bDone = true;
-                pColorBrush->Release();
             }
-
-            pTransformedGeometry->Release();
         }
     }
 
@@ -839,7 +815,7 @@ void D2DPixelProcessor2D::processBitmapPrimitive2D(
 
         if (!aUnitRange.overlaps(rDiscreteViewPort))
         {
-            // content is outside discrete local ViewPort
+            // content is outside discrete local ViewPort, done
             return;
         }
     }
@@ -848,16 +824,18 @@ void D2DPixelProcessor2D::processBitmapPrimitive2D(
 
     if (aBitmapEx.IsEmpty() || aBitmapEx.GetSizePixel().IsEmpty())
     {
+        // no pixel data, done
         return;
     }
 
     if (maBColorModifierStack.count())
     {
+        // need to apply ColorModifier to Bitmap data
         aBitmapEx = aBitmapEx.ModifyBitmapEx(maBColorModifierStack);
 
         if (aBitmapEx.IsEmpty())
         {
-            // color gets completely replaced, get it
+            // color gets completely replaced, get it (any input works)
             const basegfx::BColor aModifiedColor(
                 maBColorModifierStack.getModifiedColor(basegfx::BColor()));
 
@@ -870,24 +848,25 @@ void D2DPixelProcessor2D::processBitmapPrimitive2D(
                 new 
primitive2d::PolyPolygonColorPrimitive2D(basegfx::B2DPolyPolygon(aPolygon),
                                                              aModifiedColor));
 
+            // draw as Polygon, done
             processPolyPolygonColorPrimitive2D(*aTemp);
             return;
         }
     }
 
     bool bDone(false);
-    ID2D1Bitmap* pD2DBitmap(getOrCreateB2DBitmap(getRenderTarget(), 
aBitmapEx));
+    sal::systools::COMReference<ID2D1Bitmap> pD2DBitmap(
+        getOrCreateB2DBitmap(getRenderTarget(), aBitmapEx));
 
-    if (nullptr != pD2DBitmap)
+    if (pD2DBitmap)
     {
         const double fAAOffset(getViewInformation2D().getUseAntiAliasing() ? 
0.5 : 0.0);
-        getRenderTarget().SetTransform(D2D1::Matrix3x2F(
+        getRenderTarget()->SetTransform(D2D1::Matrix3x2F(
             aLocalTransform.a(), aLocalTransform.b(), aLocalTransform.c(), 
aLocalTransform.d(),
             aLocalTransform.e() + fAAOffset, aLocalTransform.f() + fAAOffset));
 
         // destinationRectangle is part of transformation above, so use 
UnitRange
-        getRenderTarget().DrawBitmap(pD2DBitmap, D2D1::RectF(0.0, 0.0, 1.0, 
1.0));
-        pD2DBitmap->Release();
+        getRenderTarget()->DrawBitmap(pD2DBitmap, D2D1::RectF(0.0, 0.0, 1.0, 
1.0));
         bDone = true;
     }
 
@@ -895,27 +874,28 @@ void D2DPixelProcessor2D::processBitmapPrimitive2D(
         increaseError();
 }
 
-ID2D1Bitmap* D2DPixelProcessor2D::implCreateAlpha_Direct(
+sal::systools::COMReference<ID2D1Bitmap> 
D2DPixelProcessor2D::implCreateAlpha_Direct(
     const primitive2d::TransparencePrimitive2D& rTransCandidate,
     const basegfx::B2DRange& rVisibleRange)
 {
     // Try if we can use ID2D1DeviceContext/d2d1_1 by querying for interface.
     // Only then can we use ID2D1Effect/CLSID_D2D1LuminanceToAlpha and it makes
     // sense to try to do it this way in this implementation
-    ID2D1DeviceContext* pID2D1DeviceContext(nullptr);
-    getRenderTarget().QueryInterface(__uuidof(ID2D1DeviceContext),
-                                     
reinterpret_cast<void**>(&pID2D1DeviceContext));
+    sal::systools::COMReference<ID2D1DeviceContext> pID2D1DeviceContext;
+    getRenderTarget()->QueryInterface(__uuidof(ID2D1DeviceContext),
+                                      
reinterpret_cast<void**>(&pID2D1DeviceContext));
+    sal::systools::COMReference<ID2D1Bitmap> pRetval;
 
-    if (nullptr == pID2D1DeviceContext)
+    if (!pID2D1DeviceContext)
     {
-        // no, done - use fallback by returning empty - we have not the 
preconditions for this
-        return nullptr;
+        // no, done - tell caller to use fallback by returning empty - we have
+        // not the preconditions for this
+        return pRetval;
     }
 
     // Release early, was only a test and I saw comments in docu 
thatQueryInterface
     // does already increase that refcount
-    pID2D1DeviceContext->Release();
-    pID2D1DeviceContext = nullptr;
+    pID2D1DeviceContext.clear();
 
     // I had a former version (call it 'a') where I directly painted to a
     // alpha-only bitmap target, see aAlphaFormat below and refer to
@@ -972,15 +952,14 @@ ID2D1Bitmap* D2DPixelProcessor2D::implCreateAlpha_Direct(
     if (!aSubContentRenderer.valid())
     {
         // did not work, done
-        return nullptr;
+        return pRetval;
     }
 
     // render sub-content recursively
     aSubContentRenderer.process(rTransCandidate.getTransparence());
 
     // grab Bitmap & prepare results from RGBA content rendering
-    ID2D1Bitmap* pInBetweenResult(aSubContentRenderer.getID2D1Bitmap());
-    ID2D1Bitmap* pRetval(nullptr);
+    sal::systools::COMReference<ID2D1Bitmap> 
pInBetweenResult(aSubContentRenderer.getID2D1Bitmap());
 
     // Now we need a target to render this to, using the ID2D1Effect tooling.
     // We can directly apply the effect to an alpha-only 8bit target here,
@@ -989,12 +968,12 @@ ID2D1Bitmap* D2DPixelProcessor2D::implCreateAlpha_Direct(
     // to pContent again, but that does not work due to the bitmap
     // fetched being probably only an internal reference to the
     // ID2D1BitmapRenderTarget, thus it would draw onto itself -> chaos
-    ID2D1BitmapRenderTarget* pContent(nullptr);
+    sal::systools::COMReference<ID2D1BitmapRenderTarget> pContent;
     const D2D1_PIXEL_FORMAT aAlphaFormat(
         D2D1::PixelFormat(DXGI_FORMAT_A8_UNORM, D2D1_ALPHA_MODE_STRAIGHT));
     const D2D1_SIZE_U aRenderTargetSizePixel(
         D2D1::SizeU(ceil(rVisibleRange.getWidth()), 
ceil(rVisibleRange.getHeight())));
-    HRESULT hr(getRenderTarget().CreateCompatibleRenderTarget(
+    const HRESULT hr(getRenderTarget()->CreateCompatibleRenderTarget(
         nullptr, &aRenderTargetSizePixel, &aAlphaFormat, 
D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS_NONE,
         &pContent));
 
@@ -1007,7 +986,7 @@ ID2D1Bitmap* D2DPixelProcessor2D::implCreateAlpha_Direct(
         if (pID2D1DeviceContext)
         {
             // create the effect
-            ID2D1Effect* pLuminanceToAlpha(nullptr);
+            sal::systools::COMReference<ID2D1Effect> pLuminanceToAlpha;
             pID2D1DeviceContext->CreateEffect(CLSID_D2D1LuminanceToAlpha, 
&pLuminanceToAlpha);
 
             if (pLuminanceToAlpha)
@@ -1022,20 +1001,14 @@ ID2D1Bitmap* 
D2DPixelProcessor2D::implCreateAlpha_Direct(
 
                 // grab result
                 pContent->GetBitmap(&pRetval);
-                pLuminanceToAlpha->Release();
             }
-
-            pID2D1DeviceContext->Release();
         }
-
-        pContent->Release();
     }
 
-    pInBetweenResult->Release();
     return pRetval;
 }
 
-ID2D1Bitmap* D2DPixelProcessor2D::implCreateAlpha_B2DBitmap(
+sal::systools::COMReference<ID2D1Bitmap> 
D2DPixelProcessor2D::implCreateAlpha_B2DBitmap(
     const primitive2d::TransparencePrimitive2D& rTransCandidate,
     const basegfx::B2DRange& rVisibleRange, D2D1_MATRIX_3X2_F& rMaskScale)
 {
@@ -1062,11 +1035,12 @@ ID2D1Bitmap* 
D2DPixelProcessor2D::implCreateAlpha_B2DBitmap(
     const AlphaMask aAlpha(::drawinglayer::createAlphaMask(
         std::move(xEmbedSeq), aEmptyViewInformation2D, nDiscreteClippedWidth,
         nDiscreteClippedHeight, nMaximumQuadraticPixels, true));
+    sal::systools::COMReference<ID2D1Bitmap> pRetval;
 
     if (aAlpha.IsEmpty())
     {
         // if we have no content we are done
-        return nullptr;
+        return pRetval;
     }
 
     // use alpha data to create the ID2D1Bitmap
@@ -1088,19 +1062,16 @@ ID2D1Bitmap* 
D2DPixelProcessor2D::implCreateAlpha_B2DBitmap(
         }
     }
 
-    ID2D1Bitmap* pRetval(nullptr);
     const D2D1_BITMAP_PROPERTIES aBmProps(D2D1::BitmapProperties(
         D2D1::PixelFormat(DXGI_FORMAT_A8_UNORM, 
D2D1_ALPHA_MODE_PREMULTIPLIED)));
-    HRESULT hr = getRenderTarget().CreateBitmap(
+    const HRESULT hr(getRenderTarget()->CreateBitmap(
         D2D1::SizeU(rSizePixel.Width(), rSizePixel.Height()), &aData[0],
-        rSizePixel.Width() * sizeof(sal_uInt8), &aBmProps, &pRetval);
+        rSizePixel.Width() * sizeof(sal_uInt8), &aBmProps, &pRetval));
 
-    //  D2D1_BITMAP_PROPERTIES
-
-    if (!SUCCEEDED(hr) || nullptr == pRetval)
+    if (!SUCCEEDED(hr) || !pRetval)
     {
         // did not work, done
-        return nullptr;
+        return pRetval;
     }
 
     // create needed adapted transformation for alpha brush.
@@ -1129,16 +1100,22 @@ void 
D2DPixelProcessor2D::processTransparencePrimitive2D(
     const primitive2d::TransparencePrimitive2D& rTransCandidate)
 {
     if (rTransCandidate.getChildren().empty())
+    {
+        // no content, done
         return;
+    }
 
     if (rTransCandidate.getTransparence().empty())
+    {
+        // no mask (so nothing visible), done
         return;
+    }
 
     // calculate visible range, create only for that range
     basegfx::B2DRange aDiscreteRange(
         rTransCandidate.getChildren().getB2DRange(getViewInformation2D()));
     
aDiscreteRange.transform(getViewInformation2D().getObjectToViewTransformation());
-    const D2D1_SIZE_U aB2DSizePixel(getRenderTarget().GetPixelSize());
+    const D2D1_SIZE_U aB2DSizePixel(getRenderTarget()->GetPixelSize());
     const basegfx::B2DRange aViewRange(0.0, 0.0, aB2DSizePixel.width, 
aB2DSizePixel.height);
     basegfx::B2DRange aVisibleRange(aDiscreteRange);
     aVisibleRange.intersect(aViewRange);
@@ -1150,64 +1127,60 @@ void 
D2DPixelProcessor2D::processTransparencePrimitive2D(
     }
 
     // try to create directly, this needs the current mpRT to be a 
ID2D1DeviceContext/d2d1_1
-    // what is not guaranteed but usually works for more modern windows (after 
7)
-    ID2D1Bitmap* pAlphaBitmap(implCreateAlpha_Direct(rTransCandidate, 
aVisibleRange));
+    // what is not guarenteed but usually works for more modern windows (after 
7)
+    sal::systools::COMReference<ID2D1Bitmap> pAlphaBitmap(
+        implCreateAlpha_Direct(rTransCandidate, aVisibleRange));
     D2D1_MATRIX_3X2_F aMaskScale(D2D1::Matrix3x2F::Identity());
 
-    if (nullptr == pAlphaBitmap)
+    if (!pAlphaBitmap)
     {
         // did not work, use more expensive fallback to existing tooling
         pAlphaBitmap = implCreateAlpha_B2DBitmap(rTransCandidate, 
aVisibleRange, aMaskScale);
     }
 
-    if (nullptr == pAlphaBitmap)
+    if (!pAlphaBitmap)
     {
         // could not create alpha channel, error
         increaseError();
         return;
     }
 
-    ID2D1Layer* pLayer = nullptr;
-    HRESULT hr = getRenderTarget().CreateLayer(nullptr, &pLayer);
+    sal::systools::COMReference<ID2D1Layer> pLayer;
+    HRESULT hr(getRenderTarget()->CreateLayer(nullptr, &pLayer));
     bool bDone(false);
 
-    if (SUCCEEDED(hr))
+    if (SUCCEEDED(hr) && pLayer)
     {
-        ID2D1BitmapBrush* pBitmapBrush = nullptr;
-        hr = getRenderTarget().CreateBitmapBrush(pAlphaBitmap, &pBitmapBrush);
+        sal::systools::COMReference<ID2D1BitmapBrush> pBitmapBrush;
+        hr = getRenderTarget()->CreateBitmapBrush(pAlphaBitmap, &pBitmapBrush);
 
-        if (SUCCEEDED(hr))
+        if (SUCCEEDED(hr) && pBitmapBrush)
         {
             // apply MaskScale to Brush, maybe used if 
implCreateAlpha_B2DBitmap was needed
             pBitmapBrush->SetTransform(aMaskScale);
 
             // need to set transform offset for Layer initialization, we work
             // in discrete device coordinates
-            getRenderTarget().SetTransform(D2D1::Matrix3x2F::Translation(
+            getRenderTarget()->SetTransform(D2D1::Matrix3x2F::Translation(
                 floor(aVisibleRange.getMinX()), 
floor(aVisibleRange.getMinY())));
 
-            
getRenderTarget().PushLayer(D2D1::LayerParameters(D2D1::InfiniteRect(), nullptr,
-                                                              
D2D1_ANTIALIAS_MODE_PER_PRIMITIVE,
-                                                              
D2D1::Matrix3x2F::Identity(), 1.0,
-                                                              pBitmapBrush),
-                                        pLayer);
+            
getRenderTarget()->PushLayer(D2D1::LayerParameters(D2D1::InfiniteRect(), 
nullptr,
+                                                               
D2D1_ANTIALIAS_MODE_PER_PRIMITIVE,
+                                                               
D2D1::Matrix3x2F::Identity(), 1.0,
+                                                               pBitmapBrush),
+                                         pLayer);
 
             // ... but need to reset to paint content unchanged
-            getRenderTarget().SetTransform(D2D1::Matrix3x2F::Identity());
+            getRenderTarget()->SetTransform(D2D1::Matrix3x2F::Identity());
 
-            // draw content
+            // draw content recursively
             process(rTransCandidate.getChildren());
 
-            getRenderTarget().PopLayer();
+            getRenderTarget()->PopLayer();
             bDone = true;
-            pBitmapBrush->Release();
         }
-
-        pLayer->Release();
     }
 
-    pAlphaBitmap->Release();
-
     if (!bDone)
         increaseError();
 }
@@ -1237,7 +1210,7 @@ void 
D2DPixelProcessor2D::processUnifiedTransparencePrimitive2D(
     basegfx::B2DRange aTransparencyRange(
         rTransCandidate.getChildren().getB2DRange(getViewInformation2D()));
     
aTransparencyRange.transform(getViewInformation2D().getObjectToViewTransformation());
-    const D2D1_SIZE_U aB2DSizePixel(getRenderTarget().GetPixelSize());
+    const D2D1_SIZE_U aB2DSizePixel(getRenderTarget()->GetPixelSize());
     const basegfx::B2DRange aViewRange(0.0, 0.0, aB2DSizePixel.width, 
aB2DSizePixel.height);
 
     // not visible, done
@@ -1247,25 +1220,22 @@ void 
D2DPixelProcessor2D::processUnifiedTransparencePrimitive2D(
     }
 
     bool bDone(false);
-    ID2D1Layer* pLayer = nullptr;
-    HRESULT hr = getRenderTarget().CreateLayer(nullptr, &pLayer);
+    sal::systools::COMReference<ID2D1Layer> pLayer;
+    const HRESULT hr(getRenderTarget()->CreateLayer(nullptr, &pLayer));
 
-    if (SUCCEEDED(hr))
+    if (SUCCEEDED(hr) && pLayer)
     {
         // need to set correct transform for Layer initialization, we work
         // in discrete device coordinates
-        getRenderTarget().SetTransform(D2D1::Matrix3x2F::Identity());
-
-        getRenderTarget().PushLayer(
+        getRenderTarget()->SetTransform(D2D1::Matrix3x2F::Identity());
+        getRenderTarget()->PushLayer(
             D2D1::LayerParameters(D2D1::InfiniteRect(), nullptr, 
D2D1_ANTIALIAS_MODE_PER_PRIMITIVE,
                                   D2D1::IdentityMatrix(),
                                   1.0 - rTransCandidate.getTransparence()), // 
opacity
             pLayer);
         process(rTransCandidate.getChildren());
-        getRenderTarget().PopLayer();
+        getRenderTarget()->PopLayer();
         bDone = true;
-
-        pLayer->Release();
     }
 
     if (!bDone)
@@ -1276,20 +1246,29 @@ void D2DPixelProcessor2D::processMaskPrimitive2DPixel(
     const primitive2d::MaskPrimitive2D& rMaskCandidate)
 {
     if (rMaskCandidate.getChildren().empty())
+    {
+        // no content, done
         return;
+    }
 
     basegfx::B2DPolyPolygon aMask(rMaskCandidate.getMask());
 
     if (!aMask.count())
+    {
+        // no mask (so nothing inside), done
         return;
+    }
 
     basegfx::B2DRange aMaskRange(aMask.getB2DRange());
     
aMaskRange.transform(getViewInformation2D().getObjectToViewTransformation());
-    const D2D1_SIZE_U aB2DSizePixel(getRenderTarget().GetPixelSize());
+    const D2D1_SIZE_U aB2DSizePixel(getRenderTarget()->GetPixelSize());
     const basegfx::B2DRange aViewRange(0.0, 0.0, aB2DSizePixel.width, 
aB2DSizePixel.height);
 
     if (!aViewRange.overlaps(aMaskRange))
+    {
+        // not in visible range, done
         return;
+    }
 
     bool bDone(false);
     std::shared_ptr<SystemDependentData_ID2D1PathGeometry> 
pSystemDependentData_ID2D1MaskGeometry(
@@ -1297,36 +1276,31 @@ void D2DPixelProcessor2D::processMaskPrimitive2DPixel(
 
     if (pSystemDependentData_ID2D1MaskGeometry)
     {
-        ID2D1TransformedGeometry* pTransformedMaskGeometry = nullptr;
+        sal::systools::COMReference<ID2D1TransformedGeometry> 
pTransformedMaskGeometry;
         const basegfx::B2DHomMatrix& rObjectToView(
             getViewInformation2D().getObjectToViewTransformation());
-        HRESULT hr = 
aID2D1FactoryProvider.getID2D1Factory()->CreateTransformedGeometry(
+        HRESULT 
hr(aID2D1GlobalFactoryProvider.getID2D1Factory()->CreateTransformedGeometry(
             pSystemDependentData_ID2D1MaskGeometry->getID2D1PathGeometry(),
             D2D1::Matrix3x2F(rObjectToView.a(), rObjectToView.b(), 
rObjectToView.c(),
                              rObjectToView.d(), rObjectToView.e(), 
rObjectToView.f()),
-            &pTransformedMaskGeometry);
+            &pTransformedMaskGeometry));
 
-        if (SUCCEEDED(hr))
+        if (SUCCEEDED(hr) && pTransformedMaskGeometry)
         {
-            ID2D1Layer* pLayer = nullptr;
-            hr = getRenderTarget().CreateLayer(nullptr, &pLayer);
+            sal::systools::COMReference<ID2D1Layer> pLayer;
+            hr = getRenderTarget()->CreateLayer(nullptr, &pLayer);
 
-            if (SUCCEEDED(hr))
+            if (SUCCEEDED(hr) && pLayer)
             {
                 // need to set correct transform for Layer initialization, we 
work
                 // in discrete device coordinates
-                getRenderTarget().SetTransform(D2D1::Matrix3x2F::Identity());
-
-                getRenderTarget().PushLayer(
+                getRenderTarget()->SetTransform(D2D1::Matrix3x2F::Identity());
+                getRenderTarget()->PushLayer(
                     D2D1::LayerParameters(D2D1::InfiniteRect(), 
pTransformedMaskGeometry), pLayer);
                 process(rMaskCandidate.getChildren());
-                getRenderTarget().PopLayer();
+                getRenderTarget()->PopLayer();
                 bDone = true;
-
-                pLayer->Release();
             }
-
-            pTransformedMaskGeometry->Release();
         }
     }
 
@@ -1338,24 +1312,28 @@ void D2DPixelProcessor2D::processPointArrayPrimitive2D(
     const primitive2d::PointArrayPrimitive2D& rPointArrayCandidate)
 {
     const std::vector<basegfx::B2DPoint>& 
rPositions(rPointArrayCandidate.getPositions());
+
     if (rPositions.empty())
+    {
+        // no geometry, done
         return;
+    }
 
     const basegfx::BColor aPointColor(
         
maBColorModifierStack.getModifiedColor(rPointArrayCandidate.getRGBColor()));
-    ID2D1SolidColorBrush* pColorBrush(nullptr);
+    sal::systools::COMReference<ID2D1SolidColorBrush> pColorBrush;
     D2D1::ColorF aD2DColor(aPointColor.getRed(), aPointColor.getGreen(), 
aPointColor.getBlue());
-    HRESULT hr = getRenderTarget().CreateSolidColorBrush(aD2DColor, 
&pColorBrush);
+    const HRESULT hr(getRenderTarget()->CreateSolidColorBrush(aD2DColor, 
&pColorBrush));
     bool bDone(false);
 
-    if (SUCCEEDED(hr))
+    if (SUCCEEDED(hr) && pColorBrush)
     {
-        getRenderTarget().SetTransform(D2D1::Matrix3x2F::Identity());
+        getRenderTarget()->SetTransform(D2D1::Matrix3x2F::Identity());
 
         // To really paint a single pixel I found nothing better than
         // switch off AA and draw a pixel-aligned rectangle
-        const D2D1_ANTIALIAS_MODE 
aOldAAMode(getRenderTarget().GetAntialiasMode());
-        getRenderTarget().SetAntialiasMode(D2D1_ANTIALIAS_MODE_ALIASED);
+        const D2D1_ANTIALIAS_MODE 
aOldAAMode(getRenderTarget()->GetAntialiasMode());
+        getRenderTarget()->SetAntialiasMode(D2D1_ANTIALIAS_MODE_ALIASED);
 
         for (auto const& pos : rPositions)
         {
@@ -1365,12 +1343,11 @@ void D2DPixelProcessor2D::processPointArrayPrimitive2D(
             const double fY(ceil(aDiscretePos.getY()));
             const D2D1_RECT_F rect = { FLOAT(fX), FLOAT(fY), FLOAT(fX), 
FLOAT(fY) };
 
-            getRenderTarget().DrawRectangle(&rect, pColorBrush);
+            getRenderTarget()->DrawRectangle(&rect, pColorBrush);
         }
 
-        getRenderTarget().SetAntialiasMode(aOldAAMode);
+        getRenderTarget()->SetAntialiasMode(aOldAAMode);
         bDone = true;
-        pColorBrush->Release();
     }
 
     if (!bDone)
@@ -1381,19 +1358,28 @@ void D2DPixelProcessor2D::processMarkerArrayPrimitive2D(
     const primitive2d::MarkerArrayPrimitive2D& rMarkerArrayCandidate)
 {
     const std::vector<basegfx::B2DPoint>& 
rPositions(rMarkerArrayCandidate.getPositions());
+
     if (rPositions.empty())
+    {
+        // no geometry, done
         return;
+    }
 
     const BitmapEx& rMarker(rMarkerArrayCandidate.getMarker());
+
     if (rMarker.IsEmpty())
+    {
+        // no marker defined, done
         return;
+    }
 
-    ID2D1Bitmap* pD2DBitmap(getOrCreateB2DBitmap(getRenderTarget(), rMarker));
+    sal::systools::COMReference<ID2D1Bitmap> pD2DBitmap(
+        getOrCreateB2DBitmap(getRenderTarget(), rMarker));
     bool bDone(false);
 
-    if (nullptr != pD2DBitmap)
+    if (pD2DBitmap)
     {
-        getRenderTarget().SetTransform(D2D1::Matrix3x2F::Identity());
+        getRenderTarget()->SetTransform(D2D1::Matrix3x2F::Identity());
         const Size& rSizePixel(rMarker.GetSizePixel());
         const tools::Long nMiX((rSizePixel.Width() / 2) + 1);
         const tools::Long nMiY((rSizePixel.Height() / 2) + 1);
@@ -1401,8 +1387,8 @@ void D2DPixelProcessor2D::processMarkerArrayPrimitive2D(
         const tools::Long nPlY(rSizePixel.Height() - nMiY);
 
         // draw with non-AA to show unhampered, clear, non-scaled marker
-        const D2D1_ANTIALIAS_MODE 
aOldAAMode(getRenderTarget().GetAntialiasMode());
-        getRenderTarget().SetAntialiasMode(D2D1_ANTIALIAS_MODE_ALIASED);
+        const D2D1_ANTIALIAS_MODE 
aOldAAMode(getRenderTarget()->GetAntialiasMode());
+        getRenderTarget()->SetAntialiasMode(D2D1_ANTIALIAS_MODE_ALIASED);
 
         for (auto const& pos : rPositions)
         {
@@ -1413,12 +1399,11 @@ void D2DPixelProcessor2D::processMarkerArrayPrimitive2D(
             const D2D1_RECT_F rect
                 = { FLOAT(fX - nMiX), FLOAT(fY - nMiY), FLOAT(fX + nPlX), 
FLOAT(fY + nPlY) };
 
-            getRenderTarget().DrawBitmap(pD2DBitmap, &rect);
+            getRenderTarget()->DrawBitmap(pD2DBitmap, &rect);
         }
 
-        getRenderTarget().SetAntialiasMode(aOldAAMode);
+        getRenderTarget()->SetAntialiasMode(aOldAAMode);
         bDone = true;
-        pD2DBitmap->Release();
     }
 
     if (!bDone)
@@ -1438,7 +1423,7 @@ void 
D2DPixelProcessor2D::processBackgroundColorPrimitive2D(
                                  
rBackgroundColorCandidate.getBColor().getBlue(),
                                  1.0 - 
rBackgroundColorCandidate.getTransparency());
 
-    getRenderTarget().Clear(aD2DColor);
+    getRenderTarget()->Clear(aD2DColor);
 }
 
 void D2DPixelProcessor2D::processModifiedColorPrimitive2D(
@@ -1532,16 +1517,16 @@ void 
D2DPixelProcessor2D::processPolygonStrokePrimitive2D(
 
     if (pSystemDependentData_ID2D1PathGeometry)
     {
-        ID2D1TransformedGeometry* pTransformedGeometry = nullptr;
+        sal::systools::COMReference<ID2D1TransformedGeometry> 
pTransformedGeometry;
         const double fAAOffset(getViewInformation2D().getUseAntiAliasing() ? 
0.5 : 0.0);
-        HRESULT hr = 
aID2D1FactoryProvider.getID2D1Factory()->CreateTransformedGeometry(
+        HRESULT 
hr(aID2D1GlobalFactoryProvider.getID2D1Factory()->CreateTransformedGeometry(
             pSystemDependentData_ID2D1PathGeometry->getID2D1PathGeometry(),
             D2D1::Matrix3x2F(rObjectToView.a(), rObjectToView.b(), 
rObjectToView.c(),
                              rObjectToView.d(), rObjectToView.e() + fAAOffset,
                              rObjectToView.f() + fAAOffset),
-            &pTransformedGeometry);
+            &pTransformedGeometry));
 
-        if (SUCCEEDED(hr))
+        if (SUCCEEDED(hr) && pTransformedGeometry)
         {
             const basegfx::BColor aLineColor(
                 
maBColorModifierStack.getModifiedColor(rLineAttribute.getColor()));
@@ -1553,12 +1538,12 @@ void 
D2DPixelProcessor2D::processPolygonStrokePrimitive2D(
                 aD2DColor.a = 0.5;
             }
 
-            ID2D1SolidColorBrush* pColorBrush(nullptr);
-            hr = getRenderTarget().CreateSolidColorBrush(aD2DColor, 
&pColorBrush);
+            sal::systools::COMReference<ID2D1SolidColorBrush> pColorBrush;
+            hr = getRenderTarget()->CreateSolidColorBrush(aD2DColor, 
&pColorBrush);
 
-            if (SUCCEEDED(hr))
+            if (SUCCEEDED(hr) && pColorBrush)
             {
-                ID2D1StrokeStyle* pStrokeStyle(nullptr);
+                sal::systools::COMReference<ID2D1StrokeStyle> pStrokeStyle;
                 D2D1_CAP_STYLE aCapStyle(D2D1_CAP_STYLE_FLAT);
                 D2D1_LINE_JOIN aLineJoin(D2D1_LINE_JOIN_MITER);
                 const attribute::StrokeAttribute& rStrokeAttribute(
@@ -1598,7 +1583,7 @@ void D2DPixelProcessor2D::processPolygonStrokePrimitive2D(
                         //     nice, but not what we need or is the standard 
for other graphic systems. Luckily there
                         //     is also D2D1_LINE_JOIN_MITER_OR_BEVEL and 
(after some search) the page
                         //     
https://learn.microsoft.com/en-us/windows/win32/api/d2d1/ne-d2d1-d2d1_line_join
-                        //     which gives some explanation, so that is what 
we need to use.
+                        //     which gives some explanation, so that is what 
we need to use here.
                         // (2) Instead of using an angle in radians (15 deg 
default) MS uses
                         //     "miterLimit is relative to 1/2 LineWidth", so a 
length. After some experimenting
                         //     it shows that the (better understandable) angle 
has to be converted to the length
@@ -1607,6 +1592,8 @@ void D2DPixelProcessor2D::processPolygonStrokePrimitive2D(
                         //     experimentally come to a correction value 
around 0.9925. Since that seems to
                         //     be no obvious numerical value involved somehow 
(and as long as I find no other
                         //     explanation) I will have to use that.
+                        // NOTE: To find that correction value I usd that 
handy bRenderDecomposeForCompareInRed
+                        //       and changes in debugger - as work tipp
                         // With both done I can use Direct2D for Miter 
completely - what is good for speed.
                         aLineJoin = D2D1_LINE_JOIN_MITER_OR_BEVEL;
 
@@ -1647,7 +1634,7 @@ void D2DPixelProcessor2D::processPolygonStrokePrimitive2D(
                     }
                 }
 
-                hr = 
aID2D1FactoryProvider.getID2D1Factory()->CreateStrokeStyle(
+                hr = 
aID2D1GlobalFactoryProvider.getID2D1Factory()->CreateStrokeStyle(
                     D2D1::StrokeStyleProperties(aCapStyle, // startCap
                                                 aCapStyle, // endCap
                                                 aCapStyle, // dashCap
@@ -1658,21 +1645,16 @@ void 
D2DPixelProcessor2D::processPolygonStrokePrimitive2D(
                     bDashUsed ? dashes.data() : nullptr, bDashUsed ? 
dashes.size() : 0,
                     &pStrokeStyle);
 
-                if (SUCCEEDED(hr))
+                if (SUCCEEDED(hr) && pStrokeStyle)
                 {
-                    
getRenderTarget().SetTransform(D2D1::Matrix3x2F::Identity());
-                    getRenderTarget().DrawGeometry(
+                    
getRenderTarget()->SetTransform(D2D1::Matrix3x2F::Identity());
+                    getRenderTarget()->DrawGeometry(
                         pTransformedGeometry, pColorBrush,
                         // TODO: Hairline LineWidth, see comment at 
processPolygonHairlinePrimitive2D
                         bHairline ? 1.44 : fDiscreteLineWidth, pStrokeStyle);
                     bDone = true;
-                    pStrokeStyle->Release();
                 }
-
-                pColorBrush->Release();
             }
-
-            pTransformedGeometry->Release();
         }
     }
 
@@ -1696,16 +1678,16 @@ void 
D2DPixelProcessor2D::processLineRectanglePrimitive2D(
         
maBColorModifierStack.getModifiedColor(rLineRectanglePrimitive2D.getBColor()));
     const D2D1::ColorF aD2DColor(aHairlineColor.getRed(), 
aHairlineColor.getGreen(),
                                  aHairlineColor.getBlue());
-    ID2D1SolidColorBrush* pColorBrush(nullptr);
-    HRESULT hr(getRenderTarget().CreateSolidColorBrush(aD2DColor, 
&pColorBrush));
+    sal::systools::COMReference<ID2D1SolidColorBrush> pColorBrush;
+    const HRESULT hr(getRenderTarget()->CreateSolidColorBrush(aD2DColor, 
&pColorBrush));
     bool bDone(false);
 
-    if (SUCCEEDED(hr))
+    if (SUCCEEDED(hr) && pColorBrush)
     {
         const double fAAOffset(getViewInformation2D().getUseAntiAliasing() ? 
0.5 : 0.0);
         const basegfx::B2DHomMatrix aLocalTransform(
             getViewInformation2D().getObjectToViewTransformation());
-        getRenderTarget().SetTransform(D2D1::Matrix3x2F(
+        getRenderTarget()->SetTransform(D2D1::Matrix3x2F(
             aLocalTransform.a(), aLocalTransform.b(), aLocalTransform.c(), 
aLocalTransform.d(),
             aLocalTransform.e() + fAAOffset, aLocalTransform.f() + fAAOffset));
         const basegfx::B2DRange& 
rRange(rLineRectanglePrimitive2D.getB2DRange());
@@ -1716,7 +1698,7 @@ void D2DPixelProcessor2D::processLineRectanglePrimitive2D(
              * basegfx::B2DVector(1.44, 0.0))
                 .getLength());
 
-        getRenderTarget().DrawRectangle(&rect, pColorBrush, 
fDiscreteLineWidth);
+        getRenderTarget()->DrawRectangle(&rect, pColorBrush, 
fDiscreteLineWidth);
         bDone = true;
     }
 
@@ -1736,23 +1718,23 @@ void 
D2DPixelProcessor2D::processFilledRectanglePrimitive2D(
     const basegfx::BColor aFillColor(
         
maBColorModifierStack.getModifiedColor(rFilledRectanglePrimitive2D.getBColor()));
     const D2D1::ColorF aD2DColor(aFillColor.getRed(), aFillColor.getGreen(), 
aFillColor.getBlue());
-    ID2D1SolidColorBrush* pColorBrush(nullptr);
-    HRESULT hr(getRenderTarget().CreateSolidColorBrush(aD2DColor, 
&pColorBrush));
+    sal::systools::COMReference<ID2D1SolidColorBrush> pColorBrush;
+    const HRESULT hr(getRenderTarget()->CreateSolidColorBrush(aD2DColor, 
&pColorBrush));
     bool bDone(false);
 
-    if (SUCCEEDED(hr))
+    if (SUCCEEDED(hr) && pColorBrush)
     {
         const double fAAOffset(getViewInformation2D().getUseAntiAliasing() ? 
0.5 : 0.0);
         const basegfx::B2DHomMatrix aLocalTransform(
             getViewInformation2D().getObjectToViewTransformation());
-        getRenderTarget().SetTransform(D2D1::Matrix3x2F(
+        getRenderTarget()->SetTransform(D2D1::Matrix3x2F(
             aLocalTransform.a(), aLocalTransform.b(), aLocalTransform.c(), 
aLocalTransform.d(),
             aLocalTransform.e() + fAAOffset, aLocalTransform.f() + fAAOffset));
         const basegfx::B2DRange& 
rRange(rFilledRectanglePrimitive2D.getB2DRange());
         const D2D1_RECT_F rect = { FLOAT(rRange.getMinX()), 
FLOAT(rRange.getMinY()),
                                    FLOAT(rRange.getMaxX()), 
FLOAT(rRange.getMaxY()) };
 
-        getRenderTarget().FillRectangle(&rect, pColorBrush);
+        getRenderTarget()->FillRectangle(&rect, pColorBrush);
         bDone = true;
     }
 
@@ -1766,11 +1748,11 @@ void D2DPixelProcessor2D::processSingleLinePrimitive2D(
     const basegfx::BColor aLineColor(
         
maBColorModifierStack.getModifiedColor(rSingleLinePrimitive2D.getBColor()));
     const D2D1::ColorF aD2DColor(aLineColor.getRed(), aLineColor.getGreen(), 
aLineColor.getBlue());
-    ID2D1SolidColorBrush* pColorBrush(nullptr);
-    HRESULT hr(getRenderTarget().CreateSolidColorBrush(aD2DColor, 
&pColorBrush));
+    sal::systools::COMReference<ID2D1SolidColorBrush> pColorBrush;
+    const HRESULT hr(getRenderTarget()->CreateSolidColorBrush(aD2DColor, 
&pColorBrush));
     bool bDone(false);
 
-    if (SUCCEEDED(hr))
+    if (SUCCEEDED(hr) && pColorBrush)
     {
         const double fAAOffset(getViewInformation2D().getUseAntiAliasing() ? 
0.5 : 0.0);
         basegfx::B2DHomMatrix aLocalTransform(
@@ -1778,13 +1760,13 @@ void D2DPixelProcessor2D::processSingleLinePrimitive2D(
         const basegfx::B2DPoint aStart(aLocalTransform * 
rSingleLinePrimitive2D.getStart());
         const basegfx::B2DPoint aEnd(aLocalTransform * 
rSingleLinePrimitive2D.getEnd());
 
-        getRenderTarget().SetTransform(D2D1::Matrix3x2F::Identity());
+        getRenderTarget()->SetTransform(D2D1::Matrix3x2F::Identity());
         const D2D1_POINT_2F aD2D1Start
             = { FLOAT(aStart.getX() + fAAOffset), FLOAT(aStart.getY() + 
fAAOffset) };
         const D2D1_POINT_2F aD2D1End
             = { FLOAT(aEnd.getX() + fAAOffset), FLOAT(aEnd.getY() + fAAOffset) 
};
 
-        getRenderTarget().DrawLine(aD2D1Start, aD2D1End, pColorBrush, 1.44f);
+        getRenderTarget()->DrawLine(aD2D1Start, aD2D1End, pColorBrush, 1.44f);
         bDone = true;
     }
 
@@ -1795,12 +1777,19 @@ void D2DPixelProcessor2D::processSingleLinePrimitive2D(
 void D2DPixelProcessor2D::processBasePrimitive2D(const 
primitive2d::BasePrimitive2D& rCandidate)
 {
     if (0 == mnRecursionCounter)
-        getRenderTarget().BeginDraw();
+        getRenderTarget()->BeginDraw();
     mnRecursionCounter++;
 
     switch (rCandidate.getPrimitive2DID())
     {
-        // geometry that *has* to be processed
+        // Geometry that *has* to be processed
+        //
+        // These Primitives have *no* decompose implementation, so these are 
the basic ones
+        // Just four to go to make a processor work completely (but not 
optimized)
+        // NOTE: This *could* theoretically be reduced to one and all could 
implement
+        //       a decompose to pixel data, but that seemed not to make sense 
to me when
+        //       I designed this. Thus these four are the lowest-level best 
representation
+        //       from my POV
         case PRIMITIVE2D_ID_BITMAPPRIMITIVE2D:
         {
             processBitmapPrimitive2D(
@@ -1826,7 +1815,16 @@ void D2DPixelProcessor2D::processBasePrimitive2D(const 
primitive2d::BasePrimitiv
             break;
         }
 
-        // embedding/groups that *have* to be processed
+        // Embedding/groups that *have* to be processed
+        //
+        // These represent qualifiers for freely defined content, e.g. making
+        // any combinatiopn of priitives freely transformed or transparent
+        // NOTE: PRIMITIVE2D_ID_MODIFIEDCOLORPRIMITIVE2D and
+        //       PRIMITIVE2D_ID_TRANSFORMPRIMITIVE2D are pretty much default-
+        //       implementations that cand and are re-used in all processors.
+        // So - with these and PRIMITIVE2D_ID_INVERTPRIMITIVE2D marked to
+        // be removed in the future - just three really to be implemented
+        // locally specifically
         case PRIMITIVE2D_ID_TRANSPARENCEPRIMITIVE2D:
         {
             processTransparencePrimitive2D(
@@ -1837,7 +1835,9 @@ void D2DPixelProcessor2D::processBasePrimitive2D(const 
primitive2d::BasePrimitiv
         {
             // TODO: fallback is at 
VclPixelProcessor2D::processInvertPrimitive2D, so
             // not in reach. Ignore for now.
-            // processInvertPrimitive2D(rCandidate);
+            // NOTE: We *urgently* need to get rid of the last parts in LO 
that use
+            //       XOR paint. Modern graphic systems allow no read access to 
the
+            //       pixel targets, but that's naturally a precondition for XOR
             break;
         }
         case PRIMITIVE2D_ID_MASKPRIMITIVE2D:
@@ -1859,52 +1859,70 @@ void D2DPixelProcessor2D::processBasePrimitive2D(const 
primitive2d::BasePrimitiv
             break;
         }
 
-        // geometry that *may* be processed due to being able to do it better
-        // then using the decomposition
+        // Geometry that *may* be processed due to being able to do it better
+        // then using the decomposition.
+        // NOTE: In these implementations you could always call what the 
default
+        //       case below does - call process(rCandidate) to use the 
decomposition.
+        //       So these impls should only do something if they can do it 
better/
+        //       faster that the decomposition. So some of them check if they 
could
+        //       - and if not - use exactly that.
         case PRIMITIVE2D_ID_UNIFIEDTRANSPARENCEPRIMITIVE2D:
         {
+            // transparence with a fixed alpha for all content, can be done
+            // significally faster
             processUnifiedTransparencePrimitive2D(
                 static_cast<const 
primitive2d::UnifiedTransparencePrimitive2D&>(rCandidate));
             break;
         }
         case PRIMITIVE2D_ID_MARKERARRAYPRIMITIVE2D:
         {
+            // can be done simpler and without AA better locally
             processMarkerArrayPrimitive2D(
                 static_cast<const 
primitive2d::MarkerArrayPrimitive2D&>(rCandidate));
             break;
         }
         case PRIMITIVE2D_ID_BACKGROUNDCOLORPRIMITIVE2D:
         {
+            // reset to a color, can be done more effectively locally, would
+            // else decompose to a polygon fill
             processBackgroundColorPrimitive2D(
                 static_cast<const 
primitive2d::BackgroundColorPrimitive2D&>(rCandidate));
             break;
         }
         case PRIMITIVE2D_ID_POLYGONSTROKEPRIMITIVE2D:
         {
+            // fat and stroked lines - much better doable locally, would 
decompose
+            // to the full line geometry creation (tesselation)
             processPolygonStrokePrimitive2D(
                 static_cast<const 
primitive2d::PolygonStrokePrimitive2D&>(rCandidate));
             break;
         }
         case PRIMITIVE2D_ID_LINERECTANGLEPRIMITIVE2D:
         {
+            // simple primitve to support future fast callbacks from 
OutputDevice
+            // (see 'Example POC' in Gerrit), decomposes to polygon primitive
             processLineRectanglePrimitive2D(
                 static_cast<const 
primitive2d::LineRectanglePrimitive2D&>(rCandidate));
             break;
         }
         case PRIMITIVE2D_ID_FILLEDRECTANGLEPRIMITIVE2D:
         {
+            // simple primitve to support future fast callbacks from 
OutputDevice
+            // (see 'Example POC' in Gerrit), decomposes to filled polygon 
primitive
             processFilledRectanglePrimitive2D(
                 static_cast<const 
primitive2d::FilledRectanglePrimitive2D&>(rCandidate));
             break;
         }
         case PRIMITIVE2D_ID_SINGLELINEPRIMITIVE2D:
         {
+            // simple primitve to support future fast callbacks from 
OutputDevice
+            // (see 'Example POC' in Gerrit), decomposes to polygon primitive
             processSingleLinePrimitive2D(
                 static_cast<const 
primitive2d::SingleLinePrimitive2D&>(rCandidate));
             break;
         }
 
-        // continue with decompose
+        // continue with decompose as fallback
         default:
         {
             SAL_INFO("drawinglayer", "default case for " << 
drawinglayer::primitive2d::idToString(
@@ -1917,7 +1935,7 @@ void D2DPixelProcessor2D::processBasePrimitive2D(const 
primitive2d::BasePrimitiv
 
     mnRecursionCounter--;
     if (0 == mnRecursionCounter)
-        getRenderTarget().EndDraw();
+        getRenderTarget()->EndDraw();
 }
 } // end of namespace
 
diff --git a/include/drawinglayer/processor2d/d2dpixelprocessor2d.hxx 
b/include/drawinglayer/processor2d/d2dpixelprocessor2d.hxx
index a08fef7b7ae2..10f9a11cb296 100644
--- a/include/drawinglayer/processor2d/d2dpixelprocessor2d.hxx
+++ b/include/drawinglayer/processor2d/d2dpixelprocessor2d.hxx
@@ -21,6 +21,7 @@
 
 #include <drawinglayer/processor2d/baseprocessor2d.hxx>
 #include <basegfx/color/bcolormodifier.hxx>
+#include <systools/win32/comtools.hxx>
 #include <sal/config.h>
 
 // win-specific
@@ -56,7 +57,7 @@ class DRAWINGLAYER_DLLPUBLIC D2DPixelProcessor2D : public 
BaseProcessor2D
     basegfx::BColorModifierStack maBColorModifierStack;
 
     // win and render specific data
-    ID2D1RenderTarget* mpRT;
+    sal::systools::COMReference<ID2D1RenderTarget> mpRT;
     sal_uInt32 mnRecursionCounter;
     sal_uInt32 mnErrorCounter;
 
@@ -90,9 +91,10 @@ class DRAWINGLAYER_DLLPUBLIC D2DPixelProcessor2D : public 
BaseProcessor2D
     processSingleLinePrimitive2D(const primitive2d::SingleLinePrimitive2D& 
rSingleLinePrimitive2D);
 
     // common helpers
-    ID2D1Bitmap* implCreateAlpha_Direct(const 
primitive2d::TransparencePrimitive2D& rTransCandidate,
-                                        const basegfx::B2DRange& 
rVisibleRange);
-    ID2D1Bitmap*
+    sal::systools::COMReference<ID2D1Bitmap>
+    implCreateAlpha_Direct(const primitive2d::TransparencePrimitive2D& 
rTransCandidate,
+                           const basegfx::B2DRange& rVisibleRange);
+    sal::systools::COMReference<ID2D1Bitmap>
     implCreateAlpha_B2DBitmap(const primitive2d::TransparencePrimitive2D& 
rTransCandidate,
                               const basegfx::B2DRange& rVisibleRange,
                               D2D1_MATRIX_3X2_F& rMaskScale);
@@ -109,14 +111,17 @@ protected:
     // local protected minimal accessors for usage in derivates, e.g. helpers
     void increaseError() { mnErrorCounter++; }
     bool hasError() const { return 0 != mnErrorCounter; }
-    void setRenderTarget(ID2D1RenderTarget* mpNewRT) { mpRT = mpNewRT; }
-    bool hasRenderTarget() const { return nullptr != mpRT; }
-    ID2D1RenderTarget& getRenderTarget() { return *mpRT; }
+    bool hasRenderTarget() const { return mpRT.is(); }
+
+    void setRenderTarget(const sal::systools::COMReference<ID2D1RenderTarget>& 
rNewRT)
+    {
+        mpRT = rNewRT;
+    }
+    sal::systools::COMReference<ID2D1RenderTarget>& getRenderTarget() { return 
mpRT; }
 
 public:
     bool valid() const { return hasRenderTarget() && !hasError(); }
     D2DPixelProcessor2D(const geometry::ViewInformation2D& rViewInformation, 
HDC aHdc);
-    virtual ~D2DPixelProcessor2D() override;
 };
 }
 

Reply via email to