Mir

Merge lp:~alan-griffiths/mir/fix-1701308 into lp:mir

Proposed by Alan Griffiths
Status: Merged
Approved by: Alan Griffiths
Approved revision: no longer in the source branch.
Merged at revision: 4202
Proposed branch: lp:~alan-griffiths/mir/fix-1701308
Merge into: lp:mir
Diff against target: 123 lines (+27/-40)
2 files modified
examples/eglapp.c (+12/-23)
src/client/mir_connection.cpp (+15/-17)
To merge this branch: bzr merge lp:~alan-griffiths/mir/fix-1701308
Reviewer Review Type Date Requested Status
Mir CI Bot continuous-integration Approve
Gerry Boland (community) Approve
Daniel van Vugt Abstain
Review via email: mp+326582@code.launchpad.net

Commit message

Handle initial window size being imposed by shell in eglapps.

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

Is this reliable?

I had previously discovered that you can't rely on the resize callback occurring before the app starts rendering its first frame:

https://code.launchpad.net/~vanvugt/mir/fix-1686620/+merge/323378

So I guess if you are relying on the callback then the app could render two frames on startup... First at the size it requested, and very soon again at the size the shell requested.

It won't look pretty rendering that first frame at the wrong size so I suggest using the EGL_WIDTH/HEIGHT approach shown above. Sounds like it just got broken by the Mesa-RS changes. So if Mesa is now reporting a bogus EGL_WIDTH/HEIGHT that really needs to be fixed (as a matter of higher priority and also would supersede this proposal).

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

FAILED: Continuous integration, rev:4202
https://mir-jenkins.ubuntu.com/job/mir-ci/3468/
Executed test runs:
    FAILURE: https://mir-jenkins.ubuntu.com/job/build-mir/4738/console
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-0-fetch/4896
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=artful/4885
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=xenial/4885
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=zesty/4885
    FAILURE: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=clang,platform=mesa,release=artful/4775/console
    FAILURE: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=clang,platform=mesa,release=zesty/4775/console
    FAILURE: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=artful/4775/console
    FAILURE: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=xenial/4775/console
    FAILURE: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=zesty/4775/console
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=cross-armhf,compiler=gcc,platform=mesa,release=artful/4775
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=cross-armhf,compiler=gcc,platform=mesa,release=artful/4775/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=cross-armhf,compiler=gcc,platform=mesa,release=zesty/4775
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=cross-armhf,compiler=gcc,platform=mesa,release=zesty/4775/artifact/output/*zip*/output.zip
    FAILURE: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=mesa,release=xenial/4775/console

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

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

> Is this reliable?
>
> I had previously discovered that you can't rely on the resize callback
> occurring before the app starts rendering its first frame:

It is possible for a frame to be rendered at the requested (not actual) size: the "created" callback is, necessarily, called before the "resize" callback.

With our undeprecated the client cannot query the window size in the "created" callback.

> I suggest using the EGL_WIDTH/HEIGHT approach shown above

Remember the server has only sized the window, not the surface. The current RS design relies on the client to implement the surface resize. As discussed in the bug comments there's no quick fix for that.

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

OK. I don't understand all of that but the last paragraph makes sense at least.

review: Abstain
Revision history for this message
Gerry Boland (gerboland) wrote :

I'm confused, as in eglapp.c after surface spec creation, it uses eglQuerySurface to fetch surface width & height, and has a big comment

 * Mir reserves the right to ignore our initial window dimensions and
 * resize to whatever it likes. Usually that resize callback has
 * occurred by now (see r4150), but libmirclient does not provide a
 * solid guarantee of it. Luckily, we don't care... by querying EGL
 * buffer dimensions we can get the correct answer without being
 * victim to the callback race that's going on in the background...
 * If the server has given us dimensions other than what we requested
 * then EGL will already know about it, possibly before the initial
 * resize event (!).

This patch does fix the delivery of the resize event, but as this comment says, surely the egl surface should have had the correct dimensions anyway?

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

> I'm confused, as in eglapp.c after surface spec creation, it uses
> eglQuerySurface to fetch surface width & height, and has a big comment
>
> * Mir reserves the right to ignore our initial window dimensions and
> * resize to whatever it likes. Usually that resize callback has
> * occurred by now (see r4150), but libmirclient does not provide a
> * solid guarantee of it. Luckily, we don't care... by querying EGL
> * buffer dimensions we can get the correct answer without being
> * victim to the callback race that's going on in the background...
> * If the server has given us dimensions other than what we requested
> * then EGL will already know about it, possibly before the initial
> * resize event (!).
>
> This patch does fix the delivery of the resize event, but as this comment
> says, surely the egl surface should have had the correct dimensions anyway?

That comment was obsolete: EGL has the size of the surface (not the window) which is controlled by the client.

Revision history for this message
Gerry Boland (gerboland) wrote :

Ok, I follow what is happening better now. And testing, it works ok

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

PASSED: Continuous integration, rev:4203
https://mir-jenkins.ubuntu.com/job/mir-ci/3469/
Executed test runs:
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-mir/4739
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-0-fetch/4897
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=artful/4886
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=xenial/4886
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=zesty/4886
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=clang,platform=mesa,release=artful/4776
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=clang,platform=mesa,release=artful/4776/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=clang,platform=mesa,release=zesty/4776
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=clang,platform=mesa,release=zesty/4776/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=artful/4776
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=artful/4776/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=xenial/4776
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=xenial/4776/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=zesty/4776
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=zesty/4776/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=cross-armhf,compiler=gcc,platform=mesa,release=artful/4776
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=cross-armhf,compiler=gcc,platform=mesa,release=artful/4776/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=cross-armhf,compiler=gcc,platform=mesa,release=zesty/4776
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=cross-armhf,compiler=gcc,platform=mesa,release=zesty/4776/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=mesa,release=xenial/4776
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=mesa,release=xenial/4776/artifact/output/*zip*/output.zip

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

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

PASSED: Continuous integration, rev:4206
https://mir-jenkins.ubuntu.com/job/mir-ci/3471/
Executed test runs:
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-mir/4742
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-0-fetch/4900
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=artful/4889
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=xenial/4889
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=zesty/4889
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=clang,platform=mesa,release=artful/4779
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=clang,platform=mesa,release=artful/4779/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=clang,platform=mesa,release=zesty/4779
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=clang,platform=mesa,release=zesty/4779/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=artful/4779
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=artful/4779/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=xenial/4779
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=xenial/4779/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=zesty/4779
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=zesty/4779/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=cross-armhf,compiler=gcc,platform=mesa,release=artful/4779
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=cross-armhf,compiler=gcc,platform=mesa,release=artful/4779/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=cross-armhf,compiler=gcc,platform=mesa,release=zesty/4779
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=cross-armhf,compiler=gcc,platform=mesa,release=zesty/4779/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=mesa,release=xenial/4779
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=mesa,release=xenial/4779/artifact/output/*zip*/output.zip

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

review: Approve (continuous-integration)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'examples/eglapp.c'
--- examples/eglapp.c 2017-06-06 15:41:28 +0000
+++ examples/eglapp.c 2017-06-30 11:36:00 +0000
@@ -161,7 +161,6 @@
161161
162void mir_eglapp_handle_event(MirWindow* window, MirEvent const* ev, void* unused)162void mir_eglapp_handle_event(MirWindow* window, MirEvent const* ev, void* unused)
163{163{
164 (void) window;
165 (void) unused;164 (void) unused;
166165
167 switch (mir_event_get_type(ev))166 switch (mir_event_get_type(ev))
@@ -201,13 +200,13 @@
201200
202 printf("Resized to %dx%d\n", new_width, new_height);201 printf("Resized to %dx%d\n", new_width, new_height);
203 if (surface)202 if (surface)
204 {203 {
205 mir_render_surface_set_size(surface, new_width, new_height);204 mir_render_surface_set_size(surface, new_width, new_height);
206 MirWindowSpec* spec = mir_create_window_spec(connection);205 MirWindowSpec* spec = mir_create_window_spec(connection);
207 mir_window_spec_add_render_surface(spec, surface, new_width, new_height, 0, 0);206 mir_window_spec_add_render_surface(spec, surface, new_width, new_height, 0, 0);
208 mir_window_apply_spec(window, spec);207 mir_window_apply_spec(window, spec);
209 mir_window_spec_release(spec);208 mir_window_spec_release(spec);
210 }209 }
211}210}
212211
213static void show_help(struct mir_eglapp_arg const* const* arg_lists)212static void show_help(struct mir_eglapp_arg const* const* arg_lists)
@@ -462,6 +461,8 @@
462 name = p + 1;461 name = p + 1;
463 }462 }
464 mir_window_spec_set_name(spec, name);463 mir_window_spec_set_name(spec, name);
464 mir_window_spec_set_event_handler(spec, mir_eglapp_handle_event, NULL);
465 mir_window_spec_set_cursor_name(spec, cursor_name);
465466
466 if (output_id != mir_display_output_id_invalid)467 if (output_id != mir_display_output_id_invalid)
467 mir_window_spec_set_fullscreen_on_output(spec, output_id);468 mir_window_spec_set_fullscreen_on_output(spec, output_id);
@@ -471,13 +472,6 @@
471472
472 CHECK(mir_window_is_valid(window), "Can't create a window");473 CHECK(mir_window_is_valid(window), "Can't create a window");
473474
474 mir_window_set_event_handler(window, mir_eglapp_handle_event, NULL);
475
476 spec = mir_create_window_spec(connection);
477 mir_window_spec_set_cursor_name(spec, cursor_name);
478 mir_window_apply_spec(window, spec);
479 mir_window_spec_release(spec);
480
481 eglsurface = eglCreateWindowSurface(egldisplay,475 eglsurface = eglCreateWindowSurface(egldisplay,
482 eglconfig,476 eglconfig,
483 (EGLNativeWindowType)surface,477 (EGLNativeWindowType)surface,
@@ -498,14 +492,9 @@
498 {492 {
499 /*493 /*
500 * Mir reserves the right to ignore our initial window dimensions and494 * Mir reserves the right to ignore our initial window dimensions and
501 * resize to whatever it likes. Usually that resize callback has495 * resize to whatever it likes. In that case, a resize callback to
502 * occurred by now (see r4150), but libmirclient does not provide a496 * mir_eglapp_handle_event() has occurred by now and we have resized
503 * solid guarantee of it. Luckily, we don't care... by querying EGL497 * the eglsurface.
504 * buffer dimensions we can get the correct answer without being
505 * victim to the callback race that's going on in the background...
506 * If the server has given us dimensions other than what we requested
507 * then EGL will already know about it, possibly before the initial
508 * resize event (!).
509 */498 */
510 *width = buf_width;499 *width = buf_width;
511 *height = buf_height;500 *height = buf_height;
512501
=== modified file 'src/client/mir_connection.cpp'
--- src/client/mir_connection.cpp 2017-06-09 14:16:54 +0000
+++ src/client/mir_connection.cpp 2017-06-30 11:36:00 +0000
@@ -276,21 +276,6 @@
276 MIR_LOG_UNCAUGHT_EXCEPTION(ex);276 MIR_LOG_UNCAUGHT_EXCEPTION(ex);
277}277}
278278
279void send_resize_event_if_needed(MirWindow *window, MirWindowSpec const& spec, mir::protobuf::Surface const& surface_proto)
280{
281 if (spec.width.is_set() && spec.height.is_set() && spec.event_handler.is_set())
282 {
283 mir::geometry::Size requested_size{spec.width.value(), spec.height.value()};
284 mir::geometry::Size actual_size{surface_proto.width(), surface_proto.height()};
285 auto event_handler = spec.event_handler.value();
286 if (requested_size != actual_size)
287 {
288 auto event = mev::make_event(mf::SurfaceId{surface_proto.id().value()}, actual_size);
289 event_handler.callback(window, event.get(), event_handler.context);
290 }
291 }
292}
293
294std::mutex connection_guard;279std::mutex connection_guard;
295MirConnection* valid_connections{nullptr};280MirConnection* valid_connections{nullptr};
296}281}
@@ -485,9 +470,22 @@
485 }470 }
486471
487 callback(surf.get(), context);472 callback(surf.get(), context);
473
474 if (spec.width.is_set() && spec.height.is_set() && spec.event_handler.is_set())
475 {
476 mir::geometry::Size requested_size{spec.width.value(), spec.height.value()};
477 mir::geometry::Size actual_size{(*surface_proto).width(), (*surface_proto).height()};
478 auto event_handler = spec.event_handler.value();
479 if (requested_size != actual_size)
480 {
481 auto event = mir::events::make_event(mir::frontend::SurfaceId{(*surface_proto).id().value()}, actual_size);
482 lock.unlock();
483 event_handler.callback(surf.get(), event.get(), event_handler.context);
484 lock.lock();
485 }
486 }
487
488 request->wh->result_received();488 request->wh->result_received();
489
490 send_resize_event_if_needed(surf.get(), spec, *surface_proto);
491 surface_requests.erase(request_it);489 surface_requests.erase(request_it);
492}490}
493491

Subscribers

People subscribed via source and target branches