Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(159)

Side by Side Diff: ui/events/blink/input_handler_proxy_unittest.cc

Issue 2429953002: Implement compositor thread VSync aligned event queue (Closed)
Patch Set: dtapuska's review: Non-template CompositorThreadEventQueue; Added blink_features.h; UMA only when e… Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "ui/events/blink/input_handler_proxy.h" 5 #include "ui/events/blink/input_handler_proxy.h"
6 6
7 #include <memory> 7 #include <memory>
8 8
9 #include "base/bind.h"
9 #include "base/macros.h" 10 #include "base/macros.h"
11 #include "base/memory/ptr_util.h"
10 #include "base/test/histogram_tester.h" 12 #include "base/test/histogram_tester.h"
13 #include "base/test/scoped_feature_list.h"
11 #include "cc/input/main_thread_scrolling_reason.h" 14 #include "cc/input/main_thread_scrolling_reason.h"
12 #include "cc/trees/swap_promise_monitor.h" 15 #include "cc/trees/swap_promise_monitor.h"
13 #include "testing/gmock/include/gmock/gmock.h" 16 #include "testing/gmock/include/gmock/gmock.h"
14 #include "testing/gtest/include/gtest/gtest.h" 17 #include "testing/gtest/include/gtest/gtest.h"
15 #include "third_party/WebKit/public/platform/WebFloatPoint.h" 18 #include "third_party/WebKit/public/platform/WebFloatPoint.h"
16 #include "third_party/WebKit/public/platform/WebFloatSize.h" 19 #include "third_party/WebKit/public/platform/WebFloatSize.h"
17 #include "third_party/WebKit/public/platform/WebGestureCurve.h" 20 #include "third_party/WebKit/public/platform/WebGestureCurve.h"
18 #include "third_party/WebKit/public/platform/WebInputEvent.h" 21 #include "third_party/WebKit/public/platform/WebInputEvent.h"
19 #include "third_party/WebKit/public/platform/WebPoint.h" 22 #include "third_party/WebKit/public/platform/WebPoint.h"
23 #include "ui/events/blink/compositor_thread_event_queue.h"
24 #include "ui/events/blink/did_overscroll_params.h"
25 #include "ui/events/blink/event_with_callback.h"
20 #include "ui/events/blink/input_handler_proxy_client.h" 26 #include "ui/events/blink/input_handler_proxy_client.h"
27 #include "ui/events/blink/web_input_event_traits.h"
21 #include "ui/events/latency_info.h" 28 #include "ui/events/latency_info.h"
22 #include "ui/gfx/geometry/scroll_offset.h" 29 #include "ui/gfx/geometry/scroll_offset.h"
23 #include "ui/gfx/geometry/size_f.h" 30 #include "ui/gfx/geometry/size_f.h"
24 31
25 using blink::WebActiveWheelFlingParameters; 32 using blink::WebActiveWheelFlingParameters;
26 using blink::WebFloatPoint; 33 using blink::WebFloatPoint;
27 using blink::WebFloatSize; 34 using blink::WebFloatSize;
28 using blink::WebGestureDevice; 35 using blink::WebGestureDevice;
29 using blink::WebGestureEvent; 36 using blink::WebGestureEvent;
30 using blink::WebInputEvent; 37 using blink::WebInputEvent;
31 using blink::WebKeyboardEvent; 38 using blink::WebKeyboardEvent;
32 using blink::WebMouseWheelEvent; 39 using blink::WebMouseWheelEvent;
33 using blink::WebPoint; 40 using blink::WebPoint;
34 using blink::WebSize; 41 using blink::WebSize;
35 using blink::WebTouchEvent; 42 using blink::WebTouchEvent;
36 using blink::WebTouchPoint; 43 using blink::WebTouchPoint;
37 using testing::Field; 44 using testing::Field;
38 45
39 namespace ui { 46 namespace ui {
40 namespace test { 47 namespace test {
41 48
42 namespace { 49 namespace {
43 50
51 const char* kCoalescedCountHistogram =
52 "Event.CompositorThreadEventQueue.CoalescedCount";
53
44 enum InputHandlerProxyTestType { 54 enum InputHandlerProxyTestType {
45 ROOT_SCROLL_NORMAL_HANDLER, 55 ROOT_SCROLL_NORMAL_HANDLER,
46 ROOT_SCROLL_SYNCHRONOUS_HANDLER, 56 ROOT_SCROLL_SYNCHRONOUS_HANDLER,
47 CHILD_SCROLL_NORMAL_HANDLER, 57 CHILD_SCROLL_NORMAL_HANDLER,
48 CHILD_SCROLL_SYNCHRONOUS_HANDLER, 58 CHILD_SCROLL_SYNCHRONOUS_HANDLER,
49 }; 59 };
50 static const InputHandlerProxyTestType test_types[] = { 60 static const InputHandlerProxyTestType test_types[] = {
51 ROOT_SCROLL_NORMAL_HANDLER, ROOT_SCROLL_SYNCHRONOUS_HANDLER, 61 ROOT_SCROLL_NORMAL_HANDLER, ROOT_SCROLL_SYNCHRONOUS_HANDLER,
52 CHILD_SCROLL_NORMAL_HANDLER, CHILD_SCROLL_SYNCHRONOUS_HANDLER}; 62 CHILD_SCROLL_NORMAL_HANDLER, CHILD_SCROLL_SYNCHRONOUS_HANDLER};
53 63
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
96 WebPoint global_point, 106 WebPoint global_point,
97 int modifiers) { 107 int modifiers) {
98 return CreateFling(base::TimeTicks(), 108 return CreateFling(base::TimeTicks(),
99 source_device, 109 source_device,
100 velocity, 110 velocity,
101 point, 111 point,
102 global_point, 112 global_point,
103 modifiers); 113 modifiers);
104 } 114 }
105 115
116 ScopedWebInputEvent CreateGestureScrollOrPinch(WebInputEvent::Type type,
117 float deltaYOrScale = 0,
118 int x = 0,
119 int y = 0) {
120 WebGestureEvent gesture;
121 gesture.sourceDevice = blink::WebGestureDeviceTouchpad;
122 gesture.type = type;
123 if (type == WebInputEvent::GestureScrollUpdate) {
124 gesture.data.scrollUpdate.deltaY = deltaYOrScale;
125 } else if (type == WebInputEvent::GesturePinchUpdate) {
126 gesture.data.pinchUpdate.scale = deltaYOrScale;
127 gesture.x = x;
128 gesture.y = y;
129 }
130 return WebInputEventTraits::Clone(gesture);
131 }
132
106 class MockInputHandler : public cc::InputHandler { 133 class MockInputHandler : public cc::InputHandler {
107 public: 134 public:
108 MockInputHandler() {} 135 MockInputHandler() {}
109 ~MockInputHandler() override {} 136 ~MockInputHandler() override {}
110 137
111 MOCK_METHOD0(PinchGestureBegin, void()); 138 MOCK_METHOD0(PinchGestureBegin, void());
112 MOCK_METHOD2(PinchGestureUpdate, 139 MOCK_METHOD2(PinchGestureUpdate,
113 void(float magnify_delta, const gfx::Point& anchor)); 140 void(float magnify_delta, const gfx::Point& anchor));
114 MOCK_METHOD0(PinchGestureEnd, void()); 141 MOCK_METHOD0(PinchGestureEnd, void());
115 142
(...skipping 315 matching lines...) Expand 10 before | Expand all | Expand 10 after
431 mock_synchronous_input_handler_; 458 mock_synchronous_input_handler_;
432 std::unique_ptr<TestInputHandlerProxy> input_handler_; 459 std::unique_ptr<TestInputHandlerProxy> input_handler_;
433 testing::StrictMock<MockInputHandlerProxyClient> mock_client_; 460 testing::StrictMock<MockInputHandlerProxyClient> mock_client_;
434 WebGestureEvent gesture_; 461 WebGestureEvent gesture_;
435 InputHandlerProxy::EventDisposition expected_disposition_; 462 InputHandlerProxy::EventDisposition expected_disposition_;
436 base::HistogramTester histogram_tester_; 463 base::HistogramTester histogram_tester_;
437 cc::InputHandlerScrollResult scroll_result_did_scroll_; 464 cc::InputHandlerScrollResult scroll_result_did_scroll_;
438 cc::InputHandlerScrollResult scroll_result_did_not_scroll_; 465 cc::InputHandlerScrollResult scroll_result_did_not_scroll_;
439 }; 466 };
440 467
468 class InputHandlerProxyEventQueueTest
469 : public testing::Test,
470 public testing::WithParamInterface<bool> {
471 public:
472 InputHandlerProxyEventQueueTest()
473 : enable_compositor_event_queue_(GetParam()), weak_ptr_factory_(this) {
474 if (enable_compositor_event_queue_)
475 feature_list_.InitAndEnableFeature(features::kVsyncAlignedInputEvents);
476 }
477
478 ~InputHandlerProxyEventQueueTest() { input_handler_proxy_.reset(); }
479
480 void SetUp() override {
481 event_disposition_recorder_.clear();
482 input_handler_proxy_ = base::MakeUnique<TestInputHandlerProxy>(
483 &mock_input_handler_, &mock_client_);
484 if (input_handler_proxy_->event_queue_)
485 input_handler_proxy_->event_queue_ =
486 base::MakeUnique<CompositorThreadEventQueue>();
487 }
488
489 void HandleGestureEvent(WebInputEvent::Type type,
490 float deltaYOrScale = 0,
491 int x = 0,
492 int y = 0) {
493 LatencyInfo latency;
494 input_handler_proxy_->HandleInputEventWithLatencyInfo(
495 CreateGestureScrollOrPinch(type, deltaYOrScale, x, y), latency,
496 base::Bind(
497 &InputHandlerProxyEventQueueTest::DidHandleInputEventAndOverscroll,
498 weak_ptr_factory_.GetWeakPtr()));
499 }
500
501 void DidHandleInputEventAndOverscroll(
502 InputHandlerProxy::EventDisposition event_disposition,
503 ui::ScopedWebInputEvent input_event,
504 const ui::LatencyInfo& latency_info,
505 std::unique_ptr<ui::DidOverscrollParams> overscroll_params) {
506 event_disposition_recorder_.push_back(event_disposition);
507 }
508
509 std::deque<std::unique_ptr<EventWithCallback>>& event_queue() {
510 return input_handler_proxy_->event_queue_->queue_;
511 }
512
513 protected:
514 base::test::ScopedFeatureList feature_list_;
515 bool enable_compositor_event_queue_;
516 testing::StrictMock<MockInputHandler> mock_input_handler_;
517 std::unique_ptr<TestInputHandlerProxy> input_handler_proxy_;
518 testing::StrictMock<MockInputHandlerProxyClient> mock_client_;
519 std::vector<InputHandlerProxy::EventDisposition> event_disposition_recorder_;
520
521 base::WeakPtrFactory<InputHandlerProxyEventQueueTest> weak_ptr_factory_;
522 };
523
441 TEST_P(InputHandlerProxyTest, MouseWheelNoListener) { 524 TEST_P(InputHandlerProxyTest, MouseWheelNoListener) {
442 expected_disposition_ = InputHandlerProxy::DROP_EVENT; 525 expected_disposition_ = InputHandlerProxy::DROP_EVENT;
443 EXPECT_CALL(mock_input_handler_, 526 EXPECT_CALL(mock_input_handler_,
444 GetEventListenerProperties(cc::EventListenerClass::kMouseWheel)) 527 GetEventListenerProperties(cc::EventListenerClass::kMouseWheel))
445 .WillOnce(testing::Return(cc::EventListenerProperties::kNone)); 528 .WillOnce(testing::Return(cc::EventListenerProperties::kNone));
446 529
447 WebMouseWheelEvent wheel; 530 WebMouseWheelEvent wheel;
448 wheel.type = WebInputEvent::MouseWheel; 531 wheel.type = WebInputEvent::MouseWheel;
449 wheel.modifiers = WebInputEvent::ControlKey; 532 wheel.modifiers = WebInputEvent::ControlKey;
450 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(wheel)); 533 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(wheel));
(...skipping 2358 matching lines...) Expand 10 before | Expand all | Expand 10 after
2809 input_handler_->RecordMainThreadScrollingReasonsForTest( 2892 input_handler_->RecordMainThreadScrollingReasonsForTest(
2810 blink::WebGestureDeviceTouchpad, 2893 blink::WebGestureDeviceTouchpad,
2811 cc::MainThreadScrollingReason::kHandlingScrollFromMainThread); 2894 cc::MainThreadScrollingReason::kHandlingScrollFromMainThread);
2812 2895
2813 EXPECT_THAT( 2896 EXPECT_THAT(
2814 histogram_tester().GetAllSamples("Renderer4.MainThreadWheelScrollReason"), 2897 histogram_tester().GetAllSamples("Renderer4.MainThreadWheelScrollReason"),
2815 testing::ElementsAre(base::Bucket(1, 1), base::Bucket(3, 1), 2898 testing::ElementsAre(base::Bucket(1, 1), base::Bucket(3, 1),
2816 base::Bucket(5, 1), base::Bucket(14, 1))); 2899 base::Bucket(5, 1), base::Bucket(14, 1)));
2817 } 2900 }
2818 2901
2902 TEST_P(InputHandlerProxyEventQueueTest, VSyncAlignedGestureScroll) {
2903 // Don't run the test if we aren't supporting VSync aligned input.
2904 if (!enable_compositor_event_queue_)
2905 return;
2906
2907 base::HistogramTester histogram_tester;
2908
2909 // Handle scroll on compositor.
2910 cc::InputHandlerScrollResult scroll_result_did_scroll_;
2911 scroll_result_did_scroll_.did_scroll = true;
2912
2913 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
2914 .WillOnce(testing::Return(kImplThreadScrollState));
2915 EXPECT_CALL(mock_input_handler_, SetNeedsAnimateInput()).Times(1);
2916
2917 HandleGestureEvent(WebInputEvent::GestureScrollBegin);
2918
2919 // GestureScrollBegin will be processed immediately.
2920 EXPECT_EQ(0ul, event_queue().size());
2921 EXPECT_EQ(1ul, event_disposition_recorder_.size());
2922 EXPECT_EQ(InputHandlerProxy::DID_HANDLE, event_disposition_recorder_[0]);
2923
2924 HandleGestureEvent(WebInputEvent::GestureScrollUpdate, -20);
2925
2926 // GestureScrollUpdate will be queued.
2927 EXPECT_EQ(1ul, event_queue().size());
2928 EXPECT_EQ(-20, static_cast<const blink::WebGestureEvent&>(
2929 event_queue().front()->event())
2930 .data.scrollUpdate.deltaY);
2931 EXPECT_EQ(1ul, event_queue().front()->coalescedCount());
2932 EXPECT_EQ(1ul, event_disposition_recorder_.size());
2933
2934 HandleGestureEvent(WebInputEvent::GestureScrollUpdate, -40);
2935
2936 // GestureScrollUpdate will be coalesced.
2937 EXPECT_EQ(1ul, event_queue().size());
2938 EXPECT_EQ(-60, static_cast<const blink::WebGestureEvent&>(
2939 event_queue().front()->event())
2940 .data.scrollUpdate.deltaY);
2941 EXPECT_EQ(2ul, event_queue().front()->coalescedCount());
2942 EXPECT_EQ(1ul, event_disposition_recorder_.size());
2943
2944 HandleGestureEvent(WebInputEvent::GestureScrollEnd);
2945
2946 // GestureScrollEnd will be queued.
2947 EXPECT_EQ(2ul, event_queue().size());
2948 EXPECT_EQ(1ul, event_disposition_recorder_.size());
2949 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
2950
2951 EXPECT_CALL(
2952 mock_input_handler_,
2953 ScrollBy(testing::Property(&cc::ScrollState::delta_y, testing::Gt(0))))
2954 .WillOnce(testing::Return(scroll_result_did_scroll_));
2955 EXPECT_CALL(mock_input_handler_, ScrollEnd(testing::_));
2956
2957 // Dispatch all queued events.
2958 input_handler_proxy_->DeliverInputForBeginFrame();
2959 EXPECT_EQ(0ul, event_queue().size());
2960 // Should run callbacks for every original events.
2961 EXPECT_EQ(4ul, event_disposition_recorder_.size());
2962 EXPECT_EQ(InputHandlerProxy::DID_HANDLE, event_disposition_recorder_[1]);
2963 EXPECT_EQ(InputHandlerProxy::DID_HANDLE, event_disposition_recorder_[2]);
2964 EXPECT_EQ(InputHandlerProxy::DID_HANDLE, event_disposition_recorder_[3]);
2965 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
2966 histogram_tester.ExpectUniqueSample(kCoalescedCountHistogram, 2, 1);
2967 }
2968
2969 TEST_P(InputHandlerProxyEventQueueTest, VSyncAlignedGestureScrollPinchScroll) {
2970 // Don't run the test if we aren't supporting VSync aligned input.
2971 if (!enable_compositor_event_queue_)
2972 return;
2973
2974 base::HistogramTester histogram_tester;
2975
2976 // Handle scroll on compositor.
2977 cc::InputHandlerScrollResult scroll_result_did_scroll_;
2978 scroll_result_did_scroll_.did_scroll = true;
2979
2980 // Start scroll in the first frame.
2981 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
2982 .WillOnce(testing::Return(kImplThreadScrollState));
2983 EXPECT_CALL(
2984 mock_input_handler_,
2985 ScrollBy(testing::Property(&cc::ScrollState::delta_y, testing::Gt(0))))
2986 .WillOnce(testing::Return(scroll_result_did_scroll_));
2987 EXPECT_CALL(mock_input_handler_, SetNeedsAnimateInput()).Times(1);
2988
2989 HandleGestureEvent(WebInputEvent::GestureScrollBegin);
2990 HandleGestureEvent(WebInputEvent::GestureScrollUpdate, -20);
2991
2992 EXPECT_EQ(1ul, event_queue().size());
2993 EXPECT_EQ(1ul, event_disposition_recorder_.size());
2994
2995 input_handler_proxy_->DeliverInputForBeginFrame();
2996
2997 EXPECT_EQ(0ul, event_queue().size());
2998 EXPECT_EQ(2ul, event_disposition_recorder_.size());
2999 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
3000
3001 // Continue scroll in the second frame, pinch, then start another scroll.
3002 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
3003 .WillOnce(testing::Return(kImplThreadScrollState));
3004 EXPECT_CALL(
3005 mock_input_handler_,
3006 ScrollBy(testing::Property(&cc::ScrollState::delta_y, testing::Gt(0))))
3007 .WillRepeatedly(testing::Return(scroll_result_did_scroll_));
3008 EXPECT_CALL(mock_input_handler_, ScrollEnd(testing::_)).Times(2);
3009 EXPECT_CALL(mock_input_handler_, SetNeedsAnimateInput()).Times(1);
3010 EXPECT_CALL(mock_input_handler_,
3011 GetEventListenerProperties(cc::EventListenerClass::kMouseWheel))
3012 .WillOnce(testing::Return(cc::EventListenerProperties::kNone));
3013 EXPECT_CALL(mock_input_handler_, PinchGestureBegin());
3014 // Two |GesturePinchUpdate| will be coalesced.
3015 EXPECT_CALL(mock_input_handler_,
3016 PinchGestureUpdate(0.7f, gfx::Point(13, 17)));
3017 EXPECT_CALL(mock_input_handler_, PinchGestureEnd());
3018
3019 HandleGestureEvent(WebInputEvent::GestureScrollUpdate, -30);
3020 HandleGestureEvent(WebInputEvent::GestureScrollEnd);
3021 HandleGestureEvent(WebInputEvent::GesturePinchBegin);
3022 HandleGestureEvent(WebInputEvent::GesturePinchUpdate, 1.4f, 13, 17);
3023 HandleGestureEvent(WebInputEvent::GesturePinchUpdate, 0.5f, 13, 17);
3024 HandleGestureEvent(WebInputEvent::GesturePinchEnd);
3025 HandleGestureEvent(WebInputEvent::GestureScrollBegin);
3026 HandleGestureEvent(WebInputEvent::GestureScrollUpdate, -70);
3027 HandleGestureEvent(WebInputEvent::GestureScrollUpdate, -5);
3028 HandleGestureEvent(WebInputEvent::GestureScrollEnd);
3029
3030 EXPECT_EQ(8ul, event_queue().size());
3031 EXPECT_EQ(2ul, event_disposition_recorder_.size());
3032
3033 input_handler_proxy_->DeliverInputForBeginFrame();
3034
3035 EXPECT_EQ(0ul, event_queue().size());
3036 EXPECT_EQ(12ul, event_disposition_recorder_.size());
3037 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
3038 histogram_tester.ExpectBucketCount(kCoalescedCountHistogram, 1, 2);
3039 histogram_tester.ExpectBucketCount(kCoalescedCountHistogram, 2, 2);
3040 }
2819 3041
2820 INSTANTIATE_TEST_CASE_P(AnimateInput, 3042 INSTANTIATE_TEST_CASE_P(AnimateInput,
2821 InputHandlerProxyTest, 3043 InputHandlerProxyTest,
2822 testing::ValuesIn(test_types)); 3044 testing::ValuesIn(test_types));
3045
3046 INSTANTIATE_TEST_CASE_P(InputHandlerProxyEventQueueTests,
3047 InputHandlerProxyEventQueueTest,
3048 testing::Bool());
2823 } // namespace test 3049 } // namespace test
2824 } // namespace ui 3050 } // namespace ui
OLDNEW
« ui/events/blink/input_handler_proxy.cc ('K') | « ui/events/blink/input_handler_proxy.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698