diff options
author | Noel Grandin <noel@peralex.com> | 2021-12-06 15:58:19 +0200 |
---|---|---|
committer | Noel Grandin <noel.grandin@collabora.co.uk> | 2021-12-06 19:46:10 +0100 |
commit | d2b03c4bfa284efbb45cb4904122e97439d3ee06 (patch) | |
tree | 87696527bc43ba676ff03fadf7a90f918a4a057c | |
parent | 1c9a40299d328c78c035ca63ccdf22c5c669a03b (diff) |
Revert "lose the caching in ViewObjectContact" because it breaks...
bitmap caching. Added some notes for future would-be optimizers.
This reverts commit 7f02cb80ac2075b65ee1adee4e29d1d5c4819424.
Change-Id: I39c41ea95d23d4a65edd3cef46a5d86fab48a044
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/126425
Reviewed-by: Luboš Luňák <l.lunak@collabora.com>
Tested-by: Jenkins
-rw-r--r-- | include/svx/sdr/contact/viewobjectcontact.hxx | 12 | ||||
-rw-r--r-- | svx/source/sdr/contact/viewobjectcontact.cxx | 32 | ||||
-rw-r--r-- | svx/source/sdr/contact/viewobjectcontactofunocontrol.cxx | 6 |
3 files changed, 39 insertions, 11 deletions
diff --git a/include/svx/sdr/contact/viewobjectcontact.hxx b/include/svx/sdr/contact/viewobjectcontact.hxx index 56deadd59afe..f13f247e55c2 100644 --- a/include/svx/sdr/contact/viewobjectcontact.hxx +++ b/include/svx/sdr/contact/viewobjectcontact.hxx @@ -48,6 +48,11 @@ private: // This range defines the object's BoundRect basegfx::B2DRange maObjectRange; + // PrimitiveSequence of the ViewContact. This contains all necessary information + // for the graphical visualisation and needs to be supported by all VCs which + // can be visualized. + drawinglayer::primitive2d::Primitive2DContainer mxPrimitive2DSequence; + // the PrimitiveAnimation if Primitive2DContainer contains animations std::unique_ptr<sdr::animation::PrimitiveAnimation> mpPrimitiveAnimation; @@ -64,7 +69,7 @@ protected: // Called from getPrimitive2DSequence() when vector has changed. Evaluate object animation // and setup accordingly - void checkForPrimitive2DAnimations(const drawinglayer::primitive2d::Primitive2DContainer& ); + void checkForPrimitive2DAnimations(); // This method is responsible for creating the graphical visualisation data which is // stored/cached in the local primitive. Default gets view-independent Primitive @@ -73,6 +78,9 @@ protected: // This method will not handle included hierarchies and not check geometric visibility. virtual void createPrimitive2DSequence(const DisplayInfo& rDisplayInfo, drawinglayer::primitive2d::Primitive2DDecompositionVisitor& rVisitor) const; + // method for flushing Primitive2DContainer for VOC implementations + void flushPrimitive2DSequence() { mxPrimitive2DSequence.clear(); } + public: // basic constructor. ViewObjectContact(ObjectContact& rObjectContact, ViewContact& rViewContact); @@ -103,7 +111,7 @@ public: // access to the local primitive. This will ensure that the local primitive is // current in comparing the local one with a fresh created incarnation // This method will not handle included hierarchies and not check visibility. - drawinglayer::primitive2d::Primitive2DContainer getPrimitive2DSequence(const DisplayInfo& rDisplayInfo) const; + drawinglayer::primitive2d::Primitive2DContainer const & getPrimitive2DSequence(const DisplayInfo& rDisplayInfo) const; // test this VOC for visibility concerning model-view stuff like e.g. Layer virtual bool isPrimitiveVisible(const DisplayInfo& rDisplayInfo) const; diff --git a/svx/source/sdr/contact/viewobjectcontact.cxx b/svx/source/sdr/contact/viewobjectcontact.cxx index c72c34dfaccb..1dd8fef29415 100644 --- a/svx/source/sdr/contact/viewobjectcontact.cxx +++ b/svx/source/sdr/contact/viewobjectcontact.cxx @@ -263,13 +263,13 @@ void ViewObjectContact::ActionChildInserted(ViewContact& rChild) // GetObjectContact().InvalidatePartOfView(rChildVOC.getObjectRange()); } -void ViewObjectContact::checkForPrimitive2DAnimations(const drawinglayer::primitive2d::Primitive2DContainer& xPrimitive2DSequence) +void ViewObjectContact::checkForPrimitive2DAnimations() { // remove old one mpPrimitiveAnimation.reset(); // check for animated primitives - if(xPrimitive2DSequence.empty()) + if(mxPrimitive2DSequence.empty()) return; const bool bTextAnimationAllowed(GetObjectContact().IsTextAnimationAllowed()); @@ -279,7 +279,7 @@ void ViewObjectContact::checkForPrimitive2DAnimations(const drawinglayer::primit { AnimatedExtractingProcessor2D aAnimatedExtractor(GetObjectContact().getViewInformation2D(), bTextAnimationAllowed, bGraphicAnimationAllowed); - aAnimatedExtractor.process(xPrimitive2DSequence); + aAnimatedExtractor.process(mxPrimitive2DSequence); if(!aAnimatedExtractor.getPrimitive2DSequence().empty()) { @@ -328,8 +328,14 @@ void ViewObjectContact::createPrimitive2DSequence(const DisplayInfo& rDisplayInf rVisitor.visit(xRetval); } -drawinglayer::primitive2d::Primitive2DContainer ViewObjectContact::getPrimitive2DSequence(const DisplayInfo& rDisplayInfo) const +drawinglayer::primitive2d::Primitive2DContainer const & ViewObjectContact::getPrimitive2DSequence(const DisplayInfo& rDisplayInfo) const { + /** + This method is weird because + (1) we have to re-walk the primitive tree because the flushing is unreliable + (2) we cannot just always use the new data because the old data has cached bitmaps in it e.g. see the documents in tdf#104878 + */ + drawinglayer::primitive2d::Primitive2DContainer xNewPrimitiveSequence; // take care of redirectors and create new list @@ -344,12 +350,19 @@ drawinglayer::primitive2d::Primitive2DContainer ViewObjectContact::getPrimitive2 createPrimitive2DSequence(rDisplayInfo, xNewPrimitiveSequence); } + // local up-to-date checks. New list different from local one? + if(mxPrimitive2DSequence == xNewPrimitiveSequence) + return mxPrimitive2DSequence; + + // has changed, copy content + const_cast< ViewObjectContact* >(this)->mxPrimitive2DSequence = std::move(xNewPrimitiveSequence); + // check for animated stuff - const_cast< ViewObjectContact* >(this)->checkForPrimitive2DAnimations(xNewPrimitiveSequence); + const_cast< ViewObjectContact* >(this)->checkForPrimitive2DAnimations(); // always update object range when PrimitiveSequence changes const drawinglayer::geometry::ViewInformation2D& rViewInformation2D(GetObjectContact().getViewInformation2D()); - const_cast< ViewObjectContact* >(this)->maObjectRange = xNewPrimitiveSequence.getB2DRange(rViewInformation2D); + const_cast< ViewObjectContact* >(this)->maObjectRange = mxPrimitive2DSequence.getB2DRange(rViewInformation2D); // check and eventually embed to GridOffset transform primitive if(GetObjectContact().supportsGridOffsets()) @@ -364,7 +377,7 @@ drawinglayer::primitive2d::Primitive2DContainer ViewObjectContact::getPrimitive2 drawinglayer::primitive2d::Primitive2DReference aEmbed( new drawinglayer::primitive2d::TransformPrimitive2D( aTranslateGridOffset, - std::move(xNewPrimitiveSequence))); + std::move(const_cast< ViewObjectContact* >(this)->mxPrimitive2DSequence))); // Set values at local data. So for now, the mechanism is to reset some of the // defining things (mxPrimitive2DSequence, maGridOffset) and re-create the @@ -375,13 +388,13 @@ drawinglayer::primitive2d::Primitive2DContainer ViewObjectContact::getPrimitive2 // just allow re-creation of the PrimitiveSequence (and removing buffered // decomposed content of it). May be optimized, though. OTOH it only happens // in calc which traditionally does not have a huge amount of DrawObjects anyways. - xNewPrimitiveSequence = drawinglayer::primitive2d::Primitive2DContainer { aEmbed }; + const_cast< ViewObjectContact* >(this)->mxPrimitive2DSequence = drawinglayer::primitive2d::Primitive2DContainer { aEmbed }; const_cast< ViewObjectContact* >(this)->maObjectRange.transform(aTranslateGridOffset); } } // return current Primitive2DContainer - return xNewPrimitiveSequence; + return mxPrimitive2DSequence; } bool ViewObjectContact::isPrimitiveVisible(const DisplayInfo& /*rDisplayInfo*/) const @@ -452,6 +465,7 @@ void ViewObjectContact::resetGridOffset() maGridOffset.setY(0.0); // also reset sequence to get a re-calculation when GridOffset changes + mxPrimitive2DSequence.clear(); maObjectRange.reset(); } diff --git a/svx/source/sdr/contact/viewobjectcontactofunocontrol.cxx b/svx/source/sdr/contact/viewobjectcontactofunocontrol.cxx index 4881954b2eb1..4c0f54d93b1f 100644 --- a/svx/source/sdr/contact/viewobjectcontactofunocontrol.cxx +++ b/svx/source/sdr/contact/viewobjectcontactofunocontrol.cxx @@ -1747,6 +1747,12 @@ namespace sdr::contact { { // graphical invalidate at all views ActionChanged(); + + // #i93318# flush Primitive2DContainer to force recreation with updated XControlModel + // since e.g. background color has changed and existing decompositions are possibly no + // longer valid. Unfortunately this is not detected from ControlPrimitive2D::operator== + // since it only has a uno reference to the XControlModel + flushPrimitive2DSequence(); } UnoControlPrintOrPreviewContact::UnoControlPrintOrPreviewContact( ObjectContactOfPageView& _rObjectContact, ViewContactOfUnoControl& _rViewContact ) |