зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1413073
- Part 3: Recompute ASR and clip-chains on wrap lists when merging. r=mstange
--HG-- extra : rebase_source : 5c03d88f8d3467dad32fc3589803180fdad4e488
This commit is contained in:
Родитель
7e5b5d152d
Коммит
1696dda8f9
|
@ -582,7 +582,6 @@ nsCanvasFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
|
|||
|
||||
if (layers.mLayers[i].mBlendMode != NS_STYLE_BLEND_NORMAL) {
|
||||
DisplayListClipState::AutoSaveRestore blendClip(aBuilder);
|
||||
blendClip.ClearUpToASR(thisItemASR);
|
||||
thisItemList.AppendNewToTop(
|
||||
new (aBuilder) nsDisplayBlendMode(aBuilder, this, &thisItemList,
|
||||
layers.mLayers[i].mBlendMode,
|
||||
|
@ -594,7 +593,6 @@ nsCanvasFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
|
|||
if (needBlendContainer) {
|
||||
const ActiveScrolledRoot* containerASR = contASRTracker.GetContainerASR();
|
||||
DisplayListClipState::AutoSaveRestore blendContainerClip(aBuilder);
|
||||
blendContainerClip.ClearUpToASR(containerASR);
|
||||
aLists.BorderBackground()->AppendNewToTop(
|
||||
nsDisplayBlendContainer::CreateForBackgroundBlendMode(aBuilder, this,
|
||||
aLists.BorderBackground(),
|
||||
|
|
|
@ -3098,7 +3098,6 @@ nsIFrame::BuildDisplayListForStackingContext(nsDisplayListBuilder* aBuilder,
|
|||
*/
|
||||
if (aBuilder->ContainsBlendMode()) {
|
||||
DisplayListClipState::AutoSaveRestore blendContainerClipState(aBuilder);
|
||||
blendContainerClipState.ClearUpToASR(containerItemASR);
|
||||
resultList.AppendNewToTop(
|
||||
nsDisplayBlendContainer::CreateForMixBlendMode(aBuilder, this, &resultList,
|
||||
containerItemASR));
|
||||
|
@ -3137,7 +3136,6 @@ nsIFrame::BuildDisplayListForStackingContext(nsDisplayListBuilder* aBuilder,
|
|||
|
||||
if (usingMask) {
|
||||
DisplayListClipState::AutoSaveRestore maskClipState(aBuilder);
|
||||
maskClipState.ClearUpToASR(containerItemASR);
|
||||
// The mask should move with aBuilder->CurrentActiveScrolledRoot(), so
|
||||
// that's the ASR we prefer to use for the mask item. However, we can
|
||||
// only do this if the mask if clipped with respect to that ASR, because
|
||||
|
@ -3173,7 +3171,6 @@ nsIFrame::BuildDisplayListForStackingContext(nsDisplayListBuilder* aBuilder,
|
|||
// The clip we would set on an element with opacity would clip
|
||||
// all descendant content, but some should not be clipped.
|
||||
DisplayListClipState::AutoSaveRestore opacityClipState(aBuilder);
|
||||
opacityClipState.ClearUpToASR(containerItemASR);
|
||||
resultList.AppendNewToTop(
|
||||
new (aBuilder) nsDisplayOpacity(aBuilder, this, &resultList,
|
||||
containerItemASR,
|
||||
|
@ -3316,7 +3313,6 @@ nsIFrame::BuildDisplayListForStackingContext(nsDisplayListBuilder* aBuilder,
|
|||
|
||||
if (useBlendMode) {
|
||||
DisplayListClipState::AutoSaveRestore blendModeClipState(aBuilder);
|
||||
blendModeClipState.ClearUpToASR(containerItemASR);
|
||||
resultList.AppendNewToTop(
|
||||
new (aBuilder) nsDisplayBlendMode(aBuilder, this, &resultList,
|
||||
effects->mMixBlendMode,
|
||||
|
@ -3348,7 +3344,9 @@ WrapInWrapList(nsDisplayListBuilder* aBuilder,
|
|||
return item;
|
||||
}
|
||||
|
||||
return new (aBuilder) nsDisplayWrapList(aBuilder, aFrame, aList, aContainerASR);
|
||||
// Clear clip rect for the construction of the items below. Since we're
|
||||
// clipping all their contents, they themselves don't need to be clipped.
|
||||
return new (aBuilder) nsDisplayWrapList(aBuilder, aFrame, aList, aContainerASR, true);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -3734,10 +3732,6 @@ nsIFrame::BuildDisplayListForChild(nsDisplayListBuilder* aBuilder,
|
|||
|
||||
buildingForChild.RestoreBuildingInvisibleItemsValue();
|
||||
|
||||
// Clear clip rect for the construction of the items below. Since we're
|
||||
// clipping all their contents, they themselves don't need to be clipped.
|
||||
clipState.ClearUpToASR(wrapListASR);
|
||||
|
||||
if (isPositioned || isVisuallyAtomic ||
|
||||
(aFlags & DISPLAY_CHILD_FORCE_STACKING_CONTEXT)) {
|
||||
// Genuine stacking contexts, and positioned pseudo-stacking-contexts,
|
||||
|
|
|
@ -10,20 +10,6 @@
|
|||
|
||||
namespace mozilla {
|
||||
|
||||
void
|
||||
DisplayListClipState::ClearUpToASR(const ActiveScrolledRoot* aASR)
|
||||
{
|
||||
while (mClipChainContentDescendants &&
|
||||
ActiveScrolledRoot::IsAncestor(aASR, mClipChainContentDescendants->mASR)) {
|
||||
mClipChainContentDescendants = mClipChainContentDescendants->mParent;
|
||||
}
|
||||
while (mClipChainContainingBlockDescendants &&
|
||||
ActiveScrolledRoot::IsAncestor(aASR, mClipChainContainingBlockDescendants->mASR)) {
|
||||
mClipChainContainingBlockDescendants = mClipChainContainingBlockDescendants->mParent;
|
||||
}
|
||||
InvalidateCurrentCombinedClipChain(aASR);
|
||||
}
|
||||
|
||||
const DisplayItemClipChain*
|
||||
DisplayListClipState::GetCurrentCombinedClipChain(nsDisplayListBuilder* aBuilder)
|
||||
{
|
||||
|
|
|
@ -74,8 +74,6 @@ private:
|
|||
mCurrentCombinedClipChainIsValid = false;
|
||||
}
|
||||
|
||||
void ClearUpToASR(const ActiveScrolledRoot* aASR);
|
||||
|
||||
void SetClipChainForContainingBlockDescendants(const DisplayItemClipChain* aClipChain)
|
||||
{
|
||||
mClipChainContainingBlockDescendants = aClipChain;
|
||||
|
@ -172,15 +170,6 @@ public:
|
|||
#endif
|
||||
}
|
||||
|
||||
void ClearUpToASR(const ActiveScrolledRoot* aASR)
|
||||
{
|
||||
NS_ASSERTION(!mRestored, "Already restored!");
|
||||
mState.ClearUpToASR(aASR);
|
||||
#ifdef DEBUG
|
||||
mClipUsed = false;
|
||||
#endif
|
||||
}
|
||||
|
||||
void SetClipChainForContainingBlockDescendants(const DisplayItemClipChain* aClipChain)
|
||||
{
|
||||
mState.SetClipChainForContainingBlockDescendants(aClipChain);
|
||||
|
|
|
@ -282,6 +282,20 @@ RetainedDisplayListBuilder::IncrementSubDocPresShellPaintCount(nsDisplayItem* aI
|
|||
mBuilder.IncrementPresShellPaintCount(presShell);
|
||||
}
|
||||
|
||||
void UpdateASR(nsDisplayItem* aItem,
|
||||
const ActiveScrolledRoot* aContainerASR)
|
||||
{
|
||||
nsDisplayWrapList* wrapList = aItem->AsDisplayWrapList();
|
||||
if (!wrapList) {
|
||||
aItem->SetActiveScrolledRoot(aContainerASR);
|
||||
return;
|
||||
}
|
||||
|
||||
wrapList->SetActiveScrolledRoot(
|
||||
ActiveScrolledRoot::PickAncestor(wrapList->GetFrameActiveScrolledRoot(),
|
||||
aContainerASR));
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes two display lists and merges them into an output list.
|
||||
*
|
||||
|
@ -332,11 +346,25 @@ RetainedDisplayListBuilder::IncrementSubDocPresShellPaintCount(nsDisplayItem* aI
|
|||
void
|
||||
RetainedDisplayListBuilder::MergeDisplayLists(nsDisplayList* aNewList,
|
||||
nsDisplayList* aOldList,
|
||||
nsDisplayList* aOutList)
|
||||
nsDisplayList* aOutList,
|
||||
const ActiveScrolledRoot** aOutContainerASR)
|
||||
{
|
||||
nsDisplayList merged(&mBuilder);
|
||||
const ActiveScrolledRoot* containerASR = nullptr;
|
||||
|
||||
const auto ReuseItem = [&](nsDisplayItem* aItem) {
|
||||
const ActiveScrolledRoot* itemClipASR =
|
||||
aItem->GetClipChain() ? aItem->GetClipChain()->mASR : nullptr;
|
||||
|
||||
const ActiveScrolledRoot* finiteBoundsASR = ActiveScrolledRoot::PickDescendant(
|
||||
itemClipASR, aItem->GetActiveScrolledRoot());
|
||||
if (merged.IsEmpty()) {
|
||||
containerASR = finiteBoundsASR;
|
||||
} else {
|
||||
containerASR =
|
||||
ActiveScrolledRoot::PickAncestor(containerASR, finiteBoundsASR);
|
||||
}
|
||||
|
||||
merged.AppendToTop(aItem);
|
||||
aItem->SetReused(true);
|
||||
|
||||
|
@ -380,7 +408,10 @@ RetainedDisplayListBuilder::MergeDisplayLists(nsDisplayList* aNewList,
|
|||
|
||||
if (oldItem->GetChildren()) {
|
||||
MOZ_ASSERT(newItem->GetChildren());
|
||||
MergeDisplayLists(newItem->GetChildren(), oldItem->GetChildren(), oldItem->GetChildren());
|
||||
const ActiveScrolledRoot* containerASRForChildren;
|
||||
MergeDisplayLists(newItem->GetChildren(), oldItem->GetChildren(),
|
||||
oldItem->GetChildren(), &containerASRForChildren);
|
||||
UpdateASR(oldItem, containerASRForChildren);
|
||||
oldItem->UpdateBounds(&mBuilder);
|
||||
}
|
||||
if (oldItem->GetType() == DisplayItemType::TYPE_LAYER_EVENT_REGIONS) {
|
||||
|
@ -397,8 +428,10 @@ RetainedDisplayListBuilder::MergeDisplayLists(nsDisplayList* aNewList,
|
|||
// ensure that we find and remove any invalidated items.
|
||||
if (old->GetChildren()) {
|
||||
nsDisplayList empty(&mBuilder);
|
||||
const ActiveScrolledRoot* containerASRForChildren;
|
||||
MergeDisplayLists(&empty, old->GetChildren(),
|
||||
old->GetChildren());
|
||||
old->GetChildren(), &containerASRForChildren);
|
||||
UpdateASR(old, containerASRForChildren);
|
||||
old->UpdateBounds(&mBuilder);
|
||||
}
|
||||
ReuseItem(old);
|
||||
|
@ -425,7 +458,10 @@ RetainedDisplayListBuilder::MergeDisplayLists(nsDisplayList* aNewList,
|
|||
if (!IsAnyAncestorModified(old->FrameForInvalidation()) &&
|
||||
old->GetChildren()) {
|
||||
MOZ_ASSERT(newItem->GetChildren());
|
||||
MergeDisplayLists(newItem->GetChildren(), old->GetChildren(), newItem->GetChildren());
|
||||
const ActiveScrolledRoot* containerASRForChildren;
|
||||
MergeDisplayLists(newItem->GetChildren(), old->GetChildren(),
|
||||
newItem->GetChildren(), &containerASRForChildren);
|
||||
UpdateASR(newItem, containerASRForChildren);
|
||||
newItem->UpdateBounds(&mBuilder);
|
||||
}
|
||||
|
||||
|
@ -443,27 +479,32 @@ RetainedDisplayListBuilder::MergeDisplayLists(nsDisplayList* aNewList,
|
|||
// Reuse the remaining valid items from the old display list.
|
||||
while (nsDisplayItem* old = aOldList->RemoveBottom()) {
|
||||
if (!IsAnyAncestorModified(old->FrameForInvalidation())) {
|
||||
ReuseItem(old);
|
||||
|
||||
if (old->GetChildren()) {
|
||||
// We are calling MergeDisplayLists() to ensure that the display items
|
||||
// with modified or deleted children will be correctly handled.
|
||||
// Passing an empty new display list as an argument skips the merging
|
||||
// loop above and jumps back here.
|
||||
nsDisplayList empty(&mBuilder);
|
||||
const ActiveScrolledRoot* containerASRForChildren;
|
||||
|
||||
MergeDisplayLists(&empty, old->GetChildren(), old->GetChildren());
|
||||
MergeDisplayLists(&empty, old->GetChildren(),
|
||||
old->GetChildren(), &containerASRForChildren);
|
||||
UpdateASR(old, containerASRForChildren);
|
||||
old->UpdateBounds(&mBuilder);
|
||||
}
|
||||
if (old->GetType() == DisplayItemType::TYPE_LAYER_EVENT_REGIONS) {
|
||||
MergeLayerEventRegions(old, nullptr);
|
||||
}
|
||||
ReuseItem(old);
|
||||
} else {
|
||||
old->Destroy(&mBuilder);
|
||||
}
|
||||
}
|
||||
|
||||
aOutList->AppendToTop(&merged);
|
||||
if (aOutContainerASR) {
|
||||
*aOutContainerASR = containerASR;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -787,7 +828,7 @@ RetainedDisplayListBuilder::AttemptPartialUpdate(nscolor aBackstop)
|
|||
// are not visible anymore) from the old list.
|
||||
// TODO: Optimization opportunity. In this case, MergeDisplayLists()
|
||||
// unnecessarily creates a hashtable of the old items.
|
||||
MergeDisplayLists(&modifiedDL, &mList, &mList);
|
||||
MergeDisplayLists(&modifiedDL, &mList, &mList, nullptr);
|
||||
|
||||
//printf_stderr("Painting --- Merged list:\n");
|
||||
//nsFrame::PrintDisplayList(&mBuilder, mList);
|
||||
|
|
|
@ -34,7 +34,8 @@ private:
|
|||
|
||||
void MergeDisplayLists(nsDisplayList* aNewList,
|
||||
nsDisplayList* aOldList,
|
||||
nsDisplayList* aOutList);
|
||||
nsDisplayList* aOutList,
|
||||
const mozilla::ActiveScrolledRoot** aOutContainerASR = nullptr);
|
||||
|
||||
bool ComputeRebuildRegion(nsTArray<nsIFrame*>& aModifiedFrames,
|
||||
nsRect* aOutDirty,
|
||||
|
|
|
@ -3679,7 +3679,6 @@ nsDisplayBackgroundImage::AppendBackgroundItemsToTop(nsDisplayListBuilder* aBuil
|
|||
|
||||
if (bg->mImage.mLayers[i].mBlendMode != NS_STYLE_BLEND_NORMAL) {
|
||||
DisplayListClipState::AutoSaveRestore blendClip(aBuilder);
|
||||
blendClip.ClearUpToASR(asr);
|
||||
// asr is scrolled. Even if we wrap a fixed background layer, that's
|
||||
// fine, because the item will have a scrolled clip that limits the
|
||||
// item with respect to asr.
|
||||
|
@ -3693,7 +3692,6 @@ nsDisplayBackgroundImage::AppendBackgroundItemsToTop(nsDisplayListBuilder* aBuil
|
|||
|
||||
if (needBlendContainer) {
|
||||
DisplayListClipState::AutoSaveRestore blendContainerClip(aBuilder);
|
||||
blendContainerClip.ClearUpToASR(asr);
|
||||
bgItemList.AppendNewToTop(
|
||||
nsDisplayBlendContainer::CreateForBackgroundBlendMode(aBuilder, aFrame, &bgItemList, asr));
|
||||
}
|
||||
|
@ -5929,11 +5927,14 @@ nsDisplayWrapList::nsDisplayWrapList(nsDisplayListBuilder* aBuilder,
|
|||
|
||||
nsDisplayWrapList::nsDisplayWrapList(nsDisplayListBuilder* aBuilder,
|
||||
nsIFrame* aFrame, nsDisplayList* aList,
|
||||
const ActiveScrolledRoot* aActiveScrolledRoot)
|
||||
const ActiveScrolledRoot* aActiveScrolledRoot,
|
||||
bool aClearClipChain)
|
||||
: nsDisplayItem(aBuilder, aFrame, aActiveScrolledRoot)
|
||||
, mList(aBuilder)
|
||||
, mFrameActiveScrolledRoot(aBuilder->CurrentActiveScrolledRoot())
|
||||
, mOverrideZIndex(0)
|
||||
, mHasZIndexOverride(false)
|
||||
, mClearingClipChain(aClearClipChain)
|
||||
{
|
||||
MOZ_COUNT_CTOR(nsDisplayWrapList);
|
||||
|
||||
|
@ -6251,7 +6252,7 @@ nsDisplayOpacity::nsDisplayOpacity(nsDisplayListBuilder* aBuilder,
|
|||
nsIFrame* aFrame, nsDisplayList* aList,
|
||||
const ActiveScrolledRoot* aActiveScrolledRoot,
|
||||
bool aForEventsAndPluginsOnly)
|
||||
: nsDisplayWrapList(aBuilder, aFrame, aList, aActiveScrolledRoot)
|
||||
: nsDisplayWrapList(aBuilder, aFrame, aList, aActiveScrolledRoot, true)
|
||||
, mOpacity(aFrame->StyleEffects()->mOpacity)
|
||||
, mForEventsAndPluginsOnly(aForEventsAndPluginsOnly)
|
||||
{
|
||||
|
@ -6554,7 +6555,7 @@ nsDisplayBlendMode::nsDisplayBlendMode(nsDisplayListBuilder* aBuilder,
|
|||
uint8_t aBlendMode,
|
||||
const ActiveScrolledRoot* aActiveScrolledRoot,
|
||||
uint32_t aIndex)
|
||||
: nsDisplayWrapList(aBuilder, aFrame, aList, aActiveScrolledRoot)
|
||||
: nsDisplayWrapList(aBuilder, aFrame, aList, aActiveScrolledRoot, true)
|
||||
, mBlendMode(aBlendMode)
|
||||
, mIndex(aIndex)
|
||||
{
|
||||
|
@ -6672,7 +6673,7 @@ nsDisplayBlendContainer::nsDisplayBlendContainer(nsDisplayListBuilder* aBuilder,
|
|||
nsIFrame* aFrame, nsDisplayList* aList,
|
||||
const ActiveScrolledRoot* aActiveScrolledRoot,
|
||||
bool aIsForBackground)
|
||||
: nsDisplayWrapList(aBuilder, aFrame, aList, aActiveScrolledRoot)
|
||||
: nsDisplayWrapList(aBuilder, aFrame, aList, aActiveScrolledRoot, true)
|
||||
, mIsForBackground(aIsForBackground)
|
||||
{
|
||||
MOZ_COUNT_CTOR(nsDisplayBlendContainer);
|
||||
|
@ -6731,8 +6732,9 @@ nsDisplayOwnLayer::nsDisplayOwnLayer(nsDisplayListBuilder* aBuilder,
|
|||
const ActiveScrolledRoot* aActiveScrolledRoot,
|
||||
uint32_t aFlags, ViewID aScrollTarget,
|
||||
const ScrollThumbData& aThumbData,
|
||||
bool aForceActive)
|
||||
: nsDisplayWrapList(aBuilder, aFrame, aList, aActiveScrolledRoot)
|
||||
bool aForceActive,
|
||||
bool aClearClipChain)
|
||||
: nsDisplayWrapList(aBuilder, aFrame, aList, aActiveScrolledRoot, aClearClipChain)
|
||||
, mFlags(aFlags)
|
||||
, mScrollTarget(aScrollTarget)
|
||||
, mThumbData(aThumbData)
|
||||
|
@ -9026,8 +9028,9 @@ nsCharClipDisplayItem::ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
|
|||
nsDisplaySVGEffects::nsDisplaySVGEffects(nsDisplayListBuilder* aBuilder,
|
||||
nsIFrame* aFrame, nsDisplayList* aList,
|
||||
bool aHandleOpacity,
|
||||
const ActiveScrolledRoot* aActiveScrolledRoot)
|
||||
: nsDisplayWrapList(aBuilder, aFrame, aList, aActiveScrolledRoot)
|
||||
const ActiveScrolledRoot* aActiveScrolledRoot,
|
||||
bool aClearClipChain)
|
||||
: nsDisplayWrapList(aBuilder, aFrame, aList, aActiveScrolledRoot, aClearClipChain)
|
||||
, mHandleOpacity(aHandleOpacity)
|
||||
{
|
||||
MOZ_COUNT_CTOR(nsDisplaySVGEffects);
|
||||
|
@ -9210,7 +9213,7 @@ nsDisplayMask::nsDisplayMask(nsDisplayListBuilder* aBuilder,
|
|||
nsIFrame* aFrame, nsDisplayList* aList,
|
||||
bool aHandleOpacity,
|
||||
const ActiveScrolledRoot* aActiveScrolledRoot)
|
||||
: nsDisplaySVGEffects(aBuilder, aFrame, aList, aHandleOpacity, aActiveScrolledRoot)
|
||||
: nsDisplaySVGEffects(aBuilder, aFrame, aList, aHandleOpacity, aActiveScrolledRoot, true)
|
||||
{
|
||||
MOZ_COUNT_CTOR(nsDisplayMask);
|
||||
|
||||
|
|
|
@ -1941,6 +1941,7 @@ public:
|
|||
* Downcasts this item to nsDisplayWrapList, if possible.
|
||||
*/
|
||||
virtual const nsDisplayWrapList* AsDisplayWrapList() const { return nullptr; }
|
||||
virtual nsDisplayWrapList* AsDisplayWrapList() { return nullptr; }
|
||||
|
||||
/**
|
||||
* Create a clone of this item.
|
||||
|
@ -2583,7 +2584,7 @@ public:
|
|||
}
|
||||
void IntersectClip(nsDisplayListBuilder* aBuilder, const DisplayItemClipChain* aOther, bool aStore);
|
||||
|
||||
void SetActiveScrolledRoot(const ActiveScrolledRoot* aActiveScrolledRoot) { mActiveScrolledRoot = aActiveScrolledRoot; }
|
||||
virtual void SetActiveScrolledRoot(const ActiveScrolledRoot* aActiveScrolledRoot) { mActiveScrolledRoot = aActiveScrolledRoot; }
|
||||
const ActiveScrolledRoot* GetActiveScrolledRoot() const { return mActiveScrolledRoot; }
|
||||
|
||||
virtual void SetClipChain(const DisplayItemClipChain* aClipChain,
|
||||
|
@ -4571,12 +4572,14 @@ public:
|
|||
nsDisplayList* aList);
|
||||
nsDisplayWrapList(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
|
||||
nsDisplayList* aList,
|
||||
const ActiveScrolledRoot* aActiveScrolledRoot);
|
||||
const ActiveScrolledRoot* aActiveScrolledRoot,
|
||||
bool aClearClipChain = false);
|
||||
nsDisplayWrapList(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
|
||||
nsDisplayItem* aItem);
|
||||
nsDisplayWrapList(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame)
|
||||
: nsDisplayItem(aBuilder, aFrame)
|
||||
, mList(aBuilder)
|
||||
, mFrameActiveScrolledRoot(aBuilder->CurrentActiveScrolledRoot())
|
||||
, mOverrideZIndex(0)
|
||||
, mHasZIndexOverride(false)
|
||||
{
|
||||
|
@ -4594,11 +4597,13 @@ public:
|
|||
: nsDisplayItem(aBuilder, aOther)
|
||||
, mList(aOther.mList.mBuilder)
|
||||
, mListPtr(&mList)
|
||||
, mFrameActiveScrolledRoot(aOther.mFrameActiveScrolledRoot)
|
||||
, mMergedFrames(aOther.mMergedFrames)
|
||||
, mBounds(aOther.mBounds)
|
||||
, mBaseVisibleRect(aOther.mBaseVisibleRect)
|
||||
, mOverrideZIndex(aOther.mOverrideZIndex)
|
||||
, mHasZIndexOverride(aOther.mHasZIndexOverride)
|
||||
, mClearingClipChain(aOther.mClearingClipChain)
|
||||
{
|
||||
MOZ_COUNT_CTOR(nsDisplayWrapList);
|
||||
}
|
||||
|
@ -4609,6 +4614,10 @@ public:
|
|||
{
|
||||
return this;
|
||||
}
|
||||
virtual nsDisplayWrapList* AsDisplayWrapList() override
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
virtual void Destroy(nsDisplayListBuilder* aBuilder) override {
|
||||
mList.DeleteAll(aBuilder);
|
||||
|
@ -4628,6 +4637,16 @@ public:
|
|||
*/
|
||||
virtual void UpdateBounds(nsDisplayListBuilder* aBuilder) override
|
||||
{
|
||||
// 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 = mState.mClipChain;
|
||||
while (clip && ActiveScrolledRoot::IsAncestor(GetActiveScrolledRoot(), clip->mASR)) {
|
||||
clip = clip->mParent;
|
||||
}
|
||||
SetClipChain(clip, false);
|
||||
}
|
||||
|
||||
nsRect visibleRect;
|
||||
mBounds =
|
||||
mListPtr->GetClippedBoundsWithRespectToASR(aBuilder, mActiveScrolledRoot, &visibleRect);
|
||||
|
@ -4735,6 +4754,8 @@ public:
|
|||
mozilla::layers::WebRenderLayerManager* aManager,
|
||||
nsDisplayListBuilder* aDisplayListBuilder) override;
|
||||
|
||||
const ActiveScrolledRoot* GetFrameActiveScrolledRoot() { return mFrameActiveScrolledRoot; }
|
||||
|
||||
protected:
|
||||
nsDisplayWrapList() = delete;
|
||||
|
||||
|
@ -4748,6 +4769,9 @@ protected:
|
|||
|
||||
nsDisplayList mList;
|
||||
nsDisplayList* mListPtr;
|
||||
// The active scrolled root for the frame that created this
|
||||
// wrap list.
|
||||
RefPtr<const ActiveScrolledRoot> mFrameActiveScrolledRoot;
|
||||
// The frames from items that have been merged into this item, excluding
|
||||
// this item's own frame.
|
||||
nsTArray<nsIFrame*> mMergedFrames;
|
||||
|
@ -4757,6 +4781,7 @@ protected:
|
|||
nsRect mBaseVisibleRect;
|
||||
int32_t mOverrideZIndex;
|
||||
bool mHasZIndexOverride;
|
||||
bool mClearingClipChain = false;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -5040,7 +5065,8 @@ public:
|
|||
uint32_t aFlags = 0,
|
||||
ViewID aScrollTarget = mozilla::layers::FrameMetrics::NULL_SCROLL_ID,
|
||||
const ScrollThumbData& aThumbData = ScrollThumbData{},
|
||||
bool aForceActive = true);
|
||||
bool aForceActive = true,
|
||||
bool aClearClipChain = false);
|
||||
#ifdef NS_BUILD_REFCNT_LOGGING
|
||||
virtual ~nsDisplayOwnLayer();
|
||||
#endif
|
||||
|
@ -5433,7 +5459,8 @@ class nsDisplaySVGEffects: public nsDisplayWrapList {
|
|||
public:
|
||||
nsDisplaySVGEffects(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
|
||||
nsDisplayList* aList, bool aHandleOpacity,
|
||||
const ActiveScrolledRoot* aActiveScrolledRoot);
|
||||
const ActiveScrolledRoot* aActiveScrolledRoot,
|
||||
bool aClearClipChain = false);
|
||||
nsDisplaySVGEffects(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
|
||||
nsDisplayList* aList, bool aHandleOpacity);
|
||||
#ifdef NS_BUILD_REFCNT_LOGGING
|
||||
|
@ -5760,6 +5787,12 @@ public:
|
|||
return mStoredList.GetChildren();
|
||||
}
|
||||
|
||||
virtual void SetActiveScrolledRoot(const ActiveScrolledRoot* aActiveScrolledRoot) override
|
||||
{
|
||||
nsDisplayItem::SetActiveScrolledRoot(aActiveScrolledRoot);
|
||||
mStoredList.SetActiveScrolledRoot(aActiveScrolledRoot);
|
||||
}
|
||||
|
||||
virtual void HitTest(nsDisplayListBuilder *aBuilder, const nsRect& aRect,
|
||||
HitTestState *aState, nsTArray<nsIFrame*> *aOutFrames) override;
|
||||
virtual nsRect GetBounds(nsDisplayListBuilder *aBuilder,
|
||||
|
@ -6148,6 +6181,12 @@ public:
|
|||
return mList.GetChildren();
|
||||
}
|
||||
|
||||
virtual void SetActiveScrolledRoot(const ActiveScrolledRoot* aActiveScrolledRoot) override
|
||||
{
|
||||
nsDisplayItem::SetActiveScrolledRoot(aActiveScrolledRoot);
|
||||
mList.SetActiveScrolledRoot(aActiveScrolledRoot);
|
||||
}
|
||||
|
||||
virtual nsRect GetComponentAlphaBounds(nsDisplayListBuilder* aBuilder) const override
|
||||
{
|
||||
return mList.GetComponentAlphaBounds(aBuilder);
|
||||
|
|
|
@ -0,0 +1,54 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
|
||||
<meta charset="utf-8">
|
||||
<title>The ASR for the opacity item is the root scroll frame instead of the subframe.</title>
|
||||
|
||||
<style>
|
||||
|
||||
.outer {
|
||||
/* avoid event regions messing with our demonstration */
|
||||
pointer-events: none;
|
||||
/* make sure the .outer opacity item has the root scroll frame as its ASR */
|
||||
background: rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.opacity {
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
.scrollFrameWrapper {
|
||||
/* clips off .scrollFrame's scrollbar */
|
||||
margin: 100px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.scrollFrame {
|
||||
height: 300px;
|
||||
margin-right: -20px;
|
||||
padding-right: 20px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.scrolledContents {
|
||||
height: 1000px;
|
||||
width: 200px;
|
||||
border: 5px solid black;
|
||||
pointer-events: auto;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
</head><body>
|
||||
|
||||
<div class="opacity outer">
|
||||
<div class="opacity inner">
|
||||
<div class="scrollFrameWrapper">
|
||||
<div class="scrollFrame">
|
||||
<div class="scrolledContents"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body></html>
|
|
@ -0,0 +1,69 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en" class="reftest-wait">
|
||||
<head>
|
||||
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
|
||||
<meta charset="utf-8">
|
||||
<title>The ASR for the opacity item is the root scroll frame instead of the subframe.</title>
|
||||
|
||||
<style>
|
||||
|
||||
.outer {
|
||||
/* avoid event regions messing with our demonstration */
|
||||
pointer-events: none;
|
||||
/* make sure the .outer opacity item has the root scroll frame as its ASR */
|
||||
background: rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.opacity {
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
.scrollFrameWrapper {
|
||||
/* clips off .scrollFrame's scrollbar */
|
||||
margin: 100px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.scrollFrame {
|
||||
height: 300px;
|
||||
margin-right: -20px;
|
||||
padding-right: 20px;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.scrolledContents {
|
||||
height: 1000px;
|
||||
width: 200px;
|
||||
border: 5px solid black;
|
||||
pointer-events: auto;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
</head><body>
|
||||
|
||||
<div class="opacity outer">
|
||||
<div class="opacity inner">
|
||||
<div class="scrollFrameWrapper">
|
||||
<div class="scrollFrame">
|
||||
<div class="scrolledContents"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
|
||||
function doTest()
|
||||
{
|
||||
var scrollFrame = document.querySelector('.scrollFrame');
|
||||
scrollFrame.scrollTop = 10;
|
||||
scrollFrame.scrollTop = 20;
|
||||
scrollFrame.scrollTop = 0;
|
||||
|
||||
document.documentElement.removeAttribute("class");
|
||||
}
|
||||
|
||||
document.addEventListener("MozReftestInvalidate", doTest);
|
||||
</script>
|
||||
</body></html>
|
|
@ -8,3 +8,4 @@ skip-if(!retainedDisplayList) == retained-dl-scroll-out-of-view-1.html retained-
|
|||
skip-if(!retainedDisplayList) == retained-dl-displayport-1.html retained-dl-displayport-1-ref.html
|
||||
skip-if(!retainedDisplayList) == retained-dl-prerender-transform-1.html retained-dl-prerender-transform-1-ref.html
|
||||
== retained-dl-wrap-list.html retained-dl-wrap-list-ref.html
|
||||
fuzzy(1,235200) == 1413073.html 1413073-ref.html
|
||||
|
|
|
@ -1367,11 +1367,12 @@ nsBoxFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
|
|||
const ActiveScrolledRoot* ownLayerASR = contASRTracker->GetContainerASR();
|
||||
|
||||
DisplayListClipState::AutoSaveRestore ownLayerClipState(aBuilder);
|
||||
ownLayerClipState.ClearUpToASR(ownLayerASR);
|
||||
|
||||
// Wrap the list to make it its own layer
|
||||
aLists.Content()->AppendNewToTop(new (aBuilder)
|
||||
nsDisplayOwnLayer(aBuilder, this, &masterList, ownLayerASR));
|
||||
nsDisplayOwnLayer(aBuilder, this, &masterList, ownLayerASR, 0,
|
||||
mozilla::layers::FrameMetrics::NULL_SCROLL_ID,
|
||||
mozilla::layers::ScrollThumbData{}, true, true));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче