Bug 923482 - Fix an edge case where we might try to re-use a destroyed APZC instance. r=botond
authorKartikaya Gupta <kgupta@mozilla.com>
Fri, 25 Oct 2013 11:30:17 +0200
changeset 166946 48118186773bd5e16820a52e13a203ff6fd718b3
parent 166945 cefbd9f9a42e62cb03766bf673a38b2d3e0603f7
child 166947 d3faadae49e8887125a27d36870d8fef555cd085
push id428
push userbbajaj@mozilla.com
push dateTue, 28 Jan 2014 00:16:25 +0000
treeherdermozilla-release@cd72a7ff3a75 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbotond
bugs923482
milestone27.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 923482 - Fix an edge case where we might try to re-use a destroyed APZC instance. r=botond
gfx/layers/composite/APZCTreeManager.cpp
gfx/layers/ipc/AsyncPanZoomController.cpp
gfx/layers/ipc/AsyncPanZoomController.h
--- a/gfx/layers/composite/APZCTreeManager.cpp
+++ b/gfx/layers/composite/APZCTreeManager.cpp
@@ -112,17 +112,21 @@ APZCTreeManager::UpdatePanZoomController
       const CompositorParent::LayerTreeState* state = CompositorParent::GetIndirectShadowTree(aLayersId);
       if (state && state->mController.get()) {
         // If we get here, aLayer is a scrollable container layer and somebody
         // has registered a GeckoContentController for it, so we need to ensure
         // it has an APZC instance to manage its scrolling.
 
         apzc = container->GetAsyncPanZoomController();
 
-        bool newApzc = (apzc == nullptr);
+        // The APZC we get off the layer may have been destroyed previously if the layer was inactive
+        // or omitted from the layer tree for whatever reason from a layers update. If it later comes
+        // back it will have a reference to a destroyed APZC and so we need to throw that out and make
+        // a new one.
+        bool newApzc = (apzc == nullptr || apzc->IsDestroyed());
         if (newApzc) {
           apzc = new AsyncPanZoomController(aLayersId, this, state->mController,
                                             AsyncPanZoomController::USE_GESTURE_DETECTOR);
           apzc->SetCompositorParent(aCompositor);
         } else {
           // If there was already an APZC for the layer clear the tree pointers
           // so that it doesn't continue pointing to APZCs that should no longer
           // be in the tree. These pointers will get reset properly as we continue
--- a/gfx/layers/ipc/AsyncPanZoomController.cpp
+++ b/gfx/layers/ipc/AsyncPanZoomController.cpp
@@ -321,16 +321,22 @@ AsyncPanZoomController::Destroy()
     mGestureEventListener = nullptr;
   }
   mPrevSibling = nullptr;
   mLastChild = nullptr;
   mParent = nullptr;
   mTreeManager = nullptr;
 }
 
+bool
+AsyncPanZoomController::IsDestroyed()
+{
+  return mTreeManager == nullptr;
+}
+
 /* static */float
 AsyncPanZoomController::GetTouchStartTolerance()
 {
   return gTouchStartTolerance;
 }
 
 /* static */AsyncPanZoomController::AxisLockMode AsyncPanZoomController::GetAxisLockMode()
 {
--- a/gfx/layers/ipc/AsyncPanZoomController.h
+++ b/gfx/layers/ipc/AsyncPanZoomController.h
@@ -199,16 +199,21 @@ public:
 
   /**
    * Shut down the controller/UI thread state and prepare to be
    * deleted (which may happen from any thread).
    */
   void Destroy();
 
   /**
+   * Returns true if Destroy() has already been called on this APZC instance.
+   */
+  bool IsDestroyed();
+
+  /**
    * Returns the incremental transformation corresponding to the async pan/zoom
    * in progress. That is, when this transform is multiplied with the layer's
    * existing transform, it will make the layer appear with the desired pan/zoom
    * amount.
    */
   ViewTransform GetCurrentAsyncTransform();
 
   /**