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
1=== modified file 'src/client/connection_surface_map.h'
2--- src/client/connection_surface_map.h 2016-06-06 11:51:31 +0000
3+++ src/client/connection_surface_map.h 2016-08-01 12:51:16 +0000
4@@ -39,6 +39,7 @@
5 void erase(frontend::SurfaceId surface_id);
6
7 void with_stream_do(frontend::BufferStreamId stream_id, std::function<void(ClientBufferStream*)> const& exec) const override;
8+ void if_stream_do(frontend::BufferStreamId stream_id, std::function<void(ClientBufferStream*)> const& exec) const override;
9 void with_all_streams_do(std::function<void(ClientBufferStream*)> const&) const override;
10
11 void insert(frontend::BufferStreamId stream_id, std::shared_ptr<ClientBufferStream> const& chain);
12
13=== modified file 'src/client/mir_connection.cpp'
14--- src/client/mir_connection.cpp 2016-06-28 12:18:18 +0000
15+++ src/client/mir_connection.cpp 2016-08-01 12:51:16 +0000
16@@ -1252,3 +1252,13 @@
17 released_buffer->set_buffer_id(buffer->rpc_id());
18 server.release_buffers(&request, ignored.get(), gp::NewCallback(ignore));
19 }
20+
21+void MirConnection::resize_stream(mir::frontend::BufferStreamId const id, mir::geometry::Size const& size) const
22+{
23+ surface_map->if_stream_do(
24+ id,
25+ [size](mcl::ClientBufferStream* stream)
26+ {
27+ stream->set_size(size);
28+ });
29+}
30
31=== modified file 'src/client/mir_connection.h'
32--- src/client/mir_connection.h 2016-06-28 12:18:18 +0000
33+++ src/client/mir_connection.h 2016-08-01 12:51:16 +0000
34@@ -199,6 +199,7 @@
35 mir::geometry::Size size, MirPixelFormat format, MirBufferUsage usage,
36 mir_buffer_callback callback, void* context);
37 void release_buffer(mir::client::MirBuffer* buffer);
38+ void resize_stream(mir::frontend::BufferStreamId const id, mir::geometry::Size const& size) const;
39
40 private:
41 //google cant have callbacks with more than 2 args
42
43=== modified file 'src/client/mir_surface.cpp'
44--- src/client/mir_surface.cpp 2016-06-24 07:41:32 +0000
45+++ src/client/mir_surface.cpp 2016-08-01 12:51:16 +0000
46@@ -45,6 +45,7 @@
47 namespace mp = mir::protobuf;
48 namespace gp = google::protobuf;
49 namespace md = mir::dispatch;
50+namespace mf = mir::frontend;
51
52 namespace
53 {
54@@ -153,6 +154,13 @@
55 input_platform->create_input_receiver( surface_proto.fd(0), keymapper, handle_event_callback));
56 }
57
58+ if (spec.streams.is_set() && spec.streams.value().size() >= 1)
59+ {
60+ auto first_stream = spec.streams.value().front();
61+ window_stream_id = mf::BufferStreamId{first_stream.stream_id};
62+ }
63+
64+
65 std::lock_guard<decltype(handle_mutex)> lock(handle_mutex);
66 valid_surfaces.insert(this);
67 }
68@@ -456,6 +464,8 @@
69 size = { mir_resize_event_get_width(resize_event), mir_resize_event_get_height(resize_event) };
70 if (default_stream)
71 default_stream->set_size(size);
72+ else if (window_stream_id.is_set())
73+ connection()->resize_stream(window_stream_id.value(), size);
74 break;
75 }
76 default:
77@@ -604,6 +614,8 @@
78 if (spec.streams.is_set())
79 {
80 default_stream = nullptr;
81+ if (spec.streams.value().size() >= 1)
82+ window_stream_id = mf::BufferStreamId{spec.streams.value().front().stream_id};
83 for(auto const& stream : spec.streams.value())
84 {
85 auto const new_stream = surface_specification->add_stream();
86
87=== modified file 'src/client/mir_surface.h'
88--- src/client/mir_surface.h 2016-06-09 00:38:26 +0000
89+++ src/client/mir_surface.h 2016-08-01 12:51:16 +0000
90@@ -26,6 +26,7 @@
91
92 #include "mir/client_platform.h"
93 #include "mir/frontend/surface_id.h"
94+#include "mir/frontend/buffer_stream_id.h"
95 #include "mir/optional_value.h"
96 #include "mir/geometry/dimensions.h"
97 #include "mir/geometry/displacement.h"
98@@ -249,7 +250,7 @@
99 MirPixelFormat format;
100 MirBufferUsage usage;
101 uint32_t output_id;
102-
103+ mir::optional_value<mir::frontend::BufferStreamId> window_stream_id;
104 };
105
106 #endif /* MIR_CLIENT_PRIVATE_MIR_WAIT_HANDLE_H_ */
107
108=== modified file 'src/client/surface_map.cpp'
109--- src/client/surface_map.cpp 2016-06-06 11:51:31 +0000
110+++ src/client/surface_map.cpp 2016-08-01 12:51:16 +0000
111@@ -76,6 +76,20 @@
112 }
113 }
114
115+void mcl::ConnectionSurfaceMap::if_stream_do(
116+ mf::BufferStreamId stream_id, std::function<void(ClientBufferStream*)> const& exec) const
117+{
118+ std::shared_lock<decltype(guard)> lk(guard);
119+ auto const it = streams.find(stream_id);
120+ if (it != streams.end())
121+ {
122+ auto const stream = it->second;
123+ lk.unlock();
124+ exec(stream.get());
125+ }
126+}
127+
128+
129 void mcl::ConnectionSurfaceMap::with_all_streams_do(std::function<void(ClientBufferStream*)> const& fn) const
130 {
131 std::shared_lock<decltype(guard)> lk(guard);
132
133=== modified file 'src/client/surface_map.h'
134--- src/client/surface_map.h 2016-06-06 11:51:31 +0000
135+++ src/client/surface_map.h 2016-08-01 12:51:16 +0000
136@@ -44,6 +44,8 @@
137 frontend::SurfaceId surface_id, std::function<void(MirSurface*)> const& exec) const = 0;
138 virtual void with_stream_do(
139 frontend::BufferStreamId stream_id, std::function<void(ClientBufferStream*)> const& exec) const = 0;
140+ virtual void if_stream_do(
141+ frontend::BufferStreamId stream_id, std::function<void(ClientBufferStream*)> const& exec) const = 0;
142 virtual void with_all_streams_do(std::function<void(ClientBufferStream*)> const&) const = 0;
143 virtual std::shared_ptr<MirBuffer> buffer(int buffer_id) const = 0;
144 virtual void insert(int buffer_id, std::shared_ptr<MirBuffer> const& buffer) = 0;
145
146=== modified file 'tests/unit-tests/client/test_client_mir_surface.cpp'
147--- tests/unit-tests/client/test_client_mir_surface.cpp 2016-06-08 12:30:14 +0000
148+++ tests/unit-tests/client/test_client_mir_surface.cpp 2016-08-01 12:51:16 +0000
149@@ -27,6 +27,7 @@
150 #include "mir/client_platform.h"
151 #include "mir/client_platform_factory.h"
152 #include "src/client/mir_surface.h"
153+#include "src/client/mir_presentation_chain.h"
154 #include "src/client/mir_connection.h"
155 #include "src/client/default_connection_configuration.h"
156 #include "src/client/rpc/null_rpc_report.h"
157@@ -73,6 +74,16 @@
158 namespace
159 {
160
161+struct StubPresentationChain : MirPresentationChain
162+{
163+ int id;
164+ StubPresentationChain(int id) : id{id} {}
165+ void submit_buffer(mir::client::MirBuffer*) override {}
166+ MirConnection* connection() const override {return nullptr;}
167+ int rpc_id() const override {return id;}
168+ char const* error_msg() const override {return nullptr;}
169+};
170+
171 struct MockServerPackageGenerator : public mt::StubServerTool
172 {
173 MockServerPackageGenerator()
174@@ -503,8 +514,12 @@
175 TEST_F(MirClientSurfaceTest, resizes_streams_and_calls_callback_if_no_customized_streams)
176 {
177 using namespace testing;
178- auto mock_stream = std::make_shared<mtd::MockClientBufferStream>();
179+ auto const stream_id = mir::frontend::BufferStreamId(2);
180+ auto mock_stream = std::make_shared<mtd::MockClientBufferStream>();
181 auto mock_input_platform = std::make_shared<NiceMock<MockClientInputPlatform>>();
182+
183+ surface_map->insert(stream_id, mock_stream);
184+
185 ON_CALL(*mock_input_platform, create_input_receiver(_,_,_))
186 .WillByDefault(Return(std::make_shared<mt::TestDispatchable>([]{})));
187 ON_CALL(*mock_stream, rpc_id()).WillByDefault(Return(mir::frontend::BufferStreamId(2)));
188@@ -516,31 +531,60 @@
189 MirSurface surface{connection.get(), *client_comm_channel, nullptr,
190 mock_stream, mock_input_platform, spec, surface_proto, wh};
191 surface.handle_event(*ev);
192- surface_map->erase(mir::frontend::BufferStreamId(2));
193+ surface_map->erase(stream_id);
194 }
195
196 TEST_F(MirClientSurfaceTest, resizes_streams_and_calls_callback_if_customized_streams)
197 {
198 using namespace testing;
199+ auto const stream_id = mir::frontend::BufferStreamId(2);
200 auto mock_stream = std::make_shared<NiceMock<mtd::MockClientBufferStream>>();
201 auto mock_input_platform = std::make_shared<NiceMock<MockClientInputPlatform>>();
202- ON_CALL(*mock_stream, rpc_id()).WillByDefault(Return(mir::frontend::BufferStreamId(2)));
203+
204+ surface_map->insert(stream_id, mock_stream);
205+
206+ ON_CALL(*mock_stream, rpc_id()).WillByDefault(Return(stream_id));
207 ON_CALL(*mock_input_platform, create_input_receiver(_,_,_))
208 .WillByDefault(Return(std::make_shared<mt::TestDispatchable>([]{})));
209
210 geom::Size size(120, 124);
211- EXPECT_CALL(*mock_stream, set_size(size)).Times(0);
212+ EXPECT_CALL(*mock_stream, set_size(size)).Times(1);
213 auto ev = mir::events::make_event(mir::frontend::SurfaceId(2), size);
214 MirSurface surface{connection.get(), *client_comm_channel, nullptr,
215 mock_stream, mock_input_platform, spec, surface_proto, wh};
216
217 MirSurfaceSpec spec;
218 std::vector<ContentInfo> info =
219- { ContentInfo{ geom::Displacement{0,0}, 2, geom::Size{1,1}} };
220+ { ContentInfo{ geom::Displacement{0,0}, stream_id.as_value(), geom::Size{1,1}} };
221 spec.streams = info;
222 surface.modify(spec)->wait_for_all();
223 surface.handle_event(*ev);
224- surface_map->erase(mir::frontend::BufferStreamId(2));
225+ surface_map->erase(stream_id);
226+}
227+
228+TEST_F(MirClientSurfaceTest, do_not_resize_presentation_chain)
229+{
230+ using namespace testing;
231+ auto const stream_id = mir::frontend::BufferStreamId(17);
232+ auto stub_chain = std::make_shared<StubPresentationChain>(stream_id.as_value());
233+ auto mock_input_platform = std::make_shared<NiceMock<MockClientInputPlatform>>();
234+
235+ surface_map->insert(stream_id, stub_chain);
236+
237+ ON_CALL(*mock_input_platform, create_input_receiver(_,_,_))
238+ .WillByDefault(Return(std::make_shared<mt::TestDispatchable>([]{})));
239+
240+ geom::Size size(90, 80);
241+ auto ev = mir::events::make_event(mir::frontend::SurfaceId(2), size);
242+ MirSurface surface{connection.get(), *client_comm_channel, nullptr,
243+ nullptr, mock_input_platform, spec, surface_proto, wh};
244+
245+ MirSurfaceSpec spec;
246+ std::vector<ContentInfo> info =
247+ { ContentInfo{ geom::Displacement{0,0}, stream_id.as_value(), geom::Size{1,1}} };
248+ spec.streams = info;
249+ surface.modify(spec)->wait_for_all();
250+ EXPECT_NO_THROW(surface.handle_event(*ev););
251 }
252
253 TEST_F(MirClientSurfaceTest, parameters_are_unhooked_from_stream_sizes)
254
255=== modified file 'tests/unit-tests/client/test_protobuf_rpc_channel.cpp'
256--- tests/unit-tests/client/test_protobuf_rpc_channel.cpp 2016-06-24 17:52:00 +0000
257+++ tests/unit-tests/client/test_protobuf_rpc_channel.cpp 2016-08-01 12:51:16 +0000
258@@ -63,6 +63,8 @@
259 void(mir::frontend::SurfaceId, std::function<void(MirSurface*)> const&));
260 MOCK_CONST_METHOD2(with_stream_do,
261 void(mir::frontend::BufferStreamId, std::function<void(mcl::ClientBufferStream*)> const&));
262+ MOCK_CONST_METHOD2(if_stream_do,
263+ void(mir::frontend::BufferStreamId, std::function<void(mcl::ClientBufferStream*)> const&));
264 MOCK_CONST_METHOD1(with_all_streams_do,
265 void(std::function<void(mcl::ClientBufferStream*)> const&));
266 MOCK_CONST_METHOD1(buffer, std::shared_ptr<mcl::MirBuffer>(int));
267@@ -82,6 +84,10 @@
268 mir::frontend::BufferStreamId, std::function<void(mcl::ClientBufferStream*)> const&) const override
269 {
270 }
271+ void if_stream_do(mir::frontend::BufferStreamId,
272+ std::function<void(mcl::ClientBufferStream*)> const&) const override
273+ {
274+ }
275 void with_all_streams_do(std::function<void(mcl::ClientBufferStream*)> const&) const override
276 {
277 }

Subscribers

People subscribed via source and target branches