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