Merge lp:~kdub/mir/notify-buffers-directly into lp:mir
- notify-buffers-directly
- Merge into development-branch
Status: | Merged |
---|---|
Approved by: | Cemil Azizoglu |
Approved revision: | no longer in the source branch. |
Merged at revision: | 3479 |
Proposed branch: | lp:~kdub/mir/notify-buffers-directly |
Merge into: | lp:mir |
Prerequisite: | lp:~kdub/mir/notify-buffers-directly-groundwork |
Diff against target: |
1602 lines (+556/-299) 24 files modified
examples/render_surfaces.cpp (+3/-0) include/server/mir/frontend/buffer_sink.h (+3/-0) src/client/buffer_stream.cpp (+4/-5) src/client/buffer_stream.h (+1/-1) src/client/buffer_vault.cpp (+21/-25) src/client/buffer_vault.h (+1/-1) src/client/presentation_chain.cpp (+6/-39) src/client/rpc/mir_protobuf_rpc_channel.cpp (+36/-4) src/protobuf/mir_protobuf.proto (+8/-0) src/protobuf/symbols.map (+4/-0) src/server/compositor/buffer_map.cpp (+5/-3) src/server/frontend/event_sender.cpp (+31/-1) src/server/frontend/event_sender.h (+4/-0) src/server/scene/global_event_sender.cpp (+12/-0) src/server/scene/global_event_sender.h (+3/-0) tests/include/mir/test/doubles/mock_event_sink.h (+4/-0) tests/include/mir/test/doubles/null_event_sink.h (+4/-1) tests/integration-tests/test_buffer_scheduling.cpp (+81/-19) tests/mir_test_doubles/mock_event_sink_factory.cpp (+18/-0) tests/unit-tests/client/test_buffer_vault.cpp (+99/-90) tests/unit-tests/client/test_client_buffer_stream.cpp (+20/-1) tests/unit-tests/client/test_presentation_chain.cpp (+43/-102) tests/unit-tests/client/test_protobuf_rpc_channel.cpp (+138/-0) tests/unit-tests/compositor/test_client_buffers.cpp (+7/-7) |
To merge this branch: | bzr merge lp:~kdub/mir/notify-buffers-directly |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Mir CI Bot | continuous-integration | Approve | |
Alan Griffiths | Abstain | ||
Cemil Azizoglu (community) | conceptual | Approve | |
Review via email: mp+291522@code.launchpad.net |
Commit message
client: send incoming asynchronous buffer messages directly to the mcl::Buffer object. Prepares the buffers to be allocated from the connection, instead of a chain/stream.
Change the async protocol a bit too so the RPC channel can manage the async buffers better. The RPC allocate/free buffer calls are not synchronized with the async buffer sending, so the server has to be a bit more explicit about what operation its performing, so the client side rpc channel can clean up the buffers better.
So the notification chains go from:
OBS (buffer_stream):
rpc -> buffer_stream
NBS (buffer_stream):
rpc -> buffer_stream
NBS: (presentation_
rpc -> buffer_stream -> buffer
to:
OBS (buffer_stream):
rpc -> buffer_stream
NBS (buffer_stream):
rpc -> buffer -> buffer_stream
NBS: (presentation_
rpc -> buffer
Description of the change
client: send incoming asynchronous buffer messages directly to the mcl::Buffer object. Prepares the buffers to be allocated from the connection, instead of a chain/stream.
Change the async protocol a bit too so the RPC channel can manage the async buffers better. The RPC allocate/free buffer calls are not synchronized with the async buffer sending, so the server has to be a bit more explicit about what operation its performing, so the client side rpc channel can clean up the buffers better.
So the notification chains go from:
OBS (buffer_stream):
rpc -> buffer_stream
NBS (buffer_stream):
rpc -> buffer_stream
NBS: (presentation_
rpc -> buffer_stream -> buffer
to:
OBS (buffer_stream):
rpc -> buffer_stream
NBS (buffer_stream):
rpc -> buffer -> buffer_stream
NBS: (presentation_
rpc -> buffer
Mir CI Bot (mir-ci-bot) wrote : | # |
Mir CI Bot (mir-ci-bot) wrote : | # |
FAILED: Continuous integration, rev:3434
https:/
Executed test runs:
FAILURE: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
FAILURE: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
Click here to trigger a rebuild:
https:/
Kevin DuBois (kdub) wrote : | # |
^^^
17:47:56 Slave went offline during the build
Kevin DuBois (kdub) wrote : | # |
successful rerun, not sure if jenkins will revote on the MP or not:
https:/
Mir CI Bot (mir-ci-bot) wrote : | # |
FAILED: Continuous integration, rev:3434
https:/
Executed test runs:
FAILURE: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
FAILURE: https:/
Click here to trigger a rebuild:
https:/
Kevin DuBois (kdub) wrote : | # |
17:45:22 11: [ FAILED ] MirSurfaceVisib
unrelated
Mir CI Bot (mir-ci-bot) wrote : | # |
PASSED: Continuous integration, rev:3434
https:/
Executed test runs:
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:/
Click here to trigger a rebuild:
https:/
Chris Halse Rogers (raof) wrote : | # |
Heh. Our internal interfaces could do with some documentation... What *is* a BufferSink? What should an implementation of it do? send_buffer is reasonably self explanatory, but what is update_buffer expected to do? What is add/remove buffer expected to do?
493 +void ms::GlobalEvent
494 +{
495 +}
Bah. GlobalEventSender accumulates more lies. There probably needs to be some refactory so that GlobalEventSender doesn't have so many do-nothing non-implementat
Cemil Azizoglu (cemil-azizoglu) wrote : | # |
Conceptually ok.
Alan Griffiths (alan-griffiths) wrote : | # |
+ virtual void add_buffer(
+ virtual void remove_
+ virtual void update_
These seem like very odd member functions to see on a "sink".
Also, it seems odd to see them taking a non-const reference.
I've not got any constructive suggestions right now, but I feel there must be a better way.
Kevin DuBois (kdub) wrote : | # |
notify_
notify_
notify_
?
Mir CI Bot (mir-ci-bot) wrote : | # |
PASSED: Continuous integration, rev:3436
https:/
Executed test runs:
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:/
Click here to trigger a rebuild:
https:/
Mir CI Bot (mir-ci-bot) : | # |
Preview Diff
1 | === modified file 'examples/render_surfaces.cpp' |
2 | --- examples/render_surfaces.cpp 2016-04-15 03:41:28 +0000 |
3 | +++ examples/render_surfaces.cpp 2016-04-18 17:46:27 +0000 |
4 | @@ -373,6 +373,9 @@ |
5 | struct NullBufferSink : mf::BufferSink |
6 | { |
7 | void send_buffer(mf::BufferStreamId, mg::Buffer&, mg::BufferIpcMsgType) override {} |
8 | + void add_buffer(mg::Buffer&) override {} |
9 | + void remove_buffer(mg::Buffer&) override {} |
10 | + void update_buffer(mg::Buffer&) override {} |
11 | }; |
12 | |
13 | auto const stream = buffer_stream_factory->create_buffer_stream( |
14 | |
15 | === modified file 'include/server/mir/frontend/buffer_sink.h' |
16 | --- include/server/mir/frontend/buffer_sink.h 2015-07-20 14:54:01 +0000 |
17 | +++ include/server/mir/frontend/buffer_sink.h 2016-04-18 17:46:27 +0000 |
18 | @@ -33,6 +33,9 @@ |
19 | virtual ~BufferSink() = default; |
20 | |
21 | virtual void send_buffer(frontend::BufferStreamId id, graphics::Buffer& buffer, graphics::BufferIpcMsgType) = 0; |
22 | + virtual void add_buffer(graphics::Buffer&) = 0; |
23 | + virtual void remove_buffer(graphics::Buffer&) = 0; |
24 | + virtual void update_buffer(graphics::Buffer&) = 0; |
25 | |
26 | protected: |
27 | BufferSink() = default; |
28 | |
29 | === modified file 'src/client/buffer_stream.cpp' |
30 | --- src/client/buffer_stream.cpp 2016-04-18 17:46:26 +0000 |
31 | +++ src/client/buffer_stream.cpp 2016-04-18 17:46:27 +0000 |
32 | @@ -303,9 +303,8 @@ |
33 | { |
34 | } |
35 | |
36 | - void deposit(mp::Buffer const& buffer, mir::optional_value<geom::Size>, MirPixelFormat) override |
37 | + void deposit(mp::Buffer const&, mir::optional_value<geom::Size>, MirPixelFormat) override |
38 | { |
39 | - vault.wire_transfer_inbound(buffer); |
40 | } |
41 | |
42 | void advance_current_buffer(std::unique_lock<std::mutex>& lk) |
43 | @@ -412,7 +411,7 @@ |
44 | std::shared_ptr<MirWaitHandle> creation_wait_handle, |
45 | mclr::DisplayServer& server, |
46 | std::shared_ptr<mcl::ClientPlatform> const& client_platform, |
47 | - std::weak_ptr<mcl::SurfaceMap> const&, |
48 | + std::weak_ptr<mcl::SurfaceMap> const& map, |
49 | std::shared_ptr<mcl::AsyncBufferFactory> const& factory, |
50 | mp::BufferStream const& a_protobuf_bs, |
51 | std::shared_ptr<mcl::PerfReport> const& perf_report, |
52 | @@ -429,7 +428,7 @@ |
53 | ideal_buffer_size(ideal_size), |
54 | nbuffers(nbuffers), |
55 | creation_wait_handle(creation_wait_handle), |
56 | - map(std::make_shared<mcl::ConnectionSurfaceMap>()), |
57 | + map(map), |
58 | factory(factory) |
59 | { |
60 | init_swap_interval(); |
61 | @@ -457,7 +456,7 @@ |
62 | else |
63 | { |
64 | buffer_depository = std::make_unique<NewBufferSemantics>( |
65 | - client_platform->create_buffer_factory(), std::make_shared<mcl::BufferFactory>(), |
66 | + client_platform->create_buffer_factory(), factory, |
67 | std::make_shared<Requests>(display_server, protobuf_bs->id().value()), map, |
68 | ideal_buffer_size, static_cast<MirPixelFormat>(protobuf_bs->pixel_format()), |
69 | protobuf_bs->buffer_usage(), nbuffers); |
70 | |
71 | === modified file 'src/client/buffer_stream.h' |
72 | --- src/client/buffer_stream.h 2016-04-18 17:46:26 +0000 |
73 | +++ src/client/buffer_stream.h 2016-04-18 17:46:27 +0000 |
74 | @@ -165,7 +165,7 @@ |
75 | size_t const nbuffers; |
76 | std::string error_message; |
77 | std::shared_ptr<MirWaitHandle> creation_wait_handle; |
78 | - std::shared_ptr<SurfaceMap> const map; |
79 | + std::weak_ptr<SurfaceMap> const map; |
80 | std::shared_ptr<AsyncBufferFactory> const factory; |
81 | }; |
82 | |
83 | |
84 | === modified file 'src/client/buffer_vault.cpp' |
85 | --- src/client/buffer_vault.cpp 2016-04-04 03:30:04 +0000 |
86 | +++ src/client/buffer_vault.cpp 2016-04-18 17:46:27 +0000 |
87 | @@ -24,6 +24,9 @@ |
88 | #include "surface_map.h" |
89 | #include "mir_protobuf.pb.h" |
90 | #include "protobuf_to_native_buffer.h" |
91 | +#include "connection_surface_map.h" |
92 | +#include "buffer_factory.h" |
93 | +#include "buffer.h" |
94 | #include <algorithm> |
95 | #include <boost/throw_exception.hpp> |
96 | |
97 | @@ -42,8 +45,10 @@ |
98 | |
99 | namespace |
100 | { |
101 | -void ignore(MirPresentationChain*, MirBuffer*, void*) |
102 | +void incoming_buffer(MirPresentationChain*, MirBuffer* buffer, void* context) |
103 | { |
104 | + auto vault = static_cast<mcl::BufferVault*>(context); |
105 | + vault->wire_transfer_inbound(reinterpret_cast<mcl::Buffer*>(buffer)->rpc_id()); |
106 | } |
107 | } |
108 | |
109 | @@ -74,6 +79,7 @@ |
110 | if (disconnected_) |
111 | return; |
112 | |
113 | + buffer_factory->cancel_requests_with_context(this); |
114 | for (auto& it : buffers) |
115 | try |
116 | { |
117 | @@ -86,7 +92,8 @@ |
118 | |
119 | void mcl::BufferVault::alloc_buffer(geom::Size size, MirPixelFormat format, int usage) |
120 | { |
121 | - buffer_factory->expect_buffer(platform_factory, nullptr, size, format, (MirBufferUsage)usage, ignore, nullptr); |
122 | + buffer_factory->expect_buffer(platform_factory, nullptr, size, format, static_cast<MirBufferUsage>(usage), |
123 | + incoming_buffer, this); |
124 | server_requests->allocate_buffer(size, format, usage); |
125 | } |
126 | |
127 | @@ -116,6 +123,8 @@ |
128 | mcl::NoTLSFuture<std::shared_ptr<mcl::Buffer>> mcl::BufferVault::withdraw() |
129 | { |
130 | std::lock_guard<std::mutex> lk(mutex); |
131 | + if (disconnected_) |
132 | + BOOST_THROW_EXCEPTION(std::logic_error("server_disconnected")); |
133 | mcl::NoTLSPromise<std::shared_ptr<mcl::Buffer>> promise; |
134 | auto it = std::find_if(buffers.begin(), buffers.end(), |
135 | [this](std::pair<int, Owner> const& entry) { |
136 | @@ -160,42 +169,29 @@ |
137 | server_requests->submit_buffer(*buffer); |
138 | } |
139 | |
140 | -void mcl::BufferVault::wire_transfer_inbound(mp::Buffer const& protobuf_buffer) |
141 | +void mcl::BufferVault::wire_transfer_inbound(int buffer_id) |
142 | { |
143 | - std::shared_ptr<MirBufferPackage> package = mcl::protobuf_to_native_buffer(protobuf_buffer); |
144 | - std::shared_ptr<mcl::Buffer> buffer; |
145 | std::unique_lock<std::mutex> lk(mutex); |
146 | - auto it = buffers.find(protobuf_buffer.buffer_id()); |
147 | + |
148 | + auto buffer = checked_buffer_from_map(buffer_id); |
149 | + auto inbound_size = buffer->size(); |
150 | + auto it = buffers.find(buffer_id); |
151 | if (it == buffers.end()) |
152 | { |
153 | - geom::Size sz{package->width, package->height}; |
154 | - if (sz != size) |
155 | + if (inbound_size != size) |
156 | { |
157 | lk.unlock(); |
158 | - for (int i = 0; i != package->fd_items; ++i) |
159 | - close(package->fd[i]); |
160 | - |
161 | - realloc_buffer(protobuf_buffer.buffer_id(), size, format, usage); |
162 | + realloc_buffer(buffer_id, size, format, usage); |
163 | return; |
164 | } |
165 | - |
166 | - buffer = buffer_factory->generate_buffer(protobuf_buffer); |
167 | - if (auto map = surface_map.lock()) |
168 | - map->insert(protobuf_buffer.buffer_id(), buffer); |
169 | - else |
170 | - BOOST_THROW_EXCEPTION(std::logic_error("connection resources lost; cannot access buffer")); |
171 | - |
172 | - buffers[protobuf_buffer.buffer_id()] = Owner::Self; |
173 | - buffer->received(); |
174 | + buffers[buffer_id] = Owner::Self; |
175 | } |
176 | else |
177 | { |
178 | - buffer = checked_buffer_from_map(protobuf_buffer.buffer_id()); |
179 | - buffer->received(*package); |
180 | auto should_decrease_count = (current_buffer_count > needed_buffer_count); |
181 | if (size != buffer->size() || should_decrease_count) |
182 | { |
183 | - int id = it->first; |
184 | + auto id = it->first; |
185 | buffers.erase(it); |
186 | lk.unlock(); |
187 | |
188 | @@ -214,7 +210,7 @@ |
189 | |
190 | if (!promises.empty()) |
191 | { |
192 | - buffers[protobuf_buffer.buffer_id()] = Owner::ContentProducer; |
193 | + buffers[buffer_id] = Owner::ContentProducer; |
194 | promises.front().set_value(buffer); |
195 | promises.pop_front(); |
196 | } |
197 | |
198 | === modified file 'src/client/buffer_vault.h' |
199 | --- src/client/buffer_vault.h 2016-04-04 03:30:04 +0000 |
200 | +++ src/client/buffer_vault.h 2016-04-18 17:46:27 +0000 |
201 | @@ -66,7 +66,7 @@ |
202 | |
203 | NoTLSFuture<std::shared_ptr<Buffer>> withdraw(); |
204 | void deposit(std::shared_ptr<Buffer> const& buffer); |
205 | - void wire_transfer_inbound(protobuf::Buffer const&); |
206 | + void wire_transfer_inbound(int buffer_id); |
207 | void wire_transfer_outbound(std::shared_ptr<Buffer> const& buffer); |
208 | void set_size(geometry::Size); |
209 | void disconnected(); |
210 | |
211 | === modified file 'src/client/presentation_chain.cpp' |
212 | --- src/client/presentation_chain.cpp 2016-03-23 06:39:56 +0000 |
213 | +++ src/client/presentation_chain.cpp 2016-04-18 17:46:27 +0000 |
214 | @@ -78,16 +78,9 @@ |
215 | { |
216 | mp::BufferRequest request; |
217 | { |
218 | - std::lock_guard<decltype(mutex)> lk(mutex); |
219 | - auto buffer_it = std::find_if(buffers.begin(), buffers.end(), |
220 | - [&buffer](std::unique_ptr<Buffer> const& it) |
221 | - { return reinterpret_cast<MirBuffer*>(it.get()) == buffer; }); |
222 | - if (buffer_it == buffers.end()) |
223 | - BOOST_THROW_EXCEPTION(std::logic_error("unknown buffer")); |
224 | - |
225 | request.mutable_id()->set_value(stream_id); |
226 | - request.mutable_buffer()->set_buffer_id((*buffer_it)->rpc_id()); |
227 | - (*buffer_it)->submitted(); |
228 | + request.mutable_buffer()->set_buffer_id(reinterpret_cast<mcl::Buffer*>(buffer)->rpc_id()); |
229 | + reinterpret_cast<mcl::Buffer*>(buffer)->submitted(); |
230 | } |
231 | |
232 | auto ignored = new mp::Void; |
233 | @@ -97,42 +90,16 @@ |
234 | void mcl::PresentationChain::release_buffer(MirBuffer* buffer) |
235 | { |
236 | mp::BufferRelease request; |
237 | - { |
238 | - std::lock_guard<decltype(mutex)> lk(mutex); |
239 | - auto buffer_it = std::find_if(buffers.begin(), buffers.end(), |
240 | - [&buffer](std::unique_ptr<Buffer> const& it) |
241 | - { return reinterpret_cast<MirBuffer*>(it.get()) == buffer; }); |
242 | - if (buffer_it == buffers.end()) |
243 | - BOOST_THROW_EXCEPTION(std::logic_error("unknown buffer")); |
244 | - |
245 | - request.mutable_id()->set_value(stream_id); |
246 | - auto buffer_req = request.add_buffers(); |
247 | - buffer_req->set_buffer_id((*buffer_it)->rpc_id()); |
248 | - |
249 | - buffers.erase(buffer_it); |
250 | - } |
251 | + request.mutable_id()->set_value(stream_id); |
252 | + auto buffer_req = request.add_buffers(); |
253 | + buffer_req->set_buffer_id(reinterpret_cast<mcl::Buffer*>(buffer)->rpc_id()); |
254 | |
255 | auto ignored = new mp::Void; |
256 | server.release_buffers(&request, ignored, gp::NewCallback(ignore_response, ignored)); |
257 | } |
258 | |
259 | -void mcl::PresentationChain::buffer_available(mp::Buffer const& buffer) |
260 | +void mcl::PresentationChain::buffer_available(mp::Buffer const&) |
261 | { |
262 | - std::lock_guard<decltype(mutex)> lk(mutex); |
263 | - //first see if this buffer has been here before |
264 | - std::shared_ptr<MirBufferPackage> package = mcl::protobuf_to_native_buffer(buffer); |
265 | - auto buffer_it = std::find_if(buffers.begin(), buffers.end(), |
266 | - [&buffer](std::unique_ptr<Buffer> const& b) |
267 | - { return buffer.buffer_id() == b->rpc_id(); }); |
268 | - if (buffer_it != buffers.end()) |
269 | - { |
270 | - (*buffer_it)->received(*package); |
271 | - } |
272 | - else |
273 | - { |
274 | - buffers.emplace_back(mir_buffer_factory->generate_buffer(buffer)); |
275 | - buffers.back()->received(); |
276 | - } |
277 | } |
278 | |
279 | void mcl::PresentationChain::buffer_unavailable() |
280 | |
281 | === modified file 'src/client/rpc/mir_protobuf_rpc_channel.cpp' |
282 | --- src/client/rpc/mir_protobuf_rpc_channel.cpp 2016-04-04 03:30:04 +0000 |
283 | +++ src/client/rpc/mir_protobuf_rpc_channel.cpp 2016-04-18 17:46:27 +0000 |
284 | @@ -20,11 +20,15 @@ |
285 | #include "rpc_report.h" |
286 | |
287 | #include "../surface_map.h" |
288 | +#include "../buffer.h" |
289 | +#include "../presentation_chain.h" |
290 | +#include "../buffer_factory.h" |
291 | #include "../mir_surface.h" |
292 | #include "../display_configuration.h" |
293 | #include "../lifecycle_control.h" |
294 | #include "../event_sink.h" |
295 | #include "../make_protobuf_object.h" |
296 | +#include "../protobuf_to_native_buffer.h" |
297 | #include "mir/input/input_devices.h" |
298 | #include "mir/variable_length_array.h" |
299 | #include "mir/events/event_builders.h" |
300 | @@ -35,6 +39,7 @@ |
301 | #include "mir_protobuf_wire.pb.h" |
302 | |
303 | #include <boost/bind.hpp> |
304 | +#include <boost/throw_exception.hpp> |
305 | #include <endian.h> |
306 | |
307 | #include <stdexcept> |
308 | @@ -304,10 +309,37 @@ |
309 | { |
310 | try |
311 | { |
312 | - map->with_stream_do(mf::BufferStreamId(seq.buffer_request().id().value()), |
313 | - [&] (mcl::BufferReceiver* receiver) { |
314 | - receiver->buffer_available(seq.buffer_request().buffer()); |
315 | - }); |
316 | + if (seq.buffer_request().has_id()) |
317 | + { |
318 | + map->with_stream_do(mf::BufferStreamId(seq.buffer_request().id().value()), |
319 | + [&] (mcl::BufferReceiver* receiver) { |
320 | + receiver->buffer_available(seq.buffer_request().buffer()); |
321 | + }); |
322 | + } |
323 | + |
324 | + else if (seq.buffer_request().has_operation()) |
325 | + { |
326 | + auto stream_cmd = seq.buffer_request().operation(); |
327 | + auto buffer_id = seq.buffer_request().buffer().buffer_id(); |
328 | + std::shared_ptr<mcl::Buffer> buffer; |
329 | + switch (stream_cmd) |
330 | + { |
331 | + case mp::BufferOperation::add: |
332 | + buffer = buffer_factory->generate_buffer(seq.buffer_request().buffer()); |
333 | + map->insert(buffer_id, buffer); |
334 | + buffer->received(); |
335 | + break; |
336 | + case mp::BufferOperation::update: |
337 | + map->buffer(buffer_id)->received( |
338 | + *mcl::protobuf_to_native_buffer(seq.buffer_request().buffer())); |
339 | + break; |
340 | + case mp::BufferOperation::remove: |
341 | + map->erase(buffer_id); |
342 | + break; |
343 | + default: |
344 | + BOOST_THROW_EXCEPTION(std::runtime_error("unknown buffer operation")); |
345 | + } |
346 | + } |
347 | } |
348 | catch (std::exception& e) |
349 | { |
350 | |
351 | === modified file 'src/protobuf/mir_protobuf.proto' |
352 | --- src/protobuf/mir_protobuf.proto 2016-04-14 05:37:22 +0000 |
353 | +++ src/protobuf/mir_protobuf.proto 2016-04-18 17:46:27 +0000 |
354 | @@ -137,9 +137,17 @@ |
355 | optional BufferStreamId id = 2; |
356 | }; |
357 | |
358 | +enum BufferOperation |
359 | +{ |
360 | + add = 0; |
361 | + update = 1; |
362 | + remove = 2; |
363 | +}; |
364 | + |
365 | message BufferRequest { |
366 | optional BufferStreamId id = 1; |
367 | optional Buffer buffer = 2; |
368 | + optional BufferOperation operation = 3; |
369 | }; |
370 | |
371 | message Buffer { |
372 | |
373 | === modified file 'src/protobuf/symbols.map' |
374 | --- src/protobuf/symbols.map 2016-04-13 00:58:26 +0000 |
375 | +++ src/protobuf/symbols.map 2016-04-18 17:46:27 +0000 |
376 | @@ -40,6 +40,10 @@ |
377 | mir::protobuf::Buffer::MergeFrom*; |
378 | mir::protobuf::Buffer::MergePartialFromCodedStream*; |
379 | mir::protobuf::Buffer::New*; |
380 | + mir::protobuf::BufferOperation_IsValid*; |
381 | + mir::protobuf::BufferOperation_MIN*; |
382 | + mir::protobuf::BufferOperation_ARRAYSIZE*; |
383 | + mir::protobuf::BufferOperation_MAX*; |
384 | mir::protobuf::BufferRelease::?BufferRelease*; |
385 | mir::protobuf::BufferRelease::BufferRelease*; |
386 | mir::protobuf::BufferRelease::ByteSize*; |
387 | |
388 | === modified file 'src/server/compositor/buffer_map.cpp' |
389 | --- src/server/compositor/buffer_map.cpp 2016-04-05 03:47:49 +0000 |
390 | +++ src/server/compositor/buffer_map.cpp 2016-04-18 17:46:27 +0000 |
391 | @@ -53,14 +53,16 @@ |
392 | std::unique_lock<decltype(mutex)> lk(mutex); |
393 | auto buffer = allocator->alloc_buffer(properties); |
394 | buffers[buffer->id()] = {buffer, Owner::client}; |
395 | - sink->send_buffer(stream_id, *buffer, mg::BufferIpcMsgType::full_msg); |
396 | + sink->add_buffer(*buffer); |
397 | return buffer->id(); |
398 | } |
399 | |
400 | void mc::BufferMap::remove_buffer(mg::BufferID id) |
401 | { |
402 | std::unique_lock<decltype(mutex)> lk(mutex); |
403 | - buffers.erase(checked_buffers_find(id, lk)); |
404 | + auto it = checked_buffers_find(id, lk); |
405 | + sink->remove_buffer(*it->second.buffer); |
406 | + buffers.erase(it); |
407 | } |
408 | |
409 | void mc::BufferMap::send_buffer(mg::BufferID id) |
410 | @@ -72,7 +74,7 @@ |
411 | auto buffer = it->second.buffer; |
412 | it->second.owner = Owner::client; |
413 | lk.unlock(); |
414 | - sink->send_buffer(stream_id, *buffer, mg::BufferIpcMsgType::update_msg); |
415 | + sink->update_buffer(*buffer); |
416 | } |
417 | } |
418 | |
419 | |
420 | === modified file 'src/server/frontend/event_sender.cpp' |
421 | --- src/server/frontend/event_sender.cpp 2016-01-29 08:18:22 +0000 |
422 | +++ src/server/frontend/event_sender.cpp 2016-04-18 17:46:27 +0000 |
423 | @@ -128,11 +128,41 @@ |
424 | } |
425 | } |
426 | |
427 | +void mfd::EventSender::add_buffer(graphics::Buffer& buffer) |
428 | +{ |
429 | + mp::EventSequence seq; |
430 | + auto request = seq.mutable_buffer_request(); |
431 | + request->set_operation(mir::protobuf::BufferOperation::add); |
432 | + send_buffer(seq, buffer, mg::BufferIpcMsgType::full_msg); |
433 | +} |
434 | + |
435 | +void mfd::EventSender::remove_buffer(graphics::Buffer& buffer) |
436 | +{ |
437 | + mp::EventSequence seq; |
438 | + auto request = seq.mutable_buffer_request(); |
439 | + request->set_operation(mir::protobuf::BufferOperation::remove); |
440 | + send_buffer(seq, buffer, mg::BufferIpcMsgType::update_msg); |
441 | +} |
442 | + |
443 | +void mfd::EventSender::update_buffer(graphics::Buffer& buffer) |
444 | +{ |
445 | + mp::EventSequence seq; |
446 | + auto request = seq.mutable_buffer_request(); |
447 | + request->set_operation(mir::protobuf::BufferOperation::update); |
448 | + send_buffer(seq, buffer, mg::BufferIpcMsgType::update_msg); |
449 | +} |
450 | + |
451 | void mfd::EventSender::send_buffer(frontend::BufferStreamId id, graphics::Buffer& buffer, mg::BufferIpcMsgType type) |
452 | { |
453 | mp::EventSequence seq; |
454 | auto request = seq.mutable_buffer_request(); |
455 | - request->mutable_id()->set_value(id.as_value()); |
456 | + request->mutable_id()->set_value(id.as_value()); |
457 | + send_buffer(seq, buffer, type); |
458 | +} |
459 | + |
460 | +void mfd::EventSender::send_buffer(mp::EventSequence& seq, graphics::Buffer& buffer, mg::BufferIpcMsgType type) |
461 | +{ |
462 | + auto request = seq.mutable_buffer_request(); |
463 | request->mutable_buffer()->set_buffer_id(buffer.id().as_value()); |
464 | |
465 | mfd::ProtobufBufferPacker request_msg{const_cast<mir::protobuf::Buffer*>(request->mutable_buffer())}; |
466 | |
467 | === modified file 'src/server/frontend/event_sender.h' |
468 | --- src/server/frontend/event_sender.h 2016-01-29 08:18:22 +0000 |
469 | +++ src/server/frontend/event_sender.h 2016-04-18 17:46:27 +0000 |
470 | @@ -49,9 +49,13 @@ |
471 | void handle_input_device_change(std::vector<std::shared_ptr<mir::input::Device>> const& devices) override; |
472 | void send_ping(int32_t serial) override; |
473 | void send_buffer(frontend::BufferStreamId id, graphics::Buffer& buffer, graphics::BufferIpcMsgType) override; |
474 | + void add_buffer(graphics::Buffer&) override; |
475 | + void remove_buffer(graphics::Buffer&) override; |
476 | + void update_buffer(graphics::Buffer&) override; |
477 | |
478 | private: |
479 | void send_event_sequence(protobuf::EventSequence&, FdSets const&); |
480 | + void send_buffer(protobuf::EventSequence&, graphics::Buffer&, graphics::BufferIpcMsgType); |
481 | |
482 | std::shared_ptr<MessageSender> const sender; |
483 | std::shared_ptr<graphics::PlatformIpcOperations> const buffer_packer; |
484 | |
485 | === modified file 'src/server/scene/global_event_sender.cpp' |
486 | --- src/server/scene/global_event_sender.cpp 2016-01-29 08:18:22 +0000 |
487 | +++ src/server/scene/global_event_sender.cpp 2016-04-18 17:46:27 +0000 |
488 | @@ -63,3 +63,15 @@ |
489 | void ms::GlobalEventSender::send_buffer(mir::frontend::BufferStreamId, mg::Buffer&, mg::BufferIpcMsgType) |
490 | { |
491 | } |
492 | + |
493 | +void ms::GlobalEventSender::add_buffer(graphics::Buffer&) |
494 | +{ |
495 | +} |
496 | + |
497 | +void ms::GlobalEventSender::remove_buffer(graphics::Buffer&) |
498 | +{ |
499 | +} |
500 | + |
501 | +void ms::GlobalEventSender::update_buffer(graphics::Buffer&) |
502 | +{ |
503 | +} |
504 | |
505 | === modified file 'src/server/scene/global_event_sender.h' |
506 | --- src/server/scene/global_event_sender.h 2016-01-29 08:18:22 +0000 |
507 | +++ src/server/scene/global_event_sender.h 2016-04-18 17:46:27 +0000 |
508 | @@ -39,6 +39,9 @@ |
509 | void handle_input_device_change(std::vector<std::shared_ptr<mir::input::Device>> const& devices) override; |
510 | void send_ping(int32_t serial) override; |
511 | void send_buffer(frontend::BufferStreamId id, graphics::Buffer& buffer, graphics::BufferIpcMsgType) override; |
512 | + void add_buffer(graphics::Buffer&) override; |
513 | + void remove_buffer(graphics::Buffer&) override; |
514 | + void update_buffer(graphics::Buffer&) override; |
515 | |
516 | private: |
517 | std::shared_ptr<SessionContainer> const sessions; |
518 | |
519 | === modified file 'tests/include/mir/test/doubles/mock_event_sink.h' |
520 | --- tests/include/mir/test/doubles/mock_event_sink.h 2016-01-29 08:18:22 +0000 |
521 | +++ tests/include/mir/test/doubles/mock_event_sink.h 2016-04-18 17:46:27 +0000 |
522 | @@ -39,6 +39,10 @@ |
523 | MOCK_METHOD1(handle_display_config_change, void(graphics::DisplayConfiguration const&)); |
524 | MOCK_METHOD1(send_ping, void(int32_t)); |
525 | MOCK_METHOD3(send_buffer, void(frontend::BufferStreamId, graphics::Buffer&, graphics::BufferIpcMsgType)); |
526 | + MOCK_METHOD1(add_buffer, void(graphics::Buffer&)); |
527 | + MOCK_METHOD1(remove_buffer, void(graphics::Buffer&)); |
528 | + MOCK_METHOD1(update_buffer, void(graphics::Buffer&)); |
529 | + |
530 | MOCK_METHOD1(handle_input_device_change, void(std::vector<std::shared_ptr<input::Device>> const&)); |
531 | }; |
532 | } |
533 | |
534 | === modified file 'tests/include/mir/test/doubles/null_event_sink.h' |
535 | --- tests/include/mir/test/doubles/null_event_sink.h 2016-01-29 08:18:22 +0000 |
536 | +++ tests/include/mir/test/doubles/null_event_sink.h 2016-04-18 17:46:27 +0000 |
537 | @@ -41,7 +41,10 @@ |
538 | void handle_display_config_change(graphics::DisplayConfiguration const&) override {} |
539 | void send_ping(int32_t) override {} |
540 | void send_buffer(frontend::BufferStreamId, graphics::Buffer&, graphics::BufferIpcMsgType) override {} |
541 | - void handle_input_device_change(std::vector<std::shared_ptr<mir::input::Device>> const&) override {}; |
542 | + void handle_input_device_change(std::vector<std::shared_ptr<mir::input::Device>> const&) override {} |
543 | + void add_buffer(graphics::Buffer&) override {} |
544 | + void remove_buffer(graphics::Buffer&) override {} |
545 | + void update_buffer(graphics::Buffer&) override {} |
546 | }; |
547 | |
548 | std::unique_ptr<frontend::EventSink> null_sink_factory(std::shared_ptr<frontend::MessageSender> const&); |
549 | |
550 | === modified file 'tests/integration-tests/test_buffer_scheduling.cpp' |
551 | --- tests/integration-tests/test_buffer_scheduling.cpp 2016-04-06 08:44:01 +0000 |
552 | +++ tests/integration-tests/test_buffer_scheduling.cpp 2016-04-18 17:46:27 +0000 |
553 | @@ -22,6 +22,8 @@ |
554 | #include "src/client/buffer_vault.h" |
555 | #include "src/client/buffer_factory.h" |
556 | #include "src/client/client_buffer_depository.h" |
557 | +#include "src/client/buffer_factory.h" |
558 | +#include "src/client/protobuf_to_native_buffer.h" |
559 | #include "src/client/connection_surface_map.h" |
560 | #include "src/server/compositor/buffer_queue.h" |
561 | #include "src/server/compositor/stream.h" |
562 | @@ -222,7 +224,7 @@ |
563 | server_bound_fn = fn; |
564 | } |
565 | |
566 | - void on_client_bound_transfer(std::function<void(mp::Buffer&)> fn) |
567 | + void on_client_bound_transfer(std::function<void(mp::BufferRequest&)> fn) |
568 | { |
569 | client_bound_fn = fn; |
570 | for(auto& b : buffers) |
571 | @@ -257,12 +259,12 @@ |
572 | return last_submit; |
573 | } |
574 | |
575 | - void client_bound_transfer(mp::Buffer& buffer) |
576 | + void client_bound_transfer(mp::BufferRequest& request) |
577 | { |
578 | if (client_bound_fn) |
579 | - client_bound_fn(buffer); |
580 | + client_bound_fn(request); |
581 | else |
582 | - buffers.push_back(buffer); |
583 | + buffers.push_back(request); |
584 | } |
585 | |
586 | void allocate(geom::Size sz) |
587 | @@ -273,10 +275,10 @@ |
588 | |
589 | std::function<void(geom::Size)> allocate_fn; |
590 | std::function<void(geom::Size)> resize_fn; |
591 | - std::function<void(mp::Buffer&)> client_bound_fn; |
592 | + std::function<void(mp::BufferRequest&)> client_bound_fn; |
593 | std::function<void(mp::Buffer&)> server_bound_fn; |
594 | |
595 | - std::vector<mp::Buffer> buffers; |
596 | + std::vector<mp::BufferRequest> buffers; |
597 | int last_submit{0}; |
598 | }; |
599 | |
600 | @@ -287,13 +289,45 @@ |
601 | { |
602 | } |
603 | |
604 | - void send_buffer(mf::BufferStreamId, mg::Buffer& buffer, mg::BufferIpcMsgType) |
605 | - { |
606 | - mp::Buffer protobuffer; |
607 | - protobuffer.set_buffer_id(buffer.id().as_value()); |
608 | - protobuffer.set_width(buffer.size().width.as_int()); |
609 | - protobuffer.set_height(buffer.size().height.as_int()); |
610 | - ipc->client_bound_transfer(protobuffer); |
611 | + void send_buffer(mf::BufferStreamId id, mg::Buffer& buffer, mg::BufferIpcMsgType) |
612 | + { |
613 | + mp::BufferRequest request; |
614 | + auto protobuffer = request.mutable_buffer(); |
615 | + request.mutable_id()->set_value(id.as_value()); |
616 | + protobuffer->set_buffer_id(buffer.id().as_value()); |
617 | + protobuffer->set_width(buffer.size().width.as_int()); |
618 | + protobuffer->set_height(buffer.size().height.as_int()); |
619 | + ipc->client_bound_transfer(request); |
620 | + } |
621 | + void add_buffer(mg::Buffer& buffer) |
622 | + { |
623 | + mp::BufferRequest request; |
624 | + auto protobuffer = request.mutable_buffer(); |
625 | + request.set_operation(mp::BufferOperation::add); |
626 | + protobuffer->set_buffer_id(buffer.id().as_value()); |
627 | + protobuffer->set_width(buffer.size().width.as_int()); |
628 | + protobuffer->set_height(buffer.size().height.as_int()); |
629 | + ipc->client_bound_transfer(request); |
630 | + } |
631 | + void remove_buffer(mg::Buffer& buffer) |
632 | + { |
633 | + mp::BufferRequest request; |
634 | + auto protobuffer = request.mutable_buffer(); |
635 | + request.set_operation(mp::BufferOperation::remove); |
636 | + protobuffer->set_buffer_id(buffer.id().as_value()); |
637 | + protobuffer->set_width(buffer.size().width.as_int()); |
638 | + protobuffer->set_height(buffer.size().height.as_int()); |
639 | + ipc->client_bound_transfer(request); |
640 | + } |
641 | + void update_buffer(mg::Buffer& buffer) |
642 | + { |
643 | + mp::BufferRequest request; |
644 | + auto protobuffer = request.mutable_buffer(); |
645 | + request.set_operation(mp::BufferOperation::update); |
646 | + protobuffer->set_buffer_id(buffer.id().as_value()); |
647 | + protobuffer->set_width(buffer.size().width.as_int()); |
648 | + protobuffer->set_height(buffer.size().height.as_int()); |
649 | + ipc->client_bound_transfer(request); |
650 | } |
651 | void handle_event(MirEvent const&) {} |
652 | void handle_lifecycle_event(MirLifecycleState) {} |
653 | @@ -371,16 +405,43 @@ |
654 | ScheduledProducer(std::shared_ptr<StubIpcSystem> const& ipc_stub, int nbuffers) : |
655 | ipc(ipc_stub), |
656 | map(std::make_shared<mcl::ConnectionSurfaceMap>()), |
657 | + factory(std::make_shared<mcl::BufferFactory>()), |
658 | vault( |
659 | - std::make_shared<mtd::StubClientBufferFactory>(), |
660 | - std::make_shared<mcl::BufferFactory>(), |
661 | - std::make_shared<ServerRequests>(ipc), |
662 | - map, |
663 | + std::make_shared<mtd::StubClientBufferFactory>(), factory, |
664 | + std::make_shared<ServerRequests>(ipc), map, |
665 | geom::Size(100,100), mir_pixel_format_abgr_8888, 0, nbuffers) |
666 | { |
667 | - ipc->on_client_bound_transfer([this](mp::Buffer& buffer){ |
668 | + ipc->on_client_bound_transfer([this](mp::BufferRequest& request){ |
669 | + |
670 | + if (request.has_id()) |
671 | + { |
672 | + auto& ipc_buffer = request.buffer(); |
673 | + auto buffer = map->buffer(ipc_buffer.buffer_id()); |
674 | + if (!buffer) |
675 | + { |
676 | + buffer = factory->generate_buffer(ipc_buffer); |
677 | + map->insert(ipc_buffer.buffer_id(), buffer); |
678 | + buffer->received(); |
679 | + } |
680 | + else |
681 | + { |
682 | + buffer->received(*mcl::protobuf_to_native_buffer(ipc_buffer)); |
683 | + } |
684 | + } |
685 | + else if (request.has_operation() && request.operation() == mp::BufferOperation::add) |
686 | + { |
687 | + auto& ipc_buffer = request.buffer(); |
688 | + std::shared_ptr<mcl::Buffer> buffer = factory->generate_buffer(ipc_buffer); |
689 | + map->insert(request.buffer().buffer_id(), buffer); |
690 | + buffer->received(); |
691 | + } |
692 | + else if (request.has_operation() && request.operation() == mp::BufferOperation::update) |
693 | + { |
694 | + auto buffer = map->buffer(request.buffer().buffer_id()); |
695 | + buffer->received(*mcl::protobuf_to_native_buffer(request.buffer())); |
696 | + } |
697 | available++; |
698 | - vault.wire_transfer_inbound(buffer); |
699 | + |
700 | }); |
701 | ipc->on_resize_event([this](geom::Size sz) |
702 | { |
703 | @@ -434,6 +495,7 @@ |
704 | std::vector<BufferEntry> entries; |
705 | std::shared_ptr<StubIpcSystem> ipc; |
706 | std::shared_ptr<mcl::SurfaceMap> const map; |
707 | + std::shared_ptr<mcl::BufferFactory> factory; |
708 | mcl::BufferVault vault; |
709 | int max, cur; |
710 | int available{0}; |
711 | |
712 | === modified file 'tests/mir_test_doubles/mock_event_sink_factory.cpp' |
713 | --- tests/mir_test_doubles/mock_event_sink_factory.cpp 2016-01-29 08:18:22 +0000 |
714 | +++ tests/mir_test_doubles/mock_event_sink_factory.cpp 2016-04-18 17:46:27 +0000 |
715 | @@ -40,6 +40,9 @@ |
716 | void send_ping(int32_t serial) override; |
717 | void send_buffer(mf::BufferStreamId id, mg::Buffer& buf, mg::BufferIpcMsgType type) override; |
718 | void handle_input_device_change(std::vector<std::shared_ptr<mir::input::Device>> const& devices) override; |
719 | + void add_buffer(mir::graphics::Buffer&) override; |
720 | + void remove_buffer(mir::graphics::Buffer&) override; |
721 | + void update_buffer(mir::graphics::Buffer&) override; |
722 | |
723 | private: |
724 | std::shared_ptr<mf::EventSink> underlying_sink; |
725 | @@ -90,6 +93,21 @@ |
726 | underlying_sink->send_buffer(id, buf, type); |
727 | } |
728 | |
729 | +void GloballyUniqueMockEventSink::add_buffer(mir::graphics::Buffer& buffer) |
730 | +{ |
731 | + underlying_sink->add_buffer(buffer); |
732 | +} |
733 | + |
734 | +void GloballyUniqueMockEventSink::remove_buffer(mir::graphics::Buffer& buffer) |
735 | +{ |
736 | + underlying_sink->remove_buffer(buffer); |
737 | +} |
738 | + |
739 | +void GloballyUniqueMockEventSink::update_buffer(mir::graphics::Buffer& buffer) |
740 | +{ |
741 | + underlying_sink->update_buffer(buffer); |
742 | +} |
743 | + |
744 | mtd::MockEventSinkFactory::MockEventSinkFactory() |
745 | : underlying_sink{std::make_shared<testing::NiceMock<mtd::MockEventSink>>()} |
746 | { |
747 | |
748 | === modified file 'tests/unit-tests/client/test_buffer_vault.cpp' |
749 | --- tests/unit-tests/client/test_buffer_vault.cpp 2016-04-04 03:30:04 +0000 |
750 | +++ tests/unit-tests/client/test_buffer_vault.cpp 2016-04-18 17:46:27 +0000 |
751 | @@ -71,6 +71,10 @@ |
752 | MOCK_METHOD0(disconnected, void()); |
753 | }; |
754 | |
755 | +void ignore(MirPresentationChain*, MirBuffer*, void*) |
756 | +{ |
757 | +} |
758 | + |
759 | struct BufferVault : public testing::Test |
760 | { |
761 | BufferVault() : |
762 | @@ -82,10 +86,43 @@ |
763 | package2.set_height(size.height.as_int()); |
764 | package3.set_width(size.width.as_int()); |
765 | package3.set_height(size.height.as_int()); |
766 | + package4.set_width(new_size.width.as_int()); |
767 | + package4.set_height(new_size.height.as_int()); |
768 | |
769 | package.set_buffer_id(1); |
770 | package2.set_buffer_id(2); |
771 | package3.set_buffer_id(3); |
772 | + package4.set_buffer_id(4); |
773 | + |
774 | + auto buffer1 = std::make_shared<NiceMock<mtd::MockClientBuffer>>(); |
775 | + ON_CALL(*buffer1, size()) |
776 | + .WillByDefault(Return(size)); |
777 | + auto buffer2 = std::make_shared<NiceMock<mtd::MockClientBuffer>>(); |
778 | + ON_CALL(*buffer2, size()) |
779 | + .WillByDefault(Return(size)); |
780 | + auto buffer3 = std::make_shared<NiceMock<mtd::MockClientBuffer>>(); |
781 | + ON_CALL(*buffer3, size()) |
782 | + .WillByDefault(Return(size)); |
783 | + auto buffer4 = std::make_shared<NiceMock<mtd::MockClientBuffer>>(); |
784 | + ON_CALL(*buffer4, size()) |
785 | + .WillByDefault(Return(new_size)); |
786 | + |
787 | + auto b1 = std::make_shared<mcl::Buffer>( |
788 | + ignore, nullptr, package.buffer_id(), buffer1, nullptr, mir_buffer_usage_software); |
789 | + auto b2 = std::make_shared<mcl::Buffer>( |
790 | + ignore, nullptr, package2.buffer_id(), buffer2, nullptr, mir_buffer_usage_software); |
791 | + auto b3 = std::make_shared<mcl::Buffer>( |
792 | + ignore, nullptr, package3.buffer_id(), buffer3, nullptr, mir_buffer_usage_software); |
793 | + auto b4 = std::make_shared<mcl::Buffer>( |
794 | + ignore, nullptr, package4.buffer_id(), buffer4, nullptr, mir_buffer_usage_software); |
795 | + surface_map->insert(package.buffer_id(), b1); |
796 | + surface_map->insert(package2.buffer_id(), b2); |
797 | + surface_map->insert(package3.buffer_id(), b3); |
798 | + surface_map->insert(package4.buffer_id(), b4); |
799 | + b1->received(); |
800 | + b2->received(); |
801 | + b3->received(); |
802 | + b4->received(); |
803 | } |
804 | |
805 | std::unique_ptr<mcl::BufferVault> make_vault() |
806 | @@ -100,6 +137,8 @@ |
807 | |
808 | unsigned int initial_nbuffers {3}; |
809 | geom::Size size{271, 314}; |
810 | + float scale = 2.0f; |
811 | + geom::Size new_size{ size * scale }; |
812 | MirPixelFormat format{mir_pixel_format_abgr_8888}; |
813 | int usage{0}; |
814 | mg::BufferProperties initial_properties{ |
815 | @@ -111,15 +150,16 @@ |
816 | mp::Buffer package; |
817 | mp::Buffer package2; |
818 | mp::Buffer package3; |
819 | + mp::Buffer package4; |
820 | }; |
821 | |
822 | struct StartedBufferVault : BufferVault |
823 | { |
824 | StartedBufferVault() |
825 | { |
826 | - vault.wire_transfer_inbound(package); |
827 | - vault.wire_transfer_inbound(package2); |
828 | - vault.wire_transfer_inbound(package3); |
829 | + vault.wire_transfer_inbound(package.buffer_id()); |
830 | + vault.wire_transfer_inbound(package2.buffer_id()); |
831 | + vault.wire_transfer_inbound(package3.buffer_id()); |
832 | } |
833 | mcl::BufferVault vault{ |
834 | mt::fake_shared(mock_platform_factory), mt::fake_shared(buffer_factory), |
835 | @@ -127,9 +167,6 @@ |
836 | size, format, usage, initial_nbuffers}; |
837 | }; |
838 | |
839 | -void ignore(MirPresentationChain*, MirBuffer*, void*) |
840 | -{ |
841 | -} |
842 | } |
843 | |
844 | TEST_F(BufferVault, creates_all_buffers_on_start) |
845 | @@ -144,32 +181,9 @@ |
846 | EXPECT_CALL(mock_requests, free_buffer(package.buffer_id())); |
847 | EXPECT_CALL(mock_requests, free_buffer(package2.buffer_id())); |
848 | auto vault = make_vault(); |
849 | - vault->wire_transfer_inbound(package); |
850 | - vault->wire_transfer_inbound(package2); |
851 | -} |
852 | - |
853 | -TEST_F(BufferVault, creates_buffer_on_first_insertion) |
854 | -{ |
855 | - EXPECT_CALL(mock_platform_factory, create_buffer(_,initial_properties.size,initial_properties.format)); |
856 | - auto vault = make_vault(); |
857 | - vault->wire_transfer_inbound(package); |
858 | -} |
859 | - |
860 | -TEST_F(BufferVault, updates_buffer_on_subsequent_insertions) |
861 | -{ |
862 | - auto mock_buffer = std::make_shared<NiceMock<mtd::MockClientBuffer>>(); |
863 | - EXPECT_CALL(*mock_buffer, update_from(_)); |
864 | - ON_CALL(*mock_buffer, size()) |
865 | - .WillByDefault(Return(size)); |
866 | - ON_CALL(mock_platform_factory, create_buffer(_,_,_)) |
867 | - .WillByDefault(Return(mock_buffer)); |
868 | - |
869 | - auto vault = make_vault(); |
870 | - vault->wire_transfer_inbound(package); |
871 | - auto b = vault->withdraw().get(); |
872 | - vault->deposit(b); |
873 | - vault->wire_transfer_outbound(b); |
874 | - vault->wire_transfer_inbound(package); |
875 | + |
876 | + vault->wire_transfer_inbound(package.buffer_id()); |
877 | + vault->wire_transfer_inbound(package2.buffer_id()); |
878 | } |
879 | |
880 | TEST_F(BufferVault, withdrawing_and_never_filling_up_will_timeout) |
881 | @@ -230,15 +244,12 @@ |
882 | TEST_F(BufferVault, can_transfer_again_when_we_get_the_buffer) |
883 | { |
884 | auto vault = make_vault(); |
885 | - EXPECT_CALL(mock_platform_factory, create_buffer(_,initial_properties.size,initial_properties.format)) |
886 | - .Times(Exactly(1)); |
887 | - vault->wire_transfer_inbound(package); |
888 | + vault->wire_transfer_inbound(package.buffer_id()); |
889 | auto buffer = vault->withdraw().get(); |
890 | vault->deposit(buffer); |
891 | vault->wire_transfer_outbound(buffer); |
892 | |
893 | - //should just activate, not create the buffer |
894 | - vault->wire_transfer_inbound(package); |
895 | + vault->wire_transfer_inbound(package.buffer_id()); |
896 | auto buffer2 = vault->withdraw().get(); |
897 | EXPECT_THAT(buffer, Eq(buffer2)); |
898 | } |
899 | @@ -256,8 +267,8 @@ |
900 | |
901 | auto f_buffer1 = vault->withdraw(); |
902 | auto f_buffer2 = vault->withdraw(); |
903 | - vault->wire_transfer_inbound(package); |
904 | - vault->wire_transfer_inbound(package2); |
905 | + vault->wire_transfer_inbound(package.buffer_id()); |
906 | + vault->wire_transfer_inbound(package2.buffer_id()); |
907 | |
908 | auto buffer1 = f_buffer1.get(); |
909 | auto buffer2 = f_buffer2.get(); |
910 | @@ -283,9 +294,12 @@ |
911 | EXPECT_CALL(*mock_buffer, increment_age()); |
912 | ON_CALL(mock_platform_factory, create_buffer(_,_,_)) |
913 | .WillByDefault(Return(mock_buffer)); |
914 | + auto b1 = std::make_shared<mcl::Buffer>( |
915 | + ignore, nullptr, package.buffer_id(), mock_buffer, nullptr, mir_buffer_usage_software); |
916 | + surface_map->insert(package.buffer_id(), b1); |
917 | |
918 | auto vault = make_vault(); |
919 | - vault->wire_transfer_inbound(package); |
920 | + vault->wire_transfer_inbound(package.buffer_id()); |
921 | vault->deposit(vault->withdraw().get()); |
922 | } |
923 | |
924 | @@ -297,9 +311,13 @@ |
925 | EXPECT_CALL(*mock_buffer, mark_as_submitted()); |
926 | ON_CALL(mock_platform_factory, create_buffer(_,_,_)) |
927 | .WillByDefault(Return(mock_buffer)); |
928 | + auto b1 = std::make_shared<mcl::Buffer>( |
929 | + ignore, nullptr, package.buffer_id(), mock_buffer, nullptr, mir_buffer_usage_software); |
930 | + surface_map->insert(package.buffer_id(), b1); |
931 | + b1->received(); |
932 | |
933 | auto vault = make_vault(); |
934 | - vault->wire_transfer_inbound(package); |
935 | + vault->wire_transfer_inbound(package.buffer_id()); |
936 | |
937 | auto buffer = vault->withdraw().get(); |
938 | vault->deposit(buffer); |
939 | @@ -308,53 +326,36 @@ |
940 | |
941 | TEST_F(StartedBufferVault, reallocates_incoming_buffers_of_incorrect_size_with_immediate_response) |
942 | { |
943 | - mp::Buffer package4; |
944 | - geom::Size new_size{80, 100}; |
945 | EXPECT_CALL(mock_requests, free_buffer(package.buffer_id())); |
946 | EXPECT_CALL(mock_requests, allocate_buffer(new_size,_,_)) |
947 | .WillOnce(Invoke( |
948 | - [&, this](geom::Size sz, MirPixelFormat, int) |
949 | + [&, this](geom::Size, MirPixelFormat, int) |
950 | { |
951 | - package4.set_width(sz.width.as_int()); |
952 | - package4.set_height(sz.height.as_int()); |
953 | - package4.set_buffer_id(4); |
954 | - vault.wire_transfer_inbound(package4); |
955 | + vault.wire_transfer_inbound(package4.buffer_id()); |
956 | })); |
957 | |
958 | vault.set_size(new_size); |
959 | - vault.wire_transfer_inbound(package); |
960 | + vault.wire_transfer_inbound(package.buffer_id()); |
961 | Mock::VerifyAndClearExpectations(&mock_requests); |
962 | } |
963 | |
964 | TEST_F(StartedBufferVault, reallocates_incoming_buffers_of_incorrect_size_with_delayed_response) |
965 | { |
966 | - geom::Size new_size{80, 100}; |
967 | - mp::Buffer package4; |
968 | - package4.set_width(new_size.width.as_int()); |
969 | - package4.set_height(new_size.height.as_int()); |
970 | - package4.set_buffer_id(4); |
971 | - |
972 | EXPECT_CALL(mock_requests, free_buffer(package.buffer_id())); |
973 | EXPECT_CALL(mock_requests, allocate_buffer(new_size,_,_)); |
974 | |
975 | vault.set_size(new_size); |
976 | - vault.wire_transfer_inbound(package); |
977 | - vault.wire_transfer_inbound(package4); |
978 | + vault.wire_transfer_inbound(package.buffer_id()); |
979 | + vault.wire_transfer_inbound(package4.buffer_id()); |
980 | EXPECT_THAT(vault.withdraw().get()->size(), Eq(new_size)); |
981 | Mock::VerifyAndClearExpectations(&mock_requests); |
982 | } |
983 | |
984 | TEST_F(StartedBufferVault, withdraw_gives_only_newly_sized_buffers_after_resize) |
985 | { |
986 | - mp::Buffer package4; |
987 | - geom::Size new_size{80, 100}; |
988 | - package4.set_width(new_size.width.as_int()); |
989 | - package4.set_height(new_size.height.as_int()); |
990 | - package4.set_buffer_id(4); |
991 | - |
992 | vault.set_size(new_size); |
993 | - vault.wire_transfer_inbound(package); |
994 | - vault.wire_transfer_inbound(package4); |
995 | + vault.wire_transfer_inbound(package.buffer_id()); |
996 | + vault.wire_transfer_inbound(package4.buffer_id()); |
997 | |
998 | EXPECT_THAT(vault.withdraw().get()->size(), Eq(new_size)); |
999 | Mock::VerifyAndClearExpectations(&mock_requests); |
1000 | @@ -376,16 +377,9 @@ |
1001 | |
1002 | TEST_F(StartedBufferVault, scaling_resizes_buffers_right_away) |
1003 | { |
1004 | - mp::Buffer package4; |
1005 | - float scale = 2.0f; |
1006 | - geom::Size new_size = size * scale; |
1007 | - package4.set_width(new_size.width.as_int()); |
1008 | - package4.set_height(new_size.height.as_int()); |
1009 | - package4.set_buffer_id(4); |
1010 | - |
1011 | EXPECT_CALL(mock_requests, allocate_buffer(_,_,_)) |
1012 | .WillOnce(InvokeWithoutArgs( |
1013 | - [&]{vault.wire_transfer_inbound(package4);})); |
1014 | + [&]{ vault.wire_transfer_inbound(package4.buffer_id());})); |
1015 | auto b1 = vault.withdraw().get(); |
1016 | auto b2 = vault.withdraw().get(); |
1017 | vault.set_scale(scale); |
1018 | @@ -412,7 +406,7 @@ |
1019 | .WillOnce(Throw(std::runtime_error(""))); |
1020 | EXPECT_NO_THROW({ |
1021 | auto vault = make_vault(); |
1022 | - vault->wire_transfer_inbound(package); |
1023 | + vault->wire_transfer_inbound(package.buffer_id()); |
1024 | }); |
1025 | } |
1026 | |
1027 | @@ -426,26 +420,33 @@ |
1028 | TEST_F(StartedBufferVault, buffer_count_remains_the_same_after_scaling) |
1029 | { |
1030 | std::array<mp::Buffer, 3> buffers; |
1031 | - float scale = 2.0f; |
1032 | - geom::Size new_size = size * scale; |
1033 | |
1034 | int i = initial_nbuffers; |
1035 | for (auto& buffer : buffers) |
1036 | { |
1037 | + i++; |
1038 | buffer.set_width(new_size.width.as_int()); |
1039 | buffer.set_height(new_size.height.as_int()); |
1040 | - buffer.set_buffer_id(i++); |
1041 | + buffer.set_buffer_id(i); |
1042 | + |
1043 | + auto mcb = std::make_shared<NiceMock<mtd::MockClientBuffer>>(); |
1044 | + ON_CALL(*mcb, size()) |
1045 | + .WillByDefault(Return(new_size)); |
1046 | + auto b = std::make_shared<mcl::Buffer>( |
1047 | + ignore, nullptr, i, mcb, nullptr, mir_buffer_usage_software); |
1048 | + surface_map->insert(i, b); |
1049 | + b->received(); |
1050 | } |
1051 | |
1052 | //make sure we alloc 3 new ones and free 3 old ones |
1053 | EXPECT_CALL(mock_requests, allocate_buffer(_,_,_)) |
1054 | .Times(initial_nbuffers) |
1055 | .WillOnce(InvokeWithoutArgs( |
1056 | - [&]{vault.wire_transfer_inbound(buffers[0]);})) |
1057 | - .WillOnce(InvokeWithoutArgs( |
1058 | - [&]{vault.wire_transfer_inbound(buffers[1]);})) |
1059 | - .WillOnce(InvokeWithoutArgs( |
1060 | - [&]{vault.wire_transfer_inbound(buffers[2]);})); |
1061 | + [&]{vault.wire_transfer_inbound(buffers[0].buffer_id());})) |
1062 | + .WillOnce(InvokeWithoutArgs( |
1063 | + [&]{vault.wire_transfer_inbound(buffers[1].buffer_id());})) |
1064 | + .WillOnce(InvokeWithoutArgs( |
1065 | + [&]{vault.wire_transfer_inbound(buffers[2].buffer_id());})); |
1066 | EXPECT_CALL(mock_requests, free_buffer(_)) |
1067 | .Times(initial_nbuffers); |
1068 | |
1069 | @@ -453,15 +454,16 @@ |
1070 | vault.set_scale(scale); |
1071 | vault.deposit(buffer); |
1072 | vault.wire_transfer_outbound(buffer); |
1073 | - vault.wire_transfer_inbound(package); |
1074 | + vault.wire_transfer_inbound(package.buffer_id()); |
1075 | |
1076 | for(auto i = 0; i < 100; i++) |
1077 | { |
1078 | auto b = vault.withdraw().get(); |
1079 | EXPECT_THAT(b->size(), Eq(new_size)); |
1080 | vault.deposit(b); |
1081 | + b->received(); |
1082 | vault.wire_transfer_outbound(b); |
1083 | - vault.wire_transfer_inbound(buffers[(i+1)%3]); |
1084 | + vault.wire_transfer_inbound(buffers[(i+1)%3].buffer_id()); |
1085 | } |
1086 | Mock::VerifyAndClearExpectations(&mock_requests); |
1087 | } |
1088 | @@ -475,9 +477,9 @@ |
1089 | .Times(initial_nbuffers); |
1090 | EXPECT_CALL(mock_requests, allocate_buffer(_,_,_)) |
1091 | .Times(initial_nbuffers); |
1092 | - vault->wire_transfer_inbound(package); |
1093 | - vault->wire_transfer_inbound(package2); |
1094 | - vault->wire_transfer_inbound(package3); |
1095 | + vault->wire_transfer_inbound(package.buffer_id()); |
1096 | + vault->wire_transfer_inbound(package2.buffer_id()); |
1097 | + vault->wire_transfer_inbound(package3.buffer_id()); |
1098 | |
1099 | } |
1100 | |
1101 | @@ -516,6 +518,13 @@ |
1102 | requested_buffer.set_width(size.width.as_int()); |
1103 | requested_buffer.set_height(size.height.as_int()); |
1104 | requested_buffer.set_buffer_id(4); |
1105 | + auto extra_native_buffer = std::make_shared<NiceMock<mtd::MockClientBuffer>>(); |
1106 | + ON_CALL(*extra_native_buffer, size()) |
1107 | + .WillByDefault(Return(size)); |
1108 | + auto extra_buffer = std::make_shared<mcl::Buffer>( |
1109 | + ignore, nullptr, package4.buffer_id(), extra_native_buffer, nullptr, mir_buffer_usage_software); |
1110 | + surface_map->insert(package4.buffer_id(), extra_buffer); |
1111 | + extra_buffer->received(); |
1112 | |
1113 | EXPECT_CALL(mock_requests, allocate_buffer(_,_,_)) |
1114 | .Times(1); |
1115 | @@ -523,7 +532,7 @@ |
1116 | .Times(1); |
1117 | |
1118 | vault.increase_buffer_count(); |
1119 | - vault.wire_transfer_inbound(requested_buffer); |
1120 | + vault.wire_transfer_inbound(requested_buffer.buffer_id()); |
1121 | auto b = vault.withdraw().get(); |
1122 | vault.deposit(b); |
1123 | vault.wire_transfer_outbound(b); |
1124 | @@ -541,7 +550,7 @@ |
1125 | vault.wire_transfer_outbound(b); |
1126 | |
1127 | vault.decrease_buffer_count(); |
1128 | - vault.wire_transfer_inbound(package); |
1129 | - vault.wire_transfer_inbound(package2); |
1130 | + vault.wire_transfer_inbound(package.buffer_id()); |
1131 | + vault.wire_transfer_inbound(package2.buffer_id()); |
1132 | Mock::VerifyAndClearExpectations(&mock_requests); |
1133 | } |
1134 | |
1135 | === modified file 'tests/unit-tests/client/test_client_buffer_stream.cpp' |
1136 | --- tests/unit-tests/client/test_client_buffer_stream.cpp 2016-04-18 17:46:26 +0000 |
1137 | +++ tests/unit-tests/client/test_client_buffer_stream.cpp 2016-04-18 17:46:27 +0000 |
1138 | @@ -186,7 +186,24 @@ |
1139 | |
1140 | void async_buffer_arrives(mcl::ClientBufferStream& bs, mp::Buffer& buffer) |
1141 | { |
1142 | - bs.buffer_available(buffer); |
1143 | + if (legacy_exchange_buffer) |
1144 | + { |
1145 | + bs.buffer_available(buffer); |
1146 | + } |
1147 | + else |
1148 | + { |
1149 | + try |
1150 | + { |
1151 | + map->buffer(buffer.buffer_id())->received(*mcl::protobuf_to_native_buffer(buffer)); |
1152 | + } |
1153 | + catch (std::runtime_error& e) |
1154 | + { |
1155 | + auto bb = factory->generate_buffer(buffer); |
1156 | + auto braw = bb.get(); |
1157 | + map->insert(buffer.buffer_id(), std::move(bb)); |
1158 | + braw->received(); |
1159 | + } |
1160 | + } |
1161 | } |
1162 | |
1163 | std::shared_ptr<mcl::ConnectionSurfaceMap> map{std::make_shared<mcl::ConnectionSurfaceMap>()}; |
1164 | @@ -524,6 +541,8 @@ |
1165 | { |
1166 | using namespace std::literals::chrono_literals; |
1167 | NiceMock<mtd::MockClientBuffer> mock_client_buffer; |
1168 | + ON_CALL(mock_client_buffer, size()) |
1169 | + .WillByDefault(Return(size)); |
1170 | ON_CALL(mock_factory, create_buffer(BufferPackageMatches(buffer_package),_,_)) |
1171 | .WillByDefault(Return(mt::fake_shared(mock_client_buffer))); |
1172 | ON_CALL(mock_protobuf_server, submit_buffer(_,_,_)) |
1173 | |
1174 | === modified file 'tests/unit-tests/client/test_presentation_chain.cpp' |
1175 | --- tests/unit-tests/client/test_presentation_chain.cpp 2016-03-23 06:39:56 +0000 |
1176 | +++ tests/unit-tests/client/test_presentation_chain.cpp 2016-04-18 17:46:27 +0000 |
1177 | @@ -138,13 +138,6 @@ |
1178 | static_cast<BufferCallbackContext*>(context)->set_buffer(buffer); |
1179 | } |
1180 | |
1181 | -static void counting_buffer_callback(MirPresentationChain*, MirBuffer* buffer, void* context) |
1182 | -{ |
1183 | - BufferCount* c = static_cast<BufferCount*>(context); |
1184 | - c->buffer = buffer; |
1185 | - c->count = c->count + 1; |
1186 | -} |
1187 | - |
1188 | TEST_F(PresentationChain, returns_associated_connection) |
1189 | { |
1190 | mcl::PresentationChain chain( |
1191 | @@ -177,20 +170,18 @@ |
1192 | EXPECT_CALL(mock_server, allocate_buffers(BufferAllocationMatches(mp_alloc),_,_)) |
1193 | .WillOnce(mtd::RunProtobufClosure()); |
1194 | EXPECT_CALL(*factory, create_buffer(_, size, format)); |
1195 | - |
1196 | + |
1197 | + auto mir_buffer_factory = std::make_shared<mcl::BufferFactory>(); |
1198 | mcl::PresentationChain chain( |
1199 | connection, rpc_id, mock_server, |
1200 | - factory, std::make_shared<mcl::BufferFactory>()); |
1201 | + factory, mir_buffer_factory); |
1202 | chain.allocate_buffer(size, format, usage, buffer_callback, &buffer); |
1203 | |
1204 | - EXPECT_FALSE(buffer.buffer_is_set()); |
1205 | - |
1206 | mp::Buffer ipc_buf; |
1207 | ipc_buf.set_width(size.width.as_int()); |
1208 | ipc_buf.set_height(size.height.as_int()); |
1209 | - chain.buffer_available(ipc_buf); |
1210 | - |
1211 | - EXPECT_TRUE(buffer.wait_for_buffer()); |
1212 | + auto mirbuffer = mir_buffer_factory->generate_buffer(ipc_buf); |
1213 | + EXPECT_THAT(mirbuffer, Ne(nullptr)); |
1214 | } |
1215 | |
1216 | TEST_F(PresentationChain, creates_correct_buffer_when_buffers_arrive) |
1217 | @@ -224,25 +215,32 @@ |
1218 | ipc_buf[i].set_height(sizes[i].height.as_int()); |
1219 | } |
1220 | |
1221 | + std::array<std::shared_ptr<mtd::MockClientBuffer>, num_buffers> client_buffers { { |
1222 | + std::make_shared<NiceMock<mtd::MockClientBuffer>>(), |
1223 | + std::make_shared<NiceMock<mtd::MockClientBuffer>>(), |
1224 | + std::make_shared<NiceMock<mtd::MockClientBuffer>>() |
1225 | + } }; |
1226 | + |
1227 | + for(auto i = 0u; i < client_buffers.size(); i++) |
1228 | + { |
1229 | + EXPECT_CALL(*factory, create_buffer(_, sizes[i], _)) |
1230 | + .WillOnce(Return(client_buffers[i])); |
1231 | + } |
1232 | + |
1233 | + auto mir_buffer_factory = std::make_shared<mcl::BufferFactory>(); |
1234 | mcl::PresentationChain chain( |
1235 | connection, rpc_id, mock_server, |
1236 | - std::make_shared<mtd::StubClientBufferFactory>(), |
1237 | - std::make_shared<mcl::BufferFactory>()); |
1238 | + factory, mir_buffer_factory); |
1239 | |
1240 | for (auto i = 0u; i < num_buffers; i++) |
1241 | chain.allocate_buffer(sizes[i], format, usage, buffer_callback, &buffer[i]); |
1242 | |
1243 | - chain.buffer_available(ipc_buf[1]); |
1244 | - EXPECT_FALSE(buffer[0].buffer_is_set()); |
1245 | - EXPECT_TRUE(buffer[1].wait_for_buffer()); |
1246 | - EXPECT_FALSE(buffer[2].buffer_is_set()); |
1247 | - |
1248 | - chain.buffer_available(ipc_buf[2]); |
1249 | - EXPECT_FALSE(buffer[0].buffer_is_set()); |
1250 | - EXPECT_TRUE(buffer[2].wait_for_buffer()); |
1251 | - |
1252 | - chain.buffer_available(ipc_buf[0]); |
1253 | - EXPECT_TRUE(buffer[0].wait_for_buffer()); |
1254 | + auto mirbuffer = mir_buffer_factory->generate_buffer(ipc_buf[1]); |
1255 | + EXPECT_THAT(mirbuffer->client_buffer(), Eq(client_buffers[1])); |
1256 | + mirbuffer = mir_buffer_factory->generate_buffer(ipc_buf[2]); |
1257 | + EXPECT_THAT(mirbuffer->client_buffer(), Eq(client_buffers[2])); |
1258 | + mirbuffer = mir_buffer_factory->generate_buffer(ipc_buf[0]); |
1259 | + EXPECT_THAT(mirbuffer->client_buffer(), Eq(client_buffers[0])); |
1260 | } |
1261 | |
1262 | TEST_F(PresentationChain, frees_buffer_when_asked) |
1263 | @@ -258,18 +256,15 @@ |
1264 | EXPECT_CALL(mock_server, release_buffers(BufferReleaseMatches(release_msg),_,_)) |
1265 | .WillOnce(mtd::RunProtobufClosure()); |
1266 | |
1267 | + auto mir_buffer_factory = std::make_shared<mcl::BufferFactory>(); |
1268 | mcl::PresentationChain chain( |
1269 | connection, rpc_id, mock_server, |
1270 | std::make_shared<mtd::StubClientBufferFactory>(), |
1271 | - std::make_shared<mcl::BufferFactory>()); |
1272 | + mir_buffer_factory); |
1273 | |
1274 | chain.allocate_buffer(size, format, usage, buffer_callback, &buffer); |
1275 | - chain.buffer_available(ipc_buf); |
1276 | - auto b = buffer.wait_for_buffer(); |
1277 | - ASSERT_THAT(b, Ne(nullptr)); |
1278 | - |
1279 | - chain.release_buffer(b); |
1280 | - |
1281 | + chain.release_buffer(reinterpret_cast<MirBuffer*>( |
1282 | + mir_buffer_factory->generate_buffer(ipc_buf).get())); |
1283 | } |
1284 | |
1285 | TEST_F(PresentationChain, submits_buffer_when_asked) |
1286 | @@ -284,44 +279,16 @@ |
1287 | EXPECT_CALL(mock_server, submit_buffer(BufferRequestMatches(request),_,_)) |
1288 | .WillOnce(mtd::RunProtobufClosure()); |
1289 | |
1290 | + auto mir_buffer_factory = std::make_shared<mcl::BufferFactory>(); |
1291 | mcl::PresentationChain chain( |
1292 | connection, rpc_id, mock_server, |
1293 | std::make_shared<mtd::StubClientBufferFactory>(), |
1294 | - std::make_shared<mcl::BufferFactory>()); |
1295 | - chain.allocate_buffer(size, format, usage, buffer_callback, &buffer); |
1296 | - chain.buffer_available(ipc_buf); |
1297 | - auto b = buffer.wait_for_buffer(); |
1298 | - ASSERT_THAT(b, Ne(nullptr)); |
1299 | - |
1300 | - chain.submit_buffer(b); |
1301 | -} |
1302 | - |
1303 | -TEST_F(PresentationChain, updates_buffer) |
1304 | -{ |
1305 | - mtd::MockClientBuffer mock_buffer; |
1306 | - BufferCallbackContext buffer; |
1307 | - mp::BufferRequest request; |
1308 | - request.mutable_id()->set_value(rpc_id); |
1309 | - request.mutable_buffer()->set_buffer_id(buffer_id); |
1310 | - |
1311 | - EXPECT_CALL(mock_server, allocate_buffers(_,_,_)) |
1312 | - .WillOnce(mtd::RunProtobufClosure()); |
1313 | - EXPECT_CALL(mock_server, submit_buffer(BufferRequestMatches(request),_,_)) |
1314 | - .WillOnce(mtd::RunProtobufClosure()); |
1315 | - EXPECT_CALL(mock_buffer, update_from(_)); |
1316 | - EXPECT_CALL(*factory, create_buffer(_,_,_)) |
1317 | - .WillOnce(Return(mir::test::fake_shared(mock_buffer))); |
1318 | - |
1319 | - mcl::PresentationChain chain( |
1320 | - connection, rpc_id, mock_server, factory, |
1321 | - std::make_shared<mcl::BufferFactory>()); |
1322 | - chain.allocate_buffer(size, format, usage, buffer_callback, &buffer); |
1323 | - chain.buffer_available(ipc_buf); |
1324 | - auto b = buffer.wait_for_buffer(); |
1325 | - ASSERT_THAT(b, Ne(nullptr)); |
1326 | - |
1327 | - chain.submit_buffer(b); |
1328 | - chain.buffer_available(ipc_buf); |
1329 | + mir_buffer_factory); |
1330 | + chain.allocate_buffer(size, format, usage, buffer_callback, &buffer); |
1331 | + |
1332 | + auto client_buffer = mir_buffer_factory->generate_buffer(ipc_buf); |
1333 | + client_buffer->received(); |
1334 | + chain.submit_buffer(reinterpret_cast<MirBuffer*>(client_buffer.get())); |
1335 | } |
1336 | |
1337 | TEST_F(PresentationChain, double_submission_throws) |
1338 | @@ -333,43 +300,17 @@ |
1339 | EXPECT_CALL(mock_server, submit_buffer(_,_,_)) |
1340 | .WillOnce(mtd::RunProtobufClosure()); |
1341 | |
1342 | + auto mir_buffer_factory = std::make_shared<mcl::BufferFactory>(); |
1343 | mcl::PresentationChain chain( |
1344 | connection, rpc_id, mock_server, |
1345 | std::make_shared<mtd::StubClientBufferFactory>(), |
1346 | - std::make_shared<mcl::BufferFactory>()); |
1347 | + mir_buffer_factory); |
1348 | + |
1349 | chain.allocate_buffer(size, format, usage, buffer_callback, &buffer); |
1350 | - chain.buffer_available(ipc_buf); |
1351 | - auto b = buffer.wait_for_buffer(); |
1352 | - ASSERT_THAT(b, Ne(nullptr)); |
1353 | - |
1354 | - chain.submit_buffer(b); |
1355 | + auto client_buffer = mir_buffer_factory->generate_buffer(ipc_buf); |
1356 | + client_buffer->received(); |
1357 | + chain.submit_buffer(reinterpret_cast<MirBuffer*>(client_buffer.get())); |
1358 | EXPECT_THROW({ |
1359 | - chain.submit_buffer(b); |
1360 | + chain.submit_buffer(reinterpret_cast<MirBuffer*>(client_buffer.get())); |
1361 | }, std::logic_error); |
1362 | } |
1363 | - |
1364 | -TEST_F(PresentationChain, callback_invoked_when_buffer_returned_from_allocation_and_submission) |
1365 | -{ |
1366 | - BufferCount counter; |
1367 | - |
1368 | - EXPECT_CALL(mock_server, allocate_buffers(_,_,_)) |
1369 | - .WillOnce(mtd::RunProtobufClosure()); |
1370 | - EXPECT_CALL(mock_server, submit_buffer(_,_,_)) |
1371 | - .WillOnce(mtd::RunProtobufClosure()); |
1372 | - |
1373 | - mcl::PresentationChain chain( |
1374 | - connection, rpc_id, mock_server, |
1375 | - std::make_shared<mtd::StubClientBufferFactory>(), |
1376 | - std::make_shared<mcl::BufferFactory>()); |
1377 | - chain.allocate_buffer(size, format, usage, counting_buffer_callback, &counter); |
1378 | - chain.buffer_available(ipc_buf); |
1379 | - std::unique_lock<std::mutex> lk(counter.mut); |
1380 | - EXPECT_TRUE(counter.cv.wait_for(lk, std::chrono::seconds(5), [&] { return counter.buffer; })); |
1381 | - lk.unlock(); |
1382 | - |
1383 | - chain.submit_buffer(counter.buffer); |
1384 | - chain.buffer_available(ipc_buf); |
1385 | - |
1386 | - lk.lock(); |
1387 | - EXPECT_THAT(counter.count, Eq(2)); |
1388 | -} |
1389 | |
1390 | === modified file 'tests/unit-tests/client/test_protobuf_rpc_channel.cpp' |
1391 | --- tests/unit-tests/client/test_protobuf_rpc_channel.cpp 2016-03-23 06:39:56 +0000 |
1392 | +++ tests/unit-tests/client/test_protobuf_rpc_channel.cpp 2016-04-18 17:46:27 +0000 |
1393 | @@ -26,13 +26,16 @@ |
1394 | #include "src/client/ping_handler.h" |
1395 | #include "src/client/buffer_factory.h" |
1396 | |
1397 | +#include "mir/variable_length_array.h" |
1398 | #include "mir_protobuf.pb.h" |
1399 | #include "mir_protobuf_wire.pb.h" |
1400 | #include "mir/input/input_devices.h" |
1401 | |
1402 | #include "mir/test/doubles/null_client_event_sink.h" |
1403 | #include "mir/test/doubles/mock_client_buffer_stream.h" |
1404 | +#include "mir/test/doubles/mock_client_buffer.h" |
1405 | #include "mir/test/fd_utils.h" |
1406 | +#include "mir/test/gmock_fixes.h" |
1407 | |
1408 | #include <list> |
1409 | #include <endian.h> |
1410 | @@ -674,3 +677,138 @@ |
1411 | EXPECT_TRUE(second_response_called); |
1412 | } |
1413 | |
1414 | +struct MockBufferFactory : mcl::AsyncBufferFactory |
1415 | +{ |
1416 | + MOCK_METHOD1(cancel_requests_with_context, void(void*)); |
1417 | + MOCK_METHOD1(generate_buffer, std::unique_ptr<mcl::Buffer>(mir::protobuf::Buffer const&)); |
1418 | + MOCK_METHOD7(expect_buffer, void( |
1419 | + std::shared_ptr<mcl::ClientBufferFactory> const&, |
1420 | + MirPresentationChain*, |
1421 | + mir::geometry::Size, MirPixelFormat, MirBufferUsage, |
1422 | + mir_buffer_callback, void*)); |
1423 | +}; |
1424 | + |
1425 | +namespace |
1426 | +{ |
1427 | +void buffer_cb(MirPresentationChain*, MirBuffer*, void*) |
1428 | +{ |
1429 | +} |
1430 | + |
1431 | +void set_async_buffer_message( |
1432 | + mir::protobuf::EventSequence& seq, |
1433 | + MockStreamTransport& transport) |
1434 | +{ |
1435 | + std::vector<uint8_t> send_buffer(static_cast<size_t>(seq.ByteSize())); |
1436 | + seq.SerializeToArray(send_buffer.data(), send_buffer.size()); |
1437 | + mir::protobuf::wire::Result result; |
1438 | + result.add_events(send_buffer.data(), send_buffer.size()); |
1439 | + send_buffer.resize(result.ByteSize()); |
1440 | + result.SerializeToArray(send_buffer.data(), send_buffer.size()); |
1441 | + |
1442 | + size_t header_size = 2u; |
1443 | + std::vector<uint8_t> header(header_size); |
1444 | + header.data()[0] = static_cast<unsigned char>((result.ByteSize() >> 8) & 0xff); |
1445 | + header.data()[1] = static_cast<unsigned char>((result.ByteSize() >> 0) & 0xff); |
1446 | + transport.add_server_message(header); |
1447 | + transport.add_server_message(send_buffer); |
1448 | +} |
1449 | + |
1450 | +} |
1451 | +TEST_F(MirProtobufRpcChannelTest, creates_buffer_if_not_in_map) |
1452 | +{ |
1453 | + using namespace testing; |
1454 | + int buffer_id(3); |
1455 | + auto stream_map = std::make_shared<MockSurfaceMap>(); |
1456 | + auto mock_buffer_factory = std::make_shared<MockBufferFactory>(); |
1457 | + EXPECT_CALL(*mock_buffer_factory, generate_buffer(_)) |
1458 | + .WillOnce(InvokeWithoutArgs([&]{ |
1459 | + return std::make_unique<mcl::Buffer>( |
1460 | + buffer_cb, nullptr, buffer_id, nullptr, nullptr, mir_buffer_usage_software); |
1461 | + })); |
1462 | + EXPECT_CALL(*stream_map, insert(buffer_id, _)); |
1463 | + |
1464 | + auto transport = std::make_unique<NiceMock<MockStreamTransport>>(); |
1465 | + mir::protobuf::EventSequence seq; |
1466 | + auto request = seq.mutable_buffer_request(); |
1467 | + request->set_operation(mir::protobuf::BufferOperation::add); |
1468 | + request->mutable_buffer()->set_buffer_id(buffer_id); |
1469 | + set_async_buffer_message(seq, *transport); |
1470 | + |
1471 | + mclr::MirProtobufRpcChannel channel{ |
1472 | + std::move(transport), |
1473 | + stream_map, |
1474 | + mock_buffer_factory, |
1475 | + std::make_shared<mcl::DisplayConfiguration>(), |
1476 | + std::make_shared<mir::input::InputDevices>(), |
1477 | + std::make_shared<mclr::NullRpcReport>(), |
1478 | + lifecycle, |
1479 | + std::make_shared<mir::client::PingHandler>(), |
1480 | + std::make_shared<mtd::NullClientEventSink>()}; |
1481 | + |
1482 | + channel.on_data_available(); |
1483 | +} |
1484 | + |
1485 | +TEST_F(MirProtobufRpcChannelTest, reuses_buffer_if_in_map) |
1486 | +{ |
1487 | + using namespace testing; |
1488 | + int buffer_id(3); |
1489 | + auto stream_map = std::make_shared<MockSurfaceMap>(); |
1490 | + auto mock_buffer_factory = std::make_shared<MockBufferFactory>(); |
1491 | + auto mock_client_buffer = std::make_shared<mtd::MockClientBuffer>(); |
1492 | + auto buf = std::make_shared<mcl::Buffer>(buffer_cb, nullptr, buffer_id, mock_client_buffer, nullptr, mir_buffer_usage_software); |
1493 | + EXPECT_CALL(*stream_map, buffer(buffer_id)).Times(1) |
1494 | + .WillOnce(Return(buf)); |
1495 | + EXPECT_CALL(*mock_client_buffer, update_from(_)) |
1496 | + .Times(1); |
1497 | + |
1498 | + auto transport = std::make_unique<NiceMock<MockStreamTransport>>(); |
1499 | + mir::protobuf::EventSequence seq; |
1500 | + auto request = seq.mutable_buffer_request(); |
1501 | + request->set_operation(mir::protobuf::BufferOperation::update); |
1502 | + request->mutable_buffer()->set_buffer_id(buffer_id); |
1503 | + set_async_buffer_message(seq, *transport); |
1504 | + |
1505 | + mclr::MirProtobufRpcChannel channel{ |
1506 | + std::move(transport), |
1507 | + stream_map, |
1508 | + mock_buffer_factory, |
1509 | + std::make_shared<mcl::DisplayConfiguration>(), |
1510 | + std::make_shared<mir::input::InputDevices>(), |
1511 | + std::make_shared<mclr::NullRpcReport>(), |
1512 | + lifecycle, |
1513 | + std::make_shared<mir::client::PingHandler>(), |
1514 | + std::make_shared<mtd::NullClientEventSink>()}; |
1515 | + channel.on_data_available(); |
1516 | +} |
1517 | + |
1518 | +TEST_F(MirProtobufRpcChannelTest, sends_incoming_buffer_to_stream_if_stream_id_present) |
1519 | +{ |
1520 | + using namespace testing; |
1521 | + int buffer_id(3); |
1522 | + int stream_id = 331; |
1523 | + auto stream_map = std::make_shared<MockSurfaceMap>(); |
1524 | + auto mock_buffer_factory = std::make_shared<MockBufferFactory>(); |
1525 | + auto mock_client_buffer = std::make_shared<mtd::MockClientBuffer>(); |
1526 | + auto buf = std::make_shared<mcl::Buffer>(buffer_cb, nullptr, buffer_id, mock_client_buffer, nullptr, mir_buffer_usage_software); |
1527 | + EXPECT_CALL(*stream_map, with_stream_do(mir::frontend::BufferStreamId{stream_id},_)) |
1528 | + .Times(1); |
1529 | + |
1530 | + auto transport = std::make_unique<NiceMock<MockStreamTransport>>(); |
1531 | + mir::protobuf::EventSequence seq; |
1532 | + auto request = seq.mutable_buffer_request(); |
1533 | + request->mutable_id()->set_value(stream_id); |
1534 | + request->mutable_buffer()->set_buffer_id(buffer_id); |
1535 | + set_async_buffer_message(seq, *transport); |
1536 | + |
1537 | + mclr::MirProtobufRpcChannel channel{ |
1538 | + std::move(transport), |
1539 | + stream_map, |
1540 | + mock_buffer_factory, |
1541 | + std::make_shared<mcl::DisplayConfiguration>(), |
1542 | + std::make_shared<mir::input::InputDevices>(), |
1543 | + std::make_shared<mclr::NullRpcReport>(), |
1544 | + lifecycle, |
1545 | + std::make_shared<mir::client::PingHandler>(), |
1546 | + std::make_shared<mtd::NullClientEventSink>()}; |
1547 | + channel.on_data_available(); |
1548 | +} |
1549 | |
1550 | === modified file 'tests/unit-tests/compositor/test_client_buffers.cpp' |
1551 | --- tests/unit-tests/compositor/test_client_buffers.cpp 2016-04-05 03:47:49 +0000 |
1552 | +++ tests/unit-tests/compositor/test_client_buffers.cpp 2016-04-18 17:46:27 +0000 |
1553 | @@ -72,7 +72,7 @@ |
1554 | auto stub_buffer = std::make_shared<mtd::StubBuffer>(); |
1555 | EXPECT_CALL(mock_allocator, alloc_buffer(Ref(properties))) |
1556 | .WillOnce(Return(stub_buffer)); |
1557 | - EXPECT_CALL(mock_sink, send_buffer(stream_id, Ref(*stub_buffer), mg::BufferIpcMsgType::full_msg)); |
1558 | + EXPECT_CALL(mock_sink, add_buffer(Ref(*stub_buffer))); |
1559 | mc::BufferMap map{stream_id, mt::fake_shared(mock_sink), mt::fake_shared(mock_allocator)}; |
1560 | EXPECT_THAT(map.add_buffer(properties), Eq(stub_buffer->id())); |
1561 | } |
1562 | @@ -108,7 +108,7 @@ |
1563 | ASSERT_THAT(stub_allocator.map, SizeIs(1)); |
1564 | ASSERT_THAT(stub_allocator.ids, SizeIs(1)); |
1565 | auto buffer = map[stub_allocator.ids[0]]; |
1566 | - EXPECT_CALL(mock_sink, send_buffer(stream_id, Ref(*buffer), mg::BufferIpcMsgType::update_msg)); |
1567 | + EXPECT_CALL(mock_sink, update_buffer(Ref(*buffer))); |
1568 | map.send_buffer(stub_allocator.ids[0]); |
1569 | } |
1570 | |
1571 | @@ -118,8 +118,8 @@ |
1572 | ASSERT_THAT(stub_allocator.map, SizeIs(1)); |
1573 | ASSERT_THAT(stub_allocator.ids, SizeIs(1)); |
1574 | auto buffer = map[stub_allocator.ids[0]]; |
1575 | - EXPECT_CALL(mock_sink, send_buffer(stream_id, Ref(*buffer), mg::BufferIpcMsgType::update_msg)) |
1576 | - .Times(0); |
1577 | + |
1578 | + EXPECT_CALL(mock_sink, remove_buffer(Ref(*buffer))); |
1579 | map.remove_buffer(stub_allocator.ids[0]); |
1580 | map.send_buffer(stub_allocator.ids[0]); |
1581 | } |
1582 | @@ -127,9 +127,9 @@ |
1583 | TEST_F(ClientBuffers, can_remove_buffer_from_send_callback) |
1584 | { |
1585 | map.add_buffer(properties); |
1586 | - ON_CALL(mock_sink, send_buffer(_,_,_)) |
1587 | + ON_CALL(mock_sink, update_buffer(_)) |
1588 | .WillByDefault(Invoke( |
1589 | - [&] (mf::BufferStreamId, mg::Buffer& buffer, mg::BufferIpcMsgType) |
1590 | + [&] (mg::Buffer& buffer) |
1591 | { |
1592 | map.remove_buffer(buffer.id()); |
1593 | })); |
1594 | @@ -139,7 +139,7 @@ |
1595 | |
1596 | TEST_F(ClientBuffers, ignores_unknown_receive) |
1597 | { |
1598 | - EXPECT_CALL(mock_sink, send_buffer(_,_,_)) |
1599 | + EXPECT_CALL(mock_sink, add_buffer(_)) |
1600 | .Times(1); |
1601 | map.add_buffer(properties); |
1602 | map.remove_buffer(stub_allocator.ids[0]); |
FAILED: Continuous integration, rev:3433 /mir-jenkins. ubuntu. com/job/ mir-ci/ 806/ /mir-jenkins. ubuntu. com/job/ build-mir/ 804/console /mir-jenkins. ubuntu. com/job/ build-0- fetch/841 /mir-jenkins. ubuntu. com/job/ build-1- sourcepkg/ release= vivid+overlay/ 832 /mir-jenkins. ubuntu. com/job/ build-1- sourcepkg/ release= xenial/ 832 /mir-jenkins. ubuntu. com/job/ build-2- binpkg- mir/arch= amd64,compiler= clang,platform= mesa,release= vivid+overlay/ 813/console /mir-jenkins. ubuntu. com/job/ build-2- binpkg- mir/arch= amd64,compiler= gcc,platform= mesa,release= xenial/ 813/console /mir-jenkins. ubuntu. com/job/ build-2- binpkg- mir/arch= cross-armhf, compiler= gcc,platform= android, release= vivid+overlay/ 813/console /mir-jenkins. ubuntu. com/job/ build-2- binpkg- mir/arch= cross-armhf, compiler= gcc,platform= android, release= vivid+overlay/ 813/artifact/ output/ *zip*/output. zip /mir-jenkins. ubuntu. com/job/ build-2- binpkg- mir/arch= i386,compiler= gcc,platform= android, release= vivid+overlay/ 813 /mir-jenkins. ubuntu. com/job/ build-2- binpkg- mir/arch= i386,compiler= gcc,platform= android, release= vivid+overlay/ 813/artifact/ output/ *zip*/output. zip /mir-jenkins. ubuntu. com/job/ build-2- binpkg- mir/arch= i386,compiler= gcc,platform= mesa,release= xenial/ 813/console
https:/
Executed test runs:
FAILURE: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
FAILURE: https:/
Click here to trigger a rebuild: /mir-jenkins. ubuntu. com/job/ mir-ci/ 806/rebuild
https:/