summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCaolán McNamara <caolan.mcnamara@collabora.com>2023-08-02 17:16:17 +0100
committerCaolán McNamara <caolan.mcnamara@collabora.com>2023-08-03 12:15:58 +0200
commit313be607903a381830600c0a60b2e299fcaec685 (patch)
tree49b57786654552e6d000ab3e7545b34c5b538fbe
parenta99a63287f96290f5641a4216432f7b637402ea6 (diff)
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/+/155269 Tested-by: Jenkins Reviewed-by: Caolán McNamara <caolan.mcnamara@collabora.com>
-rw-r--r--include/svx/sdr/contact/viewcontact.hxx4
-rw-r--r--include/svx/sdr/contact/viewobjectcontactofsdrobj.hxx2
-rw-r--r--svx/inc/sdr/contact/viewcontactofsdrpage.hxx7
-rw-r--r--svx/source/sdr/contact/viewcontactofsdrpage.cxx29
-rw-r--r--svx/source/sdr/contact/viewobjectcontactofsdrobj.cxx9
5 files changed, 46 insertions, 5 deletions
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 83193c98be47..43ca1fd5c06f 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