Bug 1289432 - Have the InputQueue keep RefPtrs to the active block of each input type. r?botond draft
authorKartikaya Gupta <kgupta@mozilla.com>
Mon, 12 Sep 2016 22:42:17 -0400
changeset 412854 13070745f7db93ffccdb7c1099c6c4cba5a1919f
parent 412853 e65d579027d7073c849b33813c03911cea8510c0
child 412855 5de5a38ecb530c20dc50465eb304396998c2d42e
push id29274
push userkgupta@mozilla.com
push dateTue, 13 Sep 2016 02:44:31 +0000
reviewersbotond
bugs1289432
milestone51.0a1
Bug 1289432 - Have the InputQueue keep RefPtrs to the active block of each input type. r?botond MozReview-Commit-ID: BpKYV61B9oH
gfx/layers/apz/src/InputQueue.cpp
gfx/layers/apz/src/InputQueue.h
--- a/gfx/layers/apz/src/InputQueue.cpp
+++ b/gfx/layers/apz/src/InputQueue.cpp
@@ -215,16 +215,17 @@ InputQueue::ReceiveMouseInput(const RefP
     MOZ_ASSERT(newBlock);
     block = new DragBlockState(aTarget, aTargetConfirmed, aEvent);
 
     INPQ_LOG("started new drag block %p id %" PRIu64 " for %sconfirmed target %p\n",
         block, block->GetBlockId(), aTargetConfirmed ? "" : "un", aTarget.get());
 
     SweepDepletedBlocks();
     mInputBlockQueue.AppendElement(block);
+    mActiveDragBlock = block;
 
     CancelAnimationsForNewBlock(block);
     MaybeRequestContentResponse(aTarget, block);
   }
 
   if (aOutInputBlockId) {
     *aOutInputBlockId = block->GetBlockId();
   }
@@ -265,16 +266,17 @@ InputQueue::ReceiveScrollWheelInput(cons
 
   if (!block) {
     block = new WheelBlockState(aTarget, aTargetConfirmed, aEvent);
     INPQ_LOG("started new scroll wheel block %p id %" PRIu64 " for target %p\n",
         block, block->GetBlockId(), aTarget.get());
 
     SweepDepletedBlocks();
     mInputBlockQueue.AppendElement(block);
+    mActiveWheelBlock = block;
 
     CancelAnimationsForNewBlock(block);
     MaybeRequestContentResponse(aTarget, block);
   } else {
     INPQ_LOG("received new event in block %p\n", block);
   }
 
   if (aOutInputBlockId) {
@@ -352,16 +354,17 @@ InputQueue::ReceivePanGestureInput(const
 
       // Inform our caller that we haven't scrolled in response to the event
       // and that a swipe can be started from this event if desired.
       result = nsEventStatus_eIgnore;
     }
 
     SweepDepletedBlocks();
     mInputBlockQueue.AppendElement(block);
+    mActivePanGestureBlock = block;
 
     CancelAnimationsForNewBlock(block);
     MaybeRequestContentResponse(aTarget, block);
   } else {
     INPQ_LOG("received new event in block %p\n", block);
   }
 
   if (aOutInputBlockId) {
@@ -443,16 +446,17 @@ InputQueue::SweepDepletedBlocks()
   // See corresponding comment in ProcessInputBlocks.
   while (!mInputBlockQueue.IsEmpty()) {
     CancelableBlockState* block = mInputBlockQueue[0].get();
     if (!block->IsReadyForHandling() || block->HasEvents()) {
       break;
     }
 
     INPQ_LOG("discarding depleted %s block %p\n", block->Type(), block);
+    ClearActiveBlock(block);
     mInputBlockQueue.RemoveElementAt(0);
   }
 }
 
 TouchBlockState*
 InputQueue::StartNewTouchBlock(const RefPtr<AsyncPanZoomController>& aTarget,
                                bool aTargetConfirmed,
                                bool aCopyPropertiesFromCurrent)
@@ -462,16 +466,17 @@ InputQueue::StartNewTouchBlock(const Ref
   if (aCopyPropertiesFromCurrent) {
     newBlock->CopyPropertiesFrom(*CurrentTouchBlock());
   }
 
   SweepDepletedBlocks();
 
   // Add the new block to the queue.
   mInputBlockQueue.AppendElement(newBlock);
+  mActiveTouchBlock = newBlock;
   return newBlock;
 }
 
 CancelableBlockState*
 InputQueue::CurrentBlock() const
 {
   APZThreadUtils::AssertOnControllerThread();
 
@@ -714,32 +719,52 @@ InputQueue::ProcessInputBlocks() {
       // the queue until we have started another block. This block will be
       // removed by SweepDeletedBlocks() whenever a new block is added.
       break;
     }
 
     // If we get here, we know there are more touch blocks in the queue after
     // |curBlock|, so we can remove |curBlock| and try to process the next one.
     INPQ_LOG("discarding processed %s block %p\n", curBlock->Type(), curBlock);
+    ClearActiveBlock(curBlock);
     mInputBlockQueue.RemoveElementAt(0);
   } while (!mInputBlockQueue.IsEmpty());
 }
 
 void
+InputQueue::ClearActiveBlock(CancelableBlockState* aBlock)
+{
+  // XXX: This function will be removed in a later patch
+  if (mActiveTouchBlock.get() == aBlock) {
+    mActiveTouchBlock = nullptr;
+  } else if (mActiveWheelBlock.get() == aBlock) {
+    mActiveWheelBlock = nullptr;
+  } else if (mActiveDragBlock.get() == aBlock) {
+    mActiveDragBlock = nullptr;
+  } else if (mActivePanGestureBlock.get() == aBlock) {
+    mActivePanGestureBlock = nullptr;
+  }
+}
+
+void
 InputQueue::UpdateActiveApzc(const RefPtr<AsyncPanZoomController>& aNewActive) {
   if (mLastActiveApzc && mLastActiveApzc != aNewActive
       && mTouchCounter.GetActiveTouchCount() > 0) {
     mLastActiveApzc->ResetTouchInputState();
   }
   mLastActiveApzc = aNewActive;
 }
 
 void
 InputQueue::Clear()
 {
   APZThreadUtils::AssertOnControllerThread();
 
   mInputBlockQueue.Clear();
+  mActiveTouchBlock = nullptr;
+  mActiveWheelBlock = nullptr;
+  mActiveDragBlock = nullptr;
+  mActivePanGestureBlock = nullptr;
   mLastActiveApzc = nullptr;
 }
 
 } // namespace layers
 } // namespace mozilla
--- a/gfx/layers/apz/src/InputQueue.h
+++ b/gfx/layers/apz/src/InputQueue.h
@@ -173,23 +173,34 @@ private:
    */
   bool MaybeHandleCurrentBlock(CancelableBlockState* block,
                                const InputData& aEvent);
 
   void ScheduleMainThreadTimeout(const RefPtr<AsyncPanZoomController>& aTarget,
                                  CancelableBlockState* aBlock);
   void MainThreadTimeout(const uint64_t& aInputBlockId);
   void ProcessInputBlocks();
+  void ClearActiveBlock(CancelableBlockState* aBlock);
   void UpdateActiveApzc(const RefPtr<AsyncPanZoomController>& aNewActive);
 
 private:
   // The queue of input blocks that have not yet been fully processed.
   // This member must only be accessed on the controller/UI thread.
   nsTArray<RefPtr<CancelableBlockState>> mInputBlockQueue;
 
+  // These are the most recently created blocks of each input type. They are
+  // "active" in the sense that new inputs of that type are associated with
+  // them. Note that these pointers may be null if no inputs of the type have
+  // arrived, or if the inputs for the type formed a complete block that was
+  // then discarded.
+  RefPtr<TouchBlockState> mActiveTouchBlock;
+  RefPtr<WheelBlockState> mActiveWheelBlock;
+  RefPtr<DragBlockState> mActiveDragBlock;
+  RefPtr<PanGestureBlockState> mActivePanGestureBlock;
+
   // The APZC to which the last event was delivered
   RefPtr<AsyncPanZoomController> mLastActiveApzc;
 
   // Track touches so we know when to clear mLastActiveApzc
   TouchCounter mTouchCounter;
 
   // Track mouse inputs so we know if we're in a drag or not
   DragTracker mDragTracker;