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: J3j3JTwC1TV
--- 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;