Merge lp:~kdub/mir/nested-passthrough into lp:mir
- nested-passthrough
- Merge into development-branch
Status: | Merged | ||||||||
---|---|---|---|---|---|---|---|---|---|
Approved by: | Daniel van Vugt | ||||||||
Approved revision: | no longer in the source branch. | ||||||||
Merged at revision: | 3746 | ||||||||
Proposed branch: | lp:~kdub/mir/nested-passthrough | ||||||||
Merge into: | lp:mir | ||||||||
Prerequisite: | lp:~kdub/mir/nested-passthrough-logic | ||||||||
Diff against target: |
918 lines (+376/-43) 27 files modified
include/test/mir_test_framework/any_surface.h (+3/-1) include/test/mir_test_framework/headless_display_buffer_compositor_factory.h (+5/-0) include/test/mir_test_framework/headless_nested_server_runner.h (+12/-0) src/client/atomic_callback.h (+3/-3) src/client/mir_buffer_api.cpp (+2/-0) src/server/compositor/buffer_map.cpp (+8/-4) src/server/compositor/buffer_map.h (+3/-1) src/server/graphics/nested/buffer.cpp (+1/-1) src/server/graphics/nested/host_connection.h (+1/-0) src/server/graphics/nested/host_surface_spec.h (+2/-0) src/server/graphics/nested/ipc_operations.h (+2/-2) src/server/graphics/nested/mir_client_host_connection.cpp (+192/-5) src/server/graphics/nested/mir_client_host_connection.h (+1/-0) src/server/graphics/nested/native_buffer.h (+0/-1) src/server/graphics/nested/platform.cpp (+52/-2) tests/acceptance-tests/test_nested_mir.cpp (+17/-0) tests/include/mir/test/doubles/stub_client_buffer.h (+6/-1) tests/include/mir/test/doubles/stub_host_connection.h (+5/-0) tests/integration-tests/test_buffer_scheduling.cpp (+3/-3) tests/mir_test_framework/any_surface.cpp (+7/-1) tests/mir_test_framework/headless_display_buffer_compositor_factory.cpp (+22/-2) tests/mir_test_framework/headless_nested_server_runner.cpp (+17/-3) tests/mir_test_framework/headless_test.cpp (+1/-1) tests/unit-tests/compositor/test_client_buffers.cpp (+10/-10) tests/unit-tests/platforms/nested/test_buffer.cpp (+1/-0) tests/unit-tests/platforms/nested/test_ipc_operations.cpp (+0/-1) tests/unit-tests/platforms/nested/test_nested_display_buffer.cpp (+0/-1) |
||||||||
To merge this branch: | bzr merge lp:~kdub/mir/nested-passthrough | ||||||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Daniel van Vugt | Approve | ||
Cemil Azizoglu (community) | Approve | ||
Mir CI Bot | continuous-integration | Approve | |
Review via email: mp+307315@code.launchpad.net |
Commit message
nested: optimize fullscreen client surfaces by passing their buffers through the nested server to the host server without composing.
(LP: #1262116)
Description of the change
nested: optimize fullscreen client surfaces by passing their buffers through the nested server to the host server without composing. Currently only enabled for android. EGLStreams does this under-the hood, and mesa enablement is up for review: lp:~kdub/mir/mesa-clientbuffer-eglimage-mapping
Also working on measurements (needs some more reporting changes)
Mir CI Bot (mir-ci-bot) wrote : | # |
Kevin DuBois (kdub) wrote : | # |
grr, merge madness
Mir CI Bot (mir-ci-bot) wrote : | # |
FAILED: Continuous integration, rev:3733
https:/
Executed test runs:
FAILURE: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
FAILURE: https:/
Click here to trigger a rebuild:
https:/
Mir CI Bot (mir-ci-bot) wrote : | # |
FAILED: Continuous integration, rev:3736
https:/
Executed test runs:
FAILURE: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
FAILURE: https:/
Click here to trigger a rebuild:
https:/
Mir CI Bot (mir-ci-bot) wrote : | # |
FAILED: Continuous integration, rev:3737
https:/
Executed test runs:
FAILURE: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
FAILURE: https:/
Click here to trigger a rebuild:
https:/
Kevin DuBois (kdub) wrote : | # |
Mir CI Bot (mir-ci-bot) wrote : | # |
FAILED: Continuous integration, rev:3738
https:/
Executed test runs:
FAILURE: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
deb: https:/
FAILURE: https:/
FAILURE: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
FAILURE: https:/
Click here to trigger a rebuild:
https:/
Mir CI Bot (mir-ci-bot) wrote : | # |
FAILED: Continuous integration, rev:3738
https:/
Executed test runs:
FAILURE: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
deb: https:/
FAILURE: https:/
FAILURE: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
FAILURE: https:/
Click here to trigger a rebuild:
https:/
Kevin DuBois (kdub) wrote : | # |
hmm, seems different than the logged bug, investigating further
Daniel van Vugt (vanvugt) wrote : | # |
For the measurements, we can measure latency externally using mirvanity. Although I suspect we don't expect any reduction in latency here(?).
I think CPU and GPU load is also something we aim to reduce but bug 1540207 suggests that we won't see that on desktop. So maybe try looking at CPU/GPU usage on mobile for some positive measurements.
Daniel van Vugt (vanvugt) wrote : | # |
OK, I've just done some fresh high-speed camera testing with mirvanity. Confirmed there is no reduction in latency here. Nesting still introduces two extra frames of lag (triple buffers):
Trunk: 64ms
This branch: 64ms
Trunk (nested): 97ms
This branch (nested): 97ms
But that's OK. Latency reductions will come later with the client-side vsync work I'm doing...
Daniel van Vugt (vanvugt) wrote : | # |
Oh. Is this relevant?
[2016-10-05 11:22:54.841327] <ERROR> mirclient: Caught exception at client library boundary (in mir_buffer_
Dynamic exception type: boost::
std::exception:
[2016-10-05 11:22:54.841628] <ERROR> mirclient: Caught exception at client library boundary (in mir_buffer_
Dynamic exception type: boost::
std::exception:
Daniel van Vugt (vanvugt) : | # |
Daniel van Vugt (vanvugt) wrote : | # |
Looks like that exception is fixed in:
lp:~kdub/mir/mesa-clientbuffer-eglimage-mapping
Daniel van Vugt (vanvugt) : | # |
Daniel van Vugt (vanvugt) wrote : | # |
Win! Merging lp:~kdub/mir/mesa-clientbuffer-eglimage-mapping with this one gets the nesting lag down from 97ms to 64ms. Thus after you combine both branches the nesting lag is eliminated!
Daniel van Vugt (vanvugt) wrote : | # |
Bugger. Found a regression in fullscreen framedropping clients (mir_demo_
Although a similar bug 1369763 has existed on android for at least two years. We should avoid breaking desktop as well.
Daniel van Vugt (vanvugt) wrote : | # |
Actually fixing bug 1369763 is possibly a prerequisite for my future lower latency work. So we really need to fix it everywhere.
Daniel van Vugt (vanvugt) wrote : | # |
Also, since this branch doesn't actually do what the label says until you combine it with lp:~kdub/mir/mesa-clientbuffer-eglimage-mapping, it might be an idea to prereq that.
Daniel van Vugt (vanvugt) wrote : | # |
OK, a few issues, so to summarise:
(0) Please prerequisite lp:~kdub/mir/mesa-clientbuffer-eglimage-mapping to make this branch work on desktop.
(1) Needs Fixing: Framedropping pass-through clients are incorrectly bound to 60 FPS.
(2) Needs Fixing: My nested server got stuck in an infinite loop on shutdown when testing this branch, but that bug might have originated elsewhere?...
[2016-10-05 15:49:42.260127] <ERROR> Mesa/NativeSurface: Caught exception at Mir/EGL driver boundary (in advance_buffer): Dynamic exception type: std::logic_error
std::exception:
[2016-10-05 15:49:42.262044] <ERROR> Mesa/NativeSurface: Caught exception at Mir/EGL driver boundary (in advance_buffer): Dynamic exception type: std::logic_error
std::exception:
[2016-10-05 15:49:42.264824] <ERROR> Mesa/NativeSurface: Caught exception at Mir/EGL driver boundary (in advance_buffer): Dynamic exception type: std::logic_error
std::exception:
Looks similar to bug 1630230.
Mir CI Bot (mir-ci-bot) wrote : | # |
PASSED: Continuous integration, rev:3740
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:/
Click here to trigger a rebuild:
https:/
Kevin DuBois (kdub) wrote : | # |
with the 60fps degradation, still needs investigation. The fix pushed might have fixed the shutdown problem, and did fix CI. Still investigating a situation with the io threads and shutdown, that I've only seen in the acceptance tests, but should be fixed anyways.
Mir CI Bot (mir-ci-bot) wrote : | # |
PASSED: Continuous integration, rev:3741
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:/
Click here to trigger a rebuild:
https:/
Daniel van Vugt (vanvugt) wrote : | # |
(0) I'm trying to solve this by landing the other branch today, before this one. That way this landing will actually be the revision in which nested passthrough also started working.
(1) I don't mind too much if this bug remains unresolved briefly. Since I started looking at how NBS does swap intervals yesterday I now realize we have a couple of other existing bugs in this area to fix already. So making that three bugs instead of two isn't a major problem. Especially if multiple bugs get resolved all at once.
(2) Can't reproduce that error now. Thanks.
Daniel van Vugt (vanvugt) wrote : | # |
(3) Just worth noting; a pixel format with alpha may well be able to pass-through but in some cases (at least always on desktop) will be rejected by bypass:
+bool mgn::MirClientH
467 +{
468 + auto buffer = create_
Cemil Azizoglu (cemil-azizoglu) wrote : | # |
LGTM... Looking forward to more complete performance numbers.
Kevin DuBois (kdub) wrote : | # |
@Daniel
for (1) the issue is that the client is swapinterval0, and the chain representing that client in the host server is operating with 'swapinterval1'. The spare buffers quickly all end up getting stuck in the host's queue, instead of returning from the host on new submissions.
I'm plumbing up a way for the host and the client to agree on swapinterval at the moment. will restack on that branch, and then we don't have to have the issue.
for (3) can probably add this in a subsequent branch.
@Cemil
Will propose updates to the latency suite to accommodate nested passthrough, hopefully before the sprint.
Daniel van Vugt (vanvugt) wrote : | # |
(3) I wonder if there ever might be some future platform which can't pass-through non-bypassable buffers (abgr). Doesn't seem to be important yet but it wouldn't hurt us to remove all doubt and probe using xbgr only.
Cemil:
You won't get more accurate (or encouraging) performance numbers than my above measurements. Although sadly mirvanity only runs on desktop (no Video4Linux support on Android!?).
Preview Diff
1 | === modified file 'include/test/mir_test_framework/any_surface.h' |
2 | --- include/test/mir_test_framework/any_surface.h 2016-01-29 08:18:22 +0000 |
3 | +++ include/test/mir_test_framework/any_surface.h 2016-10-06 14:43:17 +0000 |
4 | @@ -20,10 +20,12 @@ |
5 | #define MIR_TEST_FRAMEWORK_ANY_SURFACE_H_ |
6 | |
7 | #include "mir_toolkit/mir_client_library.h" |
8 | +#include "mir/geometry/size.h" |
9 | |
10 | namespace mir_test_framework |
11 | { |
12 | -MirSurface *make_any_surface(MirConnection *connection); |
13 | +MirSurface* make_any_surface(MirConnection *connection); |
14 | +MirSurface* make_surface(MirConnection *connection, mir::geometry::Size size, MirPixelFormat format); |
15 | } |
16 | |
17 | #endif // MIR_TEST_FRAMEWORK_ANY_SURFACE_H_ |
18 | |
19 | === modified file 'include/test/mir_test_framework/headless_display_buffer_compositor_factory.h' |
20 | --- include/test/mir_test_framework/headless_display_buffer_compositor_factory.h 2016-09-19 04:16:15 +0000 |
21 | +++ include/test/mir_test_framework/headless_display_buffer_compositor_factory.h 2016-10-06 14:43:17 +0000 |
22 | @@ -22,10 +22,15 @@ |
23 | |
24 | namespace mir_test_framework |
25 | { |
26 | +class PassthroughTracker; |
27 | struct HeadlessDisplayBufferCompositorFactory : mir::compositor::DisplayBufferCompositorFactory |
28 | { |
29 | + HeadlessDisplayBufferCompositorFactory(); |
30 | + HeadlessDisplayBufferCompositorFactory(std::shared_ptr<PassthroughTracker> const& tracker); |
31 | std::unique_ptr<mir::compositor::DisplayBufferCompositor> create_compositor_for( |
32 | mir::graphics::DisplayBuffer& display_buffer) override; |
33 | +private: |
34 | + std::shared_ptr<PassthroughTracker> const tracker; |
35 | }; |
36 | } |
37 | #endif /* MIR_TEST_FRAMEWORK_HEADLESS_DISPLAY_BUFFER_COMPOSITOR_FACTORY_H_ */ |
38 | |
39 | === modified file 'include/test/mir_test_framework/headless_nested_server_runner.h' |
40 | --- include/test/mir_test_framework/headless_nested_server_runner.h 2016-01-29 08:18:22 +0000 |
41 | +++ include/test/mir_test_framework/headless_nested_server_runner.h 2016-10-06 14:43:17 +0000 |
42 | @@ -20,13 +20,25 @@ |
43 | #define MIR_TEST_FRAMEWORK_HEADLESS_NESTED_SERVER_RUNNER_H_ |
44 | |
45 | #include "mir_test_framework/async_server_runner.h" |
46 | +#include <atomic> |
47 | |
48 | namespace mir_test_framework |
49 | { |
50 | +struct PassthroughTracker |
51 | +{ |
52 | + bool wait_for_passthrough_frames(size_t num_frames, std::chrono::milliseconds ms); |
53 | + void note_passthrough(); |
54 | +private: |
55 | + std::mutex mutex; |
56 | + std::condition_variable cv; |
57 | + size_t num_passthrough; |
58 | +}; |
59 | + |
60 | class HeadlessNestedServerRunner : public AsyncServerRunner |
61 | { |
62 | public: |
63 | HeadlessNestedServerRunner(std::string const& connect_string); |
64 | + std::shared_ptr<PassthroughTracker> const passthrough_tracker; |
65 | }; |
66 | } |
67 | |
68 | |
69 | === modified file 'src/client/atomic_callback.h' |
70 | --- src/client/atomic_callback.h 2016-06-06 12:49:18 +0000 |
71 | +++ src/client/atomic_callback.h 2016-10-06 14:43:17 +0000 |
72 | @@ -44,20 +44,20 @@ |
73 | |
74 | void set_callback(std::function<void(Args...)> const& fn) |
75 | { |
76 | - std::lock_guard<std::mutex> lk(guard); |
77 | + std::lock_guard<std::recursive_mutex> lk(guard); |
78 | |
79 | callback = fn; |
80 | } |
81 | |
82 | void operator()(Args&&... args) const |
83 | { |
84 | - std::lock_guard<std::mutex> lk(guard); |
85 | + std::lock_guard<std::recursive_mutex> lk(guard); |
86 | |
87 | callback(std::forward<Args>(args)...); |
88 | } |
89 | |
90 | private: |
91 | - std::mutex mutable guard; |
92 | + std::recursive_mutex mutable guard; |
93 | std::function<void(Args...)> callback; |
94 | }; |
95 | } |
96 | |
97 | === modified file 'src/client/mir_buffer_api.cpp' |
98 | --- src/client/mir_buffer_api.cpp 2016-09-30 07:03:28 +0000 |
99 | +++ src/client/mir_buffer_api.cpp 2016-10-06 14:43:17 +0000 |
100 | @@ -49,11 +49,13 @@ |
101 | MIR_LOG_UNCAUGHT_EXCEPTION(ex); |
102 | } |
103 | |
104 | +void ignore(MirBuffer*, void*){} |
105 | void mir_buffer_release(MirBuffer* b) |
106 | try |
107 | { |
108 | mir::require(b); |
109 | auto buffer = reinterpret_cast<mcl::MirBuffer*>(b); |
110 | + buffer->set_callback(ignore, nullptr); |
111 | auto connection = buffer->allocating_connection(); |
112 | connection->release_buffer(buffer); |
113 | } |
114 | |
115 | === modified file 'src/server/compositor/buffer_map.cpp' |
116 | --- src/server/compositor/buffer_map.cpp 2016-06-24 17:32:47 +0000 |
117 | +++ src/server/compositor/buffer_map.cpp 2016-10-06 14:43:17 +0000 |
118 | @@ -53,11 +53,13 @@ |
119 | std::unique_lock<decltype(mutex)> lk(mutex); |
120 | auto buffer = allocator->alloc_buffer(properties); |
121 | buffers[buffer->id()] = {buffer, Owner::client}; |
122 | - sink->add_buffer(*buffer); |
123 | + if (auto s = sink.lock()) |
124 | + s->add_buffer(*buffer); |
125 | return buffer->id(); |
126 | } catch (std::exception& e) |
127 | { |
128 | - sink->error_buffer(properties, e.what()); |
129 | + if (auto s = sink.lock()) |
130 | + s->error_buffer(properties, e.what()); |
131 | throw; |
132 | } |
133 | } |
134 | @@ -66,7 +68,8 @@ |
135 | { |
136 | std::unique_lock<decltype(mutex)> lk(mutex); |
137 | auto it = checked_buffers_find(id, lk); |
138 | - sink->remove_buffer(*it->second.buffer); |
139 | + if (auto s = sink.lock()) |
140 | + s->remove_buffer(*it->second.buffer); |
141 | buffers.erase(it); |
142 | } |
143 | |
144 | @@ -79,7 +82,8 @@ |
145 | auto buffer = it->second.buffer; |
146 | it->second.owner = Owner::client; |
147 | lk.unlock(); |
148 | - sink->update_buffer(*buffer); |
149 | + if (auto s = sink.lock()) |
150 | + s->update_buffer(*buffer); |
151 | } |
152 | } |
153 | |
154 | |
155 | === modified file 'src/server/compositor/buffer_map.h' |
156 | --- src/server/compositor/buffer_map.h 2016-06-02 05:33:50 +0000 |
157 | +++ src/server/compositor/buffer_map.h 2016-10-06 14:43:17 +0000 |
158 | @@ -58,7 +58,9 @@ |
159 | Map buffers; |
160 | Map::iterator checked_buffers_find(graphics::BufferID, std::unique_lock<std::mutex> const&); |
161 | |
162 | - std::shared_ptr<frontend::BufferSink> const sink; |
163 | + //would be better to schedule the async buffer callbacks in the ipc subsystem, |
164 | + //instead of driving from within the compositor threads (LP: #1395421) |
165 | + std::weak_ptr<frontend::BufferSink> const sink; |
166 | std::shared_ptr<graphics::GraphicBufferAllocator> const allocator; |
167 | }; |
168 | } |
169 | |
170 | === modified file 'src/server/graphics/nested/buffer.cpp' |
171 | --- src/server/graphics/nested/buffer.cpp 2016-09-22 18:17:43 +0000 |
172 | +++ src/server/graphics/nested/buffer.cpp 2016-10-06 14:43:17 +0000 |
173 | @@ -181,7 +181,7 @@ |
174 | |
175 | std::shared_ptr<mg::NativeBuffer> mgn::Buffer::native_buffer_handle() const |
176 | { |
177 | - return nullptr; |
178 | + return buffer; |
179 | } |
180 | |
181 | geom::Size mgn::Buffer::size() const |
182 | |
183 | === modified file 'src/server/graphics/nested/host_connection.h' |
184 | --- src/server/graphics/nested/host_connection.h 2016-09-22 16:27:13 +0000 |
185 | +++ src/server/graphics/nested/host_connection.h 2016-10-06 14:43:17 +0000 |
186 | @@ -77,6 +77,7 @@ |
187 | virtual void set_input_event_callback(std::function<void(MirEvent const&, mir::geometry::Rectangle const&)> const& cb) = 0; |
188 | virtual void emit_input_event(MirEvent const& event, mir::geometry::Rectangle const& source_frame) = 0; |
189 | virtual std::shared_ptr<NativeBuffer> create_buffer(graphics::BufferProperties const&) = 0; |
190 | + virtual bool supports_passthrough() = 0; |
191 | |
192 | protected: |
193 | HostConnection() = default; |
194 | |
195 | === modified file 'src/server/graphics/nested/host_surface_spec.h' |
196 | --- src/server/graphics/nested/host_surface_spec.h 2016-09-08 18:32:45 +0000 |
197 | +++ src/server/graphics/nested/host_surface_spec.h 2016-10-06 14:43:17 +0000 |
198 | @@ -19,6 +19,7 @@ |
199 | #ifndef MIR_GRAPHICS_NESTED_HOST_SURFACE_SPEC_H_ |
200 | #define MIR_GRAPHICS_NESTED_HOST_SURFACE_SPEC_H_ |
201 | |
202 | +#include "mir_toolkit/client_types.h" |
203 | #include "mir/geometry/size.h" |
204 | #include "mir/geometry/displacement.h" |
205 | |
206 | @@ -36,6 +37,7 @@ |
207 | virtual ~HostSurfaceSpec() = default; |
208 | virtual void add_chain(HostChain&, geometry::Displacement disp, geometry::Size size) = 0; |
209 | virtual void add_stream(HostStream&, geometry::Displacement disp) = 0; |
210 | + virtual MirSurfaceSpec* handle() = 0; |
211 | protected: |
212 | HostSurfaceSpec() = default; |
213 | HostSurfaceSpec(HostSurfaceSpec const&) = delete; |
214 | |
215 | === modified file 'src/server/graphics/nested/ipc_operations.h' |
216 | --- src/server/graphics/nested/ipc_operations.h 2016-09-13 12:40:23 +0000 |
217 | +++ src/server/graphics/nested/ipc_operations.h 2016-10-06 14:43:17 +0000 |
218 | @@ -33,8 +33,8 @@ |
219 | public: |
220 | IpcOperations(std::shared_ptr<graphics::PlatformIpcOperations> const& host_operations); |
221 | |
222 | - void pack_buffer(BufferIpcMessage& message, Buffer const& buffer, BufferIpcMsgType msg_type) const override; |
223 | - void unpack_buffer(BufferIpcMessage& message, Buffer const& buffer) const override; |
224 | + void pack_buffer(BufferIpcMessage& message, graphics::Buffer const& buffer, BufferIpcMsgType msg_type) const override; |
225 | + void unpack_buffer(BufferIpcMessage& message, graphics::Buffer const& buffer) const override; |
226 | std::shared_ptr<PlatformIPCPackage> connection_ipc_package() override; |
227 | PlatformOperationMessage platform_operation( |
228 | unsigned int const opcode, PlatformOperationMessage const& message) override; |
229 | |
230 | === modified file 'src/server/graphics/nested/mir_client_host_connection.cpp' |
231 | --- src/server/graphics/nested/mir_client_host_connection.cpp 2016-10-04 11:56:53 +0000 |
232 | +++ src/server/graphics/nested/mir_client_host_connection.cpp 2016-10-06 14:43:17 +0000 |
233 | @@ -20,11 +20,16 @@ |
234 | #include "host_surface.h" |
235 | #include "host_stream.h" |
236 | #include "host_chain.h" |
237 | +#include "host_surface_spec.h" |
238 | +#include "native_buffer.h" |
239 | #include "mir_toolkit/mir_client_library.h" |
240 | #include "mir_toolkit/mir_buffer.h" |
241 | +#include "mir_toolkit/mir_buffer_private.h" |
242 | +#include "mir_toolkit/mir_presentation_chain.h" |
243 | #include "mir/raii.h" |
244 | #include "mir/graphics/platform_operation_message.h" |
245 | #include "mir/graphics/cursor_image.h" |
246 | +#include "mir/graphics/buffer.h" |
247 | #include "mir/input/device.h" |
248 | #include "mir/input/device_capability.h" |
249 | #include "mir/input/pointer_configuration.h" |
250 | @@ -38,9 +43,11 @@ |
251 | |
252 | #include <algorithm> |
253 | #include <stdexcept> |
254 | +#include <condition_variable> |
255 | |
256 | #include <cstring> |
257 | |
258 | +namespace geom = mir::geometry; |
259 | namespace mg = mir::graphics; |
260 | namespace mgn = mir::graphics::nested; |
261 | namespace mi = mir::input; |
262 | @@ -114,8 +121,9 @@ |
263 | mir_surface_release_sync(mir_surface); |
264 | } |
265 | |
266 | - void apply_spec(mgn::HostSurfaceSpec&) override |
267 | + void apply_spec(mgn::HostSurfaceSpec& spec) override |
268 | { |
269 | + mir_surface_apply_spec(mir_surface, spec.handle()); |
270 | } |
271 | |
272 | EGLNativeWindowType egl_native_window() override |
273 | @@ -477,18 +485,197 @@ |
274 | return std::make_unique<MirClientHostStream>(mir_connection, properties); |
275 | } |
276 | |
277 | +struct Chain : mgn::HostChain |
278 | +{ |
279 | + Chain(MirConnection* connection) : |
280 | + chain(mir_connection_create_presentation_chain_sync(connection)) |
281 | + { |
282 | + } |
283 | + ~Chain() |
284 | + { |
285 | + mir_presentation_chain_release(chain); |
286 | + } |
287 | + |
288 | + void submit_buffer(mgn::NativeBuffer& buffer) |
289 | + { |
290 | + mir_presentation_chain_submit_buffer(chain, buffer.client_handle()); |
291 | + } |
292 | + |
293 | + MirPresentationChain* handle() |
294 | + { |
295 | + return chain; |
296 | + } |
297 | +private: |
298 | + MirPresentationChain* chain; |
299 | +}; |
300 | + |
301 | std::unique_ptr<mgn::HostChain> mgn::MirClientHostConnection::create_chain() const |
302 | { |
303 | - BOOST_THROW_EXCEPTION(std::runtime_error("not implemented yet")); |
304 | + return std::make_unique<Chain>(mir_connection); |
305 | +} |
306 | + |
307 | +namespace |
308 | +{ |
309 | +class HostBuffer : public mgn::NativeBuffer |
310 | +{ |
311 | +public: |
312 | + HostBuffer(MirConnection* mir_connection, mg::BufferProperties const& properties) |
313 | + { |
314 | + mir_connection_allocate_buffer( |
315 | + mir_connection, |
316 | + properties.size.width.as_int(), |
317 | + properties.size.height.as_int(), |
318 | + properties.format, |
319 | + (properties.usage == mg::BufferUsage::hardware) ? mir_buffer_usage_hardware : mir_buffer_usage_software, |
320 | + buffer_available, this); |
321 | + std::unique_lock<std::mutex> lk(mut); |
322 | + cv.wait(lk, [&]{ return handle; }); |
323 | + if (!mir_buffer_is_valid(handle)) |
324 | + { |
325 | + mir_buffer_release(handle); |
326 | + BOOST_THROW_EXCEPTION(std::runtime_error("could not allocate MirBuffer")); |
327 | + } |
328 | + } |
329 | + ~HostBuffer() |
330 | + { |
331 | + mir_buffer_release(handle); |
332 | + } |
333 | + |
334 | + void sync(MirBufferAccess access, std::chrono::nanoseconds ns) override |
335 | + { |
336 | + mir_buffer_wait_for_access(handle, access, ns.count()); |
337 | + } |
338 | + |
339 | + MirBuffer* client_handle() const override |
340 | + { |
341 | + return handle; |
342 | + } |
343 | + |
344 | + MirGraphicsRegion get_graphics_region() override |
345 | + { |
346 | + return mir_buffer_get_graphics_region(handle, mir_read_write); |
347 | + } |
348 | + |
349 | + geom::Size size() const override |
350 | + { |
351 | + return { mir_buffer_get_width(handle), mir_buffer_get_height(handle) }; |
352 | + } |
353 | + |
354 | + MirPixelFormat format() const override |
355 | + { |
356 | + return mir_buffer_get_pixel_format(handle); |
357 | + } |
358 | + |
359 | + std::tuple<EGLenum, EGLClientBuffer, EGLint*> egl_image_creation_hints() const override |
360 | + { |
361 | + EGLenum type; |
362 | + EGLClientBuffer client_buffer = nullptr;; |
363 | + EGLint* attrs = nullptr; |
364 | + mir_buffer_egl_image_parameters(handle, &type, &client_buffer, &attrs); |
365 | + |
366 | + return std::tuple<EGLenum, EGLClientBuffer, EGLint*>{type, client_buffer, attrs}; |
367 | + } |
368 | + |
369 | + static void buffer_available(MirBuffer* buffer, void* context) |
370 | + { |
371 | + auto host_buffer = static_cast<HostBuffer*>(context); |
372 | + host_buffer->available(buffer); |
373 | + } |
374 | + |
375 | + void available(MirBuffer* buffer) |
376 | + { |
377 | + std::unique_lock<std::mutex> lk(mut); |
378 | + if (!handle) |
379 | + { |
380 | + handle = buffer; |
381 | + cv.notify_all(); |
382 | + } |
383 | + |
384 | + auto g = f; |
385 | + lk.unlock(); |
386 | + if (g) |
387 | + g(); |
388 | + } |
389 | + |
390 | + void on_ownership_notification(std::function<void()> const& fn) override |
391 | + { |
392 | + std::unique_lock<std::mutex> lk(mut); |
393 | + f = fn; |
394 | + } |
395 | + |
396 | + MirBufferPackage* package() const override |
397 | + { |
398 | + return mir_buffer_get_buffer_package(handle); |
399 | + } |
400 | + |
401 | + void set_fence(mir::Fd fd) override |
402 | + { |
403 | + mir_buffer_associate_fence(handle, fd, mir_read_write); |
404 | + } |
405 | + |
406 | + mir::Fd fence() const override |
407 | + { |
408 | + return mir::Fd{mir::IntOwnedFd{mir_buffer_get_fence(handle)}}; |
409 | + } |
410 | + |
411 | +private: |
412 | + std::function<void()> f; |
413 | + MirBuffer* handle = nullptr; |
414 | + std::mutex mut; |
415 | + std::condition_variable cv; |
416 | +}; |
417 | + |
418 | +class SurfaceSpec : public mgn::HostSurfaceSpec |
419 | +{ |
420 | +public: |
421 | + SurfaceSpec(MirConnection* connection) : |
422 | + spec(mir_connection_create_spec_for_changes(connection)) |
423 | + { |
424 | + } |
425 | + |
426 | + ~SurfaceSpec() |
427 | + { |
428 | + mir_surface_spec_release(spec); |
429 | + } |
430 | + |
431 | + void add_chain(mgn::HostChain& chain, geom::Displacement disp, geom::Size size) override |
432 | + { |
433 | + mir_surface_spec_add_presentation_chain( |
434 | + spec, size.width.as_int(), size.height.as_int(), |
435 | + disp.dx.as_int(), disp.dy.as_int(), chain.handle()); |
436 | + } |
437 | + |
438 | + void add_stream(mgn::HostStream& stream, geom::Displacement disp) override |
439 | + { |
440 | + mir_surface_spec_add_buffer_stream(spec, disp.dx.as_int(), disp.dy.as_int(), stream.handle()); |
441 | + } |
442 | + |
443 | + MirSurfaceSpec* handle() override |
444 | + { |
445 | + return spec; |
446 | + } |
447 | +private: |
448 | + MirSurfaceSpec* spec; |
449 | +}; |
450 | } |
451 | |
452 | std::shared_ptr<mgn::NativeBuffer> mgn::MirClientHostConnection::create_buffer( |
453 | - mg::BufferProperties const&) |
454 | + mg::BufferProperties const& properties) |
455 | { |
456 | - BOOST_THROW_EXCEPTION(std::runtime_error("not implemented yet")); |
457 | + return std::make_shared<HostBuffer>(mir_connection, properties); |
458 | } |
459 | |
460 | std::unique_ptr<mgn::HostSurfaceSpec> mgn::MirClientHostConnection::create_surface_spec() |
461 | { |
462 | - BOOST_THROW_EXCEPTION(std::runtime_error("not implemented yet")); |
463 | + return std::make_unique<SurfaceSpec>(mir_connection); |
464 | +} |
465 | + |
466 | +bool mgn::MirClientHostConnection::supports_passthrough() |
467 | +{ |
468 | + auto buffer = create_buffer(mg::BufferProperties(geom::Size{1, 1} , mir_pixel_format_abgr_8888, mg::BufferUsage::software)); |
469 | + |
470 | + auto hints = buffer->egl_image_creation_hints(); |
471 | + if (std::get<1>(hints) == nullptr && std::get<2>(hints) == nullptr) |
472 | + return false; |
473 | + return true; |
474 | } |
475 | |
476 | === modified file 'src/server/graphics/nested/mir_client_host_connection.h' |
477 | --- src/server/graphics/nested/mir_client_host_connection.h 2016-10-04 11:56:53 +0000 |
478 | +++ src/server/graphics/nested/mir_client_host_connection.h 2016-10-06 14:43:17 +0000 |
479 | @@ -86,6 +86,7 @@ |
480 | void set_input_event_callback(std::function<void(MirEvent const&, mir::geometry::Rectangle const&)> const& cb) override; |
481 | void emit_input_event(MirEvent const& cb, mir::geometry::Rectangle const& source_frame) override; |
482 | std::shared_ptr<NativeBuffer> create_buffer(graphics::BufferProperties const&) override; |
483 | + bool supports_passthrough() override; |
484 | |
485 | private: |
486 | void update_input_config(UniqueInputConfig input_config); |
487 | |
488 | === modified file 'src/server/graphics/nested/native_buffer.h' |
489 | --- src/server/graphics/nested/native_buffer.h 2016-09-30 12:26:56 +0000 |
490 | +++ src/server/graphics/nested/native_buffer.h 2016-10-06 14:43:17 +0000 |
491 | @@ -43,7 +43,6 @@ |
492 | virtual ~NativeBuffer() = default; |
493 | virtual void sync(MirBufferAccess, std::chrono::nanoseconds) = 0; |
494 | virtual MirBuffer* client_handle() const = 0; |
495 | - virtual MirNativeBuffer* get_native_handle() = 0; |
496 | virtual MirGraphicsRegion get_graphics_region() = 0; |
497 | virtual geometry::Size size() const = 0; |
498 | virtual MirPixelFormat format() const = 0; |
499 | |
500 | === modified file 'src/server/graphics/nested/platform.cpp' |
501 | --- src/server/graphics/nested/platform.cpp 2016-07-19 20:56:18 +0000 |
502 | +++ src/server/graphics/nested/platform.cpp 2016-10-06 14:43:17 +0000 |
503 | @@ -19,10 +19,16 @@ |
504 | #include "platform.h" |
505 | #include "host_connection.h" |
506 | #include "display.h" |
507 | +#include "buffer.h" |
508 | +#include "native_buffer.h" |
509 | +#include "ipc_operations.h" |
510 | #include "mir/shared_library.h" |
511 | #include "mir/graphics/graphic_buffer_allocator.h" |
512 | #include "mir/graphics/display.h" |
513 | #include "mir/graphics/platform_ipc_operations.h" |
514 | +#include "mir/graphics/buffer_ipc_message.h" |
515 | +#include "mir/graphics/platform_ipc_operations.h" |
516 | +#include "mir/graphics/platform_operation_message.h" |
517 | |
518 | namespace mg = mir::graphics; |
519 | namespace mgn = mir::graphics::nested; |
520 | @@ -39,9 +45,53 @@ |
521 | { |
522 | } |
523 | |
524 | +namespace |
525 | +{ |
526 | +class BufferAllocator : public mg::GraphicBufferAllocator |
527 | +{ |
528 | +public: |
529 | + BufferAllocator( |
530 | + std::shared_ptr<mgn::HostConnection> const& connection, |
531 | + std::shared_ptr<mg::GraphicBufferAllocator> const& guest_allocator) : |
532 | + connection(connection), |
533 | + guest_allocator(guest_allocator) |
534 | + { |
535 | + } |
536 | + |
537 | + std::shared_ptr<mg::Buffer> alloc_buffer(mg::BufferProperties const& buffer_properties) override |
538 | + { |
539 | + if ((buffer_properties.size.width >= mir::geometry::Width{480}) && |
540 | + (buffer_properties.size.height >= mir::geometry::Height{480})) |
541 | + { |
542 | + return std::make_shared<mgn::Buffer>(connection, buffer_properties); |
543 | + } |
544 | + else |
545 | + { |
546 | + return guest_allocator->alloc_buffer(buffer_properties); |
547 | + } |
548 | + } |
549 | + |
550 | + std::vector<MirPixelFormat> supported_pixel_formats() override |
551 | + { |
552 | + return guest_allocator->supported_pixel_formats(); |
553 | + } |
554 | + |
555 | +private: |
556 | + std::shared_ptr<mgn::HostConnection> const connection; |
557 | + std::shared_ptr<mg::GraphicBufferAllocator> const guest_allocator; |
558 | +}; |
559 | +} |
560 | + |
561 | mir::UniqueModulePtr<mg::GraphicBufferAllocator> mgn::Platform::create_buffer_allocator() |
562 | { |
563 | - return guest_platform->create_buffer_allocator(); |
564 | + if (connection->supports_passthrough()) |
565 | + { |
566 | + return mir::make_module_ptr<BufferAllocator>(connection, guest_platform->create_buffer_allocator()); |
567 | + } |
568 | + else |
569 | + { |
570 | + return guest_platform->create_buffer_allocator(); |
571 | + } |
572 | } |
573 | |
574 | mir::UniqueModulePtr<mg::Display> mgn::Platform::create_display( |
575 | @@ -58,5 +108,5 @@ |
576 | |
577 | mir::UniqueModulePtr<mg::PlatformIpcOperations> mgn::Platform::make_ipc_operations() const |
578 | { |
579 | - return guest_platform->make_ipc_operations(); |
580 | + return mir::make_module_ptr<mgn::IpcOperations>(guest_platform->make_ipc_operations()); |
581 | } |
582 | |
583 | === modified file 'tests/acceptance-tests/test_nested_mir.cpp' |
584 | --- tests/acceptance-tests/test_nested_mir.cpp 2016-09-28 14:07:37 +0000 |
585 | +++ tests/acceptance-tests/test_nested_mir.cpp 2016-10-06 14:43:17 +0000 |
586 | @@ -640,6 +640,13 @@ |
587 | |
588 | struct ClientWithAPaintedSurface : virtual Client |
589 | { |
590 | + ClientWithAPaintedSurface(NestedMirRunner& nested_mir, geom::Size size, MirPixelFormat format) : |
591 | + Client(nested_mir), |
592 | + surface(mtf::make_surface(connection, size, format)) |
593 | + { |
594 | + mir_buffer_stream_swap_buffers_sync(mir_surface_get_buffer_stream(surface)); |
595 | + } |
596 | + |
597 | ClientWithAPaintedSurface(NestedMirRunner& nested_mir) : |
598 | Client(nested_mir), |
599 | surface(mtf::make_any_surface(connection)) |
600 | @@ -1504,3 +1511,13 @@ |
601 | EXPECT_TRUE(host_config_change.raised()); |
602 | Mock::VerifyAndClearExpectations(&display); |
603 | } |
604 | + |
605 | +TEST_F(NestedServer, uses_passthrough_when_surface_size_is_appropriate) |
606 | +{ |
607 | + using namespace std::chrono_literals; |
608 | + NestedMirRunner nested_mir{new_connection()}; |
609 | + nested_mir.wait_until_ready(); |
610 | + ClientWithAPaintedSurface client( |
611 | + nested_mir, display_geometry.front().size, mir_pixel_format_xbgr_8888); |
612 | + EXPECT_TRUE(nested_mir.passthrough_tracker->wait_for_passthrough_frames(1, 5s)); |
613 | +} |
614 | |
615 | === modified file 'tests/include/mir/test/doubles/stub_client_buffer.h' |
616 | --- tests/include/mir/test/doubles/stub_client_buffer.h 2016-09-30 07:03:28 +0000 |
617 | +++ tests/include/mir/test/doubles/stub_client_buffer.h 2016-10-06 14:43:17 +0000 |
618 | @@ -85,7 +85,12 @@ |
619 | void set_fence(Fd, MirBufferAccess) override {} |
620 | Fd get_fence() const override { return mir::Fd(mir::Fd::invalid); } |
621 | bool wait_fence(MirBufferAccess, std::chrono::nanoseconds) override { return true; } |
622 | - void egl_image_creation_parameters(EGLenum*, EGLClientBuffer*, EGLint**) {} |
623 | + void egl_image_creation_parameters(EGLenum*, EGLClientBuffer*, EGLint** attrs) |
624 | + { |
625 | + static EGLint image_attrs[] = { EGL_NONE }; |
626 | + if (attrs) |
627 | + *attrs = image_attrs; |
628 | + } |
629 | |
630 | std::shared_ptr<MirBufferPackage> const package_; |
631 | geometry::Size size_; |
632 | |
633 | === modified file 'tests/include/mir/test/doubles/stub_host_connection.h' |
634 | --- tests/include/mir/test/doubles/stub_host_connection.h 2016-09-23 16:50:05 +0000 |
635 | +++ tests/include/mir/test/doubles/stub_host_connection.h 2016-10-06 14:43:17 +0000 |
636 | @@ -156,9 +156,14 @@ |
637 | { |
638 | void add_chain(graphics::nested::HostChain&, geometry::Displacement, geometry::Size) override {} |
639 | void add_stream(graphics::nested::HostStream&, geometry::Displacement) override {} |
640 | + MirSurfaceSpec* handle() { return nullptr; } |
641 | }; |
642 | return std::make_unique<NullSpec>(); |
643 | } |
644 | + bool supports_passthrough() |
645 | + { |
646 | + return true; |
647 | + } |
648 | }; |
649 | |
650 | struct MockHostConnection : StubHostConnection |
651 | |
652 | === modified file 'tests/integration-tests/test_buffer_scheduling.cpp' |
653 | --- tests/integration-tests/test_buffer_scheduling.cpp 2016-09-28 00:41:48 +0000 |
654 | +++ tests/integration-tests/test_buffer_scheduling.cpp 2016-10-06 14:43:17 +0000 |
655 | @@ -588,9 +588,8 @@ |
656 | BufferScheduling() |
657 | { |
658 | ipc = std::make_shared<StubIpcSystem>(); |
659 | - map = std::make_shared<mc::BufferMap>( |
660 | - std::make_shared<StubEventSink>(ipc), |
661 | - std::make_shared<mtd::StubBufferAllocator>()); |
662 | + sink = std::make_shared<StubEventSink>(ipc); |
663 | + map = std::make_shared<mc::BufferMap>(sink, std::make_shared<mtd::StubBufferAllocator>()); |
664 | auto submit_stream = std::make_shared<mc::Stream>( |
665 | drop_policy, |
666 | map, |
667 | @@ -648,6 +647,7 @@ |
668 | mcl::ClientBufferDepository depository{mt::fake_shared(client_buffer_factory), nbuffers}; |
669 | std::shared_ptr<mc::BufferStream> stream; |
670 | std::shared_ptr<StubIpcSystem> ipc; |
671 | + std::shared_ptr<mf::BufferSink> sink; |
672 | std::unique_ptr<ProducerSystem> producer; |
673 | std::unique_ptr<ConsumerSystem> consumer; |
674 | std::unique_ptr<ConsumerSystem> second_consumer; |
675 | |
676 | === modified file 'tests/mir_test_framework/any_surface.cpp' |
677 | --- tests/mir_test_framework/any_surface.cpp 2016-08-23 03:44:55 +0000 |
678 | +++ tests/mir_test_framework/any_surface.cpp 2016-10-06 14:43:17 +0000 |
679 | @@ -32,10 +32,16 @@ |
680 | |
681 | MirSurface* mtf::make_any_surface(MirConnection *connection) |
682 | { |
683 | + return mtf::make_surface(connection, mir::geometry::Size{width, height}, format); |
684 | +} |
685 | + |
686 | +MirSurface* mtf::make_surface( |
687 | + MirConnection *connection, mir::geometry::Size size, MirPixelFormat f) |
688 | +{ |
689 | using namespace std::literals::string_literals; |
690 | |
691 | auto spec = mir_connection_create_spec_for_normal_surface(connection, |
692 | - width, height, format); |
693 | + size.width.as_int(), size.height.as_int(), f); |
694 | auto surface = mir_surface_create_sync(spec); |
695 | mir_surface_spec_release(spec); |
696 | |
697 | |
698 | === modified file 'tests/mir_test_framework/headless_display_buffer_compositor_factory.cpp' |
699 | --- tests/mir_test_framework/headless_display_buffer_compositor_factory.cpp 2016-09-19 06:09:48 +0000 |
700 | +++ tests/mir_test_framework/headless_display_buffer_compositor_factory.cpp 2016-10-06 14:43:17 +0000 |
701 | @@ -17,6 +17,7 @@ |
702 | */ |
703 | |
704 | #include "mir_test_framework/headless_display_buffer_compositor_factory.h" |
705 | +#include "mir_test_framework/headless_nested_server_runner.h" |
706 | #include "mir/renderer/gl/render_target.h" |
707 | #include "mir/graphics/display_buffer.h" |
708 | #include "mir/compositor/display_buffer_compositor.h" |
709 | @@ -30,13 +31,27 @@ |
710 | namespace mc = mir::compositor; |
711 | namespace geom = mir::geometry; |
712 | |
713 | +mtf::HeadlessDisplayBufferCompositorFactory::HeadlessDisplayBufferCompositorFactory() : |
714 | + tracker(nullptr) |
715 | +{ |
716 | +} |
717 | + |
718 | +mtf::HeadlessDisplayBufferCompositorFactory::HeadlessDisplayBufferCompositorFactory( |
719 | + std::shared_ptr<PassthroughTracker> const& tracker) : |
720 | + tracker(tracker) |
721 | +{ |
722 | +} |
723 | + |
724 | std::unique_ptr<mir::compositor::DisplayBufferCompositor> |
725 | mtf::HeadlessDisplayBufferCompositorFactory::create_compositor_for(mg::DisplayBuffer& db) |
726 | { |
727 | struct HeadlessDBC : mir::compositor::DisplayBufferCompositor |
728 | { |
729 | - HeadlessDBC(mg::DisplayBuffer& db) : |
730 | + HeadlessDBC( |
731 | + mg::DisplayBuffer& db, |
732 | + std::shared_ptr<mtf::PassthroughTracker> const& tracker) : |
733 | db(db), |
734 | + tracker(tracker), |
735 | render_target(dynamic_cast<mrg::RenderTarget*>( |
736 | db.native_display_buffer())) |
737 | { |
738 | @@ -73,7 +88,11 @@ |
739 | { |
740 | auto renderlist = filter(seq, db.view_area()); |
741 | if (db.overlay(renderlist)) |
742 | + { |
743 | + if (tracker) |
744 | + tracker->note_passthrough(); |
745 | return; |
746 | + } |
747 | |
748 | // Invoke GL renderer specific functions if the DisplayBuffer supports them |
749 | if (render_target) |
750 | @@ -87,7 +106,8 @@ |
751 | render_target->swap_buffers(); |
752 | } |
753 | mg::DisplayBuffer& db; |
754 | + std::shared_ptr<PassthroughTracker> const tracker; |
755 | mrg::RenderTarget* const render_target; |
756 | }; |
757 | - return std::make_unique<HeadlessDBC>(db); |
758 | + return std::make_unique<HeadlessDBC>(db, tracker); |
759 | } |
760 | |
761 | === modified file 'tests/mir_test_framework/headless_nested_server_runner.cpp' |
762 | --- tests/mir_test_framework/headless_nested_server_runner.cpp 2016-09-19 04:16:15 +0000 |
763 | +++ tests/mir_test_framework/headless_nested_server_runner.cpp 2016-10-06 14:43:17 +0000 |
764 | @@ -22,12 +22,26 @@ |
765 | |
766 | namespace mtf = mir_test_framework; |
767 | |
768 | -mtf::HeadlessNestedServerRunner::HeadlessNestedServerRunner(std::string const& connect_string) |
769 | +mtf::HeadlessNestedServerRunner::HeadlessNestedServerRunner(std::string const& connect_string) : |
770 | + passthrough_tracker(std::make_shared<mtf::PassthroughTracker>()) |
771 | { |
772 | add_to_environment("MIR_SERVER_PLATFORM_GRAPHICS_LIB", mtf::server_platform("graphics-dummy.so").c_str()); |
773 | add_to_environment("MIR_SERVER_HOST_SOCKET", connect_string.c_str()); |
774 | - server.override_the_display_buffer_compositor_factory([] |
775 | + server.override_the_display_buffer_compositor_factory([this] |
776 | { |
777 | - return std::make_shared<mtf::HeadlessDisplayBufferCompositorFactory>(); |
778 | + return std::make_shared<mtf::HeadlessDisplayBufferCompositorFactory>(passthrough_tracker); |
779 | }); |
780 | } |
781 | + |
782 | +void mtf::PassthroughTracker::note_passthrough() |
783 | +{ |
784 | + std::unique_lock<std::mutex> lk(mutex); |
785 | + num_passthrough++; |
786 | + cv.notify_all(); |
787 | +} |
788 | + |
789 | +bool mtf::PassthroughTracker::wait_for_passthrough_frames(size_t nframes, std::chrono::milliseconds ms) |
790 | +{ |
791 | + std::unique_lock<std::mutex> lk(mutex); |
792 | + return cv.wait_for(lk, ms, [&] { return num_passthrough >= nframes; } ); |
793 | +} |
794 | |
795 | === modified file 'tests/mir_test_framework/headless_test.cpp' |
796 | --- tests/mir_test_framework/headless_test.cpp 2016-09-19 04:16:15 +0000 |
797 | +++ tests/mir_test_framework/headless_test.cpp 2016-10-06 14:43:17 +0000 |
798 | @@ -34,7 +34,7 @@ |
799 | add_to_environment("MIR_SERVER_PLATFORM_GRAPHICS_LIB", mtf::server_platform("graphics-dummy.so").c_str()); |
800 | add_to_environment("MIR_SERVER_PLATFORM_INPUT_LIB", mtf::server_platform("input-stub.so").c_str()); |
801 | add_to_environment("MIR_SERVER_ENABLE_KEY_REPEAT", "false"); |
802 | - server.override_the_display_buffer_compositor_factory([] |
803 | + server.override_the_display_buffer_compositor_factory([this] |
804 | { |
805 | return std::make_shared<mtf::HeadlessDisplayBufferCompositorFactory>(); |
806 | }); |
807 | |
808 | === modified file 'tests/unit-tests/compositor/test_client_buffers.cpp' |
809 | --- tests/unit-tests/compositor/test_client_buffers.cpp 2016-06-24 17:32:47 +0000 |
810 | +++ tests/unit-tests/compositor/test_client_buffers.cpp 2016-10-06 14:43:17 +0000 |
811 | @@ -59,11 +59,11 @@ |
812 | |
813 | struct ClientBuffers : public Test |
814 | { |
815 | - testing::NiceMock<mtd::MockEventSink> mock_sink; |
816 | + std::shared_ptr<mtd::MockEventSink> mock_sink = std::make_shared<testing::NiceMock<mtd::MockEventSink>>(); |
817 | mg::BufferProperties properties{geom::Size{42,43}, mir_pixel_format_abgr_8888, mg::BufferUsage::hardware}; |
818 | MockBufferAllocator mock_allocator; |
819 | StubBufferAllocator stub_allocator; |
820 | - mc::BufferMap map{mt::fake_shared(mock_sink), mt::fake_shared(stub_allocator)}; |
821 | + mc::BufferMap map{mock_sink, mt::fake_shared(stub_allocator)}; |
822 | }; |
823 | |
824 | TEST_F(ClientBuffers, sends_full_buffer_on_allocation) |
825 | @@ -71,8 +71,8 @@ |
826 | auto stub_buffer = std::make_shared<mtd::StubBuffer>(); |
827 | EXPECT_CALL(mock_allocator, alloc_buffer(Ref(properties))) |
828 | .WillOnce(Return(stub_buffer)); |
829 | - EXPECT_CALL(mock_sink, add_buffer(Ref(*stub_buffer))); |
830 | - mc::BufferMap map{mt::fake_shared(mock_sink), mt::fake_shared(mock_allocator)}; |
831 | + EXPECT_CALL(*mock_sink, add_buffer(Ref(*stub_buffer))); |
832 | + mc::BufferMap map{mock_sink, mt::fake_shared(mock_allocator)}; |
833 | EXPECT_THAT(map.add_buffer(properties), Eq(stub_buffer->id())); |
834 | } |
835 | |
836 | @@ -107,7 +107,7 @@ |
837 | ASSERT_THAT(stub_allocator.map, SizeIs(1)); |
838 | ASSERT_THAT(stub_allocator.ids, SizeIs(1)); |
839 | auto buffer = map[stub_allocator.ids[0]]; |
840 | - EXPECT_CALL(mock_sink, update_buffer(Ref(*buffer))); |
841 | + EXPECT_CALL(*mock_sink, update_buffer(Ref(*buffer))); |
842 | map.send_buffer(stub_allocator.ids[0]); |
843 | } |
844 | |
845 | @@ -118,7 +118,7 @@ |
846 | ASSERT_THAT(stub_allocator.ids, SizeIs(1)); |
847 | auto buffer = map[stub_allocator.ids[0]]; |
848 | |
849 | - EXPECT_CALL(mock_sink, remove_buffer(Ref(*buffer))); |
850 | + EXPECT_CALL(*mock_sink, remove_buffer(Ref(*buffer))); |
851 | map.remove_buffer(stub_allocator.ids[0]); |
852 | map.send_buffer(stub_allocator.ids[0]); |
853 | } |
854 | @@ -126,7 +126,7 @@ |
855 | TEST_F(ClientBuffers, can_remove_buffer_from_send_callback) |
856 | { |
857 | map.add_buffer(properties); |
858 | - ON_CALL(mock_sink, update_buffer(_)) |
859 | + ON_CALL(*mock_sink, update_buffer(_)) |
860 | .WillByDefault(Invoke( |
861 | [&] (mg::Buffer& buffer) |
862 | { |
863 | @@ -138,7 +138,7 @@ |
864 | |
865 | TEST_F(ClientBuffers, ignores_unknown_receive) |
866 | { |
867 | - EXPECT_CALL(mock_sink, add_buffer(_)) |
868 | + EXPECT_CALL(*mock_sink, add_buffer(_)) |
869 | .Times(1); |
870 | map.add_buffer(properties); |
871 | map.remove_buffer(stub_allocator.ids[0]); |
872 | @@ -150,8 +150,8 @@ |
873 | std::string error_msg = "a reason"; |
874 | EXPECT_CALL(mock_allocator, alloc_buffer(Ref(properties))) |
875 | .WillOnce(Throw(std::runtime_error(error_msg))); |
876 | - EXPECT_CALL(mock_sink, error_buffer(properties, StrEq(error_msg))); |
877 | - mc::BufferMap map{mt::fake_shared(mock_sink), mt::fake_shared(mock_allocator)}; |
878 | + EXPECT_CALL(*mock_sink, error_buffer(properties, StrEq(error_msg))); |
879 | + mc::BufferMap map{mock_sink, mt::fake_shared(mock_allocator)}; |
880 | EXPECT_THROW({ |
881 | map.add_buffer(properties); |
882 | }, std::runtime_error); |
883 | |
884 | === modified file 'tests/unit-tests/platforms/nested/test_buffer.cpp' |
885 | --- tests/unit-tests/platforms/nested/test_buffer.cpp 2016-09-30 12:26:56 +0000 |
886 | +++ tests/unit-tests/platforms/nested/test_buffer.cpp 2016-10-06 14:43:17 +0000 |
887 | @@ -208,6 +208,7 @@ |
888 | |
889 | EXPECT_CALL(mock_egl, eglGetCurrentDisplay()); |
890 | EXPECT_CALL(mock_egl, eglGetCurrentContext()); |
891 | + EXPECT_CALL(mock_egl, eglCreateImageKHR(_,_,_,_,_)); |
892 | EXPECT_CALL(*client_buffer, sync(mir_read, _)); |
893 | EXPECT_CALL(mock_egl, glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, _)); |
894 | |
895 | |
896 | === modified file 'tests/unit-tests/platforms/nested/test_ipc_operations.cpp' |
897 | --- tests/unit-tests/platforms/nested/test_ipc_operations.cpp 2016-09-30 12:53:35 +0000 |
898 | +++ tests/unit-tests/platforms/nested/test_ipc_operations.cpp 2016-10-06 14:43:17 +0000 |
899 | @@ -47,7 +47,6 @@ |
900 | public: |
901 | void sync(MirBufferAccess, std::chrono::nanoseconds) override {} |
902 | MirBuffer* client_handle() const override { return nullptr; } |
903 | - MirNativeBuffer* get_native_handle() override { return nullptr; } |
904 | MirGraphicsRegion get_graphics_region() override |
905 | { |
906 | return MirGraphicsRegion { 0, 0, 0, mir_pixel_format_invalid, nullptr }; |
907 | |
908 | === modified file 'tests/unit-tests/platforms/nested/test_nested_display_buffer.cpp' |
909 | --- tests/unit-tests/platforms/nested/test_nested_display_buffer.cpp 2016-09-30 12:53:35 +0000 |
910 | +++ tests/unit-tests/platforms/nested/test_nested_display_buffer.cpp 2016-10-06 14:43:17 +0000 |
911 | @@ -122,7 +122,6 @@ |
912 | geom::Size size() const override { return {}; } |
913 | MirPixelFormat format() const override { return mir_pixel_format_invalid; } |
914 | void on_ownership_notification(std::function<void()> const& f) override { fn = f; } |
915 | - MirNativeBuffer* get_native_handle() override { return nullptr; } |
916 | MirBufferPackage* package() const override { return nullptr; } |
917 | mir::Fd fence() const override { return mir::Fd{mir::Fd::invalid}; } |
918 | void set_fence(mir::Fd) override {} |
FAILED: Continuous integration, rev:3732 /mir-jenkins. ubuntu. com/job/ mir-ci/ 1862/ /mir-jenkins. ubuntu. com/job/ build-mir/ 2357/console /mir-jenkins. ubuntu. com/job/ build-0- fetch/2420/ console /mir-jenkins. ubuntu. com/job/ build-1- sourcepkg/ release= vivid+overlay/ 2412/console /mir-jenkins. ubuntu. com/job/ build-1- sourcepkg/ release= xenial+ overlay/ 2412/console /mir-jenkins. ubuntu. com/job/ build-1- sourcepkg/ release= yakkety/ 2412/console /mir-jenkins. ubuntu. com/job/ build-2- binpkg- mir/arch= amd64,compiler= clang,platform= mesa,release= yakkety/ 2386/console /mir-jenkins. ubuntu. com/job/ build-2- binpkg- mir/arch= amd64,compiler= gcc,platform= mesa,release= xenial+ overlay/ 2386/console /mir-jenkins. ubuntu. com/job/ build-2- binpkg- mir/arch= amd64,compiler= gcc,platform= mesa,release= yakkety/ 2386/console /mir-jenkins. ubuntu. com/job/ build-2- binpkg- mir/arch= cross-armhf, compiler= gcc,platform= android, release= vivid+overlay/ 2386/console /mir-jenkins. ubuntu. com/job/ build-2- binpkg- mir/arch= i386,compiler= gcc,platform= android, release= vivid+overlay/ 2386/console /mir-jenkins. ubuntu. com/job/ build-2- binpkg- mir/arch= i386,compiler= gcc,platform= mesa,release= xenial+ overlay/ 2386/console
https:/
Executed test runs:
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
Click here to trigger a rebuild: /mir-jenkins. ubuntu. com/job/ mir-ci/ 1862/rebuild
https:/