From 085d0bbe3bb5e25bbe89410582a853eb379821b3 Mon Sep 17 00:00:00 2001 From: Matt Woodrow Date: Thu, 10 May 2018 11:39:12 +1200 Subject: [PATCH] Bug 1459441 - Make sure we build the full display list when we have blend containers in order to get the correct sorting for them. r=mstange MozReview-Commit-ID: ECTU7enMb1r --HG-- extra : rebase_source : 70f1b6187c152e770c4e19539645174c62198dc0 --- layout/generic/nsFrame.cpp | 50 ++++--------------- layout/generic/nsIFrame.h | 12 +---- .../painting/RetainedDisplayListBuilder.cpp | 7 +++ layout/painting/nsDisplayList.cpp | 3 +- layout/painting/nsDisplayList.h | 4 ++ .../invalidated-blendmode-sorting-ref.html | 31 ++++++++++++ .../invalidated-blendmode-sorting.html | 38 ++++++++++++++ layout/reftests/display-list/reftest.list | 1 + 8 files changed, 93 insertions(+), 53 deletions(-) create mode 100644 layout/reftests/display-list/invalidated-blendmode-sorting-ref.html create mode 100644 layout/reftests/display-list/invalidated-blendmode-sorting.html diff --git a/layout/generic/nsFrame.cpp b/layout/generic/nsFrame.cpp index e4327eeb6520..26f7af454750 100644 --- a/layout/generic/nsFrame.cpp +++ b/layout/generic/nsFrame.cpp @@ -2939,13 +2939,6 @@ nsIFrame::BuildDisplayListForStackingContext(nsDisplayListBuilder* aBuilder, hasOverrideDirtyRect = true; } } - // Always build the entire display list if we previously had a blend - // container since a partial build might make us think we no longer - // need the container even though the merged result will. - if (aBuilder->IsRetainingDisplayList() && BuiltBlendContainer()) { - dirtyRect = visibleRect; - aBuilder->MarkFrameModifiedDuringBuilding(this); - } bool usingFilter = StyleEffects()->HasFilters(); bool usingMask = nsSVGIntegrationUtils::UsingMaskOrClipPathForFrame(this); @@ -3107,42 +3100,17 @@ nsIFrame::BuildDisplayListForStackingContext(nsDisplayListBuilder* aBuilder, // is complex and likely to be buggy. // Instead we're doing the sad thing, detecting it afterwards, and just // repeating display list building if it changed. - - // If we changed whether we're going to build a blend mode item, - // then we need to make sure we're marked as invalid and we've built - // the full display list. - if (aBuilder->ContainsBlendMode() != BuiltBlendContainer() && + // We have to repeat building for the entire display list (or at least + // the outer stacking context), since we need to mark this frame as invalid + // to remove any existing content that isn't wrapped in the blend container, + // and then we need to build content infront/behind the blend container + // to get correct positioning during merging. + if (aBuilder->ContainsBlendMode() && aBuilder->IsRetainingDisplayList()) { - SetBuiltBlendContainer(aBuilder->ContainsBlendMode()); - - // If we did a partial build then delete all the items we just built - // and repeat building with the full area. if (!aBuilder->GetDirtyRect().Contains(aBuilder->GetVisibleRect())) { - aBuilder->MarkCurrentFrameModifiedDuringBuilding(); - set.DeleteAll(aBuilder); - - if (eventRegions) { - eventRegions->Destroy(aBuilder); - eventRegions = MakeDisplayItem(aBuilder, this); - eventRegions->AddFrame(aBuilder, this); - aBuilder->SetLayerEventRegions(eventRegions); - } - - aBuilder->BuildCompositorHitTestInfoIfNeeded(this, - set.BorderBackground(), - true); - - // If this is the root frame, then the previous call to - // MarkAbsoluteFramesForDisplayList might have stored some fixed - // background data. Clear that now. - if (!GetParent()) { - aBuilder->ClearFixedBackgroundDisplayData(); - } - - MarkAbsoluteFramesForDisplayList(aBuilder); - aBuilder->Check(); - BuildDisplayList(aBuilder, set); - aBuilder->Check(); + aBuilder->SetPartialBuildFailed(true); + } else { + aBuilder->SetDisablePartialUpdates(true); } } diff --git a/layout/generic/nsIFrame.h b/layout/generic/nsIFrame.h index b385ec975f5a..110604ba07e3 100644 --- a/layout/generic/nsIFrame.h +++ b/layout/generic/nsIFrame.h @@ -612,7 +612,6 @@ public: , mFrameIsModified(false) , mHasOverrideDirtyRegion(false) , mMayHaveWillChangeBudget(false) - , mBuiltBlendContainer(false) , mIsPrimaryFrame(false) , mMayHaveTransformAnimation(false) , mMayHaveOpacityAnimation(false) @@ -4145,9 +4144,6 @@ public: bool MayHaveWillChangeBudget() { return mMayHaveWillChangeBudget; } void SetMayHaveWillChangeBudget(bool aHasBudget) { mMayHaveWillChangeBudget = aHasBudget; } - bool BuiltBlendContainer() { return mBuiltBlendContainer; } - void SetBuiltBlendContainer(bool aBuilt) { mBuiltBlendContainer = aBuilt; } - /** * Returns the set of flags indicating the properties of the frame that the * compositor might care about for hit-testing purposes. Note that this function @@ -4345,12 +4341,6 @@ protected: */ bool mMayHaveWillChangeBudget : 1; - /** - * True if we built an nsDisplayBlendContainer last time - * we did retained display list building for this frame. - */ - bool mBuiltBlendContainer : 1; - private: /** * True if this is the primary frame for mContent. @@ -4372,7 +4362,7 @@ private: protected: - // There is no gap left here. + // There is a 1-bit gap left here. // Helpers /** diff --git a/layout/painting/RetainedDisplayListBuilder.cpp b/layout/painting/RetainedDisplayListBuilder.cpp index 35ebead88683..518ad6683a06 100644 --- a/layout/painting/RetainedDisplayListBuilder.cpp +++ b/layout/painting/RetainedDisplayListBuilder.cpp @@ -1151,6 +1151,13 @@ RetainedDisplayListBuilder::AttemptPartialUpdate( } mBuilder.SetPartialUpdate(false); + if (mBuilder.PartialBuildFailed()) { + mBuilder.SetPartialBuildFailed(false); + mBuilder.LeavePresShell(mBuilder.RootReferenceFrame(), List()); + mList.ClearDAG(); + return PartialUpdateResult::Failed; + } + if (aChecker) { aChecker->Set(&modifiedDL, "TM"); } diff --git a/layout/painting/nsDisplayList.cpp b/layout/painting/nsDisplayList.cpp index 7bc15110548f..4776128bb9e2 100644 --- a/layout/painting/nsDisplayList.cpp +++ b/layout/painting/nsDisplayList.cpp @@ -1011,7 +1011,8 @@ nsDisplayListBuilder::nsDisplayListBuilder(nsIFrame* aReferenceFrame, mHitTestIsForVisibility(false), mIsBuilding(false), mInInvalidSubtree(false), - mDisablePartialUpdates(false) + mDisablePartialUpdates(false), + mPartialBuildFailed(false) { MOZ_COUNT_CTOR(nsDisplayListBuilder); diff --git a/layout/painting/nsDisplayList.h b/layout/painting/nsDisplayList.h index 8c66b6842f1c..eb1e267fb4f3 100644 --- a/layout/painting/nsDisplayList.h +++ b/layout/painting/nsDisplayList.h @@ -844,6 +844,9 @@ public: void SetDisablePartialUpdates(bool aDisable) { mDisablePartialUpdates = aDisable; } bool DisablePartialUpdates() { return mDisablePartialUpdates; } + void SetPartialBuildFailed(bool aFailed) { mPartialBuildFailed = aFailed; } + bool PartialBuildFailed() { return mPartialBuildFailed; } + /** * Return true if we're currently building a display list for the presshell * of a chrome document, or if we're building the display list for a popup. @@ -1997,6 +2000,7 @@ private: bool mBuildCompositorHitTestInfo; bool mLessEventRegionItems; bool mDisablePartialUpdates; + bool mPartialBuildFailed; }; class nsDisplayItem; diff --git a/layout/reftests/display-list/invalidated-blendmode-sorting-ref.html b/layout/reftests/display-list/invalidated-blendmode-sorting-ref.html new file mode 100644 index 000000000000..9ba08744f798 --- /dev/null +++ b/layout/reftests/display-list/invalidated-blendmode-sorting-ref.html @@ -0,0 +1,31 @@ + + + + + + +
+
+
+
+
+
+ + diff --git a/layout/reftests/display-list/invalidated-blendmode-sorting.html b/layout/reftests/display-list/invalidated-blendmode-sorting.html new file mode 100644 index 000000000000..cd42694d6ebe --- /dev/null +++ b/layout/reftests/display-list/invalidated-blendmode-sorting.html @@ -0,0 +1,38 @@ + + + + + + +
+
+
+
+
+
+ + + diff --git a/layout/reftests/display-list/reftest.list b/layout/reftests/display-list/reftest.list index 8ecb3521de12..f3e395ee97b5 100644 --- a/layout/reftests/display-list/reftest.list +++ b/layout/reftests/display-list/reftest.list @@ -11,6 +11,7 @@ skip-if(!retainedDisplayList) == retained-dl-animation-on-pseudo.html retained-d == retained-dl-wrap-list.html retained-dl-wrap-list-ref.html == retained-dl-zindex-1.html retained-dl-zindex-1-ref.html == retained-dl-zindex-2.html retained-dl-zindex-2-ref.html +== invalidated-blendmode-sorting.html invalidated-blendmode-sorting-ref.html fuzzy(1,235200) == 1413073.html 1413073-ref.html == 1416291.html 1416291-ref.html == 1417601-1.html 1417601-1-ref.html