Bug 1384616 - Change how display items put their APZ-relevant info into the WebRenderScrollData. r=jrmuizel
authorKartikaya Gupta <kgupta@mozilla.com>
Mon, 31 Jul 2017 15:27:29 -0400
changeset 423152 509e1cc89fb526ff0b232f9ed3a49127e84bdd7c
parent 423151 19ee1751ecc3fef63393a233ecc47a2a7b5c9e41
child 423153 9e863293355e8c20550ebf78ae35fa2d6dba156d
push id1517
push userjlorenzo@mozilla.com
push dateThu, 14 Sep 2017 16:50:54 +0000
treeherdermozilla-release@3b41fd564418 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjrmuizel
bugs1384616
milestone56.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1384616 - Change how display items put their APZ-relevant info into the WebRenderScrollData. r=jrmuizel Instead of the WebRenderLayerScrollData code knowing about all the different display item types, it makes more sense to move this logic into the display items. In addition to avoiding dis-encapsulating the data from nsDisplayItem subclasses, this makes it easier to handle two specific scenarios: (1) the case where an nsDisplayItem A subclasses another nsDisplayItem B, but A and B have different types returned by GetType(). Previously A and B would have to be handled explicitly in the WebRenderLayerScrollData switch statements, which doesn't scale well if new types are added. With the new approach the virtual function is shared down from A to B and so takes care of it. This is particularly relevant for types like nsDisplayOwnLayer which have a number of subclasses. (2) the case where a display item *might* have APZ-relevant information. In this case the type of the item alone is not sufficient to determine if we need to create a new WebRenderLayerScrollData for it. Instead, we need to access specific state inside the display item. This is now handled by the UpdateScrollData function returning true when passed nullptr arguments, and replaces the switch statement in WebRenderLayerManager that updated forceNewLayerData. MozReview-Commit-ID: FlfHlgSccSn
gfx/layers/wr/WebRenderLayerManager.cpp
gfx/layers/wr/WebRenderScrollData.cpp
gfx/layers/wr/WebRenderScrollData.h
layout/ipc/RenderFrameParent.cpp
layout/ipc/RenderFrameParent.h
layout/painting/nsDisplayList.cpp
layout/painting/nsDisplayList.h
--- a/gfx/layers/wr/WebRenderLayerManager.cpp
+++ b/gfx/layers/wr/WebRenderLayerManager.cpp
@@ -233,29 +233,20 @@ WebRenderLayerManager::CreateWebRenderCo
       aDisplayList->AppendToBottom(itemSameCoordinateSystemChildren);
       item->~nsDisplayItem();
       continue;
     }
 
     savedItems.AppendToTop(item);
 
     if (apzEnabled) {
-      bool forceNewLayerData = false;
-
       // For some types of display items we want to force a new
       // WebRenderLayerScrollData object, to ensure we preserve the APZ-relevant
       // data that is in the display item.
-      switch (itemType) {
-      case nsDisplayItem::TYPE_SCROLL_INFO_LAYER:
-      case nsDisplayItem::TYPE_REMOTE:
-        forceNewLayerData = true;
-        break;
-      default:
-        break;
-      }
+      bool forceNewLayerData = item->UpdateScrollData(nullptr, nullptr);
 
       // Anytime the ASR changes we also want to force a new layer data because
       // the stack of scroll metadata is going to be different for this
       // display item than previously, so we can't squash the display items
       // into the same "layer".
       const ActiveScrolledRoot* asr = item->GetActiveScrolledRoot();
       if (forceNewLayerData || asr != lastAsr) {
         lastAsr = asr;
--- a/gfx/layers/wr/WebRenderScrollData.cpp
+++ b/gfx/layers/wr/WebRenderScrollData.cpp
@@ -69,34 +69,17 @@ WebRenderLayerScrollData::InitializeRoot
 
 void
 WebRenderLayerScrollData::Initialize(WebRenderScrollData& aOwner,
                                      nsDisplayItem* aItem)
 {
   mDescendantCount = 0;
 
   MOZ_ASSERT(aItem);
-  switch (aItem->GetType()) {
-  case nsDisplayItem::TYPE_SCROLL_INFO_LAYER: {
-    nsDisplayScrollInfoLayer* info = static_cast<nsDisplayScrollInfoLayer*>(aItem);
-    UniquePtr<ScrollMetadata> metadata = info->ComputeScrollMetadata(
-        nullptr, ContainerLayerParameters());
-    MOZ_ASSERT(metadata);
-    MOZ_ASSERT(metadata->GetMetrics().IsScrollInfoLayer());
-    mScrollIds.AppendElement(aOwner.AddMetadata(*metadata));
-    break;
-  }
-  case nsDisplayItem::TYPE_REMOTE: {
-    nsDisplayRemote* remote = static_cast<nsDisplayRemote*>(aItem);
-    mReferentId = Some(remote->GetRemoteLayersId());
-    break;
-  }
-  default:
-    break;
-  }
+  aItem->UpdateScrollData(&aOwner, this);
   for (const ActiveScrolledRoot* asr = aItem->GetActiveScrolledRoot();
        asr;
        asr = asr->mParent) {
     Maybe<ScrollMetadata> metadata = asr->mScrollableFrame->ComputeScrollMetadata(
         nullptr, aItem->ReferenceFrame(), ContainerLayerParameters(), nullptr);
     MOZ_ASSERT(metadata);
     mScrollIds.AppendElement(aOwner.AddMetadata(metadata.ref()));
   }
@@ -110,16 +93,23 @@ WebRenderLayerScrollData::GetDescendantC
 }
 
 size_t
 WebRenderLayerScrollData::GetScrollMetadataCount() const
 {
   return mScrollIds.Length();
 }
 
+void
+WebRenderLayerScrollData::AppendScrollMetadata(WebRenderScrollData& aOwner,
+                                               const ScrollMetadata& aData)
+{
+  mScrollIds.AppendElement(aOwner.AddMetadata(aData));
+}
+
 const ScrollMetadata&
 WebRenderLayerScrollData::GetScrollMetadata(const WebRenderScrollData& aOwner,
                                             size_t aIndex) const
 {
   MOZ_ASSERT(aIndex < mScrollIds.Length());
   return aOwner.GetScrollMetadata(mScrollIds[aIndex]);
 }
 
--- a/gfx/layers/wr/WebRenderScrollData.h
+++ b/gfx/layers/wr/WebRenderScrollData.h
@@ -43,28 +43,31 @@ public:
                   int32_t aDescendantCount);
   void InitializeRoot(int32_t aDescendantCount);
   void Initialize(WebRenderScrollData& aOwner,
                   nsDisplayItem* aItem);
 
   int32_t GetDescendantCount() const;
   size_t GetScrollMetadataCount() const;
 
+  void AppendScrollMetadata(WebRenderScrollData& aOwner,
+                            const ScrollMetadata& aData);
   // Return the ScrollMetadata object that used to be on the original Layer
   // at the given index. Since we deduplicate the ScrollMetadata objects into
   // the array in the owning WebRenderScrollData object, we need to be passed
   // in a reference to that owner as well.
   const ScrollMetadata& GetScrollMetadata(const WebRenderScrollData& aOwner,
                                           size_t aIndex) const;
 
   gfx::Matrix4x4 GetTransform() const { return mTransform; }
   CSSTransformMatrix GetTransformTyped() const;
   bool GetTransformIsPerspective() const { return mTransformIsPerspective; }
   EventRegions GetEventRegions() const { return mEventRegions; }
   const LayerIntRegion& GetVisibleRegion() const { return mVisibleRegion; }
+  void SetReferentId(uint64_t aReferentId) { mReferentId = Some(aReferentId); }
   Maybe<uint64_t> GetReferentId() const { return mReferentId; }
   EventRegionsOverride GetEventRegionsOverride() const { return mEventRegionsOverride; }
   const ScrollThumbData& GetScrollThumbData() const { return mScrollThumbData; }
   const uint64_t& GetScrollbarAnimationId() const { return mScrollbarAnimationId; }
   FrameMetrics::ViewID GetScrollbarTargetContainerId() const { return mScrollbarTargetContainerId; }
   bool IsScrollbarContainer() const { return mIsScrollbarContainer; }
   FrameMetrics::ViewID GetFixedPositionScrollContainerId() const { return mFixedPosScrollContainerId; }
 
--- a/layout/ipc/RenderFrameParent.cpp
+++ b/layout/ipc/RenderFrameParent.cpp
@@ -27,16 +27,17 @@
 #include "nsStyleStructInlines.h"
 #include "nsSubDocumentFrame.h"
 #include "nsView.h"
 #include "RenderFrameParent.h"
 #include "mozilla/gfx/GPUProcessManager.h"
 #include "mozilla/layers/LayerManagerComposite.h"
 #include "mozilla/layers/CompositorBridgeChild.h"
 #include "mozilla/layers/WebRenderLayerManager.h"
+#include "mozilla/layers/WebRenderScrollData.h"
 #include "mozilla/webrender/WebRenderAPI.h"
 #include "ClientLayerManager.h"
 #include "FrameLayerBuilder.h"
 
 using namespace mozilla::dom;
 using namespace mozilla::gfx;
 using namespace mozilla::layers;
 
@@ -395,13 +396,23 @@ nsDisplayRemote::CreateWebRenderCommands
   visible += mozilla::layout::GetContentRectLayerOffset(mFrame, aDisplayListBuilder);
 
   aBuilder.PushIFrame(aSc.ToRelativeLayoutRect(visible),
       mozilla::wr::AsPipelineId(GetRemoteLayersId()));
 
   return true;
 }
 
+bool
+nsDisplayRemote::UpdateScrollData(mozilla::layers::WebRenderScrollData* aData,
+                                  mozilla::layers::WebRenderLayerScrollData* aLayerData)
+{
+  if (aLayerData) {
+    aLayerData->SetReferentId(GetRemoteLayersId());
+  }
+  return true;
+}
+
 uint64_t
 nsDisplayRemote::GetRemoteLayersId() const
 {
   return mRemoteFrame->GetLayersId();
 }
--- a/layout/ipc/RenderFrameParent.h
+++ b/layout/ipc/RenderFrameParent.h
@@ -162,16 +162,19 @@ public:
   BuildLayer(nsDisplayListBuilder* aBuilder, LayerManager* aManager,
              const ContainerLayerParameters& aContainerParameters) override;
 
   virtual bool CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuilder,
                                        const StackingContextHelper& aSc,
                                        nsTArray<WebRenderParentCommand>& aParentCommands,
                                        mozilla::layers::WebRenderLayerManager* aManager,
                                        nsDisplayListBuilder* aDisplayListBuilder) override;
+  virtual bool UpdateScrollData(mozilla::layers::WebRenderScrollData* aData,
+                                mozilla::layers::WebRenderLayerScrollData* aLayerData) override;
+
   uint64_t GetRemoteLayersId() const;
 
   NS_DISPLAY_DECL_NAME("Remote", TYPE_REMOTE)
 
 private:
   RenderFrameParent* mRemoteFrame;
   mozilla::layers::EventRegionsOverride mEventRegionsOverride;
 };
--- a/layout/painting/nsDisplayList.cpp
+++ b/layout/painting/nsDisplayList.cpp
@@ -83,20 +83,20 @@
 #include "nsCSSProps.h"
 #include "nsPluginFrame.h"
 #include "nsSVGMaskFrame.h"
 #include "nsTableCellFrame.h"
 #include "nsTableColFrame.h"
 #include "ClientLayerManager.h"
 #include "mozilla/layers/StackingContextHelper.h"
 #include "mozilla/layers/WebRenderBridgeChild.h"
+#include "mozilla/layers/WebRenderDisplayItemLayer.h"
 #include "mozilla/layers/WebRenderLayerManager.h"
-#include "mozilla/layers/WebRenderDisplayItemLayer.h"
 #include "mozilla/layers/WebRenderMessages.h"
-#include "mozilla/layers/WebRenderDisplayItemLayer.h"
+#include "mozilla/layers/WebRenderScrollData.h"
 
 // GetCurrentTime is defined in winbase.h as zero argument macro forwarding to
 // GetTickCount().
 #ifdef GetCurrentTime
 #undef GetCurrentTime
 #endif
 
 using namespace mozilla;
@@ -6892,17 +6892,29 @@ nsDisplayScrollInfoLayer::ComputeScrollM
       mScrolledFrame, mScrollFrame, mScrollFrame->GetContent(),
       ReferenceFrame(), aLayer,
       mScrollParentId, viewport, Nothing(), false, aContainerParameters);
   metadata.GetMetrics().SetIsScrollInfoLayer(true);
 
   return UniquePtr<ScrollMetadata>(new ScrollMetadata(metadata));
 }
 
-
+bool
+nsDisplayScrollInfoLayer::UpdateScrollData(mozilla::layers::WebRenderScrollData* aData,
+                                           mozilla::layers::WebRenderLayerScrollData* aLayerData)
+{
+  if (aLayerData) {
+    UniquePtr<ScrollMetadata> metadata =
+      ComputeScrollMetadata(nullptr, ContainerLayerParameters());
+    MOZ_ASSERT(aData);
+    MOZ_ASSERT(metadata);
+    aLayerData->AppendScrollMetadata(*aData, *metadata);
+  }
+  return true;
+}
 
 void
 nsDisplayScrollInfoLayer::WriteDebugInfo(std::stringstream& aStream)
 {
   aStream << " (scrollframe " << mScrollFrame
           << " scrolledFrame " << mScrolledFrame << ")";
 }
 
--- a/layout/painting/nsDisplayList.h
+++ b/layout/painting/nsDisplayList.h
@@ -59,16 +59,18 @@ class FrameLayerBuilder;
 namespace layers {
 class Layer;
 class ImageLayer;
 class ImageContainer;
 class StackingContextHelper;
 class WebRenderCommand;
 class WebRenderParentCommand;
 class WebRenderDisplayItemLayer;
+class WebRenderScrollData;
+class WebRenderLayerScrollData;
 } // namespace layers
 namespace wr {
 class DisplayListBuilder;
 } // namespace wr
 } // namespace mozilla
 
 // A set of blend modes, that never includes OP_OVER (since it's
 // considered the default, rather than a specific blend mode).
@@ -1962,16 +1964,35 @@ public:
    */
   virtual bool CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuilder,
                                        const StackingContextHelper& aSc,
                                        nsTArray<WebRenderParentCommand>& aParentCommands,
                                        mozilla::layers::WebRenderLayerManager* aManager,
                                        nsDisplayListBuilder* aDisplayListBuilder) { return false; }
 
   /**
+   * Updates the provided aLayerData with any APZ-relevant scroll data
+   * that is specific to this display item. This is stuff that would normally
+   * be put on the layer during BuildLayer, but this is only called in
+   * layers-free webrender mode, where we don't have layers.
+   *
+   * This function returns true if and only if it has APZ-relevant scroll data
+   * to provide. Note that the arguments passed in may be nullptr, in which case
+   * the function should still return true if and only if it has APZ-relevant
+   * scroll data, but obviously in this case it can't actually put the
+   * data onto aLayerData, because there isn't one.
+   *
+   * This function assumes that aData and aLayerData will either both be null,
+   * or will both be non-null. The caller is responsible for enforcing this.
+   */
+  virtual bool UpdateScrollData(mozilla::layers::WebRenderScrollData* aData,
+                                mozilla::layers::WebRenderLayerScrollData* aLayerData)
+  { return false; }
+
+  /**
    * Builds a DisplayItemLayer and sets the display item to this.
    */
   already_AddRefed<Layer>
   BuildDisplayItemLayer(nsDisplayListBuilder* aBuilder,
                         LayerManager* aManager,
                         const ContainerLayerParameters& aContainerParameters);
 
   /**
@@ -4345,16 +4366,19 @@ public:
   virtual bool ShouldFlattenAway(nsDisplayListBuilder* aBuilder) override
   { return false; }
 
   virtual void WriteDebugInfo(std::stringstream& aStream) override;
 
   mozilla::UniquePtr<ScrollMetadata> ComputeScrollMetadata(Layer* aLayer,
                                                            const ContainerLayerParameters& aContainerParameters);
 
+  virtual bool UpdateScrollData(mozilla::layers::WebRenderScrollData* aData,
+                                mozilla::layers::WebRenderLayerScrollData* aLayerData) override;
+
 protected:
   nsIFrame* mScrollFrame;
   nsIFrame* mScrolledFrame;
   ViewID mScrollParentId;
 };
 
 /**
  * nsDisplayZoom is used for subdocuments that have a different full zoom than