Merge lp:~raof/mir/better-buffer-plumbing into lp:mir
- better-buffer-plumbing
- Merge into development-branch
Status: | Superseded |
---|---|
Proposed branch: | lp:~raof/mir/better-buffer-plumbing |
Merge into: | lp:mir |
Diff against target: |
3934 lines (+1094/-1145) 59 files modified
examples/render_surfaces.cpp (+1/-4) examples/server_example_canonical_window_manager.cpp (+5/-3) examples/server_example_canonical_window_manager.h (+7/-1) examples/server_example_window_management.cpp (+6/-1) include/server/mir/frontend/buffer_sink.h (+0/-1) include/server/mir/frontend/client_buffers.h (+0/-46) include/server/mir/frontend/session.h (+0/-6) include/server/mir/scene/buffer_stream_factory.h (+4/-6) include/server/mir/scene/session.h (+0/-6) include/server/mir/shell/window_management_info.h (+5/-1) include/test/mir/test/doubles/stub_session.h (+0/-6) src/client/buffer_vault.cpp (+10/-2) src/client/connection_surface_map.cpp (+1/-1) src/client/mir_connection.cpp (+6/-8) src/client/rpc/mir_protobuf_rpc_channel.cpp (+11/-3) src/server/compositor/CMakeLists.txt (+0/-1) src/server/compositor/buffer_map.cpp (+0/-116) src/server/compositor/buffer_map.h (+0/-65) src/server/compositor/buffer_stream_factory.cpp (+5/-12) src/server/compositor/buffer_stream_factory.h (+4/-5) src/server/compositor/dropping_schedule.cpp (+1/-12) src/server/compositor/dropping_schedule.h (+1/-3) src/server/compositor/multi_monitor_arbiter.cpp (+1/-5) src/server/compositor/multi_monitor_arbiter.h (+0/-2) src/server/compositor/stream.cpp (+7/-25) src/server/compositor/stream.h (+1/-2) src/server/frontend/default_ipc_factory.cpp (+3/-1) src/server/frontend/event_sender.cpp (+0/-8) src/server/frontend/event_sender.h (+0/-1) src/server/frontend/session_mediator.cpp (+127/-32) src/server/frontend/session_mediator.h (+6/-2) src/server/scene/application_session.cpp (+1/-53) src/server/scene/application_session.h (+0/-7) src/server/scene/global_event_sender.cpp (+0/-4) src/server/scene/global_event_sender.h (+0/-1) src/server/shell/window_management_info.cpp (+13/-26) tests/include/mir/test/doubles/mock_event_sink.h (+0/-1) tests/include/mir/test/doubles/null_event_sink.h (+0/-1) tests/include/mir/test/doubles/stub_buffer_stream_factory.h (+9/-30) tests/integration-tests/compositor/test_swapping_swappers.cpp (+1/-2) tests/integration-tests/test_buffer_scheduling.cpp (+25/-14) tests/integration-tests/test_session.cpp (+1/-1) tests/integration-tests/test_submit_buffer.cpp (+146/-108) tests/integration-tests/test_surface_stack_with_compositor.cpp (+2/-5) tests/integration-tests/test_swapinterval.cpp (+3/-8) tests/mir_test_doubles/mock_event_sink_factory.cpp (+0/-6) tests/mir_test_framework/stub_session.cpp (+0/-25) tests/unit-tests/client/test_client_buffer_stream.cpp (+6/-7) tests/unit-tests/client/test_connection_resource_map.cpp (+2/-6) tests/unit-tests/client/test_mir_connection.cpp (+0/-1) tests/unit-tests/client/test_protobuf_rpc_channel.cpp (+24/-0) tests/unit-tests/compositor/CMakeLists.txt (+0/-1) tests/unit-tests/compositor/test_client_buffers.cpp (+0/-119) tests/unit-tests/compositor/test_dropping_schedule.cpp (+6/-45) tests/unit-tests/compositor/test_multi_monitor_arbiter.cpp (+171/-112) tests/unit-tests/compositor/test_stream.cpp (+27/-68) tests/unit-tests/frontend/test_session_mediator.cpp (+437/-82) tests/unit-tests/scene/test_application_session.cpp (+7/-14) tests/unit-tests/scene/test_surface_stack.cpp (+1/-11) |
To merge this branch: | bzr merge lp:~raof/mir/better-buffer-plumbing |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Alan Griffiths | Needs Fixing | ||
Mir CI Bot | continuous-integration | Needs Fixing | |
Brandon Schaefer (community) | Approve | ||
Review via email: mp+326728@code.launchpad.net |
This proposal has been superseded by a proposal from 2017-07-18.
Commit message
Move full responsibility for buffer IPC into the frontend.
Currently buffer IPC is split between the frontend and various things which shared an mf::BufferMap.
This branch consolidates everything so that, outside the SessionMediator, everything is dealing with
a std::shared_
In addition to consolidating IPC into the frontend where it belongs, this makes it easy
to submit client-allocated buffers.
Description of the change
Mir CI Bot (mir-ci-bot) wrote : | # |
Mir CI Bot (mir-ci-bot) wrote : | # |
FAILED: Continuous integration, rev:4211
https:/
Executed test runs:
FAILURE: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
FAILURE: https:/
Click here to trigger a rebuild:
https:/
Mir CI Bot (mir-ci-bot) wrote : | # |
FAILED: Continuous integration, rev:4212
https:/
Executed test runs:
FAILURE: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
FAILURE: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
FAILURE: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
Click here to trigger a rebuild:
https:/
Mir CI Bot (mir-ci-bot) wrote : | # |
PASSED: Continuous integration, rev:4214
https:/
Executed test runs:
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
Click here to trigger a rebuild:
https:/
Brandon Schaefer (brandontschaefer) wrote : | # |
Nice, lgtm. Now we can accept gbm buffers easier then the way it looked before :)
Alan Griffiths (alan-griffiths) wrote : | # |
The name "mir::graphics:
Alan Griffiths (alan-griffiths) wrote : | # |
> The name "mir::graphics:
> "mir::graphics:
/sigh I guess that's pre-existing.
Alan Griffiths (alan-griffiths) wrote : | # |
nits
+ // We can't reasonably answer this question -
+ // Suitability for cursor use is a per-buffer property, not a per-stream property.
return true;
Instead of hard coding this to true wouldn't it be less misleading to remove the calls to this function?
~~~~
Looks like this changes the mirserver ABI - there ought to be removals from the symbols script (e.g. mir::frontend:
But that can be done separately.
Alan Griffiths (alan-griffiths) wrote : | # |
This breaks when starting a load of clients. (I built lp:miral against it and...)
$ cat `which mir_demo_
#!/bin/sh
mir_demo_
$miral-app
[in the miral terminal]
$ mir_demo_client_all
Expect: all the demos clients start
Actual: miral-shell crashes
I don't see this without this MP.
Chris Halse Rogers (raof) wrote : | # |
Interesting. I'll investigate!
Mir CI Bot (mir-ci-bot) wrote : | # |
FAILED: Continuous integration, rev:4215
https:/
Executed test runs:
FAILURE: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
FAILURE: https:/
SUCCESS: https:/
deb: https:/
FAILURE: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
FAILURE: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
Click here to trigger a rebuild:
https:/
Alan Griffiths (alan-griffiths) wrote : | # |
Works much better but...
$ miral-app -launcher mir_demo_
Wait about 30sec and it locks up
Chris Halse Rogers (raof) wrote : | # |
Huh. Artful build failures are due to Artful (specifically, dh_strip_
Urgh. Let's try multistream!
Chris Halse Rogers (raof) wrote : | # |
Ah, good. This also happens with mir_demo_server, which is easier to deal with.
But only multistream? Not the EGL demos, as far as I can tell. Odd.
Alan Griffiths (alan-griffiths) wrote : | # |
Thinking about it - a client setting a bad BufferStreamID shouldn't crash the server. It should simply kill the session.
Chris Halse Rogers (raof) wrote : | # |
Setting a bad BufferStreamID doesn't crash the server. At least, not that alone.
Hah! The hang in mir_demo_
Preview Diff
1 | === modified file 'examples/render_surfaces.cpp' | |||
2 | --- examples/render_surfaces.cpp 2017-05-08 03:04:26 +0000 | |||
3 | +++ examples/render_surfaces.cpp 2017-07-18 03:23:56 +0000 | |||
4 | @@ -34,7 +34,6 @@ | |||
5 | 34 | #include "mir/scene/surface_factory.h" | 34 | #include "mir/scene/surface_factory.h" |
6 | 35 | #include "mir/shell/surface_stack.h" | 35 | #include "mir/shell/surface_stack.h" |
7 | 36 | #include "mir/frontend/buffer_sink.h" | 36 | #include "mir/frontend/buffer_sink.h" |
8 | 37 | #include "mir/frontend/client_buffers.h" | ||
9 | 38 | #include "mir/server.h" | 37 | #include "mir/server.h" |
10 | 39 | #include "mir/report_exception.h" | 38 | #include "mir/report_exception.h" |
11 | 40 | #include "mir/renderer/gl/context.h" | 39 | #include "mir/renderer/gl/context.h" |
12 | @@ -391,13 +390,11 @@ | |||
13 | 391 | { | 390 | { |
14 | 392 | void send_buffer(mf::BufferStreamId, mg::Buffer&, mg::BufferIpcMsgType) override {} | 391 | void send_buffer(mf::BufferStreamId, mg::Buffer&, mg::BufferIpcMsgType) override {} |
15 | 393 | void add_buffer(mg::Buffer&) override {} | 392 | void add_buffer(mg::Buffer&) override {} |
16 | 394 | void remove_buffer(mg::Buffer&) override {} | ||
17 | 395 | void update_buffer(mg::Buffer&) override {} | 393 | void update_buffer(mg::Buffer&) override {} |
18 | 396 | void error_buffer(geom::Size, MirPixelFormat, std::string const&) override {} | 394 | void error_buffer(geom::Size, MirPixelFormat, std::string const&) override {} |
19 | 397 | }; | 395 | }; |
20 | 398 | 396 | ||
23 | 399 | auto buffers = buffer_stream_factory->create_buffer_map(std::make_shared<NullBufferSink>()); | 397 | auto const stream = buffer_stream_factory->create_buffer_stream({}, properties); |
22 | 400 | auto const stream = buffer_stream_factory->create_buffer_stream({}, buffers, properties); | ||
24 | 401 | auto const surface = surface_factory->create_surface( | 398 | auto const surface = surface_factory->create_surface( |
25 | 402 | {ms::StreamInfo{stream, {}, {}}}, params); | 399 | {ms::StreamInfo{stream, {}, {}}}, params); |
26 | 403 | surface_stack->add_surface(surface, params.input_mode); | 400 | surface_stack->add_surface(surface, params.input_mode); |
27 | 404 | 401 | ||
28 | === modified file 'examples/server_example_canonical_window_manager.cpp' | |||
29 | --- examples/server_example_canonical_window_manager.cpp 2017-05-25 04:33:43 +0000 | |||
30 | +++ examples/server_example_canonical_window_manager.cpp 2017-07-18 03:23:56 +0000 | |||
31 | @@ -54,9 +54,11 @@ | |||
32 | 54 | 54 | ||
33 | 55 | me::CanonicalWindowManagerPolicyCopy::CanonicalWindowManagerPolicyCopy( | 55 | me::CanonicalWindowManagerPolicyCopy::CanonicalWindowManagerPolicyCopy( |
34 | 56 | WindowManagerTools* const tools, | 56 | WindowManagerTools* const tools, |
36 | 57 | std::shared_ptr<shell::DisplayLayout> const& display_layout) : | 57 | std::shared_ptr<shell::DisplayLayout> const& display_layout, |
37 | 58 | std::shared_ptr<graphics::GraphicBufferAllocator> const& allocator) : | ||
38 | 58 | tools{tools}, | 59 | tools{tools}, |
40 | 59 | display_layout{display_layout} | 60 | display_layout{display_layout}, |
41 | 61 | allocator{allocator} | ||
42 | 60 | { | 62 | { |
43 | 61 | } | 63 | } |
44 | 62 | 64 | ||
45 | @@ -276,7 +278,7 @@ | |||
46 | 276 | surface_map.emplace(titlebar, SurfaceInfo{session, titlebar, {}}).first->second; | 278 | surface_map.emplace(titlebar, SurfaceInfo{session, titlebar, {}}).first->second; |
47 | 277 | titlebar_info.is_titlebar = true; | 279 | titlebar_info.is_titlebar = true; |
48 | 278 | titlebar_info.parent = surface; | 280 | titlebar_info.parent = surface; |
50 | 279 | titlebar_info.init_titlebar(session, titlebar); | 281 | titlebar_info.init_titlebar(*allocator, titlebar); |
51 | 280 | } | 282 | } |
52 | 281 | 283 | ||
53 | 282 | void me::CanonicalWindowManagerPolicyCopy::handle_new_surface(std::shared_ptr<ms::Session> const& session, std::shared_ptr<ms::Surface> const& surface) | 284 | void me::CanonicalWindowManagerPolicyCopy::handle_new_surface(std::shared_ptr<ms::Session> const& session, std::shared_ptr<ms::Surface> const& surface) |
54 | 283 | 285 | ||
55 | === modified file 'examples/server_example_canonical_window_manager.h' | |||
56 | --- examples/server_example_canonical_window_manager.h 2017-05-08 03:04:26 +0000 | |||
57 | +++ examples/server_example_canonical_window_manager.h 2017-07-18 03:23:56 +0000 | |||
58 | @@ -32,6 +32,10 @@ | |||
59 | 32 | namespace mir | 32 | namespace mir |
60 | 33 | { | 33 | { |
61 | 34 | namespace shell { class DisplayLayout; } | 34 | namespace shell { class DisplayLayout; } |
62 | 35 | namespace graphics | ||
63 | 36 | { | ||
64 | 37 | class GraphicBufferAllocator; | ||
65 | 38 | } | ||
66 | 35 | namespace examples | 39 | namespace examples |
67 | 36 | { | 40 | { |
68 | 37 | // standard window management algorithm: | 41 | // standard window management algorithm: |
69 | @@ -48,7 +52,8 @@ | |||
70 | 48 | 52 | ||
71 | 49 | explicit CanonicalWindowManagerPolicyCopy( | 53 | explicit CanonicalWindowManagerPolicyCopy( |
72 | 50 | WindowManagerTools* const tools, | 54 | WindowManagerTools* const tools, |
74 | 51 | std::shared_ptr<shell::DisplayLayout> const& display_layout); | 55 | std::shared_ptr<shell::DisplayLayout> const& display_layout, |
75 | 56 | std::shared_ptr<graphics::GraphicBufferAllocator> const& allocator); | ||
76 | 52 | 57 | ||
77 | 53 | void click(geometry::Point cursor); | 58 | void click(geometry::Point cursor); |
78 | 54 | 59 | ||
79 | @@ -118,6 +123,7 @@ | |||
80 | 118 | 123 | ||
81 | 119 | WindowManagerTools* const tools; | 124 | WindowManagerTools* const tools; |
82 | 120 | std::shared_ptr<shell::DisplayLayout> const display_layout; | 125 | std::shared_ptr<shell::DisplayLayout> const display_layout; |
83 | 126 | std::shared_ptr<graphics::GraphicBufferAllocator> const allocator; | ||
84 | 121 | 127 | ||
85 | 122 | geometry::Rectangle display_area; | 128 | geometry::Rectangle display_area; |
86 | 123 | geometry::Point old_cursor{}; | 129 | geometry::Point old_cursor{}; |
87 | 124 | 130 | ||
88 | === modified file 'examples/server_example_window_management.cpp' | |||
89 | --- examples/server_example_window_management.cpp 2017-05-08 03:04:26 +0000 | |||
90 | +++ examples/server_example_window_management.cpp 2017-07-18 03:23:56 +0000 | |||
91 | @@ -28,6 +28,8 @@ | |||
92 | 28 | #include "mir/scene/surface_creation_parameters.h" | 28 | #include "mir/scene/surface_creation_parameters.h" |
93 | 29 | #include "mir/shell/display_layout.h" | 29 | #include "mir/shell/display_layout.h" |
94 | 30 | #include "mir/shell/system_compositor_window_manager.h" | 30 | #include "mir/shell/system_compositor_window_manager.h" |
95 | 31 | #include "mir/graphics/platform.h" | ||
96 | 32 | #include "mir/graphics/graphic_buffer_allocator.h" | ||
97 | 31 | 33 | ||
98 | 32 | namespace me = mir::examples; | 34 | namespace me = mir::examples; |
99 | 33 | namespace mf = mir::frontend; | 35 | namespace mf = mir::frontend; |
100 | @@ -134,7 +136,10 @@ | |||
101 | 134 | } | 136 | } |
102 | 135 | else if (selection == wm_canonical) | 137 | else if (selection == wm_canonical) |
103 | 136 | { | 138 | { |
105 | 137 | return std::make_shared<CanonicalWindowManager>(focus_controller, server.the_shell_display_layout()); | 139 | return std::make_shared<CanonicalWindowManager>( |
106 | 140 | focus_controller, | ||
107 | 141 | server.the_shell_display_layout(), | ||
108 | 142 | server.the_graphics_platform()->create_buffer_allocator()); | ||
109 | 138 | } | 143 | } |
110 | 139 | else if (selection == wm_system_compositor) | 144 | else if (selection == wm_system_compositor) |
111 | 140 | { | 145 | { |
112 | 141 | 146 | ||
113 | === modified file 'include/server/mir/frontend/buffer_sink.h' | |||
114 | --- include/server/mir/frontend/buffer_sink.h 2017-05-08 03:04:26 +0000 | |||
115 | +++ include/server/mir/frontend/buffer_sink.h 2017-07-18 03:23:56 +0000 | |||
116 | @@ -37,7 +37,6 @@ | |||
117 | 37 | virtual void send_buffer(frontend::BufferStreamId id, graphics::Buffer& buffer, graphics::BufferIpcMsgType) = 0; | 37 | virtual void send_buffer(frontend::BufferStreamId id, graphics::Buffer& buffer, graphics::BufferIpcMsgType) = 0; |
118 | 38 | virtual void add_buffer(graphics::Buffer&) = 0; | 38 | virtual void add_buffer(graphics::Buffer&) = 0; |
119 | 39 | virtual void error_buffer(geometry::Size req_size, MirPixelFormat req_format, std::string const& error_msg) = 0; | 39 | virtual void error_buffer(geometry::Size req_size, MirPixelFormat req_format, std::string const& error_msg) = 0; |
120 | 40 | virtual void remove_buffer(graphics::Buffer&) = 0; | ||
121 | 41 | virtual void update_buffer(graphics::Buffer&) = 0; | 40 | virtual void update_buffer(graphics::Buffer&) = 0; |
122 | 42 | 41 | ||
123 | 43 | protected: | 42 | protected: |
124 | 44 | 43 | ||
125 | === removed file 'include/server/mir/frontend/client_buffers.h' | |||
126 | --- include/server/mir/frontend/client_buffers.h 2017-05-08 03:04:26 +0000 | |||
127 | +++ include/server/mir/frontend/client_buffers.h 1970-01-01 00:00:00 +0000 | |||
128 | @@ -1,46 +0,0 @@ | |||
129 | 1 | /* | ||
130 | 2 | * Copyright © 2015 Canonical Ltd. | ||
131 | 3 | * | ||
132 | 4 | * This program is free software: you can redistribute it and/or modify | ||
133 | 5 | * it under the terms of the GNU General Public License version 3 as | ||
134 | 6 | * published by the Free Software Foundation. | ||
135 | 7 | * | ||
136 | 8 | * This program is distributed in the hope that it will be useful, | ||
137 | 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
138 | 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
139 | 11 | * GNU General Public License for more details. | ||
140 | 12 | * | ||
141 | 13 | * You should have received a copy of the GNU General Public License | ||
142 | 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
143 | 15 | * | ||
144 | 16 | * Authored by: Kevin DuBois <kevin.dubois@canonical.com> | ||
145 | 17 | */ | ||
146 | 18 | |||
147 | 19 | #ifndef MIR_FRONTEND_CLIENT_BUFFERS_H_ | ||
148 | 20 | #define MIR_FRONTEND_CLIENT_BUFFERS_H_ | ||
149 | 21 | |||
150 | 22 | #include "mir/graphics/buffer_id.h" | ||
151 | 23 | #include <memory> | ||
152 | 24 | |||
153 | 25 | namespace mir | ||
154 | 26 | { | ||
155 | 27 | namespace graphics { class Buffer; } | ||
156 | 28 | namespace frontend | ||
157 | 29 | { | ||
158 | 30 | class ClientBuffers | ||
159 | 31 | { | ||
160 | 32 | public: | ||
161 | 33 | virtual graphics::BufferID add_buffer(std::shared_ptr<graphics::Buffer> const& properties) = 0; | ||
162 | 34 | virtual void remove_buffer(graphics::BufferID id) = 0; | ||
163 | 35 | virtual std::shared_ptr<graphics::Buffer> get(graphics::BufferID) const = 0; | ||
164 | 36 | virtual void send_buffer(graphics::BufferID id) = 0; | ||
165 | 37 | virtual void receive_buffer(graphics::BufferID id) = 0; | ||
166 | 38 | |||
167 | 39 | ClientBuffers(ClientBuffers const&) = delete; | ||
168 | 40 | ClientBuffers& operator=(ClientBuffers const&) = delete; | ||
169 | 41 | virtual ~ClientBuffers() = default; | ||
170 | 42 | ClientBuffers() = default; | ||
171 | 43 | }; | ||
172 | 44 | } | ||
173 | 45 | } | ||
174 | 46 | #endif /* MIR_FRONTEND_CLIENT_BUFFERS_H_ */ | ||
175 | 47 | 0 | ||
176 | === modified file 'include/server/mir/frontend/session.h' | |||
177 | --- include/server/mir/frontend/session.h 2017-05-08 03:04:26 +0000 | |||
178 | +++ include/server/mir/frontend/session.h 2017-07-18 03:23:56 +0000 | |||
179 | @@ -57,12 +57,6 @@ | |||
180 | 57 | virtual BufferStreamId create_buffer_stream(graphics::BufferProperties const& props) = 0; | 57 | virtual BufferStreamId create_buffer_stream(graphics::BufferProperties const& props) = 0; |
181 | 58 | virtual void destroy_buffer_stream(BufferStreamId stream) = 0; | 58 | virtual void destroy_buffer_stream(BufferStreamId stream) = 0; |
182 | 59 | 59 | ||
183 | 60 | virtual graphics::BufferID create_buffer(graphics::BufferProperties const& properties) = 0; | ||
184 | 61 | virtual graphics::BufferID create_buffer(geometry::Size, MirPixelFormat) = 0; | ||
185 | 62 | virtual graphics::BufferID create_buffer(geometry::Size, uint32_t native_format, uint32_t native_flags) = 0; | ||
186 | 63 | virtual void destroy_buffer(graphics::BufferID) = 0; | ||
187 | 64 | virtual std::shared_ptr<graphics::Buffer> get_buffer(graphics::BufferID) = 0; | ||
188 | 65 | |||
189 | 66 | virtual std::string name() const = 0; | 60 | virtual std::string name() const = 0; |
190 | 67 | 61 | ||
191 | 68 | virtual void send_display_config(graphics::DisplayConfiguration const&) = 0; | 62 | virtual void send_display_config(graphics::DisplayConfiguration const&) = 0; |
192 | 69 | 63 | ||
193 | === modified file 'include/server/mir/scene/buffer_stream_factory.h' | |||
194 | --- include/server/mir/scene/buffer_stream_factory.h 2017-05-08 03:04:26 +0000 | |||
195 | +++ include/server/mir/scene/buffer_stream_factory.h 2017-07-18 03:23:56 +0000 | |||
196 | @@ -28,7 +28,6 @@ | |||
197 | 28 | { | 28 | { |
198 | 29 | namespace compositor { class BufferStream; } | 29 | namespace compositor { class BufferStream; } |
199 | 30 | namespace graphics { struct BufferProperties; } | 30 | namespace graphics { struct BufferProperties; } |
200 | 31 | namespace frontend { class ClientBuffers; class BufferSink; } | ||
201 | 32 | namespace scene | 31 | namespace scene |
202 | 33 | { | 32 | { |
203 | 34 | class BufferStreamFactory | 33 | class BufferStreamFactory |
204 | @@ -37,13 +36,12 @@ | |||
205 | 37 | virtual ~BufferStreamFactory() = default; | 36 | virtual ~BufferStreamFactory() = default; |
206 | 38 | 37 | ||
207 | 39 | virtual std::shared_ptr<compositor::BufferStream> create_buffer_stream( | 38 | virtual std::shared_ptr<compositor::BufferStream> create_buffer_stream( |
210 | 40 | frontend::BufferStreamId, std::shared_ptr<frontend::ClientBuffers> const& sink, | 39 | frontend::BufferStreamId, |
211 | 41 | int nbuffers, graphics::BufferProperties const& buffer_properties) = 0; | 40 | int nbuffers, |
212 | 41 | graphics::BufferProperties const& buffer_properties) = 0; | ||
213 | 42 | virtual std::shared_ptr<compositor::BufferStream> create_buffer_stream( | 42 | virtual std::shared_ptr<compositor::BufferStream> create_buffer_stream( |
215 | 43 | frontend::BufferStreamId, std::shared_ptr<frontend::ClientBuffers> const& sink, | 43 | frontend::BufferStreamId, |
216 | 44 | graphics::BufferProperties const& buffer_properties) = 0; | 44 | graphics::BufferProperties const& buffer_properties) = 0; |
217 | 45 | virtual std::shared_ptr<frontend::ClientBuffers> create_buffer_map( | ||
218 | 46 | std::shared_ptr<frontend::BufferSink> const& sink) = 0; | ||
219 | 47 | 45 | ||
220 | 48 | protected: | 46 | protected: |
221 | 49 | BufferStreamFactory() = default; | 47 | BufferStreamFactory() = default; |
222 | 50 | 48 | ||
223 | === modified file 'include/server/mir/scene/session.h' | |||
224 | --- include/server/mir/scene/session.h 2017-05-08 03:04:26 +0000 | |||
225 | +++ include/server/mir/scene/session.h 2017-07-18 03:23:56 +0000 | |||
226 | @@ -65,12 +65,6 @@ | |||
227 | 65 | virtual void destroy_buffer_stream(frontend::BufferStreamId stream) = 0; | 65 | virtual void destroy_buffer_stream(frontend::BufferStreamId stream) = 0; |
228 | 66 | virtual void configure_streams(Surface& surface, std::vector<shell::StreamSpecification> const& config) = 0; | 66 | virtual void configure_streams(Surface& surface, std::vector<shell::StreamSpecification> const& config) = 0; |
229 | 67 | virtual void destroy_surface(std::weak_ptr<Surface> const& surface) = 0; | 67 | virtual void destroy_surface(std::weak_ptr<Surface> const& surface) = 0; |
230 | 68 | |||
231 | 69 | virtual graphics::BufferID create_buffer(graphics::BufferProperties const& properties) = 0; | ||
232 | 70 | virtual graphics::BufferID create_buffer(geometry::Size, MirPixelFormat) = 0; | ||
233 | 71 | virtual graphics::BufferID create_buffer(geometry::Size, uint32_t native_format, uint32_t native_flags) = 0; | ||
234 | 72 | virtual void destroy_buffer(graphics::BufferID) = 0; | ||
235 | 73 | virtual std::shared_ptr<graphics::Buffer> get_buffer(graphics::BufferID) = 0; | ||
236 | 74 | }; | 68 | }; |
237 | 75 | } | 69 | } |
238 | 76 | } | 70 | } |
239 | 77 | 71 | ||
240 | === modified file 'include/server/mir/shell/window_management_info.h' | |||
241 | --- include/server/mir/shell/window_management_info.h 2017-05-08 03:04:26 +0000 | |||
242 | +++ include/server/mir/shell/window_management_info.h 2017-07-18 03:23:56 +0000 | |||
243 | @@ -28,6 +28,10 @@ | |||
244 | 28 | namespace mir | 28 | namespace mir |
245 | 29 | { | 29 | { |
246 | 30 | namespace scene { class Session; class Surface; struct SurfaceCreationParameters; } | 30 | namespace scene { class Session; class Surface; struct SurfaceCreationParameters; } |
247 | 31 | namespace graphics | ||
248 | 32 | { | ||
249 | 33 | class GraphicBufferAllocator; | ||
250 | 34 | } | ||
251 | 31 | namespace shell | 35 | namespace shell |
252 | 32 | { | 36 | { |
253 | 33 | struct SurfaceInfo | 37 | struct SurfaceInfo |
254 | @@ -78,7 +82,7 @@ | |||
255 | 78 | mir::optional_value<graphics::DisplayConfigurationOutputId> output_id; | 82 | mir::optional_value<graphics::DisplayConfigurationOutputId> output_id; |
256 | 79 | mir::optional_value<MirPointerConfinementState> confine_pointer; | 83 | mir::optional_value<MirPointerConfinementState> confine_pointer; |
257 | 80 | 84 | ||
259 | 81 | void init_titlebar(std::shared_ptr<scene::Session> const& session, std::shared_ptr<scene::Surface> const& surface); | 85 | void init_titlebar(graphics::GraphicBufferAllocator& allocator, std::shared_ptr<scene::Surface> const& surface); |
260 | 82 | void paint_titlebar(int intensity); | 86 | void paint_titlebar(int intensity); |
261 | 83 | 87 | ||
262 | 84 | private: | 88 | private: |
263 | 85 | 89 | ||
264 | === modified file 'include/test/mir/test/doubles/stub_session.h' | |||
265 | --- include/test/mir/test/doubles/stub_session.h 2017-05-08 03:04:26 +0000 | |||
266 | +++ include/test/mir/test/doubles/stub_session.h 2017-07-18 03:23:56 +0000 | |||
267 | @@ -89,12 +89,6 @@ | |||
268 | 89 | 89 | ||
269 | 90 | void send_input_config(MirInputConfig const& config) override; | 90 | void send_input_config(MirInputConfig const& config) override; |
270 | 91 | 91 | ||
271 | 92 | graphics::BufferID create_buffer(graphics::BufferProperties const& properties) override; | ||
272 | 93 | graphics::BufferID create_buffer(geometry::Size, MirPixelFormat) override; | ||
273 | 94 | graphics::BufferID create_buffer(geometry::Size, uint32_t native_format, uint32_t native_flags) override; | ||
274 | 95 | void destroy_buffer(graphics::BufferID) override; | ||
275 | 96 | std::shared_ptr<graphics::Buffer> get_buffer(graphics::BufferID) override; | ||
276 | 97 | |||
277 | 98 | pid_t pid; | 92 | pid_t pid; |
278 | 99 | }; | 93 | }; |
279 | 100 | } | 94 | } |
280 | 101 | 95 | ||
281 | === modified file 'src/client/buffer_vault.cpp' | |||
282 | --- src/client/buffer_vault.cpp 2017-05-17 04:48:46 +0000 | |||
283 | +++ src/client/buffer_vault.cpp 2017-07-18 03:23:56 +0000 | |||
284 | @@ -86,11 +86,15 @@ | |||
285 | 86 | { | 86 | { |
286 | 87 | if (auto map = surface_map.lock()) | 87 | if (auto map = surface_map.lock()) |
287 | 88 | { | 88 | { |
290 | 89 | auto buffer = map->buffer(it.first); | 89 | if (auto buffer = map->buffer(it.first)) |
291 | 90 | buffer->set_callback(ignore_buffer, nullptr); | 90 | { |
292 | 91 | buffer->set_callback(ignore_buffer, nullptr); | ||
293 | 92 | } | ||
294 | 91 | } | 93 | } |
295 | 92 | if (!disconnected_) | 94 | if (!disconnected_) |
296 | 95 | { | ||
297 | 93 | free_buffer(it.first); | 96 | free_buffer(it.first); |
298 | 97 | } | ||
299 | 94 | } | 98 | } |
300 | 95 | catch (...) | 99 | catch (...) |
301 | 96 | { | 100 | { |
302 | @@ -110,6 +114,10 @@ | |||
303 | 110 | void mcl::BufferVault::free_buffer(int free_id) | 114 | void mcl::BufferVault::free_buffer(int free_id) |
304 | 111 | { | 115 | { |
305 | 112 | server_requests->free_buffer(free_id); | 116 | server_requests->free_buffer(free_id); |
306 | 117 | if (auto map = surface_map.lock()) | ||
307 | 118 | { | ||
308 | 119 | map->erase(free_id); | ||
309 | 120 | } | ||
310 | 113 | } | 121 | } |
311 | 114 | 122 | ||
312 | 115 | void mcl::BufferVault::realloc_buffer(int free_id, geom::Size size, MirPixelFormat format, int usage) | 123 | void mcl::BufferVault::realloc_buffer(int free_id, geom::Size size, MirPixelFormat format, int usage) |
313 | 116 | 124 | ||
314 | === modified file 'src/client/connection_surface_map.cpp' | |||
315 | --- src/client/connection_surface_map.cpp 2017-05-08 03:04:26 +0000 | |||
316 | +++ src/client/connection_surface_map.cpp 2017-07-18 03:23:56 +0000 | |||
317 | @@ -107,7 +107,7 @@ | |||
318 | 107 | if (it != buffers.end()) | 107 | if (it != buffers.end()) |
319 | 108 | return it->second; | 108 | return it->second; |
320 | 109 | else | 109 | else |
322 | 110 | BOOST_THROW_EXCEPTION(std::runtime_error("could not find buffer")); | 110 | return nullptr; |
323 | 111 | } | 111 | } |
324 | 112 | 112 | ||
325 | 113 | void mcl::ConnectionSurfaceMap::erase(void* render_surface_key) | 113 | void mcl::ConnectionSurfaceMap::erase(void* render_surface_key) |
326 | 114 | 114 | ||
327 | === modified file 'src/client/mir_connection.cpp' | |||
328 | --- src/client/mir_connection.cpp 2017-06-30 11:32:37 +0000 | |||
329 | +++ src/client/mir_connection.cpp 2017-07-18 03:23:56 +0000 | |||
330 | @@ -1305,7 +1305,6 @@ | |||
331 | 1305 | MirBufferCallback callback, void* context) | 1305 | MirBufferCallback callback, void* context) |
332 | 1306 | { | 1306 | { |
333 | 1307 | mp::BufferAllocation request; | 1307 | mp::BufferAllocation request; |
334 | 1308 | request.mutable_id()->set_value(-1); | ||
335 | 1309 | auto buffer_request = request.add_buffer_requests(); | 1308 | auto buffer_request = request.add_buffer_requests(); |
336 | 1310 | buffer_request->set_width(size.width.as_int()); | 1309 | buffer_request->set_width(size.width.as_int()); |
337 | 1311 | buffer_request->set_height(size.height.as_int()); | 1310 | buffer_request->set_height(size.height.as_int()); |
338 | @@ -1323,16 +1322,15 @@ | |||
339 | 1323 | 1322 | ||
340 | 1324 | void MirConnection::release_buffer(mcl::MirBuffer* buffer) | 1323 | void MirConnection::release_buffer(mcl::MirBuffer* buffer) |
341 | 1325 | { | 1324 | { |
343 | 1326 | if (!buffer->valid()) | 1325 | if (buffer->valid()) |
344 | 1327 | { | 1326 | { |
347 | 1328 | surface_map->erase(buffer->rpc_id()); | 1327 | mp::BufferRelease request; |
348 | 1329 | return; | 1328 | auto released_buffer = request.add_buffers(); |
349 | 1329 | released_buffer->set_buffer_id(buffer->rpc_id()); | ||
350 | 1330 | server.release_buffers(&request, ignored.get(), gp::NewCallback(ignore)); | ||
351 | 1330 | } | 1331 | } |
352 | 1331 | 1332 | ||
357 | 1332 | mp::BufferRelease request; | 1333 | surface_map->erase(buffer->rpc_id()); |
354 | 1333 | auto released_buffer = request.add_buffers(); | ||
355 | 1334 | released_buffer->set_buffer_id(buffer->rpc_id()); | ||
356 | 1335 | server.release_buffers(&request, ignored.get(), gp::NewCallback(ignore)); | ||
358 | 1336 | } | 1334 | } |
359 | 1337 | 1335 | ||
360 | 1338 | void MirConnection::release_render_surface_with_content( | 1336 | void MirConnection::release_render_surface_with_content( |
361 | 1339 | 1337 | ||
362 | === modified file 'src/client/rpc/mir_protobuf_rpc_channel.cpp' | |||
363 | --- src/client/rpc/mir_protobuf_rpc_channel.cpp 2017-05-08 03:04:26 +0000 | |||
364 | +++ src/client/rpc/mir_protobuf_rpc_channel.cpp 2017-07-18 03:23:56 +0000 | |||
365 | @@ -359,11 +359,19 @@ | |||
366 | 359 | buffer->received(); | 359 | buffer->received(); |
367 | 360 | break; | 360 | break; |
368 | 361 | case mp::BufferOperation::update: | 361 | case mp::BufferOperation::update: |
371 | 362 | map->buffer(buffer_id)->received( | 362 | buffer = map->buffer(buffer_id); |
372 | 363 | *mcl::protobuf_to_native_buffer(seq.buffer_request().buffer())); | 363 | if (buffer) |
373 | 364 | { | ||
374 | 365 | buffer->received( | ||
375 | 366 | *mcl::protobuf_to_native_buffer(seq.buffer_request().buffer())); | ||
376 | 367 | } | ||
377 | 364 | break; | 368 | break; |
378 | 365 | case mp::BufferOperation::remove: | 369 | case mp::BufferOperation::remove: |
380 | 366 | map->erase(buffer_id); | 370 | /* The server never sends us an unsolicited ::remove request |
381 | 371 | * (and clients have no way of dealing with one) | ||
382 | 372 | * | ||
383 | 373 | * Just ignore it, because we've already deleted our buffer. | ||
384 | 374 | */ | ||
385 | 367 | break; | 375 | break; |
386 | 368 | default: | 376 | default: |
387 | 369 | BOOST_THROW_EXCEPTION(std::runtime_error("unknown buffer operation")); | 377 | BOOST_THROW_EXCEPTION(std::runtime_error("unknown buffer operation")); |
388 | 370 | 378 | ||
389 | === modified file 'src/server/compositor/CMakeLists.txt' | |||
390 | --- src/server/compositor/CMakeLists.txt 2017-05-08 03:04:26 +0000 | |||
391 | +++ src/server/compositor/CMakeLists.txt 2017-07-18 03:23:56 +0000 | |||
392 | @@ -18,7 +18,6 @@ | |||
393 | 18 | compositing_screencast.cpp | 18 | compositing_screencast.cpp |
394 | 19 | stream.cpp | 19 | stream.cpp |
395 | 20 | multi_monitor_arbiter.cpp | 20 | multi_monitor_arbiter.cpp |
396 | 21 | buffer_map.cpp | ||
397 | 22 | dropping_schedule.cpp | 21 | dropping_schedule.cpp |
398 | 23 | queueing_schedule.cpp | 22 | queueing_schedule.cpp |
399 | 24 | ) | 23 | ) |
400 | 25 | 24 | ||
401 | === removed file 'src/server/compositor/buffer_map.cpp' | |||
402 | --- src/server/compositor/buffer_map.cpp 2017-05-08 03:04:26 +0000 | |||
403 | +++ src/server/compositor/buffer_map.cpp 1970-01-01 00:00:00 +0000 | |||
404 | @@ -1,116 +0,0 @@ | |||
405 | 1 | /* | ||
406 | 2 | * Copyright © 2015 Canonical Ltd. | ||
407 | 3 | * | ||
408 | 4 | * This program is free software: you can redistribute it and/or modify | ||
409 | 5 | * it under the terms of the GNU General Public License version 3 as | ||
410 | 6 | * published by the Free Software Foundation. | ||
411 | 7 | * | ||
412 | 8 | * This program is distributed in the hope that it will be useful, | ||
413 | 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
414 | 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
415 | 11 | * GNU General Public License for more details. | ||
416 | 12 | * | ||
417 | 13 | * You should have received a copy of the GNU General Public License | ||
418 | 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
419 | 15 | * | ||
420 | 16 | * Authored by: Kevin DuBois <kevin.dubois@canonical.com> | ||
421 | 17 | */ | ||
422 | 18 | |||
423 | 19 | #include "mir/graphics/buffer.h" | ||
424 | 20 | #include "mir/frontend/buffer_sink.h" | ||
425 | 21 | #include "buffer_map.h" | ||
426 | 22 | #include <boost/throw_exception.hpp> | ||
427 | 23 | #include <algorithm> | ||
428 | 24 | |||
429 | 25 | namespace mc = mir::compositor; | ||
430 | 26 | namespace mf = mir::frontend; | ||
431 | 27 | namespace mg = mir::graphics; | ||
432 | 28 | |||
433 | 29 | namespace mir | ||
434 | 30 | { | ||
435 | 31 | namespace compositor | ||
436 | 32 | { | ||
437 | 33 | enum class BufferMap::Owner | ||
438 | 34 | { | ||
439 | 35 | server, | ||
440 | 36 | client | ||
441 | 37 | }; | ||
442 | 38 | } | ||
443 | 39 | } | ||
444 | 40 | |||
445 | 41 | mc::BufferMap::BufferMap(std::shared_ptr<mf::BufferSink> const& sink) : | ||
446 | 42 | sink(sink) | ||
447 | 43 | { | ||
448 | 44 | } | ||
449 | 45 | |||
450 | 46 | mg::BufferID mc::BufferMap::add_buffer(std::shared_ptr<mg::Buffer> const& buffer) | ||
451 | 47 | { | ||
452 | 48 | try | ||
453 | 49 | { | ||
454 | 50 | std::unique_lock<decltype(mutex)> lk(mutex); | ||
455 | 51 | buffers[buffer->id()] = {buffer, Owner::client}; | ||
456 | 52 | if (auto s = sink.lock()) | ||
457 | 53 | s->add_buffer(*buffer); | ||
458 | 54 | return buffer->id(); | ||
459 | 55 | } catch (std::exception& e) | ||
460 | 56 | { | ||
461 | 57 | if (auto s = sink.lock()) | ||
462 | 58 | s->error_buffer(buffer->size(), buffer->pixel_format(), e.what()); | ||
463 | 59 | throw; | ||
464 | 60 | } | ||
465 | 61 | } | ||
466 | 62 | |||
467 | 63 | void mc::BufferMap::remove_buffer(mg::BufferID id) | ||
468 | 64 | { | ||
469 | 65 | std::unique_lock<decltype(mutex)> lk(mutex); | ||
470 | 66 | auto it = checked_buffers_find(id, lk); | ||
471 | 67 | if (auto s = sink.lock()) | ||
472 | 68 | s->remove_buffer(*it->second.buffer); | ||
473 | 69 | buffers.erase(it); | ||
474 | 70 | } | ||
475 | 71 | |||
476 | 72 | void mc::BufferMap::send_buffer(mg::BufferID id) | ||
477 | 73 | { | ||
478 | 74 | std::unique_lock<decltype(mutex)> lk(mutex); | ||
479 | 75 | auto it = buffers.find(id); | ||
480 | 76 | if (it != buffers.end()) | ||
481 | 77 | { | ||
482 | 78 | auto buffer = it->second.buffer; | ||
483 | 79 | it->second.owner = Owner::client; | ||
484 | 80 | lk.unlock(); | ||
485 | 81 | if (auto s = sink.lock()) | ||
486 | 82 | s->update_buffer(*buffer); | ||
487 | 83 | } | ||
488 | 84 | } | ||
489 | 85 | |||
490 | 86 | void mc::BufferMap::receive_buffer(graphics::BufferID id) | ||
491 | 87 | { | ||
492 | 88 | std::unique_lock<decltype(mutex)> lk(mutex); | ||
493 | 89 | auto it = buffers.find(id); | ||
494 | 90 | if (it != buffers.end()) | ||
495 | 91 | it->second.owner = Owner::server; | ||
496 | 92 | } | ||
497 | 93 | |||
498 | 94 | std::shared_ptr<mg::Buffer> mc::BufferMap::get(mg::BufferID id) const | ||
499 | 95 | { | ||
500 | 96 | std::unique_lock<decltype(mutex)> lk(mutex); | ||
501 | 97 | return checked_buffers_find(id, lk)->second.buffer; | ||
502 | 98 | } | ||
503 | 99 | |||
504 | 100 | mc::BufferMap::Map::iterator mc::BufferMap::checked_buffers_find( | ||
505 | 101 | mg::BufferID id, std::unique_lock<std::mutex> const&) | ||
506 | 102 | { | ||
507 | 103 | auto it = buffers.find(id); | ||
508 | 104 | if (it == buffers.end()) | ||
509 | 105 | BOOST_THROW_EXCEPTION(std::logic_error("cannot find buffer by id")); | ||
510 | 106 | return it; | ||
511 | 107 | } | ||
512 | 108 | |||
513 | 109 | mc::BufferMap::Map::const_iterator mc::BufferMap::checked_buffers_find( | ||
514 | 110 | mg::BufferID id, std::unique_lock<std::mutex> const&) const | ||
515 | 111 | { | ||
516 | 112 | auto it = buffers.find(id); | ||
517 | 113 | if (it == buffers.end()) | ||
518 | 114 | BOOST_THROW_EXCEPTION(std::logic_error("cannot find buffer by id")); | ||
519 | 115 | return it; | ||
520 | 116 | } | ||
521 | 117 | 0 | ||
522 | === removed file 'src/server/compositor/buffer_map.h' | |||
523 | --- src/server/compositor/buffer_map.h 2017-05-08 03:04:26 +0000 | |||
524 | +++ src/server/compositor/buffer_map.h 1970-01-01 00:00:00 +0000 | |||
525 | @@ -1,65 +0,0 @@ | |||
526 | 1 | /* | ||
527 | 2 | * Copyright © 2015 Canonical Ltd. | ||
528 | 3 | * | ||
529 | 4 | * This program is free software: you can redistribute it and/or modify | ||
530 | 5 | * it under the terms of the GNU General Public License version 3 as | ||
531 | 6 | * published by the Free Software Foundation. | ||
532 | 7 | * | ||
533 | 8 | * This program is distributed in the hope that it will be useful, | ||
534 | 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
535 | 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
536 | 11 | * GNU General Public License for more details. | ||
537 | 12 | * | ||
538 | 13 | * You should have received a copy of the GNU General Public License | ||
539 | 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
540 | 15 | * | ||
541 | 16 | * Authored by: Kevin DuBois <kevin.dubois@canonical.com> | ||
542 | 17 | */ | ||
543 | 18 | |||
544 | 19 | #ifndef MIR_COMPOSITOR_BUFFER_MAP_H_ | ||
545 | 20 | #define MIR_COMPOSITOR_BUFFER_MAP_H_ | ||
546 | 21 | |||
547 | 22 | #include "mir/frontend/client_buffers.h" | ||
548 | 23 | #include <mutex> | ||
549 | 24 | #include <map> | ||
550 | 25 | |||
551 | 26 | namespace mir | ||
552 | 27 | { | ||
553 | 28 | namespace frontend { class BufferSink; } | ||
554 | 29 | namespace compositor | ||
555 | 30 | { | ||
556 | 31 | class BufferMap : public frontend::ClientBuffers | ||
557 | 32 | { | ||
558 | 33 | public: | ||
559 | 34 | BufferMap(std::shared_ptr<frontend::BufferSink> const& sink); | ||
560 | 35 | |||
561 | 36 | graphics::BufferID add_buffer(std::shared_ptr<graphics::Buffer> const& buffer) override; | ||
562 | 37 | void remove_buffer(graphics::BufferID id) override; | ||
563 | 38 | |||
564 | 39 | void receive_buffer(graphics::BufferID id) override; | ||
565 | 40 | void send_buffer(graphics::BufferID id) override; | ||
566 | 41 | |||
567 | 42 | std::shared_ptr<graphics::Buffer> get(graphics::BufferID) const override; | ||
568 | 43 | |||
569 | 44 | private: | ||
570 | 45 | std::mutex mutable mutex; | ||
571 | 46 | |||
572 | 47 | enum class Owner; | ||
573 | 48 | struct MapEntry | ||
574 | 49 | { | ||
575 | 50 | std::shared_ptr<graphics::Buffer> buffer; | ||
576 | 51 | Owner owner; | ||
577 | 52 | }; | ||
578 | 53 | typedef std::map<graphics::BufferID, MapEntry> Map; | ||
579 | 54 | //used to keep strong reference | ||
580 | 55 | Map buffers; | ||
581 | 56 | Map::iterator checked_buffers_find(graphics::BufferID, std::unique_lock<std::mutex> const&); | ||
582 | 57 | Map::const_iterator checked_buffers_find(graphics::BufferID, std::unique_lock<std::mutex> const&) const; | ||
583 | 58 | |||
584 | 59 | //would be better to schedule the async buffer callbacks in the ipc subsystem, | ||
585 | 60 | //instead of driving from within the compositor threads (LP: #1395421) | ||
586 | 61 | std::weak_ptr<frontend::BufferSink> const sink; | ||
587 | 62 | }; | ||
588 | 63 | } | ||
589 | 64 | } | ||
590 | 65 | #endif /* MIR_COMPOSITOR_BUFFER_MAP_H_ */ | ||
591 | 66 | 0 | ||
592 | === modified file 'src/server/compositor/buffer_stream_factory.cpp' | |||
593 | --- src/server/compositor/buffer_stream_factory.cpp 2017-05-08 03:04:26 +0000 | |||
594 | +++ src/server/compositor/buffer_stream_factory.cpp 2017-07-18 03:23:56 +0000 | |||
595 | @@ -21,7 +21,6 @@ | |||
596 | 21 | #include "buffer_stream_factory.h" | 21 | #include "buffer_stream_factory.h" |
597 | 22 | #include "mir/graphics/buffer_properties.h" | 22 | #include "mir/graphics/buffer_properties.h" |
598 | 23 | #include "stream.h" | 23 | #include "stream.h" |
599 | 24 | #include "buffer_map.h" | ||
600 | 25 | #include "mir/graphics/buffer.h" | 24 | #include "mir/graphics/buffer.h" |
601 | 26 | #include "mir/graphics/buffer_id.h" | 25 | #include "mir/graphics/buffer_id.h" |
602 | 27 | #include "mir/graphics/graphic_buffer_allocator.h" | 26 | #include "mir/graphics/graphic_buffer_allocator.h" |
603 | @@ -40,23 +39,17 @@ | |||
604 | 40 | } | 39 | } |
605 | 41 | 40 | ||
606 | 42 | std::shared_ptr<mc::BufferStream> mc::BufferStreamFactory::create_buffer_stream( | 41 | std::shared_ptr<mc::BufferStream> mc::BufferStreamFactory::create_buffer_stream( |
608 | 43 | mf::BufferStreamId id, std::shared_ptr<mf::ClientBuffers> const& buffers, | 42 | mf::BufferStreamId id, |
609 | 44 | mg::BufferProperties const& buffer_properties) | 43 | mg::BufferProperties const& buffer_properties) |
610 | 45 | { | 44 | { |
612 | 46 | return create_buffer_stream(id, buffers, 0, buffer_properties); | 45 | return create_buffer_stream(id, 0, buffer_properties); |
613 | 47 | } | 46 | } |
614 | 48 | 47 | ||
615 | 49 | std::shared_ptr<mc::BufferStream> mc::BufferStreamFactory::create_buffer_stream( | 48 | std::shared_ptr<mc::BufferStream> mc::BufferStreamFactory::create_buffer_stream( |
618 | 50 | mf::BufferStreamId, std::shared_ptr<mf::ClientBuffers> const& buffers, | 49 | mf::BufferStreamId, |
619 | 51 | int, mg::BufferProperties const& buffer_properties) | 50 | int, |
620 | 51 | mg::BufferProperties const& buffer_properties) | ||
621 | 52 | { | 52 | { |
622 | 53 | return std::make_shared<mc::Stream>( | 53 | return std::make_shared<mc::Stream>( |
623 | 54 | buffers, | ||
624 | 55 | buffer_properties.size, buffer_properties.format); | 54 | buffer_properties.size, buffer_properties.format); |
625 | 56 | } | 55 | } |
626 | 57 | |||
627 | 58 | std::shared_ptr<mf::ClientBuffers> mc::BufferStreamFactory::create_buffer_map( | ||
628 | 59 | std::shared_ptr<mf::BufferSink> const& sink) | ||
629 | 60 | { | ||
630 | 61 | return std::make_shared<mc::BufferMap>(sink); | ||
631 | 62 | } | ||
632 | 63 | 56 | ||
633 | === modified file 'src/server/compositor/buffer_stream_factory.h' | |||
634 | --- src/server/compositor/buffer_stream_factory.h 2017-05-08 03:04:26 +0000 | |||
635 | +++ src/server/compositor/buffer_stream_factory.h 2017-07-18 03:23:56 +0000 | |||
636 | @@ -42,13 +42,12 @@ | |||
637 | 42 | virtual ~BufferStreamFactory() {} | 42 | virtual ~BufferStreamFactory() {} |
638 | 43 | 43 | ||
639 | 44 | virtual std::shared_ptr<compositor::BufferStream> create_buffer_stream( | 44 | virtual std::shared_ptr<compositor::BufferStream> create_buffer_stream( |
642 | 45 | frontend::BufferStreamId, std::shared_ptr<frontend::ClientBuffers> const& sink, | 45 | frontend::BufferStreamId, |
643 | 46 | int nbuffers, graphics::BufferProperties const& buffer_properties) override; | 46 | int nbuffers, |
644 | 47 | graphics::BufferProperties const& buffer_properties) override; | ||
645 | 47 | virtual std::shared_ptr<BufferStream> create_buffer_stream( | 48 | virtual std::shared_ptr<BufferStream> create_buffer_stream( |
647 | 48 | frontend::BufferStreamId, std::shared_ptr<frontend::ClientBuffers> const& sink, | 49 | frontend::BufferStreamId, |
648 | 49 | graphics::BufferProperties const&) override; | 50 | graphics::BufferProperties const&) override; |
649 | 50 | virtual std::shared_ptr<frontend::ClientBuffers> create_buffer_map( | ||
650 | 51 | std::shared_ptr<frontend::BufferSink> const& sink) override; | ||
651 | 52 | }; | 51 | }; |
652 | 53 | 52 | ||
653 | 54 | } | 53 | } |
654 | 55 | 54 | ||
655 | === modified file 'src/server/compositor/dropping_schedule.cpp' | |||
656 | --- src/server/compositor/dropping_schedule.cpp 2017-05-08 03:04:26 +0000 | |||
657 | +++ src/server/compositor/dropping_schedule.cpp 2017-07-18 03:23:56 +0000 | |||
658 | @@ -17,16 +17,13 @@ | |||
659 | 17 | */ | 17 | */ |
660 | 18 | 18 | ||
661 | 19 | #include "dropping_schedule.h" | 19 | #include "dropping_schedule.h" |
662 | 20 | #include "mir/frontend/client_buffers.h" | ||
663 | 21 | #include "mir/graphics/buffer.h" | 20 | #include "mir/graphics/buffer.h" |
664 | 22 | 21 | ||
665 | 23 | #include <boost/throw_exception.hpp> | 22 | #include <boost/throw_exception.hpp> |
666 | 24 | namespace mf = mir::frontend; | ||
667 | 25 | namespace mg = mir::graphics; | 23 | namespace mg = mir::graphics; |
668 | 26 | namespace mc = mir::compositor; | 24 | namespace mc = mir::compositor; |
669 | 27 | 25 | ||
672 | 28 | mc::DroppingSchedule::DroppingSchedule(std::shared_ptr<mf::ClientBuffers> const& client_buffers) : | 26 | mc::DroppingSchedule::DroppingSchedule() |
671 | 29 | sender(client_buffers) | ||
673 | 30 | { | 27 | { |
674 | 31 | } | 28 | } |
675 | 32 | 29 | ||
676 | @@ -42,14 +39,6 @@ | |||
677 | 42 | { | 39 | { |
678 | 43 | std::future<void> drop; | 40 | std::future<void> drop; |
679 | 44 | std::lock_guard<decltype(mutex)> lk(mutex); | 41 | std::lock_guard<decltype(mutex)> lk(mutex); |
680 | 45 | if ((the_only_buffer != buffer) && the_only_buffer) | ||
681 | 46 | { | ||
682 | 47 | drop = std::async(std::launch::deferred, | ||
683 | 48 | [sender=sender, dropped=the_only_buffer]() | ||
684 | 49 | { | ||
685 | 50 | sender->send_buffer(dropped->id()); | ||
686 | 51 | }); | ||
687 | 52 | } | ||
688 | 53 | the_only_buffer = buffer; | 42 | the_only_buffer = buffer; |
689 | 54 | return drop; | 43 | return drop; |
690 | 55 | } | 44 | } |
691 | 56 | 45 | ||
692 | === modified file 'src/server/compositor/dropping_schedule.h' | |||
693 | --- src/server/compositor/dropping_schedule.h 2017-05-08 03:04:26 +0000 | |||
694 | +++ src/server/compositor/dropping_schedule.h 2017-07-18 03:23:56 +0000 | |||
695 | @@ -25,13 +25,12 @@ | |||
696 | 25 | namespace mir | 25 | namespace mir |
697 | 26 | { | 26 | { |
698 | 27 | namespace graphics { class Buffer; } | 27 | namespace graphics { class Buffer; } |
699 | 28 | namespace frontend { class ClientBuffers; } | ||
700 | 29 | namespace compositor | 28 | namespace compositor |
701 | 30 | { | 29 | { |
702 | 31 | class DroppingSchedule : public Schedule | 30 | class DroppingSchedule : public Schedule |
703 | 32 | { | 31 | { |
704 | 33 | public: | 32 | public: |
706 | 34 | DroppingSchedule(std::shared_ptr<frontend::ClientBuffers> const&); | 33 | DroppingSchedule(); |
707 | 35 | void schedule(std::shared_ptr<graphics::Buffer> const& buffer) override; | 34 | void schedule(std::shared_ptr<graphics::Buffer> const& buffer) override; |
708 | 36 | std::future<void> schedule_nonblocking( | 35 | std::future<void> schedule_nonblocking( |
709 | 37 | std::shared_ptr<graphics::Buffer> const& buffer) override; | 36 | std::shared_ptr<graphics::Buffer> const& buffer) override; |
710 | @@ -40,7 +39,6 @@ | |||
711 | 40 | 39 | ||
712 | 41 | private: | 40 | private: |
713 | 42 | std::mutex mutable mutex; | 41 | std::mutex mutable mutex; |
714 | 43 | std::shared_ptr<frontend::ClientBuffers> const sender; | ||
715 | 44 | std::shared_ptr<graphics::Buffer> the_only_buffer; | 42 | std::shared_ptr<graphics::Buffer> the_only_buffer; |
716 | 45 | }; | 43 | }; |
717 | 46 | } | 44 | } |
718 | 47 | 45 | ||
719 | === modified file 'src/server/compositor/multi_monitor_arbiter.cpp' | |||
720 | --- src/server/compositor/multi_monitor_arbiter.cpp 2017-05-26 12:45:45 +0000 | |||
721 | +++ src/server/compositor/multi_monitor_arbiter.cpp 2017-07-18 03:23:56 +0000 | |||
722 | @@ -20,7 +20,6 @@ | |||
723 | 20 | #include "mir/graphics/buffer.h" | 20 | #include "mir/graphics/buffer.h" |
724 | 21 | #include "mir/graphics/graphic_buffer_allocator.h" | 21 | #include "mir/graphics/graphic_buffer_allocator.h" |
725 | 22 | #include "mir/frontend/event_sink.h" | 22 | #include "mir/frontend/event_sink.h" |
726 | 23 | #include "mir/frontend/client_buffers.h" | ||
727 | 24 | #include "schedule.h" | 23 | #include "schedule.h" |
728 | 25 | #include <boost/throw_exception.hpp> | 24 | #include <boost/throw_exception.hpp> |
729 | 26 | #include <algorithm> | 25 | #include <algorithm> |
730 | @@ -30,9 +29,7 @@ | |||
731 | 30 | namespace mf = mir::frontend; | 29 | namespace mf = mir::frontend; |
732 | 31 | 30 | ||
733 | 32 | mc::MultiMonitorArbiter::MultiMonitorArbiter( | 31 | mc::MultiMonitorArbiter::MultiMonitorArbiter( |
734 | 33 | std::shared_ptr<frontend::ClientBuffers> const& map, | ||
735 | 34 | std::shared_ptr<Schedule> const& schedule) : | 32 | std::shared_ptr<Schedule> const& schedule) : |
736 | 35 | map(map), | ||
737 | 36 | schedule(schedule) | 33 | schedule(schedule) |
738 | 37 | { | 34 | { |
739 | 38 | } | 35 | } |
740 | @@ -43,7 +40,7 @@ | |||
741 | 43 | for(auto it = onscreen_buffers.begin(); it != onscreen_buffers.end(); it++) | 40 | for(auto it = onscreen_buffers.begin(); it != onscreen_buffers.end(); it++) |
742 | 44 | { | 41 | { |
743 | 45 | if (it->use_count == 0) | 42 | if (it->use_count == 0) |
745 | 46 | map->send_buffer(it->buffer->id()); | 43 | it->buffer.reset(); |
746 | 47 | } | 44 | } |
747 | 48 | 45 | ||
748 | 49 | } | 46 | } |
749 | @@ -96,7 +93,6 @@ | |||
750 | 96 | if ((it->use_count == 0) && | 93 | if ((it->use_count == 0) && |
751 | 97 | (it != onscreen_buffers.begin() || schedule->num_scheduled())) //ensure monitors always have a buffer | 94 | (it != onscreen_buffers.begin() || schedule->num_scheduled())) //ensure monitors always have a buffer |
752 | 98 | { | 95 | { |
753 | 99 | map->send_buffer(it->buffer->id()); | ||
754 | 100 | it = onscreen_buffers.erase(it); | 96 | it = onscreen_buffers.erase(it); |
755 | 101 | } | 97 | } |
756 | 102 | else | 98 | else |
757 | 103 | 99 | ||
758 | === modified file 'src/server/compositor/multi_monitor_arbiter.h' | |||
759 | --- src/server/compositor/multi_monitor_arbiter.h 2017-05-25 05:49:36 +0000 | |||
760 | +++ src/server/compositor/multi_monitor_arbiter.h 2017-07-18 03:23:56 +0000 | |||
761 | @@ -38,7 +38,6 @@ | |||
762 | 38 | { | 38 | { |
763 | 39 | public: | 39 | public: |
764 | 40 | MultiMonitorArbiter( | 40 | MultiMonitorArbiter( |
765 | 41 | std::shared_ptr<frontend::ClientBuffers> const& map, | ||
766 | 42 | std::shared_ptr<Schedule> const& schedule); | 41 | std::shared_ptr<Schedule> const& schedule); |
767 | 43 | ~MultiMonitorArbiter(); | 42 | ~MultiMonitorArbiter(); |
768 | 44 | 43 | ||
769 | @@ -56,7 +55,6 @@ | |||
770 | 56 | void clean_onscreen_buffers(std::lock_guard<std::mutex> const&); | 55 | void clean_onscreen_buffers(std::lock_guard<std::mutex> const&); |
771 | 57 | 56 | ||
772 | 58 | std::mutex mutable mutex; | 57 | std::mutex mutable mutex; |
773 | 59 | std::shared_ptr<frontend::ClientBuffers> const map; | ||
774 | 60 | struct ScheduleEntry | 58 | struct ScheduleEntry |
775 | 61 | { | 59 | { |
776 | 62 | ScheduleEntry(std::shared_ptr<graphics::Buffer> const& buffer, unsigned int use_count) : | 60 | ScheduleEntry(std::shared_ptr<graphics::Buffer> const& buffer, unsigned int use_count) : |
777 | 63 | 61 | ||
778 | === modified file 'src/server/compositor/stream.cpp' | |||
779 | --- src/server/compositor/stream.cpp 2017-05-25 05:49:36 +0000 | |||
780 | +++ src/server/compositor/stream.cpp 2017-07-18 03:23:56 +0000 | |||
781 | @@ -21,7 +21,6 @@ | |||
782 | 21 | #include "queueing_schedule.h" | 21 | #include "queueing_schedule.h" |
783 | 22 | #include "dropping_schedule.h" | 22 | #include "dropping_schedule.h" |
784 | 23 | #include "temporary_buffers.h" | 23 | #include "temporary_buffers.h" |
785 | 24 | #include "mir/frontend/client_buffers.h" | ||
786 | 25 | #include "mir/graphics/buffer.h" | 24 | #include "mir/graphics/buffer.h" |
787 | 26 | #include <boost/throw_exception.hpp> | 25 | #include <boost/throw_exception.hpp> |
788 | 27 | 26 | ||
789 | @@ -37,22 +36,17 @@ | |||
790 | 37 | }; | 36 | }; |
791 | 38 | 37 | ||
792 | 39 | mc::Stream::Stream( | 38 | mc::Stream::Stream( |
794 | 40 | std::shared_ptr<frontend::ClientBuffers> map, geom::Size size, MirPixelFormat pf) : | 39 | geom::Size size, MirPixelFormat pf) : |
795 | 41 | schedule_mode(ScheduleMode::Queueing), | 40 | schedule_mode(ScheduleMode::Queueing), |
796 | 42 | schedule(std::make_shared<mc::QueueingSchedule>()), | 41 | schedule(std::make_shared<mc::QueueingSchedule>()), |
799 | 43 | buffers(map), | 42 | arbiter(std::make_shared<mc::MultiMonitorArbiter>(schedule)), |
798 | 44 | arbiter(std::make_shared<mc::MultiMonitorArbiter>(buffers, schedule)), | ||
800 | 45 | size(size), | 43 | size(size), |
801 | 46 | pf(pf), | 44 | pf(pf), |
802 | 47 | first_frame_posted(false) | 45 | first_frame_posted(false) |
803 | 48 | { | 46 | { |
804 | 49 | } | 47 | } |
805 | 50 | 48 | ||
811 | 51 | mc::Stream::~Stream() | 49 | mc::Stream::~Stream() = default; |
807 | 52 | { | ||
808 | 53 | while(schedule->num_scheduled()) | ||
809 | 54 | buffers->send_buffer(schedule->next_buffer()->id()); | ||
810 | 55 | } | ||
812 | 56 | 50 | ||
813 | 57 | unsigned int mc::Stream::client_owned_buffer_count(std::lock_guard<decltype(mutex)> const&) const | 51 | unsigned int mc::Stream::client_owned_buffer_count(std::lock_guard<decltype(mutex)> const&) const |
814 | 58 | { | 52 | { |
815 | @@ -72,9 +66,8 @@ | |||
816 | 72 | { | 66 | { |
817 | 73 | std::lock_guard<decltype(mutex)> lk(mutex); | 67 | std::lock_guard<decltype(mutex)> lk(mutex); |
818 | 74 | first_frame_posted = true; | 68 | first_frame_posted = true; |
819 | 75 | buffers->receive_buffer(buffer->id()); | ||
820 | 76 | deferred_io = schedule->schedule_nonblocking(buffers->get(buffer->id())); | ||
821 | 77 | pf = buffer->pixel_format(); | 69 | pf = buffer->pixel_format(); |
822 | 70 | deferred_io = schedule->schedule_nonblocking(buffer); | ||
823 | 78 | } | 71 | } |
824 | 79 | observers.frame_posted(1, buffer->size()); | 72 | observers.frame_posted(1, buffer->size()); |
825 | 80 | 73 | ||
826 | @@ -134,7 +127,7 @@ | |||
827 | 134 | std::lock_guard<decltype(mutex)> lk(mutex); | 127 | std::lock_guard<decltype(mutex)> lk(mutex); |
828 | 135 | if (dropping && schedule_mode == ScheduleMode::Queueing) | 128 | if (dropping && schedule_mode == ScheduleMode::Queueing) |
829 | 136 | { | 129 | { |
831 | 137 | transition_schedule(std::make_shared<mc::DroppingSchedule>(buffers), lk); | 130 | transition_schedule(std::make_shared<mc::DroppingSchedule>(), lk); |
832 | 138 | schedule_mode = ScheduleMode::Dropping; | 131 | schedule_mode = ScheduleMode::Dropping; |
833 | 139 | } | 132 | } |
834 | 140 | else if (!dropping && schedule_mode == ScheduleMode::Dropping) | 133 | else if (!dropping && schedule_mode == ScheduleMode::Dropping) |
835 | @@ -182,9 +175,6 @@ | |||
836 | 182 | transferred_buffers.pop_back(); | 175 | transferred_buffers.pop_back(); |
837 | 183 | } | 176 | } |
838 | 184 | 177 | ||
839 | 185 | for (auto &buffer : transferred_buffers) | ||
840 | 186 | buffers->send_buffer(buffer->id()); | ||
841 | 187 | |||
842 | 188 | arbiter->advance_schedule(); | 178 | arbiter->advance_schedule(); |
843 | 189 | } | 179 | } |
844 | 190 | 180 | ||
845 | @@ -214,15 +204,7 @@ | |||
846 | 214 | 204 | ||
847 | 215 | bool mc::Stream::suitable_for_cursor() const | 205 | bool mc::Stream::suitable_for_cursor() const |
848 | 216 | { | 206 | { |
859 | 217 | if (associated_buffers.empty()) | 207 | // We can't reasonably answer this question - |
860 | 218 | { | 208 | // Suitability for cursor use is a per-buffer property, not a per-stream property. |
851 | 219 | return true; | ||
852 | 220 | } | ||
853 | 221 | else | ||
854 | 222 | { | ||
855 | 223 | for (auto it : associated_buffers) | ||
856 | 224 | if (buffers->get(it)->pixel_format() != mir_pixel_format_argb_8888) | ||
857 | 225 | return false; | ||
858 | 226 | } | ||
861 | 227 | return true; | 209 | return true; |
862 | 228 | } | 210 | } |
863 | 229 | 211 | ||
864 | === modified file 'src/server/compositor/stream.h' | |||
865 | --- src/server/compositor/stream.h 2017-05-22 11:53:51 +0000 | |||
866 | +++ src/server/compositor/stream.h 2017-07-18 03:23:56 +0000 | |||
867 | @@ -39,7 +39,7 @@ | |||
868 | 39 | class Stream : public BufferStream | 39 | class Stream : public BufferStream |
869 | 40 | { | 40 | { |
870 | 41 | public: | 41 | public: |
872 | 42 | Stream(std::shared_ptr<frontend::ClientBuffers>, geometry::Size sz, MirPixelFormat format); | 42 | Stream(geometry::Size sz, MirPixelFormat format); |
873 | 43 | ~Stream(); | 43 | ~Stream(); |
874 | 44 | 44 | ||
875 | 45 | void submit_buffer(std::shared_ptr<graphics::Buffer> const& buffer) override; | 45 | void submit_buffer(std::shared_ptr<graphics::Buffer> const& buffer) override; |
876 | @@ -68,7 +68,6 @@ | |||
877 | 68 | std::mutex mutable mutex; | 68 | std::mutex mutable mutex; |
878 | 69 | ScheduleMode schedule_mode; | 69 | ScheduleMode schedule_mode; |
879 | 70 | std::shared_ptr<Schedule> schedule; | 70 | std::shared_ptr<Schedule> schedule; |
880 | 71 | std::shared_ptr<frontend::ClientBuffers> const buffers; | ||
881 | 72 | std::shared_ptr<MultiMonitorArbiter> const arbiter; | 71 | std::shared_ptr<MultiMonitorArbiter> const arbiter; |
882 | 73 | geometry::Size size; | 72 | geometry::Size size; |
883 | 74 | MirPixelFormat pf; | 73 | MirPixelFormat pf; |
884 | 75 | 74 | ||
885 | === modified file 'src/server/frontend/default_ipc_factory.cpp' | |||
886 | --- src/server/frontend/default_ipc_factory.cpp 2017-05-08 03:04:26 +0000 | |||
887 | +++ src/server/frontend/default_ipc_factory.cpp 2017-07-18 03:23:56 +0000 | |||
888 | @@ -26,6 +26,7 @@ | |||
889 | 26 | #include "resource_cache.h" | 26 | #include "resource_cache.h" |
890 | 27 | #include "mir/frontend/session_authorizer.h" | 27 | #include "mir/frontend/session_authorizer.h" |
891 | 28 | #include "mir/frontend/event_sink.h" | 28 | #include "mir/frontend/event_sink.h" |
892 | 29 | #include "event_sink_factory.h" | ||
893 | 29 | #include "mir/graphics/graphic_buffer_allocator.h" | 30 | #include "mir/graphics/graphic_buffer_allocator.h" |
894 | 30 | #include "mir/cookie/authority.h" | 31 | #include "mir/cookie/authority.h" |
895 | 31 | 32 | ||
896 | @@ -150,5 +151,6 @@ | |||
897 | 150 | anr_detector, | 151 | anr_detector, |
898 | 151 | cookie_authority, | 152 | cookie_authority, |
899 | 152 | input_changer, | 153 | input_changer, |
901 | 153 | extensions); | 154 | extensions, |
902 | 155 | buffer_allocator); | ||
903 | 154 | } | 156 | } |
904 | 155 | 157 | ||
905 | === modified file 'src/server/frontend/event_sender.cpp' | |||
906 | --- src/server/frontend/event_sender.cpp 2017-05-08 03:04:26 +0000 | |||
907 | +++ src/server/frontend/event_sender.cpp 2017-07-18 03:23:56 +0000 | |||
908 | @@ -143,14 +143,6 @@ | |||
909 | 143 | send_event_sequence(seq, {}); | 143 | send_event_sequence(seq, {}); |
910 | 144 | } | 144 | } |
911 | 145 | 145 | ||
912 | 146 | void mfd::EventSender::remove_buffer(graphics::Buffer& buffer) | ||
913 | 147 | { | ||
914 | 148 | mp::EventSequence seq; | ||
915 | 149 | auto request = seq.mutable_buffer_request(); | ||
916 | 150 | request->set_operation(mir::protobuf::BufferOperation::remove); | ||
917 | 151 | send_buffer(seq, buffer, mg::BufferIpcMsgType::update_msg); | ||
918 | 152 | } | ||
919 | 153 | |||
920 | 154 | void mfd::EventSender::update_buffer(graphics::Buffer& buffer) | 146 | void mfd::EventSender::update_buffer(graphics::Buffer& buffer) |
921 | 155 | { | 147 | { |
922 | 156 | mp::EventSequence seq; | 148 | mp::EventSequence seq; |
923 | 157 | 149 | ||
924 | === modified file 'src/server/frontend/event_sender.h' | |||
925 | --- src/server/frontend/event_sender.h 2017-05-08 03:04:26 +0000 | |||
926 | +++ src/server/frontend/event_sender.h 2017-07-18 03:23:56 +0000 | |||
927 | @@ -52,7 +52,6 @@ | |||
928 | 52 | void send_buffer(frontend::BufferStreamId id, graphics::Buffer& buffer, graphics::BufferIpcMsgType) override; | 52 | void send_buffer(frontend::BufferStreamId id, graphics::Buffer& buffer, graphics::BufferIpcMsgType) override; |
929 | 53 | void add_buffer(graphics::Buffer&) override; | 53 | void add_buffer(graphics::Buffer&) override; |
930 | 54 | void error_buffer(geometry::Size, MirPixelFormat, std::string const&) override; | 54 | void error_buffer(geometry::Size, MirPixelFormat, std::string const&) override; |
931 | 55 | void remove_buffer(graphics::Buffer&) override; | ||
932 | 56 | void update_buffer(graphics::Buffer&) override; | 55 | void update_buffer(graphics::Buffer&) override; |
933 | 57 | 56 | ||
934 | 58 | private: | 57 | private: |
935 | 59 | 58 | ||
936 | === modified file 'src/server/frontend/session_mediator.cpp' | |||
937 | --- src/server/frontend/session_mediator.cpp 2017-06-01 13:04:37 +0000 | |||
938 | +++ src/server/frontend/session_mediator.cpp 2017-07-18 03:23:56 +0000 | |||
939 | @@ -59,6 +59,7 @@ | |||
940 | 59 | #include "mir/fd.h" | 59 | #include "mir/fd.h" |
941 | 60 | #include "mir/cookie/authority.h" | 60 | #include "mir/cookie/authority.h" |
942 | 61 | #include "mir/module_properties.h" | 61 | #include "mir/module_properties.h" |
943 | 62 | #include "mir/graphics/graphic_buffer_allocator.h" | ||
944 | 62 | 63 | ||
945 | 63 | #include "mir/geometry/rectangles.h" | 64 | #include "mir/geometry/rectangles.h" |
946 | 64 | #include "protobuf_buffer_packer.h" | 65 | #include "protobuf_buffer_packer.h" |
947 | @@ -110,7 +111,8 @@ | |||
948 | 110 | std::shared_ptr<scene::ApplicationNotRespondingDetector> const& anr_detector, | 111 | std::shared_ptr<scene::ApplicationNotRespondingDetector> const& anr_detector, |
949 | 111 | std::shared_ptr<mir::cookie::Authority> const& cookie_authority, | 112 | std::shared_ptr<mir::cookie::Authority> const& cookie_authority, |
950 | 112 | std::shared_ptr<mf::InputConfigurationChanger> const& input_changer, | 113 | std::shared_ptr<mf::InputConfigurationChanger> const& input_changer, |
952 | 113 | std::vector<mir::ExtensionDescription> const& extensions) : | 114 | std::vector<mir::ExtensionDescription> const& extensions, |
953 | 115 | std::shared_ptr<mg::GraphicBufferAllocator> const& allocator) : | ||
954 | 114 | client_pid_(0), | 116 | client_pid_(0), |
955 | 115 | shell(shell), | 117 | shell(shell), |
956 | 116 | ipc_operations(ipc_operations), | 118 | ipc_operations(ipc_operations), |
957 | @@ -128,7 +130,8 @@ | |||
958 | 128 | anr_detector{anr_detector}, | 130 | anr_detector{anr_detector}, |
959 | 129 | cookie_authority(cookie_authority), | 131 | cookie_authority(cookie_authority), |
960 | 130 | input_changer(input_changer), | 132 | input_changer(input_changer), |
962 | 131 | extensions(extensions) | 133 | extensions(extensions), |
963 | 134 | allocator{allocator} | ||
964 | 132 | { | 135 | { |
965 | 133 | } | 136 | } |
966 | 134 | 137 | ||
967 | @@ -374,6 +377,58 @@ | |||
968 | 374 | buffering_sender->uncork(); | 377 | buffering_sender->uncork(); |
969 | 375 | } | 378 | } |
970 | 376 | 379 | ||
971 | 380 | namespace | ||
972 | 381 | { | ||
973 | 382 | class AutoSendBuffer : public mg::Buffer | ||
974 | 383 | { | ||
975 | 384 | public: | ||
976 | 385 | AutoSendBuffer( | ||
977 | 386 | std::shared_ptr<mg::Buffer> const& wrapped, | ||
978 | 387 | std::weak_ptr<mf::BufferSink> const& sink) | ||
979 | 388 | : buffer{wrapped}, | ||
980 | 389 | sink{sink} | ||
981 | 390 | { | ||
982 | 391 | } | ||
983 | 392 | ~AutoSendBuffer() | ||
984 | 393 | { | ||
985 | 394 | if (auto live_sink = sink.lock()) | ||
986 | 395 | { | ||
987 | 396 | live_sink->update_buffer(*buffer); | ||
988 | 397 | } | ||
989 | 398 | } | ||
990 | 399 | |||
991 | 400 | std::shared_ptr<mir::graphics::NativeBuffer> native_buffer_handle() const override | ||
992 | 401 | { | ||
993 | 402 | return buffer->native_buffer_handle(); | ||
994 | 403 | } | ||
995 | 404 | |||
996 | 405 | mir::graphics::BufferID id() const override | ||
997 | 406 | { | ||
998 | 407 | return buffer->id(); | ||
999 | 408 | } | ||
1000 | 409 | |||
1001 | 410 | mir::geometry::Size size() const override | ||
1002 | 411 | { | ||
1003 | 412 | return buffer->size(); | ||
1004 | 413 | } | ||
1005 | 414 | |||
1006 | 415 | MirPixelFormat pixel_format() const override | ||
1007 | 416 | { | ||
1008 | 417 | return buffer->pixel_format(); | ||
1009 | 418 | } | ||
1010 | 419 | |||
1011 | 420 | mir::graphics::NativeBufferBase *native_buffer_base() override | ||
1012 | 421 | { | ||
1013 | 422 | return buffer->native_buffer_base(); | ||
1014 | 423 | } | ||
1015 | 424 | |||
1016 | 425 | private: | ||
1017 | 426 | std::shared_ptr<mg::Buffer> const buffer; | ||
1018 | 427 | std::weak_ptr<mf::BufferSink> const sink; | ||
1019 | 428 | }; | ||
1020 | 429 | |||
1021 | 430 | } | ||
1022 | 431 | |||
1023 | 377 | void mf::SessionMediator::submit_buffer( | 432 | void mf::SessionMediator::submit_buffer( |
1024 | 378 | mir::protobuf::BufferRequest const* request, | 433 | mir::protobuf::BufferRequest const* request, |
1025 | 379 | mir::protobuf::Void*, | 434 | mir::protobuf::Void*, |
1026 | @@ -388,15 +443,37 @@ | |||
1027 | 388 | auto stream = session->get_buffer_stream(stream_id); | 443 | auto stream = session->get_buffer_stream(stream_id); |
1028 | 389 | 444 | ||
1029 | 390 | mfd::ProtobufBufferPacker request_msg{const_cast<mir::protobuf::Buffer*>(&request->buffer())}; | 445 | mfd::ProtobufBufferPacker request_msg{const_cast<mir::protobuf::Buffer*>(&request->buffer())}; |
1031 | 391 | auto b = session->get_buffer(buffer_id); | 446 | auto b = buffer_cache.at(buffer_id); |
1032 | 392 | ipc_operations->unpack_buffer(request_msg, *b); | 447 | ipc_operations->unpack_buffer(request_msg, *b); |
1033 | 393 | 448 | ||
1035 | 394 | stream->submit_buffer(b); | 449 | stream->submit_buffer(std::make_shared<AutoSendBuffer>(b, event_sink)); |
1036 | 395 | 450 | ||
1037 | 396 | done->Run(); | 451 | done->Run(); |
1038 | 397 | } | 452 | } |
1039 | 398 | 453 | ||
1041 | 399 | void mf::SessionMediator::allocate_buffers( | 454 | namespace |
1042 | 455 | { | ||
1043 | 456 | bool validate_buffer_request(mir::protobuf::BufferStreamParameters const& req) | ||
1044 | 457 | { | ||
1045 | 458 | // A valid buffer request has either flags & native_format set | ||
1046 | 459 | // or buffer_usage & pixel_format set, not both. | ||
1047 | 460 | return | ||
1048 | 461 | ( | ||
1049 | 462 | req.has_pixel_format() && | ||
1050 | 463 | req.has_buffer_usage() && | ||
1051 | 464 | !req.has_native_format() && | ||
1052 | 465 | !req.has_flags() | ||
1053 | 466 | ) || | ||
1054 | 467 | ( | ||
1055 | 468 | !req.has_pixel_format() && | ||
1056 | 469 | !req.has_buffer_usage() && | ||
1057 | 470 | req.has_native_format() && | ||
1058 | 471 | req.has_flags() | ||
1059 | 472 | ); | ||
1060 | 473 | } | ||
1061 | 474 | } | ||
1062 | 475 | |||
1063 | 476 | void mf::SessionMediator::allocate_buffers( | ||
1064 | 400 | mir::protobuf::BufferAllocation const* request, | 477 | mir::protobuf::BufferAllocation const* request, |
1065 | 401 | mir::protobuf::Void*, | 478 | mir::protobuf::Void*, |
1066 | 402 | google::protobuf::Closure* done) | 479 | google::protobuf::Closure* done) |
1067 | @@ -409,36 +486,54 @@ | |||
1068 | 409 | for (auto i = 0; i < request->buffer_requests().size(); i++) | 486 | for (auto i = 0; i < request->buffer_requests().size(); i++) |
1069 | 410 | { | 487 | { |
1070 | 411 | auto const& req = request->buffer_requests(i); | 488 | auto const& req = request->buffer_requests(i); |
1071 | 489 | std::shared_ptr<mg::Buffer> buffer; | ||
1072 | 490 | try | ||
1073 | 491 | { | ||
1074 | 492 | if (!validate_buffer_request(req)) | ||
1075 | 493 | { | ||
1076 | 494 | BOOST_THROW_EXCEPTION(std::logic_error("Invalid buffer request")); | ||
1077 | 495 | } | ||
1078 | 412 | 496 | ||
1090 | 413 | mg::BufferID id; | 497 | if (req.has_flags() && req.has_native_format()) |
1080 | 414 | if (req.has_flags() && req.has_native_format()) | ||
1081 | 415 | { | ||
1082 | 416 | id = session->create_buffer({req.width(), req.height()}, req.native_format(), req.flags()); | ||
1083 | 417 | } | ||
1084 | 418 | else if (req.has_buffer_usage() && req.has_pixel_format()) | ||
1085 | 419 | { | ||
1086 | 420 | auto const usage = static_cast<mg::BufferUsage>(req.buffer_usage()); | ||
1087 | 421 | geom::Size const size{req.width(), req.height()}; | ||
1088 | 422 | auto const pf = static_cast<MirPixelFormat>(req.pixel_format()); | ||
1089 | 423 | if (usage == mg::BufferUsage::software) | ||
1091 | 424 | { | 498 | { |
1093 | 425 | id = session->create_buffer(size, pf); | 499 | buffer = allocator->alloc_buffer( |
1094 | 500 | {req.width(), req.height()}, | ||
1095 | 501 | req.native_format(), | ||
1096 | 502 | req.flags()); | ||
1097 | 426 | } | 503 | } |
1098 | 427 | else | 504 | else |
1099 | 428 | { | 505 | { |
1113 | 429 | //legacy route, server-selected pf and usage | 506 | auto const usage = static_cast<mg::BufferUsage>(req.buffer_usage()); |
1114 | 430 | id = session->create_buffer(mg::BufferProperties{size, pf, mg::BufferUsage::hardware}); | 507 | geom::Size const size{req.width(), req.height()}; |
1115 | 431 | } | 508 | auto const pf = static_cast<MirPixelFormat>(req.pixel_format()); |
1116 | 432 | } | 509 | if (usage == mg::BufferUsage::software) |
1117 | 433 | else | 510 | { |
1118 | 434 | { | 511 | buffer = allocator->alloc_software_buffer(size, pf); |
1119 | 435 | BOOST_THROW_EXCEPTION(std::logic_error("Invalid buffer request")); | 512 | } |
1120 | 436 | } | 513 | else |
1121 | 437 | 514 | { | |
1122 | 438 | if (request->has_id()) | 515 | //legacy route, server-selected pf and usage |
1123 | 439 | { | 516 | buffer = |
1124 | 440 | auto stream = session->get_buffer_stream(mf::BufferStreamId(request->id().value())); | 517 | allocator->alloc_buffer(mg::BufferProperties{size, pf, mg::BufferUsage::hardware}); |
1125 | 441 | stream->associate_buffer(id); | 518 | } |
1126 | 519 | } | ||
1127 | 520 | |||
1128 | 521 | if (request->has_id()) | ||
1129 | 522 | { | ||
1130 | 523 | auto stream = session->get_buffer_stream(mf::BufferStreamId(request->id().value())); | ||
1131 | 524 | stream->associate_buffer(buffer->id()); | ||
1132 | 525 | } | ||
1133 | 526 | |||
1134 | 527 | // TODO: Throw if insert fails (duplicate ID)? | ||
1135 | 528 | buffer_cache.insert(std::make_pair(buffer->id(), buffer)); | ||
1136 | 529 | event_sink->add_buffer(*buffer); | ||
1137 | 530 | } | ||
1138 | 531 | catch (std::exception const& err) | ||
1139 | 532 | { | ||
1140 | 533 | event_sink->error_buffer( | ||
1141 | 534 | geom::Size{req.width(), req.height()}, | ||
1142 | 535 | static_cast<MirPixelFormat>(req.pixel_format()), | ||
1143 | 536 | err.what()); | ||
1144 | 442 | } | 537 | } |
1145 | 443 | } | 538 | } |
1146 | 444 | done->Run(); | 539 | done->Run(); |
1147 | @@ -473,7 +568,7 @@ | |||
1148 | 473 | for (auto i = 0; i < request->buffers().size(); i++) | 568 | for (auto i = 0; i < request->buffers().size(); i++) |
1149 | 474 | { | 569 | { |
1150 | 475 | mg::BufferID buffer_id{static_cast<uint32_t>(request->buffers(i).buffer_id())}; | 570 | mg::BufferID buffer_id{static_cast<uint32_t>(request->buffers(i).buffer_id())}; |
1152 | 476 | session->destroy_buffer(buffer_id); | 571 | buffer_cache.erase(buffer_id); |
1153 | 477 | } | 572 | } |
1154 | 478 | done->Run(); | 573 | done->Run(); |
1155 | 479 | } | 574 | } |
1156 | @@ -869,7 +964,7 @@ | |||
1157 | 869 | { | 964 | { |
1158 | 870 | auto session = weak_session.lock(); | 965 | auto session = weak_session.lock(); |
1159 | 871 | ScreencastSessionId const screencast_session_id{request->id().value()}; | 966 | ScreencastSessionId const screencast_session_id{request->id().value()}; |
1161 | 872 | auto buffer = session->get_buffer(mg::BufferID{request->buffer_id()}); | 967 | auto buffer = buffer_cache.at(mg::BufferID{request->buffer_id()}); |
1162 | 873 | screencast->capture(screencast_session_id, buffer); | 968 | screencast->capture(screencast_session_id, buffer); |
1163 | 874 | done->Run(); | 969 | done->Run(); |
1164 | 875 | } | 970 | } |
1165 | 876 | 971 | ||
1166 | === modified file 'src/server/frontend/session_mediator.h' | |||
1167 | --- src/server/frontend/session_mediator.h 2017-05-08 03:04:26 +0000 | |||
1168 | +++ src/server/frontend/session_mediator.h 2017-07-18 03:23:56 +0000 | |||
1169 | @@ -28,6 +28,7 @@ | |||
1170 | 28 | #include "mir/frontend/surface_id.h" | 28 | #include "mir/frontend/surface_id.h" |
1171 | 29 | #include "mir/frontend/buffer_stream_id.h" | 29 | #include "mir/frontend/buffer_stream_id.h" |
1172 | 30 | #include "mir/graphics/platform_ipc_operations.h" | 30 | #include "mir/graphics/platform_ipc_operations.h" |
1173 | 31 | #include "mir/graphics/buffer_id.h" | ||
1174 | 31 | #include "mir/protobuf/display_server_debug.h" | 32 | #include "mir/protobuf/display_server_debug.h" |
1175 | 32 | #include "mir_toolkit/common.h" | 33 | #include "mir_toolkit/common.h" |
1176 | 33 | 34 | ||
1177 | @@ -77,6 +78,7 @@ | |||
1178 | 77 | class PromptSession; | 78 | class PromptSession; |
1179 | 78 | class BufferStream; | 79 | class BufferStream; |
1180 | 79 | class InputConfigurationChanger; | 80 | class InputConfigurationChanger; |
1181 | 81 | class BufferMap; | ||
1182 | 80 | 82 | ||
1183 | 81 | namespace detail | 83 | namespace detail |
1184 | 82 | { | 84 | { |
1185 | @@ -124,8 +126,8 @@ | |||
1186 | 124 | std::shared_ptr<scene::ApplicationNotRespondingDetector> const& anr_detector, | 126 | std::shared_ptr<scene::ApplicationNotRespondingDetector> const& anr_detector, |
1187 | 125 | std::shared_ptr<cookie::Authority> const& cookie_authority, | 127 | std::shared_ptr<cookie::Authority> const& cookie_authority, |
1188 | 126 | std::shared_ptr<InputConfigurationChanger> const& input_changer, | 128 | std::shared_ptr<InputConfigurationChanger> const& input_changer, |
1191 | 127 | std::vector<mir::ExtensionDescription> const& extensions | 129 | std::vector<mir::ExtensionDescription> const& extensions, |
1192 | 128 | ); | 130 | std::shared_ptr<graphics::GraphicBufferAllocator> const& allocator); |
1193 | 129 | 131 | ||
1194 | 130 | ~SessionMediator() noexcept; | 132 | ~SessionMediator() noexcept; |
1195 | 131 | 133 | ||
1196 | @@ -299,6 +301,8 @@ | |||
1197 | 299 | std::shared_ptr<cookie::Authority> const cookie_authority; | 301 | std::shared_ptr<cookie::Authority> const cookie_authority; |
1198 | 300 | std::shared_ptr<InputConfigurationChanger> const input_changer; | 302 | std::shared_ptr<InputConfigurationChanger> const input_changer; |
1199 | 301 | std::vector<mir::ExtensionDescription> const extensions; | 303 | std::vector<mir::ExtensionDescription> const extensions; |
1200 | 304 | std::unordered_map<graphics::BufferID, std::shared_ptr<graphics::Buffer>> buffer_cache; | ||
1201 | 305 | std::shared_ptr<graphics::GraphicBufferAllocator> const allocator; | ||
1202 | 302 | 306 | ||
1203 | 303 | ScreencastBufferTracker screencast_buffer_tracker; | 307 | ScreencastBufferTracker screencast_buffer_tracker; |
1204 | 304 | 308 | ||
1205 | 305 | 309 | ||
1206 | === modified file 'src/server/scene/application_session.cpp' | |||
1207 | --- src/server/scene/application_session.cpp 2017-05-25 08:58:03 +0000 | |||
1208 | +++ src/server/scene/application_session.cpp 2017-07-18 03:23:56 +0000 | |||
1209 | @@ -20,7 +20,6 @@ | |||
1210 | 20 | #include "snapshot_strategy.h" | 20 | #include "snapshot_strategy.h" |
1211 | 21 | #include "default_session_container.h" | 21 | #include "default_session_container.h" |
1212 | 22 | #include "output_properties_cache.h" | 22 | #include "output_properties_cache.h" |
1213 | 23 | #include "../compositor/buffer_map.h" | ||
1214 | 24 | 23 | ||
1215 | 25 | #include "mir/scene/surface.h" | 24 | #include "mir/scene/surface.h" |
1216 | 26 | #include "mir/scene/surface_event_source.h" | 25 | #include "mir/scene/surface_event_source.h" |
1217 | @@ -68,7 +67,6 @@ | |||
1218 | 68 | snapshot_strategy(snapshot_strategy), | 67 | snapshot_strategy(snapshot_strategy), |
1219 | 69 | session_listener(session_listener), | 68 | session_listener(session_listener), |
1220 | 70 | event_sink(sink), | 69 | event_sink(sink), |
1221 | 71 | buffers(buffer_stream_factory->create_buffer_map(sink)), | ||
1222 | 72 | gralloc(gralloc), | 70 | gralloc(gralloc), |
1223 | 73 | next_surface_id(0) | 71 | next_surface_id(0) |
1224 | 74 | { | 72 | { |
1225 | @@ -372,7 +370,7 @@ | |||
1226 | 372 | mf::BufferStreamId ms::ApplicationSession::create_buffer_stream(mg::BufferProperties const& props) | 370 | mf::BufferStreamId ms::ApplicationSession::create_buffer_stream(mg::BufferProperties const& props) |
1227 | 373 | { | 371 | { |
1228 | 374 | auto const id = static_cast<mf::BufferStreamId>(next_id().as_value()); | 372 | auto const id = static_cast<mf::BufferStreamId>(next_id().as_value()); |
1230 | 375 | auto stream = buffer_stream_factory->create_buffer_stream(id, buffers, props); | 373 | auto stream = buffer_stream_factory->create_buffer_stream(id, props); |
1231 | 376 | 374 | ||
1232 | 377 | std::unique_lock<std::mutex> lock(surfaces_and_streams_mutex); | 375 | std::unique_lock<std::mutex> lock(surfaces_and_streams_mutex); |
1233 | 378 | streams[id] = stream; | 376 | streams[id] = stream; |
1234 | @@ -429,56 +427,6 @@ | |||
1235 | 429 | surface_stack->remove_surface(surface); | 427 | surface_stack->remove_surface(surface); |
1236 | 430 | } | 428 | } |
1237 | 431 | 429 | ||
1238 | 432 | mg::BufferID ms::ApplicationSession::create_buffer(mg::BufferProperties const& properties) | ||
1239 | 433 | { | ||
1240 | 434 | try | ||
1241 | 435 | { | ||
1242 | 436 | return buffers->add_buffer(gralloc->alloc_buffer(properties)); | ||
1243 | 437 | } | ||
1244 | 438 | catch (std::exception& e) | ||
1245 | 439 | { | ||
1246 | 440 | event_sink->error_buffer(properties.size, properties.format, e.what()); | ||
1247 | 441 | throw; | ||
1248 | 442 | } | ||
1249 | 443 | } | ||
1250 | 444 | |||
1251 | 445 | mg::BufferID ms::ApplicationSession::create_buffer(mir::geometry::Size size, MirPixelFormat format) | ||
1252 | 446 | { | ||
1253 | 447 | try | ||
1254 | 448 | { | ||
1255 | 449 | return buffers->add_buffer(gralloc->alloc_software_buffer(size, format)); | ||
1256 | 450 | } | ||
1257 | 451 | catch (std::exception& e) | ||
1258 | 452 | { | ||
1259 | 453 | event_sink->error_buffer(size, format, e.what()); | ||
1260 | 454 | throw; | ||
1261 | 455 | } | ||
1262 | 456 | } | ||
1263 | 457 | |||
1264 | 458 | mg::BufferID ms::ApplicationSession::create_buffer( | ||
1265 | 459 | mir::geometry::Size size, uint32_t native_format, uint32_t native_flags) | ||
1266 | 460 | { | ||
1267 | 461 | try | ||
1268 | 462 | { | ||
1269 | 463 | return buffers->add_buffer(gralloc->alloc_buffer(size, native_format, native_flags)); | ||
1270 | 464 | } | ||
1271 | 465 | catch (std::exception& e) | ||
1272 | 466 | { | ||
1273 | 467 | event_sink->error_buffer(size, static_cast<MirPixelFormat>(native_format), e.what()); | ||
1274 | 468 | throw; | ||
1275 | 469 | } | ||
1276 | 470 | } | ||
1277 | 471 | |||
1278 | 472 | void ms::ApplicationSession::destroy_buffer(mg::BufferID id) | ||
1279 | 473 | { | ||
1280 | 474 | buffers->remove_buffer(id); | ||
1281 | 475 | } | ||
1282 | 476 | |||
1283 | 477 | std::shared_ptr<mg::Buffer> ms::ApplicationSession::get_buffer(mg::BufferID id) | ||
1284 | 478 | { | ||
1285 | 479 | return buffers->get(id); | ||
1286 | 480 | } | ||
1287 | 481 | |||
1288 | 482 | void ms::ApplicationSession::send_error(mir::ClientVisibleError const& error) | 430 | void ms::ApplicationSession::send_error(mir::ClientVisibleError const& error) |
1289 | 483 | { | 431 | { |
1290 | 484 | event_sink->handle_error(error); | 432 | event_sink->handle_error(error); |
1291 | 485 | 433 | ||
1292 | === modified file 'src/server/scene/application_session.h' | |||
1293 | --- src/server/scene/application_session.h 2017-05-08 03:04:26 +0000 | |||
1294 | +++ src/server/scene/application_session.h 2017-07-18 03:23:56 +0000 | |||
1295 | @@ -100,12 +100,6 @@ | |||
1296 | 100 | void destroy_buffer_stream(frontend::BufferStreamId stream) override; | 100 | void destroy_buffer_stream(frontend::BufferStreamId stream) override; |
1297 | 101 | void configure_streams(Surface& surface, std::vector<shell::StreamSpecification> const& config) override; | 101 | void configure_streams(Surface& surface, std::vector<shell::StreamSpecification> const& config) override; |
1298 | 102 | void destroy_surface(std::weak_ptr<Surface> const& surface) override; | 102 | void destroy_surface(std::weak_ptr<Surface> const& surface) override; |
1299 | 103 | |||
1300 | 104 | graphics::BufferID create_buffer(graphics::BufferProperties const& properties) override; | ||
1301 | 105 | graphics::BufferID create_buffer(geometry::Size, MirPixelFormat) override; | ||
1302 | 106 | graphics::BufferID create_buffer(geometry::Size, uint32_t native_format, uint32_t native_flags) override; | ||
1303 | 107 | void destroy_buffer(graphics::BufferID) override; | ||
1304 | 108 | std::shared_ptr<graphics::Buffer> get_buffer(graphics::BufferID) override; | ||
1305 | 109 | protected: | 103 | protected: |
1306 | 110 | ApplicationSession(ApplicationSession const&) = delete; | 104 | ApplicationSession(ApplicationSession const&) = delete; |
1307 | 111 | ApplicationSession& operator=(ApplicationSession const&) = delete; | 105 | ApplicationSession& operator=(ApplicationSession const&) = delete; |
1308 | @@ -119,7 +113,6 @@ | |||
1309 | 119 | std::shared_ptr<SnapshotStrategy> const snapshot_strategy; | 113 | std::shared_ptr<SnapshotStrategy> const snapshot_strategy; |
1310 | 120 | std::shared_ptr<SessionListener> const session_listener; | 114 | std::shared_ptr<SessionListener> const session_listener; |
1311 | 121 | std::shared_ptr<frontend::EventSink> const event_sink; | 115 | std::shared_ptr<frontend::EventSink> const event_sink; |
1312 | 122 | std::shared_ptr<frontend::ClientBuffers> const buffers; | ||
1313 | 123 | std::shared_ptr<graphics::GraphicBufferAllocator> const gralloc; | 116 | std::shared_ptr<graphics::GraphicBufferAllocator> const gralloc; |
1314 | 124 | 117 | ||
1315 | 125 | frontend::SurfaceId next_id(); | 118 | frontend::SurfaceId next_id(); |
1316 | 126 | 119 | ||
1317 | === modified file 'src/server/scene/global_event_sender.cpp' | |||
1318 | --- src/server/scene/global_event_sender.cpp 2017-05-08 03:04:26 +0000 | |||
1319 | +++ src/server/scene/global_event_sender.cpp 2017-07-18 03:23:56 +0000 | |||
1320 | @@ -67,10 +67,6 @@ | |||
1321 | 67 | { | 67 | { |
1322 | 68 | } | 68 | } |
1323 | 69 | 69 | ||
1324 | 70 | void ms::GlobalEventSender::remove_buffer(graphics::Buffer&) | ||
1325 | 71 | { | ||
1326 | 72 | } | ||
1327 | 73 | |||
1328 | 74 | void ms::GlobalEventSender::update_buffer(graphics::Buffer&) | 70 | void ms::GlobalEventSender::update_buffer(graphics::Buffer&) |
1329 | 75 | { | 71 | { |
1330 | 76 | } | 72 | } |
1331 | 77 | 73 | ||
1332 | === modified file 'src/server/scene/global_event_sender.h' | |||
1333 | --- src/server/scene/global_event_sender.h 2017-05-08 03:04:26 +0000 | |||
1334 | +++ src/server/scene/global_event_sender.h 2017-07-18 03:23:56 +0000 | |||
1335 | @@ -41,7 +41,6 @@ | |||
1336 | 41 | void send_ping(int32_t serial) override; | 41 | void send_ping(int32_t serial) override; |
1337 | 42 | void send_buffer(frontend::BufferStreamId id, graphics::Buffer& buffer, graphics::BufferIpcMsgType) override; | 42 | void send_buffer(frontend::BufferStreamId id, graphics::Buffer& buffer, graphics::BufferIpcMsgType) override; |
1338 | 43 | void add_buffer(graphics::Buffer&) override; | 43 | void add_buffer(graphics::Buffer&) override; |
1339 | 44 | void remove_buffer(graphics::Buffer&) override; | ||
1340 | 45 | void update_buffer(graphics::Buffer&) override; | 44 | void update_buffer(graphics::Buffer&) override; |
1341 | 46 | void error_buffer(geometry::Size, MirPixelFormat, std::string const&) override; | 45 | void error_buffer(geometry::Size, MirPixelFormat, std::string const&) override; |
1342 | 47 | private: | 46 | private: |
1343 | 48 | 47 | ||
1344 | === modified file 'src/server/shell/window_management_info.cpp' | |||
1345 | --- src/server/shell/window_management_info.cpp 2017-05-08 03:04:26 +0000 | |||
1346 | +++ src/server/shell/window_management_info.cpp 2017-07-18 03:23:56 +0000 | |||
1347 | @@ -24,6 +24,7 @@ | |||
1348 | 24 | 24 | ||
1349 | 25 | #include "mir/graphics/buffer.h" | 25 | #include "mir/graphics/buffer.h" |
1350 | 26 | #include "mir/renderer/sw/pixel_source.h" | 26 | #include "mir/renderer/sw/pixel_source.h" |
1351 | 27 | #include "mir/graphics/graphic_buffer_allocator.h" | ||
1352 | 27 | 28 | ||
1353 | 28 | #include <atomic> | 29 | #include <atomic> |
1354 | 29 | 30 | ||
1355 | @@ -173,54 +174,40 @@ | |||
1356 | 173 | { | 174 | { |
1357 | 174 | AllocatingPainter( | 175 | AllocatingPainter( |
1358 | 175 | std::shared_ptr<frontend::BufferStream> const& buffer_stream, | 176 | std::shared_ptr<frontend::BufferStream> const& buffer_stream, |
1360 | 176 | std::shared_ptr<scene::Session> const& session, | 177 | mg::GraphicBufferAllocator& allocator, |
1361 | 177 | Size size) : | 178 | Size size) : |
1362 | 178 | buffer_stream(buffer_stream), | 179 | buffer_stream(buffer_stream), |
1371 | 179 | session(session), | 180 | front_buffer{allocator.alloc_software_buffer(size, buffer_stream->pixel_format())}, |
1372 | 180 | properties({ | 181 | back_buffer{allocator.alloc_software_buffer(size, buffer_stream->pixel_format())} |
1365 | 181 | size, | ||
1366 | 182 | buffer_stream->pixel_format(), | ||
1367 | 183 | mg::BufferUsage::software | ||
1368 | 184 | }), | ||
1369 | 185 | front_buffer(session->create_buffer(properties)), | ||
1370 | 186 | back_buffer(session->create_buffer(properties)) | ||
1373 | 187 | { | 182 | { |
1374 | 188 | } | 183 | } |
1375 | 189 | 184 | ||
1376 | 190 | void paint(int intensity) override | 185 | void paint(int intensity) override |
1377 | 191 | { | 186 | { |
1383 | 192 | auto buffer = session->get_buffer(back_buffer); | 187 | auto const format = back_buffer->pixel_format(); |
1384 | 193 | 188 | auto const sz = back_buffer->size().height.as_int() * | |
1385 | 194 | auto const format = buffer->pixel_format(); | 189 | back_buffer->size().width.as_int() * MIR_BYTES_PER_PIXEL(format); |
1381 | 195 | auto const sz = buffer->size().height.as_int() * | ||
1382 | 196 | buffer->size().width.as_int() * MIR_BYTES_PER_PIXEL(format); | ||
1386 | 197 | std::vector<unsigned char> pixels(sz, intensity); | 190 | std::vector<unsigned char> pixels(sz, intensity); |
1388 | 198 | if (auto pixel_source = dynamic_cast<mrs::PixelSource*>(buffer->native_buffer_base())) | 191 | if (auto pixel_source = dynamic_cast<mrs::PixelSource*>(back_buffer->native_buffer_base())) |
1389 | 199 | pixel_source->write(pixels.data(), sz); | 192 | pixel_source->write(pixels.data(), sz); |
1391 | 200 | buffer_stream->submit_buffer(buffer); | 193 | buffer_stream->submit_buffer(back_buffer); |
1392 | 201 | 194 | ||
1393 | 202 | std::swap(front_buffer, back_buffer); | 195 | std::swap(front_buffer, back_buffer); |
1394 | 203 | } | 196 | } |
1395 | 204 | 197 | ||
1396 | 205 | ~AllocatingPainter() | ||
1397 | 206 | { | ||
1398 | 207 | session->destroy_buffer(front_buffer); | ||
1399 | 208 | session->destroy_buffer(back_buffer); | ||
1400 | 209 | } | ||
1401 | 210 | |||
1402 | 211 | std::shared_ptr<frontend::BufferStream> const buffer_stream; | 198 | std::shared_ptr<frontend::BufferStream> const buffer_stream; |
1403 | 212 | std::shared_ptr<scene::Session> const session; | 199 | std::shared_ptr<scene::Session> const session; |
1404 | 213 | mg::BufferProperties properties; | 200 | mg::BufferProperties properties; |
1407 | 214 | mg::BufferID front_buffer; | 201 | std::shared_ptr<mg::Buffer> front_buffer; |
1408 | 215 | mg::BufferID back_buffer; | 202 | std::shared_ptr<mg::Buffer> back_buffer; |
1409 | 216 | }; | 203 | }; |
1410 | 217 | 204 | ||
1411 | 218 | void msh::SurfaceInfo::init_titlebar( | 205 | void msh::SurfaceInfo::init_titlebar( |
1413 | 219 | std::shared_ptr<scene::Session> const& session, | 206 | mg::GraphicBufferAllocator& allocator, |
1414 | 220 | std::shared_ptr<scene::Surface> const& surface) | 207 | std::shared_ptr<scene::Surface> const& surface) |
1415 | 221 | { | 208 | { |
1416 | 222 | auto stream = surface->primary_buffer_stream(); | 209 | auto stream = surface->primary_buffer_stream(); |
1418 | 223 | stream_painter = std::make_shared<AllocatingPainter>(stream, session, surface->size()); | 210 | stream_painter = std::make_shared<AllocatingPainter>(stream, allocator, surface->size()); |
1419 | 224 | } | 211 | } |
1420 | 225 | 212 | ||
1421 | 226 | void msh::SurfaceInfo::paint_titlebar(int intensity) | 213 | void msh::SurfaceInfo::paint_titlebar(int intensity) |
1422 | 227 | 214 | ||
1423 | === modified file 'tests/include/mir/test/doubles/mock_event_sink.h' | |||
1424 | --- tests/include/mir/test/doubles/mock_event_sink.h 2017-05-08 03:04:26 +0000 | |||
1425 | +++ tests/include/mir/test/doubles/mock_event_sink.h 2017-07-18 03:23:56 +0000 | |||
1426 | @@ -42,7 +42,6 @@ | |||
1427 | 42 | MOCK_METHOD1(send_ping, void(int32_t)); | 42 | MOCK_METHOD1(send_ping, void(int32_t)); |
1428 | 43 | MOCK_METHOD3(send_buffer, void(frontend::BufferStreamId, graphics::Buffer&, graphics::BufferIpcMsgType)); | 43 | MOCK_METHOD3(send_buffer, void(frontend::BufferStreamId, graphics::Buffer&, graphics::BufferIpcMsgType)); |
1429 | 44 | MOCK_METHOD1(add_buffer, void(graphics::Buffer&)); | 44 | MOCK_METHOD1(add_buffer, void(graphics::Buffer&)); |
1430 | 45 | MOCK_METHOD1(remove_buffer, void(graphics::Buffer&)); | ||
1431 | 46 | MOCK_METHOD1(update_buffer, void(graphics::Buffer&)); | 45 | MOCK_METHOD1(update_buffer, void(graphics::Buffer&)); |
1432 | 47 | MOCK_METHOD3(error_buffer, void(geometry::Size, MirPixelFormat, std::string const&)); | 46 | MOCK_METHOD3(error_buffer, void(geometry::Size, MirPixelFormat, std::string const&)); |
1433 | 48 | MOCK_METHOD1(handle_input_config_change, void(MirInputConfig const&)); | 47 | MOCK_METHOD1(handle_input_config_change, void(MirInputConfig const&)); |
1434 | 49 | 48 | ||
1435 | === modified file 'tests/include/mir/test/doubles/null_event_sink.h' | |||
1436 | --- tests/include/mir/test/doubles/null_event_sink.h 2017-05-08 03:04:26 +0000 | |||
1437 | +++ tests/include/mir/test/doubles/null_event_sink.h 2017-07-18 03:23:56 +0000 | |||
1438 | @@ -44,7 +44,6 @@ | |||
1439 | 44 | void send_buffer(frontend::BufferStreamId, graphics::Buffer&, graphics::BufferIpcMsgType) override {} | 44 | void send_buffer(frontend::BufferStreamId, graphics::Buffer&, graphics::BufferIpcMsgType) override {} |
1440 | 45 | void handle_input_config_change(MirInputConfig const&) override {} | 45 | void handle_input_config_change(MirInputConfig const&) override {} |
1441 | 46 | void add_buffer(graphics::Buffer&) override {} | 46 | void add_buffer(graphics::Buffer&) override {} |
1442 | 47 | void remove_buffer(graphics::Buffer&) override {} | ||
1443 | 48 | void update_buffer(graphics::Buffer&) override {} | 47 | void update_buffer(graphics::Buffer&) override {} |
1444 | 49 | void error_buffer(geometry::Size, MirPixelFormat, std::string const&) override {} | 48 | void error_buffer(geometry::Size, MirPixelFormat, std::string const&) override {} |
1445 | 50 | }; | 49 | }; |
1446 | 51 | 50 | ||
1447 | === modified file 'tests/include/mir/test/doubles/stub_buffer_stream_factory.h' | |||
1448 | --- tests/include/mir/test/doubles/stub_buffer_stream_factory.h 2017-05-08 03:04:26 +0000 | |||
1449 | +++ tests/include/mir/test/doubles/stub_buffer_stream_factory.h 2017-07-18 03:23:56 +0000 | |||
1450 | @@ -19,7 +19,6 @@ | |||
1451 | 19 | #ifndef MIR_TEST_DOUBLES_STUB_BUFFER_STREAM_FACTORY_H_ | 19 | #ifndef MIR_TEST_DOUBLES_STUB_BUFFER_STREAM_FACTORY_H_ |
1452 | 20 | #define MIR_TEST_DOUBLES_STUB_BUFFER_STREAM_FACTORY_H_ | 20 | #define MIR_TEST_DOUBLES_STUB_BUFFER_STREAM_FACTORY_H_ |
1453 | 21 | 21 | ||
1454 | 22 | #include "mir/frontend/client_buffers.h" | ||
1455 | 23 | #include "mir/scene/buffer_stream_factory.h" | 22 | #include "mir/scene/buffer_stream_factory.h" |
1456 | 24 | #include "stub_buffer_stream.h" | 23 | #include "stub_buffer_stream.h" |
1457 | 25 | 24 | ||
1458 | @@ -30,40 +29,20 @@ | |||
1459 | 30 | namespace doubles | 29 | namespace doubles |
1460 | 31 | { | 30 | { |
1461 | 32 | 31 | ||
1462 | 33 | struct StubClientBuffers : frontend::ClientBuffers | ||
1463 | 34 | { | ||
1464 | 35 | graphics::BufferID add_buffer(std::shared_ptr<graphics::Buffer> const&) override | ||
1465 | 36 | { | ||
1466 | 37 | return {}; | ||
1467 | 38 | } | ||
1468 | 39 | void remove_buffer(graphics::BufferID) override | ||
1469 | 40 | { | ||
1470 | 41 | } | ||
1471 | 42 | std::shared_ptr<graphics::Buffer> get(graphics::BufferID) const override | ||
1472 | 43 | { | ||
1473 | 44 | return buffer; | ||
1474 | 45 | } | ||
1475 | 46 | void send_buffer(graphics::BufferID) override | ||
1476 | 47 | { | ||
1477 | 48 | } | ||
1478 | 49 | void receive_buffer(graphics::BufferID) override | ||
1479 | 50 | { | ||
1480 | 51 | } | ||
1481 | 52 | std::shared_ptr<graphics::Buffer> buffer; | ||
1482 | 53 | }; | ||
1483 | 54 | |||
1484 | 55 | struct StubBufferStreamFactory : public scene::BufferStreamFactory | 32 | struct StubBufferStreamFactory : public scene::BufferStreamFactory |
1485 | 56 | { | 33 | { |
1486 | 57 | std::shared_ptr<compositor::BufferStream> create_buffer_stream( | 34 | std::shared_ptr<compositor::BufferStream> create_buffer_stream( |
1489 | 58 | frontend::BufferStreamId i, std::shared_ptr<frontend::ClientBuffers> const& s, | 35 | frontend::BufferStreamId i, |
1490 | 59 | int, graphics::BufferProperties const& p) { return create_buffer_stream(i, s, p); } | 36 | int, |
1491 | 37 | graphics::BufferProperties const& p) | ||
1492 | 38 | { | ||
1493 | 39 | return create_buffer_stream(i, p); | ||
1494 | 40 | } | ||
1495 | 60 | std::shared_ptr<compositor::BufferStream> create_buffer_stream( | 41 | std::shared_ptr<compositor::BufferStream> create_buffer_stream( |
1500 | 61 | frontend::BufferStreamId, std::shared_ptr<frontend::ClientBuffers> const&, | 42 | frontend::BufferStreamId, |
1501 | 62 | graphics::BufferProperties const&) { return std::make_shared<StubBufferStream>(); } | 43 | graphics::BufferProperties const&) |
1498 | 63 | std::shared_ptr<frontend::ClientBuffers> create_buffer_map( | ||
1499 | 64 | std::shared_ptr<frontend::BufferSink> const&) | ||
1502 | 65 | { | 44 | { |
1504 | 66 | return std::make_shared<StubClientBuffers>(); | 45 | return std::make_shared<StubBufferStream>(); |
1505 | 67 | } | 46 | } |
1506 | 68 | }; | 47 | }; |
1507 | 69 | } | 48 | } |
1508 | 70 | 49 | ||
1509 | === modified file 'tests/integration-tests/compositor/test_swapping_swappers.cpp' | |||
1510 | --- tests/integration-tests/compositor/test_swapping_swappers.cpp 2017-05-08 03:04:26 +0000 | |||
1511 | +++ tests/integration-tests/compositor/test_swapping_swappers.cpp 2017-07-18 03:23:56 +0000 | |||
1512 | @@ -19,7 +19,6 @@ | |||
1513 | 19 | #include "multithread_harness.h" | 19 | #include "multithread_harness.h" |
1514 | 20 | 20 | ||
1515 | 21 | #include "src/server/compositor/stream.h" | 21 | #include "src/server/compositor/stream.h" |
1516 | 22 | #include "src/server/compositor/buffer_map.h" | ||
1517 | 23 | #include "mir/graphics/graphic_buffer_allocator.h" | 22 | #include "mir/graphics/graphic_buffer_allocator.h" |
1518 | 24 | 23 | ||
1519 | 25 | #include <gmock/gmock.h> | 24 | #include <gmock/gmock.h> |
1520 | @@ -30,6 +29,7 @@ | |||
1521 | 30 | #include <atomic> | 29 | #include <atomic> |
1522 | 31 | 30 | ||
1523 | 32 | namespace mc = mir::compositor; | 31 | namespace mc = mir::compositor; |
1524 | 32 | namespace mf = mir::frontend; | ||
1525 | 33 | namespace mg = mir::graphics; | 33 | namespace mg = mir::graphics; |
1526 | 34 | namespace mt = mir::testing; | 34 | namespace mt = mir::testing; |
1527 | 35 | namespace geom = mir::geometry; | 35 | namespace geom = mir::geometry; |
1528 | @@ -42,7 +42,6 @@ | |||
1529 | 42 | void SetUp() | 42 | void SetUp() |
1530 | 43 | { | 43 | { |
1531 | 44 | stream = std::make_shared<mc::Stream>( | 44 | stream = std::make_shared<mc::Stream>( |
1532 | 45 | std::make_shared<mc::BufferMap>(nullptr), | ||
1533 | 46 | geom::Size{380, 210}, mir_pixel_format_abgr_8888); | 45 | geom::Size{380, 210}, mir_pixel_format_abgr_8888); |
1534 | 47 | } | 46 | } |
1535 | 48 | 47 | ||
1536 | 49 | 48 | ||
1537 | === modified file 'tests/integration-tests/test_buffer_scheduling.cpp' | |||
1538 | --- tests/integration-tests/test_buffer_scheduling.cpp 2017-05-25 05:49:36 +0000 | |||
1539 | +++ tests/integration-tests/test_buffer_scheduling.cpp 2017-07-18 03:23:56 +0000 | |||
1540 | @@ -16,17 +16,15 @@ | |||
1541 | 16 | * Authored by: Kevin DuBois <kevin.dubois@canonical.com> | 16 | * Authored by: Kevin DuBois <kevin.dubois@canonical.com> |
1542 | 17 | */ | 17 | */ |
1543 | 18 | 18 | ||
1544 | 19 | #include "mir/frontend/client_buffers.h" | ||
1545 | 20 | #include "mir/frontend/event_sink.h" | 19 | #include "mir/frontend/event_sink.h" |
1546 | 21 | #include "mir/frontend/buffer_sink.h" | 20 | #include "mir/frontend/buffer_sink.h" |
1547 | 22 | #include "mir/renderer/sw/pixel_source.h" | 21 | #include "mir/renderer/sw/pixel_source.h" |
1548 | 23 | #include "src/client/buffer_vault.h" | 22 | #include "src/client/buffer_vault.h" |
1549 | 24 | #include "src/client/buffer_factory.h" | 23 | #include "src/client/buffer_factory.h" |
1550 | 25 | #include "src/client/buffer_factory.h" | ||
1551 | 26 | #include "src/client/protobuf_to_native_buffer.h" | 24 | #include "src/client/protobuf_to_native_buffer.h" |
1552 | 27 | #include "src/client/connection_surface_map.h" | 25 | #include "src/client/connection_surface_map.h" |
1553 | 28 | #include "src/server/compositor/stream.h" | 26 | #include "src/server/compositor/stream.h" |
1555 | 29 | #include "src/server/compositor/buffer_map.h" | 27 | #include "src/server/compositor/temporary_buffers.h" |
1556 | 30 | #include "mir/test/doubles/stub_client_buffer_factory.h" | 28 | #include "mir/test/doubles/stub_client_buffer_factory.h" |
1557 | 31 | #include "mir/test/doubles/mock_client_buffer_factory.h" | 29 | #include "mir/test/doubles/mock_client_buffer_factory.h" |
1558 | 32 | #include "mir/test/doubles/stub_buffer_allocator.h" | 30 | #include "mir/test/doubles/stub_buffer_allocator.h" |
1559 | @@ -48,12 +46,6 @@ | |||
1560 | 48 | namespace | 46 | namespace |
1561 | 49 | { | 47 | { |
1562 | 50 | 48 | ||
1563 | 51 | enum class TestType | ||
1564 | 52 | { | ||
1565 | 53 | ExchangeSemantics, | ||
1566 | 54 | SubmitSemantics | ||
1567 | 55 | }; | ||
1568 | 56 | |||
1569 | 57 | enum class Access | 49 | enum class Access |
1570 | 58 | { | 50 | { |
1571 | 59 | blocked, | 51 | blocked, |
1572 | @@ -462,6 +454,24 @@ | |||
1573 | 462 | return never_blocks; | 454 | return never_blocks; |
1574 | 463 | } | 455 | } |
1575 | 464 | 456 | ||
1576 | 457 | class AutoSendBuffer : public mc::TemporaryBuffer | ||
1577 | 458 | { | ||
1578 | 459 | public: | ||
1579 | 460 | AutoSendBuffer( | ||
1580 | 461 | std::shared_ptr<mg::Buffer> const& wrapped, | ||
1581 | 462 | std::shared_ptr<mf::BufferSink> const& sink) | ||
1582 | 463 | : TemporaryBuffer(wrapped), | ||
1583 | 464 | sink{sink} | ||
1584 | 465 | { | ||
1585 | 466 | } | ||
1586 | 467 | |||
1587 | 468 | ~AutoSendBuffer() | ||
1588 | 469 | { | ||
1589 | 470 | sink->update_buffer(*buffer); | ||
1590 | 471 | } | ||
1591 | 472 | private: | ||
1592 | 473 | std::shared_ptr<mf::BufferSink> const sink; | ||
1593 | 474 | }; | ||
1594 | 465 | 475 | ||
1595 | 466 | //test infrastructure | 476 | //test infrastructure |
1596 | 467 | struct BufferScheduling : public Test, ::testing::WithParamInterface<int> | 477 | struct BufferScheduling : public Test, ::testing::WithParamInterface<int> |
1597 | @@ -470,9 +480,7 @@ | |||
1598 | 470 | { | 480 | { |
1599 | 471 | ipc = std::make_shared<StubIpcSystem>(); | 481 | ipc = std::make_shared<StubIpcSystem>(); |
1600 | 472 | sink = std::make_shared<StubEventSink>(ipc); | 482 | sink = std::make_shared<StubEventSink>(ipc); |
1601 | 473 | map = std::make_shared<mc::BufferMap>(sink); | ||
1602 | 474 | auto submit_stream = std::make_shared<mc::Stream>( | 483 | auto submit_stream = std::make_shared<mc::Stream>( |
1603 | 475 | map, | ||
1604 | 476 | geom::Size{100,100}, | 484 | geom::Size{100,100}, |
1605 | 477 | mir_pixel_format_abgr_8888); | 485 | mir_pixel_format_abgr_8888); |
1606 | 478 | auto weak_stream = std::weak_ptr<mc::Stream>(submit_stream); | 486 | auto weak_stream = std::weak_ptr<mc::Stream>(submit_stream); |
1607 | @@ -483,12 +491,15 @@ | |||
1608 | 483 | if (!submit_stream) | 491 | if (!submit_stream) |
1609 | 484 | return; | 492 | return; |
1610 | 485 | mg::BufferID id{static_cast<unsigned int>(buffer.buffer_id())}; | 493 | mg::BufferID id{static_cast<unsigned int>(buffer.buffer_id())}; |
1612 | 486 | submit_stream->submit_buffer(map->get(id)); | 494 | submit_stream->submit_buffer( |
1613 | 495 | std::make_shared<AutoSendBuffer>(map.at(id), sink)); | ||
1614 | 487 | }); | 496 | }); |
1615 | 488 | ipc->on_allocate( | 497 | ipc->on_allocate( |
1616 | 489 | [this](geom::Size sz) | 498 | [this](geom::Size sz) |
1617 | 490 | { | 499 | { |
1619 | 491 | map->add_buffer(std::make_shared<mtd::StubBuffer>(sz)); | 500 | auto const buffer = std::make_shared<mtd::StubBuffer>(sz); |
1620 | 501 | map[buffer->id()] = buffer; | ||
1621 | 502 | sink->add_buffer(*buffer); | ||
1622 | 492 | }); | 503 | }); |
1623 | 493 | 504 | ||
1624 | 494 | consumer = std::make_unique<ScheduledConsumer>(submit_stream); | 505 | consumer = std::make_unique<ScheduledConsumer>(submit_stream); |
1625 | @@ -529,7 +540,7 @@ | |||
1626 | 529 | std::unique_ptr<ConsumerSystem> consumer; | 540 | std::unique_ptr<ConsumerSystem> consumer; |
1627 | 530 | std::unique_ptr<ConsumerSystem> second_consumer; | 541 | std::unique_ptr<ConsumerSystem> second_consumer; |
1628 | 531 | std::unique_ptr<ConsumerSystem> third_consumer; | 542 | std::unique_ptr<ConsumerSystem> third_consumer; |
1630 | 532 | std::shared_ptr<mc::BufferMap> map; | 543 | std::unordered_map<mg::BufferID, std::shared_ptr<mg::Buffer>> map; |
1631 | 533 | }; | 544 | }; |
1632 | 534 | 545 | ||
1633 | 535 | struct WithAnyNumberOfBuffers : BufferScheduling {}; | 546 | struct WithAnyNumberOfBuffers : BufferScheduling {}; |
1634 | 536 | 547 | ||
1635 | === modified file 'tests/integration-tests/test_session.cpp' | |||
1636 | --- tests/integration-tests/test_session.cpp 2017-05-08 03:04:26 +0000 | |||
1637 | +++ tests/integration-tests/test_session.cpp 2017-07-18 03:23:56 +0000 | |||
1638 | @@ -80,7 +80,7 @@ | |||
1639 | 80 | struct StubGLBufferStreamFactory : public mtd::StubBufferStreamFactory | 80 | struct StubGLBufferStreamFactory : public mtd::StubBufferStreamFactory |
1640 | 81 | { | 81 | { |
1641 | 82 | std::shared_ptr<mc::BufferStream> create_buffer_stream( | 82 | std::shared_ptr<mc::BufferStream> create_buffer_stream( |
1643 | 83 | mf::BufferStreamId, std::shared_ptr<mf::ClientBuffers> const&, | 83 | mf::BufferStreamId, |
1644 | 84 | mg::BufferProperties const&) override | 84 | mg::BufferProperties const&) override |
1645 | 85 | { | 85 | { |
1646 | 86 | return std::make_shared<StubGLBufferStream>(); | 86 | return std::make_shared<StubGLBufferStream>(); |
1647 | 87 | 87 | ||
1648 | === modified file 'tests/integration-tests/test_submit_buffer.cpp' | |||
1649 | --- tests/integration-tests/test_submit_buffer.cpp 2017-05-08 03:04:26 +0000 | |||
1650 | +++ tests/integration-tests/test_submit_buffer.cpp 2017-07-18 03:23:56 +0000 | |||
1651 | @@ -32,7 +32,6 @@ | |||
1652 | 32 | #include "mir/frontend/event_sink.h" | 32 | #include "mir/frontend/event_sink.h" |
1653 | 33 | #include "mir/compositor/buffer_stream.h" | 33 | #include "mir/compositor/buffer_stream.h" |
1654 | 34 | #include "src/server/compositor/stream.h" | 34 | #include "src/server/compositor/stream.h" |
1655 | 35 | #include "src/server/compositor/buffer_map.h" | ||
1656 | 36 | #include "mir_toolkit/mir_client_library.h" | 35 | #include "mir_toolkit/mir_client_library.h" |
1657 | 37 | #include "mir_toolkit/debug/surface.h" | 36 | #include "mir_toolkit/debug/surface.h" |
1658 | 38 | #include "src/client/mir_connection.h" | 37 | #include "src/client/mir_connection.h" |
1659 | @@ -70,96 +69,17 @@ | |||
1660 | 70 | {} | 69 | {} |
1661 | 71 | 70 | ||
1662 | 72 | std::shared_ptr<mc::BufferStream> create_buffer_stream( | 71 | std::shared_ptr<mc::BufferStream> create_buffer_stream( |
1664 | 73 | mf::BufferStreamId i, std::shared_ptr<mf::ClientBuffers> const& s, | 72 | mf::BufferStreamId i, |
1665 | 74 | int, mg::BufferProperties const& p) override | 73 | int, mg::BufferProperties const& p) override |
1666 | 75 | { | 74 | { |
1668 | 76 | return create_buffer_stream(i, s, p); | 75 | return create_buffer_stream(i, p); |
1669 | 77 | } | 76 | } |
1670 | 78 | 77 | ||
1671 | 79 | std::shared_ptr<mc::BufferStream> create_buffer_stream( | 78 | std::shared_ptr<mc::BufferStream> create_buffer_stream( |
1673 | 80 | mf::BufferStreamId, std::shared_ptr<mf::ClientBuffers> const& sink, | 79 | mf::BufferStreamId, |
1674 | 81 | mg::BufferProperties const& properties) override | 80 | mg::BufferProperties const& properties) override |
1675 | 82 | { | 81 | { |
1756 | 83 | return std::make_shared<mc::Stream>(sink, properties.size, properties.format); | 82 | return std::make_shared<mc::Stream>(properties.size, properties.format); |
1677 | 84 | } | ||
1678 | 85 | |||
1679 | 86 | std::shared_ptr<mf::ClientBuffers> create_buffer_map(std::shared_ptr<mf::BufferSink> const& sink) override | ||
1680 | 87 | { | ||
1681 | 88 | struct BufferMap : mf::ClientBuffers | ||
1682 | 89 | { | ||
1683 | 90 | BufferMap( | ||
1684 | 91 | std::shared_ptr<mf::BufferSink> const& sink, | ||
1685 | 92 | std::vector<mg::BufferID> const& ids) : | ||
1686 | 93 | sink(sink), | ||
1687 | 94 | buffer_id_seq(ids) | ||
1688 | 95 | { | ||
1689 | 96 | std::reverse(buffer_id_seq.begin(), buffer_id_seq.end()); | ||
1690 | 97 | } | ||
1691 | 98 | |||
1692 | 99 | mg::BufferID add_buffer(std::shared_ptr<mg::Buffer> const& buffer) override | ||
1693 | 100 | { | ||
1694 | 101 | struct BufferIdWrapper : mg::Buffer | ||
1695 | 102 | { | ||
1696 | 103 | BufferIdWrapper(std::shared_ptr<mg::Buffer> const& b, mg::BufferID id) : | ||
1697 | 104 | wrapped(b), | ||
1698 | 105 | id_(id) | ||
1699 | 106 | { | ||
1700 | 107 | } | ||
1701 | 108 | |||
1702 | 109 | std::shared_ptr<mg::NativeBuffer> native_buffer_handle() const override | ||
1703 | 110 | { | ||
1704 | 111 | return wrapped->native_buffer_handle(); | ||
1705 | 112 | } | ||
1706 | 113 | mg::BufferID id() const override | ||
1707 | 114 | { | ||
1708 | 115 | return id_; | ||
1709 | 116 | } | ||
1710 | 117 | geom::Size size() const override | ||
1711 | 118 | { | ||
1712 | 119 | return wrapped->size(); | ||
1713 | 120 | } | ||
1714 | 121 | MirPixelFormat pixel_format() const override | ||
1715 | 122 | { | ||
1716 | 123 | return wrapped->pixel_format(); | ||
1717 | 124 | } | ||
1718 | 125 | mg::NativeBufferBase* native_buffer_base() override | ||
1719 | 126 | { | ||
1720 | 127 | return wrapped->native_buffer_base(); | ||
1721 | 128 | } | ||
1722 | 129 | std::shared_ptr<mg::Buffer> const wrapped; | ||
1723 | 130 | mg::BufferID const id_; | ||
1724 | 131 | }; | ||
1725 | 132 | |||
1726 | 133 | auto id = buffer_id_seq.back(); | ||
1727 | 134 | buffer_id_seq.pop_back(); | ||
1728 | 135 | b = std::make_shared<BufferIdWrapper>(buffer, id); | ||
1729 | 136 | sink->add_buffer(*b); | ||
1730 | 137 | return id; | ||
1731 | 138 | } | ||
1732 | 139 | |||
1733 | 140 | void remove_buffer(mg::BufferID) override | ||
1734 | 141 | { | ||
1735 | 142 | } | ||
1736 | 143 | |||
1737 | 144 | std::shared_ptr<mg::Buffer> get(mg::BufferID) const override | ||
1738 | 145 | { | ||
1739 | 146 | return b; | ||
1740 | 147 | } | ||
1741 | 148 | |||
1742 | 149 | void send_buffer(mg::BufferID) override | ||
1743 | 150 | { | ||
1744 | 151 | } | ||
1745 | 152 | |||
1746 | 153 | void receive_buffer(mg::BufferID) override | ||
1747 | 154 | { | ||
1748 | 155 | } | ||
1749 | 156 | |||
1750 | 157 | std::shared_ptr<mg::Buffer> b; | ||
1751 | 158 | std::shared_ptr<mf::BufferSink> const sink; | ||
1752 | 159 | std::shared_ptr<mtd::StubBufferAllocator> alloc{std::make_shared<mtd::StubBufferAllocator>()}; | ||
1753 | 160 | std::vector<mg::BufferID> buffer_id_seq; | ||
1754 | 161 | }; | ||
1755 | 162 | return std::make_shared<BufferMap>(sink, buffer_id_seq); | ||
1757 | 163 | } | 83 | } |
1758 | 164 | 84 | ||
1759 | 165 | std::vector<mg::BufferID> const buffer_id_seq; | 85 | std::vector<mg::BufferID> const buffer_id_seq; |
1760 | @@ -204,6 +124,66 @@ | |||
1761 | 204 | std::shared_ptr<mg::PlatformIpcOperations> const underlying_ops; | 124 | std::shared_ptr<mg::PlatformIpcOperations> const underlying_ops; |
1762 | 205 | }; | 125 | }; |
1763 | 206 | 126 | ||
1764 | 127 | class RecordingBufferAllocator : public mg::GraphicBufferAllocator | ||
1765 | 128 | { | ||
1766 | 129 | public: | ||
1767 | 130 | RecordingBufferAllocator( | ||
1768 | 131 | std::shared_ptr<mg::GraphicBufferAllocator> const& wrapped, | ||
1769 | 132 | std::vector<std::weak_ptr<mg::Buffer>>& allocated_buffers, | ||
1770 | 133 | std::mutex& buffer_mutex) | ||
1771 | 134 | : allocated_buffers{allocated_buffers}, | ||
1772 | 135 | underlying_allocator{wrapped}, | ||
1773 | 136 | buffer_mutex{buffer_mutex} | ||
1774 | 137 | { | ||
1775 | 138 | } | ||
1776 | 139 | |||
1777 | 140 | std::shared_ptr<mg::Buffer> alloc_buffer( | ||
1778 | 141 | mg::BufferProperties const& buffer_properties) override | ||
1779 | 142 | { | ||
1780 | 143 | auto const buf = underlying_allocator->alloc_buffer(buffer_properties); | ||
1781 | 144 | { | ||
1782 | 145 | std::lock_guard<std::mutex> lock{buffer_mutex}; | ||
1783 | 146 | allocated_buffers.push_back(buf); | ||
1784 | 147 | } | ||
1785 | 148 | return buf; | ||
1786 | 149 | } | ||
1787 | 150 | |||
1788 | 151 | std::vector<MirPixelFormat> supported_pixel_formats() override | ||
1789 | 152 | { | ||
1790 | 153 | return underlying_allocator->supported_pixel_formats(); | ||
1791 | 154 | } | ||
1792 | 155 | |||
1793 | 156 | std::shared_ptr<mg::Buffer> alloc_buffer( | ||
1794 | 157 | geom::Size size, | ||
1795 | 158 | uint32_t native_format, | ||
1796 | 159 | uint32_t native_flags) override | ||
1797 | 160 | { | ||
1798 | 161 | auto const buf = underlying_allocator->alloc_buffer(size, native_format, native_flags); | ||
1799 | 162 | { | ||
1800 | 163 | std::lock_guard<std::mutex> lock{buffer_mutex}; | ||
1801 | 164 | allocated_buffers.push_back(buf); | ||
1802 | 165 | } | ||
1803 | 166 | return buf; | ||
1804 | 167 | } | ||
1805 | 168 | |||
1806 | 169 | std::shared_ptr<mg::Buffer> alloc_software_buffer( | ||
1807 | 170 | geom::Size size, | ||
1808 | 171 | MirPixelFormat format) override | ||
1809 | 172 | { | ||
1810 | 173 | auto const buf = underlying_allocator->alloc_software_buffer(size, format); | ||
1811 | 174 | { | ||
1812 | 175 | std::lock_guard<std::mutex> lock{buffer_mutex}; | ||
1813 | 176 | allocated_buffers.push_back(buf); | ||
1814 | 177 | } | ||
1815 | 178 | return buf; | ||
1816 | 179 | } | ||
1817 | 180 | |||
1818 | 181 | std::vector<std::weak_ptr<mg::Buffer>>& allocated_buffers; | ||
1819 | 182 | private: | ||
1820 | 183 | std::shared_ptr<mg::GraphicBufferAllocator> const underlying_allocator; | ||
1821 | 184 | std::mutex& buffer_mutex; | ||
1822 | 185 | }; | ||
1823 | 186 | |||
1824 | 207 | struct StubPlatform : public mg::Platform | 187 | struct StubPlatform : public mg::Platform |
1825 | 208 | { | 188 | { |
1826 | 209 | StubPlatform(std::shared_ptr<mir::Fd> const& last_fd) | 189 | StubPlatform(std::shared_ptr<mir::Fd> const& last_fd) |
1827 | @@ -214,7 +194,10 @@ | |||
1828 | 214 | 194 | ||
1829 | 215 | mir::UniqueModulePtr<mg::GraphicBufferAllocator> create_buffer_allocator() override | 195 | mir::UniqueModulePtr<mg::GraphicBufferAllocator> create_buffer_allocator() override |
1830 | 216 | { | 196 | { |
1832 | 217 | return underlying_platform->create_buffer_allocator(); | 197 | return mir::make_module_ptr<RecordingBufferAllocator>( |
1833 | 198 | underlying_platform->create_buffer_allocator(), | ||
1834 | 199 | allocated_buffers, | ||
1835 | 200 | buffer_mutex); | ||
1836 | 218 | } | 201 | } |
1837 | 219 | 202 | ||
1838 | 220 | mir::UniqueModulePtr<mg::PlatformIpcOperations> make_ipc_operations() const override | 203 | mir::UniqueModulePtr<mg::PlatformIpcOperations> make_ipc_operations() const override |
1839 | @@ -231,20 +214,28 @@ | |||
1840 | 231 | return underlying_platform->create_display(policy, config); | 214 | return underlying_platform->create_display(policy, config); |
1841 | 232 | } | 215 | } |
1842 | 233 | 216 | ||
1843 | 217 | std::vector<std::weak_ptr<mg::Buffer>> get_allocated_buffers() | ||
1844 | 218 | { | ||
1845 | 219 | std::lock_guard<std::mutex> lock{buffer_mutex}; | ||
1846 | 220 | return allocated_buffers; | ||
1847 | 221 | } | ||
1848 | 222 | |||
1849 | 234 | mg::NativeRenderingPlatform* native_rendering_platform() override { return nullptr; } | 223 | mg::NativeRenderingPlatform* native_rendering_platform() override { return nullptr; } |
1850 | 235 | mg::NativeDisplayPlatform* native_display_platform() override { return nullptr; } | 224 | mg::NativeDisplayPlatform* native_display_platform() override { return nullptr; } |
1851 | 236 | std::vector<mir::ExtensionDescription> extensions() const override { return {}; } | 225 | std::vector<mir::ExtensionDescription> extensions() const override { return {}; } |
1852 | 237 | 226 | ||
1853 | 238 | std::shared_ptr<mir::Fd> const last_fd; | 227 | std::shared_ptr<mir::Fd> const last_fd; |
1854 | 239 | std::shared_ptr<mg::Platform> const underlying_platform; | 228 | std::shared_ptr<mg::Platform> const underlying_platform; |
1855 | 229 | |||
1856 | 230 | private: | ||
1857 | 231 | std::mutex buffer_mutex; | ||
1858 | 232 | std::vector<std::weak_ptr<mg::Buffer>> allocated_buffers; | ||
1859 | 240 | }; | 233 | }; |
1860 | 241 | 234 | ||
1861 | 242 | struct ExchangeServerConfiguration : mtf::StubbedServerConfiguration | 235 | struct ExchangeServerConfiguration : mtf::StubbedServerConfiguration |
1862 | 243 | { | 236 | { |
1863 | 244 | ExchangeServerConfiguration( | 237 | ExchangeServerConfiguration( |
1864 | 245 | std::vector<mg::BufferID> const& id_seq, | ||
1865 | 246 | std::shared_ptr<mir::Fd> const& last_unpacked_fd) : | 238 | std::shared_ptr<mir::Fd> const& last_unpacked_fd) : |
1866 | 247 | stream_factory{std::make_shared<StubStreamFactory>(id_seq)}, | ||
1867 | 248 | platform{std::make_shared<StubPlatform>(last_unpacked_fd)} | 239 | platform{std::make_shared<StubPlatform>(last_unpacked_fd)} |
1868 | 249 | { | 240 | { |
1869 | 250 | } | 241 | } |
1870 | @@ -254,24 +245,20 @@ | |||
1871 | 254 | return platform; | 245 | return platform; |
1872 | 255 | } | 246 | } |
1873 | 256 | 247 | ||
1881 | 257 | std::shared_ptr<msc::BufferStreamFactory> the_buffer_stream_factory() override | 248 | std::shared_ptr<StubPlatform> const platform; |
1875 | 258 | { | ||
1876 | 259 | return stream_factory; | ||
1877 | 260 | } | ||
1878 | 261 | |||
1879 | 262 | std::shared_ptr<StubStreamFactory> const stream_factory; | ||
1880 | 263 | std::shared_ptr<mg::Platform> const platform; | ||
1882 | 264 | }; | 249 | }; |
1883 | 265 | 250 | ||
1884 | 266 | struct SubmitBuffer : mir_test_framework::InProcessServer | 251 | struct SubmitBuffer : mir_test_framework::InProcessServer |
1885 | 267 | { | 252 | { |
1886 | 268 | std::vector<mg::BufferID> const buffer_id_exchange_seq{ | ||
1887 | 269 | mg::BufferID{4}, mg::BufferID{8}, mg::BufferID{9}, mg::BufferID{3}, mg::BufferID{4}}; | ||
1888 | 270 | |||
1889 | 271 | std::shared_ptr<mir::Fd> last_unpacked_fd{std::make_shared<mir::Fd>()}; | 253 | std::shared_ptr<mir::Fd> last_unpacked_fd{std::make_shared<mir::Fd>()}; |
1891 | 272 | ExchangeServerConfiguration server_configuration{buffer_id_exchange_seq, last_unpacked_fd}; | 254 | ExchangeServerConfiguration server_configuration{last_unpacked_fd}; |
1892 | 273 | mir::DefaultServerConfiguration& server_config() override { return server_configuration; } | 255 | mir::DefaultServerConfiguration& server_config() override { return server_configuration; } |
1893 | 274 | 256 | ||
1894 | 257 | std::vector<std::weak_ptr<mg::Buffer>> get_allocated_buffers() | ||
1895 | 258 | { | ||
1896 | 259 | return server_configuration.platform->get_allocated_buffers(); | ||
1897 | 260 | } | ||
1898 | 261 | |||
1899 | 275 | void request_completed() | 262 | void request_completed() |
1900 | 276 | { | 263 | { |
1901 | 277 | std::unique_lock<decltype(mutex)> lk(mutex); | 264 | std::unique_lock<decltype(mutex)> lk(mutex); |
1902 | @@ -287,7 +274,7 @@ | |||
1903 | 287 | google::protobuf::NewCallback(this, &SubmitBuffer::request_completed)); | 274 | google::protobuf::NewCallback(this, &SubmitBuffer::request_completed)); |
1904 | 288 | 275 | ||
1905 | 289 | arrived = false; | 276 | arrived = false; |
1907 | 290 | return cv.wait_for(lk, std::chrono::seconds(5), [this]() {return arrived;}); | 277 | return cv.wait_for(lk, std::chrono::seconds(500), [this]() {return arrived;}); |
1908 | 291 | } | 278 | } |
1909 | 292 | 279 | ||
1910 | 293 | bool allocate_buffers(mclr::DisplayServer& server, mp::BufferAllocation& request) | 280 | bool allocate_buffers(mclr::DisplayServer& server, mp::BufferAllocation& request) |
1911 | @@ -318,13 +305,18 @@ | |||
1912 | 318 | mp::BufferRequest buffer_request; | 305 | mp::BufferRequest buffer_request; |
1913 | 319 | }; | 306 | }; |
1914 | 320 | template<class Clock> | 307 | template<class Clock> |
1916 | 321 | bool spin_wait_for_id(mg::BufferID id, MirWindow* window, std::chrono::time_point<Clock> const& pt) | 308 | bool spin_wait_for_id( |
1917 | 309 | std::function<std::vector<mg::BufferID>()> const& id_generator, | ||
1918 | 310 | MirWindow* window, | ||
1919 | 311 | std::chrono::time_point<Clock> const& pt) | ||
1920 | 322 | { | 312 | { |
1921 | 323 | while(Clock::now() < pt) | 313 | while(Clock::now() < pt) |
1922 | 324 | { | 314 | { |
1926 | 325 | //auto z = mir_debug_window_current_buffer_id(window); | 315 | for (auto const& id : id_generator()) |
1927 | 326 | if (mir_debug_window_current_buffer_id(window) == id.as_value()) | 316 | { |
1928 | 327 | return true; | 317 | if (mir_debug_window_current_buffer_id(window) == id.as_value()) |
1929 | 318 | return true; | ||
1930 | 319 | } | ||
1931 | 328 | std::this_thread::yield(); | 320 | std::this_thread::yield(); |
1932 | 329 | } | 321 | } |
1933 | 330 | return false; | 322 | return false; |
1934 | @@ -353,7 +345,17 @@ | |||
1935 | 353 | for (auto i = 0; i < buffer_request.buffer().fd().size(); i++) | 345 | for (auto i = 0; i < buffer_request.buffer().fd().size(); i++) |
1936 | 354 | ::close(buffer_request.buffer().fd(i)); | 346 | ::close(buffer_request.buffer().fd(i)); |
1937 | 355 | 347 | ||
1939 | 356 | buffer_request.mutable_buffer()->set_buffer_id(buffer_id_exchange_seq.begin()->as_value()); | 348 | mp::BufferAllocation allocation_request; |
1940 | 349 | auto allocate = allocation_request.add_buffer_requests(); | ||
1941 | 350 | allocate->set_buffer_usage(static_cast<int32_t>(mg::BufferUsage::software)); | ||
1942 | 351 | allocate->set_pixel_format(mir_pixel_format_abgr_8888); | ||
1943 | 352 | allocate->set_width(320); | ||
1944 | 353 | allocate->set_height(240); | ||
1945 | 354 | |||
1946 | 355 | ASSERT_THAT(allocate_buffers(server, allocation_request), DidNotTimeOut()); | ||
1947 | 356 | |||
1948 | 357 | buffer_request.mutable_buffer()->set_buffer_id( | ||
1949 | 358 | get_allocated_buffers().back().lock()->id().as_value()); | ||
1950 | 357 | buffer_request.mutable_buffer()->add_fd(file); | 359 | buffer_request.mutable_buffer()->add_fd(file); |
1951 | 358 | 360 | ||
1952 | 359 | ASSERT_THAT(submit_buffer(server, buffer_request), DidNotTimeOut()); | 361 | ASSERT_THAT(submit_buffer(server, buffer_request), DidNotTimeOut()); |
1953 | @@ -377,10 +379,22 @@ | |||
1954 | 377 | auto rpc_channel = connection->rpc_channel(); | 379 | auto rpc_channel = connection->rpc_channel(); |
1955 | 378 | mclr::DisplayServer server(rpc_channel); | 380 | mclr::DisplayServer server(rpc_channel); |
1956 | 379 | 381 | ||
1957 | 382 | for(int i = 0; i < 5; ++i) | ||
1958 | 383 | { | ||
1959 | 384 | mp::BufferAllocation allocation_request; | ||
1960 | 385 | auto allocate = allocation_request.add_buffer_requests(); | ||
1961 | 386 | allocate->set_buffer_usage(static_cast<int32_t>(mg::BufferUsage::software)); | ||
1962 | 387 | allocate->set_pixel_format(mir_pixel_format_abgr_8888); | ||
1963 | 388 | allocate->set_width(320); | ||
1964 | 389 | allocate->set_height(240); | ||
1965 | 390 | |||
1966 | 391 | allocate_buffers(server, allocation_request); | ||
1967 | 392 | } | ||
1968 | 393 | |||
1969 | 380 | mp::BufferRequest request; | 394 | mp::BufferRequest request; |
1971 | 381 | for (auto const& id : buffer_id_exchange_seq) | 395 | for (auto weak_buffer : get_allocated_buffers()) |
1972 | 382 | { | 396 | { |
1974 | 383 | buffer_request.mutable_buffer()->set_buffer_id(id.as_value()); | 397 | buffer_request.mutable_buffer()->set_buffer_id(weak_buffer.lock()->id().as_value()); |
1975 | 384 | ASSERT_THAT(submit_buffer(server, buffer_request), DidNotTimeOut()); | 398 | ASSERT_THAT(submit_buffer(server, buffer_request), DidNotTimeOut()); |
1976 | 385 | } | 399 | } |
1977 | 386 | 400 | ||
1978 | @@ -396,8 +410,32 @@ | |||
1979 | 396 | auto window = mtf::make_any_surface(connection); | 410 | auto window = mtf::make_any_surface(connection); |
1980 | 397 | 411 | ||
1981 | 398 | auto timeout = std::chrono::steady_clock::now() + 5s; | 412 | auto timeout = std::chrono::steady_clock::now() + 5s; |
1984 | 399 | EXPECT_TRUE(spin_wait_for_id(buffer_id_exchange_seq.back(), window, timeout)) | 413 | |
1985 | 400 | << "failed to see the last scheduled buffer become the current one"; | 414 | EXPECT_TRUE( |
1986 | 415 | spin_wait_for_id( | ||
1987 | 416 | [this]() | ||
1988 | 417 | { | ||
1989 | 418 | /* We expect to receive one of the implicitly allocated buffers | ||
1990 | 419 | * We don't care which one we get. | ||
1991 | 420 | * | ||
1992 | 421 | * We need to repeatedly check the allocated buffers, because | ||
1993 | 422 | * buffer allocation is asynchronous WRT window creation. | ||
1994 | 423 | */ | ||
1995 | 424 | std::vector<mg::BufferID> candidate_ids; | ||
1996 | 425 | for (auto const weak_buffer : get_allocated_buffers()) | ||
1997 | 426 | { | ||
1998 | 427 | auto const buffer = weak_buffer.lock(); | ||
1999 | 428 | if (buffer) | ||
2000 | 429 | { | ||
2001 | 430 | // If there are any expired buffers we don't care about them | ||
2002 | 431 | candidate_ids.push_back(buffer->id()); | ||
2003 | 432 | } | ||
2004 | 433 | } | ||
2005 | 434 | return candidate_ids; | ||
2006 | 435 | }, | ||
2007 | 436 | window, | ||
2008 | 437 | timeout)) | ||
2009 | 438 | << "failed to see buffer"; | ||
2010 | 401 | 439 | ||
2011 | 402 | mir_window_release_sync(window); | 440 | mir_window_release_sync(window); |
2012 | 403 | mir_connection_release(connection); | 441 | mir_connection_release(connection); |
2013 | 404 | 442 | ||
2014 | === modified file 'tests/integration-tests/test_surface_stack_with_compositor.cpp' | |||
2015 | --- tests/integration-tests/test_surface_stack_with_compositor.cpp 2017-05-08 03:04:26 +0000 | |||
2016 | +++ tests/integration-tests/test_surface_stack_with_compositor.cpp 2017-07-18 03:23:56 +0000 | |||
2017 | @@ -24,7 +24,6 @@ | |||
2018 | 24 | #include "src/server/scene/basic_surface.h" | 24 | #include "src/server/scene/basic_surface.h" |
2019 | 25 | #include "src/server/compositor/default_display_buffer_compositor_factory.h" | 25 | #include "src/server/compositor/default_display_buffer_compositor_factory.h" |
2020 | 26 | #include "src/server/compositor/multi_threaded_compositor.h" | 26 | #include "src/server/compositor/multi_threaded_compositor.h" |
2021 | 27 | #include "src/server/compositor/buffer_map.h" | ||
2022 | 28 | #include "src/server/compositor/stream.h" | 27 | #include "src/server/compositor/stream.h" |
2023 | 29 | #include "mir/test/fake_shared.h" | 28 | #include "mir/test/fake_shared.h" |
2024 | 30 | #include "mir/test/doubles/mock_buffer_stream.h" | 29 | #include "mir/test/doubles/mock_buffer_stream.h" |
2025 | @@ -47,6 +46,7 @@ | |||
2026 | 47 | namespace mr = mir::report; | 46 | namespace mr = mir::report; |
2027 | 48 | namespace mc = mir::compositor; | 47 | namespace mc = mir::compositor; |
2028 | 49 | namespace mg = mir::graphics; | 48 | namespace mg = mir::graphics; |
2029 | 49 | namespace mf = mir::frontend; | ||
2030 | 50 | namespace geom = mir::geometry; | 50 | namespace geom = mir::geometry; |
2031 | 51 | using namespace testing; | 51 | using namespace testing; |
2032 | 52 | 52 | ||
2033 | @@ -123,8 +123,7 @@ | |||
2034 | 123 | { | 123 | { |
2035 | 124 | SurfaceStackCompositor() : | 124 | SurfaceStackCompositor() : |
2036 | 125 | timeout{std::chrono::system_clock::now() + std::chrono::seconds(5)}, | 125 | timeout{std::chrono::system_clock::now() + std::chrono::seconds(5)}, |
2039 | 126 | buffers(std::make_shared<mc::BufferMap>(std::make_shared<NiceMock<mtd::MockEventSink>>())), | 126 | stream(std::make_shared<mc::Stream>(geom::Size{ 1, 1 }, mir_pixel_format_abgr_8888 )), |
2038 | 127 | stream(std::make_shared<mc::Stream>(buffers, geom::Size{ 1, 1 }, mir_pixel_format_abgr_8888 )), | ||
2040 | 128 | mock_buffer_stream(std::make_shared<NiceMock<mtd::MockBufferStream>>()), | 127 | mock_buffer_stream(std::make_shared<NiceMock<mtd::MockBufferStream>>()), |
2041 | 129 | streams({ { stream, {0,0}, {} } }), | 128 | streams({ { stream, {0,0}, {} } }), |
2042 | 130 | stub_surface{std::make_shared<ms::BasicSurface>( | 129 | stub_surface{std::make_shared<ms::BasicSurface>( |
2043 | @@ -136,7 +135,6 @@ | |||
2044 | 136 | null_scene_report)}, | 135 | null_scene_report)}, |
2045 | 137 | stub_buffer(std::make_shared<mtd::StubBuffer>()) | 136 | stub_buffer(std::make_shared<mtd::StubBuffer>()) |
2046 | 138 | { | 137 | { |
2047 | 139 | buffers->add_buffer(stub_buffer); | ||
2048 | 140 | ON_CALL(*mock_buffer_stream, lock_compositor_buffer(_)) | 138 | ON_CALL(*mock_buffer_stream, lock_compositor_buffer(_)) |
2049 | 141 | .WillByDefault(Return(mt::fake_shared(*stub_buffer))); | 139 | .WillByDefault(Return(mt::fake_shared(*stub_buffer))); |
2050 | 142 | } | 140 | } |
2051 | @@ -145,7 +143,6 @@ | |||
2052 | 145 | std::shared_ptr<mc::CompositorReport> null_comp_report{mr::null_compositor_report()}; | 143 | std::shared_ptr<mc::CompositorReport> null_comp_report{mr::null_compositor_report()}; |
2053 | 146 | StubRendererFactory renderer_factory; | 144 | StubRendererFactory renderer_factory; |
2054 | 147 | std::chrono::system_clock::time_point timeout; | 145 | std::chrono::system_clock::time_point timeout; |
2055 | 148 | std::shared_ptr<mc::BufferMap> buffers; | ||
2056 | 149 | std::shared_ptr<mc::Stream> stream; | 146 | std::shared_ptr<mc::Stream> stream; |
2057 | 150 | std::shared_ptr<mtd::MockBufferStream> mock_buffer_stream; | 147 | std::shared_ptr<mtd::MockBufferStream> mock_buffer_stream; |
2058 | 151 | std::list<ms::StreamInfo> const streams; | 148 | std::list<ms::StreamInfo> const streams; |
2059 | 152 | 149 | ||
2060 | === modified file 'tests/integration-tests/test_swapinterval.cpp' | |||
2061 | --- tests/integration-tests/test_swapinterval.cpp 2017-05-08 03:04:26 +0000 | |||
2062 | +++ tests/integration-tests/test_swapinterval.cpp 2017-07-18 03:23:56 +0000 | |||
2063 | @@ -67,24 +67,19 @@ | |||
2064 | 67 | } | 67 | } |
2065 | 68 | 68 | ||
2066 | 69 | std::shared_ptr<mc::BufferStream> create_buffer_stream( | 69 | std::shared_ptr<mc::BufferStream> create_buffer_stream( |
2068 | 70 | mf::BufferStreamId id, std::shared_ptr<mf::ClientBuffers> const& sink, | 70 | mf::BufferStreamId id, |
2069 | 71 | int, mg::BufferProperties const& p) override | 71 | int, mg::BufferProperties const& p) override |
2070 | 72 | { | 72 | { |
2072 | 73 | return create_buffer_stream(id, sink, p); | 73 | return create_buffer_stream(id, p); |
2073 | 74 | } | 74 | } |
2074 | 75 | 75 | ||
2075 | 76 | std::shared_ptr<mc::BufferStream> create_buffer_stream( | 76 | std::shared_ptr<mc::BufferStream> create_buffer_stream( |
2077 | 77 | mf::BufferStreamId, std::shared_ptr<mf::ClientBuffers> const&, | 77 | mf::BufferStreamId, |
2078 | 78 | mg::BufferProperties const&) override | 78 | mg::BufferProperties const&) override |
2079 | 79 | { | 79 | { |
2080 | 80 | return std::make_shared<StubBufferStream>(framedropping_enabled); | 80 | return std::make_shared<StubBufferStream>(framedropping_enabled); |
2081 | 81 | } | 81 | } |
2082 | 82 | 82 | ||
2083 | 83 | std::shared_ptr<mf::ClientBuffers> create_buffer_map(std::shared_ptr<mf::BufferSink> const&) override | ||
2084 | 84 | { | ||
2085 | 85 | return std::make_shared<mtd::StubClientBuffers>(); | ||
2086 | 86 | } | ||
2087 | 87 | |||
2088 | 88 | private: | 83 | private: |
2089 | 89 | std::atomic<bool>& framedropping_enabled; | 84 | std::atomic<bool>& framedropping_enabled; |
2090 | 90 | }; | 85 | }; |
2091 | 91 | 86 | ||
2092 | === modified file 'tests/mir_test_doubles/mock_event_sink_factory.cpp' | |||
2093 | --- tests/mir_test_doubles/mock_event_sink_factory.cpp 2017-05-08 03:04:26 +0000 | |||
2094 | +++ tests/mir_test_doubles/mock_event_sink_factory.cpp 2017-07-18 03:23:56 +0000 | |||
2095 | @@ -42,7 +42,6 @@ | |||
2096 | 42 | void send_buffer(mf::BufferStreamId id, mg::Buffer& buf, mg::BufferIpcMsgType type) override; | 42 | void send_buffer(mf::BufferStreamId id, mg::Buffer& buf, mg::BufferIpcMsgType type) override; |
2097 | 43 | void handle_input_config_change(MirInputConfig const& devices) override; | 43 | void handle_input_config_change(MirInputConfig const& devices) override; |
2098 | 44 | void add_buffer(mir::graphics::Buffer&) override; | 44 | void add_buffer(mir::graphics::Buffer&) override; |
2099 | 45 | void remove_buffer(mir::graphics::Buffer&) override; | ||
2100 | 46 | void update_buffer(mir::graphics::Buffer&) override; | 45 | void update_buffer(mir::graphics::Buffer&) override; |
2101 | 47 | void error_buffer(mir::geometry::Size, MirPixelFormat, std::string const&) override; | 46 | void error_buffer(mir::geometry::Size, MirPixelFormat, std::string const&) override; |
2102 | 48 | 47 | ||
2103 | @@ -106,11 +105,6 @@ | |||
2104 | 106 | underlying_sink->error_buffer(sz, pf, error); | 105 | underlying_sink->error_buffer(sz, pf, error); |
2105 | 107 | } | 106 | } |
2106 | 108 | 107 | ||
2107 | 109 | void GloballyUniqueMockEventSink::remove_buffer(mir::graphics::Buffer& buffer) | ||
2108 | 110 | { | ||
2109 | 111 | underlying_sink->remove_buffer(buffer); | ||
2110 | 112 | } | ||
2111 | 113 | |||
2112 | 114 | void GloballyUniqueMockEventSink::update_buffer(mir::graphics::Buffer& buffer) | 108 | void GloballyUniqueMockEventSink::update_buffer(mir::graphics::Buffer& buffer) |
2113 | 115 | { | 109 | { |
2114 | 116 | underlying_sink->update_buffer(buffer); | 110 | underlying_sink->update_buffer(buffer); |
2115 | 117 | 111 | ||
2116 | === modified file 'tests/mir_test_framework/stub_session.cpp' | |||
2117 | --- tests/mir_test_framework/stub_session.cpp 2017-05-08 03:04:26 +0000 | |||
2118 | +++ tests/mir_test_framework/stub_session.cpp 2017-07-18 03:23:56 +0000 | |||
2119 | @@ -143,31 +143,6 @@ | |||
2120 | 143 | { | 143 | { |
2121 | 144 | } | 144 | } |
2122 | 145 | 145 | ||
2123 | 146 | mir::graphics::BufferID mtd::StubSession::create_buffer(mir::graphics::BufferProperties const&) | ||
2124 | 147 | { | ||
2125 | 148 | return mir::graphics::BufferID(3); | ||
2126 | 149 | } | ||
2127 | 150 | |||
2128 | 151 | mir::graphics::BufferID mtd::StubSession::create_buffer(mir::geometry::Size, uint32_t, uint32_t) | ||
2129 | 152 | { | ||
2130 | 153 | return mir::graphics::BufferID(3); | ||
2131 | 154 | } | ||
2132 | 155 | |||
2133 | 156 | mir::graphics::BufferID mtd::StubSession::create_buffer(mir::geometry::Size, MirPixelFormat) | ||
2134 | 157 | { | ||
2135 | 158 | return mir::graphics::BufferID(3); | ||
2136 | 159 | } | ||
2137 | 160 | |||
2138 | 161 | void mtd::StubSession::destroy_buffer(mir::graphics::BufferID) | ||
2139 | 162 | { | ||
2140 | 163 | } | ||
2141 | 164 | |||
2142 | 165 | std::shared_ptr<mir::graphics::Buffer> mtd::StubSession::get_buffer(graphics::BufferID) | ||
2143 | 166 | { | ||
2144 | 167 | return std::make_shared<mtd::StubBuffer>( | ||
2145 | 168 | std::make_shared<mir_test_framework::NativeBuffer>(graphics::BufferProperties{})); | ||
2146 | 169 | } | ||
2147 | 170 | |||
2148 | 171 | namespace | 146 | namespace |
2149 | 172 | { | 147 | { |
2150 | 173 | // Ensure we don't accidentally have an abstract class | 148 | // Ensure we don't accidentally have an abstract class |
2151 | 174 | 149 | ||
2152 | === modified file 'tests/unit-tests/client/test_client_buffer_stream.cpp' | |||
2153 | --- tests/unit-tests/client/test_client_buffer_stream.cpp 2017-05-17 04:48:46 +0000 | |||
2154 | +++ tests/unit-tests/client/test_client_buffer_stream.cpp 2017-07-18 03:23:56 +0000 | |||
2155 | @@ -204,16 +204,15 @@ | |||
2156 | 204 | 204 | ||
2157 | 205 | void async_buffer_arrives(mp::Buffer& buffer) | 205 | void async_buffer_arrives(mp::Buffer& buffer) |
2158 | 206 | { | 206 | { |
2160 | 207 | try | 207 | if (auto buf = map->buffer(buffer.buffer_id())) |
2161 | 208 | { | 208 | { |
2163 | 209 | map->buffer(buffer.buffer_id())->received(*mcl::protobuf_to_native_buffer(buffer)); | 209 | buf->received(*mcl::protobuf_to_native_buffer(buffer)); |
2164 | 210 | } | 210 | } |
2166 | 211 | catch (std::runtime_error& e) | 211 | else |
2167 | 212 | { | 212 | { |
2172 | 213 | auto bb = factory->generate_buffer(buffer); | 213 | map->insert(buffer.buffer_id(), factory->generate_buffer(buffer)); |
2173 | 214 | auto braw = bb.get(); | 214 | buf = map->buffer(buffer.buffer_id()); |
2174 | 215 | map->insert(buffer.buffer_id(), std::move(bb)); | 215 | buf->received(); |
2171 | 216 | braw->received(); | ||
2175 | 217 | } | 216 | } |
2176 | 218 | } | 217 | } |
2177 | 219 | 218 | ||
2178 | 220 | 219 | ||
2179 | === modified file 'tests/unit-tests/client/test_connection_resource_map.cpp' | |||
2180 | --- tests/unit-tests/client/test_connection_resource_map.cpp 2017-05-08 03:04:26 +0000 | |||
2181 | +++ tests/unit-tests/client/test_connection_resource_map.cpp 2017-07-18 03:23:56 +0000 | |||
2182 | @@ -97,17 +97,13 @@ | |||
2183 | 97 | { | 97 | { |
2184 | 98 | using namespace testing; | 98 | using namespace testing; |
2185 | 99 | mcl::ConnectionSurfaceMap map; | 99 | mcl::ConnectionSurfaceMap map; |
2189 | 100 | EXPECT_THROW({ | 100 | EXPECT_THAT(map.buffer(buffer_id), IsNull()); |
2187 | 101 | map.buffer(buffer_id); | ||
2188 | 102 | }, std::runtime_error); | ||
2190 | 103 | 101 | ||
2191 | 104 | map.insert(buffer_id, buffer); | 102 | map.insert(buffer_id, buffer); |
2192 | 105 | EXPECT_THAT(map.buffer(buffer_id), Eq(buffer)); | 103 | EXPECT_THAT(map.buffer(buffer_id), Eq(buffer)); |
2193 | 106 | map.erase(buffer_id); | 104 | map.erase(buffer_id); |
2194 | 107 | 105 | ||
2198 | 108 | EXPECT_THROW({ | 106 | EXPECT_THAT(map.buffer(buffer_id), IsNull()); |
2196 | 109 | map.buffer(buffer_id); | ||
2197 | 110 | }, std::runtime_error); | ||
2199 | 111 | } | 107 | } |
2200 | 112 | 108 | ||
2201 | 113 | TEST_F(ConnectionResourceMap, can_access_buffers_from_surface) | 109 | TEST_F(ConnectionResourceMap, can_access_buffers_from_surface) |
2202 | 114 | 110 | ||
2203 | === modified file 'tests/unit-tests/client/test_mir_connection.cpp' | |||
2204 | --- tests/unit-tests/client/test_mir_connection.cpp 2017-05-25 06:28:52 +0000 | |||
2205 | +++ tests/unit-tests/client/test_mir_connection.cpp 2017-07-18 03:23:56 +0000 | |||
2206 | @@ -873,7 +873,6 @@ | |||
2207 | 873 | auto native_format = 342u; | 873 | auto native_format = 342u; |
2208 | 874 | auto native_flags = 0x44; | 874 | auto native_flags = 0x44; |
2209 | 875 | mp::BufferAllocation mp_alloc; | 875 | mp::BufferAllocation mp_alloc; |
2210 | 876 | mp_alloc.mutable_id()->set_value(-1); | ||
2211 | 877 | auto params = mp_alloc.add_buffer_requests(); | 876 | auto params = mp_alloc.add_buffer_requests(); |
2212 | 878 | params->set_width(size.width.as_int()); | 877 | params->set_width(size.width.as_int()); |
2213 | 879 | params->set_height(size.height.as_int()); | 878 | params->set_height(size.height.as_int()); |
2214 | 880 | 879 | ||
2215 | === modified file 'tests/unit-tests/client/test_protobuf_rpc_channel.cpp' | |||
2216 | --- tests/unit-tests/client/test_protobuf_rpc_channel.cpp 2017-05-08 03:04:26 +0000 | |||
2217 | +++ tests/unit-tests/client/test_protobuf_rpc_channel.cpp 2017-07-18 03:23:56 +0000 | |||
2218 | @@ -840,3 +840,27 @@ | |||
2219 | 840 | std::make_shared<mtd::NullClientEventSink>()}; | 840 | std::make_shared<mtd::NullClientEventSink>()}; |
2220 | 841 | channel.on_data_available(); | 841 | channel.on_data_available(); |
2221 | 842 | } | 842 | } |
2222 | 843 | |||
2223 | 844 | TEST_F(MirProtobufRpcChannelTest, ignores_update_message_for_unknown_buffer) | ||
2224 | 845 | { | ||
2225 | 846 | mir::protobuf::EventSequence seq; | ||
2226 | 847 | auto request = seq.mutable_buffer_request(); | ||
2227 | 848 | request->mutable_buffer()->set_buffer_id(42); | ||
2228 | 849 | request->set_operation(mir::protobuf::BufferOperation::update); | ||
2229 | 850 | |||
2230 | 851 | set_async_buffer_message(seq, *transport); | ||
2231 | 852 | |||
2232 | 853 | channel->on_data_available(); | ||
2233 | 854 | } | ||
2234 | 855 | |||
2235 | 856 | TEST_F(MirProtobufRpcChannelTest, ignores_delete_message_for_unknown_buffer) | ||
2236 | 857 | { | ||
2237 | 858 | mir::protobuf::EventSequence seq; | ||
2238 | 859 | auto request = seq.mutable_buffer_request(); | ||
2239 | 860 | request->mutable_buffer()->set_buffer_id(42); | ||
2240 | 861 | request->set_operation(mir::protobuf::BufferOperation::remove); | ||
2241 | 862 | |||
2242 | 863 | set_async_buffer_message(seq, *transport); | ||
2243 | 864 | |||
2244 | 865 | channel->on_data_available(); | ||
2245 | 866 | } | ||
2246 | 843 | 867 | ||
2247 | === modified file 'tests/unit-tests/compositor/CMakeLists.txt' | |||
2248 | --- tests/unit-tests/compositor/CMakeLists.txt 2017-05-08 03:04:26 +0000 | |||
2249 | +++ tests/unit-tests/compositor/CMakeLists.txt 2017-07-18 03:23:56 +0000 | |||
2250 | @@ -7,7 +7,6 @@ | |||
2251 | 7 | ${CMAKE_CURRENT_SOURCE_DIR}/test_screencast_display_buffer.cpp | 7 | ${CMAKE_CURRENT_SOURCE_DIR}/test_screencast_display_buffer.cpp |
2252 | 8 | ${CMAKE_CURRENT_SOURCE_DIR}/test_compositing_screencast.cpp | 8 | ${CMAKE_CURRENT_SOURCE_DIR}/test_compositing_screencast.cpp |
2253 | 9 | ${CMAKE_CURRENT_SOURCE_DIR}/test_multi_monitor_arbiter.cpp | 9 | ${CMAKE_CURRENT_SOURCE_DIR}/test_multi_monitor_arbiter.cpp |
2254 | 10 | ${CMAKE_CURRENT_SOURCE_DIR}/test_client_buffers.cpp | ||
2255 | 11 | ${CMAKE_CURRENT_SOURCE_DIR}/test_dropping_schedule.cpp | 10 | ${CMAKE_CURRENT_SOURCE_DIR}/test_dropping_schedule.cpp |
2256 | 12 | ${CMAKE_CURRENT_SOURCE_DIR}/test_queueing_schedule.cpp | 11 | ${CMAKE_CURRENT_SOURCE_DIR}/test_queueing_schedule.cpp |
2257 | 13 | ) | 12 | ) |
2258 | 14 | 13 | ||
2259 | === removed file 'tests/unit-tests/compositor/test_client_buffers.cpp' | |||
2260 | --- tests/unit-tests/compositor/test_client_buffers.cpp 2017-05-08 03:04:26 +0000 | |||
2261 | +++ tests/unit-tests/compositor/test_client_buffers.cpp 1970-01-01 00:00:00 +0000 | |||
2262 | @@ -1,119 +0,0 @@ | |||
2263 | 1 | /* | ||
2264 | 2 | * Copyright © 2015 Canonical Ltd. | ||
2265 | 3 | * | ||
2266 | 4 | * This program is free software: you can redistribute it and/or modify | ||
2267 | 5 | * it under the terms of the GNU General Public License version 3 as | ||
2268 | 6 | * published by the Free Software Foundation. | ||
2269 | 7 | * | ||
2270 | 8 | * This program is distributed in the hope that it will be useful, | ||
2271 | 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
2272 | 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
2273 | 11 | * GNU General Public License for more details. | ||
2274 | 12 | * | ||
2275 | 13 | * You should have received a copy of the GNU General Public License | ||
2276 | 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
2277 | 15 | * | ||
2278 | 16 | * Authored by: Kevin DuBois <kevin.dubois@canonical.com> | ||
2279 | 17 | */ | ||
2280 | 18 | |||
2281 | 19 | #include "mir/test/doubles/mock_event_sink.h" | ||
2282 | 20 | #include "mir/test/fake_shared.h" | ||
2283 | 21 | #include "mir/test/doubles/stub_buffer_allocator.h" | ||
2284 | 22 | #include "src/server/compositor/buffer_map.h" | ||
2285 | 23 | #include "mir/graphics/display_configuration.h" | ||
2286 | 24 | |||
2287 | 25 | #include <gtest/gtest.h> | ||
2288 | 26 | using namespace testing; | ||
2289 | 27 | namespace mt = mir::test; | ||
2290 | 28 | namespace mtd = mir::test::doubles; | ||
2291 | 29 | namespace mc = mir::compositor; | ||
2292 | 30 | namespace mg = mir::graphics; | ||
2293 | 31 | namespace mf = mir::frontend; | ||
2294 | 32 | namespace geom = mir::geometry; | ||
2295 | 33 | |||
2296 | 34 | struct ClientBuffers : public Test | ||
2297 | 35 | { | ||
2298 | 36 | std::shared_ptr<mtd::MockEventSink> mock_sink = std::make_shared<testing::NiceMock<mtd::MockEventSink>>(); | ||
2299 | 37 | mg::BufferProperties properties{geom::Size{42,43}, mir_pixel_format_abgr_8888, mg::BufferUsage::hardware}; | ||
2300 | 38 | mtd::StubBuffer stub_buffer{properties}; | ||
2301 | 39 | mc::BufferMap map{mock_sink}; | ||
2302 | 40 | }; | ||
2303 | 41 | |||
2304 | 42 | TEST_F(ClientBuffers, sends_full_buffer_on_allocation) | ||
2305 | 43 | { | ||
2306 | 44 | EXPECT_CALL(*mock_sink, add_buffer(Ref(stub_buffer))); | ||
2307 | 45 | mc::BufferMap map{mock_sink}; | ||
2308 | 46 | EXPECT_THAT(map.add_buffer(mt::fake_shared(stub_buffer)), Eq(stub_buffer.id())); | ||
2309 | 47 | } | ||
2310 | 48 | |||
2311 | 49 | TEST_F(ClientBuffers, access_of_nonexistent_buffer_throws) | ||
2312 | 50 | { | ||
2313 | 51 | EXPECT_THROW({ | ||
2314 | 52 | auto buffer = map.get(stub_buffer.id()); | ||
2315 | 53 | }, std::logic_error); | ||
2316 | 54 | } | ||
2317 | 55 | |||
2318 | 56 | TEST_F(ClientBuffers, removal_of_nonexistent_buffer_throws) | ||
2319 | 57 | { | ||
2320 | 58 | EXPECT_THROW({ | ||
2321 | 59 | map.remove_buffer(stub_buffer.id()); | ||
2322 | 60 | }, std::logic_error); | ||
2323 | 61 | } | ||
2324 | 62 | |||
2325 | 63 | TEST_F(ClientBuffers, can_access_once_added) | ||
2326 | 64 | { | ||
2327 | 65 | auto id = map.add_buffer(mt::fake_shared(stub_buffer)); | ||
2328 | 66 | EXPECT_THAT(map.get(id).get(), Eq(&stub_buffer)); | ||
2329 | 67 | } | ||
2330 | 68 | |||
2331 | 69 | TEST_F(ClientBuffers, sends_update_msg_to_send_buffer) | ||
2332 | 70 | { | ||
2333 | 71 | auto id = map.add_buffer(mt::fake_shared(stub_buffer)); | ||
2334 | 72 | auto buffer = map.get(id); | ||
2335 | 73 | EXPECT_CALL(*mock_sink, update_buffer(Ref(*buffer))); | ||
2336 | 74 | map.send_buffer(id); | ||
2337 | 75 | } | ||
2338 | 76 | |||
2339 | 77 | TEST_F(ClientBuffers, sends_no_update_msg_if_buffer_is_not_around) | ||
2340 | 78 | { | ||
2341 | 79 | auto id = map.add_buffer(mt::fake_shared(stub_buffer)); | ||
2342 | 80 | auto buffer = map.get(id); | ||
2343 | 81 | |||
2344 | 82 | EXPECT_CALL(*mock_sink, remove_buffer(Ref(*buffer))); | ||
2345 | 83 | map.remove_buffer(id); | ||
2346 | 84 | map.send_buffer(id); | ||
2347 | 85 | } | ||
2348 | 86 | |||
2349 | 87 | TEST_F(ClientBuffers, can_remove_buffer_from_send_callback) | ||
2350 | 88 | { | ||
2351 | 89 | auto id = map.add_buffer(mt::fake_shared(stub_buffer)); | ||
2352 | 90 | ON_CALL(*mock_sink, update_buffer(_)) | ||
2353 | 91 | .WillByDefault(Invoke( | ||
2354 | 92 | [&] (mg::Buffer& buffer) | ||
2355 | 93 | { | ||
2356 | 94 | map.remove_buffer(buffer.id()); | ||
2357 | 95 | })); | ||
2358 | 96 | |||
2359 | 97 | map.send_buffer(id); | ||
2360 | 98 | } | ||
2361 | 99 | |||
2362 | 100 | TEST_F(ClientBuffers, ignores_unknown_receive) | ||
2363 | 101 | { | ||
2364 | 102 | EXPECT_CALL(*mock_sink, add_buffer(_)) | ||
2365 | 103 | .Times(1); | ||
2366 | 104 | auto id = map.add_buffer(mt::fake_shared(stub_buffer)); | ||
2367 | 105 | map.remove_buffer(id); | ||
2368 | 106 | map.send_buffer(id); | ||
2369 | 107 | } | ||
2370 | 108 | |||
2371 | 109 | TEST_F(ClientBuffers, sends_error_buffer_when_alloc_fails) | ||
2372 | 110 | { | ||
2373 | 111 | std::string error_msg = "a reason"; | ||
2374 | 112 | EXPECT_CALL(*mock_sink, add_buffer(_)) | ||
2375 | 113 | .WillOnce(Throw(std::runtime_error(error_msg))); | ||
2376 | 114 | EXPECT_CALL(*mock_sink, error_buffer(stub_buffer.size(), stub_buffer.pixel_format(), StrEq(error_msg))); | ||
2377 | 115 | mc::BufferMap map{mock_sink}; | ||
2378 | 116 | EXPECT_THROW({ | ||
2379 | 117 | map.add_buffer(mt::fake_shared(stub_buffer)); | ||
2380 | 118 | }, std::runtime_error); | ||
2381 | 119 | } | ||
2382 | 120 | 0 | ||
2383 | === modified file 'tests/unit-tests/compositor/test_dropping_schedule.cpp' | |||
2384 | --- tests/unit-tests/compositor/test_dropping_schedule.cpp 2017-05-08 03:04:26 +0000 | |||
2385 | +++ tests/unit-tests/compositor/test_dropping_schedule.cpp 2017-07-18 03:23:56 +0000 | |||
2386 | @@ -16,7 +16,6 @@ | |||
2387 | 16 | * Authored by: Kevin DuBois <kevin.dubois@canonical.com> | 16 | * Authored by: Kevin DuBois <kevin.dubois@canonical.com> |
2388 | 17 | */ | 17 | */ |
2389 | 18 | 18 | ||
2390 | 19 | #include "mir/frontend/client_buffers.h" | ||
2391 | 20 | #include "src/server/compositor/dropping_schedule.h" | 19 | #include "src/server/compositor/dropping_schedule.h" |
2392 | 21 | #include "mir/test/doubles/stub_buffer.h" | 20 | #include "mir/test/doubles/stub_buffer.h" |
2393 | 22 | #include "mir/test/fake_shared.h" | 21 | #include "mir/test/fake_shared.h" |
2394 | @@ -28,20 +27,9 @@ | |||
2395 | 28 | namespace mt = mir::test; | 27 | namespace mt = mir::test; |
2396 | 29 | namespace mg = mir::graphics; | 28 | namespace mg = mir::graphics; |
2397 | 30 | namespace mc = mir::compositor; | 29 | namespace mc = mir::compositor; |
2398 | 31 | namespace mf = mir::frontend; | ||
2399 | 32 | namespace | 30 | namespace |
2400 | 33 | { | 31 | { |
2401 | 34 | 32 | ||
2402 | 35 | struct MockBufferMap : mf::ClientBuffers | ||
2403 | 36 | { | ||
2404 | 37 | MOCK_METHOD1(add_buffer, mg::BufferID(std::shared_ptr<mg::Buffer> const&)); | ||
2405 | 38 | MOCK_METHOD1(remove_buffer, void(mg::BufferID id)); | ||
2406 | 39 | MOCK_METHOD1(send_buffer, void(mg::BufferID id)); | ||
2407 | 40 | MOCK_METHOD1(receive_buffer, void(mg::BufferID id)); | ||
2408 | 41 | MOCK_CONST_METHOD0(client_owned_buffer_count, size_t()); | ||
2409 | 42 | MOCK_CONST_METHOD1(get, std::shared_ptr<mg::Buffer>(mg::BufferID)); | ||
2410 | 43 | }; | ||
2411 | 44 | |||
2412 | 45 | struct DroppingSchedule : Test | 33 | struct DroppingSchedule : Test |
2413 | 46 | { | 34 | { |
2414 | 47 | DroppingSchedule() | 35 | DroppingSchedule() |
2415 | @@ -52,8 +40,7 @@ | |||
2416 | 52 | unsigned int const num_buffers{5}; | 40 | unsigned int const num_buffers{5}; |
2417 | 53 | std::vector<std::shared_ptr<mg::Buffer>> buffers; | 41 | std::vector<std::shared_ptr<mg::Buffer>> buffers; |
2418 | 54 | 42 | ||
2421 | 55 | MockBufferMap mock_client_buffers; | 43 | mc::DroppingSchedule schedule; |
2420 | 56 | mc::DroppingSchedule schedule{mt::fake_shared(mock_client_buffers)}; | ||
2422 | 57 | std::vector<std::shared_ptr<mg::Buffer>> drain_queue() | 44 | std::vector<std::shared_ptr<mg::Buffer>> drain_queue() |
2423 | 58 | { | 45 | { |
2424 | 59 | std::vector<std::shared_ptr<mg::Buffer>> scheduled_buffers; | 46 | std::vector<std::shared_ptr<mg::Buffer>> scheduled_buffers; |
2425 | @@ -74,49 +61,23 @@ | |||
2426 | 74 | 61 | ||
2427 | 75 | TEST_F(DroppingSchedule, drops_excess_buffers) | 62 | TEST_F(DroppingSchedule, drops_excess_buffers) |
2428 | 76 | { | 63 | { |
2429 | 77 | InSequence seq; | ||
2430 | 78 | EXPECT_CALL(mock_client_buffers, send_buffer(buffers[0]->id())); | ||
2431 | 79 | EXPECT_CALL(mock_client_buffers, send_buffer(buffers[1]->id())); | ||
2432 | 80 | EXPECT_CALL(mock_client_buffers, send_buffer(buffers[2]->id())); | ||
2433 | 81 | EXPECT_CALL(mock_client_buffers, send_buffer(buffers[3]->id())); | ||
2434 | 82 | |||
2435 | 83 | for(auto i = 0u; i < num_buffers; i++) | 64 | for(auto i = 0u; i < num_buffers; i++) |
2436 | 84 | schedule.schedule(buffers[i]); | 65 | schedule.schedule(buffers[i]); |
2437 | 85 | 66 | ||
2438 | 86 | auto queue = drain_queue(); | 67 | auto queue = drain_queue(); |
2439 | 87 | ASSERT_THAT(queue, SizeIs(1)); | 68 | ASSERT_THAT(queue, SizeIs(1)); |
2440 | 69 | |||
2441 | 70 | // The 5th buffer should be scheduled... | ||
2442 | 88 | EXPECT_THAT(queue[0]->id(), Eq(buffers[4]->id())); | 71 | EXPECT_THAT(queue[0]->id(), Eq(buffers[4]->id())); |
2448 | 89 | } | 72 | for (int i = 0; i < 4 ; ++i) |
2444 | 90 | |||
2445 | 91 | TEST_F(DroppingSchedule, nonblocking_schedule_avoids_socket_io) | ||
2446 | 92 | { | ||
2447 | 93 | for (auto i = 0u; i < num_buffers; i++) | ||
2449 | 94 | { | 73 | { |
2464 | 95 | EXPECT_CALL(mock_client_buffers, send_buffer(_)) | 74 | // ...and all the others should have no external references |
2465 | 96 | .Times(0); | 75 | EXPECT_TRUE(buffers[i].unique()); |
2452 | 97 | |||
2453 | 98 | auto deferred_io = schedule.schedule_nonblocking(buffers[i]); | ||
2454 | 99 | |||
2455 | 100 | testing::Mock::VerifyAndClearExpectations(&mock_client_buffers); | ||
2456 | 101 | if (i > 0) | ||
2457 | 102 | { | ||
2458 | 103 | EXPECT_CALL(mock_client_buffers, send_buffer(buffers[i-1]->id())) | ||
2459 | 104 | .Times(1); | ||
2460 | 105 | ASSERT_TRUE(deferred_io.valid()); | ||
2461 | 106 | deferred_io.wait(); | ||
2462 | 107 | testing::Mock::VerifyAndClearExpectations(&mock_client_buffers); | ||
2463 | 108 | } | ||
2466 | 109 | } | 76 | } |
2467 | 110 | |||
2468 | 111 | auto queue = drain_queue(); | ||
2469 | 112 | ASSERT_THAT(queue, SizeIs(1)); | ||
2470 | 113 | EXPECT_THAT(queue[0]->id(), Eq(buffers[4]->id())); | ||
2471 | 114 | } | 77 | } |
2472 | 115 | 78 | ||
2473 | 116 | TEST_F(DroppingSchedule, queueing_same_buffer_many_times_doesnt_drop) | 79 | TEST_F(DroppingSchedule, queueing_same_buffer_many_times_doesnt_drop) |
2474 | 117 | { | 80 | { |
2475 | 118 | EXPECT_CALL(mock_client_buffers, send_buffer(_)).Times(0); | ||
2476 | 119 | |||
2477 | 120 | schedule.schedule(buffers[2]); | 81 | schedule.schedule(buffers[2]); |
2478 | 121 | schedule.schedule(buffers[2]); | 82 | schedule.schedule(buffers[2]); |
2479 | 122 | schedule.schedule(buffers[2]); | 83 | schedule.schedule(buffers[2]); |
2480 | 123 | 84 | ||
2481 | === modified file 'tests/unit-tests/compositor/test_multi_monitor_arbiter.cpp' | |||
2482 | --- tests/unit-tests/compositor/test_multi_monitor_arbiter.cpp 2017-05-26 12:45:45 +0000 | |||
2483 | +++ tests/unit-tests/compositor/test_multi_monitor_arbiter.cpp 2017-07-18 03:23:56 +0000 | |||
2484 | @@ -21,7 +21,7 @@ | |||
2485 | 21 | #include "mir/test/doubles/stub_buffer_allocator.h" | 21 | #include "mir/test/doubles/stub_buffer_allocator.h" |
2486 | 22 | #include "src/server/compositor/multi_monitor_arbiter.h" | 22 | #include "src/server/compositor/multi_monitor_arbiter.h" |
2487 | 23 | #include "src/server/compositor/schedule.h" | 23 | #include "src/server/compositor/schedule.h" |
2489 | 24 | #include "mir/frontend/client_buffers.h" | 24 | #include "src/server/compositor/temporary_buffers.h" |
2490 | 25 | 25 | ||
2491 | 26 | #include <gtest/gtest.h> | 26 | #include <gtest/gtest.h> |
2492 | 27 | using namespace testing; | 27 | using namespace testing; |
2493 | @@ -33,16 +33,6 @@ | |||
2494 | 33 | 33 | ||
2495 | 34 | namespace | 34 | namespace |
2496 | 35 | { | 35 | { |
2497 | 36 | struct MockBufferMap : mf::ClientBuffers | ||
2498 | 37 | { | ||
2499 | 38 | MOCK_METHOD1(add_buffer, mg::BufferID(std::shared_ptr<mg::Buffer> const&)); | ||
2500 | 39 | MOCK_METHOD1(remove_buffer, void(mg::BufferID id)); | ||
2501 | 40 | MOCK_METHOD1(receive_buffer, void(mg::BufferID id)); | ||
2502 | 41 | MOCK_METHOD1(send_buffer, void(mg::BufferID id)); | ||
2503 | 42 | MOCK_CONST_METHOD0(client_owned_buffer_count, size_t()); | ||
2504 | 43 | MOCK_CONST_METHOD1(get, std::shared_ptr<mg::Buffer>(mg::BufferID)); | ||
2505 | 44 | }; | ||
2506 | 45 | |||
2507 | 46 | struct FixedSchedule : mc::Schedule | 36 | struct FixedSchedule : mc::Schedule |
2508 | 47 | { | 37 | { |
2509 | 48 | void schedule(std::shared_ptr<mg::Buffer> const&) override | 38 | void schedule(std::shared_ptr<mg::Buffer> const&) override |
2510 | @@ -63,7 +53,9 @@ | |||
2511 | 63 | { | 53 | { |
2512 | 64 | if (sched.empty() || current == sched.size()) | 54 | if (sched.empty() || current == sched.size()) |
2513 | 65 | throw std::runtime_error("no buffer scheduled"); | 55 | throw std::runtime_error("no buffer scheduled"); |
2515 | 66 | return sched[current++]; | 56 | auto buf = sched.front(); |
2516 | 57 | sched.erase(sched.begin()); | ||
2517 | 58 | return buf; | ||
2518 | 67 | } | 59 | } |
2519 | 68 | void set_schedule(std::vector<std::shared_ptr<mg::Buffer>> s) | 60 | void set_schedule(std::vector<std::shared_ptr<mg::Buffer>> s) |
2520 | 69 | { | 61 | { |
2521 | @@ -84,10 +76,40 @@ | |||
2522 | 84 | } | 76 | } |
2523 | 85 | unsigned int const num_buffers{6u}; | 77 | unsigned int const num_buffers{6u}; |
2524 | 86 | std::vector<std::shared_ptr<mg::Buffer>> buffers; | 78 | std::vector<std::shared_ptr<mg::Buffer>> buffers; |
2525 | 87 | NiceMock<MockBufferMap> mock_map; | ||
2526 | 88 | FixedSchedule schedule; | 79 | FixedSchedule schedule; |
2528 | 89 | mc::MultiMonitorArbiter arbiter{mt::fake_shared(mock_map), mt::fake_shared(schedule)}; | 80 | mc::MultiMonitorArbiter arbiter{mt::fake_shared(schedule)}; |
2529 | 90 | }; | 81 | }; |
2530 | 82 | |||
2531 | 83 | MATCHER_P(IsSameBufferAs, buffer, "") | ||
2532 | 84 | { | ||
2533 | 85 | return buffer->id() == arg->id(); | ||
2534 | 86 | } | ||
2535 | 87 | |||
2536 | 88 | std::shared_ptr<mg::Buffer> wrap_with_destruction_notifier( | ||
2537 | 89 | std::shared_ptr<mg::Buffer> const& buffer, | ||
2538 | 90 | std::shared_ptr<bool> const& destroyed) | ||
2539 | 91 | { | ||
2540 | 92 | class DestructionNotifyingBuffer : public mc::TemporaryBuffer | ||
2541 | 93 | { | ||
2542 | 94 | public: | ||
2543 | 95 | DestructionNotifyingBuffer( | ||
2544 | 96 | std::shared_ptr<mg::Buffer> const& buffer, | ||
2545 | 97 | std::shared_ptr<bool> const& destroyed) | ||
2546 | 98 | : TemporaryBuffer(buffer), | ||
2547 | 99 | destroyed{destroyed} | ||
2548 | 100 | { | ||
2549 | 101 | } | ||
2550 | 102 | |||
2551 | 103 | ~DestructionNotifyingBuffer() | ||
2552 | 104 | { | ||
2553 | 105 | *destroyed = true; | ||
2554 | 106 | } | ||
2555 | 107 | private: | ||
2556 | 108 | std::shared_ptr<bool> const destroyed; | ||
2557 | 109 | }; | ||
2558 | 110 | |||
2559 | 111 | return std::make_shared<DestructionNotifyingBuffer>(buffer, destroyed); | ||
2560 | 112 | } | ||
2561 | 91 | } | 113 | } |
2562 | 92 | 114 | ||
2563 | 93 | TEST_F(MultiMonitorArbiter, compositor_access_before_any_submission_throws) | 115 | TEST_F(MultiMonitorArbiter, compositor_access_before_any_submission_throws) |
2564 | @@ -107,32 +129,30 @@ | |||
2565 | 107 | { | 129 | { |
2566 | 108 | schedule.set_schedule({buffers[0]}); | 130 | schedule.set_schedule({buffers[0]}); |
2567 | 109 | auto cbuffer = arbiter.compositor_acquire(this); | 131 | auto cbuffer = arbiter.compositor_acquire(this); |
2569 | 110 | EXPECT_THAT(cbuffer, Eq(buffers[0])); | 132 | EXPECT_THAT(cbuffer, IsSameBufferAs(buffers[0])); |
2570 | 111 | } | 133 | } |
2571 | 112 | 134 | ||
2572 | 113 | TEST_F(MultiMonitorArbiter, compositor_release_sends_buffer_back) | 135 | TEST_F(MultiMonitorArbiter, compositor_release_sends_buffer_back) |
2573 | 114 | { | 136 | { |
2577 | 115 | EXPECT_CALL(mock_map, send_buffer(buffers[0]->id())); | 137 | auto buffer_released = std::make_shared<bool>(false); |
2578 | 116 | 138 | schedule.set_schedule({ wrap_with_destruction_notifier(buffers[0], buffer_released) }); | |
2576 | 117 | schedule.set_schedule({buffers[0]}); | ||
2579 | 118 | 139 | ||
2580 | 119 | auto cbuffer = arbiter.compositor_acquire(this); | 140 | auto cbuffer = arbiter.compositor_acquire(this); |
2581 | 120 | schedule.set_schedule({buffers[1]}); | 141 | schedule.set_schedule({buffers[1]}); |
2582 | 121 | arbiter.compositor_release(cbuffer); | 142 | arbiter.compositor_release(cbuffer); |
2583 | 143 | cbuffer.reset(); | ||
2584 | 144 | // We need to acquire a new buffer - the current one is on-screen, so can't be sent back. | ||
2585 | 145 | arbiter.compositor_acquire(this); | ||
2586 | 146 | EXPECT_TRUE(*buffer_released); | ||
2587 | 122 | } | 147 | } |
2588 | 123 | 148 | ||
2589 | 124 | TEST_F(MultiMonitorArbiter, compositor_can_acquire_different_buffers) | 149 | TEST_F(MultiMonitorArbiter, compositor_can_acquire_different_buffers) |
2590 | 125 | { | 150 | { |
2591 | 126 | EXPECT_CALL(mock_map, send_buffer(buffers[0]->id())); | ||
2592 | 127 | |||
2593 | 128 | schedule.set_schedule({buffers[0]}); | 151 | schedule.set_schedule({buffers[0]}); |
2594 | 129 | auto cbuffer1 = arbiter.compositor_acquire(this); | 152 | auto cbuffer1 = arbiter.compositor_acquire(this); |
2595 | 130 | schedule.set_schedule({buffers[1]}); | 153 | schedule.set_schedule({buffers[1]}); |
2596 | 131 | auto cbuffer2 = arbiter.compositor_acquire(this); | 154 | auto cbuffer2 = arbiter.compositor_acquire(this); |
2601 | 132 | EXPECT_THAT(cbuffer1, Ne(cbuffer2)); | 155 | EXPECT_THAT(cbuffer1, Not(IsSameBufferAs(cbuffer2))); |
2598 | 133 | arbiter.compositor_release(cbuffer2); | ||
2599 | 134 | arbiter.compositor_release(cbuffer1); | ||
2600 | 135 | Mock::VerifyAndClearExpectations(&mock_map); | ||
2602 | 136 | } | 156 | } |
2603 | 137 | 157 | ||
2604 | 138 | TEST_F(MultiMonitorArbiter, compositor_buffer_syncs_to_fastest_compositor) | 158 | TEST_F(MultiMonitorArbiter, compositor_buffer_syncs_to_fastest_compositor) |
2605 | @@ -155,13 +175,13 @@ | |||
2606 | 155 | auto cbuffer6 = arbiter.compositor_acquire(&comp_id2); | 175 | auto cbuffer6 = arbiter.compositor_acquire(&comp_id2); |
2607 | 156 | auto cbuffer7 = arbiter.compositor_acquire(&comp_id2); | 176 | auto cbuffer7 = arbiter.compositor_acquire(&comp_id2); |
2608 | 157 | 177 | ||
2616 | 158 | EXPECT_THAT(cbuffer1, Eq(buffers[0])); | 178 | EXPECT_THAT(cbuffer1, IsSameBufferAs(buffers[0])); |
2617 | 159 | EXPECT_THAT(cbuffer2, Eq(buffers[0])); | 179 | EXPECT_THAT(cbuffer2, IsSameBufferAs(buffers[0])); |
2618 | 160 | EXPECT_THAT(cbuffer3, Eq(buffers[1])); | 180 | EXPECT_THAT(cbuffer3, IsSameBufferAs(buffers[1])); |
2619 | 161 | EXPECT_THAT(cbuffer4, Eq(buffers[0])); | 181 | EXPECT_THAT(cbuffer4, IsSameBufferAs(buffers[0])); |
2620 | 162 | EXPECT_THAT(cbuffer5, Eq(buffers[0])); | 182 | EXPECT_THAT(cbuffer5, IsSameBufferAs(buffers[0])); |
2621 | 163 | EXPECT_THAT(cbuffer6, Eq(buffers[1])); | 183 | EXPECT_THAT(cbuffer6, IsSameBufferAs(buffers[1])); |
2622 | 164 | EXPECT_THAT(cbuffer7, Eq(buffers[1])); | 184 | EXPECT_THAT(cbuffer7, IsSameBufferAs(buffers[1])); |
2623 | 165 | } | 185 | } |
2624 | 166 | 186 | ||
2625 | 167 | TEST_F(MultiMonitorArbiter, compositor_consumes_all_buffers_when_operating_as_a_composited_scene_would) | 187 | TEST_F(MultiMonitorArbiter, compositor_consumes_all_buffers_when_operating_as_a_composited_scene_would) |
2626 | @@ -179,11 +199,11 @@ | |||
2627 | 179 | auto cbuffer5 = arbiter.compositor_acquire(this); | 199 | auto cbuffer5 = arbiter.compositor_acquire(this); |
2628 | 180 | arbiter.compositor_release(cbuffer5); | 200 | arbiter.compositor_release(cbuffer5); |
2629 | 181 | 201 | ||
2635 | 182 | EXPECT_THAT(cbuffer1, Eq(buffers[0])); | 202 | EXPECT_THAT(cbuffer1, IsSameBufferAs(buffers[0])); |
2636 | 183 | EXPECT_THAT(cbuffer2, Eq(buffers[1])); | 203 | EXPECT_THAT(cbuffer2, IsSameBufferAs(buffers[1])); |
2637 | 184 | EXPECT_THAT(cbuffer3, Eq(buffers[2])); | 204 | EXPECT_THAT(cbuffer3, IsSameBufferAs(buffers[2])); |
2638 | 185 | EXPECT_THAT(cbuffer4, Eq(buffers[3])); | 205 | EXPECT_THAT(cbuffer4, IsSameBufferAs(buffers[3])); |
2639 | 186 | EXPECT_THAT(cbuffer5, Eq(buffers[4])); | 206 | EXPECT_THAT(cbuffer5, IsSameBufferAs(buffers[4])); |
2640 | 187 | } | 207 | } |
2641 | 188 | 208 | ||
2642 | 189 | TEST_F(MultiMonitorArbiter, compositor_consumes_all_buffers_when_operating_as_a_bypassed_buffer_would) | 209 | TEST_F(MultiMonitorArbiter, compositor_consumes_all_buffers_when_operating_as_a_bypassed_buffer_would) |
2643 | @@ -201,11 +221,11 @@ | |||
2644 | 201 | arbiter.compositor_release(cbuffer4); | 221 | arbiter.compositor_release(cbuffer4); |
2645 | 202 | arbiter.compositor_release(cbuffer5); | 222 | arbiter.compositor_release(cbuffer5); |
2646 | 203 | 223 | ||
2652 | 204 | EXPECT_THAT(cbuffer1, Eq(buffers[0])); | 224 | EXPECT_THAT(cbuffer1, IsSameBufferAs(buffers[0])); |
2653 | 205 | EXPECT_THAT(cbuffer2, Eq(buffers[1])); | 225 | EXPECT_THAT(cbuffer2, IsSameBufferAs(buffers[1])); |
2654 | 206 | EXPECT_THAT(cbuffer3, Eq(buffers[2])); | 226 | EXPECT_THAT(cbuffer3, IsSameBufferAs(buffers[2])); |
2655 | 207 | EXPECT_THAT(cbuffer4, Eq(buffers[3])); | 227 | EXPECT_THAT(cbuffer4, IsSameBufferAs(buffers[3])); |
2656 | 208 | EXPECT_THAT(cbuffer5, Eq(buffers[4])); | 228 | EXPECT_THAT(cbuffer5, IsSameBufferAs(buffers[4])); |
2657 | 209 | } | 229 | } |
2658 | 210 | 230 | ||
2659 | 211 | TEST_F(MultiMonitorArbiter, multimonitor_compositor_buffer_syncs_to_fastest_with_more_queueing) | 231 | TEST_F(MultiMonitorArbiter, multimonitor_compositor_buffer_syncs_to_fastest_with_more_queueing) |
2660 | @@ -228,18 +248,18 @@ | |||
2661 | 228 | auto cbuffer7 = arbiter.compositor_acquire(&comp_id2); //buffer[4] | 248 | auto cbuffer7 = arbiter.compositor_acquire(&comp_id2); //buffer[4] |
2662 | 229 | auto cbuffer8 = arbiter.compositor_acquire(&comp_id1); //buffer[4] | 249 | auto cbuffer8 = arbiter.compositor_acquire(&comp_id1); //buffer[4] |
2663 | 230 | 250 | ||
2676 | 231 | EXPECT_THAT(cbuffer1, Eq(buffers[0])); | 251 | EXPECT_THAT(cbuffer1, IsSameBufferAs(buffers[0])); |
2677 | 232 | EXPECT_THAT(cbuffer2, Eq(buffers[0])); | 252 | EXPECT_THAT(cbuffer2, IsSameBufferAs(buffers[0])); |
2678 | 233 | 253 | ||
2679 | 234 | EXPECT_THAT(cbuffer3, Eq(buffers[1])); | 254 | EXPECT_THAT(cbuffer3, IsSameBufferAs(buffers[1])); |
2680 | 235 | 255 | ||
2681 | 236 | EXPECT_THAT(cbuffer4, Eq(buffers[2])); | 256 | EXPECT_THAT(cbuffer4, IsSameBufferAs(buffers[2])); |
2682 | 237 | EXPECT_THAT(cbuffer5, Eq(buffers[2])); | 257 | EXPECT_THAT(cbuffer5, IsSameBufferAs(buffers[2])); |
2683 | 238 | 258 | ||
2684 | 239 | EXPECT_THAT(cbuffer6, Eq(buffers[3])); | 259 | EXPECT_THAT(cbuffer6, IsSameBufferAs(buffers[3])); |
2685 | 240 | 260 | ||
2686 | 241 | EXPECT_THAT(cbuffer7, Eq(buffers[4])); | 261 | EXPECT_THAT(cbuffer7, IsSameBufferAs(buffers[4])); |
2687 | 242 | EXPECT_THAT(cbuffer8, Eq(buffers[4])); | 262 | EXPECT_THAT(cbuffer8, IsSameBufferAs(buffers[4])); |
2688 | 243 | } | 263 | } |
2689 | 244 | 264 | ||
2690 | 245 | TEST_F(MultiMonitorArbiter, can_set_a_new_schedule) | 265 | TEST_F(MultiMonitorArbiter, can_set_a_new_schedule) |
2691 | @@ -252,8 +272,8 @@ | |||
2692 | 252 | arbiter.set_schedule(mt::fake_shared(another_schedule)); | 272 | arbiter.set_schedule(mt::fake_shared(another_schedule)); |
2693 | 253 | auto cbuffer2 = arbiter.compositor_acquire(this); | 273 | auto cbuffer2 = arbiter.compositor_acquire(this); |
2694 | 254 | 274 | ||
2697 | 255 | EXPECT_THAT(cbuffer1, Eq(buffers[3])); | 275 | EXPECT_THAT(cbuffer1, IsSameBufferAs(buffers[3])); |
2698 | 256 | EXPECT_THAT(cbuffer2, Eq(buffers[0])); | 276 | EXPECT_THAT(cbuffer2, IsSameBufferAs(buffers[0])); |
2699 | 257 | } | 277 | } |
2700 | 258 | 278 | ||
2701 | 259 | TEST_F(MultiMonitorArbiter, basic_snapshot_equals_compositor_buffer) | 279 | TEST_F(MultiMonitorArbiter, basic_snapshot_equals_compositor_buffer) |
2702 | @@ -262,7 +282,7 @@ | |||
2703 | 262 | 282 | ||
2704 | 263 | auto cbuffer1 = arbiter.compositor_acquire(this); | 283 | auto cbuffer1 = arbiter.compositor_acquire(this); |
2705 | 264 | auto sbuffer1 = arbiter.snapshot_acquire(); | 284 | auto sbuffer1 = arbiter.snapshot_acquire(); |
2707 | 265 | EXPECT_EQ(cbuffer1, sbuffer1); | 285 | EXPECT_THAT(cbuffer1, IsSameBufferAs(sbuffer1)); |
2708 | 266 | } | 286 | } |
2709 | 267 | 287 | ||
2710 | 268 | TEST_F(MultiMonitorArbiter, basic_snapshot_equals_latest_compositor_buffer) | 288 | TEST_F(MultiMonitorArbiter, basic_snapshot_equals_latest_compositor_buffer) |
2711 | @@ -278,8 +298,8 @@ | |||
2712 | 278 | cbuffer2 = arbiter.compositor_acquire(&that); | 298 | cbuffer2 = arbiter.compositor_acquire(&that); |
2713 | 279 | 299 | ||
2714 | 280 | auto sbuffer2 = arbiter.snapshot_acquire(); | 300 | auto sbuffer2 = arbiter.snapshot_acquire(); |
2717 | 281 | EXPECT_EQ(cbuffer1, sbuffer1); | 301 | EXPECT_THAT(cbuffer1, IsSameBufferAs(sbuffer1)); |
2718 | 282 | EXPECT_EQ(cbuffer2, sbuffer2); | 302 | EXPECT_THAT(cbuffer2, IsSameBufferAs(sbuffer2)); |
2719 | 283 | } | 303 | } |
2720 | 284 | 304 | ||
2721 | 285 | TEST_F(MultiMonitorArbiter, snapshot_cycling_doesnt_advance_buffer_for_compositors) | 305 | TEST_F(MultiMonitorArbiter, snapshot_cycling_doesnt_advance_buffer_for_compositors) |
2722 | @@ -297,8 +317,8 @@ | |||
2723 | 297 | } | 317 | } |
2724 | 298 | auto cbuffer2 = arbiter.compositor_acquire(&that); | 318 | auto cbuffer2 = arbiter.compositor_acquire(&that); |
2725 | 299 | 319 | ||
2728 | 300 | EXPECT_THAT(cbuffer1, Eq(cbuffer2)); | 320 | EXPECT_THAT(cbuffer1, IsSameBufferAs(cbuffer2)); |
2729 | 301 | EXPECT_THAT(snapshot_buffers, Each(cbuffer1)); | 321 | EXPECT_THAT(snapshot_buffers, Each(IsSameBufferAs(cbuffer1))); |
2730 | 302 | } | 322 | } |
2731 | 303 | 323 | ||
2732 | 304 | TEST_F(MultiMonitorArbiter, no_buffers_available_throws_on_snapshot) | 324 | TEST_F(MultiMonitorArbiter, no_buffers_available_throws_on_snapshot) |
2733 | @@ -311,29 +331,48 @@ | |||
2734 | 311 | 331 | ||
2735 | 312 | TEST_F(MultiMonitorArbiter, snapshotting_will_release_buffer_if_it_was_the_last_owner) | 332 | TEST_F(MultiMonitorArbiter, snapshotting_will_release_buffer_if_it_was_the_last_owner) |
2736 | 313 | { | 333 | { |
2739 | 314 | EXPECT_CALL(mock_map, send_buffer(_)).Times(0); | 334 | auto buffer_released = std::make_shared<bool>(false); |
2740 | 315 | schedule.set_schedule({buffers[3],buffers[4]}); | 335 | schedule.set_schedule( |
2741 | 336 | { | ||
2742 | 337 | wrap_with_destruction_notifier(buffers[3], buffer_released), | ||
2743 | 338 | buffers[4] | ||
2744 | 339 | }); | ||
2745 | 316 | auto cbuffer1 = arbiter.compositor_acquire(this); | 340 | auto cbuffer1 = arbiter.compositor_acquire(this); |
2746 | 317 | auto sbuffer1 = arbiter.snapshot_acquire(); | 341 | auto sbuffer1 = arbiter.snapshot_acquire(); |
2747 | 318 | arbiter.compositor_release(cbuffer1); | 342 | arbiter.compositor_release(cbuffer1); |
2751 | 319 | 343 | cbuffer1.reset(); | |
2752 | 320 | Mock::VerifyAndClearExpectations(&mock_map); | 344 | |
2753 | 321 | EXPECT_CALL(mock_map, send_buffer(sbuffer1->id())); | 345 | // Acquire a new buffer so first one is no longer onscreen. |
2754 | 346 | arbiter.compositor_acquire(this); | ||
2755 | 347 | |||
2756 | 348 | EXPECT_FALSE(*buffer_released); | ||
2757 | 322 | arbiter.snapshot_release(sbuffer1); | 349 | arbiter.snapshot_release(sbuffer1); |
2758 | 350 | sbuffer1.reset(); | ||
2759 | 351 | EXPECT_TRUE(*buffer_released); | ||
2760 | 323 | } | 352 | } |
2761 | 324 | 353 | ||
2762 | 325 | TEST_F(MultiMonitorArbiter, compositor_can_acquire_a_few_times_and_only_sends_on_the_last_release) | 354 | TEST_F(MultiMonitorArbiter, compositor_can_acquire_a_few_times_and_only_sends_on_the_last_release) |
2763 | 326 | { | 355 | { |
2764 | 327 | int comp_id1{0}; | 356 | int comp_id1{0}; |
2765 | 328 | int comp_id2{0}; | 357 | int comp_id2{0}; |
2767 | 329 | schedule.set_schedule({buffers[0], buffers[1]}); | 358 | |
2768 | 359 | auto buffer_released = std::make_shared<bool>(false); | ||
2769 | 360 | schedule.set_schedule( | ||
2770 | 361 | { | ||
2771 | 362 | wrap_with_destruction_notifier(buffers[0], buffer_released), | ||
2772 | 363 | buffers[1] | ||
2773 | 364 | }); | ||
2774 | 330 | auto cbuffer1 = arbiter.compositor_acquire(&comp_id1); | 365 | auto cbuffer1 = arbiter.compositor_acquire(&comp_id1); |
2775 | 331 | auto cbuffer2 = arbiter.compositor_acquire(&comp_id2); | 366 | auto cbuffer2 = arbiter.compositor_acquire(&comp_id2); |
2778 | 332 | EXPECT_THAT(cbuffer1, Eq(cbuffer2)); | 367 | EXPECT_THAT(cbuffer1, IsSameBufferAs(cbuffer2)); |
2779 | 333 | EXPECT_CALL(mock_map, send_buffer(buffers[0]->id())).Times(Exactly(1)); | 368 | |
2780 | 334 | auto cbuffer3 = arbiter.compositor_acquire(&comp_id1); | 369 | auto cbuffer3 = arbiter.compositor_acquire(&comp_id1); |
2781 | 335 | arbiter.compositor_release(cbuffer2); | 370 | arbiter.compositor_release(cbuffer2); |
2782 | 371 | EXPECT_FALSE(*buffer_released); | ||
2783 | 336 | arbiter.compositor_release(cbuffer1); | 372 | arbiter.compositor_release(cbuffer1); |
2784 | 373 | cbuffer1.reset(); | ||
2785 | 374 | cbuffer2.reset(); | ||
2786 | 375 | EXPECT_TRUE(*buffer_released); | ||
2787 | 337 | } | 376 | } |
2788 | 338 | 377 | ||
2789 | 339 | TEST_F(MultiMonitorArbiter, advance_on_fastest_has_same_buffer) | 378 | TEST_F(MultiMonitorArbiter, advance_on_fastest_has_same_buffer) |
2790 | @@ -349,29 +388,29 @@ | |||
2791 | 349 | 388 | ||
2792 | 350 | auto cbuffer3 = arbiter.compositor_acquire(&comp_id1); //buffer[1] | 389 | auto cbuffer3 = arbiter.compositor_acquire(&comp_id1); //buffer[1] |
2793 | 351 | 390 | ||
2809 | 352 | EXPECT_THAT(cbuffer1, Eq(cbuffer2)); | 391 | EXPECT_THAT(cbuffer1, IsSameBufferAs(cbuffer2)); |
2810 | 353 | EXPECT_THAT(cbuffer1, Eq(buffers[0])); | 392 | EXPECT_THAT(cbuffer1, IsSameBufferAs(buffers[0])); |
2811 | 354 | EXPECT_THAT(cbuffer3, Eq(buffers[1])); | 393 | EXPECT_THAT(cbuffer3, IsSameBufferAs(buffers[1])); |
2797 | 355 | } | ||
2798 | 356 | |||
2799 | 357 | TEST_F(MultiMonitorArbiter, compositor_acquire_sends_buffer_back_with_fastest_guarantee) | ||
2800 | 358 | { | ||
2801 | 359 | EXPECT_CALL(mock_map, send_buffer(buffers[0]->id())); | ||
2802 | 360 | |||
2803 | 361 | schedule.set_schedule({buffers[0], buffers[1]}); | ||
2804 | 362 | |||
2805 | 363 | auto cbuffer = arbiter.compositor_acquire(this); | ||
2806 | 364 | schedule.set_schedule({buffers[1]}); | ||
2807 | 365 | arbiter.compositor_release(cbuffer); | ||
2808 | 366 | cbuffer = arbiter.compositor_acquire(this); | ||
2812 | 367 | } | 394 | } |
2813 | 368 | 395 | ||
2814 | 369 | TEST_F(MultiMonitorArbiter, buffers_are_sent_back) | 396 | TEST_F(MultiMonitorArbiter, buffers_are_sent_back) |
2815 | 370 | { | 397 | { |
2817 | 371 | EXPECT_CALL(mock_map, send_buffer(_)).Times(3); | 398 | std::array<std::shared_ptr<bool>, 3> buffer_released = { |
2818 | 399 | { | ||
2819 | 400 | std::make_shared<bool>(false), | ||
2820 | 401 | std::make_shared<bool>(false), | ||
2821 | 402 | std::make_shared<bool>(false) | ||
2822 | 403 | }}; | ||
2823 | 372 | int comp_id1{0}; | 404 | int comp_id1{0}; |
2824 | 373 | int comp_id2{0}; | 405 | int comp_id2{0}; |
2826 | 374 | schedule.set_schedule({buffers[0], buffers[1], buffers[2], buffers[3]}); | 406 | |
2827 | 407 | schedule.set_schedule( | ||
2828 | 408 | { | ||
2829 | 409 | wrap_with_destruction_notifier(buffers[0], buffer_released[0]), | ||
2830 | 410 | wrap_with_destruction_notifier(buffers[1], buffer_released[1]), | ||
2831 | 411 | wrap_with_destruction_notifier(buffers[2], buffer_released[2]), | ||
2832 | 412 | buffers[3] | ||
2833 | 413 | }); | ||
2834 | 375 | 414 | ||
2835 | 376 | auto b1 = arbiter.compositor_acquire(&comp_id1); | 415 | auto b1 = arbiter.compositor_acquire(&comp_id1); |
2836 | 377 | arbiter.compositor_release(b1); | 416 | arbiter.compositor_release(b1); |
2837 | @@ -386,7 +425,14 @@ | |||
2838 | 386 | auto b6 = arbiter.compositor_acquire(&comp_id1); | 425 | auto b6 = arbiter.compositor_acquire(&comp_id1); |
2839 | 387 | arbiter.compositor_release(b6); | 426 | arbiter.compositor_release(b6); |
2840 | 388 | 427 | ||
2842 | 389 | Mock::VerifyAndClearExpectations(&mock_map); | 428 | b1.reset(); |
2843 | 429 | b2.reset(); | ||
2844 | 430 | b3.reset(); | ||
2845 | 431 | b4.reset(); | ||
2846 | 432 | b5.reset(); | ||
2847 | 433 | b6.reset(); | ||
2848 | 434 | |||
2849 | 435 | EXPECT_THAT(buffer_released, Each(Pointee(true))); | ||
2850 | 390 | } | 436 | } |
2851 | 391 | 437 | ||
2852 | 392 | TEST_F(MultiMonitorArbiter, can_check_if_buffers_are_ready) | 438 | TEST_F(MultiMonitorArbiter, can_check_if_buffers_are_ready) |
2853 | @@ -442,17 +488,28 @@ | |||
2854 | 442 | TEST_F(MultiMonitorArbiter, will_release_buffer_in_nbuffers_2_overlay_scenario) | 488 | TEST_F(MultiMonitorArbiter, will_release_buffer_in_nbuffers_2_overlay_scenario) |
2855 | 443 | { | 489 | { |
2856 | 444 | int comp_id1{0}; | 490 | int comp_id1{0}; |
2858 | 445 | schedule.set_schedule({buffers[0], buffers[1], buffers[0], buffers[1]}); | 491 | auto buffer_released = std::make_shared<bool>(false); |
2859 | 492 | auto notifying_buffer = wrap_with_destruction_notifier(buffers[0], buffer_released); | ||
2860 | 493 | schedule.set_schedule( | ||
2861 | 494 | { | ||
2862 | 495 | notifying_buffer, | ||
2863 | 496 | buffers[1], | ||
2864 | 497 | buffers[0], // We only want to be notified when the first submission is released | ||
2865 | 498 | buffers[1] | ||
2866 | 499 | }); | ||
2867 | 500 | notifying_buffer.reset(); | ||
2868 | 446 | 501 | ||
2869 | 447 | EXPECT_CALL(mock_map, send_buffer(buffers[0]->id())); | ||
2870 | 448 | auto b1 = arbiter.compositor_acquire(&comp_id1); | 502 | auto b1 = arbiter.compositor_acquire(&comp_id1); |
2871 | 449 | auto b2 = arbiter.compositor_acquire(&comp_id1); | 503 | auto b2 = arbiter.compositor_acquire(&comp_id1); |
2874 | 450 | EXPECT_THAT(b1, Eq(buffers[0])); | 504 | EXPECT_THAT(b1, IsSameBufferAs(buffers[0])); |
2875 | 451 | EXPECT_THAT(b2, Eq(buffers[1])); | 505 | EXPECT_THAT(b2, IsSameBufferAs(buffers[1])); |
2876 | 452 | arbiter.compositor_release(b1); | 506 | arbiter.compositor_release(b1); |
2877 | 453 | arbiter.compositor_release(b2); | 507 | arbiter.compositor_release(b2); |
2880 | 454 | Mock::VerifyAndClearExpectations(&mock_map); | 508 | b1.reset(); |
2881 | 455 | } | 509 | b2.reset(); |
2882 | 510 | |||
2883 | 511 | EXPECT_TRUE(*buffer_released); | ||
2884 | 512 | } | ||
2885 | 456 | 513 | ||
2886 | 457 | TEST_F(MultiMonitorArbiter, will_release_buffer_in_nbuffers_2_starvation_scenario) | 514 | TEST_F(MultiMonitorArbiter, will_release_buffer_in_nbuffers_2_starvation_scenario) |
2887 | 458 | { | 515 | { |
2888 | @@ -471,10 +528,10 @@ | |||
2889 | 471 | arbiter.compositor_release(b2); | 528 | arbiter.compositor_release(b2); |
2890 | 472 | arbiter.compositor_release(b4); | 529 | arbiter.compositor_release(b4); |
2891 | 473 | 530 | ||
2896 | 474 | EXPECT_THAT(b1, Eq(buffers[0])); | 531 | EXPECT_THAT(b1, IsSameBufferAs(buffers[0])); |
2897 | 475 | EXPECT_THAT(b2, Eq(buffers[1])); | 532 | EXPECT_THAT(b2, IsSameBufferAs(buffers[1])); |
2898 | 476 | EXPECT_THAT(b3, Eq(buffers[1])); | 533 | EXPECT_THAT(b3, IsSameBufferAs(buffers[1])); |
2899 | 477 | EXPECT_THAT(b4, Eq(buffers[0])); | 534 | EXPECT_THAT(b4, IsSameBufferAs(buffers[0])); |
2900 | 478 | 535 | ||
2901 | 479 | } | 536 | } |
2902 | 480 | 537 | ||
2903 | @@ -482,13 +539,12 @@ | |||
2904 | 482 | { | 539 | { |
2905 | 483 | int comp_id1{0}; | 540 | int comp_id1{0}; |
2906 | 484 | int comp_id2{0}; | 541 | int comp_id2{0}; |
2907 | 542 | |||
2908 | 485 | schedule.set_schedule({ | 543 | schedule.set_schedule({ |
2909 | 486 | buffers[0], buffers[1], buffers[2], | 544 | buffers[0], buffers[1], buffers[2], |
2910 | 487 | buffers[0], buffers[1], buffers[2], | 545 | buffers[0], buffers[1], buffers[2], |
2911 | 488 | buffers[0], buffers[1], buffers[2]}); | 546 | buffers[0], buffers[1], buffers[2]}); |
2912 | 489 | 547 | ||
2913 | 490 | EXPECT_CALL(mock_map, send_buffer(buffers[0]->id())); | ||
2914 | 491 | |||
2915 | 492 | auto b1 = arbiter.compositor_acquire(&comp_id1); | 548 | auto b1 = arbiter.compositor_acquire(&comp_id1); |
2916 | 493 | auto b2 = arbiter.compositor_acquire(&comp_id2); | 549 | auto b2 = arbiter.compositor_acquire(&comp_id2); |
2917 | 494 | arbiter.compositor_release(b1); //send nothing | 550 | arbiter.compositor_release(b1); //send nothing |
2918 | @@ -502,13 +558,12 @@ | |||
2919 | 502 | auto b5 = arbiter.compositor_acquire(&comp_id1); | 558 | auto b5 = arbiter.compositor_acquire(&comp_id1); |
2920 | 503 | arbiter.compositor_release(b5); //send nothing | 559 | arbiter.compositor_release(b5); //send nothing |
2921 | 504 | 560 | ||
2929 | 505 | EXPECT_THAT(b1, Eq(buffers[0])); | 561 | EXPECT_THAT(b1, IsSameBufferAs(buffers[0])); |
2930 | 506 | EXPECT_THAT(b2, Eq(buffers[0])); | 562 | EXPECT_THAT(b2, IsSameBufferAs(buffers[0])); |
2931 | 507 | EXPECT_THAT(b3, Eq(buffers[1])); | 563 | EXPECT_THAT(b3, IsSameBufferAs(buffers[1])); |
2932 | 508 | EXPECT_THAT(b4, Eq(buffers[1])); | 564 | EXPECT_THAT(b4, IsSameBufferAs(buffers[1])); |
2933 | 509 | EXPECT_THAT(b5, Eq(buffers[2])); | 565 | EXPECT_THAT(b5, IsSameBufferAs(buffers[2])); |
2934 | 510 | Mock::VerifyAndClearExpectations(&mock_map); | 566 | } |
2928 | 511 | } | ||
2935 | 512 | 567 | ||
2936 | 513 | TEST_F(MultiMonitorArbiter, can_advance_buffer_manually) | 568 | TEST_F(MultiMonitorArbiter, can_advance_buffer_manually) |
2937 | 514 | { | 569 | { |
2938 | @@ -521,11 +576,11 @@ | |||
2939 | 521 | 576 | ||
2940 | 522 | auto b1 = arbiter.compositor_acquire(&comp_id1); | 577 | auto b1 = arbiter.compositor_acquire(&comp_id1); |
2941 | 523 | auto b2 = arbiter.compositor_acquire(&comp_id2); | 578 | auto b2 = arbiter.compositor_acquire(&comp_id2); |
2944 | 524 | EXPECT_THAT(b1->id(), Eq(buffers[1]->id())); | 579 | EXPECT_THAT(b1, IsSameBufferAs(buffers[1])); |
2945 | 525 | EXPECT_THAT(b2->id(), Eq(buffers[1]->id())); | 580 | EXPECT_THAT(b2, IsSameBufferAs(buffers[1])); |
2946 | 526 | 581 | ||
2947 | 527 | auto b3 = arbiter.compositor_acquire(&comp_id1); | 582 | auto b3 = arbiter.compositor_acquire(&comp_id1); |
2949 | 528 | EXPECT_THAT(b3->id(), Eq(buffers[2]->id())); | 583 | EXPECT_THAT(b3, IsSameBufferAs(buffers[2])); |
2950 | 529 | } | 584 | } |
2951 | 530 | 585 | ||
2952 | 531 | TEST_F(MultiMonitorArbiter, checks_if_buffer_is_valid_after_clean_onscreen_buffer) | 586 | TEST_F(MultiMonitorArbiter, checks_if_buffer_is_valid_after_clean_onscreen_buffer) |
2953 | @@ -547,8 +602,12 @@ | |||
2954 | 547 | 602 | ||
2955 | 548 | TEST_F(MultiMonitorArbiter, releases_buffer_on_destruction) | 603 | TEST_F(MultiMonitorArbiter, releases_buffer_on_destruction) |
2956 | 549 | { | 604 | { |
2961 | 550 | mc::MultiMonitorArbiter arbiter{mt::fake_shared(mock_map), mt::fake_shared(schedule)}; | 605 | auto buffer_released = std::make_shared<bool>(false); |
2962 | 551 | EXPECT_CALL(mock_map, send_buffer(buffers[0]->id())); | 606 | schedule.set_schedule({wrap_with_destruction_notifier(buffers[0], buffer_released)}); |
2963 | 552 | schedule.set_schedule({buffers[0]}); | 607 | |
2964 | 553 | arbiter.advance_schedule(); | 608 | { |
2965 | 609 | mc::MultiMonitorArbiter arbiter{mt::fake_shared(schedule)}; | ||
2966 | 610 | arbiter.advance_schedule(); | ||
2967 | 611 | } | ||
2968 | 612 | EXPECT_TRUE(*buffer_released); | ||
2969 | 554 | } | 613 | } |
2970 | 555 | 614 | ||
2971 | === modified file 'tests/unit-tests/compositor/test_stream.cpp' | |||
2972 | --- tests/unit-tests/compositor/test_stream.cpp 2017-05-08 03:04:26 +0000 | |||
2973 | +++ tests/unit-tests/compositor/test_stream.cpp 2017-07-18 03:23:56 +0000 | |||
2974 | @@ -22,7 +22,6 @@ | |||
2975 | 22 | #include "mir/test/fake_shared.h" | 22 | #include "mir/test/fake_shared.h" |
2976 | 23 | #include "src/server/compositor/stream.h" | 23 | #include "src/server/compositor/stream.h" |
2977 | 24 | #include "mir/scene/null_surface_observer.h" | 24 | #include "mir/scene/null_surface_observer.h" |
2978 | 25 | #include "mir/frontend/client_buffers.h" | ||
2979 | 26 | 25 | ||
2980 | 27 | #include <gmock/gmock.h> | 26 | #include <gmock/gmock.h> |
2981 | 28 | #include <gtest/gtest.h> | 27 | #include <gtest/gtest.h> |
2982 | @@ -41,45 +40,6 @@ | |||
2983 | 41 | MOCK_METHOD2(frame_posted, void(int, geom::Size const&)); | 40 | MOCK_METHOD2(frame_posted, void(int, geom::Size const&)); |
2984 | 42 | }; | 41 | }; |
2985 | 43 | 42 | ||
2986 | 44 | struct StubBufferMap : mf::ClientBuffers | ||
2987 | 45 | { | ||
2988 | 46 | StubBufferMap(mf::EventSink& sink, std::vector<std::shared_ptr<mg::Buffer>>& buffers) : | ||
2989 | 47 | buffers{buffers}, | ||
2990 | 48 | sink{sink} | ||
2991 | 49 | { | ||
2992 | 50 | } | ||
2993 | 51 | mg::BufferID add_buffer(std::shared_ptr<mg::Buffer> const&) | ||
2994 | 52 | { | ||
2995 | 53 | return mg::BufferID{}; | ||
2996 | 54 | } | ||
2997 | 55 | void remove_buffer(mg::BufferID) | ||
2998 | 56 | { | ||
2999 | 57 | } | ||
3000 | 58 | void with_buffer(mg::BufferID, std::function<void(mg::Buffer&)> const&) | ||
3001 | 59 | { | ||
3002 | 60 | } | ||
3003 | 61 | void receive_buffer(mg::BufferID) | ||
3004 | 62 | { | ||
3005 | 63 | } | ||
3006 | 64 | void send_buffer(mg::BufferID id) | ||
3007 | 65 | { | ||
3008 | 66 | sink.send_buffer(mf::BufferStreamId{33}, *get(id), mg::BufferIpcMsgType::update_msg); | ||
3009 | 67 | } | ||
3010 | 68 | std::shared_ptr<mg::Buffer> get(mg::BufferID id) const | ||
3011 | 69 | { | ||
3012 | 70 | auto it = std::find_if(buffers.begin(), buffers.end(), | ||
3013 | 71 | [id](std::shared_ptr<mg::Buffer> const& b) | ||
3014 | 72 | { | ||
3015 | 73 | return b->id() == id; | ||
3016 | 74 | }); | ||
3017 | 75 | if (it == buffers.end()) | ||
3018 | 76 | throw std::logic_error("cannot find buffer in map"); | ||
3019 | 77 | return *it; | ||
3020 | 78 | } | ||
3021 | 79 | std::vector<std::shared_ptr<mg::Buffer>>& buffers; | ||
3022 | 80 | mf::EventSink& sink; | ||
3023 | 81 | }; | ||
3024 | 82 | |||
3025 | 83 | struct Stream : Test | 43 | struct Stream : Test |
3026 | 84 | { | 44 | { |
3027 | 85 | Stream() : | 45 | Stream() : |
3028 | @@ -94,16 +54,14 @@ | |||
3029 | 94 | 54 | ||
3030 | 95 | geom::Size initial_size{44,2}; | 55 | geom::Size initial_size{44,2}; |
3031 | 96 | std::vector<std::shared_ptr<mg::Buffer>> buffers; | 56 | std::vector<std::shared_ptr<mg::Buffer>> buffers; |
3032 | 97 | NiceMock<mtd::MockEventSink> mock_sink; | ||
3033 | 98 | MirPixelFormat construction_format{mir_pixel_format_rgb_565}; | 57 | MirPixelFormat construction_format{mir_pixel_format_rgb_565}; |
3034 | 99 | mc::Stream stream{ | 58 | mc::Stream stream{ |
3036 | 100 | std::make_unique<StubBufferMap>(mock_sink, buffers), initial_size, construction_format}; | 59 | initial_size, construction_format}; |
3037 | 101 | }; | 60 | }; |
3038 | 102 | } | 61 | } |
3039 | 103 | 62 | ||
3040 | 104 | TEST_F(Stream, transitions_from_queuing_to_framedropping) | 63 | TEST_F(Stream, transitions_from_queuing_to_framedropping) |
3041 | 105 | { | 64 | { |
3042 | 106 | EXPECT_CALL(mock_sink, send_buffer(_,_,_)).Times(buffers.size() - 1); | ||
3043 | 107 | for(auto& buffer : buffers) | 65 | for(auto& buffer : buffers) |
3044 | 108 | stream.submit_buffer(buffer); | 66 | stream.submit_buffer(buffer); |
3045 | 109 | stream.allow_framedropping(true); | 67 | stream.allow_framedropping(true); |
3046 | @@ -111,25 +69,37 @@ | |||
3047 | 111 | std::vector<std::shared_ptr<mg::Buffer>> cbuffers; | 69 | std::vector<std::shared_ptr<mg::Buffer>> cbuffers; |
3048 | 112 | while(stream.buffers_ready_for_compositor(this)) | 70 | while(stream.buffers_ready_for_compositor(this)) |
3049 | 113 | cbuffers.push_back(stream.lock_compositor_buffer(this)); | 71 | cbuffers.push_back(stream.lock_compositor_buffer(this)); |
3050 | 72 | // Transition to framedropping should have dropped all queued buffers but the last... | ||
3051 | 114 | ASSERT_THAT(cbuffers, SizeIs(1)); | 73 | ASSERT_THAT(cbuffers, SizeIs(1)); |
3052 | 115 | EXPECT_THAT(cbuffers[0]->id(), Eq(buffers.back()->id())); | 74 | EXPECT_THAT(cbuffers[0]->id(), Eq(buffers.back()->id())); |
3054 | 116 | Mock::VerifyAndClearExpectations(&mock_sink); | 75 | |
3055 | 76 | for (unsigned long i = 0; i < buffers.size() - 1; ++i) | ||
3056 | 77 | { | ||
3057 | 78 | // ...and so all the previous buffers should no longer have external references | ||
3058 | 79 | EXPECT_TRUE(buffers[i].unique()); | ||
3059 | 80 | } | ||
3060 | 117 | } | 81 | } |
3061 | 118 | 82 | ||
3062 | 119 | TEST_F(Stream, transitions_from_framedropping_to_queuing) | 83 | TEST_F(Stream, transitions_from_framedropping_to_queuing) |
3063 | 120 | { | 84 | { |
3064 | 121 | stream.allow_framedropping(true); | 85 | stream.allow_framedropping(true); |
3065 | 122 | Mock::VerifyAndClearExpectations(&mock_sink); | ||
3066 | 123 | 86 | ||
3067 | 124 | EXPECT_CALL(mock_sink, send_buffer(_,_,_)).Times(buffers.size() - 1); | ||
3068 | 125 | for(auto& buffer : buffers) | 87 | for(auto& buffer : buffers) |
3069 | 126 | stream.submit_buffer(buffer); | 88 | stream.submit_buffer(buffer); |
3070 | 127 | 89 | ||
3071 | 90 | // Only the last buffer should be owned by the stream... | ||
3072 | 91 | EXPECT_THAT( | ||
3073 | 92 | std::make_tuple(buffers.data(), buffers.size() - 1), | ||
3074 | 93 | Each(Property(&std::shared_ptr<mg::Buffer>::unique, Eq(true)))); | ||
3075 | 94 | |||
3076 | 128 | stream.allow_framedropping(false); | 95 | stream.allow_framedropping(false); |
3077 | 129 | for(auto& buffer : buffers) | 96 | for(auto& buffer : buffers) |
3078 | 130 | stream.submit_buffer(buffer); | 97 | stream.submit_buffer(buffer); |
3079 | 131 | 98 | ||
3081 | 132 | Mock::VerifyAndClearExpectations(&mock_sink); | 99 | // All buffers should be now owned by the the stream |
3082 | 100 | EXPECT_THAT( | ||
3083 | 101 | buffers, | ||
3084 | 102 | Each(Property(&std::shared_ptr<mg::Buffer>::unique, Eq(false)))); | ||
3085 | 133 | 103 | ||
3086 | 134 | std::vector<std::shared_ptr<mg::Buffer>> cbuffers; | 104 | std::vector<std::shared_ptr<mg::Buffer>> cbuffers; |
3087 | 135 | while(stream.buffers_ready_for_compositor(this)) | 105 | while(stream.buffers_ready_for_compositor(this)) |
3088 | @@ -180,23 +150,6 @@ | |||
3089 | 180 | stream.submit_buffer(buffers[0]); | 150 | stream.submit_buffer(buffers[0]); |
3090 | 181 | } | 151 | } |
3091 | 182 | 152 | ||
3092 | 183 | TEST_F(Stream, wakes_compositor_before_starting_socket_io) | ||
3093 | 184 | { | ||
3094 | 185 | auto observer = std::make_shared<MockSurfaceObserver>(); | ||
3095 | 186 | |||
3096 | 187 | InSequence seq; | ||
3097 | 188 | EXPECT_CALL(*observer, frame_posted(_,_)).Times(2); | ||
3098 | 189 | EXPECT_CALL(mock_sink, send_buffer(_,_,_)).Times(1); | ||
3099 | 190 | |||
3100 | 191 | stream.add_observer(observer); | ||
3101 | 192 | stream.allow_framedropping(true); | ||
3102 | 193 | stream.submit_buffer(buffers[0]); | ||
3103 | 194 | stream.submit_buffer(buffers[1]); | ||
3104 | 195 | stream.remove_observer(observer); | ||
3105 | 196 | |||
3106 | 197 | Mock::VerifyAndClearExpectations(&mock_sink); | ||
3107 | 198 | } | ||
3108 | 199 | |||
3109 | 200 | TEST_F(Stream, calls_observers_call_doesnt_hold_lock) | 153 | TEST_F(Stream, calls_observers_call_doesnt_hold_lock) |
3110 | 201 | { | 154 | { |
3111 | 202 | auto observer = std::make_shared<MockSurfaceObserver>(); | 155 | auto observer = std::make_shared<MockSurfaceObserver>(); |
3112 | @@ -269,9 +222,15 @@ | |||
3113 | 269 | stream.submit_buffer(buffers[1]); | 222 | stream.submit_buffer(buffers[1]); |
3114 | 270 | stream.submit_buffer(buffers[2]); | 223 | stream.submit_buffer(buffers[2]); |
3115 | 271 | 224 | ||
3119 | 272 | Mock::VerifyAndClearExpectations(&mock_sink); | 225 | // Buffers should be owned by the stream, and our test |
3120 | 273 | EXPECT_CALL(mock_sink, send_buffer(_,Ref(*buffers[0]),_)); | 226 | ASSERT_THAT(buffers[0].use_count(), Eq(2)); |
3121 | 274 | EXPECT_CALL(mock_sink, send_buffer(_,Ref(*buffers[1]),_)); | 227 | ASSERT_THAT(buffers[1].use_count(), Eq(2)); |
3122 | 228 | ASSERT_THAT(buffers[2].use_count(), Eq(2)); | ||
3123 | 229 | |||
3124 | 275 | stream.drop_old_buffers(); | 230 | stream.drop_old_buffers(); |
3126 | 276 | Mock::VerifyAndClearExpectations(&mock_sink); | 231 | |
3127 | 232 | // Stream should have released ownership of all but the most recent buffer | ||
3128 | 233 | EXPECT_THAT(buffers[0].use_count(), Eq(1)); | ||
3129 | 234 | EXPECT_THAT(buffers[1].use_count(), Eq(1)); | ||
3130 | 235 | EXPECT_THAT(buffers[2].use_count(), Eq(2)); | ||
3131 | 277 | } | 236 | } |
3132 | 278 | 237 | ||
3133 | === modified file 'tests/unit-tests/frontend/test_session_mediator.cpp' | |||
3134 | --- tests/unit-tests/frontend/test_session_mediator.cpp 2017-05-25 08:58:03 +0000 | |||
3135 | +++ tests/unit-tests/frontend/test_session_mediator.cpp 2017-07-18 03:23:56 +0000 | |||
3136 | @@ -32,6 +32,7 @@ | |||
3137 | 32 | #include "mir/graphics/buffer_ipc_message.h" | 32 | #include "mir/graphics/buffer_ipc_message.h" |
3138 | 33 | #include "mir/graphics/platform_operation_message.h" | 33 | #include "mir/graphics/platform_operation_message.h" |
3139 | 34 | #include "mir/graphics/buffer_id.h" | 34 | #include "mir/graphics/buffer_id.h" |
3140 | 35 | #include "mir/graphics/graphic_buffer_allocator.h" | ||
3141 | 35 | #include "mir/input/cursor_images.h" | 36 | #include "mir/input/cursor_images.h" |
3142 | 36 | #include "mir/graphics/platform_ipc_operations.h" | 37 | #include "mir/graphics/platform_ipc_operations.h" |
3143 | 37 | #include "mir/scene/coordinate_translator.h" | 38 | #include "mir/scene/coordinate_translator.h" |
3144 | @@ -61,6 +62,7 @@ | |||
3145 | 61 | #include "mir/test/doubles/mock_message_sender.h" | 62 | #include "mir/test/doubles/mock_message_sender.h" |
3146 | 62 | #include "mir/test/doubles/mock_input_config_changer.h" | 63 | #include "mir/test/doubles/mock_input_config_changer.h" |
3147 | 63 | #include "mir/test/doubles/stub_input_device.h" | 64 | #include "mir/test/doubles/stub_input_device.h" |
3148 | 65 | #include "mir/test/doubles/stub_buffer.h" | ||
3149 | 64 | #include "mir/test/display_config_matchers.h" | 66 | #include "mir/test/display_config_matchers.h" |
3150 | 65 | #include "mir/test/input_devices_matcher.h" | 67 | #include "mir/test/input_devices_matcher.h" |
3151 | 66 | #include "mir/test/fake_shared.h" | 68 | #include "mir/test/fake_shared.h" |
3152 | @@ -119,11 +121,6 @@ | |||
3153 | 119 | class StubbedSession : public mtd::StubSession | 121 | class StubbedSession : public mtd::StubSession |
3154 | 120 | { | 122 | { |
3155 | 121 | public: | 123 | public: |
3156 | 122 | StubbedSession() | ||
3157 | 123 | { | ||
3158 | 124 | ON_CALL(*this, destroy_buffer(_)) | ||
3159 | 125 | .WillByDefault(Invoke([this](mg::BufferID){ ++destroy_buffers;})); | ||
3160 | 126 | } | ||
3161 | 127 | std::shared_ptr<mf::Surface> get_surface(mf::SurfaceId surface) const override | 124 | std::shared_ptr<mf::Surface> get_surface(mf::SurfaceId surface) const override |
3162 | 128 | { | 125 | { |
3163 | 129 | if (mock_surfaces.find(surface) == mock_surfaces.end()) | 126 | if (mock_surfaces.find(surface) == mock_surfaces.end()) |
3164 | @@ -195,27 +192,8 @@ | |||
3165 | 195 | mock_surfaces.erase(surface); | 192 | mock_surfaces.erase(surface); |
3166 | 196 | } | 193 | } |
3167 | 197 | 194 | ||
3168 | 198 | |||
3169 | 199 | mg::BufferID create_buffer(mg::BufferProperties const&) override | ||
3170 | 200 | { | ||
3171 | 201 | buffer_count++; | ||
3172 | 202 | return mg::BufferID{3}; | ||
3173 | 203 | } | ||
3174 | 204 | |||
3175 | 205 | mg::BufferID create_buffer(geom::Size, MirPixelFormat) override | ||
3176 | 206 | { | ||
3177 | 207 | buffer_count++; | ||
3178 | 208 | return mg::BufferID{3}; | ||
3179 | 209 | } | ||
3180 | 210 | |||
3181 | 211 | mg::BufferID create_buffer(geom::Size, uint32_t, uint32_t) override | ||
3182 | 212 | { | ||
3183 | 213 | native_buffer_count++; | ||
3184 | 214 | return mg::BufferID{3}; | ||
3185 | 215 | } | ||
3186 | 216 | 195 | ||
3187 | 217 | MOCK_METHOD1(destroy_buffer_stream, void(mf::BufferStreamId)); | 196 | MOCK_METHOD1(destroy_buffer_stream, void(mf::BufferStreamId)); |
3188 | 218 | MOCK_METHOD1(destroy_buffer, void(mg::BufferID)); | ||
3189 | 219 | 197 | ||
3190 | 220 | int num_alloc_requests() | 198 | int num_alloc_requests() |
3191 | 221 | { | 199 | { |
3192 | @@ -258,6 +236,42 @@ | |||
3193 | 258 | } | 236 | } |
3194 | 259 | }; | 237 | }; |
3195 | 260 | 238 | ||
3196 | 239 | struct RecordingBufferAllocator : public mg::GraphicBufferAllocator | ||
3197 | 240 | { | ||
3198 | 241 | std::shared_ptr<mg::Buffer> alloc_buffer(mg::BufferProperties const& buffer_properties) override | ||
3199 | 242 | { | ||
3200 | 243 | auto const buf = std::make_shared<mtd::StubBuffer>(buffer_properties); | ||
3201 | 244 | allocated_buffers.push_back(buf); | ||
3202 | 245 | return buf; | ||
3203 | 246 | } | ||
3204 | 247 | |||
3205 | 248 | std::vector<MirPixelFormat> supported_pixel_formats() override | ||
3206 | 249 | { | ||
3207 | 250 | return {}; | ||
3208 | 251 | } | ||
3209 | 252 | |||
3210 | 253 | std::shared_ptr<mg::Buffer> alloc_buffer( | ||
3211 | 254 | geom::Size size, uint32_t /*native_format*/, uint32_t /*native_flags*/) override | ||
3212 | 255 | { | ||
3213 | 256 | auto const buf = std::make_shared<mtd::StubBuffer>(size); | ||
3214 | 257 | allocated_buffers.push_back(buf); | ||
3215 | 258 | return buf; | ||
3216 | 259 | } | ||
3217 | 260 | |||
3218 | 261 | std::shared_ptr<mg::Buffer> alloc_software_buffer( | ||
3219 | 262 | geom::Size size, MirPixelFormat format) override | ||
3220 | 263 | { | ||
3221 | 264 | if ((format >= mir_pixel_formats) || format == mir_pixel_format_invalid) | ||
3222 | 265 | BOOST_THROW_EXCEPTION((std::runtime_error{"Invalid pixel format"})); | ||
3223 | 266 | |||
3224 | 267 | auto const buf = std::make_shared<mtd::StubBuffer>(size); | ||
3225 | 268 | allocated_buffers.push_back(buf); | ||
3226 | 269 | return buf; | ||
3227 | 270 | } | ||
3228 | 271 | |||
3229 | 272 | std::vector<std::weak_ptr<mg::Buffer>> allocated_buffers; | ||
3230 | 273 | }; | ||
3231 | 274 | |||
3232 | 261 | struct SessionMediator : public ::testing::Test | 275 | struct SessionMediator : public ::testing::Test |
3233 | 262 | { | 276 | { |
3234 | 263 | SessionMediator() | 277 | SessionMediator() |
3235 | @@ -269,6 +283,7 @@ | |||
3236 | 269 | stub_screencast{std::make_shared<StubScreencast>()}, | 283 | stub_screencast{std::make_shared<StubScreencast>()}, |
3237 | 270 | stubbed_session{std::make_shared<NiceMock<StubbedSession>>()}, | 284 | stubbed_session{std::make_shared<NiceMock<StubbedSession>>()}, |
3238 | 271 | null_callback{google::protobuf::NewPermanentCallback(google::protobuf::DoNothing)}, | 285 | null_callback{google::protobuf::NewPermanentCallback(google::protobuf::DoNothing)}, |
3239 | 286 | allocator{std::make_shared<RecordingBufferAllocator>()}, | ||
3240 | 272 | mediator{ | 287 | mediator{ |
3241 | 273 | shell, mt::fake_shared(mock_ipc_operations), graphics_changer, | 288 | shell, mt::fake_shared(mock_ipc_operations), graphics_changer, |
3242 | 274 | surface_pixel_formats, report, | 289 | surface_pixel_formats, report, |
3243 | @@ -280,7 +295,8 @@ | |||
3244 | 280 | std::make_shared<mtd::NullANRDetector>(), | 295 | std::make_shared<mtd::NullANRDetector>(), |
3245 | 281 | mir::cookie::Authority::create(), | 296 | mir::cookie::Authority::create(), |
3246 | 282 | mt::fake_shared(mock_input_config_changer), | 297 | mt::fake_shared(mock_input_config_changer), |
3248 | 283 | {}} | 298 | {}, |
3249 | 299 | allocator} | ||
3250 | 284 | { | 300 | { |
3251 | 285 | using namespace ::testing; | 301 | using namespace ::testing; |
3252 | 286 | 302 | ||
3253 | @@ -310,7 +326,8 @@ | |||
3254 | 310 | std::make_shared<NullCoordinateTranslator>(), | 326 | std::make_shared<NullCoordinateTranslator>(), |
3255 | 311 | std::make_shared<mtd::NullANRDetector>(), | 327 | std::make_shared<mtd::NullANRDetector>(), |
3256 | 312 | mir::cookie::Authority::create(), | 328 | mir::cookie::Authority::create(), |
3258 | 313 | mt::fake_shared(mock_input_config_changer), std::vector<mir::ExtensionDescription>{}); | 329 | mt::fake_shared(mock_input_config_changer), std::vector<mir::ExtensionDescription>{}, |
3259 | 330 | allocator); | ||
3260 | 314 | } | 331 | } |
3261 | 315 | 332 | ||
3262 | 316 | std::shared_ptr<mf::SessionMediator> create_session_mediator_with_screencast( | 333 | std::shared_ptr<mf::SessionMediator> create_session_mediator_with_screencast( |
3263 | @@ -325,7 +342,112 @@ | |||
3264 | 325 | std::make_shared<NullCoordinateTranslator>(), | 342 | std::make_shared<NullCoordinateTranslator>(), |
3265 | 326 | std::make_shared<mtd::NullANRDetector>(), | 343 | std::make_shared<mtd::NullANRDetector>(), |
3266 | 327 | mir::cookie::Authority::create(), | 344 | mir::cookie::Authority::create(), |
3268 | 328 | mt::fake_shared(mock_input_config_changer), std::vector<mir::ExtensionDescription>{}); | 345 | mt::fake_shared(mock_input_config_changer), std::vector<mir::ExtensionDescription>{}, |
3269 | 346 | allocator); | ||
3270 | 347 | } | ||
3271 | 348 | |||
3272 | 349 | std::shared_ptr<mf::SessionMediator> create_session_mediator_with_event_sink( | ||
3273 | 350 | std::shared_ptr<mf::EventSink> const& sink) | ||
3274 | 351 | { | ||
3275 | 352 | class WrappingEventSink : public mf::EventSink | ||
3276 | 353 | { | ||
3277 | 354 | public: | ||
3278 | 355 | WrappingEventSink(std::shared_ptr<mf::EventSink> const& wrapped) | ||
3279 | 356 | : wrapped{wrapped} | ||
3280 | 357 | { | ||
3281 | 358 | } | ||
3282 | 359 | |||
3283 | 360 | void handle_event(MirEvent const &e) override | ||
3284 | 361 | { | ||
3285 | 362 | wrapped->handle_event(e); | ||
3286 | 363 | } | ||
3287 | 364 | |||
3288 | 365 | void handle_lifecycle_event(MirLifecycleState state) override | ||
3289 | 366 | { | ||
3290 | 367 | wrapped->handle_lifecycle_event(state); | ||
3291 | 368 | } | ||
3292 | 369 | |||
3293 | 370 | void handle_display_config_change( | ||
3294 | 371 | mg::DisplayConfiguration const& config) override | ||
3295 | 372 | { | ||
3296 | 373 | wrapped->handle_display_config_change(config); | ||
3297 | 374 | } | ||
3298 | 375 | |||
3299 | 376 | void send_ping(int32_t serial) override | ||
3300 | 377 | { | ||
3301 | 378 | wrapped->send_ping(serial); | ||
3302 | 379 | } | ||
3303 | 380 | |||
3304 | 381 | void handle_input_config_change(MirInputConfig const& config) override | ||
3305 | 382 | { | ||
3306 | 383 | wrapped->handle_input_config_change(config); | ||
3307 | 384 | } | ||
3308 | 385 | |||
3309 | 386 | void handle_error(mir::ClientVisibleError const& error) override | ||
3310 | 387 | { | ||
3311 | 388 | wrapped->handle_error(error); | ||
3312 | 389 | } | ||
3313 | 390 | |||
3314 | 391 | void send_buffer( | ||
3315 | 392 | mf::BufferStreamId id, | ||
3316 | 393 | mg::Buffer& buffer, | ||
3317 | 394 | mg::BufferIpcMsgType type) override | ||
3318 | 395 | { | ||
3319 | 396 | wrapped->send_buffer(id, buffer, type); | ||
3320 | 397 | } | ||
3321 | 398 | |||
3322 | 399 | void add_buffer(mg::Buffer& buffer) override | ||
3323 | 400 | { | ||
3324 | 401 | wrapped->add_buffer(buffer); | ||
3325 | 402 | } | ||
3326 | 403 | |||
3327 | 404 | void error_buffer( | ||
3328 | 405 | geom::Size req_size, | ||
3329 | 406 | MirPixelFormat req_format, | ||
3330 | 407 | std::string const &error_msg) override | ||
3331 | 408 | { | ||
3332 | 409 | wrapped->error_buffer(req_size, req_format, error_msg); | ||
3333 | 410 | } | ||
3334 | 411 | |||
3335 | 412 | void update_buffer(mg::Buffer &buffer) override | ||
3336 | 413 | { | ||
3337 | 414 | wrapped->update_buffer(buffer); | ||
3338 | 415 | } | ||
3339 | 416 | |||
3340 | 417 | private: | ||
3341 | 418 | std::shared_ptr<mf::EventSink> const wrapped; | ||
3342 | 419 | }; | ||
3343 | 420 | |||
3344 | 421 | class EventSinkFactory : public mf::EventSinkFactory | ||
3345 | 422 | { | ||
3346 | 423 | public: | ||
3347 | 424 | EventSinkFactory(std::shared_ptr<mf::EventSink> const& sink) | ||
3348 | 425 | : the_sink{sink} | ||
3349 | 426 | { | ||
3350 | 427 | } | ||
3351 | 428 | |||
3352 | 429 | std::unique_ptr<mf::EventSink> create_sink( | ||
3353 | 430 | std::shared_ptr<mf::MessageSender> const&) override | ||
3354 | 431 | { | ||
3355 | 432 | return std::make_unique<WrappingEventSink>(the_sink); | ||
3356 | 433 | } | ||
3357 | 434 | |||
3358 | 435 | private: | ||
3359 | 436 | std::shared_ptr<mf::EventSink> const the_sink; | ||
3360 | 437 | }; | ||
3361 | 438 | |||
3362 | 439 | return std::make_shared<mf::SessionMediator>( | ||
3363 | 440 | shell, mt::fake_shared(mock_ipc_operations), graphics_changer, | ||
3364 | 441 | surface_pixel_formats, report, | ||
3365 | 442 | std::make_shared<EventSinkFactory>(sink), | ||
3366 | 443 | std::make_shared<mtd::NullMessageSender>(), | ||
3367 | 444 | resource_cache, stub_screencast, &connector, nullptr, | ||
3368 | 445 | std::make_shared<NullCoordinateTranslator>(), | ||
3369 | 446 | std::make_shared<mtd::NullANRDetector>(), | ||
3370 | 447 | mir::cookie::Authority::create(), | ||
3371 | 448 | mt::fake_shared(mock_input_config_changer), | ||
3372 | 449 | std::vector<mir::ExtensionDescription>{}, | ||
3373 | 450 | allocator); | ||
3374 | 329 | } | 451 | } |
3375 | 330 | 452 | ||
3376 | 331 | MockConnector connector; | 453 | MockConnector connector; |
3377 | @@ -339,6 +461,7 @@ | |||
3378 | 339 | std::shared_ptr<StubScreencast> const stub_screencast; | 461 | std::shared_ptr<StubScreencast> const stub_screencast; |
3379 | 340 | std::shared_ptr<NiceMock<StubbedSession>> const stubbed_session; | 462 | std::shared_ptr<NiceMock<StubbedSession>> const stubbed_session; |
3380 | 341 | std::unique_ptr<google::protobuf::Closure> null_callback; | 463 | std::unique_ptr<google::protobuf::Closure> null_callback; |
3381 | 464 | std::shared_ptr<RecordingBufferAllocator> const allocator; | ||
3382 | 342 | mf::SessionMediator mediator; | 465 | mf::SessionMediator mediator; |
3383 | 343 | 466 | ||
3384 | 344 | mp::ConnectParameters connect_parameters; | 467 | mp::ConnectParameters connect_parameters; |
3385 | @@ -383,7 +506,8 @@ | |||
3386 | 383 | std::make_shared<NullCoordinateTranslator>(), | 506 | std::make_shared<NullCoordinateTranslator>(), |
3387 | 384 | std::make_shared<mtd::NullANRDetector>(), | 507 | std::make_shared<mtd::NullANRDetector>(), |
3388 | 385 | mir::cookie::Authority::create(), | 508 | mir::cookie::Authority::create(), |
3390 | 386 | mt::fake_shared(mock_input_config_changer), {}}; | 509 | mt::fake_shared(mock_input_config_changer), {}, |
3391 | 510 | allocator}; | ||
3392 | 387 | 511 | ||
3393 | 388 | EXPECT_THAT(connects_handled_count, Eq(0)); | 512 | EXPECT_THAT(connects_handled_count, Eq(0)); |
3394 | 389 | 513 | ||
3395 | @@ -413,21 +537,6 @@ | |||
3396 | 413 | }, std::logic_error); | 537 | }, std::logic_error); |
3397 | 414 | } | 538 | } |
3398 | 415 | 539 | ||
3399 | 416 | TEST_F(SessionMediator, calling_methods_after_connect_works) | ||
3400 | 417 | { | ||
3401 | 418 | mediator.connect(&connect_parameters, &connection, null_callback.get()); | ||
3402 | 419 | |||
3403 | 420 | EXPECT_NO_THROW({ | ||
3404 | 421 | mediator.create_surface(&surface_parameters, &surface_response, null_callback.get()); | ||
3405 | 422 | *buffer_request.mutable_buffer() = surface_response.buffer_stream().buffer(); | ||
3406 | 423 | buffer_request.mutable_id()->set_value(surface_response.id().value()); | ||
3407 | 424 | mediator.submit_buffer(&buffer_request, nullptr, null_callback.get()); | ||
3408 | 425 | mediator.release_surface(&surface_id_request, nullptr, null_callback.get()); | ||
3409 | 426 | }); | ||
3410 | 427 | |||
3411 | 428 | mediator.disconnect(nullptr, nullptr, null_callback.get()); | ||
3412 | 429 | } | ||
3413 | 430 | |||
3414 | 431 | TEST_F(SessionMediator, calling_methods_after_disconnect_throws) | 540 | TEST_F(SessionMediator, calling_methods_after_disconnect_throws) |
3415 | 432 | { | 541 | { |
3416 | 433 | mediator.connect(&connect_parameters, &connection, null_callback.get()); | 542 | mediator.connect(&connect_parameters, &connection, null_callback.get()); |
3417 | @@ -701,15 +810,20 @@ | |||
3418 | 701 | mediator.modify_surface(&mods, &null, null_callback.get()); | 810 | mediator.modify_surface(&mods, &null, null_callback.get()); |
3419 | 702 | } | 811 | } |
3420 | 703 | 812 | ||
3422 | 704 | TEST_F(SessionMediator, allocates_software_buffers_from_the_session) | 813 | TEST_F(SessionMediator, allocates_software_buffers) |
3423 | 705 | { | 814 | { |
3424 | 706 | using namespace testing; | 815 | using namespace testing; |
3425 | 816 | |||
3426 | 817 | auto sink = std::make_shared<NiceMock<mtd::MockEventSink>>(); | ||
3427 | 818 | auto mediator = create_session_mediator_with_event_sink(sink); | ||
3428 | 819 | |||
3429 | 820 | mediator->connect(&connect_parameters, &connection, null_callback.get()); | ||
3430 | 821 | mediator->create_surface(&surface_parameters, &surface_response, null_callback.get()); | ||
3431 | 822 | |||
3432 | 707 | auto num_requests = 3; | 823 | auto num_requests = 3; |
3433 | 708 | mp::Void null; | 824 | mp::Void null; |
3434 | 709 | mp::BufferStreamId id; | ||
3435 | 710 | id.set_value(0); | ||
3436 | 711 | mp::BufferAllocation request; | 825 | mp::BufferAllocation request; |
3438 | 712 | *request.mutable_id() = id; | 826 | *request.mutable_id() = surface_response.buffer_stream().id(); |
3439 | 713 | mg::BufferProperties properties(geom::Size{34, 84}, mir_pixel_format_abgr_8888, mg::BufferUsage::hardware); | 827 | mg::BufferProperties properties(geom::Size{34, 84}, mir_pixel_format_abgr_8888, mg::BufferUsage::hardware); |
3440 | 714 | for(auto i = 0; i < num_requests; i++) | 828 | for(auto i = 0; i < num_requests; i++) |
3441 | 715 | { | 829 | { |
3442 | @@ -720,58 +834,79 @@ | |||
3443 | 720 | buffer_request->set_buffer_usage((int)properties.usage); | 834 | buffer_request->set_buffer_usage((int)properties.usage); |
3444 | 721 | } | 835 | } |
3445 | 722 | 836 | ||
3446 | 723 | mediator.connect(&connect_parameters, &connection, null_callback.get()); | ||
3447 | 724 | mediator.create_surface(&surface_parameters, &surface_response, null_callback.get()); | ||
3448 | 725 | 837 | ||
3451 | 726 | mediator.allocate_buffers(&request, &null, null_callback.get()); | 838 | EXPECT_CALL(*sink, add_buffer(_)).Times(num_requests); |
3452 | 727 | EXPECT_THAT(stubbed_session->num_alloc_requests(), Eq(num_requests)); | 839 | EXPECT_CALL(*sink, error_buffer(_,_,_)).Times(0); |
3453 | 840 | mediator->allocate_buffers(&request, &null, null_callback.get()); | ||
3454 | 841 | EXPECT_THAT(allocator->allocated_buffers.size(), Eq(num_requests)); | ||
3455 | 728 | } | 842 | } |
3456 | 729 | 843 | ||
3458 | 730 | TEST_F(SessionMediator, allocates_native_buffers_from_the_session) | 844 | TEST_F(SessionMediator, allocates_native_buffers) |
3459 | 731 | { | 845 | { |
3460 | 732 | using namespace testing; | 846 | using namespace testing; |
3461 | 847 | |||
3462 | 848 | auto sink = std::make_shared<NiceMock<mtd::MockEventSink>>(); | ||
3463 | 849 | auto mediator = create_session_mediator_with_event_sink(sink); | ||
3464 | 850 | |||
3465 | 851 | mediator->connect(&connect_parameters, &connection, null_callback.get()); | ||
3466 | 852 | mediator->create_surface(&surface_parameters, &surface_response, null_callback.get()); | ||
3467 | 853 | |||
3468 | 733 | geom::Size const size { 1029, 10302 }; | 854 | geom::Size const size { 1029, 10302 }; |
3469 | 734 | auto native_flags = 24u; | 855 | auto native_flags = 24u; |
3470 | 735 | auto native_format = 124u; | 856 | auto native_format = 124u; |
3471 | 736 | mp::Void null; | 857 | mp::Void null; |
3472 | 737 | mp::BufferStreamId id; | ||
3473 | 738 | id.set_value(0); | ||
3474 | 739 | mp::BufferAllocation request; | 858 | mp::BufferAllocation request; |
3476 | 740 | *request.mutable_id() = id; | 859 | *request.mutable_id() = surface_response.buffer_stream().id(); |
3477 | 741 | auto buffer_request = request.add_buffer_requests(); | 860 | auto buffer_request = request.add_buffer_requests(); |
3478 | 742 | buffer_request->set_width(size.width.as_int()); | 861 | buffer_request->set_width(size.width.as_int()); |
3479 | 743 | buffer_request->set_height(size.height.as_int()); | 862 | buffer_request->set_height(size.height.as_int()); |
3480 | 744 | buffer_request->set_native_format(native_format); | 863 | buffer_request->set_native_format(native_format); |
3481 | 745 | buffer_request->set_flags(native_flags); | 864 | buffer_request->set_flags(native_flags); |
3482 | 746 | 865 | ||
3488 | 747 | mediator.connect(&connect_parameters, &connection, null_callback.get()); | 866 | EXPECT_CALL(*sink, add_buffer(_)).Times(1); |
3489 | 748 | mediator.create_surface(&surface_parameters, &surface_response, null_callback.get()); | 867 | EXPECT_CALL(*sink, error_buffer(_,_,_)).Times(0); |
3490 | 749 | 868 | mediator->allocate_buffers(&request, &null, null_callback.get()); | |
3491 | 750 | mediator.allocate_buffers(&request, &null, null_callback.get()); | 869 | EXPECT_THAT(allocator->allocated_buffers.size(), Eq(1)); |
3487 | 751 | EXPECT_THAT(stubbed_session->native_buffer_count, Eq(1)); | ||
3492 | 752 | } | 870 | } |
3493 | 753 | 871 | ||
3495 | 754 | TEST_F(SessionMediator, removes_buffer_from_the_session) | 872 | TEST_F(SessionMediator, removes_buffer) |
3496 | 755 | { | 873 | { |
3497 | 756 | using namespace testing; | 874 | using namespace testing; |
3498 | 757 | auto num_requests = 3; | 875 | auto num_requests = 3; |
3499 | 758 | mp::Void null; | 876 | mp::Void null; |
3500 | 759 | mp::BufferStreamId id; | ||
3501 | 760 | id.set_value(0); | ||
3502 | 761 | mp::BufferRelease request; | 877 | mp::BufferRelease request; |
3505 | 762 | *request.mutable_id() = id; | 878 | |
3506 | 763 | auto buffer_id = 442u; | 879 | // Allocate some buffers so we can release them later... |
3507 | 880 | mp::BufferAllocation allocate_request; | ||
3508 | 764 | for(auto i = 0; i < num_requests; i++) | 881 | for(auto i = 0; i < num_requests; i++) |
3509 | 765 | { | 882 | { |
3512 | 766 | auto buffer_request = request.add_buffers(); | 883 | auto allocate = allocate_request.add_buffer_requests(); |
3513 | 767 | buffer_request->set_buffer_id(buffer_id); | 884 | allocate->set_buffer_usage(static_cast<int32_t>(mg::BufferUsage::software)); |
3514 | 885 | allocate->set_pixel_format(mir_pixel_format_abgr_8888); | ||
3515 | 886 | allocate->set_width(640); | ||
3516 | 887 | allocate->set_height(480); | ||
3517 | 768 | } | 888 | } |
3518 | 769 | 889 | ||
3519 | 770 | mediator.connect(&connect_parameters, &connection, null_callback.get()); | 890 | mediator.connect(&connect_parameters, &connection, null_callback.get()); |
3522 | 771 | mediator.create_surface(&surface_parameters, &surface_response, null_callback.get()); | 891 | mediator.allocate_buffers(&allocate_request, &null, null_callback.get()); |
3523 | 772 | 892 | ||
3524 | 893 | ASSERT_THAT(allocator->allocated_buffers.size(), Eq(num_requests)); | ||
3525 | 894 | |||
3526 | 895 | // ...Pull out the BufferIDs of the buffers we've allocated... | ||
3527 | 896 | for (auto weak_buffer : allocator->allocated_buffers) | ||
3528 | 897 | { | ||
3529 | 898 | auto buffer = weak_buffer.lock(); | ||
3530 | 899 | ASSERT_THAT(buffer, NotNull()); | ||
3531 | 900 | |||
3532 | 901 | auto release_buffer = request.add_buffers(); | ||
3533 | 902 | release_buffer->set_buffer_id(buffer->id().as_value()); | ||
3534 | 903 | } | ||
3535 | 904 | |||
3536 | 905 | // ...and now release all those buffers. | ||
3537 | 773 | mediator.release_buffers(&request, &null, null_callback.get()); | 906 | mediator.release_buffers(&request, &null, null_callback.get()); |
3539 | 774 | EXPECT_THAT(stubbed_session->num_destroy_requests(), Eq(num_requests)); | 907 | EXPECT_THAT( |
3540 | 908 | allocator->allocated_buffers, | ||
3541 | 909 | Each(Property(&std::weak_ptr<mg::Buffer>::expired, Eq(true)))); | ||
3542 | 775 | } | 910 | } |
3543 | 776 | 911 | ||
3544 | 777 | TEST_F(SessionMediator, configures_swap_intervals_on_streams) | 912 | TEST_F(SessionMediator, configures_swap_intervals_on_streams) |
3545 | @@ -861,7 +996,8 @@ | |||
3546 | 861 | std::make_shared<NullCoordinateTranslator>(), | 996 | std::make_shared<NullCoordinateTranslator>(), |
3547 | 862 | std::make_shared<mtd::NullANRDetector>(), | 997 | std::make_shared<mtd::NullANRDetector>(), |
3548 | 863 | mir::cookie::Authority::create(), | 998 | mir::cookie::Authority::create(), |
3550 | 864 | mt::fake_shared(mock_input_config_changer), {}}; | 999 | mt::fake_shared(mock_input_config_changer), {}, |
3551 | 1000 | allocator}; | ||
3552 | 865 | 1001 | ||
3553 | 866 | ON_CALL(*shell, create_surface( _, _, _)) | 1002 | ON_CALL(*shell, create_surface( _, _, _)) |
3554 | 867 | .WillByDefault( | 1003 | .WillByDefault( |
3555 | @@ -1022,22 +1158,49 @@ | |||
3556 | 1022 | TEST_F(SessionMediator, disassociates_buffers_from_stream_before_destroying) | 1158 | TEST_F(SessionMediator, disassociates_buffers_from_stream_before_destroying) |
3557 | 1023 | { | 1159 | { |
3558 | 1024 | mp::BufferRelease release_buffer; | 1160 | mp::BufferRelease release_buffer; |
3559 | 1161 | mp::BufferAllocation allocate_buffer; | ||
3560 | 1025 | mp::Void null; | 1162 | mp::Void null; |
3561 | 1026 | 1163 | ||
3562 | 1164 | // Add a fake BufferStream... | ||
3563 | 1027 | auto stream_id = mf::BufferStreamId{42}; | 1165 | auto stream_id = mf::BufferStreamId{42}; |
3564 | 1028 | auto buffer_id = mir::graphics::BufferID{42}; | ||
3565 | 1029 | auto stream = stubbed_session->create_mock_stream(stream_id); | 1166 | auto stream = stubbed_session->create_mock_stream(stream_id); |
3567 | 1030 | auto buffer1 = std::make_shared<mtd::StubBuffer>(); | 1167 | |
3568 | 1168 | // ...and allocate a buffer to it | ||
3569 | 1169 | allocate_buffer.mutable_id()->set_value(42); | ||
3570 | 1170 | auto buffer_props = allocate_buffer.add_buffer_requests(); | ||
3571 | 1171 | buffer_props->set_buffer_usage(0); | ||
3572 | 1172 | buffer_props->set_pixel_format(0); | ||
3573 | 1173 | buffer_props->set_width(230); | ||
3574 | 1174 | buffer_props->set_height(230); | ||
3575 | 1175 | |||
3576 | 1176 | mediator.connect(&connect_parameters, &connection, null_callback.get()); | ||
3577 | 1177 | mediator.allocate_buffers(&allocate_buffer, &null, null_callback.get()); | ||
3578 | 1178 | |||
3579 | 1179 | ASSERT_THAT(allocator->allocated_buffers.size(), Eq(1)); | ||
3580 | 1180 | auto allocated_buffer = allocator->allocated_buffers.front().lock(); | ||
3581 | 1181 | ASSERT_THAT(allocated_buffer, NotNull()); | ||
3582 | 1182 | |||
3583 | 1183 | auto const buffer_id = allocated_buffer->id(); | ||
3584 | 1184 | |||
3585 | 1185 | // Release our share of the buffer ownership. | ||
3586 | 1186 | allocated_buffer.reset(); | ||
3587 | 1031 | 1187 | ||
3588 | 1032 | auto buffer_item = release_buffer.add_buffers(); | 1188 | auto buffer_item = release_buffer.add_buffers(); |
3589 | 1033 | buffer_item->set_buffer_id(buffer_id.as_value()); | 1189 | buffer_item->set_buffer_id(buffer_id.as_value()); |
3590 | 1034 | release_buffer.mutable_id()->set_value(stream_id.as_value()); | 1190 | release_buffer.mutable_id()->set_value(stream_id.as_value()); |
3591 | 1035 | 1191 | ||
3594 | 1036 | EXPECT_CALL(*stream, disassociate_buffer(buffer_id)); | 1192 | EXPECT_CALL(*stream, disassociate_buffer(buffer_id)) |
3595 | 1037 | EXPECT_CALL(*stubbed_session, destroy_buffer(buffer_id)); | 1193 | .WillOnce(InvokeWithoutArgs( |
3596 | 1194 | [weak_buffer = allocator->allocated_buffers.front()]() | ||
3597 | 1195 | { | ||
3598 | 1196 | // The buffer should be live here! | ||
3599 | 1197 | EXPECT_THAT(weak_buffer.lock(), NotNull()); | ||
3600 | 1198 | })); | ||
3601 | 1038 | 1199 | ||
3602 | 1039 | mediator.connect(&connect_parameters, &connection, null_callback.get()); | ||
3603 | 1040 | mediator.release_buffers(&release_buffer, &null, null_callback.get()); | 1200 | mediator.release_buffers(&release_buffer, &null, null_callback.get()); |
3604 | 1201 | |||
3605 | 1202 | // And now we expect the buffer to have been destroyed. | ||
3606 | 1203 | EXPECT_THAT(allocator->allocated_buffers.front().lock(), IsNull()); | ||
3607 | 1041 | } | 1204 | } |
3608 | 1042 | 1205 | ||
3609 | 1043 | TEST_F(SessionMediator, releases_buffers_of_unknown_buffer_stream_does_not_throw) | 1206 | TEST_F(SessionMediator, releases_buffers_of_unknown_buffer_stream_does_not_throw) |
3610 | @@ -1046,10 +1209,30 @@ | |||
3611 | 1046 | mp::BufferRelease release_buffer; | 1209 | mp::BufferRelease release_buffer; |
3612 | 1047 | mp::Void null; | 1210 | mp::Void null; |
3613 | 1048 | 1211 | ||
3614 | 1212 | // Add a fake BufferStream... | ||
3615 | 1049 | auto stream_id = mf::BufferStreamId{42}; | 1213 | auto stream_id = mf::BufferStreamId{42}; |
3616 | 1050 | auto buffer_id = mir::graphics::BufferID{42}; | ||
3617 | 1051 | auto stream = stubbed_session->create_mock_stream(stream_id); | 1214 | auto stream = stubbed_session->create_mock_stream(stream_id); |
3619 | 1052 | auto buffer1 = std::make_shared<mtd::StubBuffer>(); | 1215 | |
3620 | 1216 | // ...and allocate a buffer to it | ||
3621 | 1217 | mp::BufferAllocation allocate_buffer; | ||
3622 | 1218 | allocate_buffer.mutable_id()->set_value(42); | ||
3623 | 1219 | auto buffer_props = allocate_buffer.add_buffer_requests(); | ||
3624 | 1220 | buffer_props->set_buffer_usage(0); | ||
3625 | 1221 | buffer_props->set_pixel_format(0); | ||
3626 | 1222 | buffer_props->set_width(230); | ||
3627 | 1223 | buffer_props->set_height(230); | ||
3628 | 1224 | |||
3629 | 1225 | mediator.connect(&connect_parameters, &connection, null_callback.get()); | ||
3630 | 1226 | mediator.allocate_buffers(&allocate_buffer, &null, null_callback.get()); | ||
3631 | 1227 | |||
3632 | 1228 | ASSERT_THAT(allocator->allocated_buffers.size(), Eq(1)); | ||
3633 | 1229 | auto allocated_buffer = allocator->allocated_buffers.front().lock(); | ||
3634 | 1230 | ASSERT_THAT(allocated_buffer, NotNull()); | ||
3635 | 1231 | |||
3636 | 1232 | auto const buffer_id = allocated_buffer->id(); | ||
3637 | 1233 | |||
3638 | 1234 | // Release our share of the buffer ownership. | ||
3639 | 1235 | allocated_buffer.reset(); | ||
3640 | 1053 | 1236 | ||
3641 | 1054 | auto buffer_item = release_buffer.add_buffers(); | 1237 | auto buffer_item = release_buffer.add_buffers(); |
3642 | 1055 | buffer_item->set_buffer_id(buffer_id.as_value()); | 1238 | buffer_item->set_buffer_id(buffer_id.as_value()); |
3643 | @@ -1058,15 +1241,15 @@ | |||
3644 | 1058 | stream_to_release.set_value(stream_id.as_value()); | 1241 | stream_to_release.set_value(stream_id.as_value()); |
3645 | 1059 | 1242 | ||
3646 | 1060 | EXPECT_CALL(*stubbed_session, destroy_buffer_stream(stream_id)); | 1243 | EXPECT_CALL(*stubbed_session, destroy_buffer_stream(stream_id)); |
3647 | 1061 | EXPECT_CALL(*stubbed_session, destroy_buffer(buffer_id)); | ||
3648 | 1062 | 1244 | ||
3649 | 1063 | mediator.connect(&connect_parameters, &connection, null_callback.get()); | ||
3650 | 1064 | mediator.release_buffer_stream(&stream_to_release, &null, null_callback.get()); | 1245 | mediator.release_buffer_stream(&stream_to_release, &null, null_callback.get()); |
3651 | 1065 | stream.reset(); | 1246 | stream.reset(); |
3652 | 1066 | 1247 | ||
3653 | 1067 | EXPECT_NO_THROW( | 1248 | EXPECT_NO_THROW( |
3654 | 1068 | mediator.release_buffers(&release_buffer, &null, null_callback.get()); | 1249 | mediator.release_buffers(&release_buffer, &null, null_callback.get()); |
3655 | 1069 | ); | 1250 | ); |
3656 | 1251 | |||
3657 | 1252 | EXPECT_TRUE(allocator->allocated_buffers.front().expired()); | ||
3658 | 1070 | } | 1253 | } |
3659 | 1071 | 1254 | ||
3660 | 1072 | MATCHER_P3(CursorIs, id_value, x_value, y_value, "cursor configuration match") | 1255 | MATCHER_P3(CursorIs, id_value, x_value, y_value, "cursor configuration match") |
3661 | @@ -1165,7 +1348,6 @@ | |||
3662 | 1165 | buffer_request->set_height(129); | 1348 | buffer_request->set_height(129); |
3663 | 1166 | buffer_request->set_pixel_format(mir_pixel_format_abgr_8888); | 1349 | buffer_request->set_pixel_format(mir_pixel_format_abgr_8888); |
3664 | 1167 | buffer_request->set_buffer_usage(mir_buffer_usage_hardware); | 1350 | buffer_request->set_buffer_usage(mir_buffer_usage_hardware); |
3665 | 1168 | int buffer_id = 3; | ||
3666 | 1169 | mf::ScreencastSessionId screencast_id{7}; | 1351 | mf::ScreencastSessionId screencast_id{7}; |
3667 | 1170 | auto mock_screencast = std::make_shared<NiceMock<mtd::MockScreencast>>(); | 1352 | auto mock_screencast = std::make_shared<NiceMock<mtd::MockScreencast>>(); |
3668 | 1171 | 1353 | ||
3669 | @@ -1181,7 +1363,180 @@ | |||
3670 | 1181 | mp::ScreencastRequest screencast_request; | 1363 | mp::ScreencastRequest screencast_request; |
3671 | 1182 | 1364 | ||
3672 | 1183 | screencast_request.mutable_id()->set_value(screencast_id.as_value()); | 1365 | screencast_request.mutable_id()->set_value(screencast_id.as_value()); |
3674 | 1184 | screencast_request.set_buffer_id(buffer_id); | 1366 | screencast_request.set_buffer_id(allocator->allocated_buffers.front().lock()->id().as_value()); |
3675 | 1185 | 1367 | ||
3676 | 1186 | mediator->screencast_to_buffer(&screencast_request, &null, null_callback.get()); | 1368 | mediator->screencast_to_buffer(&screencast_request, &null, null_callback.get()); |
3677 | 1187 | } | 1369 | } |
3678 | 1370 | |||
3679 | 1371 | namespace | ||
3680 | 1372 | { | ||
3681 | 1373 | void add_software_buffer_request( | ||
3682 | 1374 | mp::BufferAllocation& request, | ||
3683 | 1375 | int width, | ||
3684 | 1376 | int height, | ||
3685 | 1377 | MirPixelFormat format) | ||
3686 | 1378 | { | ||
3687 | 1379 | auto buffer_request = request.add_buffer_requests(); | ||
3688 | 1380 | buffer_request->set_width(width); | ||
3689 | 1381 | buffer_request->set_height(height); | ||
3690 | 1382 | buffer_request->set_pixel_format(format); | ||
3691 | 1383 | buffer_request->set_buffer_usage(static_cast<int>(mg::BufferUsage::software)); | ||
3692 | 1384 | } | ||
3693 | 1385 | |||
3694 | 1386 | void add_hardware_request( | ||
3695 | 1387 | mp::BufferAllocation& request, | ||
3696 | 1388 | int width, | ||
3697 | 1389 | int height, | ||
3698 | 1390 | int native_format, | ||
3699 | 1391 | int flags) | ||
3700 | 1392 | { | ||
3701 | 1393 | auto buffer_request = request.add_buffer_requests(); | ||
3702 | 1394 | |||
3703 | 1395 | buffer_request->set_width(width); | ||
3704 | 1396 | buffer_request->set_height(height); | ||
3705 | 1397 | buffer_request->set_native_format(native_format); | ||
3706 | 1398 | buffer_request->set_flags(flags); | ||
3707 | 1399 | } | ||
3708 | 1400 | } | ||
3709 | 1401 | |||
3710 | 1402 | TEST_F(SessionMediator, invalid_buffer_stream_in_software_buffer_allocation_sends_only_error_buffer) | ||
3711 | 1403 | { | ||
3712 | 1404 | using namespace testing; | ||
3713 | 1405 | |||
3714 | 1406 | auto sink = std::make_shared<NiceMock<mtd::MockEventSink>>(); | ||
3715 | 1407 | auto mediator = create_session_mediator_with_event_sink(sink); | ||
3716 | 1408 | |||
3717 | 1409 | mediator->connect(&connect_parameters, &connection, null_callback.get()); | ||
3718 | 1410 | |||
3719 | 1411 | auto num_requests = 3; | ||
3720 | 1412 | mp::Void null; | ||
3721 | 1413 | mp::BufferAllocation request; | ||
3722 | 1414 | request.mutable_id()->set_value(-1); | ||
3723 | 1415 | mg::BufferProperties properties(geom::Size{34, 84}, mir_pixel_format_abgr_8888, mg::BufferUsage::software); | ||
3724 | 1416 | for(auto i = 0; i < num_requests; i++) | ||
3725 | 1417 | { | ||
3726 | 1418 | add_software_buffer_request( | ||
3727 | 1419 | request, | ||
3728 | 1420 | properties.size.width.as_int(), | ||
3729 | 1421 | properties.size.height.as_int(), | ||
3730 | 1422 | properties.format); | ||
3731 | 1423 | } | ||
3732 | 1424 | |||
3733 | 1425 | EXPECT_CALL(*sink, add_buffer(_)).Times(0); | ||
3734 | 1426 | EXPECT_CALL(*sink, error_buffer(_,_,_)).Times(num_requests); | ||
3735 | 1427 | mediator->allocate_buffers(&request, &null, null_callback.get()); | ||
3736 | 1428 | EXPECT_THAT(allocator->allocated_buffers.size(), Eq(num_requests)); | ||
3737 | 1429 | } | ||
3738 | 1430 | |||
3739 | 1431 | TEST_F(SessionMediator, invalid_request_sends_error_buffer) | ||
3740 | 1432 | { | ||
3741 | 1433 | using namespace testing; | ||
3742 | 1434 | |||
3743 | 1435 | auto sink = std::make_shared<NiceMock<mtd::MockEventSink>>(); | ||
3744 | 1436 | auto mediator = create_session_mediator_with_event_sink(sink); | ||
3745 | 1437 | |||
3746 | 1438 | mediator->connect(&connect_parameters, &connection, null_callback.get()); | ||
3747 | 1439 | mediator->create_surface(&surface_parameters, &surface_response, null_callback.get()); | ||
3748 | 1440 | |||
3749 | 1441 | mp::Void null; | ||
3750 | 1442 | mp::BufferAllocation request; | ||
3751 | 1443 | *request.mutable_id() = surface_response.buffer_stream().id(); | ||
3752 | 1444 | |||
3753 | 1445 | decltype(request.add_buffer_requests()) buffer_request; | ||
3754 | 1446 | |||
3755 | 1447 | // Loop through all possibilities of has_flags, has_native_format, | ||
3756 | 1448 | // has_buffer_usage, has_pixel_format | ||
3757 | 1449 | for (int i = 0 ; i < 1<<4; ++i) | ||
3758 | 1450 | { | ||
3759 | 1451 | buffer_request = request.add_buffer_requests(); | ||
3760 | 1452 | buffer_request->set_width(1024); | ||
3761 | 1453 | buffer_request->set_height(768); | ||
3762 | 1454 | |||
3763 | 1455 | if (i & 1<<0) | ||
3764 | 1456 | buffer_request->set_flags(0xfaac); | ||
3765 | 1457 | if (i & 1<<1) | ||
3766 | 1458 | buffer_request->set_native_format(0xdeeb); | ||
3767 | 1459 | if (i & 1<<2) | ||
3768 | 1460 | buffer_request->set_pixel_format(mir_pixel_format_abgr_8888); | ||
3769 | 1461 | if (i & 1<<3) | ||
3770 | 1462 | buffer_request->set_buffer_usage(static_cast<int>(mg::BufferUsage::software)); | ||
3771 | 1463 | } | ||
3772 | 1464 | |||
3773 | 1465 | // There are two valid allocations here - one with flags and native_format set, | ||
3774 | 1466 | // one with pixel_format and buffer_usage set. | ||
3775 | 1467 | EXPECT_CALL(*sink, add_buffer(_)).Times(2); | ||
3776 | 1468 | |||
3777 | 1469 | EXPECT_CALL(*sink, error_buffer(_,_,_)).Times(16 - 2); | ||
3778 | 1470 | mediator->allocate_buffers(&request, &null, null_callback.get()); | ||
3779 | 1471 | EXPECT_THAT(allocator->allocated_buffers.size(), Eq(2)); | ||
3780 | 1472 | } | ||
3781 | 1473 | |||
3782 | 1474 | TEST_F(SessionMediator, sends_errors_only_for_invalid_buffer_parameters) | ||
3783 | 1475 | { | ||
3784 | 1476 | using namespace testing; | ||
3785 | 1477 | |||
3786 | 1478 | auto sink = std::make_shared<NiceMock<mtd::MockEventSink>>(); | ||
3787 | 1479 | auto mediator = create_session_mediator_with_event_sink(sink); | ||
3788 | 1480 | |||
3789 | 1481 | mediator->connect(&connect_parameters, &connection, null_callback.get()); | ||
3790 | 1482 | mediator->create_surface(&surface_parameters, &surface_response, null_callback.get()); | ||
3791 | 1483 | |||
3792 | 1484 | auto const num_requests = 3; | ||
3793 | 1485 | mp::Void null; | ||
3794 | 1486 | mp::BufferAllocation request; | ||
3795 | 1487 | *request.mutable_id() = surface_response.buffer_stream().id(); | ||
3796 | 1488 | mg::BufferProperties properties(geom::Size{34, 84}, mir_pixel_format_abgr_8888, mg::BufferUsage::software); | ||
3797 | 1489 | for(auto i = 0; i < num_requests; i++) | ||
3798 | 1490 | { | ||
3799 | 1491 | add_software_buffer_request( | ||
3800 | 1492 | request, | ||
3801 | 1493 | properties.size.width.as_int(), | ||
3802 | 1494 | properties.size.height.as_int(), | ||
3803 | 1495 | properties.format); | ||
3804 | 1496 | } | ||
3805 | 1497 | |||
3806 | 1498 | // Make the 2nd buffer request invalid, leaving the 1st and 3rd valid | ||
3807 | 1499 | request.mutable_buffer_requests(1)->set_pixel_format(mir_pixel_format_invalid); | ||
3808 | 1500 | |||
3809 | 1501 | EXPECT_CALL(*sink, add_buffer(_)).Times(num_requests - 1); | ||
3810 | 1502 | EXPECT_CALL(*sink, error_buffer(_,_,_)).Times(1); | ||
3811 | 1503 | mediator->allocate_buffers(&request, &null, null_callback.get()); | ||
3812 | 1504 | EXPECT_THAT(allocator->allocated_buffers.size(), Eq(num_requests - 1)); | ||
3813 | 1505 | } | ||
3814 | 1506 | |||
3815 | 1507 | TEST_F(SessionMediator, invalid_buffer_stream_in_native_buffer_allocation_sends_only_error_buffer) | ||
3816 | 1508 | { | ||
3817 | 1509 | using namespace testing; | ||
3818 | 1510 | |||
3819 | 1511 | auto const num_requests = 3; | ||
3820 | 1512 | |||
3821 | 1513 | auto sink = std::make_shared<NiceMock<mtd::MockEventSink>>(); | ||
3822 | 1514 | auto mediator = create_session_mediator_with_event_sink(sink); | ||
3823 | 1515 | |||
3824 | 1516 | mediator->connect(&connect_parameters, &connection, null_callback.get()); | ||
3825 | 1517 | |||
3826 | 1518 | geom::Size const size { 1029, 10302 }; | ||
3827 | 1519 | auto native_flags = 24u; | ||
3828 | 1520 | auto native_format = 124u; | ||
3829 | 1521 | mp::Void null; | ||
3830 | 1522 | mp::BufferAllocation request; | ||
3831 | 1523 | request.mutable_id()->set_value(42); | ||
3832 | 1524 | |||
3833 | 1525 | for (auto i = 0; i < num_requests; ++i) | ||
3834 | 1526 | { | ||
3835 | 1527 | add_hardware_request( | ||
3836 | 1528 | request, | ||
3837 | 1529 | size.width.as_int(), | ||
3838 | 1530 | size.height.as_int(), | ||
3839 | 1531 | native_format, | ||
3840 | 1532 | native_flags); | ||
3841 | 1533 | } | ||
3842 | 1534 | |||
3843 | 1535 | EXPECT_CALL(*sink, add_buffer(_)).Times(0); | ||
3844 | 1536 | EXPECT_CALL(*sink, error_buffer(_,_,_)).Times(num_requests); | ||
3845 | 1537 | mediator->allocate_buffers(&request, &null, null_callback.get()); | ||
3846 | 1538 | // We don't much care if the buffers were allocated and then freed or never allocated | ||
3847 | 1539 | EXPECT_THAT( | ||
3848 | 1540 | allocator->allocated_buffers, | ||
3849 | 1541 | Each(Property(&std::weak_ptr<mg::Buffer>::expired, Eq(true)))); | ||
3850 | 1542 | } | ||
3851 | 1188 | 1543 | ||
3852 | === modified file 'tests/unit-tests/scene/test_application_session.cpp' | |||
3853 | --- tests/unit-tests/scene/test_application_session.cpp 2017-05-25 04:43:29 +0000 | |||
3854 | +++ tests/unit-tests/scene/test_application_session.cpp 2017-07-18 03:23:56 +0000 | |||
3855 | @@ -63,17 +63,10 @@ | |||
3856 | 63 | 63 | ||
3857 | 64 | struct MockBufferStreamFactory : public ms::BufferStreamFactory | 64 | struct MockBufferStreamFactory : public ms::BufferStreamFactory |
3858 | 65 | { | 65 | { |
3864 | 66 | MockBufferStreamFactory() | 66 | MOCK_METHOD2(create_buffer_stream, std::shared_ptr<mc::BufferStream>( |
3865 | 67 | { | 67 | mf::BufferStreamId, mg::BufferProperties const&)); |
3861 | 68 | ON_CALL(*this, create_buffer_map(testing::_)) | ||
3862 | 69 | .WillByDefault(testing::Return(std::make_shared<mtd::StubClientBuffers>())); | ||
3863 | 70 | } | ||
3866 | 71 | MOCK_METHOD3(create_buffer_stream, std::shared_ptr<mc::BufferStream>( | 68 | MOCK_METHOD3(create_buffer_stream, std::shared_ptr<mc::BufferStream>( |
3872 | 72 | mf::BufferStreamId, std::shared_ptr<mf::ClientBuffers> const&, mg::BufferProperties const&)); | 69 | mf::BufferStreamId, int, mg::BufferProperties const&)); |
3868 | 73 | MOCK_METHOD4(create_buffer_stream, std::shared_ptr<mc::BufferStream>( | ||
3869 | 74 | mf::BufferStreamId, std::shared_ptr<mf::ClientBuffers> const&, int, mg::BufferProperties const&)); | ||
3870 | 75 | MOCK_METHOD1(create_buffer_map, std::shared_ptr<mf::ClientBuffers>( | ||
3871 | 76 | std::shared_ptr<mf::BufferSink> const&)); | ||
3873 | 77 | }; | 70 | }; |
3874 | 78 | 71 | ||
3875 | 79 | 72 | ||
3876 | @@ -488,7 +481,7 @@ | |||
3877 | 488 | NiceMock<MockSurfaceFactory> surface_factory; | 481 | NiceMock<MockSurfaceFactory> surface_factory; |
3878 | 489 | MockBufferStreamFactory mock_buffer_stream_factory; | 482 | MockBufferStreamFactory mock_buffer_stream_factory; |
3879 | 490 | std::shared_ptr<mc::BufferStream> const mock_stream = std::make_shared<mtd::MockBufferStream>(); | 483 | std::shared_ptr<mc::BufferStream> const mock_stream = std::make_shared<mtd::MockBufferStream>(); |
3881 | 491 | ON_CALL(mock_buffer_stream_factory, create_buffer_stream(_,_,_)).WillByDefault(Return(mock_stream)); | 484 | ON_CALL(mock_buffer_stream_factory, create_buffer_stream(_,_)).WillByDefault(Return(mock_stream)); |
3882 | 492 | ON_CALL(surface_factory, create_surface(_,_)).WillByDefault(Return(mock_surface)); | 485 | ON_CALL(surface_factory, create_surface(_,_)).WillByDefault(Return(mock_surface)); |
3883 | 493 | NiceMock<mtd::MockSurfaceStack> surface_stack; | 486 | NiceMock<mtd::MockSurfaceStack> surface_stack; |
3884 | 494 | 487 | ||
3885 | @@ -588,7 +581,7 @@ | |||
3886 | 588 | std::make_shared<mtd::StubBufferStream>(), | 581 | std::make_shared<mtd::StubBufferStream>(), |
3887 | 589 | std::make_shared<mtd::StubBufferStream>() | 582 | std::make_shared<mtd::StubBufferStream>() |
3888 | 590 | }}; | 583 | }}; |
3890 | 591 | EXPECT_CALL(mock_bufferstream_factory, create_buffer_stream(_,_,_)) | 584 | EXPECT_CALL(mock_bufferstream_factory, create_buffer_stream(_,_)) |
3891 | 592 | .WillOnce(Return(streams[0])) | 585 | .WillOnce(Return(streams[0])) |
3892 | 593 | .WillOnce(Return(streams[1])) | 586 | .WillOnce(Return(streams[1])) |
3893 | 594 | .WillOnce(Return(streams[2])); | 587 | .WillOnce(Return(streams[2])); |
3894 | @@ -630,7 +623,7 @@ | |||
3895 | 630 | 623 | ||
3896 | 631 | mg::BufferProperties properties(buffer_size, mir_pixel_format_argb_8888, mg::BufferUsage::software); | 624 | mg::BufferProperties properties(buffer_size, mir_pixel_format_argb_8888, mg::BufferUsage::software); |
3897 | 632 | 625 | ||
3899 | 633 | EXPECT_CALL(factory, create_buffer_stream(_,_,properties)).Times(1) | 626 | EXPECT_CALL(factory, create_buffer_stream(_,properties)).Times(1) |
3900 | 634 | .WillOnce(Return(mt::fake_shared(stream))); | 627 | .WillOnce(Return(mt::fake_shared(stream))); |
3901 | 635 | 628 | ||
3902 | 636 | auto session = make_application_session_with_buffer_stream_factory(mt::fake_shared(factory)); | 629 | auto session = make_application_session_with_buffer_stream_factory(mt::fake_shared(factory)); |
3903 | @@ -658,7 +651,7 @@ | |||
3904 | 658 | 651 | ||
3905 | 659 | EXPECT_CALL(stream, allow_framedropping(true)) | 652 | EXPECT_CALL(stream, allow_framedropping(true)) |
3906 | 660 | .Times(0); | 653 | .Times(0); |
3908 | 661 | EXPECT_CALL(factory, create_buffer_stream(_,_,properties)).Times(1) | 654 | EXPECT_CALL(factory, create_buffer_stream(_,properties)).Times(1) |
3909 | 662 | .WillOnce(Return(mt::fake_shared(stream))); | 655 | .WillOnce(Return(mt::fake_shared(stream))); |
3910 | 663 | 656 | ||
3911 | 664 | auto session = make_application_session_with_buffer_stream_factory(mt::fake_shared(factory)); | 657 | auto session = make_application_session_with_buffer_stream_factory(mt::fake_shared(factory)); |
3912 | 665 | 658 | ||
3913 | === modified file 'tests/unit-tests/scene/test_surface_stack.cpp' | |||
3914 | --- tests/unit-tests/scene/test_surface_stack.cpp 2017-05-08 03:04:26 +0000 | |||
3915 | +++ tests/unit-tests/scene/test_surface_stack.cpp 2017-07-18 03:23:56 +0000 | |||
3916 | @@ -289,17 +289,7 @@ | |||
3917 | 289 | ms::SurfaceStack stack{report}; | 289 | ms::SurfaceStack stack{report}; |
3918 | 290 | stack.register_compositor(this); | 290 | stack.register_compositor(this); |
3919 | 291 | 291 | ||
3931 | 292 | struct StubBuffers : mtd::StubClientBuffers | 292 | auto stream = std::make_shared<mc::Stream>(geom::Size{ 1, 1 }, mir_pixel_format_abgr_8888); |
3921 | 293 | { | ||
3922 | 294 | std::shared_ptr<mg::Buffer> get(mg::BufferID) const override | ||
3923 | 295 | { | ||
3924 | 296 | return buffer; | ||
3925 | 297 | } | ||
3926 | 298 | std::shared_ptr<mg::Buffer> buffer {std::make_shared<mtd::StubBuffer>()}; | ||
3927 | 299 | }; | ||
3928 | 300 | |||
3929 | 301 | auto buffers = std::make_shared<StubBuffers>(); | ||
3930 | 302 | auto stream = std::make_shared<mc::Stream>(buffers, geom::Size{ 1, 1 }, mir_pixel_format_abgr_8888); | ||
3932 | 303 | 293 | ||
3933 | 304 | auto surface = std::make_shared<ms::BasicSurface>( | 294 | auto surface = std::make_shared<ms::BasicSurface>( |
3934 | 305 | std::string("stub"), | 295 | std::string("stub"), |
FAILED: Continuous integration, rev:4210 /mir-jenkins. ubuntu. com/job/ mir-ci/ 3472/ /mir-jenkins. ubuntu. com/job/ build-mir/ 4745/console /mir-jenkins. ubuntu. com/job/ build-0- fetch/4903 /mir-jenkins. ubuntu. com/job/ build-1- sourcepkg/ release= artful/ 4892 /mir-jenkins. ubuntu. com/job/ build-1- sourcepkg/ release= xenial/ 4892 /mir-jenkins. ubuntu. com/job/ build-1- sourcepkg/ release= zesty/4892 /mir-jenkins. ubuntu. com/job/ build-2- binpkg- mir/arch= amd64,compiler= clang,platform= mesa,release= artful/ 4782/console /mir-jenkins. ubuntu. com/job/ build-2- binpkg- mir/arch= amd64,compiler= clang,platform= mesa,release= zesty/4782 /mir-jenkins. ubuntu. com/job/ build-2- binpkg- mir/arch= amd64,compiler= clang,platform= mesa,release= zesty/4782/ artifact/ output/ *zip*/output. zip /mir-jenkins. ubuntu. com/job/ build-2- binpkg- mir/arch= amd64,compiler= gcc,platform= mesa,release= artful/ 4782 /mir-jenkins. ubuntu. com/job/ build-2- binpkg- mir/arch= amd64,compiler= gcc,platform= mesa,release= artful/ 4782/artifact/ output/ *zip*/output. zip /mir-jenkins. ubuntu. com/job/ build-2- binpkg- mir/arch= amd64,compiler= gcc,platform= mesa,release= xenial/ 4782/console /mir-jenkins. ubuntu. com/job/ build-2- binpkg- mir/arch= amd64,compiler= gcc,platform= mesa,release= zesty/4782 /mir-jenkins. ubuntu. com/job/ build-2- binpkg- mir/arch= amd64,compiler= gcc,platform= mesa,release= zesty/4782/ artifact/ output/ *zip*/output. zip /mir-jenkins. ubuntu. com/job/ build-2- binpkg- mir/arch= cross-armhf, compiler= gcc,platform= mesa,release= artful/ 4782 /mir-jenkins. ubuntu. com/job/ build-2- binpkg- mir/arch= cross-armhf, compiler= gcc,platform= mesa,release= artful/ 4782/artifact/ output/ *zip*/output. zip /mir-jenkins. ubuntu. com/job/ build-2- binpkg- mir/arch= cross-armhf, compiler= gcc,platform= mesa,release= zesty/4782 /mir-jenkins. ubuntu. com/job/ build-2- binpkg- mir/arch= cross-armhf, compiler= gcc,platform= mesa,release= zesty/4782/ artifact/ output/ *zip*/output. zip /mir-jenkins. ubuntu. com/job/ build-2- binpkg- mir/arch= i386,compiler= gcc,platform= mesa,release= xenial/ 4782/console
https:/
Executed test runs:
FAILURE: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
FAILURE: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
FAILURE: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
FAILURE: https:/
Click here to trigger a rebuild: /mir-jenkins. ubuntu. com/job/ mir-ci/ 3472/rebuild
https:/