зеркало из 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);
|
||||
}
|
||||
|
||||
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.
|
||||
* For each item we compute the effective clip rect. Each item is assigned
|
||||
|
@ -4204,8 +4211,9 @@ ContainerState::ProcessDisplayItems(nsDisplayList* aList)
|
|||
mPaintedLayerDataTree.AddingOwnLayer(clipAGR,
|
||||
&scrolledClipRect,
|
||||
uniformColorPtr);
|
||||
} else if (*animatedGeometryRoot == item->Frame() &&
|
||||
*animatedGeometryRoot != mBuilder->RootReferenceFrame()) {
|
||||
} else if ((*animatedGeometryRoot == item->Frame() &&
|
||||
*animatedGeometryRoot != mBuilder->RootReferenceFrame()) ||
|
||||
(IsScrollThumbLayer(item) && mManager->IsWidgetLayerManager())) {
|
||||
// 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.
|
||||
mPaintedLayerDataTree.AddingOwnLayer(animatedGeometryRoot->mParentAGR,
|
||||
|
|
|
@ -6110,6 +6110,14 @@ nsDisplayOwnLayer::nsDisplayOwnLayer(nsDisplayListBuilder* aBuilder,
|
|||
, mForceActive(aForceActive)
|
||||
{
|
||||
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
|
||||
|
@ -6130,6 +6138,20 @@ nsDisplayOwnLayer::GetLayerState(nsDisplayListBuilder* aBuilder,
|
|||
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
|
||||
already_AddRefed<Layer>
|
||||
nsDisplayOwnLayer::BuildLayer(nsDisplayListBuilder* aBuilder,
|
||||
|
|
|
@ -1428,6 +1428,7 @@ private:
|
|||
AnimatedGeometryRoot* FindAnimatedGeometryRootFor(nsDisplayItem* aItem);
|
||||
|
||||
friend class nsDisplayItem;
|
||||
friend class nsDisplayOwnLayer;
|
||||
AnimatedGeometryRoot* FindAnimatedGeometryRootFor(nsIFrame* aFrame);
|
||||
|
||||
AnimatedGeometryRoot* WrapAGRForFrame(nsIFrame* aAnimatedGeometryRoot,
|
||||
|
@ -4079,7 +4080,7 @@ public:
|
|||
#ifdef NS_BUILD_REFCNT_LOGGING
|
||||
virtual ~nsDisplayOwnLayer();
|
||||
#endif
|
||||
|
||||
virtual bool ShouldBuildLayerEvenIfInvisible(nsDisplayListBuilder* aBuilder) override;
|
||||
virtual already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder,
|
||||
LayerManager* aManager,
|
||||
const ContainerLayerParameters& aContainerParameters) override;
|
||||
|
@ -4095,6 +4096,7 @@ public:
|
|||
return false;
|
||||
}
|
||||
uint32_t GetFlags() { return mFlags; }
|
||||
bool IsScrollThumbLayer() const;
|
||||
NS_DISPLAY_DECL_NAME("OwnLayer", TYPE_OWN_LAYER)
|
||||
protected:
|
||||
uint32_t mFlags;
|
||||
|
|
|
@ -421,6 +421,22 @@ nsSliderFrame::BuildDisplayListForChildren(nsDisplayListBuilder* aBuilder,
|
|||
nsRect dirty = aDirtyRect.Intersect(thumbRect);
|
||||
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);
|
||||
nsDisplayListCollection tempLists;
|
||||
nsBoxFrame::BuildDisplayListForChildren(aBuilder, dirty, tempLists);
|
||||
|
@ -435,10 +451,11 @@ nsSliderFrame::BuildDisplayListForChildren(nsDisplayListBuilder* aBuilder,
|
|||
masterList.AppendToTop(tempLists.PositionedDescendants());
|
||||
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.
|
||||
const ActiveScrolledRoot* ownLayerASR = contASRTracker.GetContainerASR();
|
||||
DisplayListClipState::AutoSaveRestore ownLayerClipState(aBuilder);
|
||||
ownLayerClipState.ClearUpToASR(ownLayerASR);
|
||||
aLists.Content()->AppendNewToTop(new (aBuilder)
|
||||
nsDisplayOwnLayer(aBuilder, this, &masterList, ownLayerASR,
|
||||
flags, scrollTargetId,
|
||||
|
|
Загрузка…
Ссылка в новой задаче