Bug 1441916 - Add hooks in APZCTreeManager to respond to layer tree changes. r?botond draft
authorKartikaya Gupta <kgupta@mozilla.com>
Thu, 01 Mar 2018 23:00:40 -0500
changeset 762496 c5aab9cea999c0727ec2379cd36f8e3d9334c6bd
parent 761174 9b69507f6511d1b23cbbe515d03a1750cf5156d3
child 762497 1d4b6bca069b32e4e075512d84dd261676355292
push id101178
push userkgupta@mozilla.com
push dateFri, 02 Mar 2018 13:48:39 +0000
reviewersbotond
bugs1441916
milestone60.0a1
Bug 1441916 - Add hooks in APZCTreeManager to respond to layer tree changes. r?botond MozReview-Commit-ID: 4dDYQ1YGOO
gfx/layers/apz/src/APZCTreeManager.cpp
gfx/layers/apz/src/APZCTreeManager.h
gfx/layers/ipc/CompositorBridgeParent.cpp
--- a/gfx/layers/apz/src/APZCTreeManager.cpp
+++ b/gfx/layers/apz/src/APZCTreeManager.cpp
@@ -259,16 +259,29 @@ APZCTreeManager::~APZCTreeManager()
 
 /*static*/ void
 APZCTreeManager::InitializeGlobalState()
 {
   MOZ_ASSERT(NS_IsMainThread());
   AsyncPanZoomController::InitializeGlobalState();
 }
 
+void
+APZCTreeManager::NotifyLayerTreeAdopted(uint64_t aLayersId,
+                                        const RefPtr<APZCTreeManager>& aOldApzcTreeManager)
+{
+  APZThreadUtils::AssertOnCompositorThread();
+}
+
+void
+APZCTreeManager::NotifyLayerTreeRemoved(uint64_t aLayersId)
+{
+  APZThreadUtils::AssertOnCompositorThread();
+}
+
 AsyncPanZoomController*
 APZCTreeManager::NewAPZCInstance(uint64_t aLayersId,
                                  GeckoContentController* aController)
 {
   return new AsyncPanZoomController(aLayersId, this, mInputQueue,
     aController, AsyncPanZoomController::USE_GESTURE_DETECTOR);
 }
 
--- a/gfx/layers/apz/src/APZCTreeManager.h
+++ b/gfx/layers/apz/src/APZCTreeManager.h
@@ -113,16 +113,36 @@ public:
    * 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();
 
   /**
+   * Notifies this APZCTreeManager that the associated compositor is now
+   * responsible for managing another layers id, which got moved over from
+   * some other compositor. That other compositor's APZCTreeManager is also
+   * provided. This allows APZCTreeManager to transfer any necessary state
+   * from the old APZCTreeManager related to that layers id.
+   * This function must be called on the compositor thread.
+   */
+  void NotifyLayerTreeAdopted(uint64_t aLayersId,
+                              const RefPtr<APZCTreeManager>& aOldTreeManager);
+
+  /**
+   * Notifies this APZCTreeManager that a layer tree being managed by the
+   * associated compositor has been removed/destroyed. Note that this does
+   * NOT get called during shutdown situations, when the root layer tree is
+   * also getting destroyed.
+   * This function must be called on the compositor thread.
+   */
+  void NotifyLayerTreeRemoved(uint64_t aLayersId);
+
+  /**
    * Rebuild the focus state based on the focus target from the layer tree update
    * that just occurred.
    *
    * @param aRootLayerTreeId The layer tree ID of the root layer corresponding
    *                         to this APZCTreeManager
    * @param aOriginatingLayersId The layer tree ID of the layer corresponding to
    *                             this layer tree update.
    */
--- a/gfx/layers/ipc/CompositorBridgeParent.cpp
+++ b/gfx/layers/ipc/CompositorBridgeParent.cpp
@@ -1655,22 +1655,24 @@ CompositorBridgeParent::RecvMapAndNotify
   NotifyChildCreated(aChild);
   *aOptions = mOptions;
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult
 CompositorBridgeParent::RecvAdoptChild(const uint64_t& child)
 {
+  RefPtr<APZCTreeManager> oldApzcTreeManager;
   APZCTreeManagerParent* parent;
   {
     MonitorAutoLock lock(*sIndirectLayerTreesLock);
     // We currently don't support adopting children from one compositor to
     // another if the two compositors don't have the same options.
     MOZ_ASSERT(sIndirectLayerTrees[child].mParent->mOptions == mOptions);
+    oldApzcTreeManager = sIndirectLayerTrees[child].mParent->mApzcTreeManager;
     NotifyChildCreated(child);
     if (sIndirectLayerTrees[child].mLayerTree) {
       sIndirectLayerTrees[child].mLayerTree->SetLayerManager(mLayerManager, GetAnimationStorage());
       // Trigger composition to handle a case that mLayerTree was not composited yet
       // by previous CompositorBridgeParent, since nsRefreshDriver might wait composition complete.
       ScheduleComposition();
     }
     if (mWrBridge && sIndirectLayerTrees[child].mWrBridge) {
@@ -1685,18 +1687,25 @@ CompositorBridgeParent::RecvAdoptChild(c
       if (cpcp) {
         TimeStamp now = TimeStamp::Now();
         cpcp->DidCompositeLocked(child, now, now);
       }
     }
     parent = sIndirectLayerTrees[child].mApzcTreeManagerParent;
   }
 
-  if (mApzcTreeManager && parent) {
-    parent->ChildAdopted(mApzcTreeManager);
+  // We don't support moving a child from a APZ-enabled compositor to a
+  // APZ-disabled compostior. The mOptions assertion above should already
+  // ensure this, since APZ-ness is one of the things in mOptions.
+  MOZ_ASSERT((oldApzcTreeManager != nullptr) == (mApzcTreeManager != nullptr));
+  if (mApzcTreeManager) {
+    if (parent) {
+      parent->ChildAdopted(mApzcTreeManager);
+    }
+    mApzcTreeManager->NotifyLayerTreeAdopted(child, oldApzcTreeManager);
   }
   return IPC_OK();
 }
 
 PWebRenderBridgeParent*
 CompositorBridgeParent::AllocPWebRenderBridgeParent(const wr::PipelineId& aPipelineId,
                                                     const LayoutDeviceIntSize& aSize,
                                                     TextureFactoryIdentifier* aTextureFactoryIdentifier,
@@ -1779,16 +1788,19 @@ EraseLayerState(uint64_t aId)
 {
   MonitorAutoLock lock(*sIndirectLayerTreesLock);
 
   auto iter = sIndirectLayerTrees.find(aId);
   if (iter != sIndirectLayerTrees.end()) {
     CompositorBridgeParent* parent = iter->second.mParent;
     if (parent) {
       parent->ClearApproximatelyVisibleRegions(aId, Nothing());
+      if (RefPtr<APZCTreeManager> apzctm = parent->GetAPZCTreeManager()) {
+        apzctm->NotifyLayerTreeRemoved(aId);
+      }
     }
 
     sIndirectLayerTrees.erase(iter);
   }
 }
 
 /*static*/ void
 CompositorBridgeParent::DeallocateLayerTreeId(uint64_t aId)