Mir

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

Proposed by Daniel van Vugt
Status: Merged
Approved by: Daniel van Vugt
Approved revision: no longer in the source branch.
Merged at revision: 3254
Proposed branch: lp:~vanvugt/mir/fix-1476201
Merge into: lp:mir
Prerequisite: lp:~vanvugt/mir/better-scaling-test-2
Diff against target: 245 lines (+142/-9)
3 files modified
src/server/compositor/buffer_queue.cpp (+24/-4)
src/server/compositor/buffer_queue.h (+1/-0)
tests/unit-tests/compositor/test_buffer_queue.cpp (+117/-5)
To merge this branch: bzr merge lp:~vanvugt/mir/fix-1476201
Reviewer Review Type Date Requested Status
PS Jenkins bot (community) continuous-integration Approve
Mir CI Bot continuous-integration Approve
Alan Griffiths Approve
Mir development team Pending
Review via email: mp+269849@code.launchpad.net

Commit message

Enhance BufferQueue::buffers_ready_for_compositor() again, this time
to support the usage pattern found in QtMir so that it too can have
working detection of slow clients (to help us decide when to scale
to triple instead of double buffers). (LP: #1476201)

We could have changed QtMir instead, but I decided it's a perfectly
valid usage pattern and we should support both, making Mir more
robust in its ability to support third-party compositors.

To post a comment you must log in.
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: Needs Fixing (continuous-integration)
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
Alan Griffiths (alan-griffiths) wrote :

What are ghost frames?

review: Needs Information
Revision history for this message
Daniel van Vugt (vanvugt) wrote :

At least two of those sizeable comments in the code explain it. If you can think of a better noun, please suggest...

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)
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: 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
Mir CI Bot (mir-ci-bot) wrote :

PASSED: Continuous integration, rev:2838
https://mir-jenkins.ubuntu.com/job/mir-ci/21/
Executed test runs:
    None: https://mir-jenkins.ubuntu.com/job/generic-update-mp/21/console

Click here to trigger a rebuild:
https://mir-jenkins.ubuntu.com/job/mir-ci/21/rebuild

review: Approve (continuous-integration)
Revision history for this message
Cemil Azizoglu (cemil-azizoglu) wrote :

This one has been around for a while. Alan, are you happy with the name "ghost frames" or did you have a suggestion?

Revision history for this message
Alan Griffiths (alan-griffiths) wrote :

> This one has been around for a while. Alan, are you happy with the name "ghost
> frames" or did you have a suggestion?

I don't know what "ghost frames" are, so I have no suggestion. The comments leave me no wiser (and, if possible, I'd prefer the code to be readable without parsing "large comments").

Revision history for this message
Daniel van Vugt (vanvugt) wrote :

"Ghost frame" terminology now removed.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :

PASSED: Continuous integration, rev:2857
http://jenkins.qa.ubuntu.com/job/mir-ci/5982/
Executed test runs:
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-android-vivid-i386-build/5491
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-clang-vivid-amd64-build/4398
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-vivid-touch/5447
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-xenial-touch/260
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-xenial-amd64-ci/306
        deb: http://jenkins.qa.ubuntu.com/job/mir-xenial-amd64-ci/306/artifact/work/output/*zip*/output.zip
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-xenial-i386-ci/306
        deb: http://jenkins.qa.ubuntu.com/job/mir-xenial-i386-ci/306/artifact/work/output/*zip*/output.zip
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-builder-vivid-armhf/5444
        deb: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-builder-vivid-armhf/5444/artifact/work/output/*zip*/output.zip
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-runner-touch/7929
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/26565
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-builder-xenial-armhf/256
        deb: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-builder-xenial-armhf/256/artifact/work/output/*zip*/output.zip
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-runner-xenial-touch/114
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/26568

Click here to trigger a rebuild:
http://s-jenkins.ubuntu-ci:8080/job/mir-ci/5982/rebuild

review: Approve (continuous-integration)
Revision history for this message
Alan Griffiths (alan-griffiths) wrote :

It would be nice to have some automated performance testing for the scenario this is intended to support. Especially as this optimization is likely to be bypassed by the "new buffer semantics" work in progress elsewhere.

review: Approve
Revision history for this message
Daniel van Vugt (vanvugt) wrote :

The automated performance testing (other than the unit tests below) is ready and waiting. The ClientLatency acceptance tests will start failing (unless updated) when/if dynamic queue scaling is re-enabled, as is documented in the ClientLatency test.

Revision history for this message
Mir CI Bot (mir-ci-bot) wrote :

PASSED: Continuous integration, rev:2857
https://mir-jenkins.ubuntu.com/job/mir-ci/36/
Executed test runs:
    None: https://mir-jenkins.ubuntu.com/job/generic-update-mp/36/console

Click here to trigger a rebuild:
https://mir-jenkins.ubuntu.com/job/mir-ci/36/rebuild

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

Possibly not even related to this branch, given queue scaling is still disabled:

12: /tmp/buildd/mir-0.19.0bzr2858pkg0xenial158/tests/acceptance-tests/test_latency.cpp:245: Failure
12: Value of: observed_latency
12: Expected: is < 3.4
12: Actual: 3.40404 (of type float)

Try again.

Revision history for this message
Mir CI Bot (mir-ci-bot) wrote :

PASSED: Continuous integration, rev:2859
https://mir-jenkins.ubuntu.com/job/mir-ci/49/
Executed test runs:
    None: https://mir-jenkins.ubuntu.com/job/generic-update-mp/49/console

Click here to trigger a rebuild:
https://mir-jenkins.ubuntu.com/job/mir-ci/49/rebuild

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

PASSED: Continuous integration, rev:2859
http://jenkins.qa.ubuntu.com/job/mir-ci/6014/
Executed test runs:
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-android-vivid-i386-build/5530
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-clang-vivid-amd64-build/4437
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-vivid-touch/5486
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-xenial-touch/275
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-xenial-amd64-ci/338
        deb: http://jenkins.qa.ubuntu.com/job/mir-xenial-amd64-ci/338/artifact/work/output/*zip*/output.zip
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-xenial-i386-ci/338
        deb: http://jenkins.qa.ubuntu.com/job/mir-xenial-i386-ci/338/artifact/work/output/*zip*/output.zip
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-builder-vivid-armhf/5483
        deb: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-builder-vivid-armhf/5483/artifact/work/output/*zip*/output.zip
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-runner-touch/7954
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/26638
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-builder-xenial-armhf/271
        deb: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-builder-xenial-armhf/271/artifact/work/output/*zip*/output.zip
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-runner-xenial-touch/129
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/26640

Click here to trigger a rebuild:
http://s-jenkins.ubuntu-ci:8080/job/mir-ci/6014/rebuild

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

PASSED: Continuous integration, rev:2860
http://jenkins.qa.ubuntu.com/job/mir-ci/6043/
Executed test runs:
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-android-vivid-i386-build/5565
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-clang-vivid-amd64-build/4472
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-vivid-touch/5521
    FAILURE: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-xenial-touch/292/console
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-xenial-amd64-ci/367
        deb: http://jenkins.qa.ubuntu.com/job/mir-xenial-amd64-ci/367/artifact/work/output/*zip*/output.zip
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-xenial-i386-ci/367
        deb: http://jenkins.qa.ubuntu.com/job/mir-xenial-i386-ci/367/artifact/work/output/*zip*/output.zip
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-builder-vivid-armhf/5518
        deb: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-builder-vivid-armhf/5518/artifact/work/output/*zip*/output.zip
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-runner-touch/7981
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/26739
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-builder-xenial-armhf/288
        deb: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-builder-xenial-armhf/288/artifact/work/output/*zip*/output.zip
    FAILURE: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-runner-xenial-touch/145/console
    None: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/26751/console

Click here to trigger a rebuild:
http://s-jenkins.ubuntu-ci:8080/job/mir-ci/6043/rebuild

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

FAILED: Continuous integration, rev:2860
https://mir-jenkins.ubuntu.com/job/mir-ci/81/
Executed test runs:
    None: https://mir-jenkins.ubuntu.com/job/generic-update-mp/81/console

Click here to trigger a rebuild:
https://mir-jenkins.ubuntu.com/job/mir-ci/81/rebuild

review: Needs Fixing (continuous-integration)
Revision history for this message
Mir CI Bot (mir-ci-bot) wrote :

PASSED: Continuous integration, rev:2861
https://mir-jenkins.ubuntu.com/job/mir-ci/82/
Executed test runs:
    None: https://mir-jenkins.ubuntu.com/job/generic-update-mp/82/console

Click here to trigger a rebuild:
https://mir-jenkins.ubuntu.com/job/mir-ci/82/rebuild

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

PASSED: Continuous integration, rev:2863
https://mir-jenkins.ubuntu.com/job/mir-ci/90/
Executed test runs:
    None: https://mir-jenkins.ubuntu.com/job/generic-update-mp/91/console

Click here to trigger a rebuild:
https://mir-jenkins.ubuntu.com/job/mir-ci/90/rebuild

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

PASSED: Continuous integration, rev:2861
http://jenkins.qa.ubuntu.com/job/mir-ci/6058/
Executed test runs:
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-android-vivid-i386-build/5589
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-clang-vivid-amd64-build/4496
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-vivid-touch/5545
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-xenial-touch/299
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-xenial-amd64-ci/382
        deb: http://jenkins.qa.ubuntu.com/job/mir-xenial-amd64-ci/382/artifact/work/output/*zip*/output.zip
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-xenial-i386-ci/382
        deb: http://jenkins.qa.ubuntu.com/job/mir-xenial-i386-ci/382/artifact/work/output/*zip*/output.zip
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-builder-vivid-armhf/5542
        deb: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-builder-vivid-armhf/5542/artifact/work/output/*zip*/output.zip
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-runner-touch/8001
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/26787
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-builder-xenial-armhf/295
        deb: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-builder-xenial-armhf/295/artifact/work/output/*zip*/output.zip
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-runner-xenial-touch/151
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/26797

Click here to trigger a rebuild:
http://s-jenkins.ubuntu-ci:8080/job/mir-ci/6058/rebuild

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

PASSED: Continuous integration, rev:2863
http://jenkins.qa.ubuntu.com/job/mir-ci/6065/
Executed test runs:
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-android-vivid-i386-build/5597
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-clang-vivid-amd64-build/4504
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-vivid-touch/5553
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-xenial-touch/303
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-xenial-amd64-ci/389
        deb: http://jenkins.qa.ubuntu.com/job/mir-xenial-amd64-ci/389/artifact/work/output/*zip*/output.zip
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-xenial-i386-ci/389
        deb: http://jenkins.qa.ubuntu.com/job/mir-xenial-i386-ci/389/artifact/work/output/*zip*/output.zip
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-builder-vivid-armhf/5550
        deb: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-builder-vivid-armhf/5550/artifact/work/output/*zip*/output.zip
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-runner-touch/8006
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/26807
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-builder-xenial-armhf/299
        deb: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-builder-xenial-armhf/299/artifact/work/output/*zip*/output.zip
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-runner-xenial-touch/155
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/26811

Click here to trigger a rebuild:
http://s-jenkins.ubuntu-ci:8080/job/mir-ci/6065/rebuild

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

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'src/server/compositor/buffer_queue.cpp'
--- src/server/compositor/buffer_queue.cpp 2015-10-20 03:30:00 +0000
+++ src/server/compositor/buffer_queue.cpp 2016-01-19 21:00:22 +0000
@@ -139,6 +139,7 @@
139 : nbuffers{nbuffers},139 : nbuffers{nbuffers},
140 frame_deadlines_threshold{-1}, // Disable scaling by default140 frame_deadlines_threshold{-1}, // Disable scaling by default
141 frame_deadlines_met{0},141 frame_deadlines_met{0},
142 scheduled_extra_frames{0},
142 frame_dropping_enabled{false},143 frame_dropping_enabled{false},
143 current_compositor_buffer_valid{false},144 current_compositor_buffer_valid{false},
144 the_properties{props},145 the_properties{props},
@@ -266,6 +267,14 @@
266267
267 auto const buffer = pop(buffers_owned_by_client);268 auto const buffer = pop(buffers_owned_by_client);
268 ready_to_composite_queue.push_back(buffer);269 ready_to_composite_queue.push_back(buffer);
270
271 /*
272 * Timerless client performance detection:
273 * Over-schedule the compositor so that it can detect if the client
274 * is falling behind. Otherwise the compositor itself goes to sleep
275 * and wouldn't be able to tell a slow client from a fast one.
276 */
277 scheduled_extra_frames = frame_deadlines_threshold - 1;
269}278}
270279
271std::shared_ptr<mg::Buffer>280std::shared_ptr<mg::Buffer>
@@ -276,6 +285,15 @@
276 bool use_current_buffer = false;285 bool use_current_buffer = false;
277 if (is_a_current_buffer_user(user_id)) // Primary/fastest display286 if (is_a_current_buffer_user(user_id)) // Primary/fastest display
278 {287 {
288 /*
289 * Yes I know different compositor user_ids will get different
290 * results with this but that's OK, and actually more efficient.
291 * We only need to overschedule one display at most for the
292 * slow client detection to work.
293 */
294 if (scheduled_extra_frames > 0)
295 --scheduled_extra_frames;
296
279 if (ready_to_composite_queue.empty())297 if (ready_to_composite_queue.empty())
280 frame_deadlines_met = 0;298 frame_deadlines_met = 0;
281 else if (frame_deadlines_met < frame_deadlines_threshold)299 else if (frame_deadlines_met < frame_deadlines_threshold)
@@ -454,21 +472,21 @@
454 }472 }
455473
456 /*474 /*
457 * Intentionally schedule one more frame than we need, and for good475 * Intentionally schedule more frames than we need, and for good
458 * reason... We can only accurately detect frame_deadlines_met in476 * reason... We can only accurately detect frame_deadlines_met in
459 * compositor_acquire if compositor_acquire is still waking up at full477 * compositor_acquire if compositor_acquire is still waking up at full
460 * frame rate even with a slow client. This is crucial to scaling the478 * frame rate even with a slow client. This is crucial to scaling the
461 * queue performance dynamically in "client_ahead_of_compositor".479 * queue performance dynamically in "client_ahead_of_compositor".
462 * But don't be concerned; very little is lost by over-scheduling. Under480 * But don't be concerned; very little is lost by over-scheduling. Under
463 * normal smooth rendering conditions all frames are used (not wasted).481 * normal smooth rendering conditions all frames are used (not wasted).
464 * And under sluggish client rendering conditions the extra frame has a482 * And under sluggish client rendering conditions the extra frames have a
465 * critical role in providing a sample point in which we detect if the483 * critical role in providing a sample point in which we detect if the
466 * client is keeping up. Only when the compositor changes from active to484 * client is keeping up. Only when the compositor changes from active to
467 * idle is the extra frame wasted. Sounds like a reasonable price to pay485 * idle is the extra frame wasted. Sounds like a reasonable price to pay
468 * for dynamic performance monitoring.486 * for dynamic performance monitoring.
469 */487 */
470 if (count && frame_deadlines_threshold >= 0)488 if (frame_deadlines_threshold >= 0 && scheduled_extra_frames > 0)
471 ++count;489 count += scheduled_extra_frames;
472490
473 return count;491 return count;
474}492}
@@ -660,6 +678,8 @@
660 std::unique_lock<decltype(guard)> lock{guard};678 std::unique_lock<decltype(guard)> lock{guard};
661 release(buffer, std::move(lock));679 release(buffer, std::move(lock));
662 }680 }
681
682 scheduled_extra_frames = 0;
663}683}
664684
665void mc::BufferQueue::drop_client_requests()685void mc::BufferQueue::drop_client_requests()
666686
=== modified file 'src/server/compositor/buffer_queue.h'
--- src/server/compositor/buffer_queue.h 2015-09-17 20:32:32 +0000
+++ src/server/compositor/buffer_queue.h 2016-01-19 21:00:22 +0000
@@ -109,6 +109,7 @@
109 int nbuffers;109 int nbuffers;
110 int frame_deadlines_threshold;110 int frame_deadlines_threshold;
111 int frame_deadlines_met;111 int frame_deadlines_met;
112 int scheduled_extra_frames;
112 bool frame_dropping_enabled;113 bool frame_dropping_enabled;
113 bool current_compositor_buffer_valid;114 bool current_compositor_buffer_valid;
114 graphics::BufferProperties the_properties;115 graphics::BufferProperties the_properties;
115116
=== modified file 'tests/unit-tests/compositor/test_buffer_queue.cpp'
--- tests/unit-tests/compositor/test_buffer_queue.cpp 2015-09-17 20:32:32 +0000
+++ tests/unit-tests/compositor/test_buffer_queue.cpp 2016-01-19 21:00:22 +0000
@@ -1405,6 +1405,33 @@
1405 q.compositor_release(c);1405 q.compositor_release(c);
1406}1406}
14071407
1408TEST_P(WithTwoOrMoreBuffers, buffers_ready_count_tapers_off)
1409{ // Another test related to QtMir's style of doing things (LP: #1476201)
1410 mc::BufferQueue q{nbuffers, allocator, basic_properties, policy_factory};
1411
1412 q.set_scaling_delay(3);
1413
1414 ASSERT_THAT(q.buffers_ready_for_compositor(this), Eq(0));
1415
1416 // Produce one frame
1417 q.client_release(client_acquire_sync(q));
1418
1419 // Ensure we're told multiple frames are ready to facilitate the
1420 // compositor detecting a slow client that misses the second one.
1421 ASSERT_THAT(q.buffers_ready_for_compositor(this), Ge(2));
1422
1423 // Consume one frame
1424 q.compositor_release(q.compositor_acquire(this));
1425
1426 // Finally verify the count is tapering off instead of dropping off
1427 ASSERT_THAT(q.buffers_ready_for_compositor(this), Ge(1));
1428
1429 for (int flush = 0; flush < q.scaling_delay(); ++flush)
1430 q.compositor_release(q.compositor_acquire(this));
1431
1432 ASSERT_THAT(q.buffers_ready_for_compositor(this), Eq(0));
1433}
1434
1408TEST_P(WithTwoOrMoreBuffers, buffers_ready_eventually_reaches_zero)1435TEST_P(WithTwoOrMoreBuffers, buffers_ready_eventually_reaches_zero)
1409{1436{
1410 mc::BufferQueue q{nbuffers, allocator, basic_properties, policy_factory};1437 mc::BufferQueue q{nbuffers, allocator, basic_properties, policy_factory};
@@ -1425,11 +1452,12 @@
1425 {1452 {
1426 ASSERT_NE(0, q.buffers_ready_for_compositor(&monitor[m]));1453 ASSERT_NE(0, q.buffers_ready_for_compositor(&monitor[m]));
14271454
1428 // Double consume to account for the +1 that1455 // Extra consume to account for the additional frames that
1429 // buffers_ready_for_compositor adds to do dynamic performance1456 // buffers_ready_for_compositor adds to do dynamic performance
1430 // detection.1457 // detection.
1431 q.compositor_release(q.compositor_acquire(&monitor[m]));1458 int const nflush = (q.scaling_delay() > 0) ? q.scaling_delay() : 1;
1432 q.compositor_release(q.compositor_acquire(&monitor[m]));1459 for (int flush = 0; flush < nflush; ++flush)
1460 q.compositor_release(q.compositor_acquire(&monitor[m]));
14331461
1434 ASSERT_EQ(0, q.buffers_ready_for_compositor(&monitor[m]));1462 ASSERT_EQ(0, q.buffers_ready_for_compositor(&monitor[m]));
1435 }1463 }
@@ -1711,6 +1739,91 @@
1711 EXPECT_THAT(buffers_acquired.size(), Eq(2));1739 EXPECT_THAT(buffers_acquired.size(), Eq(2));
1712}1740}
17131741
1742TEST_P(WithThreeOrMoreBuffers, queue_size_scales_up_without_accumulator)
1743{ // A regression test similar to above but designed to mimic QtMir
1744 // for LP: #1476201.
1745
1746 q.allow_framedropping(false);
1747 std::unordered_set<mg::Buffer *> buffers_acquired;
1748
1749 int const delay = 3;
1750 q.set_scaling_delay(delay);
1751
1752 int const nframes = 100;
1753
1754 std::shared_ptr<AcquireWaitHandle> client;
1755
1756 for (int frame = 0; frame < nframes; ++frame)
1757 {
1758 do
1759 {
1760 if (!client)
1761 client = client_acquire_async(q);
1762 if (client->has_acquired_buffer())
1763 {
1764 if (frame > delay)
1765 buffers_acquired.insert(client->buffer());
1766 client->release_buffer();
1767 client.reset();
1768 }
1769 } while (!client);
1770
1771 q.compositor_release(q.compositor_acquire(nullptr));
1772 }
1773 // Expect double-buffers for fast clients
1774 EXPECT_THAT(buffers_acquired.size(), Eq(2));
1775
1776 // Now check what happens if the client becomes slow...
1777 buffers_acquired.clear();
1778 for (int frame = 0; frame < nframes;)
1779 {
1780 do
1781 {
1782 if (!client)
1783 client = client_acquire_async(q);
1784 if (client->has_acquired_buffer())
1785 {
1786 if (frame > delay)
1787 buffers_acquired.insert(client->buffer());
1788 client->release_buffer();
1789 client.reset();
1790 }
1791 } while (!client);
1792
1793 // Mimic QtMir in that it tests buffers ready as a boolean and does
1794 // not keep its own accumulator in the compositor:
1795 while (q.buffers_ready_for_compositor(nullptr))
1796 {
1797 q.compositor_release(q.compositor_acquire(nullptr));
1798 ++frame;
1799 }
1800 }
1801 // Expect at least triple buffers for sluggish clients
1802 EXPECT_THAT(buffers_acquired.size(), Ge(3));
1803
1804 // And what happens if the client becomes fast again?...
1805 buffers_acquired.clear();
1806 for (int frame = 0; frame < nframes; ++frame)
1807 {
1808 do
1809 {
1810 if (!client)
1811 client = client_acquire_async(q);
1812 if (client->has_acquired_buffer())
1813 {
1814 if (frame > delay)
1815 buffers_acquired.insert(client->buffer());
1816 client->release_buffer();
1817 client.reset();
1818 }
1819 } while (!client);
1820
1821 q.compositor_release(q.compositor_acquire(nullptr));
1822 }
1823 // Expect double-buffers for fast clients
1824 EXPECT_THAT(buffers_acquired.size(), Eq(2));
1825}
1826
1714TEST_P(WithThreeOrMoreBuffers, greedy_compositors_need_triple_buffers)1827TEST_P(WithThreeOrMoreBuffers, greedy_compositors_need_triple_buffers)
1715{1828{
1716 /*1829 /*
@@ -1755,8 +1868,7 @@
1755 ASSERT_EQ(0, q.buffers_ready_for_compositor(this));1868 ASSERT_EQ(0, q.buffers_ready_for_compositor(this));
1756 q.client_release(client_acquire_sync(q));1869 q.client_release(client_acquire_sync(q));
17571870
1758 // Detecting a slow client requires scheduling at least one extra1871 // Detecting a slow client requires scheduling extra frames
1759 // frame...
1760 int nready = q.buffers_ready_for_compositor(this);1872 int nready = q.buffers_ready_for_compositor(this);
1761 ASSERT_THAT(nready, Ge(2));1873 ASSERT_THAT(nready, Ge(2));
1762 for (int i = 0; i < nready; ++i)1874 for (int i = 0; i < nready; ++i)

Subscribers

People subscribed via source and target branches