include/svx/sdr/contact/viewobjectcontact.hxx |    3 ++
 include/svx/svdmodel.hxx                      |    4 +++
 sc/source/core/data/drwlayer.cxx              |    2 +
 sd/source/core/drawdoc.cxx                    |    2 +
 svx/source/sdr/contact/viewobjectcontact.cxx  |   34 +++++++++++++++++++++-----
 svx/source/svdraw/svdmodel.cxx                |    1 
 6 files changed, 40 insertions(+), 6 deletions(-)

New commits:
commit 9a850dd9f3c221660b6259bdfd64a77343f2256c
Author:     Noel Grandin <[email protected]>
AuthorDate: Wed Jan 12 10:27:38 2022 +0200
Commit:     Noel Grandin <[email protected]>
CommitDate: Wed Jan 12 14:45:30 2022 +0100

    used cache value in ViewObjectContact::getPrimitive2DSequence (2nd attempt)
    
    Rely on the cached primitives in VOC.
    
    But only enable it for calc and draw right now, by adding a flag
    at the SdrModel level.
    
    This way we can leave it disabled for writer, where it definitely doesn't
    work.
    
    Change-Id: I11ca4836eb773c0f078cdb82056c6e0309d15a8b
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/128319
    Tested-by: Jenkins
    Reviewed-by: Noel Grandin <[email protected]>

diff --git a/include/svx/sdr/contact/viewobjectcontact.hxx 
b/include/svx/sdr/contact/viewobjectcontact.hxx
index f13f247e55c2..1be4cac81052 100644
--- a/include/svx/sdr/contact/viewobjectcontact.hxx
+++ b/include/svx/sdr/contact/viewobjectcontact.hxx
@@ -59,6 +59,9 @@ private:
     // possible on-demand calculated GridOffset for non-linear ViewToDevice 
transformation (calc)
     basegfx::B2DVector                              maGridOffset;
 
+    // used to detect ActionChanged() during primitive construction
+    int                                             mnActionChangedCount;
+
     // This bool gets set when the object gets invalidated by ActionChanged() 
and
     // can be used from the OC to late-invalidates
     bool                                            mbLazyInvalidate : 1;
diff --git a/include/svx/svdmodel.hxx b/include/svx/svdmodel.hxx
index 831201de4d60..2170f78907ed 100644
--- a/include/svx/svdmodel.hxx
+++ b/include/svx/svdmodel.hxx
@@ -210,6 +210,7 @@ protected:
     bool                m_bPasteResize:1; // Objects are being resized due to 
Paste with different MapMode
     bool                m_bStarDrawPreviewMode:1;
     bool                mbDisableTextEditUsesCommonUndoManager:1;
+    bool                mbVOCInvalidationIsReliable:1; // does the app 
reliably invalidate the VOC, or do we need to rebuild the primitives on every 
render?
     sal_uInt16          m_nDefaultTabulator;
     sal_uInt32          m_nMaxUndoCount;
 
@@ -612,6 +613,9 @@ public:
     virtual sal_Int32 getImagePreferredDPI() const { return 0; }
 
     virtual void dumpAsXml(xmlTextWriterPtr pWriter) const;
+
+    bool IsVOCInvalidationIsReliable() const { return 
mbVOCInvalidationIsReliable; }
+    void SetVOCInvalidationIsReliable(bool b) { mbVOCInvalidationIsReliable = 
b; }
 };
 
 /*
diff --git a/sc/source/core/data/drwlayer.cxx b/sc/source/core/data/drwlayer.cxx
index 3503ae9cd949..e5a11b57555e 100644
--- a/sc/source/core/data/drwlayer.cxx
+++ b/sc/source/core/data/drwlayer.cxx
@@ -239,6 +239,8 @@ ScDrawLayer::ScDrawLayer( ScDocument* pDocument, const 
OUString& rName ) :
     bAdjustEnabled( true ),
     bHyphenatorSet( false )
 {
+    SetVOCInvalidationIsReliable(true);
+
     pGlobalDrawPersist = nullptr;          // Only use once
 
     SfxObjectShell* pObjSh = pDocument ? pDocument->GetDocumentShell() : 
nullptr;
diff --git a/sd/source/core/drawdoc.cxx b/sd/source/core/drawdoc.cxx
index d765e3639288..0e7ad9dabd44 100644
--- a/sd/source/core/drawdoc.cxx
+++ b/sd/source/core/drawdoc.cxx
@@ -139,6 +139,8 @@ SdDrawDocument::SdDrawDocument(DocumentType eType, 
SfxObjectShell* pDrDocSh)
 , mbEmbedFontScriptComplex(true)
 , mnImagePreferredDPI(0)
 {
+    SetVOCInvalidationIsReliable(true);
+
     mpDrawPageListWatcher.reset(new ImpDrawPageListWatcher(*this));
     mpMasterPageListWatcher.reset(new ImpMasterPageListWatcher(*this));
 
diff --git a/svx/source/sdr/contact/viewobjectcontact.cxx 
b/svx/source/sdr/contact/viewobjectcontact.cxx
index 1dd8fef29415..6577b784f446 100644
--- a/svx/source/sdr/contact/viewobjectcontact.cxx
+++ b/svx/source/sdr/contact/viewobjectcontact.cxx
@@ -29,6 +29,8 @@
 #include <drawinglayer/processor2d/baseprocessor2d.hxx>
 #include <svx/sdr/primitive2d/svx_primitivetypes2d.hxx>
 #include <drawinglayer/primitive2d/transformprimitive2d.hxx>
+#include <svx/svdobj.hxx>
+#include <svx/svdmodel.hxx>
 
 using namespace com::sun::star;
 
@@ -147,6 +149,7 @@ ViewObjectContact::ViewObjectContact(ObjectContact& 
rObjectContact, ViewContact&
 :   mrObjectContact(rObjectContact),
     mrViewContact(rViewContact),
     maGridOffset(0.0, 0.0),
+    mnActionChangedCount(0),
     mbLazyInvalidate(false)
 {
     // make the ViewContact remember me
@@ -193,7 +196,7 @@ const basegfx::B2DRange& 
ViewObjectContact::getObjectRange() const
         {
             // if range is not computed (new or LazyInvalidate objects), force 
it
             const DisplayInfo aDisplayInfo;
-            const drawinglayer::primitive2d::Primitive2DContainer 
xSequence(getPrimitive2DSequence(aDisplayInfo));
+            const drawinglayer::primitive2d::Primitive2DContainer& 
xSequence(getPrimitive2DSequence(aDisplayInfo));
 
             if(!xSequence.empty())
             {
@@ -208,6 +211,10 @@ const basegfx::B2DRange& 
ViewObjectContact::getObjectRange() const
 
 void ViewObjectContact::ActionChanged()
 {
+    // clear cached primitives
+    mxPrimitive2DSequence.clear();
+    ++mnActionChangedCount;
+
     if(mbLazyInvalidate)
         return;
 
@@ -330,6 +337,14 @@ void ViewObjectContact::createPrimitive2DSequence(const 
DisplayInfo& rDisplayInf
 
 drawinglayer::primitive2d::Primitive2DContainer const & 
ViewObjectContact::getPrimitive2DSequence(const DisplayInfo& rDisplayInfo) const
 {
+    // only some of the top-level apps are any good at reliably invalidating 
us (e.g. writer is not)
+    if (SdrObject* pSdrObj = mrViewContact.TryToGetSdrObject())
+        if (pSdrObj->getSdrModelFromSdrObject().IsVOCInvalidationIsReliable())
+        {
+            if (!mxPrimitive2DSequence.empty())
+                return mxPrimitive2DSequence;
+        }
+
     /**
     This method is weird because
     (1) we have to re-walk the primitive tree because the flushing is 
unreliable
@@ -415,21 +430,28 @@ void 
ViewObjectContact::getPrimitive2DSequenceHierarchy(DisplayInfo& rDisplayInf
     if(!isPrimitiveVisible(rDisplayInfo))
         return;
 
-    drawinglayer::primitive2d::Primitive2DContainer xRetval = 
getPrimitive2DSequence(rDisplayInfo);
-    if(xRetval.empty())
+    getPrimitive2DSequence(rDisplayInfo);
+    if(mxPrimitive2DSequence.empty())
         return;
 
     // get ranges
     const drawinglayer::geometry::ViewInformation2D& 
rViewInformation2D(GetObjectContact().getViewInformation2D());
-    const basegfx::B2DRange 
aObjectRange(xRetval.getB2DRange(rViewInformation2D));
     const basegfx::B2DRange& aViewRange(rViewInformation2D.getViewport());
 
     // check geometrical visibility
-    bool bVisible = aViewRange.isEmpty() || aViewRange.overlaps(aObjectRange);
+    bool bVisible = aViewRange.isEmpty() || aViewRange.overlaps(maObjectRange);
     if(!bVisible)
         return;
 
-    rVisitor.visit(std::move(xRetval));
+    // temporarily take over the mxPrimitive2DSequence, in case it gets 
invalidated while we want to iterate over it
+    auto tmp = 
std::move(const_cast<ViewObjectContact*>(this)->mxPrimitive2DSequence);
+    int nPrevCount = mnActionChangedCount;
+
+    rVisitor.visit(tmp);
+
+    // if we received ActionChanged() calls while walking the primitives, then 
leave it empty, otherwise move it back
+    if (mnActionChangedCount == nPrevCount)
+        const_cast<ViewObjectContact*>(this)->mxPrimitive2DSequence = 
std::move(tmp);
 }
 
 void ViewObjectContact::getPrimitive2DSequenceSubHierarchy(DisplayInfo& 
rDisplayInfo, drawinglayer::primitive2d::Primitive2DDecompositionVisitor& 
rVisitor) const
diff --git a/svx/source/svdraw/svdmodel.cxx b/svx/source/svdraw/svdmodel.cxx
index 8a19ce2b27a7..e8d69ab8412a 100644
--- a/svx/source/svdraw/svdmodel.cxx
+++ b/svx/source/svdraw/svdmodel.cxx
@@ -121,6 +121,7 @@ SdrModel::SdrModel(SfxItemPool* pPool, 
comphelper::IEmbeddedHelper* pEmbeddedHel
     , m_bPasteResize(false)
     , m_bStarDrawPreviewMode(false)
     , mbDisableTextEditUsesCommonUndoManager(false)
+    , mbVOCInvalidationIsReliable(false)
     , m_nDefaultTabulator(0)
     , m_nMaxUndoCount(16)
     , m_pTextChain(new TextChain)

Reply via email to