зеркало из https://github.com/mozilla/gecko-dev.git
Backed out 7 changesets (bug 1728050, bug 1728251, bug 1728232, bug 1542929, bug 1714138, bug 1728258) for causing reftest failures. CLOSED TREE
Backed out changeset 41e053201cd3 (bug 1714138) Backed out changeset 16ae9f5b4aa0 (bug 1728258) Backed out changeset 414aa7ff05fe (bug 1542929) Backed out changeset 7217ecf149c4 (bug 1728251) Backed out changeset 405ff2ed2110 (bug 1728251) Backed out changeset 3eec9e6c7218 (bug 1728232) Backed out changeset 66038c15fe54 (bug 1728050)
This commit is contained in:
Родитель
2e2a57ae9d
Коммит
d25d135947
|
@ -275,7 +275,7 @@ Maybe<wr::WrSpatialId> ClipManager::DefineScrollLayers(
|
|||
|
||||
Maybe<ScrollMetadata> metadata =
|
||||
aASR->mScrollableFrame->ComputeScrollMetadata(
|
||||
mManager, aItem->Frame(), aItem->ToReferenceFrame(), nullptr);
|
||||
mManager, aItem->ReferenceFrame(), nullptr);
|
||||
if (!metadata) {
|
||||
MOZ_ASSERT_UNREACHABLE("Expected scroll metadata to be available!");
|
||||
return ancestorSpace;
|
||||
|
@ -289,8 +289,7 @@ Maybe<wr::WrSpatialId> ClipManager::DefineScrollLayers(
|
|||
|
||||
nsIScrollableFrame* scrollableFrame = aASR->mScrollableFrame;
|
||||
nsIFrame* scrollFrame = do_QueryFrame(scrollableFrame);
|
||||
nsPoint offset = scrollFrame->GetOffsetToCrossDoc(aItem->Frame()) +
|
||||
aItem->ToReferenceFrame();
|
||||
nsPoint offset = scrollFrame->GetOffsetToCrossDoc(aItem->ReferenceFrame());
|
||||
float auPerDevPixel = aItem->Frame()->PresContext()->AppUnitsPerDevPixel();
|
||||
nsRect scrollPort = scrollableFrame->GetScrollPortRect() + offset;
|
||||
LayoutDeviceRect clipBounds =
|
||||
|
|
|
@ -180,12 +180,6 @@ Maybe<uint16_t> DisplayItemCache::CanReuseItem(
|
|||
return Nothing();
|
||||
}
|
||||
|
||||
if (mSuppressed) {
|
||||
slot.mOccupied = false;
|
||||
slotIndex = Nothing();
|
||||
return Nothing();
|
||||
}
|
||||
|
||||
if (!(aSpaceAndClip == slot.mSpaceAndClip)) {
|
||||
// Spatial id and clip id can change between display lists, if items that
|
||||
// generate them change their order.
|
||||
|
|
|
@ -100,9 +100,9 @@ class DisplayItemCache final {
|
|||
/**
|
||||
* Suppress display item caching. This doesn't clear any existing cached
|
||||
* items or change the underlying capacity, it just makes IsEnabled() return
|
||||
* false.
|
||||
* It will also make CanReuseItem return false for the duration of the
|
||||
* suppression.
|
||||
* false. It is not meant to be flipped in the middle of a display list build,
|
||||
* but rather set before the display list build starts to suppress use of the
|
||||
* cache for that display list build.
|
||||
*/
|
||||
bool SetSuppressed(bool aSuppressed) {
|
||||
if (aSuppressed == mSuppressed) {
|
||||
|
|
|
@ -2484,8 +2484,6 @@ Maybe<wr::ImageMask> WebRenderCommandBuilder::BuildWrMaskImage(
|
|||
|
||||
nsPoint maskOffset = aMaskItem->ToReferenceFrame() - bounds.TopLeft();
|
||||
|
||||
bool shouldHandleOpacity = aBuilder.GetInheritedOpacity() != 1.0f;
|
||||
|
||||
nsRect dirtyRect;
|
||||
// If this mask item is being painted for the first time, some members of
|
||||
// WebRenderMaskData are still default initialized. This is intentional.
|
||||
|
@ -2493,7 +2491,7 @@ Maybe<wr::ImageMask> WebRenderCommandBuilder::BuildWrMaskImage(
|
|||
!itemRect.IsEqualInterior(maskData->mItemRect) ||
|
||||
!(aMaskItem->Frame()->StyleSVGReset()->mMask == maskData->mMaskStyle) ||
|
||||
maskOffset != maskData->mMaskOffset || !sameScale ||
|
||||
shouldHandleOpacity != maskData->mShouldHandleOpacity) {
|
||||
aMaskItem->ShouldHandleOpacity() != maskData->mShouldHandleOpacity) {
|
||||
IntSize size = itemRect.Size().ToUnknownSize();
|
||||
|
||||
if (!Factory::AllowedSurfaceSize(size)) {
|
||||
|
@ -2537,8 +2535,8 @@ Maybe<wr::ImageMask> WebRenderCommandBuilder::BuildWrMaskImage(
|
|||
.PreScale(scale.width, scale.height));
|
||||
|
||||
bool maskPainted = false;
|
||||
bool maskIsComplete = aMaskItem->PaintMask(
|
||||
aDisplayListBuilder, context, shouldHandleOpacity, &maskPainted);
|
||||
bool maskIsComplete =
|
||||
aMaskItem->PaintMask(aDisplayListBuilder, context, &maskPainted);
|
||||
if (!maskPainted) {
|
||||
return Nothing();
|
||||
}
|
||||
|
@ -2589,7 +2587,7 @@ Maybe<wr::ImageMask> WebRenderCommandBuilder::BuildWrMaskImage(
|
|||
maskData->mMaskOffset = maskOffset;
|
||||
maskData->mScale = scale;
|
||||
maskData->mMaskStyle = aMaskItem->Frame()->StyleSVGReset()->mMask;
|
||||
maskData->mShouldHandleOpacity = shouldHandleOpacity;
|
||||
maskData->mShouldHandleOpacity = aMaskItem->ShouldHandleOpacity();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -64,8 +64,7 @@ void WebRenderLayerScrollData::Initialize(
|
|||
} else {
|
||||
Maybe<ScrollMetadata> metadata =
|
||||
asr->mScrollableFrame->ComputeScrollMetadata(
|
||||
aOwner.GetManager(), aItem->Frame(), aItem->ToReferenceFrame(),
|
||||
nullptr);
|
||||
aOwner.GetManager(), aItem->ReferenceFrame(), nullptr);
|
||||
aOwner.GetBuilder()->AddScrollFrameToNotify(asr->mScrollableFrame);
|
||||
if (metadata) {
|
||||
MOZ_ASSERT(metadata->GetMetrics().GetScrollId() == scrollId);
|
||||
|
|
|
@ -684,17 +684,6 @@ class DisplayListBuilder final {
|
|||
mClipChainLeaf = aClipRect;
|
||||
}
|
||||
|
||||
// Used for opacity flattening. When we flatten away an opacity item,
|
||||
// we push the opacity value onto the builder.
|
||||
// Descendant items should pull the inherited opacity during
|
||||
// their CreateWebRenderCommands implementation. This can only happen if all
|
||||
// descendant items reported supporting this functionality, via
|
||||
// nsDisplayItem::CanApplyOpacity.
|
||||
float GetInheritedOpacity() { return mInheritedOpacity; }
|
||||
void SetInheritedOpacity(float aOpacity) { mInheritedOpacity = aOpacity; }
|
||||
|
||||
layers::DisplayItemCache* GetDisplayItemCache() { return mDisplayItemCache; }
|
||||
|
||||
// A chain of RAII objects, each holding a (ASR, ViewID, SideBits) tuple of
|
||||
// data. The topmost object is pointed to by the mActiveFixedPosTracker
|
||||
// pointer in the wr::DisplayListBuilder.
|
||||
|
@ -761,7 +750,6 @@ class DisplayListBuilder final {
|
|||
|
||||
layers::DisplayItemCache* mDisplayItemCache;
|
||||
Maybe<uint16_t> mCurrentCacheSlot;
|
||||
float mInheritedOpacity = 1.0f;
|
||||
|
||||
friend class WebRenderAPI;
|
||||
friend class SpaceAndClipChainHelper;
|
||||
|
|
|
@ -60,6 +60,8 @@ static void PrintDisplayItemTo(nsDisplayListBuilder* aBuilder,
|
|||
}
|
||||
bool snap;
|
||||
nsRect rect = aItem->GetBounds(aBuilder, &snap);
|
||||
nsRect layerRect = rect - (*aItem->GetAnimatedGeometryRoot())
|
||||
->GetOffsetToCrossDoc(aItem->ReferenceFrame());
|
||||
nsRect component = aItem->GetComponentAlphaBounds(aBuilder);
|
||||
nsDisplayList* list = aItem->GetChildren();
|
||||
const DisplayItemClip& clip = aItem->GetClip();
|
||||
|
@ -77,15 +79,19 @@ static void PrintDisplayItemTo(nsDisplayListBuilder* aBuilder,
|
|||
|
||||
aStream << nsPrintfCString(
|
||||
"%s p=0x%p f=0x%p(%s) key=%d %sbounds(%d,%d,%d,%d) "
|
||||
"componentAlpha(%d,%d,%d,%d) clip(%s) asr(%s) clipChain(%s)%s ",
|
||||
"layerBounds(%d,%d,%d,%d) "
|
||||
"componentAlpha(%d,%d,%d,%d) clip(%s) asr(%s) clipChain(%s)%s ref=0x%p "
|
||||
"agr=0x%p",
|
||||
aItem->Name(), aItem, (void*)f, NS_ConvertUTF16toUTF8(contentData).get(),
|
||||
aItem->GetPerFrameKey(),
|
||||
(aItem->ZIndex() ? nsPrintfCString("z=%d ", aItem->ZIndex()).get() : ""),
|
||||
rect.x, rect.y, rect.width, rect.height, component.x, component.y,
|
||||
rect.x, rect.y, rect.width, rect.height, layerRect.x, layerRect.y,
|
||||
layerRect.width, layerRect.height, component.x, component.y,
|
||||
component.width, component.height, clip.ToString().get(),
|
||||
ActiveScrolledRoot::ToString(aItem->GetActiveScrolledRoot()).get(),
|
||||
DisplayItemClipChain::ToString(aItem->GetClipChain()).get(),
|
||||
aItem->IsUniform(aBuilder) ? " uniform" : "");
|
||||
aItem->IsUniform(aBuilder) ? " uniform" : "", aItem->ReferenceFrame(),
|
||||
aItem->GetAnimatedGeometryRoot()->mFrame);
|
||||
|
||||
for (auto iter = opaque.RectIter(); !iter.Done(); iter.Next()) {
|
||||
const nsRect& r = iter.Get();
|
||||
|
|
|
@ -8540,8 +8540,7 @@ bool nsLayoutUtils::CanScrollOriginClobberApz(ScrollOrigin aScrollOrigin) {
|
|||
/* static */
|
||||
ScrollMetadata nsLayoutUtils::ComputeScrollMetadata(
|
||||
const nsIFrame* aForFrame, const nsIFrame* aScrollFrame,
|
||||
nsIContent* aContent, const nsIFrame* aItemFrame,
|
||||
const nsPoint& aOffsetToReferenceFrame,
|
||||
nsIContent* aContent, const nsIFrame* aReferenceFrame,
|
||||
WebRenderLayerManager* aLayerManager, ViewID aScrollParentId,
|
||||
const nsSize& aScrollPortSize, const Maybe<nsRect>& aClipRect,
|
||||
bool aIsRootContent) {
|
||||
|
@ -8799,8 +8798,8 @@ ScrollMetadata nsLayoutUtils::ComputeScrollMetadata(
|
|||
const nsIFrame* frameForCompositionBoundsCalculation =
|
||||
aScrollFrame ? aScrollFrame : aForFrame;
|
||||
nsRect compositionBounds(
|
||||
frameForCompositionBoundsCalculation->GetOffsetToCrossDoc(aItemFrame) +
|
||||
aOffsetToReferenceFrame,
|
||||
frameForCompositionBoundsCalculation->GetOffsetToCrossDoc(
|
||||
aReferenceFrame),
|
||||
frameForCompositionBoundsCalculation->GetSize());
|
||||
if (scrollableFrame) {
|
||||
// If we have a scrollable frame, restrict the composition bounds to its
|
||||
|
@ -8963,10 +8962,9 @@ Maybe<ScrollMetadata> nsLayoutUtils::GetRootMetadata(
|
|||
scrollPortSize = scrollableFrame->GetScrollPortRect().Size();
|
||||
}
|
||||
return Some(nsLayoutUtils::ComputeScrollMetadata(
|
||||
frame, rootScrollFrame, content, frame,
|
||||
aBuilder->ToReferenceFrame(frame), aLayerManager,
|
||||
ScrollableLayerGuid::NULL_SCROLL_ID, scrollPortSize, Nothing(),
|
||||
isRootContent));
|
||||
frame, rootScrollFrame, content, aBuilder->FindReferenceFrameFor(frame),
|
||||
aLayerManager, ScrollableLayerGuid::NULL_SCROLL_ID, scrollPortSize,
|
||||
Nothing(), isRootContent));
|
||||
}
|
||||
|
||||
return Nothing();
|
||||
|
|
|
@ -2760,8 +2760,7 @@ class nsLayoutUtils {
|
|||
|
||||
static ScrollMetadata ComputeScrollMetadata(
|
||||
const nsIFrame* aForFrame, const nsIFrame* aScrollFrame,
|
||||
nsIContent* aContent, const nsIFrame* aItemFrame,
|
||||
const nsPoint& aOffsetToReferenceFrame,
|
||||
nsIContent* aContent, const nsIFrame* aReferenceFrame,
|
||||
mozilla::layers::WebRenderLayerManager* aLayerManager,
|
||||
ViewID aScrollParentId, const nsSize& aScrollPortSize,
|
||||
const mozilla::Maybe<nsRect>& aClipRect, bool aIsRoot);
|
||||
|
|
|
@ -166,15 +166,14 @@ class nsDisplayListFocus : public nsPaintedDisplayItem {
|
|||
// the nsSelectsAreaFrame
|
||||
nsListControlFrame* listFrame = GetEnclosingListFrame(Frame());
|
||||
return listFrame->InkOverflowRectRelativeToSelf() +
|
||||
listFrame->GetOffsetToCrossDoc(Frame()) + ToReferenceFrame();
|
||||
listFrame->GetOffsetToCrossDoc(ReferenceFrame());
|
||||
}
|
||||
virtual void Paint(nsDisplayListBuilder* aBuilder,
|
||||
gfxContext* aCtx) override {
|
||||
nsListControlFrame* listFrame = GetEnclosingListFrame(Frame());
|
||||
// listFrame must be non-null or we wouldn't get called.
|
||||
listFrame->PaintFocus(
|
||||
aCtx->GetDrawTarget(),
|
||||
listFrame->GetOffsetToCrossDoc(Frame()) + ToReferenceFrame());
|
||||
listFrame->PaintFocus(aCtx->GetDrawTarget(),
|
||||
aBuilder->ToReferenceFrame(listFrame));
|
||||
}
|
||||
NS_DISPLAY_DECL_NAME("ListFocus", TYPE_LIST_FOCUS)
|
||||
};
|
||||
|
|
|
@ -76,7 +76,7 @@ class TextDrawTarget : public DrawTarget {
|
|||
mHasUnsupportedFeatures = false;
|
||||
mHasShadows = false;
|
||||
|
||||
SetPermitSubpixelAA(true);
|
||||
SetPermitSubpixelAA(!aItem->IsSubpixelAADisabled());
|
||||
|
||||
// Compute clip/bounds
|
||||
auto appUnitsPerDevPixel =
|
||||
|
|
|
@ -209,6 +209,9 @@ static void PaintTextShadowCallback(gfxContext* aCtx, nsPoint aShadowOffset,
|
|||
|
||||
void nsDisplayTextOverflowMarker::Paint(nsDisplayListBuilder* aBuilder,
|
||||
gfxContext* aCtx) {
|
||||
DrawTargetAutoDisableSubpixelAntialiasing disable(aCtx->GetDrawTarget(),
|
||||
IsSubpixelAADisabled());
|
||||
|
||||
nscolor foregroundColor =
|
||||
nsLayoutUtils::GetColor(mFrame, &nsStyleText::mWebkitTextFillColor);
|
||||
|
||||
|
|
|
@ -4354,6 +4354,9 @@ nsRect ScrollFrameHelper::RestrictToRootDisplayPort(
|
|||
bool ScrollFrameHelper::DecideScrollableLayer(
|
||||
nsDisplayListBuilder* aBuilder, nsRect* aVisibleRect, nsRect* aDirtyRect,
|
||||
bool aSetBase, bool* aDirtyRectHasBeenOverriden) {
|
||||
// Save and check if this changes so we can recompute the current agr.
|
||||
bool oldWillBuildScrollableLayer = mWillBuildScrollableLayer;
|
||||
|
||||
nsIContent* content = mOuter->GetContent();
|
||||
// For hit testing purposes with fission we want to create a
|
||||
// minimal display port for every scroll frame that could be active. (We only
|
||||
|
@ -4474,6 +4477,13 @@ bool ScrollFrameHelper::DecideScrollableLayer(
|
|||
mWillBuildScrollableLayer = usingDisplayPort ||
|
||||
nsContentUtils::HasScrollgrab(content) ||
|
||||
mZoomableByAPZ;
|
||||
|
||||
// The cached animated geometry root for the display builder is out of
|
||||
// date if we just introduced a new animated geometry root.
|
||||
if (oldWillBuildScrollableLayer != mWillBuildScrollableLayer) {
|
||||
aBuilder->RecomputeCurrentAnimatedGeometryRoot();
|
||||
}
|
||||
|
||||
return mWillBuildScrollableLayer;
|
||||
}
|
||||
|
||||
|
@ -4488,8 +4498,8 @@ void ScrollFrameHelper::NotifyApzTransaction() {
|
|||
}
|
||||
|
||||
Maybe<ScrollMetadata> ScrollFrameHelper::ComputeScrollMetadata(
|
||||
WebRenderLayerManager* aLayerManager, const nsIFrame* aItemFrame,
|
||||
const nsPoint& aOffsetToReferenceFrame,
|
||||
WebRenderLayerManager* aLayerManager,
|
||||
const nsIFrame* aContainerReferenceFrame,
|
||||
const DisplayItemClip* aClip) const {
|
||||
if (!mWillBuildScrollableLayer) {
|
||||
return Nothing();
|
||||
|
@ -4506,9 +4516,9 @@ Maybe<ScrollMetadata> ScrollFrameHelper::ComputeScrollMetadata(
|
|||
MOZ_ASSERT(mScrolledFrame->GetContent());
|
||||
|
||||
return Some(nsLayoutUtils::ComputeScrollMetadata(
|
||||
mScrolledFrame, mOuter, mOuter->GetContent(), aItemFrame,
|
||||
aOffsetToReferenceFrame, aLayerManager, mScrollParentID,
|
||||
mScrollPort.Size(), parentLayerClip, isRootContent));
|
||||
mScrolledFrame, mOuter, mOuter->GetContent(), aContainerReferenceFrame,
|
||||
aLayerManager, mScrollParentID, mScrollPort.Size(), parentLayerClip,
|
||||
isRootContent));
|
||||
}
|
||||
|
||||
bool ScrollFrameHelper::IsRectNearlyVisible(const nsRect& aRect) const {
|
||||
|
|
|
@ -484,8 +484,8 @@ class ScrollFrameHelper : public nsIReflowCallback {
|
|||
bool aApzAnimationInProgress);
|
||||
bool WantAsyncScroll() const;
|
||||
Maybe<mozilla::layers::ScrollMetadata> ComputeScrollMetadata(
|
||||
WebRenderLayerManager* aLayerManager, const nsIFrame* aItemFrame,
|
||||
const nsPoint& aOffsetToReferenceFrame,
|
||||
WebRenderLayerManager* aLayerManager,
|
||||
const nsIFrame* aContainerReferenceFrame,
|
||||
const mozilla::DisplayItemClip* aClip) const;
|
||||
// nsIScrollbarMediator
|
||||
void ScrollByPage(nsScrollbarFrame* aScrollbar, int32_t aDirection,
|
||||
|
@ -1085,10 +1085,10 @@ class nsHTMLScrollFrame : public nsContainerFrame,
|
|||
bool WantAsyncScroll() const final { return mHelper.WantAsyncScroll(); }
|
||||
mozilla::Maybe<mozilla::layers::ScrollMetadata> ComputeScrollMetadata(
|
||||
mozilla::layers::WebRenderLayerManager* aLayerManager,
|
||||
const nsIFrame* aItemFrame, const nsPoint& aOffsetToReferenceFrame,
|
||||
const nsIFrame* aContainerReferenceFrame,
|
||||
const mozilla::DisplayItemClip* aClip) const final {
|
||||
return mHelper.ComputeScrollMetadata(aLayerManager, aItemFrame,
|
||||
aOffsetToReferenceFrame, aClip);
|
||||
return mHelper.ComputeScrollMetadata(aLayerManager,
|
||||
aContainerReferenceFrame, aClip);
|
||||
}
|
||||
void MarkScrollbarsDirtyForReflow() const final {
|
||||
mHelper.MarkScrollbarsDirtyForReflow();
|
||||
|
@ -1563,10 +1563,10 @@ class nsXULScrollFrame final : public nsBoxFrame,
|
|||
bool WantAsyncScroll() const final { return mHelper.WantAsyncScroll(); }
|
||||
mozilla::Maybe<mozilla::layers::ScrollMetadata> ComputeScrollMetadata(
|
||||
mozilla::layers::WebRenderLayerManager* aLayerManager,
|
||||
const nsIFrame* aItemFrame, const nsPoint& aOffsetToReferenceFrame,
|
||||
const nsIFrame* aContainerReferenceFrame,
|
||||
const mozilla::DisplayItemClip* aClip) const final {
|
||||
return mHelper.ComputeScrollMetadata(aLayerManager, aItemFrame,
|
||||
aOffsetToReferenceFrame, aClip);
|
||||
return mHelper.ComputeScrollMetadata(aLayerManager,
|
||||
aContainerReferenceFrame, aClip);
|
||||
}
|
||||
void MarkScrollbarsDirtyForReflow() const final {
|
||||
mHelper.MarkScrollbarsDirtyForReflow();
|
||||
|
|
|
@ -476,7 +476,7 @@ class nsIScrollableFrame : public nsIScrollbarMediator {
|
|||
*/
|
||||
virtual mozilla::Maybe<mozilla::layers::ScrollMetadata> ComputeScrollMetadata(
|
||||
mozilla::layers::WebRenderLayerManager* aLayerManager,
|
||||
const nsIFrame* aItemFrame, const nsPoint& aOffsetToReferenceFrame,
|
||||
const nsIFrame* aContainerReferenceFrame,
|
||||
const mozilla::DisplayItemClip* aClip) const = 0;
|
||||
|
||||
/**
|
||||
|
|
|
@ -407,7 +407,7 @@ class nsDisplayHeaderFooter final : public nsPaintedDisplayItem {
|
|||
MOZ_ASSERT(pageFrame, "We should have an nsPageFrame");
|
||||
#endif
|
||||
static_cast<nsPageFrame*>(mFrame)->PaintHeaderFooter(
|
||||
*aCtx, ToReferenceFrame(), false);
|
||||
*aCtx, ToReferenceFrame(), IsSubpixelAADisabled());
|
||||
}
|
||||
NS_DISPLAY_DECL_NAME("HeaderFooter", TYPE_HEADER_FOOTER)
|
||||
|
||||
|
|
|
@ -43,29 +43,6 @@
|
|||
* we would have built both in the new list if they intersected. Given that, we
|
||||
* can align items that appear in both lists, and any items that appear between
|
||||
* matched items can be inserted into the merged list in any order.
|
||||
*
|
||||
* Frames that are a stacking context, containing blocks for position:fixed
|
||||
* descendants, and don't have any continuations (see
|
||||
* CanStoreDisplayListBuildingRect) trigger recursion into the algorithm with
|
||||
* separate retaining decisions made.
|
||||
*
|
||||
* RDL defines the concept of an AnimatedGeometryRoot (AGR), the nearest
|
||||
* ancestor frame which can be moved asynchronously on the compositor thread.
|
||||
* These are currently nsDisplayItems which return true from CanMoveAsync
|
||||
* (animated nsDisplayTransform and nsDisplayStickyPosition) and
|
||||
* ActiveScrolledRoots.
|
||||
*
|
||||
* For each context that we run the retaining algorithm, there can only be
|
||||
* mutations to one AnimatedGeometryRoot. This is because we are unable to
|
||||
* reason about intersections of items that might then move relative to each
|
||||
* other without RDL running again. If there are mutations to multiple
|
||||
* AnimatedGeometryRoots, then we bail out and rebuild all the items in the
|
||||
* context.
|
||||
*
|
||||
* Otherwise, when mutations are restricted to a single AGR, we pre-process the
|
||||
* old display list and mark the frames for all existing (unmodified!) items
|
||||
* that belong to a different AGR and ensure that we rebuild those items for
|
||||
* correct sorting with the modified ones.
|
||||
*/
|
||||
|
||||
using mozilla::dom::Document;
|
||||
|
@ -124,7 +101,8 @@ static void MarkFramesWithItemsAndImagesModified(nsDisplayList* aList) {
|
|||
}
|
||||
}
|
||||
|
||||
static nsIFrame* SelectAGRForFrame(nsIFrame* aFrame, nsIFrame* aParentAGR) {
|
||||
static AnimatedGeometryRoot* SelectAGRForFrame(
|
||||
nsIFrame* aFrame, AnimatedGeometryRoot* aParentAGR) {
|
||||
if (!aFrame->IsStackingContext() || !aFrame->IsFixedPosContainingBlock()) {
|
||||
return aParentAGR;
|
||||
}
|
||||
|
@ -136,7 +114,7 @@ static nsIFrame* SelectAGRForFrame(nsIFrame* aFrame, nsIFrame* aParentAGR) {
|
|||
nsDisplayListBuilder::DisplayListBuildingData* data =
|
||||
aFrame->GetProperty(nsDisplayListBuilder::DisplayListBuildingRect());
|
||||
|
||||
return data && data->mModifiedAGR ? data->mModifiedAGR : nullptr;
|
||||
return data && data->mModifiedAGR ? data->mModifiedAGR.get() : nullptr;
|
||||
}
|
||||
|
||||
void RetainedDisplayListBuilder::AddSizeOfIncludingThis(
|
||||
|
@ -170,10 +148,9 @@ bool AnyContentAncestorModified(nsIFrame* aFrame, nsIFrame* aStopAtFrame) {
|
|||
// to mark, as child stacking contexts might. It would be nice if we could
|
||||
// jump into those immediately rather than walking the entire thing.
|
||||
bool RetainedDisplayListBuilder::PreProcessDisplayList(
|
||||
RetainedDisplayList* aList, nsIFrame* aAGR, PartialUpdateResult& aUpdated,
|
||||
nsIFrame* aAsyncAncestor, const ActiveScrolledRoot* aAsyncAncestorASR,
|
||||
nsIFrame* aOuterFrame, uint32_t aCallerKey, uint32_t aNestingDepth,
|
||||
bool aKeepLinked) {
|
||||
RetainedDisplayList* aList, AnimatedGeometryRoot* aAGR,
|
||||
PartialUpdateResult& aUpdated, nsIFrame* aOuterFrame, uint32_t aCallerKey,
|
||||
uint32_t aNestingDepth, bool aKeepLinked) {
|
||||
// The DAG merging algorithm does not have strong mechanisms in place to keep
|
||||
// the complexity of the resulting DAG under control. In some cases we can
|
||||
// build up edges very quickly. Detect those cases and force a full display
|
||||
|
@ -281,21 +258,10 @@ bool RetainedDisplayListBuilder::PreProcessDisplayList(
|
|||
keepLinked = true;
|
||||
}
|
||||
|
||||
// If this item's frame is an AGR (can be moved asynchronously by the
|
||||
// compositor), then use that frame for descendants. Also pass the ASR
|
||||
// for that item, so that descendants can compare to see if any new
|
||||
// ASRs have been pushed since.
|
||||
nsIFrame* asyncAncestor = aAsyncAncestor;
|
||||
const ActiveScrolledRoot* asyncAncestorASR = aAsyncAncestorASR;
|
||||
if (item->CanMoveAsync()) {
|
||||
asyncAncestor = item->Frame();
|
||||
asyncAncestorASR = item->GetActiveScrolledRoot();
|
||||
}
|
||||
|
||||
if (!PreProcessDisplayList(
|
||||
item->GetChildren(), SelectAGRForFrame(f, aAGR), aUpdated,
|
||||
asyncAncestor, asyncAncestorASR, item->Frame(),
|
||||
item->GetPerFrameKey(), aNestingDepth + 1, keepLinked)) {
|
||||
if (!PreProcessDisplayList(item->GetChildren(),
|
||||
SelectAGRForFrame(f, aAGR), aUpdated,
|
||||
item->Frame(), item->GetPerFrameKey(),
|
||||
aNestingDepth + 1, keepLinked)) {
|
||||
MOZ_RELEASE_ASSERT(
|
||||
!aKeepLinked,
|
||||
"Can't early return since we need to move the out list back");
|
||||
|
@ -310,20 +276,15 @@ bool RetainedDisplayListBuilder::PreProcessDisplayList(
|
|||
// sibling of the changed thing to get correct ordering. The changed content
|
||||
// is a frame though, and it's hard to map that to container items in this
|
||||
// list.
|
||||
// If an ancestor display item is an AGR, and our ASR matches the ASR
|
||||
// of that item, then there can't have been any new ASRs pushed since that
|
||||
// item, so that item is our AGR. Otherwise, our AGR is our ASR.
|
||||
nsIFrame* agrFrame = nullptr;
|
||||
if (aAsyncAncestorASR == item->GetActiveScrolledRoot()) {
|
||||
agrFrame = aAsyncAncestor;
|
||||
} else {
|
||||
MOZ_ASSERT(item->GetActiveScrolledRoot());
|
||||
agrFrame =
|
||||
item->GetActiveScrolledRoot()->mScrollableFrame->GetScrolledFrame();
|
||||
if (aAGR && item->GetAnimatedGeometryRoot()->GetAsyncAGR() != aAGR) {
|
||||
mBuilder.MarkFrameForDisplayIfVisible(f, mBuilder.RootReferenceFrame());
|
||||
}
|
||||
|
||||
if (aAGR && agrFrame != aAGR) {
|
||||
mBuilder.MarkFrameForDisplayIfVisible(f, mBuilder.RootReferenceFrame());
|
||||
// TODO: This is here because we sometimes reuse the previous display list
|
||||
// completely. For optimization, we could only restore the state for reused
|
||||
// display items.
|
||||
if (item->RestoreState()) {
|
||||
item->InvalidateItemCacheEntry();
|
||||
}
|
||||
|
||||
// If we're going to keep this linked list and not merge it, then mark the
|
||||
|
@ -980,7 +941,7 @@ static bool CanStoreDisplayListBuildingRect(nsDisplayListBuilder* aBuilder,
|
|||
|
||||
static bool ProcessFrameInternal(nsIFrame* aFrame,
|
||||
nsDisplayListBuilder* aBuilder,
|
||||
nsIFrame** aAGR, nsRect& aOverflow,
|
||||
AnimatedGeometryRoot** aAGR, nsRect& aOverflow,
|
||||
const nsIFrame* aStopAtFrame,
|
||||
nsTArray<nsIFrame*>& aOutFramesWithProps,
|
||||
const bool aStopAtStackingContext) {
|
||||
|
@ -1016,7 +977,7 @@ static bool ProcessFrameInternal(nsIFrame* aFrame,
|
|||
|
||||
// Tracking AGRs for the placeholder processing is not necessary, as the
|
||||
// goal is to only modify the DisplayListBuildingData rect.
|
||||
nsIFrame* dummyAGR = nullptr;
|
||||
AnimatedGeometryRoot* dummyAGR = nullptr;
|
||||
|
||||
// Find a common ancestor frame to handle frame continuations.
|
||||
// TODO: It might be possible to write a more specific and efficient
|
||||
|
@ -1124,8 +1085,12 @@ static bool ProcessFrameInternal(nsIFrame* aFrame,
|
|||
// wrapper item and convert into into coordinate relative to the current
|
||||
// frame.
|
||||
nsRect previousVisible = wrapperItem->GetBuildingRectForChildren();
|
||||
if (wrapperItem->ReferenceFrameForChildren() != wrapperItem->Frame()) {
|
||||
if (wrapperItem->ReferenceFrameForChildren() ==
|
||||
wrapperItem->ReferenceFrame()) {
|
||||
previousVisible -= wrapperItem->ToReferenceFrame();
|
||||
} else {
|
||||
MOZ_ASSERT(wrapperItem->ReferenceFrameForChildren() ==
|
||||
wrapperItem->Frame());
|
||||
}
|
||||
|
||||
if (!previousVisible.Contains(aOverflow)) {
|
||||
|
@ -1158,7 +1123,7 @@ static bool ProcessFrameInternal(nsIFrame* aFrame,
|
|||
bool RetainedDisplayListBuilder::ProcessFrame(
|
||||
nsIFrame* aFrame, nsDisplayListBuilder* aBuilder, nsIFrame* aStopAtFrame,
|
||||
nsTArray<nsIFrame*>& aOutFramesWithProps, const bool aStopAtStackingContext,
|
||||
nsRect* aOutDirty, nsIFrame** aOutModifiedAGR) {
|
||||
nsRect* aOutDirty, AnimatedGeometryRoot** aOutModifiedAGR) {
|
||||
if (aFrame->HasOverrideDirtyRegion()) {
|
||||
aOutFramesWithProps.AppendElement(aFrame);
|
||||
}
|
||||
|
@ -1169,7 +1134,8 @@ bool RetainedDisplayListBuilder::ProcessFrame(
|
|||
|
||||
// TODO: There is almost certainly a faster way of doing this, probably can be
|
||||
// combined with the ancestor walk for TransformFrameRectToAncestor.
|
||||
nsIFrame* agrFrame = aBuilder->FindAnimatedGeometryRootFrameFor(aFrame);
|
||||
AnimatedGeometryRoot* agr =
|
||||
aBuilder->FindAnimatedGeometryRootFor(aFrame)->GetAsyncAGR();
|
||||
|
||||
CRR_LOG("Processing frame %p with agr %p\n", aFrame, agr->mFrame);
|
||||
|
||||
|
@ -1191,7 +1157,7 @@ bool RetainedDisplayListBuilder::ProcessFrame(
|
|||
overflow.UnionRect(overflow, aBuilder->GetCaretRect());
|
||||
}
|
||||
|
||||
if (!ProcessFrameInternal(aFrame, aBuilder, &agrFrame, overflow, aStopAtFrame,
|
||||
if (!ProcessFrameInternal(aFrame, aBuilder, &agr, overflow, aStopAtFrame,
|
||||
aOutFramesWithProps, aStopAtStackingContext)) {
|
||||
return false;
|
||||
}
|
||||
|
@ -1205,9 +1171,9 @@ bool RetainedDisplayListBuilder::ProcessFrame(
|
|||
// really complex to track which items would need to be marked in
|
||||
// MarkFramesForDifferentAGR.
|
||||
if (!*aOutModifiedAGR) {
|
||||
CRR_LOG("Setting %p as root stacking context AGR\n", agrFrame);
|
||||
*aOutModifiedAGR = agrFrame;
|
||||
} else if (agrFrame && *aOutModifiedAGR != agrFrame) {
|
||||
CRR_LOG("Setting %p as root stacking context AGR\n", agr);
|
||||
*aOutModifiedAGR = agr;
|
||||
} else if (agr && *aOutModifiedAGR != agr) {
|
||||
CRR_LOG("Found multiple AGRs in root stacking context, giving up\n");
|
||||
return false;
|
||||
}
|
||||
|
@ -1281,7 +1247,8 @@ static void FindContainingBlocks(nsIFrame* aFrame,
|
|||
*/
|
||||
bool RetainedDisplayListBuilder::ComputeRebuildRegion(
|
||||
nsTArray<nsIFrame*>& aModifiedFrames, nsRect* aOutDirty,
|
||||
nsIFrame** aOutModifiedAGR, nsTArray<nsIFrame*>& aOutFramesWithProps) {
|
||||
AnimatedGeometryRoot** aOutModifiedAGR,
|
||||
nsTArray<nsIFrame*>& aOutFramesWithProps) {
|
||||
CRR_LOG("Computing rebuild regions for %zu frames:\n",
|
||||
aModifiedFrames.Length());
|
||||
nsTArray<nsIFrame*> extraFrames;
|
||||
|
@ -1443,13 +1410,12 @@ PartialUpdateResult RetainedDisplayListBuilder::AttemptPartialUpdate(
|
|||
bool shouldBuildPartial = ShouldBuildPartial(modifiedFrames.Frames());
|
||||
|
||||
nsRect modifiedDirty;
|
||||
nsIFrame* modifiedAGR = nullptr;
|
||||
AnimatedGeometryRoot* modifiedAGR = nullptr;
|
||||
PartialUpdateResult result = PartialUpdateResult::NoChange;
|
||||
if (!shouldBuildPartial ||
|
||||
!ComputeRebuildRegion(modifiedFrames.Frames(), &modifiedDirty,
|
||||
&modifiedAGR, framesWithProps.Frames()) ||
|
||||
!PreProcessDisplayList(&mList, modifiedAGR, result,
|
||||
mBuilder.RootReferenceFrame(), nullptr)) {
|
||||
!PreProcessDisplayList(&mList, modifiedAGR, result)) {
|
||||
mBuilder.SetPartialBuildFailed(true);
|
||||
mBuilder.LeavePresShell(mBuilder.RootReferenceFrame(), nullptr);
|
||||
mList.DeleteAll(&mBuilder);
|
||||
|
|
|
@ -215,11 +215,13 @@ struct RetainedDisplayListBuilder {
|
|||
* aKeepLinked=true internally for sub-lists that can't be changed to keep the
|
||||
* original list structure linked for fast re-use.
|
||||
*/
|
||||
bool PreProcessDisplayList(
|
||||
RetainedDisplayList* aList, nsIFrame* aAGR, PartialUpdateResult& aUpdated,
|
||||
nsIFrame* aAsyncAncestor, const ActiveScrolledRoot* aAsyncAncestorASR,
|
||||
nsIFrame* aOuterFrame = nullptr, uint32_t aCallerKey = 0,
|
||||
uint32_t aNestingDepth = 0, bool aKeepLinked = false);
|
||||
bool PreProcessDisplayList(RetainedDisplayList* aList,
|
||||
AnimatedGeometryRoot* aAGR,
|
||||
PartialUpdateResult& aUpdated,
|
||||
nsIFrame* aOuterFrame = nullptr,
|
||||
uint32_t aCallerKey = 0,
|
||||
uint32_t aNestingDepth = 0,
|
||||
bool aKeepLinked = false);
|
||||
|
||||
/**
|
||||
* Merges items from aNewList into non-invalidated items from aOldList and
|
||||
|
@ -239,14 +241,15 @@ struct RetainedDisplayListBuilder {
|
|||
nsDisplayItem* aOuterItem = nullptr);
|
||||
|
||||
bool ComputeRebuildRegion(nsTArray<nsIFrame*>& aModifiedFrames,
|
||||
nsRect* aOutDirty, nsIFrame** aOutModifiedAGR,
|
||||
nsRect* aOutDirty,
|
||||
AnimatedGeometryRoot** aOutModifiedAGR,
|
||||
nsTArray<nsIFrame*>& aOutFramesWithProps);
|
||||
|
||||
bool ProcessFrame(nsIFrame* aFrame, nsDisplayListBuilder* aBuilder,
|
||||
nsIFrame* aStopAtFrame,
|
||||
nsTArray<nsIFrame*>& aOutFramesWithProps,
|
||||
const bool aStopAtStackingContext, nsRect* aOutDirty,
|
||||
nsIFrame** aOutModifiedAGR);
|
||||
AnimatedGeometryRoot** aOutModifiedAGR);
|
||||
|
||||
friend class MergeState;
|
||||
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -152,6 +152,97 @@ enum class DisplayListArenaObjectId {
|
|||
* reference frame for their frame subtrees.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Represents a frame that is considered to have (or will have) "animated
|
||||
* geometry" for itself and descendant frames.
|
||||
*
|
||||
* For example the scrolled frames of scrollframes which are actively being
|
||||
* scrolled fall into this category. Frames with certain CSS properties that are
|
||||
* being animated (e.g. 'left'/'top' etc) are also placed in this category.
|
||||
* Frames with different active geometry roots are in different PaintedLayers,
|
||||
* so that we can animate the geometry root by changing its transform (either on
|
||||
* the main thread or in the compositor).
|
||||
*
|
||||
* nsDisplayListBuilder constructs a tree of these (for fast traversals) and
|
||||
* assigns one for each display item.
|
||||
*
|
||||
* The animated geometry root for a display item is required to be a descendant
|
||||
* (or equal to) the item's ReferenceFrame(), which means that we will fall back
|
||||
* to returning aItem->ReferenceFrame() when we can't find another animated
|
||||
* geometry root.
|
||||
*
|
||||
* The animated geometry root isn't strongly defined for a frame as transforms
|
||||
* and background-attachment:fixed can cause it to vary between display items
|
||||
* for a given frame.
|
||||
*/
|
||||
struct AnimatedGeometryRoot {
|
||||
static already_AddRefed<AnimatedGeometryRoot> CreateAGRForFrame(
|
||||
nsIFrame* aFrame, AnimatedGeometryRoot* aParent, bool aIsAsync,
|
||||
bool aIsRetained) {
|
||||
RefPtr<AnimatedGeometryRoot> result;
|
||||
if (aIsRetained) {
|
||||
result = aFrame->GetProperty(AnimatedGeometryRootCache());
|
||||
}
|
||||
|
||||
if (result) {
|
||||
result->mParentAGR = aParent;
|
||||
result->mIsAsync = aIsAsync;
|
||||
} else {
|
||||
result = new AnimatedGeometryRoot(aFrame, aParent, aIsAsync, aIsRetained);
|
||||
}
|
||||
return result.forget();
|
||||
}
|
||||
|
||||
operator nsIFrame*() { return mFrame; }
|
||||
|
||||
nsIFrame* operator->() const { return mFrame; }
|
||||
|
||||
AnimatedGeometryRoot* GetAsyncAGR() {
|
||||
AnimatedGeometryRoot* agr = this;
|
||||
while (!agr->mIsAsync && agr->mParentAGR) {
|
||||
agr = agr->mParentAGR;
|
||||
}
|
||||
return agr;
|
||||
}
|
||||
|
||||
NS_INLINE_DECL_REFCOUNTING(AnimatedGeometryRoot)
|
||||
|
||||
nsIFrame* mFrame;
|
||||
RefPtr<AnimatedGeometryRoot> mParentAGR;
|
||||
bool mIsAsync;
|
||||
bool mIsRetained;
|
||||
|
||||
protected:
|
||||
static void DetachAGR(AnimatedGeometryRoot* aAGR) {
|
||||
aAGR->mFrame = nullptr;
|
||||
aAGR->mParentAGR = nullptr;
|
||||
NS_RELEASE(aAGR);
|
||||
}
|
||||
|
||||
NS_DECLARE_FRAME_PROPERTY_WITH_DTOR(AnimatedGeometryRootCache,
|
||||
AnimatedGeometryRoot, DetachAGR)
|
||||
|
||||
AnimatedGeometryRoot(nsIFrame* aFrame, AnimatedGeometryRoot* aParent,
|
||||
bool aIsAsync, bool aIsRetained)
|
||||
: mFrame(aFrame),
|
||||
mParentAGR(aParent),
|
||||
mIsAsync(aIsAsync),
|
||||
mIsRetained(aIsRetained) {
|
||||
MOZ_ASSERT(mParentAGR || mIsAsync,
|
||||
"The root AGR should always be treated as an async AGR.");
|
||||
if (mIsRetained) {
|
||||
NS_ADDREF(this);
|
||||
aFrame->SetProperty(AnimatedGeometryRootCache(), this);
|
||||
}
|
||||
}
|
||||
|
||||
~AnimatedGeometryRoot() {
|
||||
if (mFrame && mIsRetained) {
|
||||
mFrame->RemoveProperty(AnimatedGeometryRootCache());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* An active scrolled root (ASR) is similar to an animated geometry root (AGR).
|
||||
* The differences are:
|
||||
|
@ -304,6 +395,13 @@ class nsDisplayListBuilder {
|
|||
bool mAllowAsyncAnimation;
|
||||
};
|
||||
|
||||
/**
|
||||
* A frame can be in one of three states of AGR.
|
||||
* AGR_NO means the frame is not an AGR for now.
|
||||
* AGR_YES means the frame is an AGR for now.
|
||||
*/
|
||||
enum AGRState { AGR_NO, AGR_YES };
|
||||
|
||||
public:
|
||||
using ViewID = layers::ScrollableLayerGuid::ViewID;
|
||||
|
||||
|
@ -557,6 +655,11 @@ class nsDisplayListBuilder {
|
|||
return mCurrentOffsetToReferenceFrame;
|
||||
}
|
||||
|
||||
AnimatedGeometryRoot* GetCurrentAnimatedGeometryRoot() { return mCurrentAGR; }
|
||||
AnimatedGeometryRoot* GetRootAnimatedGeometryRoot() { return mRootAGR; }
|
||||
|
||||
void RecomputeCurrentAnimatedGeometryRoot();
|
||||
|
||||
void Check() { mPool.Check(); }
|
||||
|
||||
/**
|
||||
|
@ -928,13 +1031,6 @@ class nsDisplayListBuilder {
|
|||
const DisplayItemClipChain* aAncestor,
|
||||
const DisplayItemClipChain* aLeafClip1,
|
||||
const DisplayItemClipChain* aLeafClip2);
|
||||
/**
|
||||
* Same as above, except aAncestor is computed as the nearest common
|
||||
* ancestor of the two provided clips.
|
||||
*/
|
||||
const DisplayItemClipChain* CreateClipChainIntersection(
|
||||
const DisplayItemClipChain* aLeafClip1,
|
||||
const DisplayItemClipChain* aLeafClip2);
|
||||
|
||||
/**
|
||||
* Clone the supplied clip chain's chain items into this builder's arena.
|
||||
|
@ -942,6 +1038,14 @@ class nsDisplayListBuilder {
|
|||
const DisplayItemClipChain* CopyWholeChain(
|
||||
const DisplayItemClipChain* aClipChain);
|
||||
|
||||
/**
|
||||
* Returns a new clip chain containing an intersection of all clips of
|
||||
* |aClipChain| up to and including |aASR|.
|
||||
* If there is no clip, returns nullptr.
|
||||
*/
|
||||
const DisplayItemClipChain* FuseClipChainUpTo(
|
||||
const DisplayItemClipChain* aClipChain, const ActiveScrolledRoot* aASR);
|
||||
|
||||
const ActiveScrolledRoot* GetFilterASR() const { return mFilterASR; }
|
||||
|
||||
/**
|
||||
|
@ -982,6 +1086,8 @@ class nsDisplayListBuilder {
|
|||
mBuilder->mCurrentOffsetToReferenceFrame += aOffset;
|
||||
}
|
||||
|
||||
bool IsAnimatedGeometryRoot() const { return mCurrentAGRState == AGR_YES; }
|
||||
|
||||
void RestoreBuildingInvisibleItemsValue() {
|
||||
mBuilder->mBuildingInvisibleItems = mPrevBuildingInvisibleItems;
|
||||
}
|
||||
|
@ -992,6 +1098,7 @@ class nsDisplayListBuilder {
|
|||
mBuilder->mCurrentOffsetToReferenceFrame = mPrevOffset;
|
||||
mBuilder->mVisibleRect = mPrevVisibleRect;
|
||||
mBuilder->mDirtyRect = mPrevDirtyRect;
|
||||
mBuilder->mCurrentAGR = mPrevAGR;
|
||||
mBuilder->mAncestorHasApzAwareEventHandler =
|
||||
mPrevAncestorHasApzAwareEventHandler;
|
||||
mBuilder->mBuildingInvisibleItems = mPrevBuildingInvisibleItems;
|
||||
|
@ -1002,12 +1109,14 @@ class nsDisplayListBuilder {
|
|||
|
||||
private:
|
||||
nsDisplayListBuilder* mBuilder;
|
||||
AGRState mCurrentAGRState;
|
||||
const nsIFrame* mPrevFrame;
|
||||
const nsIFrame* mPrevReferenceFrame;
|
||||
nsPoint mPrevOffset;
|
||||
Maybe<nsPoint> mPrevAdditionalOffset;
|
||||
nsRect mPrevVisibleRect;
|
||||
nsRect mPrevDirtyRect;
|
||||
RefPtr<AnimatedGeometryRoot> mPrevAGR;
|
||||
gfx::CompositorHitTestInfo mPrevCompositorHitTestInfo;
|
||||
bool mPrevAncestorHasApzAwareEventHandler;
|
||||
bool mPrevBuildingInvisibleItems;
|
||||
|
@ -1393,7 +1502,7 @@ class nsDisplayListBuilder {
|
|||
OutOfFlowDisplayData)
|
||||
|
||||
struct DisplayListBuildingData {
|
||||
nsIFrame* mModifiedAGR = nullptr;
|
||||
RefPtr<AnimatedGeometryRoot> mModifiedAGR = nullptr;
|
||||
nsRect mDirtyRect;
|
||||
};
|
||||
NS_DECLARE_FRAME_PROPERTY_DELETABLE(DisplayListBuildingRect,
|
||||
|
@ -1584,6 +1693,13 @@ class nsDisplayListBuilder {
|
|||
return mBuildingExtraPagesForPageNum;
|
||||
}
|
||||
|
||||
/**
|
||||
* This is a convenience function to ease the transition until AGRs and ASRs
|
||||
* are unified.
|
||||
*/
|
||||
AnimatedGeometryRoot* AnimatedGeometryRootForASR(
|
||||
const ActiveScrolledRoot* aASR);
|
||||
|
||||
bool HitTestIsForVisibility() const { return mVisibleThreshold.isSome(); }
|
||||
|
||||
float VisibilityThreshold() const {
|
||||
|
@ -1682,25 +1798,48 @@ class nsDisplayListBuilder {
|
|||
nsDisplayList* mList;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the nearest ancestor frame to aFrame that is considered to have
|
||||
* (or will have) animated geometry. This can return aFrame.
|
||||
*/
|
||||
nsIFrame* FindAnimatedGeometryRootFrameFor(nsIFrame* aFrame);
|
||||
|
||||
private:
|
||||
bool MarkOutOfFlowFrameForDisplay(nsIFrame* aDirtyFrame, nsIFrame* aFrame,
|
||||
const nsRect& aVisibleRect,
|
||||
const nsRect& aDirtyRect);
|
||||
|
||||
friend class nsDisplayBackgroundImage;
|
||||
friend struct RetainedDisplayListBuilder;
|
||||
|
||||
/**
|
||||
* Returns whether a frame acts as an animated geometry root, optionally
|
||||
* returning the next ancestor to check.
|
||||
*/
|
||||
bool IsAnimatedGeometryRoot(nsIFrame* aFrame, nsIFrame** aParent = nullptr);
|
||||
AGRState IsAnimatedGeometryRoot(nsIFrame* aFrame, bool& aIsAsync,
|
||||
nsIFrame** aParent = nullptr);
|
||||
|
||||
/**
|
||||
* Returns the nearest ancestor frame to aFrame that is considered to have
|
||||
* (or will have) animated geometry. This can return aFrame.
|
||||
*/
|
||||
nsIFrame* FindAnimatedGeometryRootFrameFor(nsIFrame* aFrame, bool& aIsAsync);
|
||||
|
||||
friend class nsDisplayCanvasBackgroundImage;
|
||||
friend class nsDisplayBackgroundImage;
|
||||
friend class nsDisplayFixedPosition;
|
||||
friend class nsDisplayPerspective;
|
||||
AnimatedGeometryRoot* FindAnimatedGeometryRootFor(nsDisplayItem* aItem);
|
||||
|
||||
friend class nsDisplayItem;
|
||||
friend class nsDisplayOwnLayer;
|
||||
friend struct RetainedDisplayListBuilder;
|
||||
AnimatedGeometryRoot* FindAnimatedGeometryRootFor(nsIFrame* aFrame);
|
||||
|
||||
AnimatedGeometryRoot* WrapAGRForFrame(
|
||||
nsIFrame* aAnimatedGeometryRoot, bool aIsAsync,
|
||||
AnimatedGeometryRoot* aParent = nullptr);
|
||||
|
||||
nsTHashMap<nsIFrame*, RefPtr<AnimatedGeometryRoot>>
|
||||
mFrameToAnimatedGeometryRootMap;
|
||||
|
||||
/**
|
||||
* Add the current frame to the AGR budget if possible and remember
|
||||
* the outcome. Subsequent calls will return the same value as
|
||||
* returned here.
|
||||
*/
|
||||
bool AddToAGRBudget(nsIFrame* aFrame);
|
||||
|
||||
struct PresShellState {
|
||||
PresShell* mPresShell;
|
||||
|
@ -1764,6 +1903,9 @@ class nsDisplayListBuilder {
|
|||
|
||||
Maybe<nsPoint> mAdditionalOffset;
|
||||
|
||||
RefPtr<AnimatedGeometryRoot> mRootAGR;
|
||||
RefPtr<AnimatedGeometryRoot> mCurrentAGR;
|
||||
|
||||
// will-change budget tracker
|
||||
typedef uint32_t DocumentWillChangeBudget;
|
||||
nsTHashMap<nsPtrHashKey<const nsPresContext>, DocumentWillChangeBudget>
|
||||
|
@ -1776,6 +1918,11 @@ class nsDisplayListBuilder {
|
|||
|
||||
uint8_t mBuildingExtraPagesForPageNum;
|
||||
|
||||
// Area of animated geometry root budget already allocated
|
||||
uint32_t mUsedAGRBudget;
|
||||
// Set of frames already counted in budget
|
||||
nsTHashSet<nsIFrame*> mAGRBudgetSet;
|
||||
|
||||
nsTHashMap<nsPtrHashKey<dom::RemoteBrowser>, dom::EffectsInfo>
|
||||
mEffectsUpdates;
|
||||
|
||||
|
@ -2035,7 +2182,6 @@ class nsDisplayItem : public nsDisplayItemLink {
|
|||
public:
|
||||
using Layer = layers::Layer;
|
||||
using LayerManager = layers::LayerManager;
|
||||
using WebRenderLayerManager = layers::WebRenderLayerManager;
|
||||
using StackingContextHelper = layers::StackingContextHelper;
|
||||
using ViewID = layers::ScrollableLayerGuid::ViewID;
|
||||
|
||||
|
@ -2218,12 +2364,6 @@ class nsDisplayItem : public nsDisplayItemLink {
|
|||
|
||||
virtual bool CreatesStackingContextHelper() { return false; }
|
||||
|
||||
/**
|
||||
* Returns true if this item can be moved asynchronously on the compositor,
|
||||
* see RetainedDisplayListBuilder.cpp comments.
|
||||
*/
|
||||
virtual bool CanMoveAsync() { return false; }
|
||||
|
||||
protected:
|
||||
// This is never instantiated directly (it has pure virtual methods), so no
|
||||
// need to count constructors and destructors.
|
||||
|
@ -2243,14 +2383,20 @@ class nsDisplayItem : public nsDisplayItemLink {
|
|||
mExtraPageForPageNum(aOther.mExtraPageForPageNum),
|
||||
mPerFrameIndex(aOther.mPerFrameIndex),
|
||||
mBuildingRect(aOther.mBuildingRect),
|
||||
mReferenceFrame(aOther.mReferenceFrame),
|
||||
mToReferenceFrame(aOther.mToReferenceFrame),
|
||||
mAnimatedGeometryRoot(aOther.mAnimatedGeometryRoot),
|
||||
mActiveScrolledRoot(aOther.mActiveScrolledRoot),
|
||||
mClipChain(aOther.mClipChain) {
|
||||
mClipChain(aOther.mClipChain),
|
||||
mClip(aOther.mClip) {
|
||||
MOZ_COUNT_CTOR(nsDisplayItem);
|
||||
// TODO: It might be better to remove the flags that aren't copied.
|
||||
if (aOther.ForceNotVisible()) {
|
||||
mItemFlags += ItemFlag::ForceNotVisible;
|
||||
}
|
||||
if (aOther.IsSubpixelAADisabled()) {
|
||||
mItemFlags += ItemFlag::DisableSubpixelAA;
|
||||
}
|
||||
if (mFrame->In3DContextAndBackfaceIsHidden()) {
|
||||
mItemFlags += ItemFlag::BackfaceHidden;
|
||||
}
|
||||
|
@ -2285,6 +2431,24 @@ class nsDisplayItem : public nsDisplayItemLink {
|
|||
nsDisplayItem() = delete;
|
||||
nsDisplayItem(const nsDisplayItem&) = delete;
|
||||
|
||||
/**
|
||||
* Roll back side effects carried out by processing the display list.
|
||||
*
|
||||
* @return true if the rollback actually modified anything, to help the caller
|
||||
* decide whether to invalidate cached information about this node.
|
||||
*/
|
||||
virtual bool RestoreState() {
|
||||
if (mClipChain == mState.mClipChain && mClip == mState.mClip &&
|
||||
!mItemFlags.contains(ItemFlag::DisableSubpixelAA)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
mClipChain = mState.mClipChain;
|
||||
mClip = mState.mClip;
|
||||
mItemFlags -= ItemFlag::DisableSubpixelAA;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Invalidate cached information that depends on this node's contents, after
|
||||
* a mutation of those contents.
|
||||
|
@ -2655,11 +2819,29 @@ class nsDisplayItem : public nsDisplayItemLink {
|
|||
NS_ASSERTION(mFrame, "No frame?");
|
||||
return mToReferenceFrame;
|
||||
}
|
||||
/**
|
||||
* @return the root of the display list's frame (sub)tree, whose origin
|
||||
* establishes the coordinate system for the display list
|
||||
*/
|
||||
const nsIFrame* ReferenceFrame() const { return mReferenceFrame; }
|
||||
|
||||
/**
|
||||
* Returns the reference frame for display item children of this item.
|
||||
*/
|
||||
virtual const nsIFrame* ReferenceFrameForChildren() const { return nullptr; }
|
||||
virtual const nsIFrame* ReferenceFrameForChildren() const {
|
||||
return mReferenceFrame;
|
||||
}
|
||||
|
||||
AnimatedGeometryRoot* GetAnimatedGeometryRoot() const {
|
||||
MOZ_ASSERT(mAnimatedGeometryRoot,
|
||||
"Must have cached AGR before accessing it!");
|
||||
return mAnimatedGeometryRoot;
|
||||
}
|
||||
|
||||
virtual struct AnimatedGeometryRoot* AnimatedGeometryRootForScrollMetadata()
|
||||
const {
|
||||
return GetAnimatedGeometryRoot();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if this display item (or any children) contains content that might
|
||||
|
@ -2671,6 +2853,16 @@ class nsDisplayItem : public nsDisplayItemLink {
|
|||
return nsRect();
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable usage of component alpha. Currently only relevant for items that
|
||||
* have text.
|
||||
*/
|
||||
void DisableComponentAlpha() { mItemFlags += ItemFlag::DisableSubpixelAA; }
|
||||
|
||||
bool IsSubpixelAADisabled() const {
|
||||
return mItemFlags.contains(ItemFlag::DisableSubpixelAA);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if we can add async animations to the layer for this display item.
|
||||
*/
|
||||
|
@ -2680,7 +2872,9 @@ class nsDisplayItem : public nsDisplayItemLink {
|
|||
|
||||
virtual bool SupportsOptimizingToImage() const { return false; }
|
||||
|
||||
virtual const DisplayItemClip& GetClip() const;
|
||||
const DisplayItemClip& GetClip() const {
|
||||
return mClip ? *mClip : DisplayItemClip::NoClip();
|
||||
}
|
||||
void IntersectClip(nsDisplayListBuilder* aBuilder,
|
||||
const DisplayItemClipChain* aOther, bool aStore);
|
||||
|
||||
|
@ -2696,6 +2890,13 @@ class nsDisplayItem : public nsDisplayItemLink {
|
|||
bool aStore);
|
||||
const DisplayItemClipChain* GetClipChain() const { return mClipChain; }
|
||||
|
||||
/**
|
||||
* Intersect all clips in our clip chain up to (and including) aASR and set
|
||||
* set the intersection as this item's clip.
|
||||
*/
|
||||
void FuseClipChainUpTo(nsDisplayListBuilder* aBuilder,
|
||||
const ActiveScrolledRoot* aASR);
|
||||
|
||||
bool BackfaceIsHidden() const {
|
||||
return mItemFlags.contains(ItemFlag::BackfaceHidden);
|
||||
}
|
||||
|
@ -2760,6 +2961,7 @@ class nsDisplayItem : public nsDisplayItemLink {
|
|||
#endif
|
||||
BackfaceHidden,
|
||||
Combines3DTransformWithAncestors,
|
||||
DisableSubpixelAA,
|
||||
ForceNotVisible,
|
||||
HasHitTestInfo,
|
||||
IsGlassItem,
|
||||
|
@ -2793,10 +2995,18 @@ class nsDisplayItem : public nsDisplayItemLink {
|
|||
void SetHasHitTestInfo() { mItemFlags += ItemFlag::HasHitTestInfo; }
|
||||
|
||||
// Result of ToReferenceFrame(mFrame), if mFrame is non-null
|
||||
const nsIFrame* mReferenceFrame;
|
||||
nsPoint mToReferenceFrame;
|
||||
|
||||
RefPtr<AnimatedGeometryRoot> mAnimatedGeometryRoot;
|
||||
RefPtr<const ActiveScrolledRoot> mActiveScrolledRoot;
|
||||
RefPtr<const DisplayItemClipChain> mClipChain;
|
||||
const DisplayItemClip* mClip = nullptr;
|
||||
|
||||
struct {
|
||||
RefPtr<const DisplayItemClipChain> mClipChain;
|
||||
const DisplayItemClip* mClip;
|
||||
} mState;
|
||||
|
||||
#ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
|
||||
public:
|
||||
|
@ -2825,14 +3035,20 @@ class nsPaintedDisplayItem : public nsDisplayItem {
|
|||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores the given opacity value to be applied when drawing. It is an error
|
||||
* to call this if CanApplyOpacity returned false.
|
||||
*/
|
||||
virtual void ApplyOpacity(nsDisplayListBuilder* aBuilder, float aOpacity,
|
||||
const DisplayItemClipChain* aClip) {
|
||||
MOZ_ASSERT(CanApplyOpacity(), "ApplyOpacity is not supported on this type");
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this display item would return true from ApplyOpacity
|
||||
* without actually applying the opacity. Otherwise returns false.
|
||||
*/
|
||||
virtual bool CanApplyOpacity(WebRenderLayerManager* aManager,
|
||||
nsDisplayListBuilder* aBuilder) const {
|
||||
return false;
|
||||
}
|
||||
virtual bool CanApplyOpacity() const { return false; }
|
||||
|
||||
/**
|
||||
* Returns true if this item supports PaintWithClip, where the clipping
|
||||
|
@ -4018,6 +4234,13 @@ class nsDisplayBackgroundImage : public nsPaintedDisplayItem {
|
|||
nsIFrame* aFrameForBounds = nullptr);
|
||||
~nsDisplayBackgroundImage() override;
|
||||
|
||||
bool RestoreState() override {
|
||||
bool superChanged = nsPaintedDisplayItem::RestoreState();
|
||||
bool opacityChanged = (mOpacity != 1.0f);
|
||||
mOpacity = 1.0f;
|
||||
return (superChanged || opacityChanged);
|
||||
}
|
||||
|
||||
NS_DISPLAY_DECL_NAME("Background", TYPE_BACKGROUND)
|
||||
|
||||
/**
|
||||
|
@ -4048,9 +4271,11 @@ class nsDisplayBackgroundImage : public nsPaintedDisplayItem {
|
|||
bool* aSnap) const override;
|
||||
Maybe<nscolor> IsUniform(nsDisplayListBuilder* aBuilder) const override;
|
||||
|
||||
bool CanApplyOpacity(WebRenderLayerManager* aManager,
|
||||
nsDisplayListBuilder* aBuilder) const override {
|
||||
return CanBuildWebRenderDisplayItems(aManager, aBuilder);
|
||||
bool CanApplyOpacity() const override { return true; }
|
||||
|
||||
void ApplyOpacity(nsDisplayListBuilder* aBuilder, float aOpacity,
|
||||
const DisplayItemClipChain* aClip) override {
|
||||
mOpacity = aOpacity;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -4119,7 +4344,7 @@ class nsDisplayBackgroundImage : public nsPaintedDisplayItem {
|
|||
|
||||
protected:
|
||||
bool CanBuildWebRenderDisplayItems(layers::WebRenderLayerManager* aManager,
|
||||
nsDisplayListBuilder* aBuilder) const;
|
||||
nsDisplayListBuilder* aBuilder);
|
||||
nsRect GetBoundsInternal(nsDisplayListBuilder* aBuilder,
|
||||
nsIFrame* aFrameForBounds = nullptr);
|
||||
|
||||
|
@ -4140,6 +4365,8 @@ class nsDisplayBackgroundImage : public nsPaintedDisplayItem {
|
|||
bool mIsRasterImage;
|
||||
/* Whether the image should be treated as fixed to the viewport. */
|
||||
bool mShouldFixToViewport;
|
||||
uint32_t mImageFlags;
|
||||
float mOpacity;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -4304,6 +4531,8 @@ class nsDisplayBackgroundColor : public nsPaintedDisplayItem {
|
|||
mHasStyle(aBackgroundStyle),
|
||||
mDependentFrame(nullptr),
|
||||
mColor(gfx::sRGBColor::FromABGR(aColor)) {
|
||||
mState.mColor = mColor;
|
||||
|
||||
if (mHasStyle) {
|
||||
mBottomLayerClip =
|
||||
aBackgroundStyle->StyleBackground()->BottomLayer().mClip;
|
||||
|
@ -4320,6 +4549,15 @@ class nsDisplayBackgroundColor : public nsPaintedDisplayItem {
|
|||
|
||||
NS_DISPLAY_DECL_NAME("BackgroundColor", TYPE_BACKGROUND_COLOR)
|
||||
|
||||
bool RestoreState() override {
|
||||
if (!nsPaintedDisplayItem::RestoreState() && mColor == mState.mColor) {
|
||||
return false;
|
||||
}
|
||||
|
||||
mColor = mState.mColor;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool HasBackgroundClipText() const {
|
||||
MOZ_ASSERT(mHasStyle);
|
||||
return mBottomLayerClip == StyleGeometryBox::Text;
|
||||
|
@ -4338,8 +4576,10 @@ class nsDisplayBackgroundColor : public nsPaintedDisplayItem {
|
|||
Maybe<nscolor> IsUniform(nsDisplayListBuilder* aBuilder) const override;
|
||||
void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
|
||||
HitTestState* aState, nsTArray<nsIFrame*>* aOutFrames) override;
|
||||
bool CanApplyOpacity(WebRenderLayerManager* aManager,
|
||||
nsDisplayListBuilder* aBuilder) const override;
|
||||
void ApplyOpacity(nsDisplayListBuilder* aBuilder, float aOpacity,
|
||||
const DisplayItemClipChain* aClip) override;
|
||||
|
||||
bool CanApplyOpacity() const override;
|
||||
|
||||
float GetOpacity() const { return mColor.a; }
|
||||
|
||||
|
@ -4409,6 +4649,10 @@ class nsDisplayBackgroundColor : public nsPaintedDisplayItem {
|
|||
StyleGeometryBox mBottomLayerClip;
|
||||
nsIFrame* mDependentFrame;
|
||||
gfx::sRGBColor mColor;
|
||||
|
||||
struct {
|
||||
gfx::sRGBColor mColor;
|
||||
} mState;
|
||||
};
|
||||
|
||||
class nsDisplayTableBackgroundColor : public nsDisplayBackgroundColor {
|
||||
|
@ -4457,7 +4701,7 @@ class nsDisplayTableBackgroundColor : public nsDisplayBackgroundColor {
|
|||
class nsDisplayBoxShadowOuter final : public nsPaintedDisplayItem {
|
||||
public:
|
||||
nsDisplayBoxShadowOuter(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame)
|
||||
: nsPaintedDisplayItem(aBuilder, aFrame) {
|
||||
: nsPaintedDisplayItem(aBuilder, aFrame), mOpacity(1.0f) {
|
||||
MOZ_COUNT_CTOR(nsDisplayBoxShadowOuter);
|
||||
mBounds = GetBoundsInternal();
|
||||
}
|
||||
|
@ -4466,6 +4710,15 @@ class nsDisplayBoxShadowOuter final : public nsPaintedDisplayItem {
|
|||
|
||||
NS_DISPLAY_DECL_NAME("BoxShadowOuter", TYPE_BOX_SHADOW_OUTER)
|
||||
|
||||
bool RestoreState() override {
|
||||
if (!nsPaintedDisplayItem::RestoreState() && mOpacity == 1.0f) {
|
||||
return false;
|
||||
}
|
||||
|
||||
mOpacity = 1.0f;
|
||||
return true;
|
||||
}
|
||||
|
||||
void Paint(nsDisplayListBuilder* aBuilder, gfxContext* aCtx) override;
|
||||
nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) const override;
|
||||
bool IsInvisibleInRect(const nsRect& aRect) const override;
|
||||
|
@ -4473,12 +4726,21 @@ class nsDisplayBoxShadowOuter final : public nsPaintedDisplayItem {
|
|||
const nsDisplayItemGeometry* aGeometry,
|
||||
nsRegion* aInvalidRegion) const override;
|
||||
|
||||
bool CanApplyOpacity(WebRenderLayerManager* aManager,
|
||||
nsDisplayListBuilder* aBuilder) const override {
|
||||
return CanBuildWebRenderDisplayItems();
|
||||
void ApplyOpacity(nsDisplayListBuilder* aBuilder, float aOpacity,
|
||||
const DisplayItemClipChain* aClip) override {
|
||||
NS_ASSERTION(CanApplyOpacity(), "ApplyOpacity should be allowed");
|
||||
mOpacity = aOpacity;
|
||||
IntersectClip(aBuilder, aClip, false);
|
||||
}
|
||||
|
||||
bool CanBuildWebRenderDisplayItems() const;
|
||||
bool CanApplyOpacity() const override { return true; }
|
||||
|
||||
nsDisplayItemGeometry* AllocateGeometry(
|
||||
nsDisplayListBuilder* aBuilder) override {
|
||||
return new nsDisplayBoxShadowOuterGeometry(this, aBuilder, mOpacity);
|
||||
}
|
||||
|
||||
bool CanBuildWebRenderDisplayItems();
|
||||
bool CreateWebRenderCommands(
|
||||
wr::DisplayListBuilder& aBuilder, wr::IpcResourceUpdateQueue& aResources,
|
||||
const StackingContextHelper& aSc,
|
||||
|
@ -4488,6 +4750,7 @@ class nsDisplayBoxShadowOuter final : public nsPaintedDisplayItem {
|
|||
|
||||
private:
|
||||
nsRect mBounds;
|
||||
float mOpacity;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -4680,7 +4943,6 @@ class nsDisplayWrapList : public nsPaintedDisplayItem {
|
|||
MOZ_COUNT_CTOR(nsDisplayWrapList);
|
||||
mBaseBuildingRect = GetBuildingRect();
|
||||
mListPtr = &mList;
|
||||
mOriginalClipChain = mClipChain;
|
||||
}
|
||||
|
||||
nsDisplayWrapList() = delete;
|
||||
|
@ -4698,7 +4960,6 @@ class nsDisplayWrapList : public nsPaintedDisplayItem {
|
|||
mMergedFrames(aOther.mMergedFrames.Clone()),
|
||||
mBounds(aOther.mBounds),
|
||||
mBaseBuildingRect(aOther.mBaseBuildingRect),
|
||||
mOriginalClipChain(aOther.mClipChain),
|
||||
mOverrideZIndex(aOther.mOverrideZIndex),
|
||||
mHasZIndexOverride(aOther.mHasZIndexOverride),
|
||||
mClearingClipChain(aOther.mClearingClipChain) {
|
||||
|
@ -4730,7 +4991,7 @@ class nsDisplayWrapList : public nsPaintedDisplayItem {
|
|||
// Clear the clip chain up to the asr, but don't store it, so that we'll
|
||||
// recover it when we reuse the item.
|
||||
if (mClearingClipChain) {
|
||||
const DisplayItemClipChain* clip = mOriginalClipChain;
|
||||
const DisplayItemClipChain* clip = mState.mClipChain;
|
||||
while (clip && ActiveScrolledRoot::IsAncestor(GetActiveScrolledRoot(),
|
||||
clip->mASR)) {
|
||||
clip = clip->mParent;
|
||||
|
@ -4752,15 +5013,6 @@ class nsDisplayWrapList : public nsPaintedDisplayItem {
|
|||
SetBuildingRect(buildingRect);
|
||||
}
|
||||
|
||||
void SetClipChain(const DisplayItemClipChain* aClipChain,
|
||||
bool aStore) override {
|
||||
nsDisplayItem::SetClipChain(aClipChain, aStore);
|
||||
|
||||
if (aStore) {
|
||||
mOriginalClipChain = mClipChain;
|
||||
}
|
||||
}
|
||||
|
||||
void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
|
||||
HitTestState* aState, nsTArray<nsIFrame*>* aOutFrames) override;
|
||||
nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) const override;
|
||||
|
@ -4820,6 +5072,11 @@ class nsDisplayWrapList : public nsPaintedDisplayItem {
|
|||
nsRect GetComponentAlphaBounds(nsDisplayListBuilder* aBuilder) const override;
|
||||
|
||||
RetainedDisplayList* GetSameCoordinateSystemChildren() const override {
|
||||
NS_ASSERTION(
|
||||
mListPtr->IsEmpty() || !ReferenceFrame() ||
|
||||
!mListPtr->GetBottom()->ReferenceFrame() ||
|
||||
mListPtr->GetBottom()->ReferenceFrame() == ReferenceFrame(),
|
||||
"Children must have same reference frame");
|
||||
return mListPtr;
|
||||
}
|
||||
|
||||
|
@ -4879,7 +5136,6 @@ class nsDisplayWrapList : public nsPaintedDisplayItem {
|
|||
// Displaylist building rect contributed by this display item itself.
|
||||
// Our mBuildingRect may include the visible areas of children.
|
||||
nsRect mBaseBuildingRect;
|
||||
RefPtr<const DisplayItemClipChain> mOriginalClipChain;
|
||||
int32_t mOverrideZIndex;
|
||||
bool mHasZIndexOverride;
|
||||
bool mClearingClipChain = false;
|
||||
|
@ -4966,6 +5222,15 @@ class nsDisplayOpacity : public nsDisplayWrapList {
|
|||
|
||||
NS_DISPLAY_DECL_NAME("Opacity", TYPE_OPACITY)
|
||||
|
||||
bool RestoreState() override {
|
||||
if (!nsDisplayWrapList::RestoreState() && mOpacity == mState.mOpacity) {
|
||||
return false;
|
||||
}
|
||||
|
||||
mOpacity = mState.mOpacity;
|
||||
return true;
|
||||
}
|
||||
|
||||
void InvalidateCachedChildInfo(nsDisplayListBuilder* aBuilder) override {
|
||||
mChildOpacityState = ChildOpacityState::Unknown;
|
||||
}
|
||||
|
@ -4998,15 +5263,10 @@ class nsDisplayOpacity : public nsDisplayWrapList {
|
|||
}
|
||||
return nsDisplayWrapList::IsInvalid(aRect);
|
||||
}
|
||||
bool CanApplyOpacity(WebRenderLayerManager* aManager,
|
||||
nsDisplayListBuilder* aBuilder) const override;
|
||||
bool ShouldFlattenAway(nsDisplayListBuilder* aBuilder) override {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CanApplyOpacityToChildren(WebRenderLayerManager* aManager,
|
||||
nsDisplayListBuilder* aBuilder,
|
||||
float aInheritedOpacity);
|
||||
void ApplyOpacity(nsDisplayListBuilder* aBuilder, float aOpacity,
|
||||
const DisplayItemClipChain* aClip) override;
|
||||
bool CanApplyOpacity() const override;
|
||||
bool ShouldFlattenAway(nsDisplayListBuilder* aBuilder) override;
|
||||
|
||||
bool NeedsGeometryUpdates() const override {
|
||||
// For flattened nsDisplayOpacity items, ComputeInvalidationRegion() only
|
||||
|
@ -5041,9 +5301,8 @@ class nsDisplayOpacity : public nsDisplayWrapList {
|
|||
private:
|
||||
NS_DISPLAY_ALLOW_CLONING()
|
||||
|
||||
bool CanApplyToChildren(WebRenderLayerManager* aManager,
|
||||
nsDisplayListBuilder* aBuilder);
|
||||
bool ApplyToMask();
|
||||
bool ApplyToChildren(nsDisplayListBuilder* aBuilder);
|
||||
bool ApplyToFilterOrMask(const bool aUsingLayers);
|
||||
|
||||
float mOpacity;
|
||||
bool mForEventsOnly : 1;
|
||||
|
@ -5062,6 +5321,10 @@ class nsDisplayOpacity : public nsDisplayWrapList {
|
|||
#else
|
||||
ChildOpacityState mChildOpacityState;
|
||||
#endif
|
||||
|
||||
struct {
|
||||
float mOpacity;
|
||||
} mState{};
|
||||
};
|
||||
|
||||
class nsDisplayBlendMode : public nsDisplayWrapList {
|
||||
|
@ -5438,9 +5701,8 @@ class nsDisplayStickyPosition : public nsDisplayOwnLayer {
|
|||
|
||||
MOZ_COUNTED_DTOR_OVERRIDE(nsDisplayStickyPosition)
|
||||
|
||||
const DisplayItemClip& GetClip() const override {
|
||||
return DisplayItemClip::NoClip();
|
||||
}
|
||||
void SetClipChain(const DisplayItemClipChain* aClipChain,
|
||||
bool aStore) override;
|
||||
bool IsClippedToDisplayPort() const { return mClippedToDisplayPort; }
|
||||
|
||||
NS_DISPLAY_DECL_NAME("StickyPosition", TYPE_STICKY_POSITION)
|
||||
|
@ -5462,8 +5724,6 @@ class nsDisplayStickyPosition : public nsDisplayOwnLayer {
|
|||
|
||||
bool CreatesStackingContextHelper() override { return true; }
|
||||
|
||||
bool CanMoveAsync() override { return true; }
|
||||
|
||||
private:
|
||||
NS_DISPLAY_ALLOW_CLONING()
|
||||
|
||||
|
@ -5501,6 +5761,8 @@ class nsDisplayFixedPosition : public nsDisplayOwnLayer {
|
|||
nsDisplayFixedPosition(nsDisplayListBuilder* aBuilder,
|
||||
const nsDisplayFixedPosition& aOther)
|
||||
: nsDisplayOwnLayer(aBuilder, aOther),
|
||||
mAnimatedGeometryRootForScrollMetadata(
|
||||
aOther.mAnimatedGeometryRootForScrollMetadata),
|
||||
mContainerASR(aOther.mContainerASR),
|
||||
mIsFixedBackground(aOther.mIsFixedBackground) {
|
||||
MOZ_COUNT_CTOR(nsDisplayFixedPosition);
|
||||
|
@ -5524,6 +5786,10 @@ class nsDisplayFixedPosition : public nsDisplayOwnLayer {
|
|||
return mIsFixedBackground;
|
||||
}
|
||||
|
||||
AnimatedGeometryRoot* AnimatedGeometryRootForScrollMetadata() const override {
|
||||
return mAnimatedGeometryRootForScrollMetadata;
|
||||
}
|
||||
|
||||
bool CreateWebRenderCommands(
|
||||
wr::DisplayListBuilder& aBuilder, wr::IpcResourceUpdateQueue& aResources,
|
||||
const StackingContextHelper& aSc,
|
||||
|
@ -5537,8 +5803,10 @@ class nsDisplayFixedPosition : public nsDisplayOwnLayer {
|
|||
// For background-attachment:fixed
|
||||
nsDisplayFixedPosition(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
|
||||
nsDisplayList* aList);
|
||||
void Init(nsDisplayListBuilder* aBuilder);
|
||||
ViewID GetScrollTargetId();
|
||||
|
||||
RefPtr<AnimatedGeometryRoot> mAnimatedGeometryRootForScrollMetadata;
|
||||
RefPtr<const ActiveScrolledRoot> mContainerASR;
|
||||
bool mIsFixedBackground;
|
||||
|
||||
|
@ -5717,7 +5985,8 @@ class nsDisplayEffectsBase : public nsDisplayWrapList {
|
|||
nsDisplayEffectsBase(nsDisplayListBuilder* aBuilder,
|
||||
const nsDisplayEffectsBase& aOther)
|
||||
: nsDisplayWrapList(aBuilder, aOther),
|
||||
mEffectsBounds(aOther.mEffectsBounds) {
|
||||
mEffectsBounds(aOther.mEffectsBounds),
|
||||
mHandleOpacity(aOther.mHandleOpacity) {
|
||||
MOZ_COUNT_CTOR(nsDisplayEffectsBase);
|
||||
}
|
||||
|
||||
|
@ -5728,10 +5997,25 @@ class nsDisplayEffectsBase : public nsDisplayWrapList {
|
|||
void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
|
||||
HitTestState* aState, nsTArray<nsIFrame*>* aOutFrames) override;
|
||||
|
||||
bool RestoreState() override {
|
||||
if (!nsDisplayWrapList::RestoreState() && !mHandleOpacity) {
|
||||
return false;
|
||||
}
|
||||
|
||||
mHandleOpacity = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ShouldFlattenAway(nsDisplayListBuilder* aBuilder) override {
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual void SelectOpacityOptimization(const bool /* aUsingLayers */) {
|
||||
SetHandleOpacity();
|
||||
}
|
||||
|
||||
bool ShouldHandleOpacity() const { return mHandleOpacity; }
|
||||
|
||||
gfxRect BBoxInUserSpace() const;
|
||||
gfxPoint UserSpaceOffset() const;
|
||||
|
||||
|
@ -5740,10 +6024,13 @@ class nsDisplayEffectsBase : public nsDisplayWrapList {
|
|||
nsRegion* aInvalidRegion) const override;
|
||||
|
||||
protected:
|
||||
void SetHandleOpacity() { mHandleOpacity = true; }
|
||||
bool ValidateSVGFrame();
|
||||
|
||||
// relative to mFrame
|
||||
nsRect mEffectsBounds;
|
||||
// True if we need to handle css opacity in this display item.
|
||||
bool mHandleOpacity;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -5809,10 +6096,12 @@ class nsDisplayMasksAndClipPaths : public nsDisplayEffectsBase {
|
|||
* return whether the mask layer was painted successfully.
|
||||
*/
|
||||
bool PaintMask(nsDisplayListBuilder* aBuilder, gfxContext* aMaskContext,
|
||||
bool aHandleOpacity, bool* aMaskPainted = nullptr);
|
||||
bool* aMaskPainted = nullptr);
|
||||
|
||||
const nsTArray<nsRect>& GetDestRects() { return mDestRects; }
|
||||
|
||||
void SelectOpacityOptimization(const bool aUsingLayers) override;
|
||||
|
||||
bool CreateWebRenderCommands(
|
||||
wr::DisplayListBuilder& aBuilder, wr::IpcResourceUpdateQueue& aResources,
|
||||
const StackingContextHelper& aSc,
|
||||
|
@ -5833,6 +6122,7 @@ class nsDisplayMasksAndClipPaths : public nsDisplayEffectsBase {
|
|||
bool CanPaintOnMaskLayer(LayerManager* aManager);
|
||||
|
||||
nsTArray<nsRect> mDestRects;
|
||||
bool mApplyOpacityWithSimpleClipPath;
|
||||
};
|
||||
|
||||
class nsDisplayBackdropRootContainer : public nsDisplayWrapList {
|
||||
|
@ -5963,12 +6253,7 @@ class nsDisplayFilters : public nsDisplayEffectsBase {
|
|||
const StackingContextHelper& aSc,
|
||||
layers::RenderRootStateManager* aManager,
|
||||
nsDisplayListBuilder* aDisplayListBuilder) override;
|
||||
bool CanCreateWebRenderCommands() const;
|
||||
|
||||
bool CanApplyOpacity(WebRenderLayerManager* aManager,
|
||||
nsDisplayListBuilder* aBuilder) const override {
|
||||
return CanCreateWebRenderCommands();
|
||||
}
|
||||
bool CanCreateWebRenderCommands();
|
||||
|
||||
bool CreatesStackingContextHelper() override { return true; }
|
||||
|
||||
|
@ -6022,6 +6307,15 @@ class nsDisplayTransform : public nsPaintedDisplayItem {
|
|||
|
||||
NS_DISPLAY_DECL_NAME("nsDisplayTransform", TYPE_TRANSFORM)
|
||||
|
||||
bool RestoreState() override {
|
||||
if (!nsPaintedDisplayItem::RestoreState() && !mShouldFlatten) {
|
||||
return false;
|
||||
}
|
||||
|
||||
mShouldFlatten = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void UpdateBounds(nsDisplayListBuilder* aBuilder) override;
|
||||
|
||||
/**
|
||||
|
@ -6091,6 +6385,8 @@ class nsDisplayTransform : public nsPaintedDisplayItem {
|
|||
}
|
||||
}
|
||||
|
||||
bool NeedsGeometryUpdates() const override { return mShouldFlatten; }
|
||||
|
||||
const nsIFrame* ReferenceFrameForChildren() const override {
|
||||
// If we were created using a transform-getter, then we don't
|
||||
// belong to a transformed frame, and aren't a reference frame
|
||||
|
@ -6101,6 +6397,10 @@ class nsDisplayTransform : public nsPaintedDisplayItem {
|
|||
return nsPaintedDisplayItem::ReferenceFrameForChildren();
|
||||
}
|
||||
|
||||
AnimatedGeometryRoot* AnimatedGeometryRootForScrollMetadata() const override {
|
||||
return mAnimatedGeometryRootForScrollMetadata;
|
||||
}
|
||||
|
||||
const nsRect& GetBuildingRectForChildren() const override {
|
||||
return mChildrenBuildingRect;
|
||||
}
|
||||
|
@ -6280,11 +6580,6 @@ class nsDisplayTransform : public nsPaintedDisplayItem {
|
|||
|
||||
void WriteDebugInfo(std::stringstream& aStream) override;
|
||||
|
||||
bool CanMoveAsync() override {
|
||||
return EffectCompositor::HasAnimationsForCompositor(
|
||||
mFrame, DisplayItemType::TYPE_TRANSFORM);
|
||||
}
|
||||
|
||||
/**
|
||||
* This item is an additional item as the boundary between parent
|
||||
* and child 3D rendering context.
|
||||
|
@ -6339,6 +6634,8 @@ class nsDisplayTransform : public nsPaintedDisplayItem {
|
|||
mutable Maybe<Matrix4x4Flagged> mInverseTransform;
|
||||
// Accumulated transform of ancestors on the preserves-3d chain.
|
||||
UniquePtr<Matrix4x4> mTransformPreserves3D;
|
||||
RefPtr<AnimatedGeometryRoot> mAnimatedGeometryRootForChildren;
|
||||
RefPtr<AnimatedGeometryRoot> mAnimatedGeometryRootForScrollMetadata;
|
||||
nsRect mChildrenBuildingRect;
|
||||
mutable RetainedDisplayList mChildren;
|
||||
|
||||
|
@ -6355,6 +6652,8 @@ class nsDisplayTransform : public nsPaintedDisplayItem {
|
|||
// parent context unintendedly if the root of the child preserves3d context
|
||||
// doesn't create a transform item.
|
||||
bool mIsTransformSeparator : 1;
|
||||
// True if this nsDisplayTransform should get flattened
|
||||
bool mShouldFlatten : 1;
|
||||
// True if we have a transform getter.
|
||||
bool mHasTransformGetter : 1;
|
||||
};
|
||||
|
@ -6447,6 +6746,15 @@ class nsDisplayText final : public nsPaintedDisplayItem {
|
|||
|
||||
NS_DISPLAY_DECL_NAME("Text", TYPE_TEXT)
|
||||
|
||||
bool RestoreState() final {
|
||||
if (!nsPaintedDisplayItem::RestoreState() && mOpacity == 1.0f) {
|
||||
return false;
|
||||
}
|
||||
|
||||
mOpacity = 1.0f;
|
||||
return true;
|
||||
}
|
||||
|
||||
nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) const final {
|
||||
*aSnap = false;
|
||||
return mBounds;
|
||||
|
@ -6486,10 +6794,16 @@ class nsDisplayText final : public nsPaintedDisplayItem {
|
|||
nsRegion* aInvalidRegion) const final;
|
||||
|
||||
void RenderToContext(gfxContext* aCtx, nsDisplayListBuilder* aBuilder,
|
||||
float aOpacity = 1.0f, bool aIsRecording = false);
|
||||
bool aIsRecording = false);
|
||||
|
||||
bool CanApplyOpacity(WebRenderLayerManager* aManager,
|
||||
nsDisplayListBuilder* aBuilder) const final;
|
||||
bool CanApplyOpacity() const final;
|
||||
|
||||
void ApplyOpacity(nsDisplayListBuilder* aBuilder, float aOpacity,
|
||||
const DisplayItemClipChain* aClip) final {
|
||||
NS_ASSERTION(CanApplyOpacity(), "ApplyOpacity should be allowed");
|
||||
mOpacity = aOpacity;
|
||||
IntersectClip(aBuilder, aClip, false);
|
||||
}
|
||||
|
||||
void WriteDebugInfo(std::stringstream& aStream) final;
|
||||
|
||||
|
@ -6528,9 +6842,11 @@ class nsDisplayText final : public nsPaintedDisplayItem {
|
|||
|
||||
nscoord& VisIStartEdge() { return mVisIStartEdge; }
|
||||
nscoord& VisIEndEdge() { return mVisIEndEdge; }
|
||||
float Opacity() const { return mOpacity; }
|
||||
|
||||
private:
|
||||
nsRect mBounds;
|
||||
float mOpacity;
|
||||
|
||||
// Lengths measured from the visual inline start and end sides
|
||||
// (i.e. left and right respectively in horizontal writing modes,
|
||||
|
|
|
@ -91,6 +91,10 @@ void nsDisplayBoxShadowInnerGeometry::MoveBy(const nsPoint& aOffset) {
|
|||
mPaddingRect.MoveBy(aOffset);
|
||||
}
|
||||
|
||||
nsDisplayBoxShadowOuterGeometry::nsDisplayBoxShadowOuterGeometry(
|
||||
nsDisplayItem* aItem, nsDisplayListBuilder* aBuilder, float aOpacity)
|
||||
: nsDisplayItemGenericGeometry(aItem, aBuilder), mOpacity(aOpacity) {}
|
||||
|
||||
void nsDisplaySolidColorRegionGeometry::MoveBy(const nsPoint& aOffset) {
|
||||
nsDisplayItemGeometry::MoveBy(aOffset);
|
||||
mRegion.MoveBy(aOffset);
|
||||
|
@ -101,7 +105,9 @@ nsDisplaySVGEffectGeometry::nsDisplaySVGEffectGeometry(
|
|||
: nsDisplayItemGeometry(aItem, aBuilder),
|
||||
mBBox(aItem->BBoxInUserSpace()),
|
||||
mUserSpaceOffset(aItem->UserSpaceOffset()),
|
||||
mFrameOffsetToReferenceFrame(aItem->ToReferenceFrame()) {}
|
||||
mFrameOffsetToReferenceFrame(aItem->ToReferenceFrame()),
|
||||
mOpacity(aItem->Frame()->StyleEffects()->mOpacity),
|
||||
mHandleOpacity(aItem->ShouldHandleOpacity()) {}
|
||||
|
||||
void nsDisplaySVGEffectGeometry::MoveBy(const nsPoint& aOffset) {
|
||||
mBounds.MoveBy(aOffset);
|
||||
|
|
|
@ -245,6 +245,15 @@ class nsDisplayBoxShadowInnerGeometry : public nsDisplayItemGeometry {
|
|||
nsRect mPaddingRect;
|
||||
};
|
||||
|
||||
class nsDisplayBoxShadowOuterGeometry : public nsDisplayItemGenericGeometry {
|
||||
public:
|
||||
nsDisplayBoxShadowOuterGeometry(nsDisplayItem* aItem,
|
||||
nsDisplayListBuilder* aBuilder,
|
||||
float aOpacity);
|
||||
|
||||
float mOpacity;
|
||||
};
|
||||
|
||||
class nsDisplaySolidColorGeometry : public nsDisplayItemBoundsGeometry {
|
||||
public:
|
||||
nsDisplaySolidColorGeometry(nsDisplayItem* aItem,
|
||||
|
@ -280,6 +289,7 @@ class nsDisplaySVGEffectGeometry : public nsDisplayItemGeometry {
|
|||
gfxRect mBBox;
|
||||
gfxPoint mUserSpaceOffset;
|
||||
nsPoint mFrameOffsetToReferenceFrame;
|
||||
float mOpacity;
|
||||
bool mHandleOpacity;
|
||||
};
|
||||
|
||||
|
|
|
@ -2714,6 +2714,9 @@ void DisplaySVGText::HitTest(nsDisplayListBuilder* aBuilder,
|
|||
}
|
||||
|
||||
void DisplaySVGText::Paint(nsDisplayListBuilder* aBuilder, gfxContext* aCtx) {
|
||||
DrawTargetAutoDisableSubpixelAntialiasing disable(aCtx->GetDrawTarget(),
|
||||
IsSubpixelAADisabled());
|
||||
|
||||
uint32_t appUnitsPerDevPixel = mFrame->PresContext()->AppUnitsPerDevPixel();
|
||||
|
||||
// ToReferenceFrame includes our mRect offset, but painting takes
|
||||
|
|
|
@ -263,6 +263,9 @@ static void PaintTextShadowCallback(gfxContext* aCtx, nsPoint aShadowOffset,
|
|||
|
||||
void nsDisplayXULTextBox::Paint(nsDisplayListBuilder* aBuilder,
|
||||
gfxContext* aCtx) {
|
||||
DrawTargetAutoDisableSubpixelAntialiasing disable(aCtx->GetDrawTarget(),
|
||||
IsSubpixelAADisabled());
|
||||
|
||||
// Paint the text shadow before doing any foreground stuff
|
||||
nsRect drawRect =
|
||||
static_cast<nsTextBoxFrame*>(mFrame)->mTextDrawRect + ToReferenceFrame();
|
||||
|
|
|
@ -2525,6 +2525,9 @@ class nsDisplayTreeBody final : public nsPaintedDisplayItem {
|
|||
virtual void Paint(nsDisplayListBuilder* aBuilder,
|
||||
gfxContext* aCtx) override {
|
||||
MOZ_ASSERT(aBuilder);
|
||||
DrawTargetAutoDisableSubpixelAntialiasing disable(aCtx->GetDrawTarget(),
|
||||
IsSubpixelAADisabled());
|
||||
|
||||
ImgDrawResult result = static_cast<nsTreeBodyFrame*>(mFrame)->PaintTreeBody(
|
||||
*aCtx, GetPaintRect(aBuilder, aCtx), ToReferenceFrame(), aBuilder);
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче