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