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:
Matt Woodrow 2017-11-10 13:16:55 +13:00
Родитель 7e5b5d152d
Коммит 1696dda8f9
12 изменённых файлов: 238 добавлений и 62 удалений

Просмотреть файл

@ -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));
}
}