Bug 1443436 - Don't use a raw pointer owned by the compositor thread on the controller thread. r=rbarker, a=jcristau
authorKartikaya Gupta <kgupta@mozilla.com>
Mon, 07 May 2018 08:05:43 -0400
changeset 802220 5a7eef7de073ad8b0405ee3903290f617eda10eb
parent 802219 d8b664cb3708d96b3c4f9fad8ec866a6892ce6b4
child 802221 c3f38f9d316e1159bd7716f8a35f13bebc51c707
push id111850
push userbmo:tom@mozilla.com
push dateThu, 31 May 2018 16:41:37 +0000
reviewersrbarker, jcristau
bugs1443436
milestone60.0.2
Bug 1443436 - Don't use a raw pointer owned by the compositor thread on the controller thread. r=rbarker, a=jcristau
gfx/layers/apz/src/APZCTreeManager.cpp
gfx/layers/apz/src/AndroidDynamicToolbarAnimator.cpp
gfx/layers/apz/src/AndroidDynamicToolbarAnimator.h
--- a/gfx/layers/apz/src/APZCTreeManager.cpp
+++ b/gfx/layers/apz/src/APZCTreeManager.cpp
@@ -1107,17 +1107,18 @@ APZCTreeManager::ReceiveInputEvent(Input
   {
     RecursiveMutexAutoLock lock(mTreeLock);
     RefPtr<AsyncPanZoomController> apzc = FindRootContentOrRootApzc();
     if (apzc) {
       scrollOffset = ViewAs<ScreenPixel>(apzc->GetCurrentAsyncScrollOffset(AsyncPanZoomController::eForHitTesting),
                                          PixelCastJustification::ScreenIsParentLayerForRoot);
     }
   }
-  nsEventStatus isConsumed = mToolbarAnimator->ReceiveInputEvent(aEvent, scrollOffset);
+  RefPtr<APZCTreeManager> self = this;
+  nsEventStatus isConsumed = mToolbarAnimator->ReceiveInputEvent(self, aEvent, scrollOffset);
   // Check if the mToolbarAnimator consumed the event.
   if (isConsumed == nsEventStatus_eConsumeNoDefault) {
     APZCTM_LOG("Dynamic toolbar consumed event");
     return isConsumed;
   }
 #endif // (MOZ_WIDGET_ANDROID)
 
   // Initialize aOutInputBlockId to a sane value, and then later we overwrite
--- a/gfx/layers/apz/src/AndroidDynamicToolbarAnimator.cpp
+++ b/gfx/layers/apz/src/AndroidDynamicToolbarAnimator.cpp
@@ -111,17 +111,17 @@ GetTouchY(MultiTouchInput& multiTouch, S
     *value = multiTouch.mTouches[0].mScreenPoint.y;
     return true;
   }
 
   return false;
 }
 
 nsEventStatus
-AndroidDynamicToolbarAnimator::ReceiveInputEvent(InputData& aEvent, const ScreenPoint& aScrollOffset)
+AndroidDynamicToolbarAnimator::ReceiveInputEvent(const RefPtr<APZCTreeManager>& aApz, InputData& aEvent, const ScreenPoint& aScrollOffset)
 {
   MOZ_ASSERT(APZThreadUtils::IsControllerThread());
 
   mControllerRootScrollY = aScrollOffset.y;
 
   // Only process and adjust touch events. Wheel events (aka scroll events) are adjusted in the NativePanZoomController
   if (aEvent.mInputType != MULTITOUCH_INPUT) {
     return nsEventStatus_eIgnore;
@@ -194,17 +194,17 @@ AndroidDynamicToolbarAnimator::ReceiveIn
           mControllerDragChangedDirection = true;
         }
         mControllerLastDragDirection = direction;
       }
       // NOTE: gfxPrefs::ToolbarScrollThreshold() returns a percentage as an int32_t. So multiply it by 0.01f to convert.
       const uint32_t dragThreshold = Abs(std::lround(0.01f * gfxPrefs::ToolbarScrollThreshold() * mControllerCompositionHeight));
       if ((Abs(mControllerTotalDistance.value) > dragThreshold) && (delta != 0)) {
         mControllerDragThresholdReached = true;
-        status = ProcessTouchDelta(currentToolbarState, delta, multiTouch.mTime);
+        status = ProcessTouchDelta(aApz, currentToolbarState, delta, multiTouch.mTime);
       }
       mControllerLastEventTimeStamp = multiTouch.mTime;
     }
     break;
   }
   case MultiTouchInput::MULTITOUCH_END:
   case MultiTouchInput::MULTITOUCH_CANCEL:
     // last finger was lifted
@@ -582,19 +582,20 @@ AndroidDynamicToolbarAnimator::Shutdown(
   if (mCompositorToolbarPixels) {
     RefPtr<UiCompositorControllerParent> uiController = UiCompositorControllerParent::GetFromRootLayerTreeId(mRootLayerTreeId);
     uiController->DeallocShmem(mCompositorToolbarPixels.ref());
     mCompositorToolbarPixels.reset();
   }
 }
 
 nsEventStatus
-AndroidDynamicToolbarAnimator::ProcessTouchDelta(StaticToolbarState aCurrentToolbarState, ScreenIntCoord aDelta, uint32_t aTimeStamp)
+AndroidDynamicToolbarAnimator::ProcessTouchDelta(const RefPtr<APZCTreeManager>& aApz, StaticToolbarState aCurrentToolbarState, ScreenIntCoord aDelta, uint32_t aTimeStamp)
 {
   MOZ_ASSERT(APZThreadUtils::IsControllerThread());
+  MOZ_ASSERT(aApz);
   nsEventStatus status = nsEventStatus_eIgnore;
 
   const bool tryingToHideToolbar = aDelta < 0;
 
   if (tryingToHideToolbar && !mControllerScrollingRootContent) {
     // This prevent the toolbar from hiding if a subframe is being scrolled up.
     // The toolbar will always become visible regardless what is being scrolled down.
     return status;
@@ -637,19 +638,20 @@ AndroidDynamicToolbarAnimator::ProcessTo
     // If there was no delta left over, the event was completely consumed.
     if (deltaRemainder == 0) {
       status = nsEventStatus_eConsumeNoDefault;
     }
 
     uint32_t timeDelta = aTimeStamp - mControllerLastEventTimeStamp;
     if (mControllerLastEventTimeStamp && timeDelta && aDelta) {
       float speed = -(float)aDelta / (float)timeDelta;
-      if (mApz) {
-        mApz->ProcessTouchVelocity(aTimeStamp, speed);
-      }
+      // we can't use mApz because we're on the controller thread, so we have
+      // the caller provide a RefPtr to the same underlying object, which should
+      // be safe to use.
+      aApz->ProcessTouchVelocity(aTimeStamp, speed);
     }
   }
 
   return status;
 }
 
 void
 AndroidDynamicToolbarAnimator::HandleTouchEnd(StaticToolbarState aCurrentToolbarState, ScreenIntCoord aCurrentTouch)
--- a/gfx/layers/apz/src/AndroidDynamicToolbarAnimator.h
+++ b/gfx/layers/apz/src/AndroidDynamicToolbarAnimator.h
@@ -55,17 +55,17 @@ public:
   explicit AndroidDynamicToolbarAnimator(APZCTreeManager* aApz);
   void Initialize(uint64_t aRootLayerTreeId);
   void ClearTreeManager();
   // Used to intercept events to determine if the event affects the toolbar.
   // May apply translation to touch events if the toolbar is visible.
   // Returns nsEventStatus_eIgnore when the event is not consumed and
   // nsEventStatus_eConsumeNoDefault when the event was used to translate the
   // toolbar.
-  nsEventStatus ReceiveInputEvent(InputData& aEvent, const ScreenPoint& aScrollOffset);
+  nsEventStatus ReceiveInputEvent(const RefPtr<APZCTreeManager>& aApz, InputData& aEvent, const ScreenPoint& aScrollOffset);
   void SetMaxToolbarHeight(ScreenIntCoord aHeight);
   // When a pinned reason is set to true, the animator will prevent
   // touch events from altering the height of the toolbar. All pinned
   // reasons must be cleared before touch events will affect the toolbar.
   // Animation requests from the UI thread are still honored even if any
   // pin reason is set. This allows the UI thread to pin the toolbar for
   // full screen and then request the animator hide the toolbar.
   void SetPinned(bool aPinned, int32_t aReason);
@@ -128,17 +128,17 @@ protected:
     eAnimationStopPending
   };
   enum AnimationStyle {
     eImmediate,
     eAnimate
   };
 
   ~AndroidDynamicToolbarAnimator(){}
-  nsEventStatus ProcessTouchDelta(StaticToolbarState aCurrentToolbarState, ScreenIntCoord aDelta, uint32_t aTimeStamp);
+  nsEventStatus ProcessTouchDelta(const RefPtr<APZCTreeManager>& aApz, StaticToolbarState aCurrentToolbarState, ScreenIntCoord aDelta, uint32_t aTimeStamp);
   // Called when a touch ends
   void HandleTouchEnd(StaticToolbarState aCurrentToolbarState, ScreenIntCoord aCurrentTouch);
   // Sends a message to the UI thread. May be called from any thread
   void PostMessage(int32_t aMessage);
   void UpdateCompositorToolbarHeight(ScreenIntCoord aHeight);
   void UpdateControllerToolbarHeight(ScreenIntCoord aHeight, ScreenIntCoord aMaxHeight = -1);
   void UpdateControllerSurfaceHeight(ScreenIntCoord aHeight);
   void UpdateControllerCompositionHeight(ScreenIntCoord aHeight);