Commit f4886cba authored by Stephen Nusko's avatar Stephen Nusko Committed by Commit Bot

Ensure that TouchEvents are always async after scrolling has started.

Currently we can flip flop back and forth between TouchMoves being sent
async or sync which can cause some pretty noticeable cases of jank. This
ensures that we are always consistently scrolling after deciding
TouchMoves can be async.

Bug: 1072364
Change-Id: I3ef1ed6715d4b1fd2d3e1377ebd6b0c8bcc02872
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2182426
Commit-Queue: Stephen Nusko <nuskos@chromium.org>
Auto-Submit: Stephen Nusko <nuskos@chromium.org>
Reviewed-by: default avatarDavid Bokan <bokan@chromium.org>
Cr-Commit-Position: refs/heads/master@{#776487}
parent 1e5c0f79
...@@ -1621,6 +1621,9 @@ TEST_F(InputRouterImplTest, AsyncTouchMoveAckedImmediately) { ...@@ -1621,6 +1621,9 @@ TEST_F(InputRouterImplTest, AsyncTouchMoveAckedImmediately) {
dispatched_messages[0]->ToEvent()->CallCallback( dispatched_messages[0]->ToEvent()->CallCallback(
blink::mojom::InputEventResultState::kConsumed); blink::mojom::InputEventResultState::kConsumed);
EXPECT_EQ(1U, disposition_handler_->GetAndResetAckCount()); EXPECT_EQ(1U, disposition_handler_->GetAndResetAckCount());
EXPECT_EQ(WebInputEvent::Type::kTouchStart,
disposition_handler_->ack_event_type());
SimulateGestureEvent(WebInputEvent::Type::kGestureScrollBegin, SimulateGestureEvent(WebInputEvent::Type::kGestureScrollBegin,
blink::WebGestureDevice::kTouchscreen); blink::WebGestureDevice::kTouchscreen);
dispatched_messages = GetAndResetDispatchedMessages(); dispatched_messages = GetAndResetDispatchedMessages();
...@@ -1629,14 +1632,55 @@ TEST_F(InputRouterImplTest, AsyncTouchMoveAckedImmediately) { ...@@ -1629,14 +1632,55 @@ TEST_F(InputRouterImplTest, AsyncTouchMoveAckedImmediately) {
dispatched_messages[0]->ToEvent()->CallCallback( dispatched_messages[0]->ToEvent()->CallCallback(
blink::mojom::InputEventResultState::kConsumed); blink::mojom::InputEventResultState::kConsumed);
EXPECT_EQ(1U, disposition_handler_->GetAndResetAckCount()); EXPECT_EQ(1U, disposition_handler_->GetAndResetAckCount());
EXPECT_EQ(WebInputEvent::Type::kGestureScrollBegin,
disposition_handler_->ack_event_type());
SimulateGestureEvent(WebInputEvent::Type::kGestureScrollUpdate, SimulateGestureEvent(WebInputEvent::Type::kGestureScrollUpdate,
blink::WebGestureDevice::kTouchscreen); blink::WebGestureDevice::kTouchscreen);
EXPECT_EQ(0U, disposition_handler_->GetAndResetAckCount()); EXPECT_EQ(0U, disposition_handler_->GetAndResetAckCount());
EXPECT_EQ(2U, GetAndResetDispatchedMessages().size()); dispatched_messages = GetAndResetDispatchedMessages();
EXPECT_EQ(2U, dispatched_messages.size());
EXPECT_EQ(WebInputEvent::Type::kTouchScrollStarted,
dispatched_messages[0]->ToEvent()->Event()->Event().GetType());
EXPECT_EQ(WebInputEvent::Type::kGestureScrollUpdate,
dispatched_messages[1]->ToEvent()->Event()->Event().GetType());
// Ack the GestureScrollUpdate.
dispatched_messages[1]->ToEvent()->CallCallback(
blink::mojom::InputEventResultState::kConsumed);
EXPECT_EQ(WebInputEvent::Type::kGestureScrollUpdate,
disposition_handler_->ack_event_type());
EXPECT_EQ(1U, disposition_handler_->GetAndResetAckCount());
// Now send an async move. // Now since we're scrolling send an async move.
MoveTouchPoint(0, 5, 5); MoveTouchPoint(0, 5, 5);
SendTouchEvent(); SendTouchEvent();
EXPECT_EQ(WebInputEvent::Type::kTouchMove,
disposition_handler_->ack_event_type());
EXPECT_EQ(1U, disposition_handler_->GetAndResetAckCount());
EXPECT_EQ(1U, GetAndResetDispatchedMessages().size());
// To catch crbug/1072364 send another scroll which returns kNoConsumerExists
// and ensure we're still async scrolling since we've already started the
// scroll.
SimulateGestureEvent(WebInputEvent::Type::kGestureScrollUpdate,
blink::WebGestureDevice::kTouchscreen);
EXPECT_EQ(0U, disposition_handler_->GetAndResetAckCount());
dispatched_messages = GetAndResetDispatchedMessages();
EXPECT_EQ(1U, dispatched_messages.size());
EXPECT_EQ(WebInputEvent::Type::kGestureScrollUpdate,
dispatched_messages[0]->ToEvent()->Event()->Event().GetType());
// Ack the GestureScrollUpdate.
dispatched_messages[0]->ToEvent()->CallCallback(
blink::mojom::InputEventResultState::kNoConsumerExists);
EXPECT_EQ(WebInputEvent::Type::kGestureScrollUpdate,
disposition_handler_->ack_event_type());
EXPECT_EQ(1U, disposition_handler_->GetAndResetAckCount());
// Now since we're scrolling (even with NoConsumerExists) send an async move.
MoveTouchPoint(0, 10, 5);
SendTouchEvent();
EXPECT_EQ(WebInputEvent::Type::kTouchMove,
disposition_handler_->ack_event_type());
EXPECT_EQ(1U, disposition_handler_->GetAndResetAckCount()); EXPECT_EQ(1U, disposition_handler_->GetAndResetAckCount());
EXPECT_EQ(1U, GetAndResetDispatchedMessages().size()); EXPECT_EQ(1U, GetAndResetDispatchedMessages().size());
} }
......
...@@ -156,6 +156,7 @@ void PassthroughTouchEventQueue::ProcessTouchAck( ...@@ -156,6 +156,7 @@ void PassthroughTouchEventQueue::ProcessTouchAck(
void PassthroughTouchEventQueue::OnGestureScrollEvent( void PassthroughTouchEventQueue::OnGestureScrollEvent(
const GestureEventWithLatencyInfo& gesture_event) { const GestureEventWithLatencyInfo& gesture_event) {
// Turn events sent during gesture scrolls to be async.
if (gesture_event.event.GetType() == if (gesture_event.event.GetType() ==
blink::WebInputEvent::Type::kGestureScrollUpdate) { blink::WebInputEvent::Type::kGestureScrollUpdate) {
send_touch_events_async_ = true; send_touch_events_async_ = true;
...@@ -165,11 +166,12 @@ void PassthroughTouchEventQueue::OnGestureScrollEvent( ...@@ -165,11 +166,12 @@ void PassthroughTouchEventQueue::OnGestureScrollEvent(
void PassthroughTouchEventQueue::OnGestureEventAck( void PassthroughTouchEventQueue::OnGestureEventAck(
const GestureEventWithLatencyInfo& event, const GestureEventWithLatencyInfo& event,
blink::mojom::InputEventResultState ack_result) { blink::mojom::InputEventResultState ack_result) {
// Turn events sent during gesture scrolls to be async. // When the scroll finishes allow TouchEvents to be blocking again.
if (event.event.GetType() == if (event.event.GetType() == blink::WebInputEvent::Type::kGestureScrollEnd) {
blink::WebInputEvent::Type::kGestureScrollUpdate) { send_touch_events_async_ = false;
send_touch_events_async_ = } else if (event.event.GetType() ==
(ack_result == blink::mojom::InputEventResultState::kConsumed); blink::WebInputEvent::Type::kGestureScrollUpdate) {
send_touch_events_async_ = true;
} }
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment