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
1=== modified file 'src/platforms/mesa/server/display_helpers.cpp'
2--- src/platforms/mesa/server/display_helpers.cpp 2017-01-18 02:29:37 +0000
3+++ src/platforms/mesa/server/display_helpers.cpp 2017-02-28 00:55:32 +0000
4@@ -321,6 +321,31 @@
5 {
6 }
7
8+mgmh::EGLHelper::EGLHelper(
9+ GLConfig const& gl_config,
10+ GBMHelper const& gbm,
11+ gbm_surface* surface,
12+ EGLContext shared_context)
13+ : EGLHelper(gl_config)
14+{
15+ setup(gbm, surface, shared_context);
16+}
17+
18+mgmh::EGLHelper::EGLHelper(EGLHelper&& from)
19+ : depth_buffer_bits{from.depth_buffer_bits},
20+ stencil_buffer_bits{from.stencil_buffer_bits},
21+ egl_display{from.egl_display},
22+ egl_config{from.egl_config},
23+ egl_context{from.egl_context},
24+ egl_surface{from.egl_surface},
25+ should_terminate_egl{from.should_terminate_egl}
26+{
27+ from.should_terminate_egl = false;
28+ from.egl_display = EGL_NO_DISPLAY;
29+ from.egl_context = EGL_NO_CONTEXT;
30+ from.egl_surface = EGL_NO_SURFACE;
31+}
32+
33 void mgmh::EGLHelper::setup(GBMHelper const& gbm)
34 {
35 eglBindAPI(MIR_SERVER_EGL_OPENGL_API);
36
37=== modified file 'src/platforms/mesa/server/display_helpers.h'
38--- src/platforms/mesa/server/display_helpers.h 2017-01-18 02:29:37 +0000
39+++ src/platforms/mesa/server/display_helpers.h 2017-02-28 00:55:32 +0000
40@@ -102,7 +102,13 @@
41 {
42 public:
43 EGLHelper(GLConfig const& gl_config);
44+ EGLHelper(
45+ GLConfig const& gl_config,
46+ GBMHelper const& gbm,
47+ gbm_surface* surface,
48+ EGLContext shared_context);
49 ~EGLHelper() noexcept;
50+ EGLHelper(EGLHelper&& from);
51
52 EGLHelper(const EGLHelper&) = delete;
53 EGLHelper& operator=(const EGLHelper&) = delete;
54
55=== modified file 'src/platforms/mesa/server/kms/CMakeLists.txt'
56--- src/platforms/mesa/server/kms/CMakeLists.txt 2017-01-18 02:29:37 +0000
57+++ src/platforms/mesa/server/kms/CMakeLists.txt 2017-02-28 00:55:32 +0000
58@@ -30,12 +30,16 @@
59 display.cpp
60 display_buffer.cpp
61 guest_platform.cpp
62+ page_flipper.h
63 kms_page_flipper.cpp
64 linux_virtual_terminal.cpp
65 nested_authentication.cpp
66 platform.cpp
67+ kms_display_configuration.h
68 real_kms_display_configuration.cpp
69+ kms_output.h
70 real_kms_output.cpp
71+ kms_output_container.h
72 real_kms_output_container.cpp
73 )
74
75
76=== modified file 'src/platforms/mesa/server/kms/display.cpp'
77--- src/platforms/mesa/server/kms/display.cpp 2017-02-15 07:38:33 +0000
78+++ src/platforms/mesa/server/kms/display.cpp 2017-02-28 00:55:32 +0000
79@@ -414,18 +414,25 @@
80 }
81
82 auto surface = gbm->create_scanout_surface(width, height);
83+ auto const raw_surface = surface.get();
84
85 std::unique_ptr<DisplayBuffer> db{
86 new DisplayBuffer{bypass_option,
87- drm,
88- gbm,
89 listener,
90 kms_outputs,
91- std::move(surface),
92+ GBMOutputSurface{
93+ drm->fd,
94+ std::move(surface),
95+ width, height,
96+ helpers::EGLHelper{
97+ *gl_config,
98+ *gbm,
99+ raw_surface,
100+ shared_egl.context()
101+ }
102+ },
103 bounding_rect,
104- orientation,
105- *gl_config,
106- shared_egl.context()}};
107+ orientation}};
108
109 display_buffers_new.push_back(std::move(db));
110 }
111
112=== modified file 'src/platforms/mesa/server/kms/display_buffer.cpp'
113--- src/platforms/mesa/server/kms/display_buffer.cpp 2017-02-21 01:04:13 +0000
114+++ src/platforms/mesa/server/kms/display_buffer.cpp 2017-02-28 00:55:32 +0000
115@@ -39,13 +39,13 @@
116 namespace mgm = mir::graphics::mesa;
117 namespace geom = mir::geometry;
118
119-mgm::GBMFrontBuffer::GBMFrontBuffer()
120+mgm::GBMOutputSurface::FrontBuffer::FrontBuffer()
121 : surf{nullptr},
122 bo{nullptr}
123 {
124 }
125
126-mgm::GBMFrontBuffer::GBMFrontBuffer(gbm_surface* surface)
127+mgm::GBMOutputSurface::FrontBuffer::FrontBuffer(gbm_surface* surface)
128 : surf{surface},
129 bo{gbm_surface_lock_front_buffer(surface)}
130 {
131@@ -55,7 +55,7 @@
132 }
133 }
134
135-mgm::GBMFrontBuffer::~GBMFrontBuffer()
136+mgm::GBMOutputSurface::FrontBuffer::~FrontBuffer()
137 {
138 if (surf)
139 {
140@@ -63,7 +63,7 @@
141 }
142 }
143
144-mgm::GBMFrontBuffer::GBMFrontBuffer(GBMFrontBuffer&& from)
145+mgm::GBMOutputSurface::FrontBuffer::FrontBuffer(FrontBuffer&& from)
146 : surf{from.surf},
147 bo{from.bo}
148 {
149@@ -71,7 +71,7 @@
150 const_cast<gbm_bo*&>(from.bo) = nullptr;
151 }
152
153-auto mgm::GBMFrontBuffer::operator=(GBMFrontBuffer&& from) -> GBMFrontBuffer&
154+auto mgm::GBMOutputSurface::FrontBuffer::operator=(FrontBuffer&& from) -> FrontBuffer&
155 {
156 if (surf)
157 {
158@@ -87,57 +87,24 @@
159 return *this;
160 }
161
162-auto mgm::GBMFrontBuffer::operator=(std::nullptr_t) -> GBMFrontBuffer&
163+auto mgm::GBMOutputSurface::FrontBuffer::operator=(std::nullptr_t) -> FrontBuffer&
164 {
165- return *this = GBMFrontBuffer{};
166+ return *this = FrontBuffer{};
167 }
168
169-mgm::GBMFrontBuffer::operator gbm_bo*()
170+mgm::GBMOutputSurface::FrontBuffer::operator gbm_bo*()
171 {
172 return bo;
173 }
174
175-mgm::GBMFrontBuffer::operator bool() const
176+mgm::GBMOutputSurface::FrontBuffer::operator bool() const
177 {
178 return (surf != nullptr) && (bo != nullptr);
179 }
180
181-class mgm::DRMFB
182-{
183-public:
184- DRMFB(gbm_bo* bo, uint32_t drm_fb_id)
185- : bo{bo}, drm_fb_id{drm_fb_id}
186- {
187- }
188-
189- ~DRMFB()
190- {
191- if (drm_fb_id)
192- {
193- int drm_fd = gbm_device_get_fd(gbm_bo_get_device(bo));
194- drmModeRmFB(drm_fd, drm_fb_id);
195- }
196- }
197-
198- uint32_t get_drm_fb_id() const
199- {
200- return drm_fb_id;
201- }
202-
203-private:
204- gbm_bo *bo;
205- uint32_t drm_fb_id;
206-};
207-
208 namespace
209 {
210
211-void bo_user_data_destroy(gbm_bo* /*bo*/, void *data)
212-{
213- auto bufobj = static_cast<mgm::DRMFB*>(data);
214- delete bufobj;
215-}
216-
217 void ensure_egl_image_extensions()
218 {
219 std::string ext_string;
220@@ -153,22 +120,15 @@
221
222 mgm::DisplayBuffer::DisplayBuffer(
223 mgm::BypassOption option,
224- std::shared_ptr<helpers::DRMHelper> const& drm,
225- std::shared_ptr<helpers::GBMHelper> const& gbm,
226 std::shared_ptr<DisplayReport> const& listener,
227 std::vector<std::shared_ptr<KMSOutput>> const& outputs,
228- GBMSurfaceUPtr surface_gbm_param,
229+ GBMOutputSurface&& surface_gbm,
230 geom::Rectangle const& area,
231- MirOrientation rot,
232- GLConfig const& gl_config,
233- EGLContext shared_context)
234+ MirOrientation rot)
235 : listener(listener),
236 bypass_option(option),
237- drm(drm),
238- gbm(gbm),
239 outputs(outputs),
240- egl{gl_config},
241- surface_gbm{std::move(surface_gbm_param)},
242+ surface{std::move(surface_gbm)},
243 area(area),
244 transform{mg::transformation(rot)},
245 needs_set_crtc{false},
246@@ -187,8 +147,6 @@
247 fb_height = area_height;
248 }
249
250- egl.setup(*gbm, surface_gbm.get(), shared_context);
251-
252 listener->report_successful_setup_of_native_resources();
253
254 make_current();
255@@ -199,22 +157,21 @@
256
257 glClear(GL_COLOR_BUFFER_BIT);
258
259- if (!egl.swap_buffers())
260- fatal_error("Failed to perform initial surface buffer swap");
261+ surface.swap_buffers();
262
263 listener->report_successful_egl_buffer_swap_on_construction();
264
265- visible_composite_frame = GBMFrontBuffer{surface_gbm.get()};
266+ visible_composite_frame = surface.lock_front();
267 if (!visible_composite_frame)
268 fatal_error("Failed to get frontbuffer");
269
270- set_crtc(get_drm_fb(visible_composite_frame));
271+ set_crtc(*outputs.front()->fb_for(visible_composite_frame, fb_width, fb_height));
272
273 release_current();
274
275 listener->report_successful_drm_mode_set_crtc_on_construction();
276 listener->report_successful_display_construction();
277- egl.report_egl_configuration(
278+ surface.report_egl_configuration(
279 [&listener] (EGLDisplay disp, EGLConfig cfg)
280 {
281 listener->report_egl_configuration(disp, cfg);
282@@ -258,7 +215,7 @@
283 if (native->flags & mir_buffer_flag_can_scanout &&
284 bypass_buffer->size() == geom::Size{fb_width,fb_height})
285 {
286- if (auto bufobj = get_buffer_object(native->bo))
287+ if (auto bufobj = outputs.front()->fb_for(native->bo, fb_width, fb_height))
288 {
289 bypass_buf = bypass_buffer;
290 bypass_bufobj = bufobj;
291@@ -281,13 +238,12 @@
292
293 void mgm::DisplayBuffer::swap_buffers()
294 {
295- if (!egl.swap_buffers())
296- fatal_error("Failed to perform buffer swap");
297+ surface.swap_buffers();
298 bypass_buf = nullptr;
299 bypass_bufobj = nullptr;
300 }
301
302-void mgm::DisplayBuffer::set_crtc(DRMFB const* forced_frame)
303+void mgm::DisplayBuffer::set_crtc(FBHandle const& forced_frame)
304 {
305 for (auto& output : outputs)
306 {
307@@ -298,7 +254,7 @@
308 * sometimes it's really not there). Xorg often reports similar
309 * errors, and it's not fatal.
310 */
311- if (!output->set_crtc(forced_frame->get_drm_fb_id()))
312+ if (!output->set_crtc(forced_frame))
313 mir::log_error("Failed to set DRM CRTC. "
314 "Screen contents may be incomplete. "
315 "Try plugging the monitor in again.");
316@@ -315,15 +271,15 @@
317 */
318 wait_for_page_flip();
319
320- mgm::DRMFB *bufobj;
321+ mgm::FBHandle *bufobj;
322 if (bypass_buf)
323 {
324 bufobj = bypass_bufobj;
325 }
326 else
327 {
328- scheduled_composite_frame = GBMFrontBuffer(surface_gbm.get());
329- bufobj = get_drm_fb(scheduled_composite_frame);
330+ scheduled_composite_frame = surface.lock_front();
331+ bufobj = outputs.front()->fb_for(scheduled_composite_frame, fb_width, fb_height);
332 if (!bufobj)
333 fatal_error("Failed to get front buffer object");
334 }
335@@ -332,7 +288,7 @@
336 * Try to schedule a page flip as first preference to avoid tearing.
337 * [will complete in a background thread]
338 */
339- if (!needs_set_crtc && !schedule_page_flip(bufobj))
340+ if (!needs_set_crtc && !schedule_page_flip(*bufobj))
341 needs_set_crtc = true;
342
343 /*
344@@ -341,7 +297,7 @@
345 */
346 if (needs_set_crtc)
347 {
348- set_crtc(bufobj);
349+ set_crtc(*bufobj);
350 needs_set_crtc = false;
351 }
352
353@@ -406,55 +362,7 @@
354 return recommend_sleep;
355 }
356
357-mgm::DRMFB* mgm::DisplayBuffer::get_drm_fb(GBMFrontBuffer& bo)
358-{
359- return get_buffer_object(bo);
360-}
361-
362-mgm::DRMFB* mgm::DisplayBuffer::get_buffer_object(
363- struct gbm_bo *bo)
364-{
365- if (!bo)
366- return nullptr;
367-
368- /*
369- * Check if we have already set up this gbm_bo (the gbm implementation is
370- * free to reuse gbm_bos). If so, return the associated DRMFB.
371- */
372- auto bufobj = static_cast<DRMFB*>(gbm_bo_get_user_data(bo));
373- if (bufobj)
374- return bufobj;
375-
376- uint32_t fb_id{0};
377- uint32_t handles[4] = {gbm_bo_get_handle(bo).u32, 0, 0, 0};
378- uint32_t strides[4] = {gbm_bo_get_stride(bo), 0, 0, 0};
379- uint32_t offsets[4] = {0, 0, 0, 0};
380-
381- auto format = gbm_bo_get_format(bo);
382- /*
383- * Mir might use the old GBM_BO_ enum formats, but KMS and the rest of
384- * the world need fourcc formats, so convert...
385- */
386- if (format == GBM_BO_FORMAT_XRGB8888)
387- format = GBM_FORMAT_XRGB8888;
388- else if (format == GBM_BO_FORMAT_ARGB8888)
389- format = GBM_FORMAT_ARGB8888;
390-
391- /* Create a KMS FB object with the gbm_bo attached to it. */
392- auto ret = drmModeAddFB2(drm->fd, fb_width, fb_height, format,
393- handles, strides, offsets, &fb_id, 0);
394- if (ret)
395- return nullptr;
396-
397- /* Create a DRMFB and associate it with the gbm_bo */
398- bufobj = new DRMFB{bo, fb_id};
399- gbm_bo_set_user_data(bo, bufobj, bo_user_data_destroy);
400-
401- return bufobj;
402-}
403-
404-
405-bool mgm::DisplayBuffer::schedule_page_flip(DRMFB* bufobj)
406+bool mgm::DisplayBuffer::schedule_page_flip(FBHandle const& bufobj)
407 {
408 /*
409 * Schedule the current front buffer object for display. Note that
410@@ -462,7 +370,7 @@
411 */
412 for (auto& output : outputs)
413 {
414- if (output->schedule_page_flip(bufobj->get_drm_fb_id()))
415+ if (output->schedule_page_flip(bufobj))
416 page_flips_pending = true;
417 }
418
419@@ -494,19 +402,17 @@
420
421 void mgm::DisplayBuffer::make_current()
422 {
423- if (!egl.make_current())
424- {
425- fatal_error("Failed to make EGL surface current");
426- }
427+ surface.make_current();
428 }
429
430 void mgm::DisplayBuffer::bind()
431 {
432+ surface.bind();
433 }
434
435 void mgm::DisplayBuffer::release_current()
436 {
437- egl.release_current();
438+ surface.release_current();
439 }
440
441 void mgm::DisplayBuffer::schedule_set_crtc()
442@@ -518,3 +424,62 @@
443 {
444 return this;
445 }
446+
447+mgm::GBMOutputSurface::GBMOutputSurface(
448+ int drm_fd,
449+ GBMSurfaceUPtr&& surface,
450+ uint32_t width,
451+ uint32_t height,
452+ helpers::EGLHelper&& egl)
453+ : drm_fd{drm_fd},
454+ width{width},
455+ height{height},
456+ egl{std::move(egl)},
457+ surface{std::move(surface)}
458+{
459+}
460+
461+mgm::GBMOutputSurface::GBMOutputSurface(GBMOutputSurface&& from)
462+ : drm_fd{from.drm_fd},
463+ width{from.width},
464+ height{from.height},
465+ egl{std::move(from.egl)},
466+ surface{std::move(from.surface)}
467+{
468+}
469+
470+
471+void mgm::GBMOutputSurface::make_current()
472+{
473+ if (!egl.make_current())
474+ {
475+ fatal_error("Failed to make EGL surface current");
476+ }
477+}
478+
479+void mgm::GBMOutputSurface::release_current()
480+{
481+ egl.release_current();
482+}
483+
484+void mgm::GBMOutputSurface::swap_buffers()
485+{
486+ if (!egl.swap_buffers())
487+ fatal_error("Failed to perform buffer swap");
488+}
489+
490+void mgm::GBMOutputSurface::bind()
491+{
492+
493+}
494+
495+auto mgm::GBMOutputSurface::lock_front() -> FrontBuffer
496+{
497+ return FrontBuffer{surface.get()};
498+}
499+
500+void mgm::GBMOutputSurface::report_egl_configuration(
501+ std::function<void(EGLDisplay, EGLConfig)> const& to)
502+{
503+ egl.report_egl_configuration(to);
504+}
505
506=== modified file 'src/platforms/mesa/server/kms/display_buffer.h'
507--- src/platforms/mesa/server/kms/display_buffer.h 2017-02-21 01:04:13 +0000
508+++ src/platforms/mesa/server/kms/display_buffer.h 2017-02-28 00:55:32 +0000
509@@ -41,26 +41,55 @@
510 {
511
512 class Platform;
513-class DRMFB;
514+class FBHandle;
515 class KMSOutput;
516+class NativeBuffer;
517
518-class GBMFrontBuffer
519+class GBMOutputSurface : public renderer::gl::RenderTarget
520 {
521 public:
522- GBMFrontBuffer(gbm_surface* surface);
523- GBMFrontBuffer();
524- ~GBMFrontBuffer();
525-
526- GBMFrontBuffer(GBMFrontBuffer&& from);
527-
528- GBMFrontBuffer& operator=(GBMFrontBuffer&& from);
529- GBMFrontBuffer& operator=(std::nullptr_t);
530-
531- operator gbm_bo*();
532- operator bool() const;
533+ class FrontBuffer
534+ {
535+ public:
536+ FrontBuffer();
537+ ~FrontBuffer();
538+
539+ FrontBuffer(FrontBuffer&& from);
540+
541+ FrontBuffer& operator=(FrontBuffer&& from);
542+ FrontBuffer& operator=(std::nullptr_t);
543+
544+ operator gbm_bo*();
545+ operator bool() const;
546+ private:
547+ friend class GBMOutputSurface;
548+ FrontBuffer(gbm_surface* surface);
549+
550+ gbm_surface* const surf;
551+ gbm_bo* const bo;
552+ };
553+
554+ GBMOutputSurface(
555+ int drm_fd,
556+ GBMSurfaceUPtr&& surface,
557+ uint32_t width,
558+ uint32_t height,
559+ helpers::EGLHelper&& egl);
560+ GBMOutputSurface(GBMOutputSurface&& from);
561+
562+ // gl::RenderTarget
563+ void make_current() override;
564+ void release_current() override;
565+ void swap_buffers() override;
566+ void bind() override;
567+
568+ FrontBuffer lock_front();
569+ void report_egl_configuration(std::function<void(EGLDisplay, EGLConfig)> const& to);
570 private:
571- gbm_surface* const surf;
572- gbm_bo* const bo;
573+ int const drm_fd;
574+ uint32_t width, height;
575+ helpers::EGLHelper egl;
576+ GBMSurfaceUPtr surface;
577 };
578
579 class DisplayBuffer : public graphics::DisplayBuffer,
580@@ -70,15 +99,11 @@
581 {
582 public:
583 DisplayBuffer(BypassOption bypass_options,
584- std::shared_ptr<helpers::DRMHelper> const& drm,
585- std::shared_ptr<helpers::GBMHelper> const& gbm,
586 std::shared_ptr<DisplayReport> const& listener,
587 std::vector<std::shared_ptr<KMSOutput>> const& outputs,
588- GBMSurfaceUPtr surface_gbm,
589+ GBMOutputSurface&& surface_gbm,
590 geometry::Rectangle const& area,
591- MirOrientation rot,
592- GLConfig const& gl_config,
593- EGLContext shared_context);
594+ MirOrientation rot);
595 ~DisplayBuffer();
596
597 geometry::Rectangle view_area() const override;
598@@ -101,30 +126,24 @@
599 void wait_for_page_flip();
600
601 private:
602- DRMFB* get_drm_fb(GBMFrontBuffer& bo);
603- DRMFB* get_buffer_object(struct gbm_bo *bo);
604- bool schedule_page_flip(DRMFB* bufobj);
605- void set_crtc(DRMFB const*);
606+ bool schedule_page_flip(FBHandle const& bufobj);
607+ void set_crtc(FBHandle const&);
608
609 std::shared_ptr<graphics::Buffer> visible_bypass_frame, scheduled_bypass_frame;
610 std::shared_ptr<Buffer> bypass_buf{nullptr};
611- DRMFB* bypass_bufobj{nullptr};
612+ FBHandle* bypass_bufobj{nullptr};
613 std::shared_ptr<DisplayReport> const listener;
614 BypassOption bypass_option;
615- /* DRM helper from mgm::Platform */
616- std::shared_ptr<helpers::DRMHelper> const drm;
617- std::shared_ptr<helpers::GBMHelper> const gbm;
618+
619 std::vector<std::shared_ptr<KMSOutput>> outputs;
620
621 /*
622 * Destruction order is important here:
623- * - The GBM surface depends on EGL
624 * - The GBMFrontBuffers depend on the GBM surface
625 */
626- helpers::EGLHelper egl;
627- GBMSurfaceUPtr surface_gbm;
628- GBMFrontBuffer visible_composite_frame;
629- GBMFrontBuffer scheduled_composite_frame;
630+ GBMOutputSurface surface;
631+ GBMOutputSurface::FrontBuffer visible_composite_frame;
632+ GBMOutputSurface::FrontBuffer scheduled_composite_frame;
633
634 geometry::Rectangle area;
635 uint32_t fb_width, fb_height;
636
637=== modified file 'src/platforms/mesa/server/kms/kms_output.h'
638--- src/platforms/mesa/server/kms/kms_output.h 2017-02-15 07:38:33 +0000
639+++ src/platforms/mesa/server/kms/kms_output.h 2017-02-28 00:55:32 +0000
640@@ -35,6 +35,8 @@
641 namespace mesa
642 {
643
644+class FBHandle;
645+
646 class KMSOutput
647 {
648 public:
649@@ -52,9 +54,9 @@
650 */
651 virtual int max_refresh_rate() const = 0;
652
653- virtual bool set_crtc(uint32_t fb_id) = 0;
654+ virtual bool set_crtc(FBHandle const& fb) = 0;
655 virtual void clear_crtc() = 0;
656- virtual bool schedule_page_flip(uint32_t fb_id) = 0;
657+ virtual bool schedule_page_flip(FBHandle const& fb) = 0;
658 virtual void wait_for_page_flip() = 0;
659
660 virtual bool set_cursor(gbm_bo* buffer) = 0;
661@@ -66,6 +68,8 @@
662 virtual void set_gamma(GammaCurves const& gamma) = 0;
663 virtual Frame last_frame() const = 0;
664
665+ virtual FBHandle* fb_for(gbm_bo* bo, uint32_t width, uint32_t height) const = 0;
666+
667 protected:
668 KMSOutput() = default;
669 KMSOutput(const KMSOutput&) = delete;
670
671=== modified file 'src/platforms/mesa/server/kms/real_kms_output.cpp'
672--- src/platforms/mesa/server/kms/real_kms_output.cpp 2017-02-15 07:38:33 +0000
673+++ src/platforms/mesa/server/kms/real_kms_output.cpp 2017-02-28 00:55:32 +0000
674@@ -31,6 +31,43 @@
675 namespace mgk = mg::kms;
676 namespace geom = mir::geometry;
677
678+class mgm::FBHandle
679+{
680+public:
681+ FBHandle(gbm_bo* bo, uint32_t drm_fb_id)
682+ : bo{bo}, drm_fb_id{drm_fb_id}
683+ {
684+ }
685+
686+ ~FBHandle()
687+ {
688+ if (drm_fb_id)
689+ {
690+ int drm_fd = gbm_device_get_fd(gbm_bo_get_device(bo));
691+ drmModeRmFB(drm_fd, drm_fb_id);
692+ }
693+ }
694+
695+ uint32_t get_drm_fb_id() const
696+ {
697+ return drm_fb_id;
698+ }
699+
700+private:
701+ gbm_bo *bo;
702+ uint32_t drm_fb_id;
703+};
704+
705+namespace
706+{
707+void bo_user_data_destroy(gbm_bo* /*bo*/, void *data)
708+{
709+ auto bufobj = static_cast<mgm::FBHandle*>(data);
710+ delete bufobj;
711+}
712+
713+}
714+
715 mgm::RealKMSOutput::RealKMSOutput(int drm_fd, uint32_t connector_id,
716 std::shared_ptr<PageFlipper> const& page_flipper)
717 : drm_fd{drm_fd}, connector_id{connector_id}, page_flipper{page_flipper},
718@@ -108,7 +145,7 @@
719 mode_index = kms_mode_index;
720 }
721
722-bool mgm::RealKMSOutput::set_crtc(uint32_t fb_id)
723+bool mgm::RealKMSOutput::set_crtc(FBHandle const& fb)
724 {
725 if (!ensure_crtc())
726 {
727@@ -118,7 +155,7 @@
728 }
729
730 auto ret = drmModeSetCrtc(drm_fd, current_crtc->crtc_id,
731- fb_id, fb_offset.dx.as_int(), fb_offset.dy.as_int(),
732+ fb.get_drm_fb_id(), fb_offset.dx.as_int(), fb_offset.dy.as_int(),
733 &connector->connector_id, 1,
734 &connector->modes[mode_index]);
735 if (ret)
736@@ -159,7 +196,7 @@
737 current_crtc = nullptr;
738 }
739
740-bool mgm::RealKMSOutput::schedule_page_flip(uint32_t fb_id)
741+bool mgm::RealKMSOutput::schedule_page_flip(FBHandle const& fb)
742 {
743 std::unique_lock<std::mutex> lg(power_mutex);
744 if (power_mode != mir_power_mode_on)
745@@ -170,7 +207,7 @@
746 mgk::connector_name(connector).c_str());
747 return false;
748 }
749- return page_flipper->schedule_flip(current_crtc->crtc_id, fb_id, connector_id);
750+ return page_flipper->schedule_flip(current_crtc->crtc_id, fb.get_drm_fb_id(), connector_id);
751 }
752
753 void mgm::RealKMSOutput::wait_for_page_flip()
754@@ -319,3 +356,44 @@
755
756 // TODO: return bool in future? Then do what with it?
757 }
758+
759+mgm::FBHandle* mgm::RealKMSOutput::fb_for(gbm_bo* bo, uint32_t width, uint32_t height) const
760+{
761+ if (!bo)
762+ return nullptr;
763+
764+ /*
765+ * Check if we have already set up this gbm_bo (the gbm implementation is
766+ * free to reuse gbm_bos). If so, return the associated FBHandle.
767+ */
768+ auto bufobj = static_cast<FBHandle*>(gbm_bo_get_user_data(bo));
769+ if (bufobj)
770+ return bufobj;
771+
772+ uint32_t fb_id{0};
773+ uint32_t handles[4] = {gbm_bo_get_handle(bo).u32, 0, 0, 0};
774+ uint32_t strides[4] = {gbm_bo_get_stride(bo), 0, 0, 0};
775+ uint32_t offsets[4] = {0, 0, 0, 0};
776+
777+ auto format = gbm_bo_get_format(bo);
778+ /*
779+ * Mir might use the old GBM_BO_ enum formats, but KMS and the rest of
780+ * the world need fourcc formats, so convert...
781+ */
782+ if (format == GBM_BO_FORMAT_XRGB8888)
783+ format = GBM_FORMAT_XRGB8888;
784+ else if (format == GBM_BO_FORMAT_ARGB8888)
785+ format = GBM_FORMAT_ARGB8888;
786+
787+ /* Create a KMS FB object with the gbm_bo attached to it. */
788+ auto ret = drmModeAddFB2(drm_fd, width, height, format,
789+ handles, strides, offsets, &fb_id, 0);
790+ if (ret)
791+ return nullptr;
792+
793+ /* Create a FBHandle and associate it with the gbm_bo */
794+ bufobj = new FBHandle{bo, fb_id};
795+ gbm_bo_set_user_data(bo, bufobj, bo_user_data_destroy);
796+
797+ return bufobj;
798+}
799
800=== modified file 'src/platforms/mesa/server/kms/real_kms_output.h'
801--- src/platforms/mesa/server/kms/real_kms_output.h 2017-02-15 07:38:33 +0000
802+++ src/platforms/mesa/server/kms/real_kms_output.h 2017-02-28 00:55:32 +0000
803@@ -47,9 +47,9 @@
804 geometry::Size size() const override;
805 int max_refresh_rate() const override;
806
807- bool set_crtc(uint32_t fb_id) override;
808+ bool set_crtc(FBHandle const& fb) override;
809 void clear_crtc() override;
810- bool schedule_page_flip(uint32_t fb_id) override;
811+ bool schedule_page_flip(FBHandle const& fb) override;
812 void wait_for_page_flip() override;
813
814 bool set_cursor(gbm_bo* buffer) override;
815@@ -62,6 +62,8 @@
816
817 Frame last_frame() const override;
818
819+ FBHandle* fb_for(gbm_bo* bo, uint32_t width, uint32_t height) const override;
820+
821 private:
822 bool ensure_crtc();
823 void restore_saved_crtc();
824
825=== modified file 'tests/unit-tests/platforms/mesa/kms/mock_kms_output.h'
826--- tests/unit-tests/platforms/mesa/kms/mock_kms_output.h 2017-02-15 07:38:33 +0000
827+++ tests/unit-tests/platforms/mesa/kms/mock_kms_output.h 2017-02-28 00:55:32 +0000
828@@ -24,6 +24,15 @@
829
830 namespace mir
831 {
832+
833+namespace graphics
834+{
835+namespace mesa
836+{
837+class DRMFB;
838+}
839+}
840+
841 namespace test
842 {
843
844@@ -34,9 +43,19 @@
845 MOCK_CONST_METHOD0(size, geometry::Size());
846 MOCK_CONST_METHOD0(max_refresh_rate, int());
847
848- MOCK_METHOD1(set_crtc, bool(uint32_t));
849+ bool set_crtc(graphics::mesa::FBHandle const& fb) override
850+ {
851+ return set_crtc_thunk(&fb);
852+ }
853+
854+ MOCK_METHOD1(set_crtc_thunk, bool(graphics::mesa::FBHandle const*));
855 MOCK_METHOD0(clear_crtc, void());
856- MOCK_METHOD1(schedule_page_flip, bool(uint32_t));
857+
858+ bool schedule_page_flip(graphics::mesa::FBHandle const& fb) override
859+ {
860+ return schedule_page_flip_thunk(&fb);
861+ }
862+ MOCK_METHOD1(schedule_page_flip_thunk, bool(graphics::mesa::FBHandle const*));
863 MOCK_METHOD0(wait_for_page_flip, void());
864
865 MOCK_CONST_METHOD0(last_frame, graphics::Frame());
866@@ -48,6 +67,8 @@
867
868 MOCK_METHOD1(set_power_mode, void(MirPowerMode));
869 MOCK_METHOD1(set_gamma, void(mir::graphics::GammaCurves const&));
870+
871+ MOCK_CONST_METHOD3(fb_for, graphics::mesa::FBHandle*(gbm_bo*, uint32_t, uint32_t));
872 };
873
874 } // namespace test
875
876=== modified file 'tests/unit-tests/platforms/mesa/kms/test_display_buffer.cpp'
877--- tests/unit-tests/platforms/mesa/kms/test_display_buffer.cpp 2017-01-27 08:13:36 +0000
878+++ tests/unit-tests/platforms/mesa/kms/test_display_buffer.cpp 2017-02-28 00:55:32 +0000
879@@ -85,12 +85,14 @@
880 fake_devices.add_standard_device("standard-drm-devices");
881
882 mock_kms_output = std::make_shared<NiceMock<MockKMSOutput>>();
883- ON_CALL(*mock_kms_output, set_crtc(_))
884+ ON_CALL(*mock_kms_output, set_crtc_thunk(_))
885 .WillByDefault(Return(true));
886- ON_CALL(*mock_kms_output, schedule_page_flip(_))
887+ ON_CALL(*mock_kms_output, schedule_page_flip_thunk(_))
888 .WillByDefault(Return(true));
889 ON_CALL(*mock_kms_output, max_refresh_rate())
890 .WillByDefault(Return(mock_refresh_rate));
891+ ON_CALL(*mock_kms_output, fb_for(_,_,_))
892+ .WillByDefault(Return(reinterpret_cast<FBHandle*>(0x12ad)));
893
894 ON_CALL(*mock_bypassable_buffer, size())
895 .WillByDefault(Return(display_area.size));
896@@ -108,6 +110,18 @@
897 }
898
899 protected:
900+ GBMOutputSurface make_output_surface()
901+ {
902+ helpers::EGLHelper egl{gl_config};
903+ return GBMOutputSurface{
904+ drm->fd,
905+ GBMSurfaceUPtr{nullptr},
906+ static_cast<uint32_t>(width),
907+ static_cast<uint32_t>(height),
908+ std::move(egl)
909+ };
910+ }
911+
912 int const width{56};
913 int const height{78};
914 mir::geometry::Rectangle const display_area{{12,34}, {width,height}};
915@@ -135,15 +149,11 @@
916 {
917 graphics::mesa::DisplayBuffer db(
918 graphics::mesa::BypassOption::allowed,
919- drm,
920- gbm,
921 null_display_report(),
922- {},
923- nullptr,
924+ {mock_kms_output},
925+ make_output_surface(),
926 display_area,
927- mir_orientation_normal,
928- gl_config,
929- mock_egl.fake_egl_context);
930+ mir_orientation_normal);
931
932 EXPECT_EQ(display_area, db.view_area());
933 }
934@@ -152,15 +162,11 @@
935 {
936 graphics::mesa::DisplayBuffer db(
937 graphics::mesa::BypassOption::allowed,
938- drm,
939- gbm,
940 null_display_report(),
941 {mock_kms_output},
942- nullptr,
943+ make_output_surface(),
944 display_area,
945- mir_orientation_normal,
946- gl_config,
947- mock_egl.fake_egl_context);
948+ mir_orientation_normal);
949
950 auto original_count = mock_bypassable_buffer.use_count();
951
952@@ -180,15 +186,11 @@
953 {
954 graphics::mesa::DisplayBuffer db(
955 graphics::mesa::BypassOption::allowed,
956- drm,
957- gbm,
958 null_display_report(),
959 {mock_kms_output},
960- nullptr,
961+ make_output_surface(),
962 display_area,
963- mir_orientation_normal,
964- gl_config,
965- mock_egl.fake_egl_context);
966+ mir_orientation_normal);
967
968 for (int frame = 0; frame < 5; ++frame)
969 {
970@@ -210,15 +212,11 @@
971
972 graphics::mesa::DisplayBuffer db(
973 graphics::mesa::BypassOption::allowed,
974- drm,
975- gbm,
976 null_display_report(),
977 {mock_kms_output},
978- nullptr,
979+ make_output_surface(),
980 display_area,
981- mir_orientation_normal,
982- gl_config,
983- mock_egl.fake_egl_context);
984+ mir_orientation_normal);
985
986 for (int frame = 0; frame < 5; ++frame)
987 {
988@@ -234,15 +232,11 @@
989 {
990 graphics::mesa::DisplayBuffer db(
991 graphics::mesa::BypassOption::allowed,
992- drm,
993- gbm,
994 null_display_report(),
995 {mock_kms_output},
996- nullptr,
997+ make_output_surface(),
998 display_area,
999- mir_orientation_normal,
1000- gl_config,
1001- mock_egl.fake_egl_context);
1002+ mir_orientation_normal);
1003
1004 auto original_count = mock_bypassable_buffer.use_count();
1005
1006@@ -259,37 +253,29 @@
1007 {
1008 graphics::mesa::DisplayBuffer db(
1009 graphics::mesa::BypassOption::allowed,
1010- drm,
1011- gbm,
1012 null_display_report(),
1013 {mock_kms_output},
1014- nullptr,
1015+ make_output_surface(),
1016 display_area,
1017- mir_orientation_normal,
1018- gl_config,
1019- mock_egl.fake_egl_context);
1020+ mir_orientation_normal);
1021
1022 EXPECT_TRUE(db.overlay(bypassable_list));
1023 }
1024
1025 TEST_F(MesaDisplayBufferTest, failed_bypass_falls_back_gracefully)
1026 { // Regression test for LP: #1398296
1027- EXPECT_CALL(mock_drm, drmModeAddFB2(_, _, _, _, _, _, _, _, _))
1028- .WillOnce(Return(0)) // During the DisplayBuffer constructor
1029- .WillOnce(Return(-22)) // Fail first bypass attempt
1030- .WillOnce(Return(0)); // Succeed second bypass attempt
1031+ EXPECT_CALL(*mock_kms_output, fb_for(_,_,_))
1032+ .WillOnce(Return(reinterpret_cast<FBHandle*>(0xaabb))) // During the DisplayBuffer constructor
1033+ .WillOnce(Return(nullptr)) // Fail first bypass attempt
1034+ .WillOnce(Return(reinterpret_cast<FBHandle*>(0xbbcc))); // Succeed second bypass attempt
1035
1036 graphics::mesa::DisplayBuffer db(
1037 graphics::mesa::BypassOption::allowed,
1038- drm,
1039- gbm,
1040 null_display_report(),
1041 {mock_kms_output},
1042- nullptr,
1043+ make_output_surface(),
1044 display_area,
1045- mir_orientation_normal,
1046- gl_config,
1047- mock_egl.fake_egl_context);
1048+ mir_orientation_normal);
1049
1050 EXPECT_FALSE(db.overlay(bypassable_list));
1051 // And then we recover. DRM finds enough resources to AddFB ...
1052@@ -310,15 +296,11 @@
1053
1054 graphics::mesa::DisplayBuffer db(
1055 graphics::mesa::BypassOption::allowed,
1056- drm,
1057- gbm,
1058 null_display_report(),
1059 {mock_kms_output},
1060- nullptr,
1061+ make_output_surface(),
1062 display_area,
1063- mir_orientation_normal,
1064- gl_config,
1065- mock_egl.fake_egl_context);
1066+ mir_orientation_normal);
1067
1068 EXPECT_FALSE(db.overlay(list));
1069 }
1070@@ -327,15 +309,11 @@
1071 {
1072 graphics::mesa::DisplayBuffer db(
1073 graphics::mesa::BypassOption::allowed,
1074- drm,
1075- gbm,
1076 null_display_report(),
1077- {},
1078- nullptr,
1079+ {mock_kms_output},
1080+ make_output_surface(),
1081 display_area,
1082- mir_orientation_right,
1083- gl_config,
1084- mock_egl.fake_egl_context);
1085+ mir_orientation_right);
1086
1087 EXPECT_FALSE(db.overlay(bypassable_list));
1088 }
1089@@ -349,15 +327,11 @@
1090
1091 graphics::mesa::DisplayBuffer db(
1092 graphics::mesa::BypassOption::allowed,
1093- drm,
1094- gbm,
1095 null_display_report(),
1096- {},
1097- nullptr,
1098+ {mock_kms_output},
1099+ make_output_surface(),
1100 display_area,
1101- mir_orientation_normal,
1102- gl_config,
1103- mock_egl.fake_egl_context);
1104+ mir_orientation_normal);
1105
1106 EXPECT_FALSE(db.overlay(list));
1107 }
1108@@ -371,15 +345,11 @@
1109
1110 graphics::mesa::DisplayBuffer db(
1111 graphics::mesa::BypassOption::allowed,
1112- drm,
1113- gbm,
1114 null_display_report(),
1115- {},
1116- nullptr,
1117+ {mock_kms_output},
1118+ make_output_surface(),
1119 display_area,
1120- mir_orientation_normal,
1121- gl_config,
1122- mock_egl.fake_egl_context);
1123+ mir_orientation_normal);
1124
1125 // If you find yourself using gbm_ functions on a Shm buffer then you're
1126 // asking for a crash (LP: #1493721) ...
1127@@ -394,119 +364,31 @@
1128
1129 graphics::mesa::DisplayBuffer db(
1130 graphics::mesa::BypassOption::allowed,
1131- drm,
1132- gbm,
1133 null_display_report(),
1134- {},
1135- nullptr,
1136+ {mock_kms_output},
1137+ make_output_surface(),
1138 display_area,
1139- mir_orientation_left,
1140- gl_config,
1141- mock_egl.fake_egl_context);
1142+ mir_orientation_left);
1143
1144 EXPECT_EQ(rotate_left, db.transformation());
1145 }
1146
1147-TEST_F(MesaDisplayBufferTest, normal_rotation_constructs_normal_fb)
1148-{
1149- EXPECT_CALL(mock_gbm, gbm_bo_get_user_data(_))
1150- .WillOnce(Return((void*)0));
1151- EXPECT_CALL(mock_drm, drmModeAddFB2(_, width, height, _, _, _, _, _, _))
1152- .Times(1);
1153-
1154- graphics::mesa::DisplayBuffer db(
1155- graphics::mesa::BypassOption::allowed,
1156- drm,
1157- gbm,
1158- null_display_report(),
1159- {},
1160- nullptr,
1161- display_area,
1162- mir_orientation_normal,
1163- gl_config,
1164- mock_egl.fake_egl_context);
1165-}
1166-
1167-TEST_F(MesaDisplayBufferTest, left_rotation_constructs_transposed_fb)
1168-{
1169- EXPECT_CALL(mock_gbm, gbm_bo_get_user_data(_))
1170- .WillOnce(Return((void*)0));
1171- EXPECT_CALL(mock_drm, drmModeAddFB2(_, height, width, _, _, _, _, _, _))
1172- .Times(1);
1173-
1174- graphics::mesa::DisplayBuffer db(
1175- graphics::mesa::BypassOption::allowed,
1176- drm,
1177- gbm,
1178- null_display_report(),
1179- {},
1180- nullptr,
1181- display_area,
1182- mir_orientation_left,
1183- gl_config,
1184- mock_egl.fake_egl_context);
1185-}
1186-
1187-TEST_F(MesaDisplayBufferTest, inverted_rotation_constructs_normal_fb)
1188-{
1189- EXPECT_CALL(mock_gbm, gbm_bo_get_user_data(_))
1190- .WillOnce(Return((void*)0));
1191- EXPECT_CALL(mock_drm, drmModeAddFB2(_, width, height, _, _, _, _, _, _))
1192- .Times(1);
1193-
1194- graphics::mesa::DisplayBuffer db(
1195- graphics::mesa::BypassOption::allowed,
1196- drm,
1197- gbm,
1198- null_display_report(),
1199- {},
1200- nullptr,
1201- display_area,
1202- mir_orientation_inverted,
1203- gl_config,
1204- mock_egl.fake_egl_context);
1205-}
1206-
1207-TEST_F(MesaDisplayBufferTest, right_rotation_constructs_transposed_fb)
1208-{
1209- EXPECT_CALL(mock_gbm, gbm_bo_get_user_data(_))
1210- .WillOnce(Return((void*)0));
1211- EXPECT_CALL(mock_drm, drmModeAddFB2(_, height, width, _, _, _, _, _, _))
1212- .Times(1);
1213-
1214- graphics::mesa::DisplayBuffer db(
1215- graphics::mesa::BypassOption::allowed,
1216- drm,
1217- gbm,
1218- null_display_report(),
1219- {},
1220- nullptr,
1221- display_area,
1222- mir_orientation_right,
1223- gl_config,
1224- mock_egl.fake_egl_context);
1225-}
1226-
1227 TEST_F(MesaDisplayBufferTest, clone_mode_first_flip_flips_but_no_wait)
1228 {
1229 // Ensure clone mode can do multiple page flips in parallel without
1230 // blocking on either (at least till the second post)
1231- EXPECT_CALL(*mock_kms_output, schedule_page_flip(_))
1232+ EXPECT_CALL(*mock_kms_output, schedule_page_flip_thunk(_))
1233 .Times(2);
1234 EXPECT_CALL(*mock_kms_output, wait_for_page_flip())
1235 .Times(0);
1236
1237 graphics::mesa::DisplayBuffer db(
1238 graphics::mesa::BypassOption::allowed,
1239- drm,
1240- gbm,
1241 null_display_report(),
1242 {mock_kms_output, mock_kms_output},
1243- nullptr,
1244+ make_output_surface(),
1245 display_area,
1246- mir_orientation_normal,
1247- gl_config,
1248- mock_egl.fake_egl_context);
1249+ mir_orientation_normal);
1250
1251 db.swap_buffers();
1252 db.post();
1253@@ -514,22 +396,18 @@
1254
1255 TEST_F(MesaDisplayBufferTest, single_mode_first_post_flips_with_wait)
1256 {
1257- EXPECT_CALL(*mock_kms_output, schedule_page_flip(_))
1258+ EXPECT_CALL(*mock_kms_output, schedule_page_flip_thunk(_))
1259 .Times(1);
1260 EXPECT_CALL(*mock_kms_output, wait_for_page_flip())
1261 .Times(1);
1262
1263 graphics::mesa::DisplayBuffer db(
1264 graphics::mesa::BypassOption::allowed,
1265- drm,
1266- gbm,
1267 null_display_report(),
1268 {mock_kms_output},
1269- nullptr,
1270+ make_output_surface(),
1271 display_area,
1272- mir_orientation_normal,
1273- gl_config,
1274- mock_egl.fake_egl_context);
1275+ mir_orientation_normal);
1276
1277 db.swap_buffers();
1278 db.post();
1279@@ -541,26 +419,22 @@
1280
1281 EXPECT_CALL(*mock_kms_output, wait_for_page_flip())
1282 .Times(0);
1283- EXPECT_CALL(*mock_kms_output, schedule_page_flip(_))
1284+ EXPECT_CALL(*mock_kms_output, schedule_page_flip_thunk(_))
1285 .Times(2);
1286 EXPECT_CALL(*mock_kms_output, wait_for_page_flip())
1287 .Times(2);
1288- EXPECT_CALL(*mock_kms_output, schedule_page_flip(_))
1289+ EXPECT_CALL(*mock_kms_output, schedule_page_flip_thunk(_))
1290 .Times(2);
1291 EXPECT_CALL(*mock_kms_output, wait_for_page_flip())
1292 .Times(0);
1293
1294 graphics::mesa::DisplayBuffer db(
1295 graphics::mesa::BypassOption::allowed,
1296- drm,
1297- gbm,
1298 null_display_report(),
1299 {mock_kms_output, mock_kms_output},
1300- nullptr,
1301+ make_output_surface(),
1302 display_area,
1303- mir_orientation_normal,
1304- gl_config,
1305- mock_egl.fake_egl_context);
1306+ mir_orientation_normal);
1307
1308 db.swap_buffers();
1309 db.post();
1310@@ -578,15 +452,11 @@
1311
1312 graphics::mesa::DisplayBuffer db(
1313 graphics::mesa::BypassOption::allowed,
1314- drm,
1315- gbm,
1316 null_display_report(),
1317 {mock_kms_output},
1318- nullptr,
1319+ make_output_surface(),
1320 display_area,
1321- mir_orientation_normal,
1322- gl_config,
1323- mock_egl.fake_egl_context);
1324+ mir_orientation_normal);
1325
1326 EXPECT_FALSE(db.overlay(list));
1327 }
1328@@ -607,15 +477,11 @@
1329
1330 graphics::mesa::DisplayBuffer db(
1331 graphics::mesa::BypassOption::allowed,
1332- drm,
1333- gbm,
1334 null_display_report(),
1335 {mock_kms_output},
1336- nullptr,
1337+ make_output_surface(),
1338 display_area,
1339- mir_orientation_normal,
1340- gl_config,
1341- mock_egl.fake_egl_context);
1342+ mir_orientation_normal);
1343
1344 EXPECT_FALSE(db.overlay(list));
1345 }
1346
1347=== modified file 'tests/unit-tests/platforms/mesa/kms/test_real_kms_output.cpp'
1348--- tests/unit-tests/platforms/mesa/kms/test_real_kms_output.cpp 2017-01-18 02:29:37 +0000
1349+++ tests/unit-tests/platforms/mesa/kms/test_real_kms_output.cpp 2017-02-28 00:55:32 +0000
1350@@ -66,6 +66,9 @@
1351 {
1352 ON_CALL(mock_page_flipper, wait_for_flip(_))
1353 .WillByDefault(Return(mg::Frame{}));
1354+
1355+ ON_CALL(mock_gbm, gbm_bo_get_handle(_))
1356+ .WillByDefault(Return(gbm_bo_handle{0}));
1357 }
1358
1359 void setup_outputs_connected_crtc()
1360@@ -106,12 +109,22 @@
1361 resources.prepare();
1362 }
1363
1364+ void append_fb_id(uint32_t fb_id)
1365+ {
1366+ EXPECT_CALL(mock_drm, drmModeAddFB2(_,_,_,_,_,_,_,_,_))
1367+ .WillOnce(
1368+ DoAll(
1369+ SetArgPointee<7>(fb_id),
1370+ Return(0)));
1371+ }
1372+
1373 testing::NiceMock<mtd::MockDRM> mock_drm;
1374 testing::NiceMock<mtd::MockGBM> mock_gbm;
1375 MockPageFlipper mock_page_flipper;
1376 NullPageFlipper null_page_flipper;
1377
1378 std::vector<drmModeModeInfo> modes_empty;
1379+ gbm_bo* const fake_bo{reinterpret_cast<gbm_bo*>(0x123ba)};
1380 uint32_t const invalid_id;
1381 std::vector<uint32_t> const crtc_ids;
1382 std::vector<uint32_t> const encoder_ids;
1383@@ -139,10 +152,11 @@
1384 {
1385 using namespace testing;
1386
1387- uint32_t const fb_id{67};
1388-
1389 setup_outputs_connected_crtc();
1390
1391+ uint32_t const fb_id{42};
1392+ append_fb_id(fb_id);
1393+
1394 {
1395 InSequence s;
1396
1397@@ -166,8 +180,10 @@
1398 mgm::RealKMSOutput output{mock_drm.fake_drm.fd(), connector_ids[0],
1399 mt::fake_shared(mock_page_flipper)};
1400
1401- EXPECT_TRUE(output.set_crtc(fb_id));
1402- EXPECT_TRUE(output.schedule_page_flip(fb_id));
1403+ auto fb = output.fb_for(fake_bo, 1920, 1024);
1404+
1405+ EXPECT_TRUE(output.set_crtc(*fb));
1406+ EXPECT_TRUE(output.schedule_page_flip(*fb));
1407 output.wait_for_page_flip();
1408 }
1409
1410@@ -199,11 +215,15 @@
1411 .Times(1);
1412 }
1413
1414+ append_fb_id(fb_id);
1415+
1416 mgm::RealKMSOutput output{mock_drm.fake_drm.fd(), connector_ids[0],
1417 mt::fake_shared(mock_page_flipper)};
1418
1419- EXPECT_TRUE(output.set_crtc(fb_id));
1420- EXPECT_TRUE(output.schedule_page_flip(fb_id));
1421+ auto fb = output.fb_for(fake_bo, 1920, 756);
1422+
1423+ EXPECT_TRUE(output.set_crtc(*fb));
1424+ EXPECT_TRUE(output.schedule_page_flip(*fb));
1425 output.wait_for_page_flip();
1426 }
1427
1428@@ -219,7 +239,7 @@
1429 {
1430 InSequence s;
1431
1432- EXPECT_CALL(mock_drm, drmModeSetCrtc(_, crtc_ids[0], fb_id, _, _, _, _, _))
1433+ EXPECT_CALL(mock_drm, drmModeSetCrtc(_, crtc_ids[0], _, _, _, _, _, _))
1434 .Times(1)
1435 .WillOnce(Return(1));
1436
1437@@ -232,13 +252,18 @@
1438 EXPECT_CALL(mock_drm, drmModeSetCrtc(_, _, _, _, _, _, _, _))
1439 .Times(0);
1440 }
1441-
1442- mgm::RealKMSOutput output{mock_drm.fake_drm.fd(), connector_ids[0],
1443- mt::fake_shared(mock_page_flipper)};
1444-
1445- EXPECT_FALSE(output.set_crtc(fb_id));
1446+ append_fb_id(fb_id);
1447+
1448+ mgm::RealKMSOutput output{
1449+ mock_drm.fake_drm.fd(),
1450+ connector_ids[0],
1451+ mt::fake_shared(mock_page_flipper)};
1452+
1453+ auto fb = output.fb_for(fake_bo, 1280, 1024);
1454+
1455+ EXPECT_FALSE(output.set_crtc(*fb));
1456 EXPECT_NO_THROW({
1457- EXPECT_FALSE(output.schedule_page_flip(fb_id));
1458+ EXPECT_FALSE(output.schedule_page_flip(*fb));
1459 });
1460 EXPECT_THROW({ // schedule failed. It's programmer error if you then wait.
1461 output.wait_for_page_flip();
1462@@ -299,7 +324,9 @@
1463 mgm::RealKMSOutput output{mock_drm.fake_drm.fd(), connector_ids[0],
1464 mt::fake_shared(mock_page_flipper)};
1465
1466- EXPECT_TRUE(output.set_crtc(987));
1467+ auto fb = output.fb_for(fake_bo, 1292, 222);
1468+
1469+ EXPECT_TRUE(output.set_crtc(*fb));
1470 EXPECT_NO_THROW({
1471 output.move_cursor({123, 456});
1472 });
1473@@ -323,7 +350,9 @@
1474 mgm::RealKMSOutput output{mock_drm.fake_drm.fd(), connector_ids[0],
1475 mt::fake_shared(mock_page_flipper)};
1476
1477- EXPECT_TRUE(output.set_crtc(987));
1478+ auto fb = output.fb_for(fake_bo, 1292, 222);
1479+
1480+ EXPECT_TRUE(output.set_crtc(*fb));
1481 struct gbm_bo *dummy = reinterpret_cast<struct gbm_bo*>(0x1234567);
1482 EXPECT_NO_THROW({
1483 output.set_cursor(dummy);
1484@@ -348,7 +377,9 @@
1485 mgm::RealKMSOutput output{mock_drm.fake_drm.fd(), connector_ids[0],
1486 mt::fake_shared(mock_page_flipper)};
1487
1488- EXPECT_TRUE(output.set_crtc(987));
1489+ auto fb = output.fb_for(fake_bo, 1292, 222);
1490+
1491+ EXPECT_TRUE(output.set_crtc(*fb));
1492 struct gbm_bo *dummy = reinterpret_cast<struct gbm_bo*>(0x1234567);
1493 output.set_cursor(dummy);
1494 EXPECT_FALSE(output.has_cursor());
1495@@ -394,7 +425,12 @@
1496 const_cast<uint16_t*>(gamma.blue.data())))
1497 .Times(1);
1498
1499- EXPECT_TRUE(output.set_crtc(fb_id));
1500+ append_fb_id(fb_id);
1501+
1502+ auto fb = output.fb_for(fake_bo, 1292, 222);
1503+
1504+ EXPECT_TRUE(output.set_crtc(*fb));
1505+
1506 output.set_gamma(gamma);
1507 }
1508
1509@@ -418,7 +454,11 @@
1510 const_cast<uint16_t*>(gamma.blue.data())))
1511 .WillOnce(Return(-ENOSYS));
1512
1513- EXPECT_TRUE(output.set_crtc(fb_id));
1514+ append_fb_id(fb_id);
1515+
1516+ auto fb = output.fb_for(fake_bo, 1292, 222);
1517+
1518+ EXPECT_TRUE(output.set_crtc(*fb));
1519
1520 EXPECT_NO_THROW(output.set_gamma(gamma););
1521 }

Subscribers

People subscribed via source and target branches