mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-14 22:05:44 +00:00
Bug 1405359 - Avoid pushing and popping identical clip stacks for adjacent display items. r=jrmuizel
Instead of unconditionally pushing and popping clips per display item, this patch changes things so that for each recursive display list, we create an ItemClips struct. We push this onto the stack when we enter the display list, and pop it off at the end. For each display item, we check to see if the clips would actually change compared to the previous display item, and only do the pop/repush in that case. MozReview-Commit-ID: GadIp2J8TrA --HG-- extra : rebase_source : ba64c6b4659b8e51cab19b807088b9a50d71b85a
This commit is contained in:
parent
1ef110fd03
commit
3bc78496af
@ -37,10 +37,35 @@ ScrollingLayersHelper::EndBuild()
|
||||
MOZ_ASSERT(mItemClipStack.empty());
|
||||
}
|
||||
|
||||
void
|
||||
ScrollingLayersHelper::BeginList()
|
||||
{
|
||||
mItemClipStack.emplace_back(nullptr, nullptr);
|
||||
}
|
||||
|
||||
void
|
||||
ScrollingLayersHelper::EndList()
|
||||
{
|
||||
MOZ_ASSERT(!mItemClipStack.empty());
|
||||
mItemClipStack.back().Unapply(mBuilder);
|
||||
mItemClipStack.pop_back();
|
||||
}
|
||||
|
||||
void
|
||||
ScrollingLayersHelper::BeginItem(nsDisplayItem* aItem,
|
||||
const StackingContextHelper& aStackingContext)
|
||||
{
|
||||
ItemClips clips(aItem->GetActiveScrolledRoot(), aItem->GetClipChain());
|
||||
MOZ_ASSERT(!mItemClipStack.empty());
|
||||
if (clips.HasSameInputs(mItemClipStack.back())) {
|
||||
// Early-exit because if the clips are the same then we don't need to do
|
||||
// do the work of popping the old stuff and then pushing it right back on
|
||||
// for the new item.
|
||||
return;
|
||||
}
|
||||
mItemClipStack.back().Unapply(mBuilder);
|
||||
mItemClipStack.pop_back();
|
||||
|
||||
int32_t auPerDevPixel = aItem->Frame()->PresContext()->AppUnitsPerDevPixel();
|
||||
|
||||
// There are two ASR chains here that we need to be fully defined. One is the
|
||||
@ -78,7 +103,6 @@ ScrollingLayersHelper::BeginItem(nsDisplayItem* aItem,
|
||||
// the item's ASR. So for those cases we need to use the ClipAndScroll API.
|
||||
bool needClipAndScroll = (leafmostId != scrollId);
|
||||
|
||||
ItemClips clips;
|
||||
// If we don't need a ClipAndScroll, ensure the item's ASR is at the top of
|
||||
// the scroll stack
|
||||
if (!needClipAndScroll && mBuilder->TopmostScrollId() != scrollId) {
|
||||
@ -376,15 +400,6 @@ ScrollingLayersHelper::RecurseAndDefineAsr(nsDisplayItem* aItem,
|
||||
return ids;
|
||||
}
|
||||
|
||||
void
|
||||
ScrollingLayersHelper::EndItem(nsDisplayItem* aItem)
|
||||
{
|
||||
MOZ_ASSERT(!mItemClipStack.empty());
|
||||
ItemClips& clips = mItemClipStack.back();
|
||||
clips.Unapply(mBuilder);
|
||||
mItemClipStack.pop_back();
|
||||
}
|
||||
|
||||
ScrollingLayersHelper::~ScrollingLayersHelper()
|
||||
{
|
||||
MOZ_ASSERT(!mBuilder);
|
||||
@ -392,6 +407,13 @@ ScrollingLayersHelper::~ScrollingLayersHelper()
|
||||
MOZ_ASSERT(mItemClipStack.empty());
|
||||
}
|
||||
|
||||
ScrollingLayersHelper::ItemClips::ItemClips(const ActiveScrolledRoot* aAsr,
|
||||
const DisplayItemClipChain* aChain)
|
||||
: mAsr(aAsr)
|
||||
, mChain(aChain)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
ScrollingLayersHelper::ItemClips::Apply(wr::DisplayListBuilder* aBuilder)
|
||||
{
|
||||
@ -421,5 +443,12 @@ ScrollingLayersHelper::ItemClips::Unapply(wr::DisplayListBuilder* aBuilder)
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
ScrollingLayersHelper::ItemClips::HasSameInputs(const ItemClips& aOther)
|
||||
{
|
||||
return mAsr == aOther.mAsr &&
|
||||
mChain == aOther.mChain;
|
||||
}
|
||||
|
||||
} // namespace layers
|
||||
} // namespace mozilla
|
||||
|
@ -32,9 +32,11 @@ public:
|
||||
void BeginBuild(wr::DisplayListBuilder& aBuilder);
|
||||
void EndBuild();
|
||||
|
||||
void BeginList();
|
||||
void EndList();
|
||||
|
||||
void BeginItem(nsDisplayItem* aItem,
|
||||
const StackingContextHelper& aStackingContext);
|
||||
void EndItem(nsDisplayItem* aItem);
|
||||
~ScrollingLayersHelper();
|
||||
|
||||
private:
|
||||
@ -75,12 +77,19 @@ private:
|
||||
ClipIdMap mCache;
|
||||
|
||||
struct ItemClips {
|
||||
ItemClips(const ActiveScrolledRoot* aAsr,
|
||||
const DisplayItemClipChain* aChain);
|
||||
|
||||
const ActiveScrolledRoot* mAsr;
|
||||
const DisplayItemClipChain* mChain;
|
||||
|
||||
Maybe<FrameMetrics::ViewID> mScrollId;
|
||||
Maybe<wr::WrClipId> mClipId;
|
||||
Maybe<std::pair<FrameMetrics::ViewID, Maybe<wr::WrClipId>>> mClipAndScroll;
|
||||
|
||||
void Apply(wr::DisplayListBuilder* aBuilder);
|
||||
void Unapply(wr::DisplayListBuilder* aBuilder);
|
||||
bool HasSameInputs(const ItemClips& aOther);
|
||||
};
|
||||
|
||||
std::vector<ItemClips> mItemClipStack;
|
||||
|
@ -112,6 +112,8 @@ WebRenderCommandBuilder::CreateWebRenderCommandsFromDisplayList(nsDisplayList* a
|
||||
wr::DisplayListBuilder& aBuilder,
|
||||
wr::IpcResourceUpdateQueue& aResources)
|
||||
{
|
||||
mScrollingHelper.BeginList();
|
||||
|
||||
bool apzEnabled = mManager->AsyncPanZoomEnabled();
|
||||
EventRegions eventRegions;
|
||||
|
||||
@ -221,7 +223,6 @@ WebRenderCommandBuilder::CreateWebRenderCommandsFromDisplayList(nsDisplayList* a
|
||||
aDisplayListBuilder)) {
|
||||
PushItemAsImage(item, aBuilder, aResources, aSc, aDisplayListBuilder);
|
||||
}
|
||||
mScrollingHelper.EndItem(item);
|
||||
|
||||
if (apzEnabled) {
|
||||
if (forceNewLayerData) {
|
||||
@ -259,6 +260,8 @@ WebRenderCommandBuilder::CreateWebRenderCommandsFromDisplayList(nsDisplayList* a
|
||||
MOZ_ASSERT(!mLayerScrollData.empty());
|
||||
mLayerScrollData.back().AddEventRegions(eventRegions);
|
||||
}
|
||||
|
||||
mScrollingHelper.EndList();
|
||||
}
|
||||
|
||||
Maybe<wr::ImageKey>
|
||||
|
Loading…
Reference in New Issue
Block a user