Bug 1382682 - Collect scroll metadata from the display list in layers-free webrender. r?mstange draft
authorKartikaya Gupta <kgupta@mozilla.com>
Fri, 21 Jul 2017 08:33:24 -0400
changeset 613032 4ffbfeec83e61c5e7af2ae4b7ae5bcbf62dddf4e
parent 612317 d88d37789b4a26d411d29c0e66605fd39d9e328b
child 613033 c982667f60c020686c10b0daed52f8e5237fafce
push id69701
push userkgupta@mozilla.com
push dateFri, 21 Jul 2017 12:34:29 +0000
reviewersmstange
bugs1382682
milestone56.0a1
Bug 1382682 - Collect scroll metadata from the display list in layers-free webrender. r?mstange MozReview-Commit-ID: 9uiwmjpJH3T
gfx/layers/wr/WebRenderLayerManager.cpp
gfx/layers/wr/WebRenderLayerManager.h
--- 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;