зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1367488 - Pre-render offscreen portions of scrollbar thumbs inside an iframe. r=mstange
MozReview-Commit-ID: LCBHnFJdGtp --HG-- extra : rebase_source : 1ab1d812674d321d76e634953284b3983774d798
This commit is contained in:
Родитель
4564af3454
Коммит
539791ed1e
|
@ -3935,6 +3935,13 @@ ContainerState::SetupMaskLayerForCSSMask(Layer* aLayer,
|
||||||
aLayer->SetMaskLayer(maskLayer);
|
aLayer->SetMaskLayer(maskLayer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
IsScrollThumbLayer(nsDisplayItem* aItem)
|
||||||
|
{
|
||||||
|
return aItem->GetType() == nsDisplayItem::TYPE_OWN_LAYER &&
|
||||||
|
static_cast<nsDisplayOwnLayer*>(aItem)->IsScrollThumbLayer();
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Iterate through the non-clip items in aList and its descendants.
|
* Iterate through the non-clip items in aList and its descendants.
|
||||||
* For each item we compute the effective clip rect. Each item is assigned
|
* For each item we compute the effective clip rect. Each item is assigned
|
||||||
|
@ -4204,8 +4211,9 @@ ContainerState::ProcessDisplayItems(nsDisplayList* aList)
|
||||||
mPaintedLayerDataTree.AddingOwnLayer(clipAGR,
|
mPaintedLayerDataTree.AddingOwnLayer(clipAGR,
|
||||||
&scrolledClipRect,
|
&scrolledClipRect,
|
||||||
uniformColorPtr);
|
uniformColorPtr);
|
||||||
} else if (*animatedGeometryRoot == item->Frame() &&
|
} else if ((*animatedGeometryRoot == item->Frame() &&
|
||||||
*animatedGeometryRoot != mBuilder->RootReferenceFrame()) {
|
*animatedGeometryRoot != mBuilder->RootReferenceFrame()) ||
|
||||||
|
(IsScrollThumbLayer(item) && mManager->IsWidgetLayerManager())) {
|
||||||
// This is the case for scrollbar thumbs, for example. In that case the
|
// This is the case for scrollbar thumbs, for example. In that case the
|
||||||
// clip we care about is the overflow:hidden clip on the scrollbar.
|
// clip we care about is the overflow:hidden clip on the scrollbar.
|
||||||
mPaintedLayerDataTree.AddingOwnLayer(animatedGeometryRoot->mParentAGR,
|
mPaintedLayerDataTree.AddingOwnLayer(animatedGeometryRoot->mParentAGR,
|
||||||
|
|
|
@ -6110,6 +6110,14 @@ nsDisplayOwnLayer::nsDisplayOwnLayer(nsDisplayListBuilder* aBuilder,
|
||||||
, mForceActive(aForceActive)
|
, mForceActive(aForceActive)
|
||||||
{
|
{
|
||||||
MOZ_COUNT_CTOR(nsDisplayOwnLayer);
|
MOZ_COUNT_CTOR(nsDisplayOwnLayer);
|
||||||
|
|
||||||
|
// For scroll thumb layers, override the AGR to be the thumb's AGR rather
|
||||||
|
// than the AGR for mFrame (which is the slider frame).
|
||||||
|
if (IsScrollThumbLayer()) {
|
||||||
|
if (nsIFrame* thumbFrame = nsBox::GetChildXULBox(mFrame)) {
|
||||||
|
mAnimatedGeometryRoot = aBuilder->FindAnimatedGeometryRootFor(thumbFrame);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef NS_BUILD_REFCNT_LOGGING
|
#ifdef NS_BUILD_REFCNT_LOGGING
|
||||||
|
@ -6130,6 +6138,20 @@ nsDisplayOwnLayer::GetLayerState(nsDisplayListBuilder* aBuilder,
|
||||||
return RequiredLayerStateForChildren(aBuilder, aManager, aParameters, mList, mAnimatedGeometryRoot);
|
return RequiredLayerStateForChildren(aBuilder, aManager, aParameters, mList, mAnimatedGeometryRoot);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
nsDisplayOwnLayer::IsScrollThumbLayer() const
|
||||||
|
{
|
||||||
|
return (mFlags & VERTICAL_SCROLLBAR) || (mFlags & HORIZONTAL_SCROLLBAR);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
nsDisplayOwnLayer::ShouldBuildLayerEvenIfInvisible(nsDisplayListBuilder* aBuilder)
|
||||||
|
{
|
||||||
|
// Render scroll thumb layers even if they are invisible, because async
|
||||||
|
// scrolling might bring them into view.
|
||||||
|
return IsScrollThumbLayer();
|
||||||
|
}
|
||||||
|
|
||||||
// nsDisplayOpacity uses layers for rendering
|
// nsDisplayOpacity uses layers for rendering
|
||||||
already_AddRefed<Layer>
|
already_AddRefed<Layer>
|
||||||
nsDisplayOwnLayer::BuildLayer(nsDisplayListBuilder* aBuilder,
|
nsDisplayOwnLayer::BuildLayer(nsDisplayListBuilder* aBuilder,
|
||||||
|
|
|
@ -1428,6 +1428,7 @@ private:
|
||||||
AnimatedGeometryRoot* FindAnimatedGeometryRootFor(nsDisplayItem* aItem);
|
AnimatedGeometryRoot* FindAnimatedGeometryRootFor(nsDisplayItem* aItem);
|
||||||
|
|
||||||
friend class nsDisplayItem;
|
friend class nsDisplayItem;
|
||||||
|
friend class nsDisplayOwnLayer;
|
||||||
AnimatedGeometryRoot* FindAnimatedGeometryRootFor(nsIFrame* aFrame);
|
AnimatedGeometryRoot* FindAnimatedGeometryRootFor(nsIFrame* aFrame);
|
||||||
|
|
||||||
AnimatedGeometryRoot* WrapAGRForFrame(nsIFrame* aAnimatedGeometryRoot,
|
AnimatedGeometryRoot* WrapAGRForFrame(nsIFrame* aAnimatedGeometryRoot,
|
||||||
|
@ -4079,7 +4080,7 @@ public:
|
||||||
#ifdef NS_BUILD_REFCNT_LOGGING
|
#ifdef NS_BUILD_REFCNT_LOGGING
|
||||||
virtual ~nsDisplayOwnLayer();
|
virtual ~nsDisplayOwnLayer();
|
||||||
#endif
|
#endif
|
||||||
|
virtual bool ShouldBuildLayerEvenIfInvisible(nsDisplayListBuilder* aBuilder) override;
|
||||||
virtual already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder,
|
virtual already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder,
|
||||||
LayerManager* aManager,
|
LayerManager* aManager,
|
||||||
const ContainerLayerParameters& aContainerParameters) override;
|
const ContainerLayerParameters& aContainerParameters) override;
|
||||||
|
@ -4095,6 +4096,7 @@ public:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
uint32_t GetFlags() { return mFlags; }
|
uint32_t GetFlags() { return mFlags; }
|
||||||
|
bool IsScrollThumbLayer() const;
|
||||||
NS_DISPLAY_DECL_NAME("OwnLayer", TYPE_OWN_LAYER)
|
NS_DISPLAY_DECL_NAME("OwnLayer", TYPE_OWN_LAYER)
|
||||||
protected:
|
protected:
|
||||||
uint32_t mFlags;
|
uint32_t mFlags;
|
||||||
|
|
|
@ -421,6 +421,22 @@ nsSliderFrame::BuildDisplayListForChildren(nsDisplayListBuilder* aBuilder,
|
||||||
nsRect dirty = aDirtyRect.Intersect(thumbRect);
|
nsRect dirty = aDirtyRect.Intersect(thumbRect);
|
||||||
dirty = nsLayoutUtils::ComputePartialPrerenderArea(aDirtyRect, overflow, refSize);
|
dirty = nsLayoutUtils::ComputePartialPrerenderArea(aDirtyRect, overflow, refSize);
|
||||||
|
|
||||||
|
// Clip the thumb layer to the slider track. This is necessary to ensure
|
||||||
|
// FrameLayerBuilder is able to merge content before and after the
|
||||||
|
// scrollframe into the same layer (otherwise it thinks the thumb could
|
||||||
|
// potentially move anywhere within the existing clip).
|
||||||
|
DisplayListClipState::AutoSaveRestore thumbClipState(aBuilder);
|
||||||
|
aBuilder->GetCurrentReferenceFrame();
|
||||||
|
thumbClipState.ClipContainingBlockDescendants(
|
||||||
|
GetRectRelativeToSelf() + aBuilder->ToReferenceFrame(this));
|
||||||
|
|
||||||
|
// Have the thumb's container layer capture the current clip, so
|
||||||
|
// it doesn't apply to the thumb's contents. This allows the contents
|
||||||
|
// to be fully rendered even if they're partially or fully offscreen,
|
||||||
|
// so async scrolling can still bring it into view.
|
||||||
|
DisplayListClipState::AutoSaveRestore thumbContentsClipState(aBuilder);
|
||||||
|
thumbContentsClipState.Clear();
|
||||||
|
|
||||||
nsDisplayListBuilder::AutoContainerASRTracker contASRTracker(aBuilder);
|
nsDisplayListBuilder::AutoContainerASRTracker contASRTracker(aBuilder);
|
||||||
nsDisplayListCollection tempLists;
|
nsDisplayListCollection tempLists;
|
||||||
nsBoxFrame::BuildDisplayListForChildren(aBuilder, dirty, tempLists);
|
nsBoxFrame::BuildDisplayListForChildren(aBuilder, dirty, tempLists);
|
||||||
|
@ -435,10 +451,11 @@ nsSliderFrame::BuildDisplayListForChildren(nsDisplayListBuilder* aBuilder,
|
||||||
masterList.AppendToTop(tempLists.PositionedDescendants());
|
masterList.AppendToTop(tempLists.PositionedDescendants());
|
||||||
masterList.AppendToTop(tempLists.Outlines());
|
masterList.AppendToTop(tempLists.Outlines());
|
||||||
|
|
||||||
|
// Restore the saved clip so it applies to the thumb container layer.
|
||||||
|
thumbContentsClipState.Restore();
|
||||||
|
|
||||||
// Wrap the list to make it its own layer.
|
// Wrap the list to make it its own layer.
|
||||||
const ActiveScrolledRoot* ownLayerASR = contASRTracker.GetContainerASR();
|
const ActiveScrolledRoot* ownLayerASR = contASRTracker.GetContainerASR();
|
||||||
DisplayListClipState::AutoSaveRestore ownLayerClipState(aBuilder);
|
|
||||||
ownLayerClipState.ClearUpToASR(ownLayerASR);
|
|
||||||
aLists.Content()->AppendNewToTop(new (aBuilder)
|
aLists.Content()->AppendNewToTop(new (aBuilder)
|
||||||
nsDisplayOwnLayer(aBuilder, this, &masterList, ownLayerASR,
|
nsDisplayOwnLayer(aBuilder, this, &masterList, ownLayerASR,
|
||||||
flags, scrollTargetId,
|
flags, scrollTargetId,
|
||||||
|
|
Загрузка…
Ссылка в новой задаче