зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1423746 - Filter on root should not establish containing block for fixedpos elements. r=mstange
Teach nsDisplay{Filters,BackdropFilters} to use a style that doesn't belong to mFrame for the root frame, and use it as needed. Remove the BackdropFilters::CanCreateWebrenderCommands call because it was testing for StyleSVGEffects::mFilters rather than mBackdropFilters, so it was doing nothing. Differential Revision: https://phabricator.services.mozilla.com/D146188
This commit is contained in:
Родитель
466753ca05
Коммит
5302cc0936
|
@ -4172,6 +4172,35 @@ void ScrollFrameHelper::BuildDisplayList(nsDisplayListBuilder* aBuilder,
|
|||
set.PositionedDescendants()->AppendToTop(topLayerWrapList);
|
||||
}
|
||||
|
||||
nsDisplayList rootResultList(aBuilder);
|
||||
bool serializedList = false;
|
||||
auto SerializeList = [&] {
|
||||
if (!serializedList) {
|
||||
serializedList = true;
|
||||
set.SerializeWithCorrectZOrder(&rootResultList, mOuter->GetContent());
|
||||
}
|
||||
};
|
||||
if (mIsRoot) {
|
||||
if (nsIFrame* rootStyleFrame = GetFrameForStyle()) {
|
||||
if (rootStyleFrame->StyleEffects()->HasFilters()) {
|
||||
SerializeList();
|
||||
rootResultList.AppendNewToTop<nsDisplayFilters>(
|
||||
aBuilder, mOuter, &rootResultList, rootStyleFrame);
|
||||
}
|
||||
|
||||
if (rootStyleFrame->StyleEffects()->HasBackdropFilters() &&
|
||||
rootStyleFrame->IsVisibleForPainting()) {
|
||||
SerializeList();
|
||||
aBuilder->SetContainsBackdropFilter(true);
|
||||
DisplayListClipState::AutoSaveRestore clipState(aBuilder);
|
||||
nsRect backdropRect = mOuter->GetRectRelativeToSelf() +
|
||||
aBuilder->ToReferenceFrame(mOuter);
|
||||
rootResultList.AppendNewToTop<nsDisplayBackdropFilters>(
|
||||
aBuilder, mOuter, &rootResultList, backdropRect, rootStyleFrame);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (willBuildAsyncZoomContainer) {
|
||||
MOZ_ASSERT(mIsRoot);
|
||||
|
||||
|
@ -4181,9 +4210,7 @@ void ScrollFrameHelper::BuildDisplayList(nsDisplayListBuilder* aBuilder,
|
|||
// it. The children have the layout viewport clip applied to them (above).
|
||||
// Effectively we are double clipping to the viewport, at potentially
|
||||
// different async scales.
|
||||
|
||||
nsDisplayList resultList(aBuilder);
|
||||
set.SerializeWithCorrectZOrder(&resultList, mOuter->GetContent());
|
||||
SerializeList();
|
||||
|
||||
if (blendCapture.CaptureContainsBlendMode()) {
|
||||
// The async zoom contents contain a mix-blend mode, so let's wrap all
|
||||
|
@ -4193,9 +4220,9 @@ void ScrollFrameHelper::BuildDisplayList(nsDisplayListBuilder* aBuilder,
|
|||
// WebRender.
|
||||
nsDisplayItem* blendContainer =
|
||||
nsDisplayBlendContainer::CreateForMixBlendMode(
|
||||
aBuilder, mOuter, &resultList,
|
||||
aBuilder, mOuter, &rootResultList,
|
||||
aBuilder->CurrentActiveScrolledRoot());
|
||||
resultList.AppendToTop(blendContainer);
|
||||
rootResultList.AppendToTop(blendContainer);
|
||||
|
||||
// Blend containers can be created or omitted during partial updates
|
||||
// depending on the dirty rect. So we basically can't do partial updates
|
||||
|
@ -4217,8 +4244,9 @@ void ScrollFrameHelper::BuildDisplayList(nsDisplayListBuilder* aBuilder,
|
|||
// backdrop container in the async zoom container. Otherwise the
|
||||
// backdrop-root container ends up outside the zoom container which
|
||||
// results in blend failure for WebRender.
|
||||
resultList.AppendNewToTop<nsDisplayBackdropRootContainer>(
|
||||
aBuilder, mOuter, &resultList, aBuilder->CurrentActiveScrolledRoot());
|
||||
rootResultList.AppendNewToTop<nsDisplayBackdropRootContainer>(
|
||||
aBuilder, mOuter, &rootResultList,
|
||||
aBuilder->CurrentActiveScrolledRoot());
|
||||
|
||||
// Backdrop root containers can be created or omitted during partial
|
||||
// updates depending on the dirty rect. So we basically can't do partial
|
||||
|
@ -4241,9 +4269,13 @@ void ScrollFrameHelper::BuildDisplayList(nsDisplayListBuilder* aBuilder,
|
|||
DisplayListClipState::AutoSaveRestore clipState(aBuilder);
|
||||
clipState.ClipContentDescendants(clipRect, haveRadii ? radii : nullptr);
|
||||
|
||||
set.Content()->AppendNewToTop<nsDisplayAsyncZoom>(
|
||||
aBuilder, mOuter, &resultList, aBuilder->CurrentActiveScrolledRoot(),
|
||||
viewID);
|
||||
rootResultList.AppendNewToTop<nsDisplayAsyncZoom>(
|
||||
aBuilder, mOuter, &rootResultList,
|
||||
aBuilder->CurrentActiveScrolledRoot(), viewID);
|
||||
}
|
||||
|
||||
if (serializedList) {
|
||||
set.Content()->AppendToTop(&rootResultList);
|
||||
}
|
||||
|
||||
nsDisplayListCollection scrolledContent(aBuilder);
|
||||
|
|
|
@ -1779,7 +1779,7 @@ bool nsIFrame::HasOpacityInternal(float aThreshold,
|
|||
EffectSet* aEffectSet) const {
|
||||
MOZ_ASSERT(0.0 <= aThreshold && aThreshold <= 1.0, "Invalid argument");
|
||||
if (aStyleEffects->mOpacity < aThreshold ||
|
||||
(aStyleDisplay->mWillChange.bits & StyleWillChangeBits::OPACITY)) {
|
||||
aStyleDisplay->mWillChange.bits & StyleWillChangeBits::OPACITY) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -2651,32 +2651,38 @@ inline static bool IsSVGContentWithCSSClip(const nsIFrame* aFrame) {
|
|||
nsGkAtoms::foreignObject);
|
||||
}
|
||||
|
||||
bool nsIFrame::FormsBackdropRoot(const nsStyleDisplay* aStyleDisplay,
|
||||
const nsStyleEffects* aStyleEffects,
|
||||
const nsStyleSVGReset* aStyleSVGReset) {
|
||||
bool nsIFrame::FormsBackdropRoot() const {
|
||||
// Check if this is a root frame.
|
||||
if (!GetParent()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const auto& style = *Style();
|
||||
const auto& effects = *style.StyleEffects();
|
||||
// Check for filter effects.
|
||||
if (aStyleEffects->HasFilters() || aStyleEffects->HasBackdropFilters() ||
|
||||
aStyleEffects->HasMixBlendMode()) {
|
||||
if (!style.IsRootElementStyle()) {
|
||||
if (effects.HasFilters() || effects.HasBackdropFilters()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (effects.HasMixBlendMode()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Check for opacity.
|
||||
if (HasOpacity(aStyleDisplay, aStyleEffects)) {
|
||||
const auto& disp = *style.StyleDisplay();
|
||||
if (HasOpacity(&disp, &effects)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Check for mask or clip path.
|
||||
if (aStyleSVGReset->HasMask() || aStyleSVGReset->HasClipPath()) {
|
||||
const auto& svgReset = *style.StyleSVGReset();
|
||||
if (svgReset.HasMask() || svgReset.HasClipPath()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// TODO(cbrewster): Check will-change attributes
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -3146,8 +3152,9 @@ void nsIFrame::BuildDisplayListForStackingContext(
|
|||
return;
|
||||
}
|
||||
|
||||
const nsStyleDisplay* disp = StyleDisplay();
|
||||
const nsStyleEffects* effects = StyleEffects();
|
||||
const auto& style = *Style();
|
||||
const nsStyleDisplay* disp = style.StyleDisplay();
|
||||
const nsStyleEffects* effects = style.StyleEffects();
|
||||
EffectSet* effectSetForOpacity = EffectSet::GetEffectSetForFrame(
|
||||
this, nsCSSPropertyIDSet::OpacityProperties());
|
||||
// We can stop right away if this is a zero-opacity stacking context and
|
||||
|
@ -3224,10 +3231,11 @@ void nsIFrame::BuildDisplayListForStackingContext(
|
|||
AutoSaveRestoreContainsBlendMode autoRestoreBlendMode(*aBuilder);
|
||||
aBuilder->SetContainsBlendMode(false);
|
||||
|
||||
bool usingBackdropFilter =
|
||||
IsVisibleForPainting() && effects->HasBackdropFilters() &&
|
||||
nsDisplayBackdropFilters::CanCreateWebRenderCommands(aBuilder, this);
|
||||
|
||||
// NOTE: When changing this condition make sure to tweak nsGfxScrollFrame as
|
||||
// well.
|
||||
bool usingBackdropFilter = effects->HasBackdropFilters() &&
|
||||
IsVisibleForPainting() &&
|
||||
!style.IsRootElementStyle();
|
||||
if (usingBackdropFilter) {
|
||||
aBuilder->SetContainsBackdropFilter(true);
|
||||
}
|
||||
|
@ -3319,7 +3327,7 @@ void nsIFrame::BuildDisplayListForStackingContext(
|
|||
}
|
||||
}
|
||||
|
||||
bool usingFilter = effects->HasFilters();
|
||||
bool usingFilter = effects->HasFilters() && !style.IsRootElementStyle();
|
||||
bool usingMask = SVGIntegrationUtils::UsingMaskOrClipPathForFrame(this);
|
||||
bool usingSVGEffects = usingFilter || usingMask;
|
||||
|
||||
|
@ -3482,8 +3490,8 @@ void nsIFrame::BuildDisplayListForStackingContext(
|
|||
aBuilder->Check();
|
||||
aBuilder->DisplayCaret(this, set.Outlines());
|
||||
|
||||
insertBackdropRoot = aBuilder->ContainsBackdropFilter() &&
|
||||
FormsBackdropRoot(disp, effects, StyleSVGReset());
|
||||
insertBackdropRoot =
|
||||
aBuilder->ContainsBackdropFilter() && FormsBackdropRoot();
|
||||
|
||||
// Blend modes are a real pain for retained display lists. We build a blend
|
||||
// container item if the built list contains any blend mode items within
|
||||
|
@ -3584,7 +3592,7 @@ void nsIFrame::BuildDisplayListForStackingContext(
|
|||
nsRect backdropRect =
|
||||
GetRectRelativeToSelf() + aBuilder->ToReferenceFrame(this);
|
||||
resultList.AppendNewToTop<nsDisplayBackdropFilters>(
|
||||
aBuilder, this, &resultList, backdropRect);
|
||||
aBuilder, this, &resultList, backdropRect, this);
|
||||
createdContainer = true;
|
||||
}
|
||||
|
||||
|
@ -3606,7 +3614,8 @@ void nsIFrame::BuildDisplayListForStackingContext(
|
|||
// Skip all filter effects while generating glyph mask.
|
||||
if (usingFilter && !aBuilder->IsForGenerateGlyphMask()) {
|
||||
/* List now emptied, so add the new list to the top. */
|
||||
resultList.AppendNewToTop<nsDisplayFilters>(aBuilder, this, &resultList);
|
||||
resultList.AppendNewToTop<nsDisplayFilters>(aBuilder, this, &resultList,
|
||||
this);
|
||||
createdContainer = true;
|
||||
}
|
||||
|
||||
|
|
|
@ -1955,9 +1955,7 @@ class nsIFrame : public nsQueryFrame {
|
|||
* Return true if this frame should form a backdrop root container.
|
||||
* See: https://drafts.fxtf.org/filter-effects-2/#BackdropRootTriggers
|
||||
*/
|
||||
bool FormsBackdropRoot(const nsStyleDisplay* aStyleDisplay,
|
||||
const nsStyleEffects* aStyleEffects,
|
||||
const nsStyleSVGReset* aStyleSvgReset);
|
||||
bool FormsBackdropRoot() const;
|
||||
|
||||
/**
|
||||
* Returns whether this frame will attempt to extend the 3d transforms of its
|
||||
|
|
|
@ -8296,19 +8296,14 @@ bool nsDisplayBackdropRootContainer::CreateWebRenderCommands(
|
|||
return true;
|
||||
}
|
||||
|
||||
/* static */
|
||||
bool nsDisplayBackdropFilters::CanCreateWebRenderCommands(
|
||||
nsDisplayListBuilder* aBuilder, nsIFrame* aFrame) {
|
||||
return SVGIntegrationUtils::CanCreateWebRenderFiltersForFrame(aFrame);
|
||||
}
|
||||
|
||||
bool nsDisplayBackdropFilters::CreateWebRenderCommands(
|
||||
wr::DisplayListBuilder& aBuilder, wr::IpcResourceUpdateQueue& aResources,
|
||||
const StackingContextHelper& aSc, RenderRootStateManager* aManager,
|
||||
nsDisplayListBuilder* aDisplayListBuilder) {
|
||||
WrFiltersHolder wrFilters;
|
||||
Maybe<nsRect> filterClip;
|
||||
auto filterChain = mFrame->StyleEffects()->mBackdropFilters.AsSpan();
|
||||
const ComputedStyle& style = mStyle ? *mStyle : *mFrame->Style();
|
||||
auto filterChain = style.StyleEffects()->mBackdropFilters.AsSpan();
|
||||
bool initialized = true;
|
||||
if (!SVGIntegrationUtils::CreateWebRenderCSSFilters(filterChain, mFrame,
|
||||
wrFilters) &&
|
||||
|
@ -8324,7 +8319,7 @@ bool nsDisplayBackdropFilters::CreateWebRenderCommands(
|
|||
|
||||
nsCSSRendering::ImageLayerClipState clip;
|
||||
nsCSSRendering::GetImageLayerClip(
|
||||
mFrame->StyleBackground()->BottomLayer(), mFrame, *mFrame->StyleBorder(),
|
||||
style.StyleBackground()->BottomLayer(), mFrame, *style.StyleBorder(),
|
||||
mBackdropRect, mBackdropRect, false,
|
||||
mFrame->PresContext()->AppUnitsPerDevPixel(), &clip);
|
||||
|
||||
|
@ -8359,8 +8354,10 @@ void nsDisplayBackdropFilters::Paint(nsDisplayListBuilder* aBuilder,
|
|||
|
||||
/* static */
|
||||
nsDisplayFilters::nsDisplayFilters(nsDisplayListBuilder* aBuilder,
|
||||
nsIFrame* aFrame, nsDisplayList* aList)
|
||||
nsIFrame* aFrame, nsDisplayList* aList,
|
||||
nsIFrame* aStyleFrame)
|
||||
: nsDisplayEffectsBase(aBuilder, aFrame, aList),
|
||||
mStyle(aFrame == aStyleFrame ? nullptr : aStyleFrame->Style()),
|
||||
mEffectsBounds(aFrame->InkOverflowRectRelativeToSelf()) {
|
||||
MOZ_COUNT_CTOR(nsDisplayFilters);
|
||||
mVisibleRect = aBuilder->GetVisibleRect() +
|
||||
|
@ -8382,7 +8379,6 @@ void nsDisplayFilters::ComputeInvalidationRegion(
|
|||
|
||||
const auto* geometry =
|
||||
static_cast<const nsDisplayFiltersGeometry*>(aGeometry);
|
||||
|
||||
if (aBuilder->ShouldSyncDecodeImages() &&
|
||||
geometry->ShouldInvalidateToSyncDecodeImages()) {
|
||||
bool snap;
|
||||
|
@ -8394,6 +8390,7 @@ void nsDisplayFilters::ComputeInvalidationRegion(
|
|||
void nsDisplayFilters::PaintWithContentsPaintCallback(
|
||||
nsDisplayListBuilder* aBuilder, gfxContext* aCtx,
|
||||
const std::function<void(gfxContext* aContext)>& aPaintChildren) {
|
||||
MOZ_ASSERT(!mStyle, "Shouldn't get to this code path on the root");
|
||||
imgDrawingParams imgParams(aBuilder->GetImageDecodeFlags());
|
||||
nsRect borderArea = nsRect(ToReferenceFrame(), mFrame->GetSize());
|
||||
SVGIntegrationUtils::PaintFramesParams params(
|
||||
|
@ -8427,11 +8424,16 @@ bool nsDisplayFilters::CreateWebRenderCommands(
|
|||
WrFiltersHolder wrFilters;
|
||||
Maybe<nsRect> filterClip;
|
||||
bool initialized = true;
|
||||
auto filterChain = mFrame->StyleEffects()->mFilters.AsSpan();
|
||||
auto filterChain = mStyle ? mStyle->StyleEffects()->mFilters.AsSpan()
|
||||
: mFrame->StyleEffects()->mFilters.AsSpan();
|
||||
if (!SVGIntegrationUtils::CreateWebRenderCSSFilters(filterChain, mFrame,
|
||||
wrFilters) &&
|
||||
!SVGIntegrationUtils::BuildWebRenderFilters(
|
||||
mFrame, filterChain, wrFilters, filterClip, initialized)) {
|
||||
if (mStyle) {
|
||||
// TODO(bug 1769223): Support fallback filters in the root code-path.
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -5973,8 +5973,10 @@ class nsDisplayBackdropRootContainer : public nsDisplayWrapList {
|
|||
class nsDisplayBackdropFilters : public nsDisplayWrapList {
|
||||
public:
|
||||
nsDisplayBackdropFilters(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
|
||||
nsDisplayList* aList, const nsRect& aBackdropRect)
|
||||
nsDisplayList* aList, const nsRect& aBackdropRect,
|
||||
nsIFrame* aStyleFrame)
|
||||
: nsDisplayWrapList(aBuilder, aFrame, aList),
|
||||
mStyle(aFrame == aStyleFrame ? nullptr : aStyleFrame->Style()),
|
||||
mBackdropRect(aBackdropRect) {
|
||||
MOZ_COUNT_CTOR(nsDisplayBackdropFilters);
|
||||
}
|
||||
|
@ -5990,9 +5992,6 @@ class nsDisplayBackdropFilters : public nsDisplayWrapList {
|
|||
nsDisplayListBuilder* aDisplayListBuilder) override;
|
||||
void Paint(nsDisplayListBuilder* aBuilder, gfxContext* aCtx) override;
|
||||
|
||||
static bool CanCreateWebRenderCommands(nsDisplayListBuilder* aBuilder,
|
||||
nsIFrame* aFrame);
|
||||
|
||||
bool ShouldFlattenAway(nsDisplayListBuilder* aBuilder) override {
|
||||
return !aBuilder->IsPaintingForWebRender();
|
||||
}
|
||||
|
@ -6000,6 +5999,7 @@ class nsDisplayBackdropFilters : public nsDisplayWrapList {
|
|||
bool CreatesStackingContextHelper() override { return true; }
|
||||
|
||||
private:
|
||||
RefPtr<ComputedStyle> mStyle;
|
||||
nsRect mBackdropRect;
|
||||
};
|
||||
|
||||
|
@ -6013,11 +6013,12 @@ class nsDisplayBackdropFilters : public nsDisplayWrapList {
|
|||
class nsDisplayFilters : public nsDisplayEffectsBase {
|
||||
public:
|
||||
nsDisplayFilters(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
|
||||
nsDisplayList* aList);
|
||||
nsDisplayList* aList, nsIFrame* aStyleFrame);
|
||||
|
||||
nsDisplayFilters(nsDisplayListBuilder* aBuilder,
|
||||
const nsDisplayFilters& aOther)
|
||||
: nsDisplayEffectsBase(aBuilder, aOther),
|
||||
mStyle(aOther.mStyle),
|
||||
mEffectsBounds(aOther.mEffectsBounds) {
|
||||
MOZ_COUNT_CTOR(nsDisplayFilters);
|
||||
}
|
||||
|
@ -6082,6 +6083,7 @@ class nsDisplayFilters : public nsDisplayEffectsBase {
|
|||
private:
|
||||
NS_DISPLAY_ALLOW_CLONING()
|
||||
|
||||
RefPtr<ComputedStyle> mStyle;
|
||||
// relative to mFrame
|
||||
nsRect mEffectsBounds;
|
||||
nsRect mVisibleRect;
|
||||
|
|
|
@ -97,6 +97,10 @@ bool nsStyleDisplay::IsFixedPosContainingBlockForNonSVGTextFrames(
|
|||
// should return FIXPOS_CB_NON_SVG for will-change.
|
||||
NS_ASSERTION(aStyle.StyleDisplay() == this, "unexpected aStyle");
|
||||
|
||||
if (aStyle.IsRootElementStyle()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mWillChange.bits & mozilla::StyleWillChangeBits::FIXPOS_CB_NON_SVG) {
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -1732,7 +1732,8 @@ already_AddRefed<nsIURI> SVGObserverUtils::GetBaseURLForLocalRef(
|
|||
already_AddRefed<URLAndReferrerInfo> SVGObserverUtils::GetFilterURI(
|
||||
nsIFrame* aFrame, const StyleFilter& aFilter) {
|
||||
MOZ_ASSERT(!aFrame->StyleEffects()->mFilters.IsEmpty() ||
|
||||
!aFrame->StyleEffects()->mBackdropFilters.IsEmpty());
|
||||
!aFrame->StyleEffects()->mBackdropFilters.IsEmpty() ||
|
||||
!aFrame->GetContent()->GetParent());
|
||||
MOZ_ASSERT(aFilter.IsUrl());
|
||||
return ResolveURLUsingLocalRef(aFrame, aFilter.AsUrl());
|
||||
}
|
||||
|
|
|
@ -1,2 +0,0 @@
|
|||
[root-element-filter.html]
|
||||
expected: FAIL
|
|
@ -1,2 +0,0 @@
|
|||
[will-change-fixedpos-cb-003.html]
|
||||
expected: FAIL
|
|
@ -1,3 +0,0 @@
|
|||
[will-change-fixedpos-cb-006.html]
|
||||
expected: FAIL
|
||||
bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1423746
|
|
@ -1,2 +0,0 @@
|
|||
[filtered-html-is-not-container.html]
|
||||
expected: FAIL
|
Загрузка…
Ссылка в новой задаче