Mir

Merge lp:~vanvugt/mir/fix-1372300 into lp:mir

Proposed by Daniel van Vugt
Status: Merged
Merged at revision: 1936
Proposed branch: lp:~vanvugt/mir/fix-1372300
Merge into: lp:mir
Diff against target: 84 lines (+46/-13)
2 files modified
src/common/input/android/android_input_receiver.cpp (+1/-13)
tests/unit-tests/client/input/test_android_input_receiver.cpp (+45/-0)
To merge this branch: bzr merge lp:~vanvugt/mir/fix-1372300
Reviewer Review Type Date Requested Status
PS Jenkins bot (community) continuous-integration Needs Fixing
Alexandros Frantzis (community) Approve
Review via email: mp+235573@code.launchpad.net

Commit message

Fix jerky/stuttering event delivery that could happen inside
nested servers sometimes (LP: #1372300)

Waiting significantly longer than a frame before consuming previously
batched events is too dangerous in slow raw-event environments
(nested servers or very slow input devices). It causes frame skipping.

To post a comment you must log in.
Revision history for this message
Daniel van Vugt (vanvugt) wrote :

If you decide to do any manual testing, beware of bug 1372850, which is technically unrelated.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Alexandros Frantzis (afrantzis) wrote :

Confirming this fixes the issue.

review: Approve
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'src/common/input/android/android_input_receiver.cpp'
--- src/common/input/android/android_input_receiver.cpp 2014-09-11 05:51:44 +0000
+++ src/common/input/android/android_input_receiver.cpp 2014-09-24 07:21:12 +0000
@@ -134,23 +134,11 @@
134 }134 }
135135
136 auto reduced_timeout = timeout;136 auto reduced_timeout = timeout;
137 if (input_consumer->hasDeferredEvent())137 if (input_consumer->hasDeferredEvent() || input_consumer->hasPendingBatch())
138 {138 {
139 // consume() didn't finish last time. Retry it immediately.139 // consume() didn't finish last time. Retry it immediately.
140 reduced_timeout = std::chrono::milliseconds::zero();140 reduced_timeout = std::chrono::milliseconds::zero();
141 }141 }
142 else if (input_consumer->hasPendingBatch())
143 {
144 /*
145 * A batch is pending and must be completed or else the client could
146 * be starved of events. But don't hurry. A continuous motion gesture
147 * will wake us up much sooner than 50ms. This timeout is only reached
148 * in the case that motion has ended (fingers lifted).
149 */
150 std::chrono::milliseconds const motion_idle_timeout(50);
151 if (timeout.count() < 0 || timeout > motion_idle_timeout)
152 reduced_timeout = motion_idle_timeout;
153 }
154142
155 auto result = looper->pollOnce(reduced_timeout.count());143 auto result = looper->pollOnce(reduced_timeout.count());
156 if (result == ALOOPER_POLL_WAKE)144 if (result == ALOOPER_POLL_WAKE)
157145
=== modified file 'tests/unit-tests/client/input/test_android_input_receiver.cpp'
--- tests/unit-tests/client/input/test_android_input_receiver.cpp 2014-09-11 05:51:44 +0000
+++ tests/unit-tests/client/input/test_android_input_receiver.cpp 2014-09-24 07:21:12 +0000
@@ -204,6 +204,51 @@
204 EXPECT_FALSE(receiver.next_event(std::chrono::milliseconds(1), ev)); // Minimal timeout needed for valgrind204 EXPECT_FALSE(receiver.next_event(std::chrono::milliseconds(1), ev)); // Minimal timeout needed for valgrind
205}205}
206206
207TEST_F(AndroidInputReceiverSetup, slow_raw_input_doesnt_cause_frameskipping)
208{ // Regression test for LP: #1372300
209 using namespace testing;
210 using namespace std::chrono;
211
212 nsecs_t t = 0;
213
214 mircva::InputReceiver receiver(
215 client_fd, std::make_shared<mircv::NullInputReceiverReport>(),
216 [&t](int) { return t; }
217 );
218 TestingInputProducer producer(server_fd);
219
220 nsecs_t const one_millisecond = 1000000ULL;
221 nsecs_t const one_second = 1000 * one_millisecond;
222 nsecs_t const one_frame = one_second / 60;
223
224 MirEvent ev;
225
226 producer.produce_a_motion_event(123, 456, t);
227 producer.produce_a_key_event();
228 flush_channels();
229
230 std::chrono::milliseconds const max_timeout(1000);
231
232 // Key events don't get resampled. Will be reported first.
233 ASSERT_TRUE(receiver.next_event(max_timeout, ev));
234 ASSERT_EQ(mir_event_type_key, ev.type);
235
236 // The motion is still too new. Won't be reported yet, but is batched.
237 auto start = high_resolution_clock::now();
238 ASSERT_FALSE(receiver.next_event(max_timeout, ev));
239 auto end = high_resolution_clock::now();
240 auto duration = end - start;
241
242 // Verify we timed out in under a frame (LP: #1372300)
243 // Sadly using real time as droidinput::Looper doesn't use a mocked clock.
244 ASSERT_LT(duration_cast<nanoseconds>(duration).count(), one_frame);
245
246 // But later in a frame or so, the motion will be reported:
247 t += one_frame;
248 ASSERT_TRUE(receiver.next_event(max_timeout, ev));
249 ASSERT_EQ(mir_event_type_motion, ev.type);
250}
251
207TEST_F(AndroidInputReceiverSetup, rendering_does_not_lag_behind_input)252TEST_F(AndroidInputReceiverSetup, rendering_does_not_lag_behind_input)
208{253{
209 using namespace testing;254 using namespace testing;

Subscribers

People subscribed via source and target branches