Mir

Merge lp:~vanvugt/mir/fix-1584894 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: 3804
Proposed branch: lp:~vanvugt/mir/fix-1584894
Merge into: lp:mir
Diff against target: 202 lines (+66/-30)
5 files modified
src/platforms/mesa/server/kms/display_buffer.cpp (+20/-12)
src/platforms/mesa/server/kms/kms_page_flipper.cpp (+6/-0)
src/platforms/mesa/server/kms/real_kms_output.cpp (+9/-6)
tests/unit-tests/platforms/mesa/kms/test_display.cpp (+27/-8)
tests/unit-tests/platforms/mesa/kms/test_real_kms_output.cpp (+4/-4)
To merge this branch: bzr merge lp:~vanvugt/mir/fix-1584894
Reviewer Review Type Date Requested Status
Kevin DuBois (community) Approve
Andreas Pokorny (community) Approve
Mir CI Bot continuous-integration Approve
Review via email: mp+309819@code.launchpad.net

Commit message

If page flipping fails then fall back to blitting the screen
instead of crashing. This allows Mir servers to run under VirtualBox
(LP: #1584894) and also on ASpeed graphics chips.

Server-side GL rendering works fine, as do software clients. Hardware
(GL) clients presently just hang and never render, but I'm happy to
declare that outside the scope of LP: #1584894.

Description of the change

Surprisingly resizing the screen (the VirtualBox window) also works. VirtualBox simply 'unplugs' the old virtual display and plugs in a new one with the new dimensions. And Mir already supports such hotplugging.

To post a comment you must log in.
Revision history for this message
Mir CI Bot (mir-ci-bot) wrote :

PASSED: Continuous integration, rev:3801
https://mir-jenkins.ubuntu.com/job/mir-ci/2097/
Executed test runs:
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-mir/2697
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-0-fetch/2760
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=vivid+overlay/2752
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=xenial+overlay/2752
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=yakkety/2752
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=clang,platform=mesa,release=yakkety/2726
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=clang,platform=mesa,release=yakkety/2726/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=xenial+overlay/2726
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=xenial+overlay/2726/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=yakkety/2726
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=yakkety/2726/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=cross-armhf,compiler=gcc,platform=android,release=vivid+overlay/2726
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=cross-armhf,compiler=gcc,platform=android,release=vivid+overlay/2726/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=android,release=vivid+overlay/2726
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=android,release=vivid+overlay/2726/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=mesa,release=xenial+overlay/2726
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=mesa,release=xenial+overlay/2726/artifact/output/*zip*/output.zip

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

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

The lack of hardware client support is probably because DRM_CAP_PRIME is missing (returned as zero) under VirtualBox. We may need to fall back to flink to resolve that on systems that lack PRIME. I'm hoping that's all it is...

Revision history for this message
Andreas Pokorny (andreas-pokorny) wrote :

I tried it on a ast-drm system. But the system behaves strange compared to x11. I.e. in fingerpaint one mouse down the system freezes for a short time - or the frame rate drops to below one frame per second. I havent tried virtual box - but the vbox drm driver code claims to be a fork of ast.

Approve because it is an improvement over crashing on startup..

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

Fingerpaint might be driving the display too hard (since it uses swap interval 0). Maybe try the -w option to force swap interval 1. That said, there is no throttling in this code path so my VM for example renders >80FPS (according to compositor report) despite the virtual output reporting 59.8Hz.

If your ast system supports wait for vblank then we should do that (after set_crtc) to slow it down, perhaps. Or just sleep, in case the driver doesn't support wait for vblank.

Revision history for this message
Andreas Pokorny (andreas-pokorny) wrote :

It also happens with flicker.. I will add a few reports to learn more. It would be easier if we could restrict mir to only open specific dri nodes.. I currently have to remove the amd card, because it would otherwise try to poke on the amd card.. especially then for rendering.. and the aspeed then stops working.

Revision history for this message
Kevin DuBois (kdub) wrote :

alright by me

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'src/platforms/mesa/server/kms/display_buffer.cpp'
--- src/platforms/mesa/server/kms/display_buffer.cpp 2016-10-12 13:31:04 +0000
+++ src/platforms/mesa/server/kms/display_buffer.cpp 2016-11-02 08:19:38 +0000
@@ -22,6 +22,7 @@
22#include "bypass.h"22#include "bypass.h"
23#include "gbm_buffer.h"23#include "gbm_buffer.h"
24#include "mir/fatal.h"24#include "mir/fatal.h"
25#include "mir/log.h"
25#include "native_buffer.h"26#include "native_buffer.h"
2627
27#include <boost/throw_exception.hpp>28#include <boost/throw_exception.hpp>
@@ -247,8 +248,17 @@
247{248{
248 for (auto& output : outputs)249 for (auto& output : outputs)
249 {250 {
251 /*
252 * Note that failure to set the CRTC is not a fatal error. This can
253 * happen under normal conditions when resizing VirtualBox (which
254 * actually removes and replaces the virtual output each time so
255 * sometimes it's really not there). Xorg often reports similar
256 * errors, and it's not fatal.
257 */
250 if (!output->set_crtc(forced_frame->get_drm_fb_id()))258 if (!output->set_crtc(forced_frame->get_drm_fb_id()))
251 fatal_error("Failed to set DRM CRTC");259 mir::log_error("Failed to set DRM CRTC. "
260 "Screen contents may be incomplete. "
261 "Try plugging the monitor in again.");
252 }262 }
253}263}
254264
@@ -275,19 +285,17 @@
275 }285 }
276286
277 /*287 /*
278 * Schedule the current front buffer object for display, and wait288 * Try to schedule a page flip as first preference to avoid tearing.
279 * for it to be actually displayed (flipped).289 * [will complete in a background thread]
280 *
281 * If the flip fails, release the buffer object to make it available
282 * for future rendering.
283 */290 */
284 if (!needs_set_crtc && !schedule_page_flip(bufobj))291 if (!needs_set_crtc && !schedule_page_flip(bufobj))
285 {292 needs_set_crtc = true;
286 if (!bypass_buf)293
287 bufobj->release();294 /*
288 fatal_error("Failed to schedule page flip");295 * Fallback blitting: Not pretty, since it may tear. VirtualBox seems
289 }296 * to need to do this on every frame. [will complete in this thread]
290 else if (needs_set_crtc)297 */
298 if (needs_set_crtc)
291 {299 {
292 set_crtc(bufobj);300 set_crtc(bufobj);
293 needs_set_crtc = false;301 needs_set_crtc = false;
294302
=== modified file 'src/platforms/mesa/server/kms/kms_page_flipper.cpp'
--- src/platforms/mesa/server/kms/kms_page_flipper.cpp 2016-10-12 06:03:15 +0000
+++ src/platforms/mesa/server/kms/kms_page_flipper.cpp 2016-11-02 08:19:38 +0000
@@ -71,6 +71,12 @@
7171
72 pending_page_flips[crtc_id] = PageFlipEventData{crtc_id, connector_id, this};72 pending_page_flips[crtc_id] = PageFlipEventData{crtc_id, connector_id, this};
7373
74 /*
75 * It appears we can't tell the difference between flipping being
76 * unsupported or failing for other reasons. On VirtualBox this always
77 * fails with -22 (Invalid argument) despite the arguments being
78 * apparently valid.
79 */
74 auto ret = drmModePageFlip(drm_fd, crtc_id, fb_id,80 auto ret = drmModePageFlip(drm_fd, crtc_id, fb_id,
75 DRM_MODE_PAGE_FLIP_EVENT,81 DRM_MODE_PAGE_FLIP_EVENT,
76 &pending_page_flips[crtc_id]);82 &pending_page_flips[crtc_id]);
7783
=== modified file 'src/platforms/mesa/server/kms/real_kms_output.cpp'
--- src/platforms/mesa/server/kms/real_kms_output.cpp 2016-11-01 09:34:45 +0000
+++ src/platforms/mesa/server/kms/real_kms_output.cpp 2016-11-02 08:19:38 +0000
@@ -112,8 +112,9 @@
112{112{
113 if (!ensure_crtc())113 if (!ensure_crtc())
114 {114 {
115 fatal_error("Output %s has no associated CRTC to set a framebuffer on",115 mir::log_error("Output %s has no associated CRTC to set a framebuffer on",
116 mgk::connector_name(connector).c_str());116 mgk::connector_name(connector).c_str());
117 return false;
117 }118 }
118119
119 auto ret = drmModeSetCrtc(drm_fd, current_crtc->crtc_id,120 auto ret = drmModeSetCrtc(drm_fd, current_crtc->crtc_id,
@@ -165,8 +166,9 @@
165 return true;166 return true;
166 if (!current_crtc)167 if (!current_crtc)
167 {168 {
168 fatal_error("Output %s has no associated CRTC to schedule page flips on",169 mir::log_error("Output %s has no associated CRTC to schedule page flips on",
169 mgk::connector_name(connector).c_str());170 mgk::connector_name(connector).c_str());
171 return false;
170 }172 }
171 return page_flipper->schedule_flip(current_crtc->crtc_id, fb_id, connector_id);173 return page_flipper->schedule_flip(current_crtc->crtc_id, fb_id, connector_id);
172}174}
@@ -285,8 +287,9 @@
285{287{
286 if (!ensure_crtc())288 if (!ensure_crtc())
287 {289 {
288 fatal_error("Output %s has no associated CRTC to set gamma on",290 mir::log_warning("Output %s has no associated CRTC to set gamma on",
289 mgk::connector_name(connector).c_str());291 mgk::connector_name(connector).c_str());
292 return;
290 }293 }
291294
292 if (gamma.red.size() != gamma.green.size() ||295 if (gamma.red.size() != gamma.green.size() ||
293296
=== modified file 'tests/unit-tests/platforms/mesa/kms/test_display.cpp'
--- tests/unit-tests/platforms/mesa/kms/test_display.cpp 2016-10-12 06:03:15 +0000
+++ tests/unit-tests/platforms/mesa/kms/test_display.cpp 2016-11-02 08:19:38 +0000
@@ -458,10 +458,23 @@
458458
459 setup_post_update_expectations();459 setup_post_update_expectations();
460460
461 // clear_crtc happens at some stage. Not interesting.
462 EXPECT_CALL(mock_drm, drmModeSetCrtc(mock_drm.fake_drm.fd(),
463 crtc_id, 0,
464 _, _, _, _, _))
465 .WillOnce(Return(0));
466
461 {467 {
462 InSequence s;468 InSequence s;
463469
464 /* New FB flip failure */470 // DisplayBuffer construction paints an empty screen.
471 // That's probably less than ideal but we've always had it that way.
472 EXPECT_CALL(mock_drm, drmModeSetCrtc(mock_drm.fake_drm.fd(),
473 crtc_id, fake.fb_id1,
474 _, _, _, _, _))
475 .WillOnce(Return(0));
476
477 // New FB flip failure
465 EXPECT_CALL(mock_drm, drmModePageFlip(mock_drm.fake_drm.fd(),478 EXPECT_CALL(mock_drm, drmModePageFlip(mock_drm.fake_drm.fd(),
466 crtc_id,479 crtc_id,
467 fake.fb_id2,480 fake.fb_id2,
@@ -469,16 +482,22 @@
469 .Times(Exactly(1))482 .Times(Exactly(1))
470 .WillOnce(Return(-1));483 .WillOnce(Return(-1));
471484
472 /* Release failed bufobj */485 // Expect fallback to blitting
486 EXPECT_CALL(mock_drm, drmModeSetCrtc(mock_drm.fake_drm.fd(),
487 crtc_id, fake.fb_id2,
488 _, _, _, _, _))
489 .WillOnce(Return(0));
490
491 // Release all buffer objects
492 EXPECT_CALL(mock_gbm, gbm_surface_release_buffer(mock_gbm.fake_gbm.surface, fake.bo1))
493 .Times(Exactly(1));
494
473 EXPECT_CALL(mock_gbm, gbm_surface_release_buffer(mock_gbm.fake_gbm.surface, fake.bo2))495 EXPECT_CALL(mock_gbm, gbm_surface_release_buffer(mock_gbm.fake_gbm.surface, fake.bo2))
474 .Times(Exactly(1));496 .Times(Exactly(1));
475
476 /* Release scheduled_bufobj (at destruction time) */
477 EXPECT_CALL(mock_gbm, gbm_surface_release_buffer(mock_gbm.fake_gbm.surface, fake.bo1))
478 .Times(Exactly(1));
479 }497 }
480498
481 EXPECT_THROW(499 // drmModePageFlip is allowed to fail (e.g. on VirtualBox)
500 EXPECT_NO_THROW(
482 {501 {
483 auto display = create_display(create_platform());502 auto display = create_display(create_platform());
484 display->for_each_display_sync_group([](mg::DisplaySyncGroup& group) {503 display->for_each_display_sync_group([](mg::DisplaySyncGroup& group) {
@@ -487,7 +506,7 @@
487 });506 });
488 group.post();507 group.post();
489 });508 });
490 }, std::runtime_error);509 });
491}510}
492511
493TEST_F(MesaDisplayTest, successful_creation_of_display_reports_successful_setup_of_native_resources)512TEST_F(MesaDisplayTest, successful_creation_of_display_reports_successful_setup_of_native_resources)
494513
=== modified file 'tests/unit-tests/platforms/mesa/kms/test_real_kms_output.cpp'
--- tests/unit-tests/platforms/mesa/kms/test_real_kms_output.cpp 2016-11-01 09:30:32 +0000
+++ tests/unit-tests/platforms/mesa/kms/test_real_kms_output.cpp 2016-11-02 08:19:38 +0000
@@ -237,10 +237,10 @@
237 mt::fake_shared(mock_page_flipper)};237 mt::fake_shared(mock_page_flipper)};
238238
239 EXPECT_FALSE(output.set_crtc(fb_id));239 EXPECT_FALSE(output.set_crtc(fb_id));
240 EXPECT_THROW({240 EXPECT_NO_THROW({
241 output.schedule_page_flip(fb_id);241 EXPECT_FALSE(output.schedule_page_flip(fb_id));
242 }, std::runtime_error);242 });
243 EXPECT_THROW({243 EXPECT_THROW({ // schedule failed. It's programmer error if you then wait.
244 output.wait_for_page_flip();244 output.wait_for_page_flip();
245 }, std::runtime_error);245 }, std::runtime_error);
246}246}

Subscribers

People subscribed via source and target branches