From 3b8aaa896a8814619b4ccf481ab9c73e71f7f67d Mon Sep 17 00:00:00 2001 From: Kartikaya Gupta Date: Mon, 31 Jul 2017 15:27:29 -0400 Subject: [PATCH] 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 --HG-- extra : rebase_source : d1fe841724cc6020433aea31ffb5214d8a44d0a9 --- gfx/layers/wr/WebRenderLayerManager.cpp | 11 +---------- gfx/layers/wr/WebRenderScrollData.cpp | 26 ++++++++----------------- gfx/layers/wr/WebRenderScrollData.h | 3 +++ layout/ipc/RenderFrameParent.cpp | 11 +++++++++++ layout/ipc/RenderFrameParent.h | 3 +++ layout/painting/nsDisplayList.cpp | 18 ++++++++++++++--- layout/painting/nsDisplayList.h | 24 +++++++++++++++++++++++ 7 files changed, 65 insertions(+), 31 deletions(-) diff --git a/gfx/layers/wr/WebRenderLayerManager.cpp b/gfx/layers/wr/WebRenderLayerManager.cpp index a13497b227b6..a9dfcffaa07c 100644 --- a/gfx/layers/wr/WebRenderLayerManager.cpp +++ b/gfx/layers/wr/WebRenderLayerManager.cpp @@ -238,19 +238,10 @@ WebRenderLayerManager::CreateWebRenderCommandsFromDisplayList(nsDisplayList* aDi 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 diff --git a/gfx/layers/wr/WebRenderScrollData.cpp b/gfx/layers/wr/WebRenderScrollData.cpp index ba0210700ce7..c5250b60de9e 100644 --- a/gfx/layers/wr/WebRenderScrollData.cpp +++ b/gfx/layers/wr/WebRenderScrollData.cpp @@ -74,24 +74,7 @@ WebRenderLayerScrollData::Initialize(WebRenderScrollData& aOwner, mDescendantCount = 0; MOZ_ASSERT(aItem); - switch (aItem->GetType()) { - case nsDisplayItem::TYPE_SCROLL_INFO_LAYER: { - nsDisplayScrollInfoLayer* info = static_cast(aItem); - UniquePtr 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(aItem); - mReferentId = Some(remote->GetRemoteLayersId()); - break; - } - default: - break; - } + aItem->UpdateScrollData(&aOwner, this); for (const ActiveScrolledRoot* asr = aItem->GetActiveScrolledRoot(); asr; asr = asr->mParent) { @@ -115,6 +98,13 @@ 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 diff --git a/gfx/layers/wr/WebRenderScrollData.h b/gfx/layers/wr/WebRenderScrollData.h index edc6e6beda49..ea206c45f15d 100644 --- a/gfx/layers/wr/WebRenderScrollData.h +++ b/gfx/layers/wr/WebRenderScrollData.h @@ -48,6 +48,8 @@ public: 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 @@ -60,6 +62,7 @@ public: 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 GetReferentId() const { return mReferentId; } EventRegionsOverride GetEventRegionsOverride() const { return mEventRegionsOverride; } const ScrollThumbData& GetScrollThumbData() const { return mScrollThumbData; } diff --git a/layout/ipc/RenderFrameParent.cpp b/layout/ipc/RenderFrameParent.cpp index fa1a7cadae0e..07ee949d8334 100644 --- a/layout/ipc/RenderFrameParent.cpp +++ b/layout/ipc/RenderFrameParent.cpp @@ -32,6 +32,7 @@ #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" @@ -400,6 +401,16 @@ nsDisplayRemote::CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuild 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 { diff --git a/layout/ipc/RenderFrameParent.h b/layout/ipc/RenderFrameParent.h index 93c605a8895a..ac0c31b9d8ef 100644 --- a/layout/ipc/RenderFrameParent.h +++ b/layout/ipc/RenderFrameParent.h @@ -167,6 +167,9 @@ public: nsTArray& 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) diff --git a/layout/painting/nsDisplayList.cpp b/layout/painting/nsDisplayList.cpp index 8a165bfd7eaa..1f560c8dd523 100644 --- a/layout/painting/nsDisplayList.cpp +++ b/layout/painting/nsDisplayList.cpp @@ -88,10 +88,10 @@ #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(). @@ -6897,7 +6897,19 @@ nsDisplayScrollInfoLayer::ComputeScrollMetadata(Layer* aLayer, return UniquePtr(new ScrollMetadata(metadata)); } - +bool +nsDisplayScrollInfoLayer::UpdateScrollData(mozilla::layers::WebRenderScrollData* aData, + mozilla::layers::WebRenderLayerScrollData* aLayerData) +{ + if (aLayerData) { + UniquePtr metadata = + ComputeScrollMetadata(nullptr, ContainerLayerParameters()); + MOZ_ASSERT(aData); + MOZ_ASSERT(metadata); + aLayerData->AppendScrollMetadata(*aData, *metadata); + } + return true; +} void nsDisplayScrollInfoLayer::WriteDebugInfo(std::stringstream& aStream) diff --git a/layout/painting/nsDisplayList.h b/layout/painting/nsDisplayList.h index 87eb503e946d..5273444cb447 100644 --- a/layout/painting/nsDisplayList.h +++ b/layout/painting/nsDisplayList.h @@ -64,6 +64,8 @@ class StackingContextHelper; class WebRenderCommand; class WebRenderParentCommand; class WebRenderDisplayItemLayer; +class WebRenderScrollData; +class WebRenderLayerScrollData; } // namespace layers namespace wr { class DisplayListBuilder; @@ -1966,6 +1968,25 @@ public: 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. */ @@ -4350,6 +4371,9 @@ public: mozilla::UniquePtr ComputeScrollMetadata(Layer* aLayer, const ContainerLayerParameters& aContainerParameters); + virtual bool UpdateScrollData(mozilla::layers::WebRenderScrollData* aData, + mozilla::layers::WebRenderLayerScrollData* aLayerData) override; + protected: nsIFrame* mScrollFrame; nsIFrame* mScrolledFrame;