Skip to content

Commit

Permalink
Stop sending input event ack messages for ignored ack types
Browse files Browse the repository at this point in the history
A subset of input event types always ignore their ack messages responses from
the renderer. Stop sending ack messages for those types.

BUG=302852

Review URL: https://codereview.chromium.org/109433014

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@240686 0039d316-1c4b-4281-b951-d872f2087c98
  • Loading branch information
jdduke@chromium.org committed Dec 13, 2013
1 parent 45d6679 commit 34afe10
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 30 deletions.
15 changes: 9 additions & 6 deletions content/browser/renderer_host/input/input_router_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -441,12 +441,14 @@ bool InputRouterImpl::OfferToClient(const WebInputEvent& input_event,
}

bool InputRouterImpl::OfferToRenderer(const WebInputEvent& input_event,
const ui::LatencyInfo& latency_info,
bool is_keyboard_shortcut) {
const ui::LatencyInfo& latency_info,
bool is_keyboard_shortcut) {
input_event_start_time_ = TimeTicks::Now();
if (Send(new InputMsg_HandleInputEvent(
routing_id(), &input_event, latency_info, is_keyboard_shortcut))) {
client_->IncrementInFlightEventCount();
// Only increment the event count if we require an ACK for |input_event|.
if (!WebInputEventTraits::IgnoresAckDisposition(input_event.type))
client_->IncrementInFlightEventCount();
return true;
}
return false;
Expand All @@ -459,12 +461,13 @@ void InputRouterImpl::OnInputEventAck(WebInputEvent::Type event_type,
TimeDelta delta = TimeTicks::Now() - input_event_start_time_;
UMA_HISTOGRAM_TIMES("MPArch.IIR_InputEventDelta", delta);

client_->DecrementInFlightEventCount();

// A synthetic ack will already have been sent for this event.
// A synthetic ack will already have been sent for this event, and it will
// not have affected the in-flight event count.
if (WebInputEventTraits::IgnoresAckDisposition(event_type))
return;

client_->DecrementInFlightEventCount();

ProcessInputEventAck(event_type, ack_result, latency_info, RENDERER);
// WARNING: |this| may be deleted at this point.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -718,11 +718,13 @@ TEST_F(InputRouterImplTest, TouchTypesIgnoringAck) {
INPUT_EVENT_ACK_STATE_CONSUMED);
ASSERT_EQ(1U, GetSentMessageCountAndResetSink());
ASSERT_EQ(1U, ack_handler_->GetAndResetAckCount());
ASSERT_EQ(0, client_->in_flight_event_count());
}

SimulateTouchEvent(type);
EXPECT_EQ(1U, GetSentMessageCountAndResetSink());
EXPECT_EQ(1U, ack_handler_->GetAndResetAckCount());
EXPECT_EQ(0, client_->in_flight_event_count());
SendInputEventACK(type, INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
EXPECT_EQ(0U, GetSentMessageCountAndResetSink());
EXPECT_EQ(0U, ack_handler_->GetAndResetAckCount());
Expand All @@ -740,6 +742,7 @@ TEST_F(InputRouterImplTest, GestureTypesIgnoringAck) {
SimulateGestureEvent(type, WebGestureEvent::Touchscreen);
EXPECT_EQ(1U, GetSentMessageCountAndResetSink());
EXPECT_EQ(1U, ack_handler_->GetAndResetAckCount());
EXPECT_EQ(0, client_->in_flight_event_count());
SendInputEventACK(type, INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
EXPECT_EQ(0U, GetSentMessageCountAndResetSink());
EXPECT_EQ(0U, ack_handler_->GetAndResetAckCount());
Expand All @@ -756,11 +759,13 @@ TEST_F(InputRouterImplTest, GestureTypesIgnoringAckInterleaved) {
WebGestureEvent::Touchscreen);
ASSERT_EQ(1U, GetSentMessageCountAndResetSink());
EXPECT_EQ(0U, ack_handler_->GetAndResetAckCount());
EXPECT_EQ(1, client_->in_flight_event_count());

SimulateGestureEvent(WebInputEvent::GestureTapDown,
WebGestureEvent::Touchscreen);
EXPECT_EQ(0U, GetSentMessageCountAndResetSink());
EXPECT_EQ(0U, ack_handler_->GetAndResetAckCount());
EXPECT_EQ(1, client_->in_flight_event_count());

SimulateGestureEvent(WebInputEvent::GesturePinchUpdate,
WebGestureEvent::Touchscreen);
Expand All @@ -784,39 +789,46 @@ TEST_F(InputRouterImplTest, GestureTypesIgnoringAckInterleaved) {

// Now ack each event. Ack-ignoring events should not be dispatched until all
// prior events which observe ack disposition have been fired, at which
// point they should be sent immediately.
// point they should be sent immediately. They should also have no effect
// on the in-flight event count.
SendInputEventACK(WebInputEvent::GesturePinchUpdate,
INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
EXPECT_EQ(2U, GetSentMessageCountAndResetSink());
EXPECT_EQ(2U, ack_handler_->GetAndResetAckCount());
EXPECT_EQ(1, client_->in_flight_event_count());

// For events which ignore ack disposition, non-synthetic acks are ignored.
SendInputEventACK(WebInputEvent::GestureTapDown,
INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
EXPECT_EQ(0U, GetSentMessageCountAndResetSink());
EXPECT_EQ(0U, ack_handler_->GetAndResetAckCount());
EXPECT_EQ(1, client_->in_flight_event_count());

SendInputEventACK(WebInputEvent::GesturePinchUpdate,
INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
EXPECT_EQ(2U, GetSentMessageCountAndResetSink());
EXPECT_EQ(2U, ack_handler_->GetAndResetAckCount());
EXPECT_EQ(1, client_->in_flight_event_count());

// For events which ignore ack disposition, non-synthetic acks are ignored.
SendInputEventACK(WebInputEvent::GestureShowPress,
INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
EXPECT_EQ(0U, GetSentMessageCountAndResetSink());
EXPECT_EQ(0U, ack_handler_->GetAndResetAckCount());
EXPECT_EQ(1, client_->in_flight_event_count());

SendInputEventACK(WebInputEvent::GesturePinchUpdate,
INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
EXPECT_EQ(1U, GetSentMessageCountAndResetSink());
EXPECT_EQ(2U, ack_handler_->GetAndResetAckCount());
EXPECT_EQ(0, client_->in_flight_event_count());

// For events which ignore ack disposition, non-synthetic acks are ignored.
SendInputEventACK(WebInputEvent::GestureTapCancel,
INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
EXPECT_EQ(0U, GetSentMessageCountAndResetSink());
EXPECT_EQ(0U, ack_handler_->GetAndResetAckCount());
EXPECT_EQ(0, client_->in_flight_event_count());
}

// Test that GestureShowPress events don't get out of order due to
Expand Down
4 changes: 3 additions & 1 deletion content/renderer/input/input_event_filter.cc
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include "base/location.h"
#include "base/message_loop/message_loop_proxy.h"
#include "cc/input/input_handler.h"
#include "content/common/input/web_input_event_traits.h"
#include "content/common/input_messages.h"
#include "content/common/view_messages.h"
#include "content/public/common/content_switches.h"
Expand Down Expand Up @@ -145,7 +146,8 @@ void InputEventFilter::ForwardToHandler(const IPC::Message& message) {
return;
}

SendACK(event->type, ack, latency_info, routing_id);
if (!WebInputEventTraits::IgnoresAckDisposition(event->type))
SendACK(event->type, ack, latency_info, routing_id);
}

void InputEventFilter::SendACK(blink::WebInputEvent::Type type,
Expand Down
46 changes: 24 additions & 22 deletions content/renderer/render_widget.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1141,11 +1141,6 @@ void RenderWidget::OnHandleInputEvent(const blink::WebInputEvent* input_event,
}
}

IPC::Message* response =
new InputHostMsg_HandleInputEvent_ACK(routing_id_,
input_event->type,
ack_result,
latency_info);
bool event_type_can_be_rate_limited =
input_event->type == WebInputEvent::MouseMove ||
input_event->type == WebInputEvent::MouseWheel ||
Expand All @@ -1168,24 +1163,31 @@ void RenderWidget::OnHandleInputEvent(const blink::WebInputEvent* input_event,
kInputHandlingTimeThrottlingThresholdMicroseconds;
}

if (rate_limiting_wanted && event_type_can_be_rate_limited &&
frame_pending && !is_hidden_) {
// We want to rate limit the input events in this case, so we'll wait for
// painting to finish before ACKing this message.
TRACE_EVENT_INSTANT0("renderer",
"RenderWidget::OnHandleInputEvent ack throttled",
TRACE_EVENT_SCOPE_THREAD);
if (pending_input_event_ack_) {
// As two different kinds of events could cause us to postpone an ack
// we send it now, if we have one pending. The Browser should never
// send us the same kind of event we are delaying the ack for.
Send(pending_input_event_ack_.release());
if (!WebInputEventTraits::IgnoresAckDisposition(input_event->type)) {
scoped_ptr<IPC::Message> response(
new InputHostMsg_HandleInputEvent_ACK(routing_id_,
input_event->type,
ack_result,
latency_info));
if (rate_limiting_wanted && event_type_can_be_rate_limited &&
frame_pending && !is_hidden_) {
// We want to rate limit the input events in this case, so we'll wait for
// painting to finish before ACKing this message.
TRACE_EVENT_INSTANT0("renderer",
"RenderWidget::OnHandleInputEvent ack throttled",
TRACE_EVENT_SCOPE_THREAD);
if (pending_input_event_ack_) {
// As two different kinds of events could cause us to postpone an ack
// we send it now, if we have one pending. The Browser should never
// send us the same kind of event we are delaying the ack for.
Send(pending_input_event_ack_.release());
}
pending_input_event_ack_ = response.Pass();
if (compositor_)
compositor_->NotifyInputThrottledUntilCommit();
} else {
Send(response.release());
}
pending_input_event_ack_.reset(response);
if (compositor_)
compositor_->NotifyInputThrottledUntilCommit();
} else {
Send(response);
}

#if defined(OS_ANDROID)
Expand Down

0 comments on commit 34afe10

Please sign in to comment.