Index: content/renderer/input/main_thread_event_queue_unittest.cc |
diff --git a/content/renderer/input/main_thread_event_queue_unittest.cc b/content/renderer/input/main_thread_event_queue_unittest.cc |
index d5036cfec1dbd991c21d2ef94518a6ef30f05c72..d92e896f6c29c181e4fa33702b88cc0af68b7b7b 100644 |
--- a/content/renderer/input/main_thread_event_queue_unittest.cc |
+++ b/content/renderer/input/main_thread_event_queue_unittest.cc |
@@ -9,6 +9,7 @@ |
#include <vector> |
#include "base/macros.h" |
+#include "base/test/histogram_tester.h" |
#include "base/test/test_simple_task_runner.h" |
#include "build/build_config.h" |
#include "content/common/input/synthetic_web_input_event_builders.h" |
@@ -36,9 +37,11 @@ namespace content { |
namespace { |
const int kTestRoutingID = 13; |
+const char* kCoalescedCountHistogram = |
+ "Event.MainThreadEventQueue.CoalescedCount"; |
tdresser
2016/08/24 13:43:00
Missing space
dtapuska
2016/08/24 17:10:06
you mean a LF? done.
|
} |
-class MainThreadEventQueueTest : public testing::Test, |
+class MainThreadEventQueueTest : public testing::TestWithParam<bool>, |
public MainThreadEventQueueClient { |
public: |
MainThreadEventQueueTest() |
@@ -46,7 +49,9 @@ class MainThreadEventQueueTest : public testing::Test, |
queue_(new MainThreadEventQueue(kTestRoutingID, |
this, |
main_task_runner_, |
- &renderer_scheduler_)) {} |
+ &renderer_scheduler_, |
+ GetParam())), |
+ needs_main_frame_(false) {} |
tdresser
2016/08/24 13:43:00
This indentation looks off.
dtapuska
2016/08/24 17:10:07
how so; this is run through git cl format.
tdresser
2016/08/24 17:45:16
Nevermind.
|
void HandleEventOnMainThread(int routing_id, |
const blink::WebInputEvent* event, |
@@ -69,6 +74,8 @@ class MainThreadEventQueueTest : public testing::Test, |
ui::LatencyInfo(), DISPATCH_TYPE_BLOCKING, ack_result); |
} |
+ void NeedsMainFrame(int routing_id) override { needs_main_frame_ = true; } |
+ |
WebInputEventQueue<EventWithDispatchType>& event_queue() { |
return queue_->events_; |
} |
@@ -85,15 +92,33 @@ class MainThreadEventQueueTest : public testing::Test, |
queue_->enable_fling_passive_listener_flag_ = enable_flag; |
} |
+ void RunPendingTasksWithSimulatedRaf() { |
+ while (needs_main_frame_ || main_task_runner_->HasPendingTask()) { |
+ main_task_runner_->RunUntilIdle(); |
+ needs_main_frame_ = false; |
+ queue_->DispatchRafAlignedInput(); |
+ } |
+ } |
+ |
+ void RunSimulatedRafOnce() { |
+ if (needs_main_frame_) { |
+ needs_main_frame_ = false; |
+ queue_->DispatchRafAlignedInput(); |
+ } |
+ } |
+ |
protected: |
scoped_refptr<base::TestSimpleTaskRunner> main_task_runner_; |
blink::scheduler::MockRendererScheduler renderer_scheduler_; |
scoped_refptr<MainThreadEventQueue> queue_; |
std::vector<ui::ScopedWebInputEvent> handled_events_; |
std::vector<uint32_t> additional_acked_events_; |
+ bool needs_main_frame_; |
}; |
-TEST_F(MainThreadEventQueueTest, NonBlockingWheel) { |
+TEST_P(MainThreadEventQueueTest, NonBlockingWheel) { |
+ base::HistogramTester histogram_tester; |
+ |
WebMouseWheelEvent kEvents[4] = { |
SyntheticWebMouseWheelEventBuilder::Build(10, 10, 0, 53, 0, false), |
SyntheticWebMouseWheelEventBuilder::Build(20, 20, 0, 53, 0, false), |
@@ -108,8 +133,8 @@ TEST_F(MainThreadEventQueueTest, NonBlockingWheel) { |
HandleEvent(event, INPUT_EVENT_ACK_STATE_SET_NON_BLOCKING); |
EXPECT_EQ(2u, event_queue().size()); |
- EXPECT_TRUE(main_task_runner_->HasPendingTask()); |
- main_task_runner_->RunUntilIdle(); |
+ EXPECT_EQ(GetParam(), !main_task_runner_->HasPendingTask()); |
+ RunPendingTasksWithSimulatedRaf(); |
EXPECT_FALSE(main_task_runner_->HasPendingTask()); |
EXPECT_EQ(0u, event_queue().size()); |
EXPECT_EQ(2u, handled_events_.size()); |
@@ -137,9 +162,12 @@ TEST_F(MainThreadEventQueueTest, NonBlockingWheel) { |
WebInputEvent::DispatchType::ListenersNonBlockingPassive; |
EXPECT_EQ(coalesced_event, *last_wheel_event); |
} |
+ histogram_tester.ExpectUniqueSample(kCoalescedCountHistogram, 1, 2); |
} |
-TEST_F(MainThreadEventQueueTest, NonBlockingTouch) { |
+TEST_P(MainThreadEventQueueTest, NonBlockingTouch) { |
+ base::HistogramTester histogram_tester; |
+ |
SyntheticWebTouchEvent kEvents[4]; |
kEvents[0].PressPoint(10, 10); |
kEvents[1].PressPoint(10, 10); |
@@ -155,7 +183,7 @@ TEST_F(MainThreadEventQueueTest, NonBlockingTouch) { |
EXPECT_EQ(3u, event_queue().size()); |
EXPECT_TRUE(main_task_runner_->HasPendingTask()); |
- main_task_runner_->RunUntilIdle(); |
+ RunPendingTasksWithSimulatedRaf(); |
EXPECT_FALSE(main_task_runner_->HasPendingTask()); |
EXPECT_EQ(0u, event_queue().size()); |
EXPECT_EQ(3u, handled_events_.size()); |
@@ -185,9 +213,13 @@ TEST_F(MainThreadEventQueueTest, NonBlockingTouch) { |
coalesced_event.dispatchType = |
WebInputEvent::DispatchType::ListenersNonBlockingPassive; |
EXPECT_EQ(coalesced_event, *last_touch_event); |
+ histogram_tester.ExpectBucketCount(kCoalescedCountHistogram, 0, 1); |
+ histogram_tester.ExpectBucketCount(kCoalescedCountHistogram, 1, 1); |
} |
-TEST_F(MainThreadEventQueueTest, BlockingTouch) { |
+TEST_P(MainThreadEventQueueTest, BlockingTouch) { |
+ base::HistogramTester histogram_tester; |
+ |
SyntheticWebTouchEvent kEvents[4]; |
kEvents[0].PressPoint(10, 10); |
kEvents[1].PressPoint(10, 10); |
@@ -207,14 +239,17 @@ TEST_F(MainThreadEventQueueTest, BlockingTouch) { |
EXPECT_EQ(2u, event_queue().size()); |
EXPECT_TRUE(main_task_runner_->HasPendingTask()); |
- main_task_runner_->RunUntilIdle(); |
+ RunPendingTasksWithSimulatedRaf(); |
+ |
EXPECT_EQ(0u, event_queue().size()); |
EXPECT_EQ(2u, additional_acked_events_.size()); |
EXPECT_EQ(kEvents[2].uniqueTouchEventId, additional_acked_events_.at(0)); |
EXPECT_EQ(kEvents[3].uniqueTouchEventId, additional_acked_events_.at(1)); |
+ |
+ histogram_tester.ExpectUniqueSample(kCoalescedCountHistogram, 2, 1); |
} |
-TEST_F(MainThreadEventQueueTest, InterleavedEvents) { |
+TEST_P(MainThreadEventQueueTest, InterleavedEvents) { |
WebMouseWheelEvent kWheelEvents[2] = { |
SyntheticWebMouseWheelEventBuilder::Build(10, 10, 0, 53, 0, false), |
SyntheticWebMouseWheelEventBuilder::Build(20, 20, 0, 53, 0, false), |
@@ -234,8 +269,8 @@ TEST_F(MainThreadEventQueueTest, InterleavedEvents) { |
HandleEvent(kTouchEvents[1], INPUT_EVENT_ACK_STATE_SET_NON_BLOCKING); |
EXPECT_EQ(2u, event_queue().size()); |
- EXPECT_TRUE(main_task_runner_->HasPendingTask()); |
- main_task_runner_->RunUntilIdle(); |
+ EXPECT_EQ(GetParam(), !main_task_runner_->HasPendingTask()); |
tdresser
2016/08/24 13:43:00
Save the parameter into a well named variable.
I
dtapuska
2016/08/24 17:10:07
done
|
+ RunPendingTasksWithSimulatedRaf(); |
EXPECT_FALSE(main_task_runner_->HasPendingTask()); |
EXPECT_EQ(0u, event_queue().size()); |
EXPECT_EQ(2u, handled_events_.size()); |
@@ -265,7 +300,127 @@ TEST_F(MainThreadEventQueueTest, InterleavedEvents) { |
} |
} |
-TEST_F(MainThreadEventQueueTest, BlockingTouchesDuringFling) { |
+TEST_P(MainThreadEventQueueTest, RafAlignedMouseInput) { |
+ // Don't run the test for when we aren't supporting raf aligned. |
tdresser
2016/08/24 13:43:00
Don't run the test when we aren't supporting rAF a
dtapuska
2016/08/24 17:10:06
done
|
+ if (!GetParam()) |
+ return; |
+ |
+ WebMouseEvent kMouseEvents[3] = { |
+ SyntheticWebMouseEventBuilder::Build(WebInputEvent::MouseDown, 10, 10, 0), |
+ SyntheticWebMouseEventBuilder::Build(WebInputEvent::MouseMove, 10, 10, 0), |
+ SyntheticWebMouseEventBuilder::Build(WebInputEvent::MouseUp, 10, 10, 0), |
+ }; |
+ |
+ WebMouseWheelEvent kWheelEvents[2] = { |
+ SyntheticWebMouseWheelEventBuilder::Build(10, 10, 0, 53, 0, false), |
+ SyntheticWebMouseWheelEventBuilder::Build(20, 20, 0, 53, 0, false), |
+ }; |
+ |
+ EXPECT_FALSE(main_task_runner_->HasPendingTask()); |
+ EXPECT_EQ(0u, event_queue().size()); |
+ |
+ // Simulate enqueing a normal event, followed by "continious" events and then |
tdresser
2016/08/24 13:43:00
continuous
dtapuska
2016/08/24 17:10:06
done
|
+ // a normal event. The "continious" events should not wait for RAF. |
tdresser
2016/08/24 13:43:00
nittiest nit: We normally write rAF, as it abbrevi
tdresser
2016/08/24 13:43:00
Is the above comment correct? Isn't it the discret
dtapuska
2016/08/24 17:10:06
done
|
+ HandleEvent(kMouseEvents[0], INPUT_EVENT_ACK_STATE_SET_NON_BLOCKING); |
+ HandleEvent(kMouseEvents[1], INPUT_EVENT_ACK_STATE_SET_NON_BLOCKING); |
+ HandleEvent(kWheelEvents[0], INPUT_EVENT_ACK_STATE_SET_NON_BLOCKING); |
tdresser
2016/08/24 13:43:00
If we aren't iterating through the events, I'd rat
dtapuska
2016/08/24 17:10:07
done
|
+ HandleEvent(kWheelEvents[1], INPUT_EVENT_ACK_STATE_SET_NON_BLOCKING); |
+ HandleEvent(kMouseEvents[2], INPUT_EVENT_ACK_STATE_SET_NON_BLOCKING); |
+ |
+ EXPECT_EQ(4u, event_queue().size()); |
+ EXPECT_TRUE(main_task_runner_->HasPendingTask()); |
+ EXPECT_TRUE(needs_main_frame_); |
+ main_task_runner_->RunUntilIdle(); |
+ EXPECT_EQ(0u, event_queue().size()); |
+ RunPendingTasksWithSimulatedRaf(); |
+ |
+ // Simulate the RAF running before the PostTask occurs. The first RAF |
+ // shouldn't do anything. |
+ HandleEvent(kMouseEvents[0], INPUT_EVENT_ACK_STATE_SET_NON_BLOCKING); |
+ HandleEvent(kWheelEvents[0], INPUT_EVENT_ACK_STATE_SET_NON_BLOCKING); |
+ EXPECT_EQ(2u, event_queue().size()); |
+ EXPECT_TRUE(needs_main_frame_); |
+ RunSimulatedRafOnce(); |
+ EXPECT_FALSE(needs_main_frame_); |
+ EXPECT_EQ(2u, event_queue().size()); |
+ main_task_runner_->RunUntilIdle(); |
+ EXPECT_TRUE(needs_main_frame_); |
+ EXPECT_EQ(1u, event_queue().size()); |
+ RunPendingTasksWithSimulatedRaf(); |
+ EXPECT_EQ(0u, event_queue().size()); |
+} |
+ |
+TEST_P(MainThreadEventQueueTest, RafAlignedTouchInput) { |
+ // Don't run the test for when we aren't supporting raf aligned. |
+ if (!GetParam()) |
+ return; |
+ |
+ SyntheticWebTouchEvent kEvents[3]; |
+ kEvents[0].PressPoint(10, 10); |
+ kEvents[1].PressPoint(10, 10); |
+ kEvents[1].MovePoint(0, 50, 50); |
+ kEvents[2].PressPoint(10, 10); |
+ kEvents[2].ReleasePoint(0); |
+ |
+ EXPECT_FALSE(main_task_runner_->HasPendingTask()); |
+ EXPECT_EQ(0u, event_queue().size()); |
+ |
+ // Simulate enqueing a normal event, followed by "continious" events and then |
+ // a normal event. The "continious" events should not wait for RAF. |
+ for (SyntheticWebTouchEvent& event : kEvents) |
+ HandleEvent(event, INPUT_EVENT_ACK_STATE_SET_NON_BLOCKING); |
+ |
+ EXPECT_EQ(3u, event_queue().size()); |
+ EXPECT_TRUE(main_task_runner_->HasPendingTask()); |
+ EXPECT_TRUE(needs_main_frame_); |
+ main_task_runner_->RunUntilIdle(); |
+ EXPECT_EQ(0u, event_queue().size()); |
+ RunPendingTasksWithSimulatedRaf(); |
+ |
+ // Simulate the RAF running before the PostTask occurs. The first RAF |
+ // shouldn't do anything. |
+ HandleEvent(kEvents[0], INPUT_EVENT_ACK_STATE_SET_NON_BLOCKING); |
+ HandleEvent(kEvents[1], INPUT_EVENT_ACK_STATE_SET_NON_BLOCKING); |
+ EXPECT_EQ(2u, event_queue().size()); |
+ EXPECT_TRUE(needs_main_frame_); |
+ RunSimulatedRafOnce(); |
+ EXPECT_FALSE(needs_main_frame_); |
+ EXPECT_EQ(2u, event_queue().size()); |
+ RunPendingTasksWithSimulatedRaf(); |
+ EXPECT_EQ(0u, event_queue().size()); |
+} |
+ |
+TEST_P(MainThreadEventQueueTest, RafAlignedMaxSize) { |
+ // Don't run the test for when we aren't supporting raf aligned. |
+ if (!GetParam()) |
+ return; |
+ |
+ const size_t kNumEventsToQueue = 16; |
+ WebMouseWheelEvent mouseEvent = |
+ SyntheticWebMouseWheelEventBuilder::Build(10, 10, 0, 53, 0, false); |
+ |
+ EXPECT_FALSE(main_task_runner_->HasPendingTask()); |
+ EXPECT_EQ(0u, event_queue().size()); |
+ |
+ for (size_t i = 0; i < kNumEventsToQueue; ++i) { |
+ mouseEvent.modifiers = i; |
+ HandleEvent(mouseEvent, INPUT_EVENT_ACK_STATE_SET_NON_BLOCKING); |
+ } |
+ |
+ // There is a maximum number of events we handle in a RAF. kNumEventsToQueue |
+ // exceeds that. Ensure that two RAF calls need to run. |
+ EXPECT_EQ(kNumEventsToQueue, event_queue().size()); |
+ EXPECT_FALSE(main_task_runner_->HasPendingTask()); |
+ EXPECT_TRUE(needs_main_frame_); |
+ RunSimulatedRafOnce(); |
+ EXPECT_TRUE(needs_main_frame_); |
+ EXPECT_FALSE(main_task_runner_->HasPendingTask()); |
+ RunSimulatedRafOnce(); |
+ EXPECT_EQ(0u, event_queue().size()); |
+ EXPECT_FALSE(main_task_runner_->HasPendingTask()); |
+} |
+ |
+TEST_P(MainThreadEventQueueTest, BlockingTouchesDuringFling) { |
SyntheticWebTouchEvent kEvents[1]; |
kEvents[0].PressPoint(10, 10); |
kEvents[0].touchStartOrFirstTouchMove = true; |
@@ -274,7 +429,7 @@ TEST_F(MainThreadEventQueueTest, BlockingTouchesDuringFling) { |
EXPECT_FALSE(last_touch_start_forced_nonblocking_due_to_fling()); |
HandleEvent(kEvents[0], INPUT_EVENT_ACK_STATE_NOT_CONSUMED); |
- main_task_runner_->RunUntilIdle(); |
+ RunPendingTasksWithSimulatedRaf(); |
EXPECT_FALSE(main_task_runner_->HasPendingTask()); |
EXPECT_EQ(0u, event_queue().size()); |
EXPECT_EQ(1u, handled_events_.size()); |
@@ -289,7 +444,7 @@ TEST_F(MainThreadEventQueueTest, BlockingTouchesDuringFling) { |
kEvents[0].MovePoint(0, 30, 30); |
HandleEvent(kEvents[0], INPUT_EVENT_ACK_STATE_NOT_CONSUMED); |
- main_task_runner_->RunUntilIdle(); |
+ RunPendingTasksWithSimulatedRaf(); |
EXPECT_FALSE(main_task_runner_->HasPendingTask()); |
EXPECT_EQ(0u, event_queue().size()); |
EXPECT_EQ(2u, handled_events_.size()); |
@@ -305,7 +460,7 @@ TEST_F(MainThreadEventQueueTest, BlockingTouchesDuringFling) { |
kEvents[0].MovePoint(0, 50, 50); |
kEvents[0].touchStartOrFirstTouchMove = false; |
HandleEvent(kEvents[0], INPUT_EVENT_ACK_STATE_NOT_CONSUMED); |
- main_task_runner_->RunUntilIdle(); |
+ RunPendingTasksWithSimulatedRaf(); |
EXPECT_FALSE(main_task_runner_->HasPendingTask()); |
EXPECT_EQ(0u, event_queue().size()); |
EXPECT_EQ(3u, handled_events_.size()); |
@@ -319,7 +474,7 @@ TEST_F(MainThreadEventQueueTest, BlockingTouchesDuringFling) { |
kEvents[0].ReleasePoint(0); |
HandleEvent(kEvents[0], INPUT_EVENT_ACK_STATE_NOT_CONSUMED); |
- main_task_runner_->RunUntilIdle(); |
+ RunPendingTasksWithSimulatedRaf(); |
EXPECT_FALSE(main_task_runner_->HasPendingTask()); |
EXPECT_EQ(0u, event_queue().size()); |
EXPECT_EQ(4u, handled_events_.size()); |
@@ -332,7 +487,7 @@ TEST_F(MainThreadEventQueueTest, BlockingTouchesDuringFling) { |
EXPECT_EQ(kEvents[0], *last_touch_event); |
} |
-TEST_F(MainThreadEventQueueTest, BlockingTouchesOutsideFling) { |
+TEST_P(MainThreadEventQueueTest, BlockingTouchesOutsideFling) { |
SyntheticWebTouchEvent kEvents[1]; |
kEvents[0].PressPoint(10, 10); |
kEvents[0].touchStartOrFirstTouchMove = true; |
@@ -340,7 +495,7 @@ TEST_F(MainThreadEventQueueTest, BlockingTouchesOutsideFling) { |
set_enable_fling_passive_listener_flag(false); |
HandleEvent(kEvents[0], INPUT_EVENT_ACK_STATE_NOT_CONSUMED); |
- main_task_runner_->RunUntilIdle(); |
+ RunPendingTasksWithSimulatedRaf(); |
EXPECT_FALSE(main_task_runner_->HasPendingTask()); |
EXPECT_EQ(0u, event_queue().size()); |
EXPECT_EQ(1u, handled_events_.size()); |
@@ -356,7 +511,7 @@ TEST_F(MainThreadEventQueueTest, BlockingTouchesOutsideFling) { |
set_is_flinging(true); |
set_enable_fling_passive_listener_flag(false); |
HandleEvent(kEvents[0], INPUT_EVENT_ACK_STATE_NOT_CONSUMED); |
- main_task_runner_->RunUntilIdle(); |
+ RunPendingTasksWithSimulatedRaf(); |
EXPECT_FALSE(main_task_runner_->HasPendingTask()); |
EXPECT_EQ(0u, event_queue().size()); |
EXPECT_EQ(2u, handled_events_.size()); |
@@ -373,7 +528,7 @@ TEST_F(MainThreadEventQueueTest, BlockingTouchesOutsideFling) { |
set_is_flinging(false); |
set_enable_fling_passive_listener_flag(true); |
HandleEvent(kEvents[0], INPUT_EVENT_ACK_STATE_NOT_CONSUMED); |
- main_task_runner_->RunUntilIdle(); |
+ RunPendingTasksWithSimulatedRaf(); |
EXPECT_FALSE(main_task_runner_->HasPendingTask()); |
EXPECT_EQ(0u, event_queue().size()); |
EXPECT_EQ(3u, handled_events_.size()); |
@@ -389,7 +544,7 @@ TEST_F(MainThreadEventQueueTest, BlockingTouchesOutsideFling) { |
kEvents[0].MovePoint(0, 30, 30); |
HandleEvent(kEvents[0], INPUT_EVENT_ACK_STATE_NOT_CONSUMED); |
- main_task_runner_->RunUntilIdle(); |
+ RunPendingTasksWithSimulatedRaf(); |
EXPECT_FALSE(main_task_runner_->HasPendingTask()); |
EXPECT_EQ(0u, event_queue().size()); |
EXPECT_EQ(4u, handled_events_.size()); |
@@ -403,4 +558,8 @@ TEST_F(MainThreadEventQueueTest, BlockingTouchesOutsideFling) { |
EXPECT_EQ(kEvents[0], *last_touch_event); |
} |
-} // namespace content |
+INSTANTIATE_TEST_CASE_P(MainThreadEventQueueTests, |
tdresser
2016/08/24 13:43:00
Add a comment indicating what the bool means.
dtapuska
2016/08/24 17:10:07
done
|
+ MainThreadEventQueueTest, |
+ testing::Bool()); |
+ |
+} // namespace content |