Mir

Merge lp:~raof/mir/factor-out-gbm-output-surface into lp:mir

Proposed by Chris Halse Rogers
Status: Merged
Approved by: Daniel van Vugt
Approved revision: no longer in the source branch.
Merged at revision: 4080
Proposed branch: lp:~raof/mir/factor-out-gbm-output-surface
Merge into: lp:mir
Diff against target: 1521 lines (+426/-389)
12 files modified
src/platforms/mesa/server/display_helpers.cpp (+25/-0)
src/platforms/mesa/server/display_helpers.h (+6/-0)
src/platforms/mesa/server/kms/CMakeLists.txt (+4/-0)
src/platforms/mesa/server/kms/display.cpp (+13/-6)
src/platforms/mesa/server/kms/display_buffer.cpp (+89/-124)
src/platforms/mesa/server/kms/display_buffer.h (+53/-34)
src/platforms/mesa/server/kms/kms_output.h (+6/-2)
src/platforms/mesa/server/kms/real_kms_output.cpp (+82/-4)
src/platforms/mesa/server/kms/real_kms_output.h (+4/-2)
tests/unit-tests/platforms/mesa/kms/mock_kms_output.h (+23/-2)
tests/unit-tests/platforms/mesa/kms/test_display_buffer.cpp (+63/-197)
tests/unit-tests/platforms/mesa/kms/test_real_kms_output.cpp (+58/-18)
To merge this branch: bzr merge lp:~raof/mir/factor-out-gbm-output-surface
Reviewer Review Type Date Requested Status
Daniel van Vugt Approve
Alan Griffiths Approve
Mir CI Bot continuous-integration Approve
Review via email: mp+318062@code.launchpad.net

Commit message

mesa-kms: Factor out a GBMOutputSurface

This divides up the responsibility of mgm::DisplayBuffer.
mgm::GBMOutputSurface is now responsible for providing gl::RenderTarget support and a GBMFrontBuffer.
mgm::KMSOutput is now responsible for allocating DRMFB objects from gbm_bo*s.

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

FAILED: Continuous integration, rev:4053
https://mir-jenkins.ubuntu.com/job/mir-ci/3043/
Executed test runs:
    FAILURE: https://mir-jenkins.ubuntu.com/job/build-mir/4067/console
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-0-fetch/4154
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=vivid+overlay/4144
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=xenial+overlay/4144
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=zesty/4144
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=clang,platform=mesa,release=zesty/4094
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=clang,platform=mesa,release=zesty/4094/artifact/output/*zip*/output.zip
    FAILURE: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=xenial+overlay/4094/console
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=zesty/4094
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=zesty/4094/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/4094
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=cross-armhf,compiler=gcc,platform=android,release=vivid+overlay/4094/artifact/output/*zip*/output.zip
    FAILURE: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=android,release=vivid+overlay/4094/console
    FAILURE: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=mesa,release=xenial+overlay/4094/console

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

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

FAILED: Continuous integration, rev:4055
https://mir-jenkins.ubuntu.com/job/mir-ci/3044/
Executed test runs:
    FAILURE: https://mir-jenkins.ubuntu.com/job/build-mir/4068/console
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-0-fetch/4155
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=vivid+overlay/4145
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=xenial+overlay/4145
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=zesty/4145
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=clang,platform=mesa,release=zesty/4095
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=clang,platform=mesa,release=zesty/4095/artifact/output/*zip*/output.zip
    FAILURE: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=xenial+overlay/4095/console
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=zesty/4095
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=zesty/4095/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/4095
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=cross-armhf,compiler=gcc,platform=android,release=vivid+overlay/4095/artifact/output/*zip*/output.zip
    FAILURE: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=android,release=vivid+overlay/4095/console
    FAILURE: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=mesa,release=xenial+overlay/4095/console

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

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

PASSED: Continuous integration, rev:4056
https://mir-jenkins.ubuntu.com/job/mir-ci/3051/
Executed test runs:
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-mir/4079
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-0-fetch/4166
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=vivid+overlay/4156
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=xenial+overlay/4156
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=zesty/4156
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=clang,platform=mesa,release=zesty/4106
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=clang,platform=mesa,release=zesty/4106/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/4106
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=xenial+overlay/4106/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=zesty/4106
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=zesty/4106/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/4106
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=cross-armhf,compiler=gcc,platform=android,release=vivid+overlay/4106/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/4106
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=android,release=vivid+overlay/4106/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/4106
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=mesa,release=xenial+overlay/4106/artifact/output/*zip*/output.zip

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

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

FAILED: Continuous integration, rev:4057
https://mir-jenkins.ubuntu.com/job/mir-ci/3053/
Executed test runs:
    FAILURE: https://mir-jenkins.ubuntu.com/job/build-mir/4081/console
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-0-fetch/4168
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=vivid+overlay/4158
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=xenial+overlay/4158
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=zesty/4158
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=clang,platform=mesa,release=zesty/4108
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=clang,platform=mesa,release=zesty/4108/artifact/output/*zip*/output.zip
    FAILURE: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=xenial+overlay/4108/console
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=zesty/4108
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=zesty/4108/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/4108
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=cross-armhf,compiler=gcc,platform=android,release=vivid+overlay/4108/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/4108
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=android,release=vivid+overlay/4108/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/4108
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=mesa,release=xenial+overlay/4108/artifact/output/*zip*/output.zip

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

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

PASSED: Continuous integration, rev:4057
https://mir-jenkins.ubuntu.com/job/mir-ci/3055/
Executed test runs:
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-mir/4084
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-0-fetch/4171
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=vivid+overlay/4161
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=xenial+overlay/4161
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=zesty/4161
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=clang,platform=mesa,release=zesty/4111
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=clang,platform=mesa,release=zesty/4111/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/4111
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=xenial+overlay/4111/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=zesty/4111
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=zesty/4111/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/4111
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=cross-armhf,compiler=gcc,platform=android,release=vivid+overlay/4111/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/4111
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=android,release=vivid+overlay/4111/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/4111
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=mesa,release=xenial+overlay/4111/artifact/output/*zip*/output.zip

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

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

+mgmh::EGLHelper::EGLHelper(EGLHelper&& from)
+ : depth_buffer_bits{from.depth_buffer_bits},
+ stencil_buffer_bits{from.stencil_buffer_bits},
+ egl_display{from.egl_display},
+ egl_config{from.egl_config},
+ egl_context{from.egl_context},
+ egl_surface{from.egl_surface},
+ should_terminate_egl{from.should_terminate_egl}
+{
+}

A long way to write "mgmh::EGLHelper::EGLHelper(EGLHelper&& from) = default;"?

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

$ sudo bin/mir_demo_server --vt 4
...
[2017-02-27 12:51:06.476517] mirserver: Mir version 0.27.0
Mir fatal error: Failed to make EGL surface current
Mir fatal error: Failed to make EGL surface current
Aborted (core dumped)

review: Needs Fixing
Revision history for this message
Chris Halse Rogers (raof) wrote :

> +mgmh::EGLHelper::EGLHelper(EGLHelper&& from)
> + : depth_buffer_bits{from.depth_buffer_bits},
> + stencil_buffer_bits{from.stencil_buffer_bits},
> + egl_display{from.egl_display},
> + egl_config{from.egl_config},
> + egl_context{from.egl_context},
> + egl_surface{from.egl_surface},
> + should_terminate_egl{from.should_terminate_egl}
> +{
> +}
>
> A long way to write "mgmh::EGLHelper::EGLHelper(EGLHelper&& from) = default;"?

No, an incomplete move constructor - it doesn't invalidate the moved-from object, resulting in the crash.

/me notes to test *exactly* the code submitted, not just the source of the code that's being copied into the branch.

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

FAILED: Continuous integration, rev:4058
https://mir-jenkins.ubuntu.com/job/mir-ci/3070/
Executed test runs:
    FAILURE: https://mir-jenkins.ubuntu.com/job/build-mir/4109/console
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-0-fetch/4196
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=vivid+overlay/4186
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=xenial+overlay/4186
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=zesty/4186
    FAILURE: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=clang,platform=mesa,release=zesty/4136/console
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=xenial+overlay/4136
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=xenial+overlay/4136/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=zesty/4136
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=zesty/4136/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/4136
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=cross-armhf,compiler=gcc,platform=android,release=vivid+overlay/4136/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/4136
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=android,release=vivid+overlay/4136/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/4136
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=mesa,release=xenial+overlay/4136/artifact/output/*zip*/output.zip

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

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

PASSED: Continuous integration, rev:4058
https://mir-jenkins.ubuntu.com/job/mir-ci/3071/
Executed test runs:
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-mir/4111
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-0-fetch/4198
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=vivid+overlay/4188
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=xenial+overlay/4188
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=zesty/4188
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=clang,platform=mesa,release=zesty/4138
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=clang,platform=mesa,release=zesty/4138/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/4138
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=xenial+overlay/4138/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=zesty/4138
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=zesty/4138/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/4138
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=cross-armhf,compiler=gcc,platform=android,release=vivid+overlay/4138/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/4138
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=android,release=vivid+overlay/4138/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/4138
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=mesa,release=xenial+overlay/4138/artifact/output/*zip*/output.zip

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

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

> > +mgmh::EGLHelper::EGLHelper(EGLHelper&& from)
> > + : depth_buffer_bits{from.depth_buffer_bits},
> > + stencil_buffer_bits{from.stencil_buffer_bits},
> > + egl_display{from.egl_display},
> > + egl_config{from.egl_config},
> > + egl_context{from.egl_context},
> > + egl_surface{from.egl_surface},
> > + should_terminate_egl{from.should_terminate_egl}
> > +{
> > +}
> >
> > A long way to write "mgmh::EGLHelper::EGLHelper(EGLHelper&& from) =
> default;"?
>
> No, an incomplete move constructor - it doesn't invalidate the moved-from
> object, resulting in the crash.

So why have a move constructor at all?!

A move constructor that promises to behave like a copy constructor is misleading at best.

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

> > No, an incomplete move constructor - it doesn't invalidate the moved-from
> > object, resulting in the crash.
>
> So why have a move constructor at all?!
>
> A move constructor that promises to behave like a copy constructor is
> misleading at best.

Ah! I now looked at the final code. That make sense.

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

Sounds like a sane plan on the surface of it.

I would point out that you've deleted some test cases, but assuming that rotation happens only on construction is an outdated idea. Plus I'm about to change that logic even more soon...

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/display_helpers.cpp'
--- src/platforms/mesa/server/display_helpers.cpp 2017-01-18 02:29:37 +0000
+++ src/platforms/mesa/server/display_helpers.cpp 2017-02-28 00:55:32 +0000
@@ -321,6 +321,31 @@
321{321{
322}322}
323323
324mgmh::EGLHelper::EGLHelper(
325 GLConfig const& gl_config,
326 GBMHelper const& gbm,
327 gbm_surface* surface,
328 EGLContext shared_context)
329 : EGLHelper(gl_config)
330{
331 setup(gbm, surface, shared_context);
332}
333
334mgmh::EGLHelper::EGLHelper(EGLHelper&& from)
335 : depth_buffer_bits{from.depth_buffer_bits},
336 stencil_buffer_bits{from.stencil_buffer_bits},
337 egl_display{from.egl_display},
338 egl_config{from.egl_config},
339 egl_context{from.egl_context},
340 egl_surface{from.egl_surface},
341 should_terminate_egl{from.should_terminate_egl}
342{
343 from.should_terminate_egl = false;
344 from.egl_display = EGL_NO_DISPLAY;
345 from.egl_context = EGL_NO_CONTEXT;
346 from.egl_surface = EGL_NO_SURFACE;
347}
348
324void mgmh::EGLHelper::setup(GBMHelper const& gbm)349void mgmh::EGLHelper::setup(GBMHelper const& gbm)
325{350{
326 eglBindAPI(MIR_SERVER_EGL_OPENGL_API);351 eglBindAPI(MIR_SERVER_EGL_OPENGL_API);
327352
=== modified file 'src/platforms/mesa/server/display_helpers.h'
--- src/platforms/mesa/server/display_helpers.h 2017-01-18 02:29:37 +0000
+++ src/platforms/mesa/server/display_helpers.h 2017-02-28 00:55:32 +0000
@@ -102,7 +102,13 @@
102{102{
103public:103public:
104 EGLHelper(GLConfig const& gl_config);104 EGLHelper(GLConfig const& gl_config);
105 EGLHelper(
106 GLConfig const& gl_config,
107 GBMHelper const& gbm,
108 gbm_surface* surface,
109 EGLContext shared_context);
105 ~EGLHelper() noexcept;110 ~EGLHelper() noexcept;
111 EGLHelper(EGLHelper&& from);
106112
107 EGLHelper(const EGLHelper&) = delete;113 EGLHelper(const EGLHelper&) = delete;
108 EGLHelper& operator=(const EGLHelper&) = delete;114 EGLHelper& operator=(const EGLHelper&) = delete;
109115
=== modified file 'src/platforms/mesa/server/kms/CMakeLists.txt'
--- src/platforms/mesa/server/kms/CMakeLists.txt 2017-01-18 02:29:37 +0000
+++ src/platforms/mesa/server/kms/CMakeLists.txt 2017-02-28 00:55:32 +0000
@@ -30,12 +30,16 @@
30 display.cpp30 display.cpp
31 display_buffer.cpp31 display_buffer.cpp
32 guest_platform.cpp32 guest_platform.cpp
33 page_flipper.h
33 kms_page_flipper.cpp34 kms_page_flipper.cpp
34 linux_virtual_terminal.cpp35 linux_virtual_terminal.cpp
35 nested_authentication.cpp36 nested_authentication.cpp
36 platform.cpp37 platform.cpp
38 kms_display_configuration.h
37 real_kms_display_configuration.cpp39 real_kms_display_configuration.cpp
40 kms_output.h
38 real_kms_output.cpp41 real_kms_output.cpp
42 kms_output_container.h
39 real_kms_output_container.cpp43 real_kms_output_container.cpp
40)44)
4145
4246
=== modified file 'src/platforms/mesa/server/kms/display.cpp'
--- src/platforms/mesa/server/kms/display.cpp 2017-02-15 07:38:33 +0000
+++ src/platforms/mesa/server/kms/display.cpp 2017-02-28 00:55:32 +0000
@@ -414,18 +414,25 @@
414 }414 }
415415
416 auto surface = gbm->create_scanout_surface(width, height);416 auto surface = gbm->create_scanout_surface(width, height);
417 auto const raw_surface = surface.get();
417418
418 std::unique_ptr<DisplayBuffer> db{419 std::unique_ptr<DisplayBuffer> db{
419 new DisplayBuffer{bypass_option,420 new DisplayBuffer{bypass_option,
420 drm,
421 gbm,
422 listener,421 listener,
423 kms_outputs,422 kms_outputs,
424 std::move(surface),423 GBMOutputSurface{
424 drm->fd,
425 std::move(surface),
426 width, height,
427 helpers::EGLHelper{
428 *gl_config,
429 *gbm,
430 raw_surface,
431 shared_egl.context()
432 }
433 },
425 bounding_rect,434 bounding_rect,
426 orientation,435 orientation}};
427 *gl_config,
428 shared_egl.context()}};
429436
430 display_buffers_new.push_back(std::move(db));437 display_buffers_new.push_back(std::move(db));
431 }438 }
432439
=== modified file 'src/platforms/mesa/server/kms/display_buffer.cpp'
--- src/platforms/mesa/server/kms/display_buffer.cpp 2017-02-21 01:04:13 +0000
+++ src/platforms/mesa/server/kms/display_buffer.cpp 2017-02-28 00:55:32 +0000
@@ -39,13 +39,13 @@
39namespace mgm = mir::graphics::mesa;39namespace mgm = mir::graphics::mesa;
40namespace geom = mir::geometry;40namespace geom = mir::geometry;
4141
42mgm::GBMFrontBuffer::GBMFrontBuffer()42mgm::GBMOutputSurface::FrontBuffer::FrontBuffer()
43 : surf{nullptr},43 : surf{nullptr},
44 bo{nullptr}44 bo{nullptr}
45{45{
46}46}
4747
48mgm::GBMFrontBuffer::GBMFrontBuffer(gbm_surface* surface)48mgm::GBMOutputSurface::FrontBuffer::FrontBuffer(gbm_surface* surface)
49 : surf{surface},49 : surf{surface},
50 bo{gbm_surface_lock_front_buffer(surface)}50 bo{gbm_surface_lock_front_buffer(surface)}
51{51{
@@ -55,7 +55,7 @@
55 }55 }
56}56}
5757
58mgm::GBMFrontBuffer::~GBMFrontBuffer()58mgm::GBMOutputSurface::FrontBuffer::~FrontBuffer()
59{59{
60 if (surf)60 if (surf)
61 {61 {
@@ -63,7 +63,7 @@
63 }63 }
64}64}
6565
66mgm::GBMFrontBuffer::GBMFrontBuffer(GBMFrontBuffer&& from)66mgm::GBMOutputSurface::FrontBuffer::FrontBuffer(FrontBuffer&& from)
67 : surf{from.surf},67 : surf{from.surf},
68 bo{from.bo}68 bo{from.bo}
69{69{
@@ -71,7 +71,7 @@
71 const_cast<gbm_bo*&>(from.bo) = nullptr;71 const_cast<gbm_bo*&>(from.bo) = nullptr;
72}72}
7373
74auto mgm::GBMFrontBuffer::operator=(GBMFrontBuffer&& from) -> GBMFrontBuffer&74auto mgm::GBMOutputSurface::FrontBuffer::operator=(FrontBuffer&& from) -> FrontBuffer&
75{75{
76 if (surf)76 if (surf)
77 {77 {
@@ -87,57 +87,24 @@
87 return *this;87 return *this;
88}88}
8989
90auto mgm::GBMFrontBuffer::operator=(std::nullptr_t) -> GBMFrontBuffer&90auto mgm::GBMOutputSurface::FrontBuffer::operator=(std::nullptr_t) -> FrontBuffer&
91{91{
92 return *this = GBMFrontBuffer{};92 return *this = FrontBuffer{};
93}93}
9494
95mgm::GBMFrontBuffer::operator gbm_bo*()95mgm::GBMOutputSurface::FrontBuffer::operator gbm_bo*()
96{96{
97 return bo;97 return bo;
98}98}
9999
100mgm::GBMFrontBuffer::operator bool() const100mgm::GBMOutputSurface::FrontBuffer::operator bool() const
101{101{
102 return (surf != nullptr) && (bo != nullptr);102 return (surf != nullptr) && (bo != nullptr);
103}103}
104104
105class mgm::DRMFB
106{
107public:
108 DRMFB(gbm_bo* bo, uint32_t drm_fb_id)
109 : bo{bo}, drm_fb_id{drm_fb_id}
110 {
111 }
112
113 ~DRMFB()
114 {
115 if (drm_fb_id)
116 {
117 int drm_fd = gbm_device_get_fd(gbm_bo_get_device(bo));
118 drmModeRmFB(drm_fd, drm_fb_id);
119 }
120 }
121
122 uint32_t get_drm_fb_id() const
123 {
124 return drm_fb_id;
125 }
126
127private:
128 gbm_bo *bo;
129 uint32_t drm_fb_id;
130};
131
132namespace105namespace
133{106{
134107
135void bo_user_data_destroy(gbm_bo* /*bo*/, void *data)
136{
137 auto bufobj = static_cast<mgm::DRMFB*>(data);
138 delete bufobj;
139}
140
141void ensure_egl_image_extensions()108void ensure_egl_image_extensions()
142{109{
143 std::string ext_string;110 std::string ext_string;
@@ -153,22 +120,15 @@
153120
154mgm::DisplayBuffer::DisplayBuffer(121mgm::DisplayBuffer::DisplayBuffer(
155 mgm::BypassOption option,122 mgm::BypassOption option,
156 std::shared_ptr<helpers::DRMHelper> const& drm,
157 std::shared_ptr<helpers::GBMHelper> const& gbm,
158 std::shared_ptr<DisplayReport> const& listener,123 std::shared_ptr<DisplayReport> const& listener,
159 std::vector<std::shared_ptr<KMSOutput>> const& outputs,124 std::vector<std::shared_ptr<KMSOutput>> const& outputs,
160 GBMSurfaceUPtr surface_gbm_param,125 GBMOutputSurface&& surface_gbm,
161 geom::Rectangle const& area,126 geom::Rectangle const& area,
162 MirOrientation rot,127 MirOrientation rot)
163 GLConfig const& gl_config,
164 EGLContext shared_context)
165 : listener(listener),128 : listener(listener),
166 bypass_option(option),129 bypass_option(option),
167 drm(drm),
168 gbm(gbm),
169 outputs(outputs),130 outputs(outputs),
170 egl{gl_config},131 surface{std::move(surface_gbm)},
171 surface_gbm{std::move(surface_gbm_param)},
172 area(area),132 area(area),
173 transform{mg::transformation(rot)},133 transform{mg::transformation(rot)},
174 needs_set_crtc{false},134 needs_set_crtc{false},
@@ -187,8 +147,6 @@
187 fb_height = area_height;147 fb_height = area_height;
188 }148 }
189149
190 egl.setup(*gbm, surface_gbm.get(), shared_context);
191
192 listener->report_successful_setup_of_native_resources();150 listener->report_successful_setup_of_native_resources();
193151
194 make_current();152 make_current();
@@ -199,22 +157,21 @@
199157
200 glClear(GL_COLOR_BUFFER_BIT);158 glClear(GL_COLOR_BUFFER_BIT);
201159
202 if (!egl.swap_buffers())160 surface.swap_buffers();
203 fatal_error("Failed to perform initial surface buffer swap");
204161
205 listener->report_successful_egl_buffer_swap_on_construction();162 listener->report_successful_egl_buffer_swap_on_construction();
206163
207 visible_composite_frame = GBMFrontBuffer{surface_gbm.get()};164 visible_composite_frame = surface.lock_front();
208 if (!visible_composite_frame)165 if (!visible_composite_frame)
209 fatal_error("Failed to get frontbuffer");166 fatal_error("Failed to get frontbuffer");
210167
211 set_crtc(get_drm_fb(visible_composite_frame));168 set_crtc(*outputs.front()->fb_for(visible_composite_frame, fb_width, fb_height));
212169
213 release_current();170 release_current();
214171
215 listener->report_successful_drm_mode_set_crtc_on_construction();172 listener->report_successful_drm_mode_set_crtc_on_construction();
216 listener->report_successful_display_construction();173 listener->report_successful_display_construction();
217 egl.report_egl_configuration(174 surface.report_egl_configuration(
218 [&listener] (EGLDisplay disp, EGLConfig cfg)175 [&listener] (EGLDisplay disp, EGLConfig cfg)
219 {176 {
220 listener->report_egl_configuration(disp, cfg);177 listener->report_egl_configuration(disp, cfg);
@@ -258,7 +215,7 @@
258 if (native->flags & mir_buffer_flag_can_scanout &&215 if (native->flags & mir_buffer_flag_can_scanout &&
259 bypass_buffer->size() == geom::Size{fb_width,fb_height})216 bypass_buffer->size() == geom::Size{fb_width,fb_height})
260 {217 {
261 if (auto bufobj = get_buffer_object(native->bo))218 if (auto bufobj = outputs.front()->fb_for(native->bo, fb_width, fb_height))
262 {219 {
263 bypass_buf = bypass_buffer;220 bypass_buf = bypass_buffer;
264 bypass_bufobj = bufobj;221 bypass_bufobj = bufobj;
@@ -281,13 +238,12 @@
281238
282void mgm::DisplayBuffer::swap_buffers()239void mgm::DisplayBuffer::swap_buffers()
283{240{
284 if (!egl.swap_buffers())241 surface.swap_buffers();
285 fatal_error("Failed to perform buffer swap");
286 bypass_buf = nullptr;242 bypass_buf = nullptr;
287 bypass_bufobj = nullptr;243 bypass_bufobj = nullptr;
288}244}
289245
290void mgm::DisplayBuffer::set_crtc(DRMFB const* forced_frame)246void mgm::DisplayBuffer::set_crtc(FBHandle const& forced_frame)
291{247{
292 for (auto& output : outputs)248 for (auto& output : outputs)
293 {249 {
@@ -298,7 +254,7 @@
298 * sometimes it's really not there). Xorg often reports similar254 * sometimes it's really not there). Xorg often reports similar
299 * errors, and it's not fatal.255 * errors, and it's not fatal.
300 */256 */
301 if (!output->set_crtc(forced_frame->get_drm_fb_id()))257 if (!output->set_crtc(forced_frame))
302 mir::log_error("Failed to set DRM CRTC. "258 mir::log_error("Failed to set DRM CRTC. "
303 "Screen contents may be incomplete. "259 "Screen contents may be incomplete. "
304 "Try plugging the monitor in again.");260 "Try plugging the monitor in again.");
@@ -315,15 +271,15 @@
315 */271 */
316 wait_for_page_flip();272 wait_for_page_flip();
317273
318 mgm::DRMFB *bufobj;274 mgm::FBHandle *bufobj;
319 if (bypass_buf)275 if (bypass_buf)
320 {276 {
321 bufobj = bypass_bufobj;277 bufobj = bypass_bufobj;
322 }278 }
323 else279 else
324 {280 {
325 scheduled_composite_frame = GBMFrontBuffer(surface_gbm.get());281 scheduled_composite_frame = surface.lock_front();
326 bufobj = get_drm_fb(scheduled_composite_frame);282 bufobj = outputs.front()->fb_for(scheduled_composite_frame, fb_width, fb_height);
327 if (!bufobj)283 if (!bufobj)
328 fatal_error("Failed to get front buffer object");284 fatal_error("Failed to get front buffer object");
329 }285 }
@@ -332,7 +288,7 @@
332 * Try to schedule a page flip as first preference to avoid tearing.288 * Try to schedule a page flip as first preference to avoid tearing.
333 * [will complete in a background thread]289 * [will complete in a background thread]
334 */290 */
335 if (!needs_set_crtc && !schedule_page_flip(bufobj))291 if (!needs_set_crtc && !schedule_page_flip(*bufobj))
336 needs_set_crtc = true;292 needs_set_crtc = true;
337293
338 /*294 /*
@@ -341,7 +297,7 @@
341 */297 */
342 if (needs_set_crtc)298 if (needs_set_crtc)
343 {299 {
344 set_crtc(bufobj);300 set_crtc(*bufobj);
345 needs_set_crtc = false;301 needs_set_crtc = false;
346 }302 }
347303
@@ -406,55 +362,7 @@
406 return recommend_sleep;362 return recommend_sleep;
407}363}
408364
409mgm::DRMFB* mgm::DisplayBuffer::get_drm_fb(GBMFrontBuffer& bo)365bool mgm::DisplayBuffer::schedule_page_flip(FBHandle const& bufobj)
410{
411 return get_buffer_object(bo);
412}
413
414mgm::DRMFB* mgm::DisplayBuffer::get_buffer_object(
415 struct gbm_bo *bo)
416{
417 if (!bo)
418 return nullptr;
419
420 /*
421 * Check if we have already set up this gbm_bo (the gbm implementation is
422 * free to reuse gbm_bos). If so, return the associated DRMFB.
423 */
424 auto bufobj = static_cast<DRMFB*>(gbm_bo_get_user_data(bo));
425 if (bufobj)
426 return bufobj;
427
428 uint32_t fb_id{0};
429 uint32_t handles[4] = {gbm_bo_get_handle(bo).u32, 0, 0, 0};
430 uint32_t strides[4] = {gbm_bo_get_stride(bo), 0, 0, 0};
431 uint32_t offsets[4] = {0, 0, 0, 0};
432
433 auto format = gbm_bo_get_format(bo);
434 /*
435 * Mir might use the old GBM_BO_ enum formats, but KMS and the rest of
436 * the world need fourcc formats, so convert...
437 */
438 if (format == GBM_BO_FORMAT_XRGB8888)
439 format = GBM_FORMAT_XRGB8888;
440 else if (format == GBM_BO_FORMAT_ARGB8888)
441 format = GBM_FORMAT_ARGB8888;
442
443 /* Create a KMS FB object with the gbm_bo attached to it. */
444 auto ret = drmModeAddFB2(drm->fd, fb_width, fb_height, format,
445 handles, strides, offsets, &fb_id, 0);
446 if (ret)
447 return nullptr;
448
449 /* Create a DRMFB and associate it with the gbm_bo */
450 bufobj = new DRMFB{bo, fb_id};
451 gbm_bo_set_user_data(bo, bufobj, bo_user_data_destroy);
452
453 return bufobj;
454}
455
456
457bool mgm::DisplayBuffer::schedule_page_flip(DRMFB* bufobj)
458{366{
459 /*367 /*
460 * Schedule the current front buffer object for display. Note that368 * Schedule the current front buffer object for display. Note that
@@ -462,7 +370,7 @@
462 */370 */
463 for (auto& output : outputs)371 for (auto& output : outputs)
464 {372 {
465 if (output->schedule_page_flip(bufobj->get_drm_fb_id()))373 if (output->schedule_page_flip(bufobj))
466 page_flips_pending = true;374 page_flips_pending = true;
467 }375 }
468376
@@ -494,19 +402,17 @@
494402
495void mgm::DisplayBuffer::make_current()403void mgm::DisplayBuffer::make_current()
496{404{
497 if (!egl.make_current())405 surface.make_current();
498 {
499 fatal_error("Failed to make EGL surface current");
500 }
501}406}
502407
503void mgm::DisplayBuffer::bind()408void mgm::DisplayBuffer::bind()
504{409{
410 surface.bind();
505}411}
506412
507void mgm::DisplayBuffer::release_current()413void mgm::DisplayBuffer::release_current()
508{414{
509 egl.release_current();415 surface.release_current();
510}416}
511417
512void mgm::DisplayBuffer::schedule_set_crtc()418void mgm::DisplayBuffer::schedule_set_crtc()
@@ -518,3 +424,62 @@
518{424{
519 return this;425 return this;
520}426}
427
428mgm::GBMOutputSurface::GBMOutputSurface(
429 int drm_fd,
430 GBMSurfaceUPtr&& surface,
431 uint32_t width,
432 uint32_t height,
433 helpers::EGLHelper&& egl)
434 : drm_fd{drm_fd},
435 width{width},
436 height{height},
437 egl{std::move(egl)},
438 surface{std::move(surface)}
439{
440}
441
442mgm::GBMOutputSurface::GBMOutputSurface(GBMOutputSurface&& from)
443 : drm_fd{from.drm_fd},
444 width{from.width},
445 height{from.height},
446 egl{std::move(from.egl)},
447 surface{std::move(from.surface)}
448{
449}
450
451
452void mgm::GBMOutputSurface::make_current()
453{
454 if (!egl.make_current())
455 {
456 fatal_error("Failed to make EGL surface current");
457 }
458}
459
460void mgm::GBMOutputSurface::release_current()
461{
462 egl.release_current();
463}
464
465void mgm::GBMOutputSurface::swap_buffers()
466{
467 if (!egl.swap_buffers())
468 fatal_error("Failed to perform buffer swap");
469}
470
471void mgm::GBMOutputSurface::bind()
472{
473
474}
475
476auto mgm::GBMOutputSurface::lock_front() -> FrontBuffer
477{
478 return FrontBuffer{surface.get()};
479}
480
481void mgm::GBMOutputSurface::report_egl_configuration(
482 std::function<void(EGLDisplay, EGLConfig)> const& to)
483{
484 egl.report_egl_configuration(to);
485}
521486
=== modified file 'src/platforms/mesa/server/kms/display_buffer.h'
--- src/platforms/mesa/server/kms/display_buffer.h 2017-02-21 01:04:13 +0000
+++ src/platforms/mesa/server/kms/display_buffer.h 2017-02-28 00:55:32 +0000
@@ -41,26 +41,55 @@
41{41{
4242
43class Platform;43class Platform;
44class DRMFB;44class FBHandle;
45class KMSOutput;45class KMSOutput;
46class NativeBuffer;
4647
47class GBMFrontBuffer48class GBMOutputSurface : public renderer::gl::RenderTarget
48{49{
49public:50public:
50 GBMFrontBuffer(gbm_surface* surface);51 class FrontBuffer
51 GBMFrontBuffer();52 {
52 ~GBMFrontBuffer();53 public:
5354 FrontBuffer();
54 GBMFrontBuffer(GBMFrontBuffer&& from);55 ~FrontBuffer();
5556
56 GBMFrontBuffer& operator=(GBMFrontBuffer&& from);57 FrontBuffer(FrontBuffer&& from);
57 GBMFrontBuffer& operator=(std::nullptr_t);58
5859 FrontBuffer& operator=(FrontBuffer&& from);
59 operator gbm_bo*();60 FrontBuffer& operator=(std::nullptr_t);
60 operator bool() const;61
62 operator gbm_bo*();
63 operator bool() const;
64 private:
65 friend class GBMOutputSurface;
66 FrontBuffer(gbm_surface* surface);
67
68 gbm_surface* const surf;
69 gbm_bo* const bo;
70 };
71
72 GBMOutputSurface(
73 int drm_fd,
74 GBMSurfaceUPtr&& surface,
75 uint32_t width,
76 uint32_t height,
77 helpers::EGLHelper&& egl);
78 GBMOutputSurface(GBMOutputSurface&& from);
79
80 // gl::RenderTarget
81 void make_current() override;
82 void release_current() override;
83 void swap_buffers() override;
84 void bind() override;
85
86 FrontBuffer lock_front();
87 void report_egl_configuration(std::function<void(EGLDisplay, EGLConfig)> const& to);
61private:88private:
62 gbm_surface* const surf;89 int const drm_fd;
63 gbm_bo* const bo;90 uint32_t width, height;
91 helpers::EGLHelper egl;
92 GBMSurfaceUPtr surface;
64};93};
6594
66class DisplayBuffer : public graphics::DisplayBuffer,95class DisplayBuffer : public graphics::DisplayBuffer,
@@ -70,15 +99,11 @@
70{99{
71public:100public:
72 DisplayBuffer(BypassOption bypass_options,101 DisplayBuffer(BypassOption bypass_options,
73 std::shared_ptr<helpers::DRMHelper> const& drm,
74 std::shared_ptr<helpers::GBMHelper> const& gbm,
75 std::shared_ptr<DisplayReport> const& listener,102 std::shared_ptr<DisplayReport> const& listener,
76 std::vector<std::shared_ptr<KMSOutput>> const& outputs,103 std::vector<std::shared_ptr<KMSOutput>> const& outputs,
77 GBMSurfaceUPtr surface_gbm,104 GBMOutputSurface&& surface_gbm,
78 geometry::Rectangle const& area,105 geometry::Rectangle const& area,
79 MirOrientation rot,106 MirOrientation rot);
80 GLConfig const& gl_config,
81 EGLContext shared_context);
82 ~DisplayBuffer();107 ~DisplayBuffer();
83108
84 geometry::Rectangle view_area() const override;109 geometry::Rectangle view_area() const override;
@@ -101,30 +126,24 @@
101 void wait_for_page_flip();126 void wait_for_page_flip();
102127
103private:128private:
104 DRMFB* get_drm_fb(GBMFrontBuffer& bo);129 bool schedule_page_flip(FBHandle const& bufobj);
105 DRMFB* get_buffer_object(struct gbm_bo *bo);130 void set_crtc(FBHandle const&);
106 bool schedule_page_flip(DRMFB* bufobj);
107 void set_crtc(DRMFB const*);
108131
109 std::shared_ptr<graphics::Buffer> visible_bypass_frame, scheduled_bypass_frame;132 std::shared_ptr<graphics::Buffer> visible_bypass_frame, scheduled_bypass_frame;
110 std::shared_ptr<Buffer> bypass_buf{nullptr};133 std::shared_ptr<Buffer> bypass_buf{nullptr};
111 DRMFB* bypass_bufobj{nullptr};134 FBHandle* bypass_bufobj{nullptr};
112 std::shared_ptr<DisplayReport> const listener;135 std::shared_ptr<DisplayReport> const listener;
113 BypassOption bypass_option;136 BypassOption bypass_option;
114 /* DRM helper from mgm::Platform */137
115 std::shared_ptr<helpers::DRMHelper> const drm;
116 std::shared_ptr<helpers::GBMHelper> const gbm;
117 std::vector<std::shared_ptr<KMSOutput>> outputs;138 std::vector<std::shared_ptr<KMSOutput>> outputs;
118139
119 /*140 /*
120 * Destruction order is important here:141 * Destruction order is important here:
121 * - The GBM surface depends on EGL
122 * - The GBMFrontBuffers depend on the GBM surface142 * - The GBMFrontBuffers depend on the GBM surface
123 */143 */
124 helpers::EGLHelper egl;144 GBMOutputSurface surface;
125 GBMSurfaceUPtr surface_gbm;145 GBMOutputSurface::FrontBuffer visible_composite_frame;
126 GBMFrontBuffer visible_composite_frame;146 GBMOutputSurface::FrontBuffer scheduled_composite_frame;
127 GBMFrontBuffer scheduled_composite_frame;
128147
129 geometry::Rectangle area;148 geometry::Rectangle area;
130 uint32_t fb_width, fb_height;149 uint32_t fb_width, fb_height;
131150
=== modified file 'src/platforms/mesa/server/kms/kms_output.h'
--- src/platforms/mesa/server/kms/kms_output.h 2017-02-15 07:38:33 +0000
+++ src/platforms/mesa/server/kms/kms_output.h 2017-02-28 00:55:32 +0000
@@ -35,6 +35,8 @@
35namespace mesa35namespace mesa
36{36{
3737
38class FBHandle;
39
38class KMSOutput40class KMSOutput
39{41{
40public:42public:
@@ -52,9 +54,9 @@
52 */54 */
53 virtual int max_refresh_rate() const = 0;55 virtual int max_refresh_rate() const = 0;
5456
55 virtual bool set_crtc(uint32_t fb_id) = 0;57 virtual bool set_crtc(FBHandle const& fb) = 0;
56 virtual void clear_crtc() = 0;58 virtual void clear_crtc() = 0;
57 virtual bool schedule_page_flip(uint32_t fb_id) = 0;59 virtual bool schedule_page_flip(FBHandle const& fb) = 0;
58 virtual void wait_for_page_flip() = 0;60 virtual void wait_for_page_flip() = 0;
5961
60 virtual bool set_cursor(gbm_bo* buffer) = 0;62 virtual bool set_cursor(gbm_bo* buffer) = 0;
@@ -66,6 +68,8 @@
66 virtual void set_gamma(GammaCurves const& gamma) = 0;68 virtual void set_gamma(GammaCurves const& gamma) = 0;
67 virtual Frame last_frame() const = 0;69 virtual Frame last_frame() const = 0;
6870
71 virtual FBHandle* fb_for(gbm_bo* bo, uint32_t width, uint32_t height) const = 0;
72
69protected:73protected:
70 KMSOutput() = default;74 KMSOutput() = default;
71 KMSOutput(const KMSOutput&) = delete;75 KMSOutput(const KMSOutput&) = delete;
7276
=== modified file 'src/platforms/mesa/server/kms/real_kms_output.cpp'
--- src/platforms/mesa/server/kms/real_kms_output.cpp 2017-02-15 07:38:33 +0000
+++ src/platforms/mesa/server/kms/real_kms_output.cpp 2017-02-28 00:55:32 +0000
@@ -31,6 +31,43 @@
31namespace mgk = mg::kms;31namespace mgk = mg::kms;
32namespace geom = mir::geometry;32namespace geom = mir::geometry;
3333
34class mgm::FBHandle
35{
36public:
37 FBHandle(gbm_bo* bo, uint32_t drm_fb_id)
38 : bo{bo}, drm_fb_id{drm_fb_id}
39 {
40 }
41
42 ~FBHandle()
43 {
44 if (drm_fb_id)
45 {
46 int drm_fd = gbm_device_get_fd(gbm_bo_get_device(bo));
47 drmModeRmFB(drm_fd, drm_fb_id);
48 }
49 }
50
51 uint32_t get_drm_fb_id() const
52 {
53 return drm_fb_id;
54 }
55
56private:
57 gbm_bo *bo;
58 uint32_t drm_fb_id;
59};
60
61namespace
62{
63void bo_user_data_destroy(gbm_bo* /*bo*/, void *data)
64{
65 auto bufobj = static_cast<mgm::FBHandle*>(data);
66 delete bufobj;
67}
68
69}
70
34mgm::RealKMSOutput::RealKMSOutput(int drm_fd, uint32_t connector_id,71mgm::RealKMSOutput::RealKMSOutput(int drm_fd, uint32_t connector_id,
35 std::shared_ptr<PageFlipper> const& page_flipper)72 std::shared_ptr<PageFlipper> const& page_flipper)
36 : drm_fd{drm_fd}, connector_id{connector_id}, page_flipper{page_flipper},73 : drm_fd{drm_fd}, connector_id{connector_id}, page_flipper{page_flipper},
@@ -108,7 +145,7 @@
108 mode_index = kms_mode_index;145 mode_index = kms_mode_index;
109}146}
110147
111bool mgm::RealKMSOutput::set_crtc(uint32_t fb_id)148bool mgm::RealKMSOutput::set_crtc(FBHandle const& fb)
112{149{
113 if (!ensure_crtc())150 if (!ensure_crtc())
114 {151 {
@@ -118,7 +155,7 @@
118 }155 }
119156
120 auto ret = drmModeSetCrtc(drm_fd, current_crtc->crtc_id,157 auto ret = drmModeSetCrtc(drm_fd, current_crtc->crtc_id,
121 fb_id, fb_offset.dx.as_int(), fb_offset.dy.as_int(),158 fb.get_drm_fb_id(), fb_offset.dx.as_int(), fb_offset.dy.as_int(),
122 &connector->connector_id, 1,159 &connector->connector_id, 1,
123 &connector->modes[mode_index]);160 &connector->modes[mode_index]);
124 if (ret)161 if (ret)
@@ -159,7 +196,7 @@
159 current_crtc = nullptr;196 current_crtc = nullptr;
160}197}
161198
162bool mgm::RealKMSOutput::schedule_page_flip(uint32_t fb_id)199bool mgm::RealKMSOutput::schedule_page_flip(FBHandle const& fb)
163{200{
164 std::unique_lock<std::mutex> lg(power_mutex);201 std::unique_lock<std::mutex> lg(power_mutex);
165 if (power_mode != mir_power_mode_on)202 if (power_mode != mir_power_mode_on)
@@ -170,7 +207,7 @@
170 mgk::connector_name(connector).c_str());207 mgk::connector_name(connector).c_str());
171 return false;208 return false;
172 }209 }
173 return page_flipper->schedule_flip(current_crtc->crtc_id, fb_id, connector_id);210 return page_flipper->schedule_flip(current_crtc->crtc_id, fb.get_drm_fb_id(), connector_id);
174}211}
175212
176void mgm::RealKMSOutput::wait_for_page_flip()213void mgm::RealKMSOutput::wait_for_page_flip()
@@ -319,3 +356,44 @@
319356
320 // TODO: return bool in future? Then do what with it?357 // TODO: return bool in future? Then do what with it?
321}358}
359
360mgm::FBHandle* mgm::RealKMSOutput::fb_for(gbm_bo* bo, uint32_t width, uint32_t height) const
361{
362 if (!bo)
363 return nullptr;
364
365 /*
366 * Check if we have already set up this gbm_bo (the gbm implementation is
367 * free to reuse gbm_bos). If so, return the associated FBHandle.
368 */
369 auto bufobj = static_cast<FBHandle*>(gbm_bo_get_user_data(bo));
370 if (bufobj)
371 return bufobj;
372
373 uint32_t fb_id{0};
374 uint32_t handles[4] = {gbm_bo_get_handle(bo).u32, 0, 0, 0};
375 uint32_t strides[4] = {gbm_bo_get_stride(bo), 0, 0, 0};
376 uint32_t offsets[4] = {0, 0, 0, 0};
377
378 auto format = gbm_bo_get_format(bo);
379 /*
380 * Mir might use the old GBM_BO_ enum formats, but KMS and the rest of
381 * the world need fourcc formats, so convert...
382 */
383 if (format == GBM_BO_FORMAT_XRGB8888)
384 format = GBM_FORMAT_XRGB8888;
385 else if (format == GBM_BO_FORMAT_ARGB8888)
386 format = GBM_FORMAT_ARGB8888;
387
388 /* Create a KMS FB object with the gbm_bo attached to it. */
389 auto ret = drmModeAddFB2(drm_fd, width, height, format,
390 handles, strides, offsets, &fb_id, 0);
391 if (ret)
392 return nullptr;
393
394 /* Create a FBHandle and associate it with the gbm_bo */
395 bufobj = new FBHandle{bo, fb_id};
396 gbm_bo_set_user_data(bo, bufobj, bo_user_data_destroy);
397
398 return bufobj;
399}
322400
=== modified file 'src/platforms/mesa/server/kms/real_kms_output.h'
--- src/platforms/mesa/server/kms/real_kms_output.h 2017-02-15 07:38:33 +0000
+++ src/platforms/mesa/server/kms/real_kms_output.h 2017-02-28 00:55:32 +0000
@@ -47,9 +47,9 @@
47 geometry::Size size() const override;47 geometry::Size size() const override;
48 int max_refresh_rate() const override;48 int max_refresh_rate() const override;
4949
50 bool set_crtc(uint32_t fb_id) override;50 bool set_crtc(FBHandle const& fb) override;
51 void clear_crtc() override;51 void clear_crtc() override;
52 bool schedule_page_flip(uint32_t fb_id) override;52 bool schedule_page_flip(FBHandle const& fb) override;
53 void wait_for_page_flip() override;53 void wait_for_page_flip() override;
5454
55 bool set_cursor(gbm_bo* buffer) override;55 bool set_cursor(gbm_bo* buffer) override;
@@ -62,6 +62,8 @@
6262
63 Frame last_frame() const override;63 Frame last_frame() const override;
6464
65 FBHandle* fb_for(gbm_bo* bo, uint32_t width, uint32_t height) const override;
66
65private:67private:
66 bool ensure_crtc();68 bool ensure_crtc();
67 void restore_saved_crtc();69 void restore_saved_crtc();
6870
=== modified file 'tests/unit-tests/platforms/mesa/kms/mock_kms_output.h'
--- tests/unit-tests/platforms/mesa/kms/mock_kms_output.h 2017-02-15 07:38:33 +0000
+++ tests/unit-tests/platforms/mesa/kms/mock_kms_output.h 2017-02-28 00:55:32 +0000
@@ -24,6 +24,15 @@
2424
25namespace mir25namespace mir
26{26{
27
28namespace graphics
29{
30namespace mesa
31{
32class DRMFB;
33}
34}
35
27namespace test36namespace test
28{37{
2938
@@ -34,9 +43,19 @@
34 MOCK_CONST_METHOD0(size, geometry::Size());43 MOCK_CONST_METHOD0(size, geometry::Size());
35 MOCK_CONST_METHOD0(max_refresh_rate, int());44 MOCK_CONST_METHOD0(max_refresh_rate, int());
3645
37 MOCK_METHOD1(set_crtc, bool(uint32_t));46 bool set_crtc(graphics::mesa::FBHandle const& fb) override
47 {
48 return set_crtc_thunk(&fb);
49 }
50
51 MOCK_METHOD1(set_crtc_thunk, bool(graphics::mesa::FBHandle const*));
38 MOCK_METHOD0(clear_crtc, void());52 MOCK_METHOD0(clear_crtc, void());
39 MOCK_METHOD1(schedule_page_flip, bool(uint32_t));53
54 bool schedule_page_flip(graphics::mesa::FBHandle const& fb) override
55 {
56 return schedule_page_flip_thunk(&fb);
57 }
58 MOCK_METHOD1(schedule_page_flip_thunk, bool(graphics::mesa::FBHandle const*));
40 MOCK_METHOD0(wait_for_page_flip, void());59 MOCK_METHOD0(wait_for_page_flip, void());
4160
42 MOCK_CONST_METHOD0(last_frame, graphics::Frame());61 MOCK_CONST_METHOD0(last_frame, graphics::Frame());
@@ -48,6 +67,8 @@
4867
49 MOCK_METHOD1(set_power_mode, void(MirPowerMode));68 MOCK_METHOD1(set_power_mode, void(MirPowerMode));
50 MOCK_METHOD1(set_gamma, void(mir::graphics::GammaCurves const&));69 MOCK_METHOD1(set_gamma, void(mir::graphics::GammaCurves const&));
70
71 MOCK_CONST_METHOD3(fb_for, graphics::mesa::FBHandle*(gbm_bo*, uint32_t, uint32_t));
51};72};
5273
53} // namespace test74} // namespace test
5475
=== modified file 'tests/unit-tests/platforms/mesa/kms/test_display_buffer.cpp'
--- tests/unit-tests/platforms/mesa/kms/test_display_buffer.cpp 2017-01-27 08:13:36 +0000
+++ tests/unit-tests/platforms/mesa/kms/test_display_buffer.cpp 2017-02-28 00:55:32 +0000
@@ -85,12 +85,14 @@
85 fake_devices.add_standard_device("standard-drm-devices");85 fake_devices.add_standard_device("standard-drm-devices");
8686
87 mock_kms_output = std::make_shared<NiceMock<MockKMSOutput>>();87 mock_kms_output = std::make_shared<NiceMock<MockKMSOutput>>();
88 ON_CALL(*mock_kms_output, set_crtc(_))88 ON_CALL(*mock_kms_output, set_crtc_thunk(_))
89 .WillByDefault(Return(true));89 .WillByDefault(Return(true));
90 ON_CALL(*mock_kms_output, schedule_page_flip(_))90 ON_CALL(*mock_kms_output, schedule_page_flip_thunk(_))
91 .WillByDefault(Return(true));91 .WillByDefault(Return(true));
92 ON_CALL(*mock_kms_output, max_refresh_rate())92 ON_CALL(*mock_kms_output, max_refresh_rate())
93 .WillByDefault(Return(mock_refresh_rate));93 .WillByDefault(Return(mock_refresh_rate));
94 ON_CALL(*mock_kms_output, fb_for(_,_,_))
95 .WillByDefault(Return(reinterpret_cast<FBHandle*>(0x12ad)));
9496
95 ON_CALL(*mock_bypassable_buffer, size())97 ON_CALL(*mock_bypassable_buffer, size())
96 .WillByDefault(Return(display_area.size));98 .WillByDefault(Return(display_area.size));
@@ -108,6 +110,18 @@
108 }110 }
109111
110protected:112protected:
113 GBMOutputSurface make_output_surface()
114 {
115 helpers::EGLHelper egl{gl_config};
116 return GBMOutputSurface{
117 drm->fd,
118 GBMSurfaceUPtr{nullptr},
119 static_cast<uint32_t>(width),
120 static_cast<uint32_t>(height),
121 std::move(egl)
122 };
123 }
124
111 int const width{56};125 int const width{56};
112 int const height{78};126 int const height{78};
113 mir::geometry::Rectangle const display_area{{12,34}, {width,height}};127 mir::geometry::Rectangle const display_area{{12,34}, {width,height}};
@@ -135,15 +149,11 @@
135{149{
136 graphics::mesa::DisplayBuffer db(150 graphics::mesa::DisplayBuffer db(
137 graphics::mesa::BypassOption::allowed,151 graphics::mesa::BypassOption::allowed,
138 drm,
139 gbm,
140 null_display_report(),152 null_display_report(),
141 {},153 {mock_kms_output},
142 nullptr,154 make_output_surface(),
143 display_area,155 display_area,
144 mir_orientation_normal,156 mir_orientation_normal);
145 gl_config,
146 mock_egl.fake_egl_context);
147157
148 EXPECT_EQ(display_area, db.view_area());158 EXPECT_EQ(display_area, db.view_area());
149}159}
@@ -152,15 +162,11 @@
152{162{
153 graphics::mesa::DisplayBuffer db(163 graphics::mesa::DisplayBuffer db(
154 graphics::mesa::BypassOption::allowed,164 graphics::mesa::BypassOption::allowed,
155 drm,
156 gbm,
157 null_display_report(),165 null_display_report(),
158 {mock_kms_output},166 {mock_kms_output},
159 nullptr,167 make_output_surface(),
160 display_area,168 display_area,
161 mir_orientation_normal,169 mir_orientation_normal);
162 gl_config,
163 mock_egl.fake_egl_context);
164170
165 auto original_count = mock_bypassable_buffer.use_count();171 auto original_count = mock_bypassable_buffer.use_count();
166172
@@ -180,15 +186,11 @@
180{186{
181 graphics::mesa::DisplayBuffer db(187 graphics::mesa::DisplayBuffer db(
182 graphics::mesa::BypassOption::allowed,188 graphics::mesa::BypassOption::allowed,
183 drm,
184 gbm,
185 null_display_report(),189 null_display_report(),
186 {mock_kms_output},190 {mock_kms_output},
187 nullptr,191 make_output_surface(),
188 display_area,192 display_area,
189 mir_orientation_normal,193 mir_orientation_normal);
190 gl_config,
191 mock_egl.fake_egl_context);
192194
193 for (int frame = 0; frame < 5; ++frame)195 for (int frame = 0; frame < 5; ++frame)
194 {196 {
@@ -210,15 +212,11 @@
210212
211 graphics::mesa::DisplayBuffer db(213 graphics::mesa::DisplayBuffer db(
212 graphics::mesa::BypassOption::allowed,214 graphics::mesa::BypassOption::allowed,
213 drm,
214 gbm,
215 null_display_report(),215 null_display_report(),
216 {mock_kms_output},216 {mock_kms_output},
217 nullptr,217 make_output_surface(),
218 display_area,218 display_area,
219 mir_orientation_normal,219 mir_orientation_normal);
220 gl_config,
221 mock_egl.fake_egl_context);
222220
223 for (int frame = 0; frame < 5; ++frame)221 for (int frame = 0; frame < 5; ++frame)
224 {222 {
@@ -234,15 +232,11 @@
234{232{
235 graphics::mesa::DisplayBuffer db(233 graphics::mesa::DisplayBuffer db(
236 graphics::mesa::BypassOption::allowed,234 graphics::mesa::BypassOption::allowed,
237 drm,
238 gbm,
239 null_display_report(),235 null_display_report(),
240 {mock_kms_output},236 {mock_kms_output},
241 nullptr,237 make_output_surface(),
242 display_area,238 display_area,
243 mir_orientation_normal,239 mir_orientation_normal);
244 gl_config,
245 mock_egl.fake_egl_context);
246240
247 auto original_count = mock_bypassable_buffer.use_count();241 auto original_count = mock_bypassable_buffer.use_count();
248242
@@ -259,37 +253,29 @@
259{253{
260 graphics::mesa::DisplayBuffer db(254 graphics::mesa::DisplayBuffer db(
261 graphics::mesa::BypassOption::allowed,255 graphics::mesa::BypassOption::allowed,
262 drm,
263 gbm,
264 null_display_report(),256 null_display_report(),
265 {mock_kms_output},257 {mock_kms_output},
266 nullptr,258 make_output_surface(),
267 display_area,259 display_area,
268 mir_orientation_normal,260 mir_orientation_normal);
269 gl_config,
270 mock_egl.fake_egl_context);
271261
272 EXPECT_TRUE(db.overlay(bypassable_list));262 EXPECT_TRUE(db.overlay(bypassable_list));
273}263}
274264
275TEST_F(MesaDisplayBufferTest, failed_bypass_falls_back_gracefully)265TEST_F(MesaDisplayBufferTest, failed_bypass_falls_back_gracefully)
276{ // Regression test for LP: #1398296266{ // Regression test for LP: #1398296
277 EXPECT_CALL(mock_drm, drmModeAddFB2(_, _, _, _, _, _, _, _, _))267 EXPECT_CALL(*mock_kms_output, fb_for(_,_,_))
278 .WillOnce(Return(0)) // During the DisplayBuffer constructor268 .WillOnce(Return(reinterpret_cast<FBHandle*>(0xaabb))) // During the DisplayBuffer constructor
279 .WillOnce(Return(-22)) // Fail first bypass attempt269 .WillOnce(Return(nullptr)) // Fail first bypass attempt
280 .WillOnce(Return(0)); // Succeed second bypass attempt270 .WillOnce(Return(reinterpret_cast<FBHandle*>(0xbbcc))); // Succeed second bypass attempt
281271
282 graphics::mesa::DisplayBuffer db(272 graphics::mesa::DisplayBuffer db(
283 graphics::mesa::BypassOption::allowed,273 graphics::mesa::BypassOption::allowed,
284 drm,
285 gbm,
286 null_display_report(),274 null_display_report(),
287 {mock_kms_output},275 {mock_kms_output},
288 nullptr,276 make_output_surface(),
289 display_area,277 display_area,
290 mir_orientation_normal,278 mir_orientation_normal);
291 gl_config,
292 mock_egl.fake_egl_context);
293279
294 EXPECT_FALSE(db.overlay(bypassable_list));280 EXPECT_FALSE(db.overlay(bypassable_list));
295 // And then we recover. DRM finds enough resources to AddFB ...281 // And then we recover. DRM finds enough resources to AddFB ...
@@ -310,15 +296,11 @@
310296
311 graphics::mesa::DisplayBuffer db(297 graphics::mesa::DisplayBuffer db(
312 graphics::mesa::BypassOption::allowed,298 graphics::mesa::BypassOption::allowed,
313 drm,
314 gbm,
315 null_display_report(),299 null_display_report(),
316 {mock_kms_output},300 {mock_kms_output},
317 nullptr,301 make_output_surface(),
318 display_area,302 display_area,
319 mir_orientation_normal,303 mir_orientation_normal);
320 gl_config,
321 mock_egl.fake_egl_context);
322304
323 EXPECT_FALSE(db.overlay(list));305 EXPECT_FALSE(db.overlay(list));
324}306}
@@ -327,15 +309,11 @@
327{309{
328 graphics::mesa::DisplayBuffer db(310 graphics::mesa::DisplayBuffer db(
329 graphics::mesa::BypassOption::allowed,311 graphics::mesa::BypassOption::allowed,
330 drm,
331 gbm,
332 null_display_report(),312 null_display_report(),
333 {},313 {mock_kms_output},
334 nullptr,314 make_output_surface(),
335 display_area,315 display_area,
336 mir_orientation_right,316 mir_orientation_right);
337 gl_config,
338 mock_egl.fake_egl_context);
339317
340 EXPECT_FALSE(db.overlay(bypassable_list));318 EXPECT_FALSE(db.overlay(bypassable_list));
341}319}
@@ -349,15 +327,11 @@
349327
350 graphics::mesa::DisplayBuffer db(328 graphics::mesa::DisplayBuffer db(
351 graphics::mesa::BypassOption::allowed,329 graphics::mesa::BypassOption::allowed,
352 drm,
353 gbm,
354 null_display_report(),330 null_display_report(),
355 {},331 {mock_kms_output},
356 nullptr,332 make_output_surface(),
357 display_area,333 display_area,
358 mir_orientation_normal,334 mir_orientation_normal);
359 gl_config,
360 mock_egl.fake_egl_context);
361335
362 EXPECT_FALSE(db.overlay(list));336 EXPECT_FALSE(db.overlay(list));
363}337}
@@ -371,15 +345,11 @@
371345
372 graphics::mesa::DisplayBuffer db(346 graphics::mesa::DisplayBuffer db(
373 graphics::mesa::BypassOption::allowed,347 graphics::mesa::BypassOption::allowed,
374 drm,
375 gbm,
376 null_display_report(),348 null_display_report(),
377 {},349 {mock_kms_output},
378 nullptr,350 make_output_surface(),
379 display_area,351 display_area,
380 mir_orientation_normal,352 mir_orientation_normal);
381 gl_config,
382 mock_egl.fake_egl_context);
383353
384 // If you find yourself using gbm_ functions on a Shm buffer then you're354 // If you find yourself using gbm_ functions on a Shm buffer then you're
385 // asking for a crash (LP: #1493721) ...355 // asking for a crash (LP: #1493721) ...
@@ -394,119 +364,31 @@
394364
395 graphics::mesa::DisplayBuffer db(365 graphics::mesa::DisplayBuffer db(
396 graphics::mesa::BypassOption::allowed,366 graphics::mesa::BypassOption::allowed,
397 drm,
398 gbm,
399 null_display_report(),367 null_display_report(),
400 {},368 {mock_kms_output},
401 nullptr,369 make_output_surface(),
402 display_area,370 display_area,
403 mir_orientation_left,371 mir_orientation_left);
404 gl_config,
405 mock_egl.fake_egl_context);
406372
407 EXPECT_EQ(rotate_left, db.transformation());373 EXPECT_EQ(rotate_left, db.transformation());
408}374}
409375
410TEST_F(MesaDisplayBufferTest, normal_rotation_constructs_normal_fb)
411{
412 EXPECT_CALL(mock_gbm, gbm_bo_get_user_data(_))
413 .WillOnce(Return((void*)0));
414 EXPECT_CALL(mock_drm, drmModeAddFB2(_, width, height, _, _, _, _, _, _))
415 .Times(1);
416
417 graphics::mesa::DisplayBuffer db(
418 graphics::mesa::BypassOption::allowed,
419 drm,
420 gbm,
421 null_display_report(),
422 {},
423 nullptr,
424 display_area,
425 mir_orientation_normal,
426 gl_config,
427 mock_egl.fake_egl_context);
428}
429
430TEST_F(MesaDisplayBufferTest, left_rotation_constructs_transposed_fb)
431{
432 EXPECT_CALL(mock_gbm, gbm_bo_get_user_data(_))
433 .WillOnce(Return((void*)0));
434 EXPECT_CALL(mock_drm, drmModeAddFB2(_, height, width, _, _, _, _, _, _))
435 .Times(1);
436
437 graphics::mesa::DisplayBuffer db(
438 graphics::mesa::BypassOption::allowed,
439 drm,
440 gbm,
441 null_display_report(),
442 {},
443 nullptr,
444 display_area,
445 mir_orientation_left,
446 gl_config,
447 mock_egl.fake_egl_context);
448}
449
450TEST_F(MesaDisplayBufferTest, inverted_rotation_constructs_normal_fb)
451{
452 EXPECT_CALL(mock_gbm, gbm_bo_get_user_data(_))
453 .WillOnce(Return((void*)0));
454 EXPECT_CALL(mock_drm, drmModeAddFB2(_, width, height, _, _, _, _, _, _))
455 .Times(1);
456
457 graphics::mesa::DisplayBuffer db(
458 graphics::mesa::BypassOption::allowed,
459 drm,
460 gbm,
461 null_display_report(),
462 {},
463 nullptr,
464 display_area,
465 mir_orientation_inverted,
466 gl_config,
467 mock_egl.fake_egl_context);
468}
469
470TEST_F(MesaDisplayBufferTest, right_rotation_constructs_transposed_fb)
471{
472 EXPECT_CALL(mock_gbm, gbm_bo_get_user_data(_))
473 .WillOnce(Return((void*)0));
474 EXPECT_CALL(mock_drm, drmModeAddFB2(_, height, width, _, _, _, _, _, _))
475 .Times(1);
476
477 graphics::mesa::DisplayBuffer db(
478 graphics::mesa::BypassOption::allowed,
479 drm,
480 gbm,
481 null_display_report(),
482 {},
483 nullptr,
484 display_area,
485 mir_orientation_right,
486 gl_config,
487 mock_egl.fake_egl_context);
488}
489
490TEST_F(MesaDisplayBufferTest, clone_mode_first_flip_flips_but_no_wait)376TEST_F(MesaDisplayBufferTest, clone_mode_first_flip_flips_but_no_wait)
491{377{
492 // Ensure clone mode can do multiple page flips in parallel without378 // Ensure clone mode can do multiple page flips in parallel without
493 // blocking on either (at least till the second post)379 // blocking on either (at least till the second post)
494 EXPECT_CALL(*mock_kms_output, schedule_page_flip(_))380 EXPECT_CALL(*mock_kms_output, schedule_page_flip_thunk(_))
495 .Times(2);381 .Times(2);
496 EXPECT_CALL(*mock_kms_output, wait_for_page_flip())382 EXPECT_CALL(*mock_kms_output, wait_for_page_flip())
497 .Times(0);383 .Times(0);
498384
499 graphics::mesa::DisplayBuffer db(385 graphics::mesa::DisplayBuffer db(
500 graphics::mesa::BypassOption::allowed,386 graphics::mesa::BypassOption::allowed,
501 drm,
502 gbm,
503 null_display_report(),387 null_display_report(),
504 {mock_kms_output, mock_kms_output},388 {mock_kms_output, mock_kms_output},
505 nullptr,389 make_output_surface(),
506 display_area,390 display_area,
507 mir_orientation_normal,391 mir_orientation_normal);
508 gl_config,
509 mock_egl.fake_egl_context);
510392
511 db.swap_buffers();393 db.swap_buffers();
512 db.post();394 db.post();
@@ -514,22 +396,18 @@
514396
515TEST_F(MesaDisplayBufferTest, single_mode_first_post_flips_with_wait)397TEST_F(MesaDisplayBufferTest, single_mode_first_post_flips_with_wait)
516{398{
517 EXPECT_CALL(*mock_kms_output, schedule_page_flip(_))399 EXPECT_CALL(*mock_kms_output, schedule_page_flip_thunk(_))
518 .Times(1);400 .Times(1);
519 EXPECT_CALL(*mock_kms_output, wait_for_page_flip())401 EXPECT_CALL(*mock_kms_output, wait_for_page_flip())
520 .Times(1);402 .Times(1);
521403
522 graphics::mesa::DisplayBuffer db(404 graphics::mesa::DisplayBuffer db(
523 graphics::mesa::BypassOption::allowed,405 graphics::mesa::BypassOption::allowed,
524 drm,
525 gbm,
526 null_display_report(),406 null_display_report(),
527 {mock_kms_output},407 {mock_kms_output},
528 nullptr,408 make_output_surface(),
529 display_area,409 display_area,
530 mir_orientation_normal,410 mir_orientation_normal);
531 gl_config,
532 mock_egl.fake_egl_context);
533411
534 db.swap_buffers();412 db.swap_buffers();
535 db.post();413 db.post();
@@ -541,26 +419,22 @@
541419
542 EXPECT_CALL(*mock_kms_output, wait_for_page_flip())420 EXPECT_CALL(*mock_kms_output, wait_for_page_flip())
543 .Times(0);421 .Times(0);
544 EXPECT_CALL(*mock_kms_output, schedule_page_flip(_))422 EXPECT_CALL(*mock_kms_output, schedule_page_flip_thunk(_))
545 .Times(2);423 .Times(2);
546 EXPECT_CALL(*mock_kms_output, wait_for_page_flip())424 EXPECT_CALL(*mock_kms_output, wait_for_page_flip())
547 .Times(2);425 .Times(2);
548 EXPECT_CALL(*mock_kms_output, schedule_page_flip(_))426 EXPECT_CALL(*mock_kms_output, schedule_page_flip_thunk(_))
549 .Times(2);427 .Times(2);
550 EXPECT_CALL(*mock_kms_output, wait_for_page_flip())428 EXPECT_CALL(*mock_kms_output, wait_for_page_flip())
551 .Times(0);429 .Times(0);
552430
553 graphics::mesa::DisplayBuffer db(431 graphics::mesa::DisplayBuffer db(
554 graphics::mesa::BypassOption::allowed,432 graphics::mesa::BypassOption::allowed,
555 drm,
556 gbm,
557 null_display_report(),433 null_display_report(),
558 {mock_kms_output, mock_kms_output},434 {mock_kms_output, mock_kms_output},
559 nullptr,435 make_output_surface(),
560 display_area,436 display_area,
561 mir_orientation_normal,437 mir_orientation_normal);
562 gl_config,
563 mock_egl.fake_egl_context);
564438
565 db.swap_buffers();439 db.swap_buffers();
566 db.post();440 db.post();
@@ -578,15 +452,11 @@
578452
579 graphics::mesa::DisplayBuffer db(453 graphics::mesa::DisplayBuffer db(
580 graphics::mesa::BypassOption::allowed,454 graphics::mesa::BypassOption::allowed,
581 drm,
582 gbm,
583 null_display_report(),455 null_display_report(),
584 {mock_kms_output},456 {mock_kms_output},
585 nullptr,457 make_output_surface(),
586 display_area,458 display_area,
587 mir_orientation_normal,459 mir_orientation_normal);
588 gl_config,
589 mock_egl.fake_egl_context);
590460
591 EXPECT_FALSE(db.overlay(list));461 EXPECT_FALSE(db.overlay(list));
592}462}
@@ -607,15 +477,11 @@
607477
608 graphics::mesa::DisplayBuffer db(478 graphics::mesa::DisplayBuffer db(
609 graphics::mesa::BypassOption::allowed,479 graphics::mesa::BypassOption::allowed,
610 drm,
611 gbm,
612 null_display_report(),480 null_display_report(),
613 {mock_kms_output},481 {mock_kms_output},
614 nullptr,482 make_output_surface(),
615 display_area,483 display_area,
616 mir_orientation_normal,484 mir_orientation_normal);
617 gl_config,
618 mock_egl.fake_egl_context);
619485
620 EXPECT_FALSE(db.overlay(list));486 EXPECT_FALSE(db.overlay(list));
621}487}
622488
=== modified file 'tests/unit-tests/platforms/mesa/kms/test_real_kms_output.cpp'
--- tests/unit-tests/platforms/mesa/kms/test_real_kms_output.cpp 2017-01-18 02:29:37 +0000
+++ tests/unit-tests/platforms/mesa/kms/test_real_kms_output.cpp 2017-02-28 00:55:32 +0000
@@ -66,6 +66,9 @@
66 {66 {
67 ON_CALL(mock_page_flipper, wait_for_flip(_))67 ON_CALL(mock_page_flipper, wait_for_flip(_))
68 .WillByDefault(Return(mg::Frame{}));68 .WillByDefault(Return(mg::Frame{}));
69
70 ON_CALL(mock_gbm, gbm_bo_get_handle(_))
71 .WillByDefault(Return(gbm_bo_handle{0}));
69 }72 }
7073
71 void setup_outputs_connected_crtc()74 void setup_outputs_connected_crtc()
@@ -106,12 +109,22 @@
106 resources.prepare();109 resources.prepare();
107 }110 }
108111
112 void append_fb_id(uint32_t fb_id)
113 {
114 EXPECT_CALL(mock_drm, drmModeAddFB2(_,_,_,_,_,_,_,_,_))
115 .WillOnce(
116 DoAll(
117 SetArgPointee<7>(fb_id),
118 Return(0)));
119 }
120
109 testing::NiceMock<mtd::MockDRM> mock_drm;121 testing::NiceMock<mtd::MockDRM> mock_drm;
110 testing::NiceMock<mtd::MockGBM> mock_gbm;122 testing::NiceMock<mtd::MockGBM> mock_gbm;
111 MockPageFlipper mock_page_flipper;123 MockPageFlipper mock_page_flipper;
112 NullPageFlipper null_page_flipper;124 NullPageFlipper null_page_flipper;
113125
114 std::vector<drmModeModeInfo> modes_empty;126 std::vector<drmModeModeInfo> modes_empty;
127 gbm_bo* const fake_bo{reinterpret_cast<gbm_bo*>(0x123ba)};
115 uint32_t const invalid_id;128 uint32_t const invalid_id;
116 std::vector<uint32_t> const crtc_ids;129 std::vector<uint32_t> const crtc_ids;
117 std::vector<uint32_t> const encoder_ids;130 std::vector<uint32_t> const encoder_ids;
@@ -139,10 +152,11 @@
139{152{
140 using namespace testing;153 using namespace testing;
141154
142 uint32_t const fb_id{67};
143
144 setup_outputs_connected_crtc();155 setup_outputs_connected_crtc();
145156
157 uint32_t const fb_id{42};
158 append_fb_id(fb_id);
159
146 {160 {
147 InSequence s;161 InSequence s;
148162
@@ -166,8 +180,10 @@
166 mgm::RealKMSOutput output{mock_drm.fake_drm.fd(), connector_ids[0],180 mgm::RealKMSOutput output{mock_drm.fake_drm.fd(), connector_ids[0],
167 mt::fake_shared(mock_page_flipper)};181 mt::fake_shared(mock_page_flipper)};
168182
169 EXPECT_TRUE(output.set_crtc(fb_id));183 auto fb = output.fb_for(fake_bo, 1920, 1024);
170 EXPECT_TRUE(output.schedule_page_flip(fb_id));184
185 EXPECT_TRUE(output.set_crtc(*fb));
186 EXPECT_TRUE(output.schedule_page_flip(*fb));
171 output.wait_for_page_flip();187 output.wait_for_page_flip();
172}188}
173189
@@ -199,11 +215,15 @@
199 .Times(1);215 .Times(1);
200 }216 }
201217
218 append_fb_id(fb_id);
219
202 mgm::RealKMSOutput output{mock_drm.fake_drm.fd(), connector_ids[0],220 mgm::RealKMSOutput output{mock_drm.fake_drm.fd(), connector_ids[0],
203 mt::fake_shared(mock_page_flipper)};221 mt::fake_shared(mock_page_flipper)};
204222
205 EXPECT_TRUE(output.set_crtc(fb_id));223 auto fb = output.fb_for(fake_bo, 1920, 756);
206 EXPECT_TRUE(output.schedule_page_flip(fb_id));224
225 EXPECT_TRUE(output.set_crtc(*fb));
226 EXPECT_TRUE(output.schedule_page_flip(*fb));
207 output.wait_for_page_flip();227 output.wait_for_page_flip();
208}228}
209229
@@ -219,7 +239,7 @@
219 {239 {
220 InSequence s;240 InSequence s;
221241
222 EXPECT_CALL(mock_drm, drmModeSetCrtc(_, crtc_ids[0], fb_id, _, _, _, _, _))242 EXPECT_CALL(mock_drm, drmModeSetCrtc(_, crtc_ids[0], _, _, _, _, _, _))
223 .Times(1)243 .Times(1)
224 .WillOnce(Return(1));244 .WillOnce(Return(1));
225245
@@ -232,13 +252,18 @@
232 EXPECT_CALL(mock_drm, drmModeSetCrtc(_, _, _, _, _, _, _, _))252 EXPECT_CALL(mock_drm, drmModeSetCrtc(_, _, _, _, _, _, _, _))
233 .Times(0);253 .Times(0);
234 }254 }
235255 append_fb_id(fb_id);
236 mgm::RealKMSOutput output{mock_drm.fake_drm.fd(), connector_ids[0],256
237 mt::fake_shared(mock_page_flipper)};257 mgm::RealKMSOutput output{
238258 mock_drm.fake_drm.fd(),
239 EXPECT_FALSE(output.set_crtc(fb_id));259 connector_ids[0],
260 mt::fake_shared(mock_page_flipper)};
261
262 auto fb = output.fb_for(fake_bo, 1280, 1024);
263
264 EXPECT_FALSE(output.set_crtc(*fb));
240 EXPECT_NO_THROW({265 EXPECT_NO_THROW({
241 EXPECT_FALSE(output.schedule_page_flip(fb_id));266 EXPECT_FALSE(output.schedule_page_flip(*fb));
242 });267 });
243 EXPECT_THROW({ // schedule failed. It's programmer error if you then wait.268 EXPECT_THROW({ // schedule failed. It's programmer error if you then wait.
244 output.wait_for_page_flip();269 output.wait_for_page_flip();
@@ -299,7 +324,9 @@
299 mgm::RealKMSOutput output{mock_drm.fake_drm.fd(), connector_ids[0],324 mgm::RealKMSOutput output{mock_drm.fake_drm.fd(), connector_ids[0],
300 mt::fake_shared(mock_page_flipper)};325 mt::fake_shared(mock_page_flipper)};
301326
302 EXPECT_TRUE(output.set_crtc(987));327 auto fb = output.fb_for(fake_bo, 1292, 222);
328
329 EXPECT_TRUE(output.set_crtc(*fb));
303 EXPECT_NO_THROW({330 EXPECT_NO_THROW({
304 output.move_cursor({123, 456});331 output.move_cursor({123, 456});
305 });332 });
@@ -323,7 +350,9 @@
323 mgm::RealKMSOutput output{mock_drm.fake_drm.fd(), connector_ids[0],350 mgm::RealKMSOutput output{mock_drm.fake_drm.fd(), connector_ids[0],
324 mt::fake_shared(mock_page_flipper)};351 mt::fake_shared(mock_page_flipper)};
325352
326 EXPECT_TRUE(output.set_crtc(987));353 auto fb = output.fb_for(fake_bo, 1292, 222);
354
355 EXPECT_TRUE(output.set_crtc(*fb));
327 struct gbm_bo *dummy = reinterpret_cast<struct gbm_bo*>(0x1234567);356 struct gbm_bo *dummy = reinterpret_cast<struct gbm_bo*>(0x1234567);
328 EXPECT_NO_THROW({357 EXPECT_NO_THROW({
329 output.set_cursor(dummy);358 output.set_cursor(dummy);
@@ -348,7 +377,9 @@
348 mgm::RealKMSOutput output{mock_drm.fake_drm.fd(), connector_ids[0],377 mgm::RealKMSOutput output{mock_drm.fake_drm.fd(), connector_ids[0],
349 mt::fake_shared(mock_page_flipper)};378 mt::fake_shared(mock_page_flipper)};
350379
351 EXPECT_TRUE(output.set_crtc(987));380 auto fb = output.fb_for(fake_bo, 1292, 222);
381
382 EXPECT_TRUE(output.set_crtc(*fb));
352 struct gbm_bo *dummy = reinterpret_cast<struct gbm_bo*>(0x1234567);383 struct gbm_bo *dummy = reinterpret_cast<struct gbm_bo*>(0x1234567);
353 output.set_cursor(dummy);384 output.set_cursor(dummy);
354 EXPECT_FALSE(output.has_cursor());385 EXPECT_FALSE(output.has_cursor());
@@ -394,7 +425,12 @@
394 const_cast<uint16_t*>(gamma.blue.data())))425 const_cast<uint16_t*>(gamma.blue.data())))
395 .Times(1);426 .Times(1);
396427
397 EXPECT_TRUE(output.set_crtc(fb_id));428 append_fb_id(fb_id);
429
430 auto fb = output.fb_for(fake_bo, 1292, 222);
431
432 EXPECT_TRUE(output.set_crtc(*fb));
433
398 output.set_gamma(gamma);434 output.set_gamma(gamma);
399}435}
400436
@@ -418,7 +454,11 @@
418 const_cast<uint16_t*>(gamma.blue.data())))454 const_cast<uint16_t*>(gamma.blue.data())))
419 .WillOnce(Return(-ENOSYS));455 .WillOnce(Return(-ENOSYS));
420456
421 EXPECT_TRUE(output.set_crtc(fb_id));457 append_fb_id(fb_id);
458
459 auto fb = output.fb_for(fake_bo, 1292, 222);
460
461 EXPECT_TRUE(output.set_crtc(*fb));
422462
423 EXPECT_NO_THROW(output.set_gamma(gamma););463 EXPECT_NO_THROW(output.set_gamma(gamma););
424}464}

Subscribers

People subscribed via source and target branches