Bug 1417519 - Add a mechanism for APZ to get the WebRenderAPI instance. r?botond
MozReview-Commit-ID: FhdQhKIfQbw
--- a/gfx/layers/apz/src/APZCTreeManager.cpp
+++ b/gfx/layers/apz/src/APZCTreeManager.cpp
@@ -212,18 +212,19 @@ private:
APZCTreeManager::CalculatePendingDisplayPort(
const FrameMetrics& aFrameMetrics,
const ParentLayerPoint& aVelocity)
{
return AsyncPanZoomController::CalculatePendingDisplayPort(
aFrameMetrics, aVelocity);
}
-APZCTreeManager::APZCTreeManager()
+APZCTreeManager::APZCTreeManager(uint64_t aRootLayersId)
: mInputQueue(new InputQueue()),
+ mRootLayersId(aRootLayersId),
mTreeLock("APZCTreeLock"),
mHitResultForInputBlock(HitNothing),
mRetainedTouchIdentifier(-1),
mInScrollbarTouchDrag(false),
mApzcTreeLog("apzctree")
{
RefPtr<APZCTreeManager> self(this);
NS_DispatchToMainThread(
@@ -448,16 +449,17 @@ APZCTreeManager::UpdateHitTestingTree(ui
bool
APZCTreeManager::PushStateToWR(wr::WebRenderAPI* aWrApi,
const TimeStamp& aSampleTime,
nsTArray<wr::WrTransformProperty>& aTransformArray)
{
APZThreadUtils::AssertOnCompositorThread();
MOZ_ASSERT(aWrApi);
+ MOZ_ASSERT(aWrApi == RefPtr<wr::WebRenderAPI>(GetWebRenderAPI()).get());
MutexAutoLock lock(mTreeLock);
// During the first pass through the tree, we build a cache of guid->HTTN so
// that we can find the relevant APZC instances quickly in subsequent passes,
// such as the one below to generate scrollbar transforms. Without this, perf
// could end up being O(n^2) instead of O(n log n) because we'd have to search
// the tree to find the corresponding APZC every time we hit a thumb node.
@@ -2732,16 +2734,28 @@ APZCTreeManager::ComputeTransformForNode
nullptr);
});
}
}
// Otherwise, the node does not have an async transform.
return aNode->GetTransform() * AsyncTransformMatrix();
}
+already_AddRefed<wr::WebRenderAPI>
+APZCTreeManager::GetWebRenderAPI() const
+{
+ RefPtr<wr::WebRenderAPI> api;
+ if (LayerTreeState* state = CompositorBridgeParent::GetIndirectShadowTree(mRootLayersId)) {
+ if (state->mWrBridge) {
+ api = state->mWrBridge->GetWebRenderAPI();
+ }
+ }
+ return api.forget();
+}
+
#if defined(MOZ_WIDGET_ANDROID)
void
APZCTreeManager::InitializeDynamicToolbarAnimator(const int64_t& aRootLayerTreeId)
{
MOZ_ASSERT(mToolbarAnimator);
mToolbarAnimator->Initialize(aRootLayerTreeId);
}
--- a/gfx/layers/apz/src/APZCTreeManager.h
+++ b/gfx/layers/apz/src/APZCTreeManager.h
@@ -99,17 +99,17 @@ class APZCTreeManager : public IAPZCTree
// Helper struct to hold some state while we build the hit-testing tree. The
// sole purpose of this struct is to shorten the argument list to
// UpdateHitTestingTree. All the state that we don't need to
// push on the stack during recursion and pop on unwind is stored here.
struct TreeBuildingState;
public:
- APZCTreeManager();
+ explicit APZCTreeManager(uint64_t aRootLayersId);
/**
* Initializes the global state used in AsyncPanZoomController.
* This is normally called when it is first needed in the constructor
* of APZCTreeManager, but can be called manually to force it to be
* initialized earlier.
*/
static void InitializeGlobalState();
@@ -606,23 +606,30 @@ private:
const AsyncPanZoomController* apzc);
void NotifyScrollbarDragRejected(const ScrollableLayerGuid& aGuid) const;
void NotifyAutoscrollRejected(const ScrollableLayerGuid& aGuid) const;
// Requires the caller to hold mTreeLock.
LayerToParentLayerMatrix4x4 ComputeTransformForNode(const HitTestingTreeNode* aNode) const;
+ // Returns a pointer to the WebRenderAPI for the root layers id this APZCTreeManager
+ // is for. This might be null (for example, if WebRender is not enabled).
+ already_AddRefed<wr::WebRenderAPI> GetWebRenderAPI() const;
+
protected:
/* The input queue where input events are held until we know enough to
* figure out where they're going. Protected so gtests can access it.
*/
RefPtr<InputQueue> mInputQueue;
private:
+ /* Layers id for the root CompositorBridgeParent that owns this APZCTreeManager. */
+ uint64_t mRootLayersId;
+
/* Whenever walking or mutating the tree rooted at mRootNode, mTreeLock must be held.
* This lock does not need to be held while manipulating a single APZC instance in
* isolation (that is, if its tree pointers are not being accessed or mutated). The
* lock also needs to be held when accessing the mRootNode instance variable, as that
* is considered part of the APZC tree management state.
* Finally, the lock needs to be held when accessing mZoomConstraints.
* IMPORTANT: See the note about lock ordering at the top of this file. */
mutable mozilla::Mutex mTreeLock;
--- a/gfx/layers/apz/test/gtest/APZTestCommon.h
+++ b/gfx/layers/apz/test/gtest/APZTestCommon.h
@@ -167,17 +167,20 @@ private:
// The following array is sorted by timestamp (tasks are inserted in order by
// timestamp).
nsTArray<std::pair<RefPtr<Runnable>, TimeStamp>> mTaskQueue;
TimeStamp mTime;
};
class TestAPZCTreeManager : public APZCTreeManager {
public:
- explicit TestAPZCTreeManager(MockContentControllerDelayed* aMcc) : mcc(aMcc) {}
+ explicit TestAPZCTreeManager(MockContentControllerDelayed* aMcc)
+ : APZCTreeManager(0)
+ , mcc(aMcc)
+ {}
RefPtr<InputQueue> GetInputQueue() const {
return mInputQueue;
}
void ClearContentController() {
mcc = nullptr;
}
--- a/gfx/layers/ipc/CompositorBridgeParent.cpp
+++ b/gfx/layers/ipc/CompositorBridgeParent.cpp
@@ -351,17 +351,17 @@ CompositorBridgeParent::InitSameProcess(
const uint64_t& aLayerTreeId)
{
MOZ_ASSERT(XRE_IsParentProcess());
MOZ_ASSERT(NS_IsMainThread());
mWidget = aWidget;
mRootLayerTreeID = aLayerTreeId;
if (mOptions.UseAPZ()) {
- mApzcTreeManager = new APZCTreeManager();
+ mApzcTreeManager = new APZCTreeManager(mRootLayerTreeID);
}
Initialize();
}
mozilla::ipc::IPCResult
CompositorBridgeParent::RecvInitialize(const uint64_t& aRootLayerTreeId)
{
@@ -1122,17 +1122,17 @@ CompositorBridgeParent::AllocPAPZCTreeMa
// We should only ever get this if APZ is enabled in this compositor.
MOZ_ASSERT(mOptions.UseAPZ());
// The main process should pass in 0 because we assume mRootLayerTreeID
MOZ_ASSERT(aLayersId == 0);
// This message doubles as initialization
MOZ_ASSERT(!mApzcTreeManager);
- mApzcTreeManager = new APZCTreeManager();
+ mApzcTreeManager = new APZCTreeManager(mRootLayerTreeID);
MonitorAutoLock lock(*sIndirectLayerTreesLock);
CompositorBridgeParent::LayerTreeState& state = sIndirectLayerTrees[mRootLayerTreeID];
MOZ_ASSERT(state.mParent);
MOZ_ASSERT(!state.mApzcTreeManagerParent);
state.mApzcTreeManagerParent = new APZCTreeManagerParent(mRootLayerTreeID, state.mParent->GetAPZCTreeManager());
return state.mApzcTreeManagerParent;
--- a/gfx/layers/ipc/CrossProcessCompositorBridgeParent.cpp
+++ b/gfx/layers/ipc/CrossProcessCompositorBridgeParent.cpp
@@ -126,17 +126,17 @@ CrossProcessCompositorBridgeParent::Allo
CompositorBridgeParent::LayerTreeState& state = sIndirectLayerTrees[aLayersId];
// If the widget has shutdown its compositor, we may not have had a chance yet
// to unmap our layers id, and we could get here without a parent compositor.
// In this case return an empty APZCTM.
if (!state.mParent) {
// Note: we immediately call ClearTree since otherwise the APZCTM will
// retain a reference to itself, through the checkerboard observer.
- RefPtr<APZCTreeManager> temp = new APZCTreeManager();
+ RefPtr<APZCTreeManager> temp = new APZCTreeManager(0);
temp->ClearTree();
return new APZCTreeManagerParent(aLayersId, temp);
}
MOZ_ASSERT(!state.mApzcTreeManagerParent);
state.mApzcTreeManagerParent = new APZCTreeManagerParent(aLayersId, state.mParent->GetAPZCTreeManager());
return state.mApzcTreeManagerParent;