include/svx/sdr/contact/viewcontact.hxx               |    7 ++++
 include/svx/sdr/contact/viewobjectcontactofsdrobj.hxx |    2 +
 svx/inc/sdr/contact/viewcontactofsdrpage.hxx          |    7 ++++
 svx/source/sdr/contact/viewcontact.cxx                |    9 ++++-
 svx/source/sdr/contact/viewcontactofsdrpage.cxx       |   29 ++++++++++++++++--
 svx/source/sdr/contact/viewobjectcontact.cxx          |    9 +----
 svx/source/sdr/contact/viewobjectcontactofsdrobj.cxx  |    9 ++++-
 7 files changed, 61 insertions(+), 11 deletions(-)

New commits:
commit 9e6ce2a4ea7f259c84d54b2e81739d6414ca344b
Author:     Caolán McNamara <[email protected]>
AuthorDate: Wed Aug 2 17:16:17 2023 +0100
Commit:     Caolán McNamara <[email protected]>
CommitDate: Fri Aug 4 14:08:32 2023 +0200

    Related: cool#6911 opt to skip SdrObject::GetViewContent() when possible
    
    as seen in: 
https://user-images.githubusercontent.com/122848/253732636-3dfeddad-f146-4268-bde5-85788b72d539.svg
    
    SdrPageView::DrawLayer takes ~11% of the time when scrolling with
    many comments in calc, but none of these comments actually get drawn,
    all this effort is to find that they are not to be drawn.
    
    optimize ViewContactOfPageHierarchy impl over its parent impl to skip
    SdrObject::GetViewContent(), etc if the SdrObject isn't shown on the
    target layer.
    
    ViewObjectContactOfSdrobject::getPrimitive2DSequenceHierarchy does the
    same check, but after a set of allocations which is expensive in the
    case of SdrCaptions in a calc internal layer where there can be
    thousands of such objects.
    
    Change-Id: Iad86c77e8fa71ec90f54ce06d5a27c0380fb03ab
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/155285
    Tested-by: Jenkins CollaboraOffice <[email protected]>
    Reviewed-by: Noel Grandin <[email protected]>
    Reviewed-by: Caolán McNamara <[email protected]>

diff --git a/include/svx/sdr/contact/viewcontact.hxx 
b/include/svx/sdr/contact/viewcontact.hxx
index 1491d0a1401d..7b6d0f3ab2c1 100644
--- a/include/svx/sdr/contact/viewcontact.hxx
+++ b/include/svx/sdr/contact/viewcontact.hxx
@@ -148,7 +148,9 @@ public:
     // It is always possible to delete the VOCs, these are re-created on demand
     void flushViewObjectContacts(bool bWithHierarchy = true);
 
-    void getPrimitive2DSequenceHierarchyOfIndex(
+    // helper around getPrimitive2DSequenceHierarchy to enable a given 
implementation
+    // to optimize getting a Primitive2DSequenceHierarchy for a child of index 
a
+    virtual void getPrimitive2DSequenceHierarchyOfIndex(
         sal_uInt32 a, DisplayInfo& rDisplayInfo, ObjectContact& rObjectContact,
         drawinglayer::primitive2d::Primitive2DDecompositionVisitor& rVisitor);
 };
diff --git a/include/svx/sdr/contact/viewobjectcontactofsdrobj.hxx 
b/include/svx/sdr/contact/viewobjectcontactofsdrobj.hxx
index 5989559c758e..0ea6f307a22c 100644
--- a/include/svx/sdr/contact/viewobjectcontactofsdrobj.hxx
+++ b/include/svx/sdr/contact/viewobjectcontactofsdrobj.hxx
@@ -56,6 +56,8 @@ public:
         This method cares for this, by retrieving the very original 
OutputDevice.
     */
     const OutputDevice* getPageViewOutputDevice() const;
+
+    static bool isObjectVisibleOnAnyLayer(const SdrObject& rObject, const 
SdrLayerIDSet& rLayers);
 };
 }
 
diff --git a/svx/inc/sdr/contact/viewcontactofsdrpage.hxx 
b/svx/inc/sdr/contact/viewcontactofsdrpage.hxx
index 98d6f577e86e..0f7143aebcda 100644
--- a/svx/inc/sdr/contact/viewcontactofsdrpage.hxx
+++ b/svx/inc/sdr/contact/viewcontactofsdrpage.hxx
@@ -113,12 +113,19 @@ class ViewContactOfPageHierarchy final : public 
ViewContactOfPageSubObject
     virtual ViewObjectContact& 
CreateObjectSpecificViewObjectContact(ObjectContact& rObjectContact) override;
     virtual void 
createViewIndependentPrimitive2DSequence(drawinglayer::primitive2d::Primitive2DDecompositionVisitor&
 rVisitor) const override;
 
+    SdrObject& GetSdrObject(sal_uInt32 nIndex) const;
+
 public:
     explicit ViewContactOfPageHierarchy(ViewContactOfSdrPage& 
rParentViewContactOfSdrPage);
     virtual ~ViewContactOfPageHierarchy() override;
 
     virtual sal_uInt32 GetObjectCount() const override;
     virtual ViewContact& GetViewContact(sal_uInt32 nIndex) const override;
+
+    // optimize version of parent impl to quicker skip hidden SdrObjects
+    virtual void getPrimitive2DSequenceHierarchyOfIndex(
+        sal_uInt32 a, DisplayInfo& rDisplayInfo, ObjectContact& rObjectContact,
+        drawinglayer::primitive2d::Primitive2DDecompositionVisitor& rVisitor) 
override;
 };
 
 class ViewContactOfGrid final : public ViewContactOfPageSubObject
diff --git a/svx/source/sdr/contact/viewcontactofsdrpage.cxx 
b/svx/source/sdr/contact/viewcontactofsdrpage.cxx
index 0f04045815b5..888fe1dc34dc 100644
--- a/svx/source/sdr/contact/viewcontactofsdrpage.cxx
+++ b/svx/source/sdr/contact/viewcontactofsdrpage.cxx
@@ -18,6 +18,7 @@
  */
 
 #include <sdr/contact/viewcontactofsdrpage.hxx>
+#include <svx/sdr/contact/displayinfo.hxx>
 #include <svx/sdr/contact/viewobjectcontact.hxx>
 #include <svx/svdpage.hxx>
 #include <sdr/contact/viewobjectcontactofsdrpage.hxx>
@@ -27,6 +28,7 @@
 #include <tools/debug.hxx>
 #include <vcl/svapp.hxx>
 #include <svx/sdr/contact/objectcontact.hxx>
+#include <svx/sdr/contact/viewobjectcontactofsdrobj.hxx>
 #include <drawinglayer/primitive2d/backgroundcolorprimitive2d.hxx>
 #include <drawinglayer/primitive2d/PolygonHairlinePrimitive2D.hxx>
 #include <drawinglayer/primitive2d/PolyPolygonColorPrimitive2D.hxx>
@@ -400,11 +402,34 @@ sal_uInt32 ViewContactOfPageHierarchy::GetObjectCount() 
const
     return getPage().GetObjCount();
 }
 
-ViewContact& ViewContactOfPageHierarchy::GetViewContact(sal_uInt32 nIndex) 
const
+SdrObject& ViewContactOfPageHierarchy::GetSdrObject(sal_uInt32 nIndex) const
 {
     SdrObject* pObj = getPage().GetObj(nIndex);
     assert(pObj && "ViewContactOfPageHierarchy::GetViewContact: Corrupt 
SdrObjList (!)");
-    return pObj->GetViewContact();
+    return *pObj;
+}
+
+ViewContact& ViewContactOfPageHierarchy::GetViewContact(sal_uInt32 nIndex) 
const
+{
+    return GetSdrObject(nIndex).GetViewContact();
+}
+
+void ViewContactOfPageHierarchy::getPrimitive2DSequenceHierarchyOfIndex(
+    sal_uInt32 nIndex, DisplayInfo& rDisplayInfo, ObjectContact& 
rObjectContact,
+    drawinglayer::primitive2d::Primitive2DDecompositionVisitor& rVisitor)
+{
+    SdrObject& rSdrObject(GetSdrObject(nIndex));
+
+    // optimization over parent impl to skip SdrObject::GetViewContent(), etc 
if the SdrObject isn't
+    // shown on the target layer. 
ViewObjectContactOfSdrobject::getPrimitive2DSequenceHierarchy does
+    // the same check, but after a set of allocations which is expensive in 
the case of SdrCaptions
+    // in a calc internal layer where there can be thousands of such objects.
+    if (!ViewObjectContactOfSdrObj::isObjectVisibleOnAnyLayer(rSdrObject, 
rDisplayInfo.GetProcessLayers()))
+        return;
+
+    ViewContact& rViewContact = rSdrObject.GetViewContact();
+    const ViewObjectContact& 
rCandidate(rViewContact.GetViewObjectContact(rObjectContact));
+    rCandidate.getPrimitive2DSequenceHierarchy(rDisplayInfo, rVisitor);
 }
 
 ViewObjectContact& 
ViewContactOfGrid::CreateObjectSpecificViewObjectContact(ObjectContact& 
rObjectContact)
diff --git a/svx/source/sdr/contact/viewobjectcontactofsdrobj.cxx 
b/svx/source/sdr/contact/viewobjectcontactofsdrobj.cxx
index f87906240338..0cc353a5b65c 100644
--- a/svx/source/sdr/contact/viewobjectcontactofsdrobj.cxx
+++ b/svx/source/sdr/contact/viewobjectcontactofsdrobj.cxx
@@ -50,9 +50,14 @@ ViewObjectContactOfSdrObj::~ViewObjectContactOfSdrObj()
 {
 }
 
-bool ViewObjectContactOfSdrObj::isPrimitiveVisibleOnAnyLayer(const 
SdrLayerIDSet& aLayers) const
+bool ViewObjectContactOfSdrObj::isObjectVisibleOnAnyLayer(const SdrObject& 
rSdrObject, const SdrLayerIDSet& rLayers)
 {
-    return aLayers.IsSet(getSdrObject().GetLayer());
+    return rLayers.IsSet(rSdrObject.GetLayer());
+}
+
+bool ViewObjectContactOfSdrObj::isPrimitiveVisibleOnAnyLayer(const 
SdrLayerIDSet& rLayers) const
+{
+    return 
ViewObjectContactOfSdrObj::isObjectVisibleOnAnyLayer(getSdrObject(), rLayers);
 }
 
 bool ViewObjectContactOfSdrObj::isPrimitiveVisible(const DisplayInfo& 
rDisplayInfo) const
commit e48e048a1c2e60831daada70d9a7a76584bbc46e
Author:     Caolán McNamara <[email protected]>
AuthorDate: Wed Aug 2 17:09:19 2023 +0100
Commit:     Caolán McNamara <[email protected]>
CommitDate: Fri Aug 4 14:08:22 2023 +0200

    Related: cool#6911 refactor for an optimization
    
    no change intended here
    
    Change-Id: I34b72776b1a05979fbe3a02ff1548b6aa8a183df
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/155244
    Tested-by: Jenkins CollaboraOffice <[email protected]>
    Reviewed-by: Caolán McNamara <[email protected]>

diff --git a/include/svx/sdr/contact/viewcontact.hxx 
b/include/svx/sdr/contact/viewcontact.hxx
index ffdc6d055008..1491d0a1401d 100644
--- a/include/svx/sdr/contact/viewcontact.hxx
+++ b/include/svx/sdr/contact/viewcontact.hxx
@@ -30,6 +30,7 @@ class SdrObject;
 
 namespace sdr::contact
 {
+class DisplayInfo;
 class ObjectContact;
 class ViewObjectContact;
 
@@ -146,6 +147,10 @@ public:
     // delete all existing VOCs by purpose, but can also be used for other 
purposes.
     // It is always possible to delete the VOCs, these are re-created on demand
     void flushViewObjectContacts(bool bWithHierarchy = true);
+
+    void getPrimitive2DSequenceHierarchyOfIndex(
+        sal_uInt32 a, DisplayInfo& rDisplayInfo, ObjectContact& rObjectContact,
+        drawinglayer::primitive2d::Primitive2DDecompositionVisitor& rVisitor);
 };
 }
 
diff --git a/svx/source/sdr/contact/viewcontact.cxx 
b/svx/source/sdr/contact/viewcontact.cxx
index 9ecb324e200f..99106d0d6ed0 100644
--- a/svx/source/sdr/contact/viewcontact.cxx
+++ b/svx/source/sdr/contact/viewcontact.cxx
@@ -292,6 +292,13 @@ void ViewContact::flushViewObjectContacts(bool 
bWithHierarchy)
     // delete local VOCs
     deleteAllVOCs();
 }
-}
 
+void ViewContact::getPrimitive2DSequenceHierarchyOfIndex(
+    sal_uInt32 a, DisplayInfo& rDisplayInfo, ObjectContact& rObjectContact,
+    drawinglayer::primitive2d::Primitive2DDecompositionVisitor& rVisitor)
+{
+    const ViewObjectContact& 
rCandidate(GetViewContact(a).GetViewObjectContact(rObjectContact));
+    rCandidate.getPrimitive2DSequenceHierarchy(rDisplayInfo, rVisitor);
+}
+}
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/svx/source/sdr/contact/viewobjectcontact.cxx 
b/svx/source/sdr/contact/viewobjectcontact.cxx
index f6e70a335d3d..d48cef106c13 100644
--- a/svx/source/sdr/contact/viewobjectcontact.cxx
+++ b/svx/source/sdr/contact/viewobjectcontact.cxx
@@ -553,14 +553,11 @@ void 
ViewObjectContact::getPrimitive2DSequenceHierarchy(DisplayInfo& rDisplayInf
 
 void ViewObjectContact::getPrimitive2DSequenceSubHierarchy(DisplayInfo& 
rDisplayInfo, drawinglayer::primitive2d::Primitive2DDecompositionVisitor& 
rVisitor) const
 {
-    const sal_uInt32 nSubHierarchyCount(GetViewContact().GetObjectCount());
+    ViewContact& rViewContact = GetViewContact();
+    const sal_uInt32 nSubHierarchyCount(rViewContact.GetObjectCount());
 
     for(sal_uInt32 a(0); a < nSubHierarchyCount; a++)
-    {
-        const ViewObjectContact& 
rCandidate(GetViewContact().GetViewContact(a).GetViewObjectContact(GetObjectContact()));
-
-        rCandidate.getPrimitive2DSequenceHierarchy(rDisplayInfo, rVisitor);
-    }
+        rViewContact.getPrimitive2DSequenceHierarchyOfIndex(a, rDisplayInfo, 
GetObjectContact(), rVisitor);
 }
 
 // Support getting a GridOffset per object and view for non-linear ViewToDevice

Reply via email to