Bug 1382682 - Collect scroll metadata from the display list in layers-free webrender. r?mstange
MozReview-Commit-ID: 9uiwmjpJH3T
--- a/gfx/layers/wr/WebRenderLayerManager.cpp
+++ b/gfx/layers/wr/WebRenderLayerManager.cpp
@@ -189,16 +189,19 @@ PopulateScrollData(WebRenderScrollData&
}
void
WebRenderLayerManager::CreateWebRenderCommandsFromDisplayList(nsDisplayList* aDisplayList,
nsDisplayListBuilder* aDisplayListBuilder,
StackingContextHelper& aSc,
wr::DisplayListBuilder& aBuilder)
{
+ bool apzEnabled = AsyncPanZoomEnabled();
+ const ActiveScrolledRoot* lastAsr = nullptr;
+
nsDisplayList savedItems;
nsDisplayItem* item;
while ((item = aDisplayList->RemoveBottom()) != nullptr) {
nsDisplayItem::Type itemType = item->GetType();
// If the item is a event regions item, but is empty (has no regions in it)
// then we should just throw it out
if (itemType == nsDisplayItem::TYPE_LAYER_EVENT_REGIONS) {
@@ -229,16 +232,37 @@ WebRenderLayerManager::CreateWebRenderCo
if (item->ShouldFlattenAway(aDisplayListBuilder)) {
aDisplayList->AppendToBottom(itemSameCoordinateSystemChildren);
item->~nsDisplayItem();
continue;
}
savedItems.AppendToTop(item);
+ if (apzEnabled) {
+ const ActiveScrolledRoot* asr = item->GetActiveScrolledRoot();
+ // The ASR check here is just an optimization to avoid doing any unnecessary
+ // work in a common case, where adjacent items in the display list have
+ // the same ASR.
+ if (asr && asr != lastAsr) {
+ lastAsr = asr;
+ FrameMetrics::ViewID id = nsLayoutUtils::ViewIDForASR(asr);
+ if (mScrollMetadata.find(id) == mScrollMetadata.end()) {
+ // We pass null here for the display item clip because we don't need
+ // the clip to be in the ScrollMetadata here; we will push the clip
+ // information into the WR display list directly.
+ Maybe<ScrollMetadata> metadata = asr->mScrollableFrame->ComputeScrollMetadata(
+ nullptr, item->ReferenceFrame(),
+ ContainerLayerParameters(), nullptr);
+ MOZ_ASSERT(metadata);
+ mScrollMetadata[id] = *metadata;
+ }
+ }
+ }
+
if (!item->CreateWebRenderCommands(aBuilder, aSc, mParentCommands, this,
aDisplayListBuilder)) {
PushItemAsImage(item, aBuilder, aSc, aDisplayListBuilder);
}
}
aDisplayList->AppendToTop(&savedItems);
}
@@ -482,21 +506,25 @@ WebRenderLayerManager::EndTransactionInt
}
DiscardCompositorAnimations();
wr::LayoutSize contentSize { (float)size.width, (float)size.height };
wr::DisplayListBuilder builder(WrBridge()->GetPipeline(), contentSize);
if (mEndTransactionWithoutLayers) {
// aDisplayList being null here means this is an empty transaction following a layers-free
- // transaction, so we reuse the previously built displaylist.
+ // transaction, so we reuse the previously built displaylist and scroll
+ // metadata information
if (aDisplayList && aDisplayListBuilder) {
StackingContextHelper sc;
mParentCommands.Clear();
+ mScrollMetadata.clear();
+
CreateWebRenderCommandsFromDisplayList(aDisplayList, aDisplayListBuilder, sc, builder);
+
builder.Finalize(contentSize, mBuiltDisplayList);
}
builder.PushBuiltDisplayList(mBuiltDisplayList);
WrBridge()->AddWebRenderParentCommands(mParentCommands);
} else {
mRoot->StartPendingAnimations(mAnimationReadyTime);
StackingContextHelper sc;
--- a/gfx/layers/wr/WebRenderLayerManager.h
+++ b/gfx/layers/wr/WebRenderLayerManager.h
@@ -231,16 +231,20 @@ private:
LayerRefArray mKeepAlive;
// These fields are used to save a copy of the display list for
// empty transactions in layers-free mode.
wr::BuiltDisplayList mBuiltDisplayList;
nsTArray<WebRenderParentCommand> mParentCommands;
+ // We need this for building scroll data for the compositor in
+ // layers-free mode
+ std::unordered_map<FrameMetrics::ViewID, ScrollMetadata> mScrollMetadata;
+
// Layers that have been mutated. If we have an empty transaction
// then a display item layer will no longer be valid
// if it was a mutated layers.
void AddMutatedLayer(Layer* aLayer);
void ClearMutatedLayers();
LayerRefArray mMutatedLayers;
bool mTransactionIncomplete;