mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Remove lazy scrollinfo hoisting introduced in bug 1193557. (bug 1209278 part 2, r=mstange)
This commit is contained in:
parent
a6a367262a
commit
458b69cf21
@ -608,13 +608,13 @@ nsDisplayListBuilder::nsDisplayListBuilder(nsIFrame* aReferenceFrame,
|
||||
mUsedAGRBudget(0),
|
||||
mDirtyRect(-1,-1,-1,-1),
|
||||
mGlassDisplayItem(nullptr),
|
||||
mPendingScrollInfoItems(nullptr),
|
||||
mCommittedScrollInfoItems(nullptr),
|
||||
mScrollInfoItemsForHoisting(nullptr),
|
||||
mMode(aMode),
|
||||
mCurrentScrollParentId(FrameMetrics::NULL_SCROLL_ID),
|
||||
mCurrentScrollbarTarget(FrameMetrics::NULL_SCROLL_ID),
|
||||
mCurrentScrollbarFlags(0),
|
||||
mPerspectiveItemIndex(0),
|
||||
mSVGEffectsBuildingDepth(0),
|
||||
mIsBuildingScrollbar(false),
|
||||
mCurrentScrollbarWillHaveLayer(false),
|
||||
mBuildCaret(aBuildCaret),
|
||||
@ -1366,27 +1366,35 @@ nsDisplayListBuilder::AddToAGRBudget(nsIFrame* aFrame)
|
||||
return onBudget;
|
||||
}
|
||||
|
||||
nsDisplayList*
|
||||
nsDisplayListBuilder::EnterScrollInfoItemHoisting(nsDisplayList* aScrollInfoItemStorage)
|
||||
void
|
||||
nsDisplayListBuilder::EnterSVGEffectsContents(nsDisplayList* aHoistedItemsStorage)
|
||||
{
|
||||
MOZ_ASSERT(ShouldBuildScrollInfoItemsForHoisting());
|
||||
nsDisplayList* old = mPendingScrollInfoItems;
|
||||
mPendingScrollInfoItems = aScrollInfoItemStorage;
|
||||
return old;
|
||||
MOZ_ASSERT(mSVGEffectsBuildingDepth >= 0);
|
||||
MOZ_ASSERT(aHoistedItemsStorage);
|
||||
if (mSVGEffectsBuildingDepth == 0) {
|
||||
MOZ_ASSERT(!mScrollInfoItemsForHoisting);
|
||||
mScrollInfoItemsForHoisting = aHoistedItemsStorage;
|
||||
}
|
||||
mSVGEffectsBuildingDepth++;
|
||||
}
|
||||
|
||||
void
|
||||
nsDisplayListBuilder::LeaveScrollInfoItemHoisting(nsDisplayList* aScrollInfoItemStorage)
|
||||
nsDisplayListBuilder::ExitSVGEffectsContents()
|
||||
{
|
||||
MOZ_ASSERT(ShouldBuildScrollInfoItemsForHoisting());
|
||||
mPendingScrollInfoItems = aScrollInfoItemStorage;
|
||||
mSVGEffectsBuildingDepth--;
|
||||
MOZ_ASSERT(mSVGEffectsBuildingDepth >= 0);
|
||||
MOZ_ASSERT(mScrollInfoItemsForHoisting);
|
||||
if (mSVGEffectsBuildingDepth == 0) {
|
||||
mScrollInfoItemsForHoisting = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsDisplayListBuilder::AppendNewScrollInfoItemForHoisting(nsDisplayScrollInfoLayer* aScrollInfoItem)
|
||||
{
|
||||
MOZ_ASSERT(ShouldBuildScrollInfoItemsForHoisting());
|
||||
mPendingScrollInfoItems->AppendNewToTop(aScrollInfoItem);
|
||||
MOZ_ASSERT(mScrollInfoItemsForHoisting);
|
||||
mScrollInfoItemsForHoisting->AppendNewToTop(aScrollInfoItem);
|
||||
}
|
||||
|
||||
void
|
||||
@ -4320,8 +4328,6 @@ nsDisplayMixBlendMode::GetLayerState(nsDisplayListBuilder* aBuilder,
|
||||
LayerManager* aManager,
|
||||
const ContainerLayerParameters& aParameters)
|
||||
{
|
||||
CompositionOp op =
|
||||
nsCSSRendering::GetGFXBlendMode(mFrame->StyleDisplay()->mMixBlendMode);
|
||||
return LAYER_ACTIVE;
|
||||
}
|
||||
|
||||
@ -4894,7 +4900,6 @@ nsDisplayScrollInfoLayer::nsDisplayScrollInfoLayer(
|
||||
, mScrollFrame(aScrollFrame)
|
||||
, mScrolledFrame(aScrolledFrame)
|
||||
, mScrollParentId(aBuilder->GetCurrentScrollParentId())
|
||||
, mIgnoreIfCompositorSupportsBlending(false)
|
||||
{
|
||||
#ifdef NS_BUILD_REFCNT_LOGGING
|
||||
MOZ_COUNT_CTOR(nsDisplayScrollInfoLayer);
|
||||
@ -4918,14 +4923,6 @@ nsDisplayScrollInfoLayer::BuildLayer(nsDisplayListBuilder* aBuilder,
|
||||
// cannot be layerized, and so needs to scroll synchronously. To handle those
|
||||
// cases, we still want to generate scrollinfo layers.
|
||||
|
||||
if (mIgnoreIfCompositorSupportsBlending) {
|
||||
// This item was created pessimistically because, during display list
|
||||
// building, we encountered a mix blend mode. If our layer manager
|
||||
// supports compositing this mix blend mode, we don't actually need to
|
||||
// create a scroll info layer.
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ContainerLayerParameters params = aContainerParameters;
|
||||
if (mScrolledFrame->GetContent() &&
|
||||
nsLayoutUtils::HasCriticalDisplayPort(mScrolledFrame->GetContent())) {
|
||||
@ -4969,24 +4966,7 @@ nsDisplayScrollInfoLayer::ComputeFrameMetrics(Layer* aLayer,
|
||||
return UniquePtr<FrameMetrics>(new FrameMetrics(metrics));
|
||||
}
|
||||
|
||||
void
|
||||
nsDisplayScrollInfoLayer::IgnoreIfCompositorSupportsBlending(BlendModeSet aBlendModes)
|
||||
{
|
||||
mContainedBlendModes += aBlendModes;
|
||||
mIgnoreIfCompositorSupportsBlending = true;
|
||||
}
|
||||
|
||||
void
|
||||
nsDisplayScrollInfoLayer::UnsetIgnoreIfCompositorSupportsBlending()
|
||||
{
|
||||
mIgnoreIfCompositorSupportsBlending = false;
|
||||
}
|
||||
|
||||
bool
|
||||
nsDisplayScrollInfoLayer::ContainedInMixBlendMode() const
|
||||
{
|
||||
return mIgnoreIfCompositorSupportsBlending;
|
||||
}
|
||||
|
||||
void
|
||||
nsDisplayScrollInfoLayer::WriteDebugInfo(std::stringstream& aStream)
|
||||
|
@ -1056,26 +1056,11 @@ public:
|
||||
*/
|
||||
bool IsInWillChangeBudget(nsIFrame* aFrame, const nsSize& aSize);
|
||||
|
||||
void SetCommittedScrollInfoItemList(nsDisplayList* aScrollInfoItemStorage) {
|
||||
mCommittedScrollInfoItems = aScrollInfoItemStorage;
|
||||
}
|
||||
nsDisplayList* CommittedScrollInfoItems() const {
|
||||
return mCommittedScrollInfoItems;
|
||||
}
|
||||
bool ShouldBuildScrollInfoItemsForHoisting() const {
|
||||
return IsPaintingToWindow();
|
||||
}
|
||||
void EnterSVGEffectsContents(nsDisplayList* aHoistedItemsStorage);
|
||||
void ExitSVGEffectsContents();
|
||||
|
||||
// When building display lists for stacking contexts, we append scroll info
|
||||
// items to a temporary list. If the stacking context would create an
|
||||
// inactive layer, we commit these items to the final hoisted scroll items
|
||||
// list. Otherwise, we propagate these items to the parent stacking
|
||||
// context's list of pending scroll info items.
|
||||
//
|
||||
// EnterScrollInfoItemHoisting returns the parent stacking context's pending
|
||||
// item list.
|
||||
nsDisplayList* EnterScrollInfoItemHoisting(nsDisplayList* aScrollInfoItemStorage);
|
||||
void LeaveScrollInfoItemHoisting(nsDisplayList* aScrollInfoItemStorage);
|
||||
bool ShouldBuildScrollInfoItemsForHoisting() const
|
||||
{ return mSVGEffectsBuildingDepth > 0; }
|
||||
|
||||
void AppendNewScrollInfoItemForHoisting(nsDisplayScrollInfoLayer* aScrollInfoItem);
|
||||
|
||||
@ -1242,14 +1227,12 @@ private:
|
||||
LayoutDeviceIntRegion mWindowNoDraggingRegion;
|
||||
// The display item for the Windows window glass background, if any
|
||||
nsDisplayItem* mGlassDisplayItem;
|
||||
// When encountering inactive layers, we need to hoist scroll info items
|
||||
// above these layers so APZ can deliver events to content. Such scroll
|
||||
// info items are considered "committed" to the final hoisting list. If
|
||||
// no hoisting is needed immediately, it may be needed later if a blend
|
||||
// mode is introduced in a higher stacking context, so we keep all scroll
|
||||
// info items until the end of display list building.
|
||||
nsDisplayList* mPendingScrollInfoItems;
|
||||
nsDisplayList* mCommittedScrollInfoItems;
|
||||
// A temporary list that we append scroll info items to while building
|
||||
// display items for the contents of frames with SVG effects.
|
||||
// Only non-null when ShouldBuildScrollInfoItemsForHoisting() is true.
|
||||
// This is a pointer and not a real nsDisplayList value because the
|
||||
// nsDisplayList class is defined below this class, so we can't use it here.
|
||||
nsDisplayList* mScrollInfoItemsForHoisting;
|
||||
nsTArray<DisplayItemScrollClip*> mScrollClipsToDestroy;
|
||||
nsTArray<DisplayItemClip*> mDisplayItemClipsToDestroy;
|
||||
Mode mMode;
|
||||
@ -1259,6 +1242,7 @@ private:
|
||||
BlendModeSet mContainedBlendModes;
|
||||
Preserves3DContext mPreserves3DCtx;
|
||||
uint32_t mPerspectiveItemIndex;
|
||||
int32_t mSVGEffectsBuildingDepth;
|
||||
bool mIsBuildingScrollbar;
|
||||
bool mCurrentScrollbarWillHaveLayer;
|
||||
bool mBuildCaret;
|
||||
@ -3717,20 +3701,10 @@ public:
|
||||
mozilla::UniquePtr<FrameMetrics> ComputeFrameMetrics(Layer* aLayer,
|
||||
const ContainerLayerParameters& aContainerParameters);
|
||||
|
||||
void IgnoreIfCompositorSupportsBlending(BlendModeSet aBlendModes);
|
||||
void UnsetIgnoreIfCompositorSupportsBlending();
|
||||
bool ContainedInMixBlendMode() const;
|
||||
|
||||
protected:
|
||||
nsIFrame* mScrollFrame;
|
||||
nsIFrame* mScrolledFrame;
|
||||
ViewID mScrollParentId;
|
||||
|
||||
// If the only reason for the ScrollInfoLayer is a blend mode, the blend
|
||||
// mode may be supported in the compositor. We track it here to determine
|
||||
// if so during layer construction.
|
||||
BlendModeSet mContainedBlendModes;
|
||||
bool mIgnoreIfCompositorSupportsBlending;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -3265,11 +3265,6 @@ nsLayoutUtils::PaintFrame(nsRenderingContext* aRenderingContext, nsIFrame* aFram
|
||||
/* aAllowCreateDisplayPort = */ true);
|
||||
}
|
||||
|
||||
nsDisplayList hoistedScrollItemStorage;
|
||||
if (builder.IsPaintingToWindow()) {
|
||||
builder.SetCommittedScrollInfoItemList(&hoistedScrollItemStorage);
|
||||
}
|
||||
|
||||
nsRegion visibleRegion;
|
||||
if (aFlags & PAINT_WIDGET_LAYERS) {
|
||||
// This layer tree will be reused, so we'll need to calculate it
|
||||
|
@ -1841,87 +1841,6 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
class AutoHoistScrollInfoItems
|
||||
{
|
||||
nsDisplayListBuilder& mBuilder;
|
||||
nsDisplayList* mParentPendingList;
|
||||
nsDisplayList mPendingList;
|
||||
|
||||
public:
|
||||
explicit AutoHoistScrollInfoItems(nsDisplayListBuilder& aBuilder)
|
||||
: mBuilder(aBuilder),
|
||||
mParentPendingList(nullptr)
|
||||
{
|
||||
if (!mBuilder.ShouldBuildScrollInfoItemsForHoisting()) {
|
||||
return;
|
||||
}
|
||||
mParentPendingList = mBuilder.EnterScrollInfoItemHoisting(&mPendingList);
|
||||
}
|
||||
~AutoHoistScrollInfoItems() {
|
||||
if (!mParentPendingList) {
|
||||
// If we have no parent stacking context, we will throw out any scroll
|
||||
// info items that are pending (meaning, we can safely ignore them since
|
||||
// the scrollable layers they represent will not be flattened).
|
||||
return;
|
||||
}
|
||||
mParentPendingList->AppendToTop(&mPendingList);
|
||||
mBuilder.LeaveScrollInfoItemHoisting(mParentPendingList);
|
||||
}
|
||||
|
||||
// The current stacking context will definitely be flattened, so commit all
|
||||
// pending scroll info items and make sure they will not be optimized away
|
||||
// in the case they were also inside a compositor-supported mix-blend-mode.
|
||||
void Commit() {
|
||||
nsDisplayItem* iter = nullptr;
|
||||
while ((iter = mPendingList.RemoveBottom()) != nullptr) {
|
||||
MOZ_ASSERT(iter->GetType() == nsDisplayItem::TYPE_SCROLL_INFO_LAYER);
|
||||
auto item = static_cast<nsDisplayScrollInfoLayer*>(iter);
|
||||
|
||||
item->UnsetIgnoreIfCompositorSupportsBlending();
|
||||
mBuilder.CommittedScrollInfoItems()->AppendToTop(item);
|
||||
}
|
||||
}
|
||||
|
||||
// The current stacking context will only be flattened if the given mix-blend
|
||||
// mode is not supported in the compositor. Annotate the scroll info items
|
||||
// and keep them in the pending list.
|
||||
void AnnotateForBlendModes(BlendModeSet aBlendModes) {
|
||||
for (nsDisplayItem* iter = mPendingList.GetBottom(); iter; iter = iter->GetAbove()) {
|
||||
MOZ_ASSERT(iter->GetType() == nsDisplayItem::TYPE_SCROLL_INFO_LAYER);
|
||||
auto item = static_cast<nsDisplayScrollInfoLayer*>(iter);
|
||||
|
||||
item->IgnoreIfCompositorSupportsBlending(aBlendModes);
|
||||
}
|
||||
}
|
||||
|
||||
bool IsRootStackingContext() {
|
||||
// We're only finished building the hoisted list if we have no parent
|
||||
// stacking context.
|
||||
return !mParentPendingList;
|
||||
}
|
||||
|
||||
// Any scroll info items which contain a mix-blend mode are moved into the
|
||||
// parent display list.
|
||||
void Finish(nsDisplayList* aResultList) {
|
||||
MOZ_ASSERT(IsRootStackingContext());
|
||||
|
||||
nsDisplayItem* iter = nullptr;
|
||||
while ((iter = mPendingList.RemoveBottom()) != nullptr) {
|
||||
MOZ_ASSERT(iter->GetType() == nsDisplayItem::TYPE_SCROLL_INFO_LAYER);
|
||||
nsDisplayScrollInfoLayer *item = static_cast<decltype(item)>(iter);
|
||||
|
||||
if (!item->ContainedInMixBlendMode()) {
|
||||
// Discard the item, it was not committed for having an SVG effect nor
|
||||
// was it contained with a mix-blend mode.
|
||||
item->~nsDisplayScrollInfoLayer();
|
||||
continue;
|
||||
}
|
||||
|
||||
aResultList->AppendToTop(item);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
static void
|
||||
CheckForApzAwareEventHandlers(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame)
|
||||
{
|
||||
@ -2096,13 +2015,13 @@ nsIFrame::BuildDisplayListForStackingContext(nsDisplayListBuilder* aBuilder,
|
||||
inTransform = true;
|
||||
}
|
||||
|
||||
AutoHoistScrollInfoItems hoistedScrollInfoItems(*aBuilder);
|
||||
|
||||
bool usingSVGEffects = nsSVGIntegrationUtils::UsingEffectsForFrame(this);
|
||||
nsRect dirtyRectOutsideSVGEffects = dirtyRect;
|
||||
nsDisplayList hoistedScrollInfoItemsStorage;
|
||||
if (usingSVGEffects) {
|
||||
dirtyRect =
|
||||
nsSVGIntegrationUtils::GetRequiredSourceForInvalidArea(this, dirtyRect);
|
||||
aBuilder->EnterSVGEffectsContents(&hoistedScrollInfoItemsStorage);
|
||||
}
|
||||
|
||||
bool useOpacity = HasVisualOpacity() && !nsSVGUtils::CanOptimizeOpacity(this);
|
||||
@ -2247,6 +2166,10 @@ nsIFrame::BuildDisplayListForStackingContext(nsDisplayListBuilder* aBuilder,
|
||||
/* List now emptied, so add the new list to the top. */
|
||||
resultList.AppendNewToTop(
|
||||
new (aBuilder) nsDisplaySVGEffects(aBuilder, this, &resultList));
|
||||
// Also add the hoisted scroll info items. We need those for APZ scrolling
|
||||
// because nsDisplaySVGEffects items can't build active layers.
|
||||
aBuilder->ExitSVGEffectsContents();
|
||||
resultList.AppendToTop(&hoistedScrollInfoItemsStorage);
|
||||
}
|
||||
else if (useOpacity && !resultList.IsEmpty() && !is3DContextRoot) {
|
||||
/* If this element is the root of a preserve-3d context, then we want
|
||||
@ -2365,25 +2288,8 @@ nsIFrame::BuildDisplayListForStackingContext(nsDisplayListBuilder* aBuilder,
|
||||
*/
|
||||
|
||||
if (aBuilder->ContainsBlendMode()) {
|
||||
resultList.AppendNewToTop(
|
||||
new (aBuilder) nsDisplayBlendContainer(aBuilder, this, &resultList, aBuilder->ContainedBlendModes()));
|
||||
}
|
||||
|
||||
if (aBuilder->ShouldBuildScrollInfoItemsForHoisting()) {
|
||||
if (usingSVGEffects) {
|
||||
// We know this stacking context will be flattened, so hoist any scroll
|
||||
// info items we created.
|
||||
hoistedScrollInfoItems.Commit();
|
||||
} else if (aBuilder->ContainsBlendMode()) {
|
||||
hoistedScrollInfoItems.AnnotateForBlendModes(aBuilder->ContainedBlendModes());
|
||||
}
|
||||
|
||||
if (hoistedScrollInfoItems.IsRootStackingContext()) {
|
||||
// If we're the root stacking context, no more mix-blend modes can be
|
||||
// introduced and it's safe to hoist scroll info items.
|
||||
resultList.AppendToTop(aBuilder->CommittedScrollInfoItems());
|
||||
hoistedScrollInfoItems.Finish(&resultList);
|
||||
}
|
||||
resultList.AppendNewToTop(
|
||||
new (aBuilder) nsDisplayBlendContainer(aBuilder, this, &resultList, aBuilder->ContainedBlendModes()));
|
||||
}
|
||||
|
||||
/* If there's blending, wrap up the list in a blend-mode item. Note
|
||||
|
Loading…
Reference in New Issue
Block a user