mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-12-04 11:26:09 +00:00
Bug 1768986 - Remove nsDisplayBackdropRoot r=gfx-reviewers,lsalzman
It's not possible to implement backdrop-filter with gecko adding explicit boundaries for backdrop roots, since backdrop filters can sample from a backdrop in a parent iframe. In this case, the parent display list (in one process) doesn't see a backdrop filter, so no root display item is added, even if there is a child display list (in another process) that has a backdrop-filter. This patch just removes the existing backdrop-filter root display items from Gecko. A follow up patch will add implicit backdrop root handling inside WR itself, where we have access to all of the display lists. Differential Revision: https://phabricator.services.mozilla.com/D146148
This commit is contained in:
parent
cebe610723
commit
63d7dcbcd1
@ -3693,41 +3693,6 @@ class MOZ_RAII AutoContainsBlendModeCapturer {
|
||||
}
|
||||
};
|
||||
|
||||
// This is an equivalent to the AutoContainsBlendModeCapturer helper class
|
||||
// above but for backdrop filters.
|
||||
class MOZ_RAII AutoContainsBackdropFilterCapturer {
|
||||
nsDisplayListBuilder& mBuilder;
|
||||
bool mSavedContainsBackdropFilter;
|
||||
|
||||
public:
|
||||
explicit AutoContainsBackdropFilterCapturer(nsDisplayListBuilder& aBuilder)
|
||||
: mBuilder(aBuilder),
|
||||
mSavedContainsBackdropFilter(aBuilder.ContainsBackdropFilter()) {
|
||||
mBuilder.SetContainsBackdropFilter(false);
|
||||
}
|
||||
|
||||
bool CaptureContainsBackdropFilter() {
|
||||
// "Capture" the flag by extracting and clearing the ContainsBackdropFilter
|
||||
// flag on the builder.
|
||||
bool capturedBackdropFilter = mBuilder.ContainsBackdropFilter();
|
||||
mBuilder.SetContainsBackdropFilter(false);
|
||||
return capturedBackdropFilter;
|
||||
}
|
||||
|
||||
~AutoContainsBackdropFilterCapturer() {
|
||||
// If CaptureContainsBackdropFilter() was called, the descendant filter was
|
||||
// "captured" and so uncapturedContainsBackdropFilter will be false. If
|
||||
// CaptureContainsBackdropFilter() wasn't called, then no capture occurred,
|
||||
// and uncapturedContainsBackdropFilter may be true if there was a
|
||||
// descendant filter. In that case, we set the flag on the DL builder so
|
||||
// that we restore state to what it would have been without this RAII class
|
||||
// on the stack.
|
||||
bool uncapturedContainsBackdropFilter = mBuilder.ContainsBackdropFilter();
|
||||
mBuilder.SetContainsBackdropFilter(mSavedContainsBackdropFilter ||
|
||||
uncapturedContainsBackdropFilter);
|
||||
}
|
||||
};
|
||||
|
||||
// Finds the max z-index of the items in aList that meet the following
|
||||
// conditions
|
||||
// 1) have z-index auto or z-index >= 0.
|
||||
@ -3947,7 +3912,6 @@ void ScrollFrameHelper::BuildDisplayList(nsDisplayListBuilder* aBuilder,
|
||||
|
||||
nsDisplayListCollection set(aBuilder);
|
||||
AutoContainsBlendModeCapturer blendCapture(*aBuilder);
|
||||
AutoContainsBackdropFilterCapturer backdropFilterCapture(*aBuilder);
|
||||
|
||||
bool willBuildAsyncZoomContainer =
|
||||
mWillBuildScrollableLayer && aBuilder->ShouldBuildAsyncZoomContainer() &&
|
||||
@ -4191,7 +4155,6 @@ void ScrollFrameHelper::BuildDisplayList(nsDisplayListBuilder* aBuilder,
|
||||
if (rootStyleFrame->StyleEffects()->HasBackdropFilters() &&
|
||||
rootStyleFrame->IsVisibleForPainting()) {
|
||||
SerializeList();
|
||||
aBuilder->SetContainsBackdropFilter(true);
|
||||
DisplayListClipState::AutoSaveRestore clipState(aBuilder);
|
||||
nsRect backdropRect = mOuter->GetRectRelativeToSelf() +
|
||||
aBuilder->ToReferenceFrame(mOuter);
|
||||
@ -4238,31 +4201,6 @@ void ScrollFrameHelper::BuildDisplayList(nsDisplayListBuilder* aBuilder,
|
||||
}
|
||||
}
|
||||
|
||||
if (backdropFilterCapture.CaptureContainsBackdropFilter()) {
|
||||
// The async zoom contents contain a backdrop-filter, so let's wrap all
|
||||
// those contents into a backdrop root container, and then wrap the
|
||||
// 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.
|
||||
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
|
||||
// updates if there's a backdrop root container involved. There is
|
||||
// equivalent code to this in the BuildDisplayListForStackingContext
|
||||
// function as well, with a more detailed comment explaining things
|
||||
// better.
|
||||
if (aBuilder->IsRetainingDisplayList()) {
|
||||
if (aBuilder->IsPartialUpdate()) {
|
||||
aBuilder->SetPartialBuildFailed(true);
|
||||
} else {
|
||||
aBuilder->SetDisablePartialUpdates(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mozilla::layers::FrameMetrics::ViewID viewID =
|
||||
nsLayoutUtils::FindOrCreateIDFor(mScrolledFrame->GetContent());
|
||||
|
||||
|
@ -2651,41 +2651,6 @@ inline static bool IsSVGContentWithCSSClip(const nsIFrame* aFrame) {
|
||||
nsGkAtoms::foreignObject);
|
||||
}
|
||||
|
||||
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 (!style.IsRootElementStyle()) {
|
||||
if (effects.HasFilters() || effects.HasBackdropFilters()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (effects.HasMixBlendMode()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Check for opacity.
|
||||
const auto& disp = *style.StyleDisplay();
|
||||
if (HasOpacity(&disp, &effects)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Check for mask or clip path.
|
||||
const auto& svgReset = *style.StyleSVGReset();
|
||||
if (svgReset.HasMask() || svgReset.HasClipPath()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// TODO(cbrewster): Check will-change attributes
|
||||
return false;
|
||||
}
|
||||
|
||||
Maybe<nsRect> nsIFrame::GetClipPropClipRect(const nsStyleDisplay* aDisp,
|
||||
const nsStyleEffects* aEffects,
|
||||
const nsSize& aSize) const {
|
||||
@ -2849,30 +2814,6 @@ class AutoSaveRestoreContainsBlendMode {
|
||||
}
|
||||
};
|
||||
|
||||
class AutoSaveRestoreContainsBackdropFilter {
|
||||
nsDisplayListBuilder& mBuilder;
|
||||
bool mSavedContainsBackdropFilter;
|
||||
|
||||
public:
|
||||
explicit AutoSaveRestoreContainsBackdropFilter(nsDisplayListBuilder& aBuilder)
|
||||
: mBuilder(aBuilder),
|
||||
mSavedContainsBackdropFilter(aBuilder.ContainsBackdropFilter()) {}
|
||||
|
||||
/**
|
||||
* This is called if a stacking context which does not form a backdrop root
|
||||
* contains a descendent with a backdrop filter. In this case we need to
|
||||
* delegate backdrop root creation to the next parent in the tree until we hit
|
||||
* the nearest backdrop root ancestor.
|
||||
*/
|
||||
void DelegateUp(bool aContainsBackdropFilter) {
|
||||
mSavedContainsBackdropFilter = aContainsBackdropFilter;
|
||||
}
|
||||
|
||||
~AutoSaveRestoreContainsBackdropFilter() {
|
||||
mBuilder.SetContainsBackdropFilter(mSavedContainsBackdropFilter);
|
||||
}
|
||||
};
|
||||
|
||||
static void CheckForApzAwareEventHandlers(nsDisplayListBuilder* aBuilder,
|
||||
nsIFrame* aFrame) {
|
||||
if (aBuilder->GetAncestorHasApzAwareEventHandler()) {
|
||||
@ -3236,12 +3177,6 @@ void nsIFrame::BuildDisplayListForStackingContext(
|
||||
bool usingBackdropFilter = effects->HasBackdropFilters() &&
|
||||
IsVisibleForPainting() &&
|
||||
!style.IsRootElementStyle();
|
||||
if (usingBackdropFilter) {
|
||||
aBuilder->SetContainsBackdropFilter(true);
|
||||
}
|
||||
|
||||
AutoSaveRestoreContainsBackdropFilter autoRestoreBackdropFilter(*aBuilder);
|
||||
aBuilder->SetContainsBackdropFilter(false);
|
||||
|
||||
nsRect visibleRectOutsideTransform = visibleRect;
|
||||
nsDisplayTransform::PrerenderInfo prerenderInfo;
|
||||
@ -3444,7 +3379,6 @@ void nsIFrame::BuildDisplayListForStackingContext(
|
||||
|
||||
nsDisplayListCollection set(aBuilder);
|
||||
Maybe<nsRect> clipForMask;
|
||||
bool insertBackdropRoot;
|
||||
{
|
||||
DisplayListClipState::AutoSaveRestore nestedClipState(aBuilder);
|
||||
nsDisplayListBuilder::AutoInTransformSetter inTransformSetter(aBuilder,
|
||||
@ -3490,9 +3424,6 @@ void nsIFrame::BuildDisplayListForStackingContext(
|
||||
aBuilder->Check();
|
||||
aBuilder->DisplayCaret(this, set.Outlines());
|
||||
|
||||
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
|
||||
// the current stacking context. This can change without an invalidation
|
||||
@ -3511,7 +3442,7 @@ void nsIFrame::BuildDisplayListForStackingContext(
|
||||
// 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 ((insertBackdropRoot || aBuilder->ContainsBlendMode()) &&
|
||||
if ((aBuilder->ContainsBlendMode()) &&
|
||||
aBuilder->IsRetainingDisplayList()) {
|
||||
if (aBuilder->IsPartialUpdate()) {
|
||||
aBuilder->SetPartialBuildFailed(true);
|
||||
@ -3521,13 +3452,6 @@ void nsIFrame::BuildDisplayListForStackingContext(
|
||||
}
|
||||
}
|
||||
|
||||
// If a child contains a backdrop filter, but this stacking context does not
|
||||
// form a backdrop root, we need to propogate up the tree until we find an
|
||||
// ancestor that does form a backdrop root.
|
||||
if (!insertBackdropRoot && aBuilder->ContainsBackdropFilter()) {
|
||||
autoRestoreBackdropFilter.DelegateUp(true);
|
||||
}
|
||||
|
||||
if (aBuilder->IsBackgroundOnly()) {
|
||||
set.BlockBorderBackgrounds()->DeleteAll(aBuilder);
|
||||
set.Floats()->DeleteAll(aBuilder);
|
||||
@ -3579,14 +3503,6 @@ void nsIFrame::BuildDisplayListForStackingContext(
|
||||
createdContainer = true;
|
||||
}
|
||||
|
||||
if (insertBackdropRoot) {
|
||||
DisplayListClipState::AutoSaveRestore backdropRootContainerClipState(
|
||||
aBuilder);
|
||||
resultList.AppendNewToTop<nsDisplayBackdropRootContainer>(
|
||||
aBuilder, this, &resultList, containerItemASR);
|
||||
createdContainer = true;
|
||||
}
|
||||
|
||||
if (usingBackdropFilter) {
|
||||
DisplayListClipState::AutoSaveRestore clipState(aBuilder);
|
||||
nsRect backdropRect =
|
||||
|
@ -1951,12 +1951,6 @@ class nsIFrame : public nsQueryFrame {
|
||||
virtual bool IsSVGTransformed(Matrix* aOwnTransforms = nullptr,
|
||||
Matrix* aFromParentTransforms = nullptr) const;
|
||||
|
||||
/**
|
||||
* Return true if this frame should form a backdrop root container.
|
||||
* See: https://drafts.fxtf.org/filter-effects-2/#BackdropRootTriggers
|
||||
*/
|
||||
bool FormsBackdropRoot() const;
|
||||
|
||||
/**
|
||||
* Returns whether this frame will attempt to extend the 3d transforms of its
|
||||
* children. This requires transform-style: preserve-3d, as well as no
|
||||
|
@ -693,7 +693,6 @@ nsDisplayListBuilder::nsDisplayListBuilder(nsIFrame* aReferenceFrame,
|
||||
mPartialBuildFailed(false),
|
||||
mIsInActiveDocShell(false),
|
||||
mBuildAsyncZoomContainer(false),
|
||||
mContainsBackdropFilter(false),
|
||||
mIsRelativeToLayoutViewport(false),
|
||||
mUseOverlayScrollbars(false),
|
||||
mAlwaysLayerizeScrollbars(false) {
|
||||
@ -8272,30 +8271,6 @@ void nsDisplayMasksAndClipPaths::PrintEffects(nsACString& aTo) {
|
||||
}
|
||||
#endif
|
||||
|
||||
void nsDisplayBackdropRootContainer::Paint(nsDisplayListBuilder* aBuilder,
|
||||
gfxContext* aCtx) {
|
||||
aCtx->GetDrawTarget()->PushLayer(false, 1.0, nullptr, gfx::Matrix());
|
||||
GetChildren()->Paint(aBuilder, aCtx,
|
||||
mFrame->PresContext()->AppUnitsPerDevPixel());
|
||||
aCtx->GetDrawTarget()->PopLayer();
|
||||
}
|
||||
|
||||
bool nsDisplayBackdropRootContainer::CreateWebRenderCommands(
|
||||
wr::DisplayListBuilder& aBuilder, wr::IpcResourceUpdateQueue& aResources,
|
||||
const StackingContextHelper& aSc, RenderRootStateManager* aManager,
|
||||
nsDisplayListBuilder* aDisplayListBuilder) {
|
||||
wr::StackingContextParams params;
|
||||
params.flags |= wr::StackingContextFlags::IS_BACKDROP_ROOT;
|
||||
params.clip =
|
||||
wr::WrStackingContextClip::ClipChain(aBuilder.CurrentClipChainId());
|
||||
StackingContextHelper sc(aSc, GetActiveScrolledRoot(), mFrame, this, aBuilder,
|
||||
params);
|
||||
|
||||
nsDisplayWrapList::CreateWebRenderCommands(aBuilder, aResources, sc, aManager,
|
||||
aDisplayListBuilder);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool nsDisplayBackdropFilters::CreateWebRenderCommands(
|
||||
wr::DisplayListBuilder& aBuilder, wr::IpcResourceUpdateQueue& aResources,
|
||||
const StackingContextHelper& aSc, RenderRootStateManager* aManager,
|
||||
|
@ -1490,17 +1490,6 @@ class nsDisplayListBuilder {
|
||||
}
|
||||
bool ContainsBlendMode() const { return mContainsBlendMode; }
|
||||
|
||||
/**
|
||||
* mContainsBackdropFilter is true if we proccessed a display item that
|
||||
* has a backdrop filter set. We track this so we can insert a
|
||||
* nsDisplayBackdropRootContainer in the stacking context of the nearest
|
||||
* ancestor that forms a backdrop root.
|
||||
*/
|
||||
void SetContainsBackdropFilter(bool aContainsBackdropFilter) {
|
||||
mContainsBackdropFilter = aContainsBackdropFilter;
|
||||
}
|
||||
bool ContainsBackdropFilter() const { return mContainsBackdropFilter; }
|
||||
|
||||
DisplayListClipState& ClipState() { return mClipState; }
|
||||
const ActiveScrolledRoot* CurrentActiveScrolledRoot() {
|
||||
return mCurrentActiveScrolledRoot;
|
||||
@ -1918,7 +1907,6 @@ class nsDisplayListBuilder {
|
||||
bool mPartialBuildFailed;
|
||||
bool mIsInActiveDocShell;
|
||||
bool mBuildAsyncZoomContainer;
|
||||
bool mContainsBackdropFilter;
|
||||
bool mIsRelativeToLayoutViewport;
|
||||
bool mUseOverlayScrollbars;
|
||||
bool mAlwaysLayerizeScrollbars;
|
||||
@ -5946,34 +5934,6 @@ class nsDisplayMasksAndClipPaths : public nsDisplayEffectsBase {
|
||||
nsTArray<nsRect> mDestRects;
|
||||
};
|
||||
|
||||
class nsDisplayBackdropRootContainer : public nsDisplayWrapList {
|
||||
public:
|
||||
nsDisplayBackdropRootContainer(nsDisplayListBuilder* aBuilder,
|
||||
nsIFrame* aFrame, nsDisplayList* aList,
|
||||
const ActiveScrolledRoot* aActiveScrolledRoot)
|
||||
: nsDisplayWrapList(aBuilder, aFrame, aList, aActiveScrolledRoot, true) {
|
||||
MOZ_COUNT_CTOR(nsDisplayBackdropRootContainer);
|
||||
}
|
||||
|
||||
MOZ_COUNTED_DTOR_OVERRIDE(nsDisplayBackdropRootContainer)
|
||||
|
||||
NS_DISPLAY_DECL_NAME("BackdropRootContainer", TYPE_BACKDROP_ROOT_CONTAINER)
|
||||
|
||||
void Paint(nsDisplayListBuilder* aBuilder, gfxContext* aCtx) override;
|
||||
|
||||
bool CreateWebRenderCommands(
|
||||
wr::DisplayListBuilder& aBuilder, wr::IpcResourceUpdateQueue& aResources,
|
||||
const StackingContextHelper& aSc,
|
||||
layers::RenderRootStateManager* aManager,
|
||||
nsDisplayListBuilder* aDisplayListBuilder) override;
|
||||
|
||||
bool ShouldFlattenAway(nsDisplayListBuilder* aBuilder) override {
|
||||
return !aBuilder->IsPaintingForWebRender();
|
||||
}
|
||||
|
||||
bool CreatesStackingContextHelper() override { return true; }
|
||||
};
|
||||
|
||||
class nsDisplayBackdropFilters : public nsDisplayWrapList {
|
||||
public:
|
||||
nsDisplayBackdropFilters(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
|
||||
|
Loading…
Reference in New Issue
Block a user