Mir

Merge lp:~andreas-pokorny/mir/nbs-resize-first-stream-of-surface into lp:mir

Proposed by Andreas Pokorny
Status: Rejected
Rejected by: Andreas Pokorny
Proposed branch: lp:~andreas-pokorny/mir/nbs-resize-first-stream-of-surface
Merge into: lp:mir
Prerequisite: lp:~andreas-pokorny/mir/avoid-static-library-ordering-problems
Diff against target: 277 lines (+98/-7)
9 files modified
src/client/connection_surface_map.h (+1/-0)
src/client/mir_connection.cpp (+10/-0)
src/client/mir_connection.h (+1/-0)
src/client/mir_surface.cpp (+12/-0)
src/client/mir_surface.h (+2/-1)
src/client/surface_map.cpp (+14/-0)
src/client/surface_map.h (+2/-0)
tests/unit-tests/client/test_client_mir_surface.cpp (+50/-6)
tests/unit-tests/client/test_protobuf_rpc_channel.cpp (+6/-0)
To merge this branch: bzr merge lp:~andreas-pokorny/mir/nbs-resize-first-stream-of-surface
Reviewer Review Type Date Requested Status
Daniel van Vugt Abstain
Alan Griffiths Abstain
Mir CI Bot continuous-integration Approve
Mir development team Pending
Review via email: mp+301277@code.launchpad.net

Commit message

Make NBS behave like OBS - resize the first buffer stream

With OBS mir::scene::BasicSurface would pull out the first stream as the 'default' stream and forward all resizes to that stream. With NBS this is done by the client library. So if no buffer stream is configured via the mir_surface_spec_add_buffer_stream or mir_surface_spec_set_streams API the client side surface will forward the content of resize events to the 'default' stream.

Since we deprecate using mir_surface_get_buffer_stream users are forces to specify the streams or presentation queues they want for display. But streams buffers lack a resize functionality so switching to the new function would not be a viable option.

Description of the change

With presentation chains the client handles resizes by submitting buffers in an adjusted size. With BufferStream there is no way a client can resize an existing stream. With OBS the server made sure that upcoming allocations adapt to the window size. Since the BufferStreams functionality moved to mirclient with NBS, the resize is forwarded to the 'default' BufferStream.

This change makes sure that even when the caller uses mir_surface_spec_set_streams or mir_surface_spec_add_buffer_stream - the 'default' or in other words first stream still gets resized.

To post a comment you must log in.
3616. By Andreas Pokorny

spell out the actual expectation: no exception when attempting to resize a presentation chain

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

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

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

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

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

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

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

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

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

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

I'm not sure enough of the implications to know if this is a good idea. What user visible feature does it effect?

Also "with_potential_stream_do" seems verbose, maybe "if_stream_do"?

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

> I'm not sure enough of the implications to know if this is a good idea. What
> user visible feature does it effect?
>
> Also "with_potential_stream_do" seems verbose, maybe "if_stream_do"?

Created a bug (lp:1608457) for the problem I observerd with gtk+

3617. By Andreas Pokorny

rename new method

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

I think this is fine as a workaround while the definitions are improved in this area.

The physical buffer size is something the client sets, and the onscreen size is something server/shell sets.

The legacy problem has to do with how the sizes (physical and on-screen) were assumed to be the same. The default stream used to just be resized, and now the 1st stream will just be resized.

A function like:
mir_buffer_stream_set_buffers_size() //sets just the physical buffer size.
might be what's needed to make things in the non-legacy world a bit nicer and clearer.

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

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

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

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

*Needs Discussion*

It seems that the client API lacks a mir_buffer_stream_set_size() and adding that would be a better fix than this proposal.

But I'm concerned that clients might want to make an atomic update of size and scale. Is the "correct" approach to create a new buffer stream?

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

> *Needs Discussion*
>
> It seems that the client API lacks a mir_buffer_stream_set_size() and adding
> that would be a better fix than this proposal.
>
> But I'm concerned that clients might want to make an atomic update of size and
> scale. Is the "correct" approach to create a new buffer stream?

Existing behavior with and without mir_surface_spec_set_streams was that the server controls the size of the first buffer stream and does not care about the other. At the moment the server decides based on the --nbuffers=3 vs --nbuffers=0 whether the first buffer stream is resized or not.

The release-create-with-new-size approach led to hang ups and allocation failures - and those are fixed here:
lp:~andreas-pokorny/mir/fix-buffer-release-requests-after-buffer-stream-destruction

The recreate approach has the advantage that it is immediately clear that the first buffer you get from the buffer stream will have the right size. Additionally the screen update would be tied to the necessary mir_surface_apply_spec call. While with the _set_size approach there are arguments to have it happen instantly or only after the next buffer swap..

But a current implementation detail makes the recreate approach a bit more resource intense since on creation three buffers are allocated. With a sequence of resize events two thirds of all created buffers are just allocated and freed without use. I assume that problem can be solved through an implementation change in mirclient.

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

Do we need to hold 0.23.5 for this?

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

> I think this is fine as a workaround while the definitions are improved in
> this area.
>
> The physical buffer size is something the client sets, and the onscreen size
> is something server/shell sets.
>
> The legacy problem has to do with how the sizes (physical and on-screen) were
> assumed to be the same. The default stream used to just be resized, and now
> the 1st stream will just be resized.
>
> A function like:
> mir_buffer_stream_set_buffers_size() //sets just the physical buffer size.
> might be what's needed to make things in the non-legacy world a bit nicer and
> clearer.

What is the unit of the physical size? Is this related to the existing mir_buffer_stream_set_scale?

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

> Do we need to hold 0.23.5 for this?

We discussed that yesterday. The combination in which resize does not happen is not used by qt, gtk or sdl. So no need to hold 0.23.5 for now.

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

Sorry, I don't remember having that discussion. Only asking a few times. Maybe I didn't understand the answer.

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

The current special treatment of the first buffer seems inconsistent. So, as it is unused in practice, I'd rather not add this code to replicate it.

> The recreate approach has the advantage that it is immediately clear that the
> first buffer you get from the buffer stream will have the right size.
> Additionally the screen update would be tied to the necessary
> mir_surface_apply_spec call. While with the _set_size approach there are
> arguments to have it happen instantly or only after the next buffer swap..
>
> But a current implementation detail makes the recreate approach a bit more
> resource intense since on creation three buffers are allocated. With a
> sequence of resize events two thirds of all created buffers are just allocated
> and freed without use. I assume that problem can be solved through an
> implementation change in mirclient.

My *preference* would be to make the recreate approach (1) work and (2) work efficiently.

But I don't feel strongly about it today.

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

> The current special treatment of the first buffer seems inconsistent. So, as
> it is unused in practice, I'd rather not add this code to replicate it.

Right, it is inconsistent, but it is used, iirc. The surface that gets resized by the server has to respond by resizing the 'default' buffer stream. It seemed better to just keep the auto-resizing around for the 'default/legacy' case, instead saying that the first stream gets resized to the size of the surface (as it is in this MP).

Auto-resizing the 1st stream, as opposed to the only a 'legacy' stream, makes it a bit harder to arrange a scene. Like, if I wanted a 200x200 surface with 4 100x100 windows, and then the server resizes the surface to 500x500, the 1st stream would fill the space after the resize message. The current design is a bit broken for other reasons (no atomic scene arrangements), but I think this might complicate the matter (esp if we're going to use 'tips' for this intented purpose).

This region is due for a bit of cleanup with the atomic updates topic that's coming around soon, maybe we WIP the branch until then, and then roll it into a larger fix to make the scene arrangement and sizes more consistent?

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

> > The current special treatment of the first buffer seems inconsistent. So, as
> > it is unused in practice, I'd rather not add this code to replicate it.
>
> Right, it is inconsistent, but it is used, iirc. The surface that gets resized
> by the server has to respond by resizing the 'default' buffer stream. It
> seemed better to just keep the auto-resizing around for the 'default/legacy'
> case, instead saying that the first stream gets resized to the size of the
> surface (as it is in this MP).
>
> Auto-resizing the 1st stream, as opposed to the only a 'legacy' stream, makes
> it a bit harder to arrange a scene. Like, if I wanted a 200x200 surface with 4
> 100x100 windows, and then the server resizes the surface to 500x500, the 1st
> stream would fill the space after the resize message. The current design is a
> bit broken for other reasons (no atomic scene arrangements), but I think this
> might complicate the matter (esp if we're going to use 'tips' for this
> intented purpose).
>
> This region is due for a bit of cleanup with the atomic updates topic that's
> coming around soon, maybe we WIP the branch until then, and then roll it into
> a larger fix to make the scene arrangement and sizes more consistent?

The reason why I proposed this is because we resized the first stream when old buffer semantics were used. But not without another "but". It only did so for the initial configuration - if the users switches to different "first" stream with another spec update it stopped working

We have so many wrong behaviors that I wasnt sure what to expect when changing gtk+.

I also do not like the auto resizing.. So I guess we should focus on making client driven resizes nicer then.

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

I don't want to be a blocker here. I didn't realize mir_surface_get_buffer_stream was getting deprecated.

All toolkits want is a:
   mir_surface_swap_buffers(s);
which they currently have to do via:
   mir_buffer_stream_swap_buffers_sync(mir_surface_get_buffer_stream(s));

It's already annoying enough. I don't endorse us making it worse. But that's not the fault of this branch.

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

Rejecting - the fact that OBS with set_streams would resize buffer stream is fishy for the more interesting use cases.

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

*would resize the first buffer stream*

Unmerged revisions

3617. By Andreas Pokorny

rename new method

3616. By Andreas Pokorny

spell out the actual expectation: no exception when attempting to resize a presentation chain

3615. By Andreas Pokorny

Tests and additional changes to handle the PresentationChain case

3614. By Andreas Pokorny

Make NBS behave like OBS - resize the first buffer stream

With OBS mir::scene::BasicSurface would pull out the first stream as the 'default' stream and forward all resizes to that stream. With NBS this is done by the client library. So if no buffer stream is configured via the mir_surface_spec_add_buffer_stream or mir_surface_spec_set_streams API the client side surface will forward the content of resize events to the 'default' stream.

Since we deprecate using mir_surface_get_buffer_stream users are forces to specify the streams or presentation queues they want for display. But streams buffers lack a resize functionality so switching to the new function would not be a viable option.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'src/client/connection_surface_map.h'
--- src/client/connection_surface_map.h 2016-06-06 11:51:31 +0000
+++ src/client/connection_surface_map.h 2016-08-01 12:51:16 +0000
@@ -39,6 +39,7 @@
39 void erase(frontend::SurfaceId surface_id);39 void erase(frontend::SurfaceId surface_id);
4040
41 void with_stream_do(frontend::BufferStreamId stream_id, std::function<void(ClientBufferStream*)> const& exec) const override;41 void with_stream_do(frontend::BufferStreamId stream_id, std::function<void(ClientBufferStream*)> const& exec) const override;
42 void if_stream_do(frontend::BufferStreamId stream_id, std::function<void(ClientBufferStream*)> const& exec) const override;
42 void with_all_streams_do(std::function<void(ClientBufferStream*)> const&) const override;43 void with_all_streams_do(std::function<void(ClientBufferStream*)> const&) const override;
4344
44 void insert(frontend::BufferStreamId stream_id, std::shared_ptr<ClientBufferStream> const& chain);45 void insert(frontend::BufferStreamId stream_id, std::shared_ptr<ClientBufferStream> const& chain);
4546
=== modified file 'src/client/mir_connection.cpp'
--- src/client/mir_connection.cpp 2016-06-28 12:18:18 +0000
+++ src/client/mir_connection.cpp 2016-08-01 12:51:16 +0000
@@ -1252,3 +1252,13 @@
1252 released_buffer->set_buffer_id(buffer->rpc_id());1252 released_buffer->set_buffer_id(buffer->rpc_id());
1253 server.release_buffers(&request, ignored.get(), gp::NewCallback(ignore));1253 server.release_buffers(&request, ignored.get(), gp::NewCallback(ignore));
1254}1254}
1255
1256void MirConnection::resize_stream(mir::frontend::BufferStreamId const id, mir::geometry::Size const& size) const
1257{
1258 surface_map->if_stream_do(
1259 id,
1260 [size](mcl::ClientBufferStream* stream)
1261 {
1262 stream->set_size(size);
1263 });
1264}
12551265
=== modified file 'src/client/mir_connection.h'
--- src/client/mir_connection.h 2016-06-28 12:18:18 +0000
+++ src/client/mir_connection.h 2016-08-01 12:51:16 +0000
@@ -199,6 +199,7 @@
199 mir::geometry::Size size, MirPixelFormat format, MirBufferUsage usage,199 mir::geometry::Size size, MirPixelFormat format, MirBufferUsage usage,
200 mir_buffer_callback callback, void* context);200 mir_buffer_callback callback, void* context);
201 void release_buffer(mir::client::MirBuffer* buffer);201 void release_buffer(mir::client::MirBuffer* buffer);
202 void resize_stream(mir::frontend::BufferStreamId const id, mir::geometry::Size const& size) const;
202203
203private:204private:
204 //google cant have callbacks with more than 2 args205 //google cant have callbacks with more than 2 args
205206
=== modified file 'src/client/mir_surface.cpp'
--- src/client/mir_surface.cpp 2016-06-24 07:41:32 +0000
+++ src/client/mir_surface.cpp 2016-08-01 12:51:16 +0000
@@ -45,6 +45,7 @@
45namespace mp = mir::protobuf;45namespace mp = mir::protobuf;
46namespace gp = google::protobuf;46namespace gp = google::protobuf;
47namespace md = mir::dispatch;47namespace md = mir::dispatch;
48namespace mf = mir::frontend;
4849
49namespace50namespace
50{51{
@@ -153,6 +154,13 @@
153 input_platform->create_input_receiver( surface_proto.fd(0), keymapper, handle_event_callback));154 input_platform->create_input_receiver( surface_proto.fd(0), keymapper, handle_event_callback));
154 }155 }
155156
157 if (spec.streams.is_set() && spec.streams.value().size() >= 1)
158 {
159 auto first_stream = spec.streams.value().front();
160 window_stream_id = mf::BufferStreamId{first_stream.stream_id};
161 }
162
163
156 std::lock_guard<decltype(handle_mutex)> lock(handle_mutex);164 std::lock_guard<decltype(handle_mutex)> lock(handle_mutex);
157 valid_surfaces.insert(this);165 valid_surfaces.insert(this);
158}166}
@@ -456,6 +464,8 @@
456 size = { mir_resize_event_get_width(resize_event), mir_resize_event_get_height(resize_event) };464 size = { mir_resize_event_get_width(resize_event), mir_resize_event_get_height(resize_event) };
457 if (default_stream)465 if (default_stream)
458 default_stream->set_size(size);466 default_stream->set_size(size);
467 else if (window_stream_id.is_set())
468 connection()->resize_stream(window_stream_id.value(), size);
459 break;469 break;
460 }470 }
461 default:471 default:
@@ -604,6 +614,8 @@
604 if (spec.streams.is_set())614 if (spec.streams.is_set())
605 {615 {
606 default_stream = nullptr;616 default_stream = nullptr;
617 if (spec.streams.value().size() >= 1)
618 window_stream_id = mf::BufferStreamId{spec.streams.value().front().stream_id};
607 for(auto const& stream : spec.streams.value())619 for(auto const& stream : spec.streams.value())
608 {620 {
609 auto const new_stream = surface_specification->add_stream();621 auto const new_stream = surface_specification->add_stream();
610622
=== modified file 'src/client/mir_surface.h'
--- src/client/mir_surface.h 2016-06-09 00:38:26 +0000
+++ src/client/mir_surface.h 2016-08-01 12:51:16 +0000
@@ -26,6 +26,7 @@
2626
27#include "mir/client_platform.h"27#include "mir/client_platform.h"
28#include "mir/frontend/surface_id.h"28#include "mir/frontend/surface_id.h"
29#include "mir/frontend/buffer_stream_id.h"
29#include "mir/optional_value.h"30#include "mir/optional_value.h"
30#include "mir/geometry/dimensions.h"31#include "mir/geometry/dimensions.h"
31#include "mir/geometry/displacement.h"32#include "mir/geometry/displacement.h"
@@ -249,7 +250,7 @@
249 MirPixelFormat format;250 MirPixelFormat format;
250 MirBufferUsage usage;251 MirBufferUsage usage;
251 uint32_t output_id;252 uint32_t output_id;
252253 mir::optional_value<mir::frontend::BufferStreamId> window_stream_id;
253};254};
254255
255#endif /* MIR_CLIENT_PRIVATE_MIR_WAIT_HANDLE_H_ */256#endif /* MIR_CLIENT_PRIVATE_MIR_WAIT_HANDLE_H_ */
256257
=== modified file 'src/client/surface_map.cpp'
--- src/client/surface_map.cpp 2016-06-06 11:51:31 +0000
+++ src/client/surface_map.cpp 2016-08-01 12:51:16 +0000
@@ -76,6 +76,20 @@
76 }76 }
77}77}
7878
79void mcl::ConnectionSurfaceMap::if_stream_do(
80 mf::BufferStreamId stream_id, std::function<void(ClientBufferStream*)> const& exec) const
81{
82 std::shared_lock<decltype(guard)> lk(guard);
83 auto const it = streams.find(stream_id);
84 if (it != streams.end())
85 {
86 auto const stream = it->second;
87 lk.unlock();
88 exec(stream.get());
89 }
90}
91
92
79void mcl::ConnectionSurfaceMap::with_all_streams_do(std::function<void(ClientBufferStream*)> const& fn) const93void mcl::ConnectionSurfaceMap::with_all_streams_do(std::function<void(ClientBufferStream*)> const& fn) const
80{94{
81 std::shared_lock<decltype(guard)> lk(guard);95 std::shared_lock<decltype(guard)> lk(guard);
8296
=== modified file 'src/client/surface_map.h'
--- src/client/surface_map.h 2016-06-06 11:51:31 +0000
+++ src/client/surface_map.h 2016-08-01 12:51:16 +0000
@@ -44,6 +44,8 @@
44 frontend::SurfaceId surface_id, std::function<void(MirSurface*)> const& exec) const = 0;44 frontend::SurfaceId surface_id, std::function<void(MirSurface*)> const& exec) const = 0;
45 virtual void with_stream_do(45 virtual void with_stream_do(
46 frontend::BufferStreamId stream_id, std::function<void(ClientBufferStream*)> const& exec) const = 0;46 frontend::BufferStreamId stream_id, std::function<void(ClientBufferStream*)> const& exec) const = 0;
47 virtual void if_stream_do(
48 frontend::BufferStreamId stream_id, std::function<void(ClientBufferStream*)> const& exec) const = 0;
47 virtual void with_all_streams_do(std::function<void(ClientBufferStream*)> const&) const = 0;49 virtual void with_all_streams_do(std::function<void(ClientBufferStream*)> const&) const = 0;
48 virtual std::shared_ptr<MirBuffer> buffer(int buffer_id) const = 0;50 virtual std::shared_ptr<MirBuffer> buffer(int buffer_id) const = 0;
49 virtual void insert(int buffer_id, std::shared_ptr<MirBuffer> const& buffer) = 0;51 virtual void insert(int buffer_id, std::shared_ptr<MirBuffer> const& buffer) = 0;
5052
=== modified file 'tests/unit-tests/client/test_client_mir_surface.cpp'
--- tests/unit-tests/client/test_client_mir_surface.cpp 2016-06-08 12:30:14 +0000
+++ tests/unit-tests/client/test_client_mir_surface.cpp 2016-08-01 12:51:16 +0000
@@ -27,6 +27,7 @@
27#include "mir/client_platform.h"27#include "mir/client_platform.h"
28#include "mir/client_platform_factory.h"28#include "mir/client_platform_factory.h"
29#include "src/client/mir_surface.h"29#include "src/client/mir_surface.h"
30#include "src/client/mir_presentation_chain.h"
30#include "src/client/mir_connection.h"31#include "src/client/mir_connection.h"
31#include "src/client/default_connection_configuration.h"32#include "src/client/default_connection_configuration.h"
32#include "src/client/rpc/null_rpc_report.h"33#include "src/client/rpc/null_rpc_report.h"
@@ -73,6 +74,16 @@
73namespace74namespace
74{75{
7576
77struct StubPresentationChain : MirPresentationChain
78{
79 int id;
80 StubPresentationChain(int id) : id{id} {}
81 void submit_buffer(mir::client::MirBuffer*) override {}
82 MirConnection* connection() const override {return nullptr;}
83 int rpc_id() const override {return id;}
84 char const* error_msg() const override {return nullptr;}
85};
86
76struct MockServerPackageGenerator : public mt::StubServerTool87struct MockServerPackageGenerator : public mt::StubServerTool
77{88{
78 MockServerPackageGenerator()89 MockServerPackageGenerator()
@@ -503,8 +514,12 @@
503TEST_F(MirClientSurfaceTest, resizes_streams_and_calls_callback_if_no_customized_streams)514TEST_F(MirClientSurfaceTest, resizes_streams_and_calls_callback_if_no_customized_streams)
504{515{
505 using namespace testing;516 using namespace testing;
506 auto mock_stream = std::make_shared<mtd::MockClientBufferStream>(); 517 auto const stream_id = mir::frontend::BufferStreamId(2);
518 auto mock_stream = std::make_shared<mtd::MockClientBufferStream>();
507 auto mock_input_platform = std::make_shared<NiceMock<MockClientInputPlatform>>();519 auto mock_input_platform = std::make_shared<NiceMock<MockClientInputPlatform>>();
520
521 surface_map->insert(stream_id, mock_stream);
522
508 ON_CALL(*mock_input_platform, create_input_receiver(_,_,_))523 ON_CALL(*mock_input_platform, create_input_receiver(_,_,_))
509 .WillByDefault(Return(std::make_shared<mt::TestDispatchable>([]{})));524 .WillByDefault(Return(std::make_shared<mt::TestDispatchable>([]{})));
510 ON_CALL(*mock_stream, rpc_id()).WillByDefault(Return(mir::frontend::BufferStreamId(2)));525 ON_CALL(*mock_stream, rpc_id()).WillByDefault(Return(mir::frontend::BufferStreamId(2)));
@@ -516,31 +531,60 @@
516 MirSurface surface{connection.get(), *client_comm_channel, nullptr,531 MirSurface surface{connection.get(), *client_comm_channel, nullptr,
517 mock_stream, mock_input_platform, spec, surface_proto, wh};532 mock_stream, mock_input_platform, spec, surface_proto, wh};
518 surface.handle_event(*ev);533 surface.handle_event(*ev);
519 surface_map->erase(mir::frontend::BufferStreamId(2));534 surface_map->erase(stream_id);
520}535}
521536
522TEST_F(MirClientSurfaceTest, resizes_streams_and_calls_callback_if_customized_streams)537TEST_F(MirClientSurfaceTest, resizes_streams_and_calls_callback_if_customized_streams)
523{538{
524 using namespace testing;539 using namespace testing;
540 auto const stream_id = mir::frontend::BufferStreamId(2);
525 auto mock_stream = std::make_shared<NiceMock<mtd::MockClientBufferStream>>();541 auto mock_stream = std::make_shared<NiceMock<mtd::MockClientBufferStream>>();
526 auto mock_input_platform = std::make_shared<NiceMock<MockClientInputPlatform>>();542 auto mock_input_platform = std::make_shared<NiceMock<MockClientInputPlatform>>();
527 ON_CALL(*mock_stream, rpc_id()).WillByDefault(Return(mir::frontend::BufferStreamId(2)));543
544 surface_map->insert(stream_id, mock_stream);
545
546 ON_CALL(*mock_stream, rpc_id()).WillByDefault(Return(stream_id));
528 ON_CALL(*mock_input_platform, create_input_receiver(_,_,_))547 ON_CALL(*mock_input_platform, create_input_receiver(_,_,_))
529 .WillByDefault(Return(std::make_shared<mt::TestDispatchable>([]{})));548 .WillByDefault(Return(std::make_shared<mt::TestDispatchable>([]{})));
530549
531 geom::Size size(120, 124);550 geom::Size size(120, 124);
532 EXPECT_CALL(*mock_stream, set_size(size)).Times(0);551 EXPECT_CALL(*mock_stream, set_size(size)).Times(1);
533 auto ev = mir::events::make_event(mir::frontend::SurfaceId(2), size);552 auto ev = mir::events::make_event(mir::frontend::SurfaceId(2), size);
534 MirSurface surface{connection.get(), *client_comm_channel, nullptr,553 MirSurface surface{connection.get(), *client_comm_channel, nullptr,
535 mock_stream, mock_input_platform, spec, surface_proto, wh};554 mock_stream, mock_input_platform, spec, surface_proto, wh};
536555
537 MirSurfaceSpec spec;556 MirSurfaceSpec spec;
538 std::vector<ContentInfo> info =557 std::vector<ContentInfo> info =
539 { ContentInfo{ geom::Displacement{0,0}, 2, geom::Size{1,1}} };558 { ContentInfo{ geom::Displacement{0,0}, stream_id.as_value(), geom::Size{1,1}} };
540 spec.streams = info;559 spec.streams = info;
541 surface.modify(spec)->wait_for_all();560 surface.modify(spec)->wait_for_all();
542 surface.handle_event(*ev);561 surface.handle_event(*ev);
543 surface_map->erase(mir::frontend::BufferStreamId(2));562 surface_map->erase(stream_id);
563}
564
565TEST_F(MirClientSurfaceTest, do_not_resize_presentation_chain)
566{
567 using namespace testing;
568 auto const stream_id = mir::frontend::BufferStreamId(17);
569 auto stub_chain = std::make_shared<StubPresentationChain>(stream_id.as_value());
570 auto mock_input_platform = std::make_shared<NiceMock<MockClientInputPlatform>>();
571
572 surface_map->insert(stream_id, stub_chain);
573
574 ON_CALL(*mock_input_platform, create_input_receiver(_,_,_))
575 .WillByDefault(Return(std::make_shared<mt::TestDispatchable>([]{})));
576
577 geom::Size size(90, 80);
578 auto ev = mir::events::make_event(mir::frontend::SurfaceId(2), size);
579 MirSurface surface{connection.get(), *client_comm_channel, nullptr,
580 nullptr, mock_input_platform, spec, surface_proto, wh};
581
582 MirSurfaceSpec spec;
583 std::vector<ContentInfo> info =
584 { ContentInfo{ geom::Displacement{0,0}, stream_id.as_value(), geom::Size{1,1}} };
585 spec.streams = info;
586 surface.modify(spec)->wait_for_all();
587 EXPECT_NO_THROW(surface.handle_event(*ev););
544}588}
545589
546TEST_F(MirClientSurfaceTest, parameters_are_unhooked_from_stream_sizes)590TEST_F(MirClientSurfaceTest, parameters_are_unhooked_from_stream_sizes)
547591
=== modified file 'tests/unit-tests/client/test_protobuf_rpc_channel.cpp'
--- tests/unit-tests/client/test_protobuf_rpc_channel.cpp 2016-06-24 17:52:00 +0000
+++ tests/unit-tests/client/test_protobuf_rpc_channel.cpp 2016-08-01 12:51:16 +0000
@@ -63,6 +63,8 @@
63 void(mir::frontend::SurfaceId, std::function<void(MirSurface*)> const&));63 void(mir::frontend::SurfaceId, std::function<void(MirSurface*)> const&));
64 MOCK_CONST_METHOD2(with_stream_do,64 MOCK_CONST_METHOD2(with_stream_do,
65 void(mir::frontend::BufferStreamId, std::function<void(mcl::ClientBufferStream*)> const&));65 void(mir::frontend::BufferStreamId, std::function<void(mcl::ClientBufferStream*)> const&));
66 MOCK_CONST_METHOD2(if_stream_do,
67 void(mir::frontend::BufferStreamId, std::function<void(mcl::ClientBufferStream*)> const&));
66 MOCK_CONST_METHOD1(with_all_streams_do,68 MOCK_CONST_METHOD1(with_all_streams_do,
67 void(std::function<void(mcl::ClientBufferStream*)> const&));69 void(std::function<void(mcl::ClientBufferStream*)> const&));
68 MOCK_CONST_METHOD1(buffer, std::shared_ptr<mcl::MirBuffer>(int));70 MOCK_CONST_METHOD1(buffer, std::shared_ptr<mcl::MirBuffer>(int));
@@ -82,6 +84,10 @@
82 mir::frontend::BufferStreamId, std::function<void(mcl::ClientBufferStream*)> const&) const override84 mir::frontend::BufferStreamId, std::function<void(mcl::ClientBufferStream*)> const&) const override
83 {85 {
84 }86 }
87 void if_stream_do(mir::frontend::BufferStreamId,
88 std::function<void(mcl::ClientBufferStream*)> const&) const override
89 {
90 }
85 void with_all_streams_do(std::function<void(mcl::ClientBufferStream*)> const&) const override91 void with_all_streams_do(std::function<void(mcl::ClientBufferStream*)> const&) const override
86 {92 {
87 }93 }

Subscribers

People subscribed via source and target branches