Bug 1289432 - Start populating the mQueuedInput array with queued input objects. r=botond
authorKartikaya Gupta <kgupta@mozilla.com>
Wed, 14 Sep 2016 07:54:36 -0400
changeset 355211 5544fb9a3c9ad5dff93b4eaefb489337e9d17ba0
parent 355210 73db06b5db9a3d06c168cdbf80eb1007a34b858d
child 355212 1e58cc81dbefe464518acabcd2babf1eb4d8382e
push id6570
push userraliiev@mozilla.com
push dateMon, 14 Nov 2016 12:26:13 +0000
treeherdermozilla-beta@f455459b2ae5 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbotond
bugs1289432
milestone51.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 1289432 - Start populating the mQueuedInput array with queued input objects. r=botond Most of the changes to InputBlockState.* are temporary and will be removed in a future patch, once the transition to using mQueuedInputs is complete. However, the code is useful as an intermediate step to verify that mQueuedInputs is maintaining events in the same order and with the same lifetime as the old block- based queue. MozReview-Commit-ID: I8lVhMiT4hg
gfx/layers/apz/src/InputBlockState.cpp
gfx/layers/apz/src/InputBlockState.h
gfx/layers/apz/src/InputQueue.cpp
gfx/layers/apz/src/QueuedInput.cpp
gfx/layers/apz/src/QueuedInput.h
--- a/gfx/layers/apz/src/InputBlockState.cpp
+++ b/gfx/layers/apz/src/InputBlockState.cpp
@@ -8,16 +8,17 @@
 #include "AsyncPanZoomController.h"         // for AsyncPanZoomController
 #include "AsyncScrollBase.h"                // for kScrollSeriesTimeoutMs
 #include "gfxPrefs.h"                       // for gfxPrefs
 #include "mozilla/MouseEvents.h"
 #include "mozilla/SizePrintfMacros.h"       // for PRIuSIZE
 #include "mozilla/Telemetry.h"              // for Telemetry
 #include "mozilla/layers/APZCTreeManager.h" // for AllowedTouchBehavior
 #include "OverscrollHandoffState.h"
+#include "QueuedInput.h"
 
 #define TBS_LOG(...)
 // #define TBS_LOG(...) printf_stderr("TBS: " __VA_ARGS__)
 
 namespace mozilla {
 namespace layers {
 
 static uint64_t sBlockCounter = InputBlockState::NO_BLOCK_ID + 1;
@@ -302,28 +303,38 @@ DragBlockState::AddEvent(const MouseInpu
 
 bool
 DragBlockState::HasEvents() const
 {
   return !mEvents.IsEmpty();
 }
 
 void
-DragBlockState::DropEvents()
+DragBlockState::DropEvents(nsTArray<UniquePtr<QueuedInput>>* aQueued)
 {
   TBS_LOG("%p dropping %" PRIuSIZE " events\n", this, mEvents.Length());
+  MOZ_ASSERT(aQueued->Length() >= mEvents.Length());
+  for (size_t i = 0; i < mEvents.Length(); i++) {
+    MOZ_ASSERT(aQueued->ElementAt(i)->Block() == this);
+    MOZ_ASSERT(aQueued->ElementAt(i)->Input()->mInputType == mEvents[i].mInputType);
+  }
+  aQueued->RemoveElementsAt(0, mEvents.Length());
   mEvents.Clear();
 }
 
 void
-DragBlockState::HandleEvents()
+DragBlockState::HandleEvents(nsTArray<UniquePtr<QueuedInput>>* aQueued)
 {
   while (HasEvents()) {
     TBS_LOG("%p returning first of %" PRIuSIZE " events\n", this, mEvents.Length());
     MouseInput event = mEvents[0];
+    MOZ_ASSERT(aQueued->Length() > 0);
+    MOZ_ASSERT(aQueued->ElementAt(0)->Block() == this);
+    MOZ_ASSERT(aQueued->ElementAt(0)->Input()->mInputType == event.mInputType);
+    aQueued->RemoveElementAt(0);
     mEvents.RemoveElementAt(0);
     DispatchEvent(event);
   }
 }
 
 bool
 DragBlockState::MustStayActive()
 {
@@ -441,28 +452,38 @@ WheelBlockState::AddEvent(const ScrollWh
 
 bool
 WheelBlockState::HasEvents() const
 {
   return !mEvents.IsEmpty();
 }
 
 void
-WheelBlockState::DropEvents()
+WheelBlockState::DropEvents(nsTArray<UniquePtr<QueuedInput>>* aQueued)
 {
   TBS_LOG("%p dropping %" PRIuSIZE " events\n", this, mEvents.Length());
+  MOZ_ASSERT(aQueued->Length() >= mEvents.Length());
+  for (size_t i = 0; i < mEvents.Length(); i++) {
+    MOZ_ASSERT(aQueued->ElementAt(i)->Block() == this);
+    MOZ_ASSERT(aQueued->ElementAt(i)->Input()->mInputType == mEvents[i].mInputType);
+  }
+  aQueued->RemoveElementsAt(0, mEvents.Length());
   mEvents.Clear();
 }
 
 void
-WheelBlockState::HandleEvents()
+WheelBlockState::HandleEvents(nsTArray<UniquePtr<QueuedInput>>* aQueued)
 {
   while (HasEvents()) {
     TBS_LOG("%p returning first of %" PRIuSIZE " events\n", this, mEvents.Length());
     ScrollWheelInput event = mEvents[0];
+    MOZ_ASSERT(aQueued->Length() > 0);
+    MOZ_ASSERT(aQueued->ElementAt(0)->Block() == this);
+    MOZ_ASSERT(aQueued->ElementAt(0)->Input()->mInputType == event.mInputType);
+    aQueued->RemoveElementAt(0);
     mEvents.RemoveElementAt(0);
     DispatchEvent(event);
   }
 }
 
 bool
 WheelBlockState::MustStayActive()
 {
@@ -651,28 +672,38 @@ PanGestureBlockState::AddEvent(const Pan
 
 bool
 PanGestureBlockState::HasEvents() const
 {
   return !mEvents.IsEmpty();
 }
 
 void
-PanGestureBlockState::DropEvents()
+PanGestureBlockState::DropEvents(nsTArray<UniquePtr<QueuedInput>>* aQueued)
 {
   TBS_LOG("%p dropping %" PRIuSIZE " events\n", this, mEvents.Length());
+  MOZ_ASSERT(aQueued->Length() >= mEvents.Length());
+  for (size_t i = 0; i < mEvents.Length(); i++) {
+    MOZ_ASSERT(aQueued->ElementAt(i)->Block() == this);
+    MOZ_ASSERT(aQueued->ElementAt(i)->Input()->mInputType == mEvents[i].mInputType);
+  }
+  aQueued->RemoveElementsAt(0, mEvents.Length());
   mEvents.Clear();
 }
 
 void
-PanGestureBlockState::HandleEvents()
+PanGestureBlockState::HandleEvents(nsTArray<UniquePtr<QueuedInput>>* aQueued)
 {
   while (HasEvents()) {
     TBS_LOG("%p returning first of %" PRIuSIZE " events\n", this, mEvents.Length());
     PanGestureInput event = mEvents[0];
+    MOZ_ASSERT(aQueued->Length() > 0);
+    MOZ_ASSERT(aQueued->ElementAt(0)->Block() == this);
+    MOZ_ASSERT(aQueued->ElementAt(0)->Input()->mInputType == event.mInputType);
+    aQueued->RemoveElementAt(0);
     mEvents.RemoveElementAt(0);
     DispatchEvent(event);
   }
 }
 
 bool
 PanGestureBlockState::MustStayActive()
 {
@@ -852,28 +883,38 @@ TouchBlockState::MustStayActive()
 
 const char*
 TouchBlockState::Type()
 {
   return "touch";
 }
 
 void
-TouchBlockState::DropEvents()
+TouchBlockState::DropEvents(nsTArray<UniquePtr<QueuedInput>>* aQueued)
 {
   TBS_LOG("%p dropping %" PRIuSIZE " events\n", this, mEvents.Length());
+  MOZ_ASSERT(aQueued->Length() >= mEvents.Length());
+  for (size_t i = 0; i < mEvents.Length(); i++) {
+    MOZ_ASSERT(aQueued->ElementAt(i)->Block() == this);
+    MOZ_ASSERT(aQueued->ElementAt(i)->Input()->mInputType == mEvents[i].mInputType);
+  }
+  aQueued->RemoveElementsAt(0, mEvents.Length());
   mEvents.Clear();
 }
 
 void
-TouchBlockState::HandleEvents()
+TouchBlockState::HandleEvents(nsTArray<UniquePtr<QueuedInput>>* aQueued)
 {
   while (HasEvents()) {
     TBS_LOG("%p returning first of %" PRIuSIZE " events\n", this, mEvents.Length());
     MultiTouchInput event = mEvents[0];
+    MOZ_ASSERT(aQueued->Length() > 0);
+    MOZ_ASSERT(aQueued->ElementAt(0)->Block() == this);
+    MOZ_ASSERT(aQueued->ElementAt(0)->Input()->mInputType == event.mInputType);
+    aQueued->RemoveElementAt(0);
     mEvents.RemoveElementAt(0);
     DispatchEvent(event);
   }
 }
 
 void
 TouchBlockState::DispatchEvent(const InputData& aEvent) const
 {
--- a/gfx/layers/apz/src/InputBlockState.h
+++ b/gfx/layers/apz/src/InputBlockState.h
@@ -192,23 +192,23 @@ public:
   /**
    * Returns whether or not this block has pending events.
    */
   virtual bool HasEvents() const = 0;
 
   /**
    * Throw away all the events in this input block.
    */
-  virtual void DropEvents() = 0;
+  virtual void DropEvents(nsTArray<UniquePtr<QueuedInput>>* aQueued) = 0;
 
   /**
    * Process all events using this input block's target apzc, leaving this
    * block depleted. This input block's apzc must not be nullptr.
    */
-  virtual void HandleEvents() = 0;
+  virtual void HandleEvents(nsTArray<UniquePtr<QueuedInput>>* aQueued) = 0;
 
   /**
    * Return true if this input block must stay active if it would otherwise
    * be removed as the last item in the pending queue.
    */
   virtual bool MustStayActive() = 0;
 
   /**
@@ -230,18 +230,18 @@ class WheelBlockState : public Cancelabl
 {
 public:
   WheelBlockState(const RefPtr<AsyncPanZoomController>& aTargetApzc,
                   bool aTargetConfirmed,
                   const ScrollWheelInput& aEvent);
 
   bool SetContentResponse(bool aPreventDefault) override;
   bool HasEvents() const override;
-  void DropEvents() override;
-  void HandleEvents() override;
+  void DropEvents(nsTArray<UniquePtr<QueuedInput>>* aQueued) override;
+  void HandleEvents(nsTArray<UniquePtr<QueuedInput>>* aQueued) override;
   bool MustStayActive() override;
   const char* Type() override;
   bool SetConfirmedTargetApzc(const RefPtr<AsyncPanZoomController>& aTargetApzc,
                               TargetConfirmationState aState) override;
 
   void AddEvent(const ScrollWheelInput& aEvent);
 
   WheelBlockState *AsWheelBlock() override {
@@ -315,18 +315,18 @@ private:
 class DragBlockState : public CancelableBlockState
 {
 public:
   DragBlockState(const RefPtr<AsyncPanZoomController>& aTargetApzc,
                  bool aTargetConfirmed,
                  const MouseInput& aEvent);
 
   bool HasEvents() const override;
-  void DropEvents() override;
-  void HandleEvents() override;
+  void DropEvents(nsTArray<UniquePtr<QueuedInput>>* aQueued) override;
+  void HandleEvents(nsTArray<UniquePtr<QueuedInput>>* aQueued) override;
   bool MustStayActive() override;
   const char* Type() override;
 
   bool HasReceivedMouseUp();
   void MarkMouseUpReceived();
 
   void AddEvent(const MouseInput& aEvent);
 
@@ -352,18 +352,18 @@ public:
   PanGestureBlockState(const RefPtr<AsyncPanZoomController>& aTargetApzc,
                        bool aTargetConfirmed,
                        const PanGestureInput& aEvent);
 
   bool SetContentResponse(bool aPreventDefault) override;
   bool HasReceivedAllContentNotifications() const override;
   bool IsReadyForHandling() const override;
   bool HasEvents() const override;
-  void DropEvents() override;
-  void HandleEvents() override;
+  void DropEvents(nsTArray<UniquePtr<QueuedInput>>* aQueued) override;
+  void HandleEvents(nsTArray<UniquePtr<QueuedInput>>* aQueued) override;
   bool MustStayActive() override;
   const char* Type() override;
   bool SetConfirmedTargetApzc(const RefPtr<AsyncPanZoomController>& aTargetApzc,
                               TargetConfirmationState aState) override;
 
   void AddEvent(const PanGestureInput& aEvent);
 
   PanGestureBlockState *AsPanGestureBlock() override {
@@ -502,18 +502,18 @@ public:
                        bool aApzcCanConsumeEvents);
 
   /**
    * Returns the number of touch points currently active.
    */
   uint32_t GetActiveTouchCount() const;
 
   bool HasEvents() const override;
-  void DropEvents() override;
-  void HandleEvents() override;
+  void DropEvents(nsTArray<UniquePtr<QueuedInput>>* aQueued) override;
+  void HandleEvents(nsTArray<UniquePtr<QueuedInput>>* aQueued) override;
   void DispatchEvent(const InputData& aEvent) const override;
   bool MustStayActive() override;
   const char* Type() override;
 
 private:
   nsTArray<TouchBehaviorFlags> mAllowedTouchBehaviors;
   bool mAllowedTouchBehaviorSet;
   bool mDuringFastFling;
--- a/gfx/layers/apz/src/InputQueue.cpp
+++ b/gfx/layers/apz/src/InputQueue.cpp
@@ -21,16 +21,17 @@ namespace mozilla {
 namespace layers {
 
 InputQueue::InputQueue()
 {
 }
 
 InputQueue::~InputQueue() {
   mInputBlockQueue.Clear();
+  mQueuedInputs.Clear();
 }
 
 nsEventStatus
 InputQueue::ReceiveInputEvent(const RefPtr<AsyncPanZoomController>& aTarget,
                               bool aTargetConfirmed,
                               const InputData& aEvent,
                               uint64_t* aOutInputBlockId) {
   APZThreadUtils::AssertOnControllerThread();
@@ -169,16 +170,17 @@ InputQueue::ReceiveTouchInput(const RefP
       result = nsEventStatus_eConsumeDoDefault;
     }
   } else if (block->UpdateSlopState(aEvent.AsMultiTouchInput(), false)) {
     INPQ_LOG("dropping event due to block %p being in mini-slop\n", block);
     result = nsEventStatus_eConsumeNoDefault;
   }
   if (!MaybeHandleCurrentBlock(block, aEvent)) {
     block->AddEvent(aEvent.AsMultiTouchInput());
+    mQueuedInputs.AppendElement(MakeUnique<QueuedInput>(aEvent.AsMultiTouchInput(), *block));
   }
   return result;
 }
 
 nsEventStatus
 InputQueue::ReceiveMouseInput(const RefPtr<AsyncPanZoomController>& aTarget,
                               bool aTargetConfirmed,
                               const MouseInput& aEvent,
@@ -228,16 +230,17 @@ InputQueue::ReceiveMouseInput(const RefP
   }
 
   if (aOutInputBlockId) {
     *aOutInputBlockId = block->GetBlockId();
   }
 
   if (!MaybeHandleCurrentBlock(block, aEvent)) {
     block->AddEvent(aEvent.AsMouseInput());
+    mQueuedInputs.AppendElement(MakeUnique<QueuedInput>(aEvent.AsMouseInput(), *block));
   }
 
   if (DragTracker::EndsDrag(aEvent)) {
     block->MarkMouseUpReceived();
   }
 
   // The event is part of a drag block and could potentially cause
   // scrolling, so return DoDefault.
@@ -290,16 +293,17 @@ InputQueue::ReceiveScrollWheelInput(cons
 
   // Note that the |aTarget| the APZCTM sent us may contradict the confirmed
   // target set on the block. In this case the confirmed target (which may be
   // null) should take priority. This is equivalent to just always using the
   // target (confirmed or not) from the block, which is what
   // MaybeHandleCurrentBlock() does.
   if (!MaybeHandleCurrentBlock(block, event)) {
     block->AddEvent(event);
+    mQueuedInputs.AppendElement(MakeUnique<QueuedInput>(event, *block));
   }
 
   return nsEventStatus_eConsumeDoDefault;
 }
 
 static bool
 CanScrollTargetHorizontally(const PanGestureInput& aInitialEvent,
                             PanGestureBlockState* aBlock)
@@ -374,16 +378,17 @@ InputQueue::ReceivePanGestureInput(const
 
   // Note that the |aTarget| the APZCTM sent us may contradict the confirmed
   // target set on the block. In this case the confirmed target (which may be
   // null) should take priority. This is equivalent to just always using the
   // target (confirmed or not) from the block, which is what
   // MaybeHandleCurrentBlock() does.
   if (!MaybeHandleCurrentBlock(block, event)) {
     block->AddEvent(event.AsPanGestureInput());
+    mQueuedInputs.AppendElement(MakeUnique<QueuedInput>(event.AsPanGestureInput(), *block));
   }
 
   return result;
 }
 
 void
 InputQueue::CancelAnimationsForNewBlock(CancelableBlockState* aBlock)
 {
@@ -697,25 +702,25 @@ InputQueue::ProcessInputBlocks() {
 
     INPQ_LOG("processing input block %p; preventDefault %d target %p\n",
         curBlock, curBlock->IsDefaultPrevented(),
         curBlock->GetTargetApzc().get());
     RefPtr<AsyncPanZoomController> target = curBlock->GetTargetApzc();
     // target may be null here if the initial target was unconfirmed and then
     // we later got a confirmed null target. in that case drop the events.
     if (!target) {
-      curBlock->DropEvents();
+      curBlock->DropEvents(&mQueuedInputs);
     } else if (curBlock->IsDefaultPrevented()) {
-      curBlock->DropEvents();
+      curBlock->DropEvents(&mQueuedInputs);
       if (curBlock->AsTouchBlock()) {
         target->ResetTouchInputState();
       }
     } else {
       UpdateActiveApzc(curBlock->GetTargetApzc());
-      curBlock->HandleEvents();
+      curBlock->HandleEvents(&mQueuedInputs);
     }
     MOZ_ASSERT(!curBlock->HasEvents());
 
     if (mInputBlockQueue.Length() == 1 && curBlock->MustStayActive()) {
       // Some types of blocks (e.g. touch blocks) accumulate events until the
       // next input block is started. Therefore we cannot remove the block from
       // the queue until we have started another block. This block will be
       // removed by SweepDeletedBlocks() whenever a new block is added.
@@ -755,16 +760,17 @@ InputQueue::UpdateActiveApzc(const RefPt
 }
 
 void
 InputQueue::Clear()
 {
   APZThreadUtils::AssertOnControllerThread();
 
   mInputBlockQueue.Clear();
+  mQueuedInputs.Clear();
   mActiveTouchBlock = nullptr;
   mActiveWheelBlock = nullptr;
   mActiveDragBlock = nullptr;
   mActivePanGestureBlock = nullptr;
   mLastActiveApzc = nullptr;
 }
 
 } // namespace layers
--- a/gfx/layers/apz/src/QueuedInput.cpp
+++ b/gfx/layers/apz/src/QueuedInput.cpp
@@ -33,10 +33,22 @@ QueuedInput::QueuedInput(const MouseInpu
 }
 
 QueuedInput::QueuedInput(const PanGestureInput& aInput, PanGestureBlockState& aBlock)
   : mInput(MakeUnique<PanGestureInput>(aInput))
   , mBlock(&aBlock)
 {
 }
 
+InputData*
+QueuedInput::Input()
+{
+  return mInput.get();
+}
+
+CancelableBlockState*
+QueuedInput::Block()
+{
+  return mBlock.get();
+}
+
 } // namespace layers
 } // namespace mozilla
--- a/gfx/layers/apz/src/QueuedInput.h
+++ b/gfx/layers/apz/src/QueuedInput.h
@@ -34,16 +34,19 @@ class PanGestureBlockState;
 class QueuedInput
 {
 public:
   QueuedInput(const MultiTouchInput& aInput, TouchBlockState& aBlock);
   QueuedInput(const ScrollWheelInput& aInput, WheelBlockState& aBlock);
   QueuedInput(const MouseInput& aInput, DragBlockState& aBlock);
   QueuedInput(const PanGestureInput& aInput, PanGestureBlockState& aBlock);
 
+  InputData* Input();
+  CancelableBlockState* Block();
+
 private:
   // A copy of the input event that is provided to the constructor. This must
   // be non-null, and is owned by this QueuedInput instance (hence the
   // UniquePtr).
   UniquePtr<InputData> mInput;
   // A pointer to the block that the input event is associated with. This must
   // be non-null.
   RefPtr<CancelableBlockState> mBlock;