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