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
--- 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