Commit 42f43cb3 authored by sahel's avatar sahel Committed by Commit bot

Send a GSB to main thread before switching to it in the middle of

scrolling.

When wheel scroll latching is enabled, GSB occurs only once in the
beginning of a scroll sequence. So, it is possible to need to switch
to the main thread scroll handling in the middle of a scroll scroll
sequence (e.g. due to a change in main thread scrolling reasons).
To have a complete scroll sequence on main thread side and do the scroll
chain computation only while handling GSB, this cl sends a GSB to the main thread before sending the GSU that is not handled in the impl thread
side.

BUG=526463
TEST=AnimateInput/InputHandlerProxyTest.GestureScrollHandlingSwitchedToMainThread/*

Review-Url: https://codereview.chromium.org/2854683002
Cr-Commit-Position: refs/heads/master@{#471006}
parent a1692d2d
...@@ -91,4 +91,22 @@ void InputHandlerWrapper::DidAnimateForInput() { ...@@ -91,4 +91,22 @@ void InputHandlerWrapper::DidAnimateForInput() {
input_handler_manager_->DidAnimateForInput(); input_handler_manager_->DidAnimateForInput();
} }
void InputHandlerWrapper::GenerateScrollBeginAndSendToMainThread(
const blink::WebGestureEvent& update_event) {
DCHECK_EQ(update_event.GetType(), blink::WebInputEvent::kGestureScrollUpdate);
blink::WebGestureEvent scroll_begin(update_event);
scroll_begin.SetType(blink::WebInputEvent::kGestureScrollBegin);
scroll_begin.data.scroll_begin.inertial_phase =
update_event.data.scroll_update.inertial_phase;
scroll_begin.data.scroll_begin.delta_x_hint =
update_event.data.scroll_update.delta_x;
scroll_begin.data.scroll_begin.delta_y_hint =
update_event.data.scroll_update.delta_y;
scroll_begin.data.scroll_begin.delta_hint_units =
update_event.data.scroll_update.delta_units;
DispatchNonBlockingEventToMainThread(
ui::WebInputEventTraits::Clone(scroll_begin), ui::LatencyInfo());
}
} // namespace content } // namespace content
...@@ -55,6 +55,8 @@ class InputHandlerWrapper : public ui::InputHandlerProxyClient { ...@@ -55,6 +55,8 @@ class InputHandlerWrapper : public ui::InputHandlerProxyClient {
const gfx::PointF& causal_event_viewport_point) override; const gfx::PointF& causal_event_viewport_point) override;
void DidStopFlinging() override; void DidStopFlinging() override;
void DidAnimateForInput() override; void DidAnimateForInput() override;
void GenerateScrollBeginAndSendToMainThread(
const blink::WebGestureEvent& update_event) override;
private: private:
InputHandlerManager* input_handler_manager_; InputHandlerManager* input_handler_manager_;
......
...@@ -910,6 +910,8 @@ InputHandlerProxy::HandleGestureScrollUpdate( ...@@ -910,6 +910,8 @@ InputHandlerProxy::HandleGestureScrollUpdate(
gesture_event.source_device == blink::kWebGestureDeviceTouchpad && gesture_event.source_device == blink::kWebGestureDeviceTouchpad &&
touchpad_and_wheel_scroll_latching_enabled_) { touchpad_and_wheel_scroll_latching_enabled_) {
gesture_scroll_on_impl_thread_ = false; gesture_scroll_on_impl_thread_ = false;
client_->GenerateScrollBeginAndSendToMainThread(gesture_event);
if (!gesture_pinch_on_impl_thread_) if (!gesture_pinch_on_impl_thread_)
return DID_NOT_HANDLE; return DID_NOT_HANDLE;
} }
......
...@@ -55,6 +55,11 @@ class InputHandlerProxyClient { ...@@ -55,6 +55,11 @@ class InputHandlerProxyClient {
virtual void DidAnimateForInput() = 0; virtual void DidAnimateForInput() = 0;
// Used to send a GSB to the main thread when the wheel scroll latching is
// enabled and the scrolling should switch to the main thread.
virtual void GenerateScrollBeginAndSendToMainThread(
const blink::WebGestureEvent& update_event) = 0;
protected: protected:
virtual ~InputHandlerProxyClient() {} virtual ~InputHandlerProxyClient() {}
}; };
......
...@@ -289,6 +289,9 @@ class MockInputHandlerProxyClient ...@@ -289,6 +289,9 @@ class MockInputHandlerProxyClient
MOCK_METHOD1(DispatchNonBlockingEventToMainThread_, MOCK_METHOD1(DispatchNonBlockingEventToMainThread_,
void(const WebInputEvent&)); void(const WebInputEvent&));
MOCK_METHOD1(GenerateScrollBeginAndSendToMainThread,
void(const blink::WebGestureEvent& update_event));
void DispatchNonBlockingEventToMainThread( void DispatchNonBlockingEventToMainThread(
WebScopedInputEvent event, WebScopedInputEvent event,
const ui::LatencyInfo& latency_info) override { const ui::LatencyInfo& latency_info) override {
...@@ -1036,6 +1039,53 @@ TEST_P(InputHandlerProxyWithoutWheelScrollLatchingTest, ...@@ -1036,6 +1039,53 @@ TEST_P(InputHandlerProxyWithoutWheelScrollLatchingTest,
GestureFlingStartedTouchpad(); GestureFlingStartedTouchpad();
} }
TEST_P(InputHandlerProxyTest, GestureScrollHandlingSwitchedToMainThread) {
// We shouldn't send any events to the widget for this gesture.
expected_disposition_ = InputHandlerProxy::DID_HANDLE;
VERIFY_AND_RESET_MOCKS();
EXPECT_CALL(mock_input_handler_, ScrollBegin(::testing::_, ::testing::_))
.WillOnce(testing::Return(kImplThreadScrollState));
// HandleGestureScrollBegin will set gesture_scroll_on_impl_thread_.
gesture_.SetType(WebInputEvent::kGestureScrollBegin);
EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
EXPECT_TRUE(input_handler_->gesture_scroll_on_impl_thread_for_testing());
VERIFY_AND_RESET_MOCKS();
gesture_.SetType(WebInputEvent::kGestureScrollUpdate);
gesture_.data.scroll_update.delta_y = -40;
EXPECT_CALL(
mock_input_handler_,
ScrollBy(testing::Property(&cc::ScrollState::delta_y, testing::Gt(0))))
.WillOnce(testing::Return(scroll_result_did_scroll_));
EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
EXPECT_TRUE(input_handler_->gesture_scroll_on_impl_thread_for_testing());
// The scroll handling switches to the main thread, a GSB is sent to the main
// thread to initiate the hit testing and compute the scroll chain.
expected_disposition_ = InputHandlerProxy::DID_NOT_HANDLE;
EXPECT_CALL(
mock_input_handler_,
ScrollBy(testing::Property(&cc::ScrollState::delta_y, testing::Gt(0))))
.WillOnce(testing::Return(scroll_result_did_not_scroll_));
EXPECT_CALL(mock_input_handler_, ScrollingShouldSwitchtoMainThread())
.WillOnce(testing::Return(true));
EXPECT_CALL(mock_client_,
GenerateScrollBeginAndSendToMainThread(::testing::_));
EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
EXPECT_FALSE(input_handler_->gesture_scroll_on_impl_thread_for_testing());
VERIFY_AND_RESET_MOCKS();
gesture_.SetType(WebInputEvent::kGestureScrollEnd);
EXPECT_CALL(mock_input_handler_, ScrollEnd(testing::_));
EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
VERIFY_AND_RESET_MOCKS();
}
TEST_P(InputHandlerProxyTest, GestureFlingTouchpadScrollLatchingEnabled) { TEST_P(InputHandlerProxyTest, GestureFlingTouchpadScrollLatchingEnabled) {
// Reset the input_handler_ with wheel scroll latching enabled. // Reset the input_handler_ with wheel scroll latching enabled.
input_handler_.reset( input_handler_.reset(
......
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