Bug 1289432 - Stop relying on the mEvents array inside the SetConfirmedTargetApzc implementations. r=botond

MozReview-Commit-ID: BG7BmQPa6g9
This commit is contained in:
Kartikaya Gupta 2016-09-14 07:54:37 -04:00
Родитель e9b2ac2229
Коммит 5b33e5009a
4 изменённых файлов: 89 добавлений и 43 удалений

Просмотреть файл

@ -38,7 +38,8 @@ InputBlockState::InputBlockState(const RefPtr<AsyncPanZoomController>& aTargetAp
bool
InputBlockState::SetConfirmedTargetApzc(const RefPtr<AsyncPanZoomController>& aTargetApzc,
TargetConfirmationState aState)
TargetConfirmationState aState,
InputData* aFirstInput)
{
MOZ_ASSERT(aState == TargetConfirmationState::eConfirmed
|| aState == TargetConfirmationState::eTimedOut);
@ -382,18 +383,18 @@ WheelBlockState::SetContentResponse(bool aPreventDefault)
bool
WheelBlockState::SetConfirmedTargetApzc(const RefPtr<AsyncPanZoomController>& aTargetApzc,
TargetConfirmationState aState)
TargetConfirmationState aState,
InputData* aFirstInput)
{
// The APZC that we find via APZCCallbackHelpers may not be the same APZC
// ESM or OverscrollHandoff would have computed. Make sure we get the right
// one by looking for the first apzc the next pending event can scroll.
RefPtr<AsyncPanZoomController> apzc = aTargetApzc;
if (apzc && mEvents.Length() > 0) {
const ScrollWheelInput& event = mEvents.ElementAt(0);
apzc = apzc->BuildOverscrollHandoffChain()->FindFirstScrollable(event);
if (apzc && aFirstInput) {
apzc = apzc->BuildOverscrollHandoffChain()->FindFirstScrollable(*aFirstInput);
}
InputBlockState::SetConfirmedTargetApzc(apzc, aState);
InputBlockState::SetConfirmedTargetApzc(apzc, aState, aFirstInput);
return true;
}
@ -637,22 +638,22 @@ PanGestureBlockState::PanGestureBlockState(const RefPtr<AsyncPanZoomController>&
bool
PanGestureBlockState::SetConfirmedTargetApzc(const RefPtr<AsyncPanZoomController>& aTargetApzc,
TargetConfirmationState aState)
TargetConfirmationState aState,
InputData* aFirstInput)
{
// The APZC that we find via APZCCallbackHelpers may not be the same APZC
// ESM or OverscrollHandoff would have computed. Make sure we get the right
// one by looking for the first apzc the next pending event can scroll.
RefPtr<AsyncPanZoomController> apzc = aTargetApzc;
if (apzc && mEvents.Length() > 0) {
const PanGestureInput& event = mEvents.ElementAt(0);
if (apzc && aFirstInput) {
RefPtr<AsyncPanZoomController> scrollableApzc =
apzc->BuildOverscrollHandoffChain()->FindFirstScrollable(event);
apzc->BuildOverscrollHandoffChain()->FindFirstScrollable(*aFirstInput);
if (scrollableApzc) {
apzc = scrollableApzc;
}
}
InputBlockState::SetConfirmedTargetApzc(apzc, aState);
InputBlockState::SetConfirmedTargetApzc(apzc, aState, aFirstInput);
return true;
}

Просмотреть файл

@ -55,7 +55,8 @@ public:
{}
virtual bool SetConfirmedTargetApzc(const RefPtr<AsyncPanZoomController>& aTargetApzc,
TargetConfirmationState aState);
TargetConfirmationState aState,
InputData* aFirstInput);
const RefPtr<AsyncPanZoomController>& GetTargetApzc() const;
const RefPtr<const OverscrollHandoffChain>& GetOverscrollHandoffChain() const;
uint64_t GetBlockId() const;
@ -233,7 +234,8 @@ public:
bool MustStayActive() override;
const char* Type() override;
bool SetConfirmedTargetApzc(const RefPtr<AsyncPanZoomController>& aTargetApzc,
TargetConfirmationState aState) override;
TargetConfirmationState aState,
InputData* aFirstInput) override;
void AddEvent(const ScrollWheelInput& aEvent);
@ -355,7 +357,8 @@ public:
bool MustStayActive() override;
const char* Type() override;
bool SetConfirmedTargetApzc(const RefPtr<AsyncPanZoomController>& aTargetApzc,
TargetConfirmationState aState) override;
TargetConfirmationState aState,
InputData* aFirstInput) override;
void AddEvent(const PanGestureInput& aEvent);

Просмотреть файл

@ -104,7 +104,8 @@ InputQueue::ReceiveTouchInput(const RefPtr<AsyncPanZoomController>& aTarget,
// the first finger is moving).
block->SetDuringFastFling();
block->SetConfirmedTargetApzc(aTarget,
InputBlockState::TargetConfirmationState::eConfirmed);
InputBlockState::TargetConfirmationState::eConfirmed,
nullptr /* the block was just created so it has no events */);
if (gfxPrefs::TouchActionEnabled()) {
block->SetAllowedTouchBehaviors(currentBehaviors);
}
@ -546,23 +547,55 @@ InputQueue::ScheduleMainThreadTimeout(const RefPtr<AsyncPanZoomController>& aTar
gfxPrefs::APZContentResponseTimeout());
}
CancelableBlockState*
InputQueue::FindBlockForId(const uint64_t& aInputBlockId,
InputData** aOutFirstInput)
{
for (size_t i = 0; i < mQueuedInputs.Length(); i++) {
if (mQueuedInputs[i]->Block()->GetBlockId() == aInputBlockId) {
if (aOutFirstInput) {
*aOutFirstInput = mQueuedInputs[i]->Input();
}
return mQueuedInputs[i]->Block();
}
}
CancelableBlockState* block = nullptr;
if (mActiveTouchBlock && mActiveTouchBlock->GetBlockId() == aInputBlockId) {
block = mActiveTouchBlock.get();
} else if (mActiveWheelBlock && mActiveWheelBlock->GetBlockId() == aInputBlockId) {
block = mActiveWheelBlock.get();
} else if (mActiveDragBlock && mActiveDragBlock->GetBlockId() == aInputBlockId) {
block = mActiveDragBlock.get();
} else if (mActivePanGestureBlock && mActivePanGestureBlock->GetBlockId() == aInputBlockId) {
block = mActivePanGestureBlock.get();
}
// Since we didn't encounter this block while iterating through mQueuedInputs,
// it must have no events associated with it at the moment.
MOZ_ASSERT(!block || !block->HasEvents());
if (aOutFirstInput) {
*aOutFirstInput = nullptr;
}
return block;
}
void
InputQueue::MainThreadTimeout(const uint64_t& aInputBlockId) {
APZThreadUtils::AssertOnControllerThread();
INPQ_LOG("got a main thread timeout; block=%" PRIu64 "\n", aInputBlockId);
bool success = false;
for (size_t i = 0; i < mInputBlockQueue.Length(); i++) {
if (mInputBlockQueue[i]->GetBlockId() == aInputBlockId) {
// time out the touch-listener response and also confirm the existing
// target apzc in the case where the main thread doesn't get back to us
// fast enough.
success = mInputBlockQueue[i]->TimeoutContentResponse();
success |= mInputBlockQueue[i]->SetConfirmedTargetApzc(
mInputBlockQueue[i]->GetTargetApzc(),
InputBlockState::TargetConfirmationState::eTimedOut);
break;
}
InputData* firstInput = nullptr;
CancelableBlockState* block = FindBlockForId(aInputBlockId, &firstInput);
if (block) {
// time out the touch-listener response and also confirm the existing
// target apzc in the case where the main thread doesn't get back to us
// fast enough.
success = block->TimeoutContentResponse();
success |= block->SetConfirmedTargetApzc(
block->GetTargetApzc(),
InputBlockState::TargetConfirmationState::eTimedOut,
firstInput);
}
if (success) {
ProcessInputBlocks();
@ -595,14 +628,13 @@ InputQueue::SetConfirmedTargetApzc(uint64_t aInputBlockId, const RefPtr<AsyncPan
INPQ_LOG("got a target apzc; block=%" PRIu64 " guid=%s\n",
aInputBlockId, aTargetApzc ? Stringify(aTargetApzc->GetGuid()).c_str() : "");
bool success = false;
for (size_t i = 0; i < mInputBlockQueue.Length(); i++) {
CancelableBlockState* block = mInputBlockQueue[i].get();
if (block->GetBlockId() == aInputBlockId) {
success = block->SetConfirmedTargetApzc(aTargetApzc,
InputBlockState::TargetConfirmationState::eConfirmed);
block->RecordContentResponseTime();
break;
}
InputData* firstInput = nullptr;
CancelableBlockState* block = FindBlockForId(aInputBlockId, &firstInput);
if (block) {
success = block->SetConfirmedTargetApzc(aTargetApzc,
InputBlockState::TargetConfirmationState::eConfirmed,
firstInput);
block->RecordContentResponseTime();
}
if (success) {
ProcessInputBlocks();
@ -618,15 +650,14 @@ InputQueue::ConfirmDragBlock(uint64_t aInputBlockId, const RefPtr<AsyncPanZoomCo
INPQ_LOG("got a target apzc; block=%" PRIu64 " guid=%s\n",
aInputBlockId, aTargetApzc ? Stringify(aTargetApzc->GetGuid()).c_str() : "");
bool success = false;
for (size_t i = 0; i < mInputBlockQueue.Length(); i++) {
DragBlockState* block = mInputBlockQueue[i]->AsDragBlock();
if (block && block->GetBlockId() == aInputBlockId) {
block->SetDragMetrics(aDragMetrics);
success = block->SetConfirmedTargetApzc(aTargetApzc,
InputBlockState::TargetConfirmationState::eConfirmed);
block->RecordContentResponseTime();
break;
}
InputData* firstInput = nullptr;
CancelableBlockState* block = FindBlockForId(aInputBlockId, &firstInput);
if (block && block->AsDragBlock()) {
block->AsDragBlock()->SetDragMetrics(aDragMetrics);
success = block->SetConfirmedTargetApzc(aTargetApzc,
InputBlockState::TargetConfirmationState::eConfirmed,
firstInput);
block->RecordContentResponseTime();
}
if (success) {
ProcessInputBlocks();

Просмотреть файл

@ -172,6 +172,17 @@ private:
*/
void SweepDepletedBlocks();
/**
* Helper function that searches mQueuedInputs for the first block matching
* the given id, and returns it. If |aOutFirstInput| is non-null, it is
* populated with a pointer to the first input in mQueuedInputs that
* corresponds to the block, or null if no such input was found. Note that
* even if there are no inputs in mQueuedInputs, this function can return
* non-null if the block id provided matches one of the depleted-but-still-
* active blocks (mActiveTouchBlock, mActiveWheelBlock, etc.).
*/
CancelableBlockState* FindBlockForId(const uint64_t& aInputBlockId,
InputData** aOutFirstInput);
void ScheduleMainThreadTimeout(const RefPtr<AsyncPanZoomController>& aTarget,
CancelableBlockState* aBlock);
void MainThreadTimeout(const uint64_t& aInputBlockId);