Bug 1449982 - Move the WebRenderScrollData storage from WebRenderBridgeParent to APZUpdater. r?botond
This allows us to easily store a handle to the APZUpdater on the
WebRenderScrollDataWrapper class and walk around in the scroll data tree
without having to query other classes like CompositorBridgeParent or
WebRenderBridgeParent when we encounter a reflayer boundary.
MozReview-Commit-ID: 6l7oMb7tBlW
--- a/gfx/layers/apz/public/APZSampler.h
+++ b/gfx/layers/apz/public/APZSampler.h
@@ -70,22 +70,22 @@ public:
void MarkAsyncTransformAppliedToContent(const LayerMetricsWrapper& aLayer);
bool HasUnusedAsyncTransform(const LayerMetricsWrapper& aLayer);
/**
* This can be used to assert that the current thread is the
* sampler thread (which samples the async transform).
* This does nothing if thread assertions are disabled.
*/
- void AssertOnSamplerThread();
+ void AssertOnSamplerThread() const;
/**
* Returns true if currently on the APZSampler's "sampler thread".
*/
- bool IsSamplerThread();
+ bool IsSamplerThread() const;
protected:
virtual ~APZSampler();
private:
RefPtr<APZCTreeManager> mApz;
};
--- a/gfx/layers/apz/public/APZUpdater.h
+++ b/gfx/layers/apz/public/APZUpdater.h
@@ -8,16 +8,17 @@
#define mozilla_layers_APZUpdater_h
#include <deque>
#include <unordered_map>
#include "base/platform_thread.h" // for PlatformThreadId
#include "LayersTypes.h"
#include "mozilla/layers/APZTestData.h"
+#include "mozilla/layers/WebRenderScrollData.h"
#include "mozilla/StaticMutex.h"
#include "nsThreadUtils.h"
#include "Units.h"
namespace mozilla {
namespace wr {
struct WrWindowId;
@@ -59,53 +60,60 @@ public:
void UpdateFocusState(LayersId aRootLayerTreeId,
LayersId aOriginatingLayersId,
const FocusTarget& aFocusTarget);
void UpdateHitTestingTree(LayersId aRootLayerTreeId,
Layer* aRoot,
bool aIsFirstPaint,
LayersId aOriginatingLayersId,
uint32_t aPaintSequenceNumber);
- void UpdateHitTestingTree(LayersId aRootLayerTreeId,
- const WebRenderScrollData& aScrollData,
- bool aIsFirstPaint,
- LayersId aOriginatingLayersId,
- uint32_t aPaintSequenceNumber);
+ /**
+ * This should be called (in the WR-enabled case) when the compositor receives
+ * a new WebRenderScrollData for a layers id. The |aScrollData| parameter is
+ * the scroll data for |aOriginatingLayersId|. This function will store
+ * the new scroll data and update the focus state and hit-testing tree.
+ */
+ void UpdateScrollDataAndTreeState(LayersId aRootLayerTreeId,
+ LayersId aOriginatingLayersId,
+ WebRenderScrollData&& aScrollData);
void NotifyLayerTreeAdopted(LayersId aLayersId,
const RefPtr<APZUpdater>& aOldUpdater);
void NotifyLayerTreeRemoved(LayersId aLayersId);
bool GetAPZTestData(LayersId aLayersId, APZTestData* aOutData);
void SetTestAsyncScrollOffset(LayersId aLayersId,
const FrameMetrics::ViewID& aScrollId,
const CSSPoint& aOffset);
void SetTestAsyncZoom(LayersId aLayersId,
const FrameMetrics::ViewID& aScrollId,
const LayerToParentLayerScale& aZoom);
+ // This can only be called on the updater thread.
+ const WebRenderScrollData* GetScrollData(LayersId aLayersId) const;
+
/**
* This can be used to assert that the current thread is the
* updater thread (which samples the async transform).
* This does nothing if thread assertions are disabled.
*/
- void AssertOnUpdaterThread();
+ void AssertOnUpdaterThread() const;
/**
* Runs the given task on the APZ "updater thread" for this APZUpdater. If
* this function is called from the updater thread itself then the task is
* run immediately without getting queued.
*/
void RunOnUpdaterThread(already_AddRefed<Runnable> aTask);
/**
* Returns true if currently on the APZUpdater's "updater thread".
*/
- bool IsUpdaterThread();
+ bool IsUpdaterThread() const;
/**
* Dispatches the given task to the APZ "controller thread", but does it *from*
* the updater thread. That is, if the thread on which this function is called
* is not the updater thread, the task is first dispatched to the updater thread.
* When the updater thread runs it (or if this is called directly on the updater
* thread), that is when the task gets dispatched to the controller thread.
* The controller thread then actually runs the task.
@@ -116,16 +124,22 @@ protected:
virtual ~APZUpdater();
bool UsingWebRenderUpdaterThread() const;
static already_AddRefed<APZUpdater> GetUpdater(const wr::WrWindowId& aWindowId);
private:
RefPtr<APZCTreeManager> mApz;
+ // Map from layers id to WebRenderScrollData. This can only be touched on
+ // the updater thread.
+ std::unordered_map<LayersId,
+ WebRenderScrollData,
+ LayersId::HashFn> mScrollData;
+
// Used to manage the mapping from a WR window id to APZUpdater. These are only
// used if WebRender is enabled. Both sWindowIdMap and mWindowId should only
// be used while holding the sWindowIdLock.
static StaticMutex sWindowIdLock;
static std::unordered_map<uint64_t, APZUpdater*> sWindowIdMap;
Maybe<wr::WrWindowId> mWindowId;
// If WebRender and async scene building are enabled, this holds the thread id
--- a/gfx/layers/apz/src/APZCTreeManager.cpp
+++ b/gfx/layers/apz/src/APZCTreeManager.cpp
@@ -514,25 +514,24 @@ APZCTreeManager::UpdateHitTestingTree(La
LayerMetricsWrapper root(aRoot);
UpdateHitTestingTreeImpl(aRootLayerTreeId, root, aIsFirstPaint,
aOriginatingLayersId, aPaintSequenceNumber);
}
void
APZCTreeManager::UpdateHitTestingTree(LayersId aRootLayerTreeId,
- const WebRenderScrollData& aScrollData,
+ const WebRenderScrollDataWrapper& aScrollWrapper,
bool aIsFirstPaint,
LayersId aOriginatingLayersId,
uint32_t aPaintSequenceNumber)
{
AssertOnUpdaterThread();
- WebRenderScrollDataWrapper wrapper(&aScrollData);
- UpdateHitTestingTreeImpl(aRootLayerTreeId, wrapper, aIsFirstPaint,
+ UpdateHitTestingTreeImpl(aRootLayerTreeId, aScrollWrapper, aIsFirstPaint,
aOriginatingLayersId, aPaintSequenceNumber);
}
bool
APZCTreeManager::PushStateToWR(wr::TransactionBuilder& aTxn,
const TimeStamp& aSampleTime,
nsTArray<wr::WrTransformProperty>& aTransformArray)
{
--- a/gfx/layers/apz/src/APZCTreeManager.h
+++ b/gfx/layers/apz/src/APZCTreeManager.h
@@ -52,17 +52,17 @@ class OverscrollHandoffChain;
struct OverscrollHandoffState;
class FocusTarget;
struct FlingHandoffState;
struct ScrollableLayerGuidHash;
class LayerMetricsWrapper;
class InputQueue;
class GeckoContentController;
class HitTestingTreeNode;
-class WebRenderScrollData;
+class WebRenderScrollDataWrapper;
struct AncestorTransform;
struct ScrollThumbData;
/**
* ****************** NOTE ON LOCK ORDERING IN APZ **************************
*
* There are two main kinds of locks used by APZ: APZCTreeManager::mTreeLock
* ("the tree lock") and AsyncPanZoomController::mRecursiveMutex ("APZC locks").
@@ -184,17 +184,17 @@ public:
/**
* Same as the above UpdateHitTestingTree, except slightly modified to take
* the scrolling data passed over PWebRenderBridge instead of the raw layer
* tree. This version is used when WebRender is enabled because we don't have
* shadow layers in that scenario.
*/
void UpdateHitTestingTree(LayersId aRootLayerTreeId,
- const WebRenderScrollData& aScrollData,
+ const WebRenderScrollDataWrapper& aScrollWrapper,
bool aIsFirstPaint,
LayersId aOriginatingLayersId,
uint32_t aPaintSequenceNumber);
/**
* Called when webrender is enabled, from the sampler thread. This function
* walks through the tree of APZC instances and tells webrender about the
* async scroll position. It also advances APZ animations to the specified
--- a/gfx/layers/apz/src/APZSampler.cpp
+++ b/gfx/layers/apz/src/APZSampler.cpp
@@ -141,23 +141,23 @@ APZSampler::HasUnusedAsyncTransform(cons
AsyncPanZoomController* apzc = aLayer.GetApzc();
return apzc
&& !apzc->GetAsyncTransformAppliedToContent()
&& !AsyncTransformComponentMatrix(apzc->GetCurrentAsyncTransform(AsyncPanZoomController::eForCompositing)).IsIdentity();
}
void
-APZSampler::AssertOnSamplerThread()
+APZSampler::AssertOnSamplerThread() const
{
if (APZThreadUtils::GetThreadAssertionsEnabled()) {
MOZ_ASSERT(IsSamplerThread());
}
}
bool
-APZSampler::IsSamplerThread()
+APZSampler::IsSamplerThread() const
{
return CompositorThreadHolder::IsInCompositorThread();
}
} // namespace layers
} // namespace mozilla
--- a/gfx/layers/apz/src/APZUpdater.cpp
+++ b/gfx/layers/apz/src/APZUpdater.cpp
@@ -7,17 +7,17 @@
#include "mozilla/layers/APZUpdater.h"
#include "APZCTreeManager.h"
#include "AsyncPanZoomController.h"
#include "base/task.h"
#include "mozilla/layers/APZThreadUtils.h"
#include "mozilla/layers/CompositorThread.h"
#include "mozilla/layers/SynchronousTask.h"
-#include "mozilla/layers/WebRenderScrollData.h"
+#include "mozilla/layers/WebRenderScrollDataWrapper.h"
#include "mozilla/webrender/WebRenderAPI.h"
#include "mozilla/webrender/WebRenderTypes.h"
namespace mozilla {
namespace layers {
StaticMutex APZUpdater::sWindowIdLock;
std::unordered_map<uint64_t, APZUpdater*> APZUpdater::sWindowIdMap;
@@ -128,43 +128,39 @@ APZUpdater::UpdateHitTestingTree(LayersI
{
MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
AssertOnUpdaterThread();
mApz->UpdateHitTestingTree(aRootLayerTreeId, aRoot, aIsFirstPaint,
aOriginatingLayersId, aPaintSequenceNumber);
}
void
-APZUpdater::UpdateHitTestingTree(LayersId aRootLayerTreeId,
- const WebRenderScrollData& aScrollData,
- bool aIsFirstPaint,
- LayersId aOriginatingLayersId,
- uint32_t aPaintSequenceNumber)
+APZUpdater::UpdateScrollDataAndTreeState(LayersId aRootLayerTreeId,
+ LayersId aOriginatingLayersId,
+ WebRenderScrollData&& aScrollData)
{
MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
- // use the local variable to resolve the function overload.
- auto func = static_cast<void (APZCTreeManager::*)(LayersId,
- const WebRenderScrollData&,
- bool,
- LayersId,
- uint32_t)>
- (&APZCTreeManager::UpdateHitTestingTree);
- RunOnUpdaterThread(NewRunnableMethod<LayersId,
- WebRenderScrollData,
- bool,
- LayersId,
- uint32_t>(
- "APZUpdater::UpdateHitTestingTree",
- mApz,
- func,
- aRootLayerTreeId,
- aScrollData,
- aIsFirstPaint,
- aOriginatingLayersId,
- aPaintSequenceNumber));
+ RefPtr<APZUpdater> self = this;
+ RunOnUpdaterThread(NS_NewRunnableFunction(
+ "APZUpdater::UpdateHitTestingTree",
+ [=,aScrollData=Move(aScrollData)]() {
+ self->mApz->UpdateFocusState(aRootLayerTreeId,
+ aOriginatingLayersId, aScrollData.GetFocusTarget());
+
+ self->mScrollData[aOriginatingLayersId] = aScrollData;
+ auto root = self->mScrollData.find(aRootLayerTreeId);
+ if (root == self->mScrollData.end()) {
+ return;
+ }
+ self->mApz->UpdateHitTestingTree(aRootLayerTreeId,
+ WebRenderScrollDataWrapper(*self, &(root->second)),
+ aScrollData.IsFirstPaint(), aOriginatingLayersId,
+ aScrollData.GetPaintSequenceNumber());
+ }
+ ));
}
void
APZUpdater::NotifyLayerTreeAdopted(LayersId aLayersId,
const RefPtr<APZUpdater>& aOldUpdater)
{
MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
RunOnUpdaterThread(NewRunnableMethod<LayersId, RefPtr<APZCTreeManager>>(
@@ -174,21 +170,24 @@ APZUpdater::NotifyLayerTreeAdopted(Layer
aLayersId,
aOldUpdater ? aOldUpdater->mApz : nullptr));
}
void
APZUpdater::NotifyLayerTreeRemoved(LayersId aLayersId)
{
MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
- RunOnUpdaterThread(NewRunnableMethod<LayersId>(
- "APZUpdater::NotifyLayerTreeRemoved",
- mApz,
- &APZCTreeManager::NotifyLayerTreeRemoved,
- aLayersId));
+ RefPtr<APZUpdater> self = this;
+ RunOnUpdaterThread(NS_NewRunnableFunction(
+ "APZUpdater::NotifyLayerTreeRemoved",
+ [=]() {
+ self->mScrollData.erase(aLayersId);
+ self->mApz->NotifyLayerTreeRemoved(aLayersId);
+ }
+ ));
}
bool
APZUpdater::GetAPZTestData(LayersId aLayersId,
APZTestData* aOutData)
{
MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
@@ -244,18 +243,26 @@ APZUpdater::SetTestAsyncZoom(LayersId aL
apzc->SetTestAsyncZoom(aZoom);
} else {
NS_WARNING("Unable to find APZC in SetTestAsyncZoom");
}
}
));
}
+const WebRenderScrollData*
+APZUpdater::GetScrollData(LayersId aLayersId) const
+{
+ AssertOnUpdaterThread();
+ auto it = mScrollData.find(aLayersId);
+ return (it == mScrollData.end() ? nullptr : &(it->second));
+}
+
void
-APZUpdater::AssertOnUpdaterThread()
+APZUpdater::AssertOnUpdaterThread() const
{
if (APZThreadUtils::GetThreadAssertionsEnabled()) {
MOZ_ASSERT(IsUpdaterThread());
}
}
void
APZUpdater::RunOnUpdaterThread(already_AddRefed<Runnable> aTask)
@@ -295,17 +302,17 @@ APZUpdater::RunOnUpdaterThread(already_A
loop->PostTask(task.forget());
} else {
// Could happen during startup
NS_WARNING("Dropping task posted to updater thread");
}
}
bool
-APZUpdater::IsUpdaterThread()
+APZUpdater::IsUpdaterThread() const
{
if (UsingWebRenderUpdaterThread()) {
return PlatformThread::CurrentId() == *mUpdaterThreadId;
}
return CompositorThreadHolder::IsInCompositorThread();
}
void
--- a/gfx/layers/wr/WebRenderBridgeParent.cpp
+++ b/gfx/layers/wr/WebRenderBridgeParent.cpp
@@ -501,35 +501,38 @@ WebRenderBridgeParent::GetRootCompositor
CompositorBridgeParent::GetIndirectShadowTree(GetLayersId());
if (!lts) {
return nullptr;
}
return lts->mParent;
}
void
-WebRenderBridgeParent::UpdateAPZ(bool aUpdateHitTestingTree)
+WebRenderBridgeParent::UpdateAPZFocusState(const FocusTarget& aFocus)
{
CompositorBridgeParent* cbp = GetRootCompositorBridgeParent();
if (!cbp) {
return;
}
LayersId rootLayersId = cbp->RootLayerTreeId();
- RefPtr<WebRenderBridgeParent> rootWrbp = cbp->GetWebRenderBridgeParent();
- if (!rootWrbp) {
+ if (RefPtr<APZUpdater> apz = cbp->GetAPZUpdater()) {
+ apz->UpdateFocusState(rootLayersId, GetLayersId(), aFocus);
+ }
+}
+
+void
+WebRenderBridgeParent::UpdateAPZScrollData(WebRenderScrollData&& aData)
+{
+ CompositorBridgeParent* cbp = GetRootCompositorBridgeParent();
+ if (!cbp) {
return;
}
+ LayersId rootLayersId = cbp->RootLayerTreeId();
if (RefPtr<APZUpdater> apz = cbp->GetAPZUpdater()) {
- apz->UpdateFocusState(rootLayersId, GetLayersId(),
- mScrollData.GetFocusTarget());
- if (aUpdateHitTestingTree) {
- apz->UpdateHitTestingTree(rootLayersId, rootWrbp->GetScrollData(),
- mScrollData.IsFirstPaint(), GetLayersId(),
- mScrollData.GetPaintSequenceNumber());
- }
+ apz->UpdateScrollDataAndTreeState(rootLayersId, GetLayersId(), Move(aData));
}
}
bool
WebRenderBridgeParent::PushAPZStateToWR(wr::TransactionBuilder& aTxn,
nsTArray<wr::WrTransformProperty>& aTransformArray)
{
CompositorBridgeParent* cbp = GetRootCompositorBridgeParent();
@@ -545,23 +548,16 @@ WebRenderBridgeParent::PushAPZStateToWR(
if (frameInterval != TimeDuration::Forever()) {
animationTime += frameInterval;
}
return apz->PushStateToWR(aTxn, animationTime, aTransformArray);
}
return false;
}
-const WebRenderScrollData&
-WebRenderBridgeParent::GetScrollData() const
-{
- MOZ_ASSERT(mozilla::layers::CompositorThreadHolder::IsInCompositorThread());
- return mScrollData;
-}
-
mozilla::ipc::IPCResult
WebRenderBridgeParent::RecvSetDisplayList(const gfx::IntSize& aSize,
InfallibleTArray<WebRenderParentCommand>&& aCommands,
InfallibleTArray<OpDestroy>&& aToDestroy,
const uint64_t& aFwdTransactionId,
const uint64_t& aTransactionId,
const wr::LayoutSize& aContentSize,
ipc::ByteBuf&& dl,
@@ -623,18 +619,21 @@ WebRenderBridgeParent::RecvSetDisplayLis
if (ShouldParentObserveEpoch()) {
mCompositorBridge->ObserveLayerUpdate(GetLayersId(), GetChildLayerObserverEpoch(), true);
}
}
HoldPendingTransactionId(wrEpoch, aTransactionId, aTxnStartTime, aFwdTime);
- mScrollData = aScrollData;
- UpdateAPZ(true);
+ // aScrollData is moved into this function but that is not reflected by the
+ // function signature due to the way the IPDL generator works. We remove the
+ // const so that we can move this structure all the way to the desired
+ // destination.
+ UpdateAPZScrollData(Move(const_cast<WebRenderScrollData&>(aScrollData)));
if (mIdNamespace != aIdNamespace) {
// Pretend we composited since someone is wating for this event,
// though DisplayList was not pushed to webrender.
TimeStamp now = TimeStamp::Now();
mCompositorBridge->DidComposite(GetLayersId(), now, now);
}
@@ -668,18 +667,17 @@ WebRenderBridgeParent::RecvEmptyTransact
AutoWebRenderBridgeParentAsyncMessageSender autoAsyncMessageSender(this, &aToDestroy);
if (!aCommands.IsEmpty()) {
mAsyncImageManager->SetCompositionTime(TimeStamp::Now());
ProcessWebRenderParentCommands(aCommands);
ScheduleGenerateFrame();
}
- mScrollData.SetFocusTarget(aFocusTarget);
- UpdateAPZ(false);
+ UpdateAPZFocusState(aFocusTarget);
if (!aCommands.IsEmpty()) {
wr::TransactionBuilder txn;
wr::Epoch wrEpoch = GetNextWrEpoch();
txn.UpdateEpoch(mPipelineId, wrEpoch);
mApi->SendTransaction(txn);
HoldPendingTransactionId(wrEpoch, aTransactionId, aTxnStartTime, aFwdTime);
@@ -698,18 +696,17 @@ WebRenderBridgeParent::RecvEmptyTransact
}
return IPC_OK();
}
mozilla::ipc::IPCResult
WebRenderBridgeParent::RecvSetFocusTarget(const FocusTarget& aFocusTarget)
{
- mScrollData.SetFocusTarget(aFocusTarget);
- UpdateAPZ(false);
+ UpdateAPZFocusState(aFocusTarget);
return IPC_OK();
}
mozilla::ipc::IPCResult
WebRenderBridgeParent::RecvParentCommands(nsTArray<WebRenderParentCommand>&& aCommands)
{
if (mDestroyed) {
return IPC_OK();
--- a/gfx/layers/wr/WebRenderBridgeParent.h
+++ b/gfx/layers/wr/WebRenderBridgeParent.h
@@ -165,18 +165,18 @@ public:
void ExtractImageCompositeNotifications(nsTArray<ImageCompositeNotificationInfo>* aNotifications);
wr::IdNamespace GetIdNamespace()
{
return mIdNamespace;
}
- void UpdateAPZ(bool aUpdateHitTestingTree);
- const WebRenderScrollData& GetScrollData() const;
+ void UpdateAPZFocusState(const FocusTarget& aFocus);
+ void UpdateAPZScrollData(WebRenderScrollData&& aData);
void FlushRendering();
void FlushRenderingAsync();
/**
* Schedule generating WebRender frame definitely at next composite timing.
*
* WebRenderBridgeParent uses composite timing to check if there is an update
@@ -266,17 +266,14 @@ private:
std::queue<PendingTransactionId> mPendingTransactionIds;
wr::Epoch mWrEpoch;
wr::IdNamespace mIdNamespace;
bool mPaused;
bool mDestroyed;
bool mForceRendering;
bool mReceivedDisplayList;
-
- // Can only be accessed on the compositor thread.
- WebRenderScrollData mScrollData;
};
} // namespace layers
} // namespace mozilla
#endif // mozilla_layers_WebRenderBridgeParent_h
--- a/gfx/layers/wr/WebRenderScrollDataWrapper.h
+++ b/gfx/layers/wr/WebRenderScrollDataWrapper.h
@@ -39,18 +39,20 @@ namespace layers {
* This class being declared a MOZ_STACK_CLASS should help with that.
*
* Refer to LayerMetricsWrapper.h for actual documentation on the exposed API.
*/
class MOZ_STACK_CLASS WebRenderScrollDataWrapper {
public:
// Basic constructor for external callers. Starts the walker at the root of
// the tree.
- explicit WebRenderScrollDataWrapper(const WebRenderScrollData* aData = nullptr)
- : mData(aData)
+ explicit WebRenderScrollDataWrapper(const APZUpdater& aUpdater,
+ const WebRenderScrollData* aData = nullptr)
+ : mUpdater(&aUpdater)
+ , mData(aData)
, mLayerIndex(0)
, mContainingSubtreeLastIndex(0)
, mLayer(nullptr)
, mMetadataIndex(0)
{
if (!mData) {
return;
}
@@ -70,20 +72,22 @@ public:
mMetadataIndex--;
}
}
private:
// Internal constructor for walking from one WebRenderLayerScrollData to
// another. In this case we need to recompute the mMetadataIndex to be the
// "topmost" scroll metadata on the new layer.
- WebRenderScrollDataWrapper(const WebRenderScrollData* aData,
+ WebRenderScrollDataWrapper(const APZUpdater* aUpdater,
+ const WebRenderScrollData* aData,
size_t aLayerIndex,
size_t aContainingSubtreeLastIndex)
- : mData(aData)
+ : mUpdater(aUpdater)
+ , mData(aData)
, mLayerIndex(aLayerIndex)
, mContainingSubtreeLastIndex(aContainingSubtreeLastIndex)
, mLayer(nullptr)
, mMetadataIndex(0)
{
MOZ_ASSERT(mData);
mLayer = mData->GetLayerData(mLayerIndex);
MOZ_ASSERT(mLayer);
@@ -93,22 +97,24 @@ private:
mMetadataIndex = mLayer->GetScrollMetadataCount();
if (mMetadataIndex > 0) {
mMetadataIndex--;
}
}
// Internal constructor for walking from one metadata to another metadata on
// the same WebRenderLayerScrollData.
- WebRenderScrollDataWrapper(const WebRenderScrollData* aData,
+ WebRenderScrollDataWrapper(const APZUpdater* aUpdater,
+ const WebRenderScrollData* aData,
size_t aLayerIndex,
size_t aContainingSubtreeLastIndex,
const WebRenderLayerScrollData* aLayer,
uint32_t aMetadataIndex)
- : mData(aData)
+ : mUpdater(aUpdater)
+ , mData(aData)
, mLayerIndex(aLayerIndex)
, mContainingSubtreeLastIndex(aContainingSubtreeLastIndex)
, mLayer(aLayer)
, mMetadataIndex(aMetadataIndex)
{
MOZ_ASSERT(mData);
MOZ_ASSERT(mLayer);
MOZ_ASSERT(mLayer == mData->GetLayerData(mLayerIndex));
@@ -129,66 +135,63 @@ public:
WebRenderScrollDataWrapper GetLastChild() const
{
MOZ_ASSERT(IsValid());
if (!AtBottomLayer()) {
// If we're still walking around in the virtual container layers created
// by the ScrollMetadata array, we just need to update the metadata index
// and that's it.
- return WebRenderScrollDataWrapper(mData, mLayerIndex,
+ return WebRenderScrollDataWrapper(mUpdater, mData, mLayerIndex,
mContainingSubtreeLastIndex, mLayer, mMetadataIndex - 1);
}
// Otherwise, we need to walk to a different WebRenderLayerScrollData in
// mData.
// Since mData contains the layer in depth-first, last-to-first order,
// the index after mLayerIndex must be mLayerIndex's last child, if it
// has any children (indicated by GetDescendantCount() > 0). Furthermore
// we compute the first index outside the subtree rooted at this node
// (in |subtreeLastIndex|) and pass that in to the child wrapper to use as
// its mContainingSubtreeLastIndex.
if (mLayer->GetDescendantCount() > 0) {
size_t prevSiblingIndex = mLayerIndex + 1 + mLayer->GetDescendantCount();
size_t subtreeLastIndex = std::min(mContainingSubtreeLastIndex, prevSiblingIndex);
- return WebRenderScrollDataWrapper(mData, mLayerIndex + 1, subtreeLastIndex);
+ return WebRenderScrollDataWrapper(mUpdater, mData, mLayerIndex + 1, subtreeLastIndex);
}
// We've run out of descendants. But! If the original layer was a RefLayer,
// then it connects to another layer tree and we need to traverse that too.
// So return a WebRenderScrollDataWrapper for the root of the child layer
// tree.
if (mLayer->GetReferentId()) {
- CompositorBridgeParent::LayerTreeState* lts =
- CompositorBridgeParent::GetIndirectShadowTree(mLayer->GetReferentId().value());
- if (lts && lts->mWrBridge) {
- return WebRenderScrollDataWrapper(&(lts->mWrBridge->GetScrollData()));
- }
+ return WebRenderScrollDataWrapper(*mUpdater,
+ mUpdater->GetScrollData(*mLayer->GetReferentId()));
}
- return WebRenderScrollDataWrapper();
+ return WebRenderScrollDataWrapper(*mUpdater);
}
WebRenderScrollDataWrapper GetPrevSibling() const
{
MOZ_ASSERT(IsValid());
if (!AtTopLayer()) {
// The virtual container layers don't have siblings
- return WebRenderScrollDataWrapper();
+ return WebRenderScrollDataWrapper(*mUpdater);
}
// Skip past the descendants to get to the previous sibling. However, we
// might be at the last sibling already.
size_t prevSiblingIndex = mLayerIndex + 1 + mLayer->GetDescendantCount();
if (prevSiblingIndex < mContainingSubtreeLastIndex) {
- return WebRenderScrollDataWrapper(mData, prevSiblingIndex, mContainingSubtreeLastIndex);
+ return WebRenderScrollDataWrapper(mUpdater, mData, prevSiblingIndex, mContainingSubtreeLastIndex);
}
- return WebRenderScrollDataWrapper();
+ return WebRenderScrollDataWrapper(*mUpdater);
}
const ScrollMetadata& Metadata() const
{
MOZ_ASSERT(IsValid());
if (mMetadataIndex >= mLayer->GetScrollMetadataCount()) {
return *ScrollMetadata::sNullMetadata;
@@ -335,16 +338,17 @@ private:
}
bool AtTopLayer() const
{
return mLayer->GetScrollMetadataCount() == 0 || mMetadataIndex == mLayer->GetScrollMetadataCount() - 1;
}
private:
+ const APZUpdater* mUpdater;
const WebRenderScrollData* mData;
// The index (in mData->mLayerScrollData) of the WebRenderLayerScrollData this
// wrapper is pointing to.
size_t mLayerIndex;
// The upper bound on the set of valid indices inside the subtree rooted at
// the parent of this "layer". That is, any layer index |i| in the range
// mLayerIndex <= i < mContainingSubtreeLastIndex is guaranteed to point to
// a layer that is a descendant of "parent", where "parent" is the parent