зеркало из https://github.com/mozilla/gecko-dev.git
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
This commit is contained in:
Родитель
1044f75cf5
Коммит
085d0bbe3b
|
@ -2939,13 +2939,6 @@ nsIFrame::BuildDisplayListForStackingContext(nsDisplayListBuilder* aBuilder,
|
||||||
hasOverrideDirtyRect = true;
|
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 usingFilter = StyleEffects()->HasFilters();
|
||||||
bool usingMask = nsSVGIntegrationUtils::UsingMaskOrClipPathForFrame(this);
|
bool usingMask = nsSVGIntegrationUtils::UsingMaskOrClipPathForFrame(this);
|
||||||
|
@ -3107,42 +3100,17 @@ nsIFrame::BuildDisplayListForStackingContext(nsDisplayListBuilder* aBuilder,
|
||||||
// is complex and likely to be buggy.
|
// is complex and likely to be buggy.
|
||||||
// Instead we're doing the sad thing, detecting it afterwards, and just
|
// Instead we're doing the sad thing, detecting it afterwards, and just
|
||||||
// repeating display list building if it changed.
|
// repeating display list building if it changed.
|
||||||
|
// We have to repeat building for the entire display list (or at least
|
||||||
// If we changed whether we're going to build a blend mode item,
|
// the outer stacking context), since we need to mark this frame as invalid
|
||||||
// then we need to make sure we're marked as invalid and we've built
|
// to remove any existing content that isn't wrapped in the blend container,
|
||||||
// the full display list.
|
// and then we need to build content infront/behind the blend container
|
||||||
if (aBuilder->ContainsBlendMode() != BuiltBlendContainer() &&
|
// to get correct positioning during merging.
|
||||||
|
if (aBuilder->ContainsBlendMode() &&
|
||||||
aBuilder->IsRetainingDisplayList()) {
|
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())) {
|
if (!aBuilder->GetDirtyRect().Contains(aBuilder->GetVisibleRect())) {
|
||||||
aBuilder->MarkCurrentFrameModifiedDuringBuilding();
|
aBuilder->SetPartialBuildFailed(true);
|
||||||
set.DeleteAll(aBuilder);
|
} else {
|
||||||
|
aBuilder->SetDisablePartialUpdates(true);
|
||||||
if (eventRegions) {
|
|
||||||
eventRegions->Destroy(aBuilder);
|
|
||||||
eventRegions = MakeDisplayItem<nsDisplayLayerEventRegions>(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();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -612,7 +612,6 @@ public:
|
||||||
, mFrameIsModified(false)
|
, mFrameIsModified(false)
|
||||||
, mHasOverrideDirtyRegion(false)
|
, mHasOverrideDirtyRegion(false)
|
||||||
, mMayHaveWillChangeBudget(false)
|
, mMayHaveWillChangeBudget(false)
|
||||||
, mBuiltBlendContainer(false)
|
|
||||||
, mIsPrimaryFrame(false)
|
, mIsPrimaryFrame(false)
|
||||||
, mMayHaveTransformAnimation(false)
|
, mMayHaveTransformAnimation(false)
|
||||||
, mMayHaveOpacityAnimation(false)
|
, mMayHaveOpacityAnimation(false)
|
||||||
|
@ -4145,9 +4144,6 @@ public:
|
||||||
bool MayHaveWillChangeBudget() { return mMayHaveWillChangeBudget; }
|
bool MayHaveWillChangeBudget() { return mMayHaveWillChangeBudget; }
|
||||||
void SetMayHaveWillChangeBudget(bool aHasBudget) { mMayHaveWillChangeBudget = aHasBudget; }
|
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
|
* 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
|
* compositor might care about for hit-testing purposes. Note that this function
|
||||||
|
@ -4345,12 +4341,6 @@ protected:
|
||||||
*/
|
*/
|
||||||
bool mMayHaveWillChangeBudget : 1;
|
bool mMayHaveWillChangeBudget : 1;
|
||||||
|
|
||||||
/**
|
|
||||||
* True if we built an nsDisplayBlendContainer last time
|
|
||||||
* we did retained display list building for this frame.
|
|
||||||
*/
|
|
||||||
bool mBuiltBlendContainer : 1;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/**
|
/**
|
||||||
* True if this is the primary frame for mContent.
|
* True if this is the primary frame for mContent.
|
||||||
|
@ -4372,7 +4362,7 @@ private:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
// There is no gap left here.
|
// There is a 1-bit gap left here.
|
||||||
|
|
||||||
// Helpers
|
// Helpers
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1151,6 +1151,13 @@ RetainedDisplayListBuilder::AttemptPartialUpdate(
|
||||||
}
|
}
|
||||||
mBuilder.SetPartialUpdate(false);
|
mBuilder.SetPartialUpdate(false);
|
||||||
|
|
||||||
|
if (mBuilder.PartialBuildFailed()) {
|
||||||
|
mBuilder.SetPartialBuildFailed(false);
|
||||||
|
mBuilder.LeavePresShell(mBuilder.RootReferenceFrame(), List());
|
||||||
|
mList.ClearDAG();
|
||||||
|
return PartialUpdateResult::Failed;
|
||||||
|
}
|
||||||
|
|
||||||
if (aChecker) {
|
if (aChecker) {
|
||||||
aChecker->Set(&modifiedDL, "TM");
|
aChecker->Set(&modifiedDL, "TM");
|
||||||
}
|
}
|
||||||
|
|
|
@ -1011,7 +1011,8 @@ nsDisplayListBuilder::nsDisplayListBuilder(nsIFrame* aReferenceFrame,
|
||||||
mHitTestIsForVisibility(false),
|
mHitTestIsForVisibility(false),
|
||||||
mIsBuilding(false),
|
mIsBuilding(false),
|
||||||
mInInvalidSubtree(false),
|
mInInvalidSubtree(false),
|
||||||
mDisablePartialUpdates(false)
|
mDisablePartialUpdates(false),
|
||||||
|
mPartialBuildFailed(false)
|
||||||
{
|
{
|
||||||
MOZ_COUNT_CTOR(nsDisplayListBuilder);
|
MOZ_COUNT_CTOR(nsDisplayListBuilder);
|
||||||
|
|
||||||
|
|
|
@ -844,6 +844,9 @@ public:
|
||||||
void SetDisablePartialUpdates(bool aDisable) { mDisablePartialUpdates = aDisable; }
|
void SetDisablePartialUpdates(bool aDisable) { mDisablePartialUpdates = aDisable; }
|
||||||
bool DisablePartialUpdates() { return mDisablePartialUpdates; }
|
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
|
* 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.
|
* of a chrome document, or if we're building the display list for a popup.
|
||||||
|
@ -1997,6 +2000,7 @@ private:
|
||||||
bool mBuildCompositorHitTestInfo;
|
bool mBuildCompositorHitTestInfo;
|
||||||
bool mLessEventRegionItems;
|
bool mLessEventRegionItems;
|
||||||
bool mDisablePartialUpdates;
|
bool mDisablePartialUpdates;
|
||||||
|
bool mPartialBuildFailed;
|
||||||
};
|
};
|
||||||
|
|
||||||
class nsDisplayItem;
|
class nsDisplayItem;
|
||||||
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<style>
|
||||||
|
div {
|
||||||
|
width: 200px;
|
||||||
|
height: 200px;
|
||||||
|
}
|
||||||
|
.sort-marker {
|
||||||
|
position: fixed;
|
||||||
|
background-color: green;
|
||||||
|
}
|
||||||
|
.wrapper {
|
||||||
|
position: absolute;
|
||||||
|
isolation: isolate;
|
||||||
|
}
|
||||||
|
.inner {
|
||||||
|
position: absolute;
|
||||||
|
background-color: blue;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="sort-marker"></div>
|
||||||
|
<div class="wrapper">
|
||||||
|
<div class="inner" style="left: 5px; top: 5px; mix-blend-mode:screen"></div>
|
||||||
|
<div class="inner" id="move" style="left: 221px;"></div>
|
||||||
|
</div>
|
||||||
|
<div class="sort-marker" style="left: 20px; top: 20px;"></div>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,38 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html class="reftest-wait">
|
||||||
|
<head>
|
||||||
|
<style>
|
||||||
|
div {
|
||||||
|
width: 200px;
|
||||||
|
height: 200px;
|
||||||
|
}
|
||||||
|
.sort-marker {
|
||||||
|
position: fixed;
|
||||||
|
background-color: green;
|
||||||
|
}
|
||||||
|
.wrapper {
|
||||||
|
position: absolute;
|
||||||
|
isolation: isolate;
|
||||||
|
}
|
||||||
|
.inner {
|
||||||
|
position: absolute;
|
||||||
|
background-color: blue;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="sort-marker"></div>
|
||||||
|
<div class="wrapper">
|
||||||
|
<div class="inner" style="left: 5px; top: 5px; mix-blend-mode:screen"></div>
|
||||||
|
<div class="inner" id="move" style="left: 220px;"></div>
|
||||||
|
</div>
|
||||||
|
<div class="sort-marker" style="left: 20px; top: 20px;"></div>
|
||||||
|
</body>
|
||||||
|
<script>
|
||||||
|
function doTest() {
|
||||||
|
document.getElementById("move").style.left = "221px";
|
||||||
|
document.documentElement.removeAttribute("class");
|
||||||
|
}
|
||||||
|
document.addEventListener("MozReftestInvalidate", doTest);
|
||||||
|
</script>
|
||||||
|
</html>
|
|
@ -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-wrap-list.html retained-dl-wrap-list-ref.html
|
||||||
== retained-dl-zindex-1.html retained-dl-zindex-1-ref.html
|
== retained-dl-zindex-1.html retained-dl-zindex-1-ref.html
|
||||||
== retained-dl-zindex-2.html retained-dl-zindex-2-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
|
fuzzy(1,235200) == 1413073.html 1413073-ref.html
|
||||||
== 1416291.html 1416291-ref.html
|
== 1416291.html 1416291-ref.html
|
||||||
== 1417601-1.html 1417601-1-ref.html
|
== 1417601-1.html 1417601-1-ref.html
|
||||||
|
|
Загрузка…
Ссылка в новой задаче