Merge lp:~kdub/mir/resettable-buffer-cb into lp:mir
- resettable-buffer-cb
- Merge into development-branch
Status: | Merged |
---|---|
Approved by: | Chris Halse Rogers |
Approved revision: | no longer in the source branch. |
Merged at revision: | 3574 |
Proposed branch: | lp:~kdub/mir/resettable-buffer-cb |
Merge into: | lp:mir |
Diff against target: |
272 lines (+106/-7) 12 files modified
src/client/atomic_callback.h (+5/-0) src/client/buffer.cpp (+9/-4) src/client/buffer.h (+6/-3) src/client/error_buffer.cpp (+1/-0) src/client/error_buffer.h (+1/-0) src/client/mir_buffer.h (+1/-0) src/client/mir_buffer_api.cpp (+13/-0) src/client/symbols.map (+1/-0) src/include/client/mir_toolkit/mir_buffer.h (+12/-0) tests/acceptance-tests/throwback/test_presentation_chain.cpp (+38/-0) tests/include/mir/test/doubles/mock_mir_buffer.h (+1/-0) tests/unit-tests/client/test_mir_buffer.cpp (+18/-0) |
To merge this branch: | bzr merge lp:~kdub/mir/resettable-buffer-cb |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Chris Halse Rogers | Approve | ||
Mir CI Bot | continuous-integration | Approve | |
Alan Griffiths | Approve | ||
Cemil Azizoglu (community) | Approve | ||
Review via email: mp+295068@code.launchpad.net |
Commit message
client: add a function to the MirBuffer set of functions that allows a user to set the callback and context of a MirBuffer. Callback and context were provided in the construction; allow changing these via the new client api function.
Description of the change
client: add a function to the MirBuffer set of functions that allows a user to set the callback and context of a MirBuffer. Callback and context were provided in the construction; allow changing these via the new client api function.
Mir CI Bot (mir-ci-bot) wrote : | # |
FAILED: Continuous integration, rev:3509
https:/
Executed test runs:
FAILURE: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
FAILURE: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
Click here to trigger a rebuild:
https:/
Alan Griffiths (alan-griffiths) wrote : | # |
I'm not entirely convinced that a recursive lock allows useful behaviour, but OK.
Chris Halse Rogers (raof) wrote : | # |
This *seems* like the sort of thing mcl::AtomicCallback is for? It doesn't currently handle changing the callback from an active callback, but that'd be a simple matter of copy-then-unlock.
Kevin DuBois (kdub) wrote : | # |
Ah yes, that class would make the code better, will use it.
Mir CI Bot (mir-ci-bot) wrote : | # |
PASSED: Continuous integration, rev:3512
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) wrote : | # |
FAILED: Autolanding.
More details in the following jenkins job:
https:/
Executed test runs:
FAILURE: https:/
None: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
Mir CI Bot (mir-ci-bot) wrote : | # |
FAILED: Continuous integration, rev:3513
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 : | # |
krillin image 515 fails to come up, retriggering.
Mir CI Bot (mir-ci-bot) wrote : | # |
PASSED: Continuous integration, rev:3513
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 : | # |
+ cb.set_callback([&, callback, context]{ (*callback)
The ‘&’ is rather strange there - you only really want to capture /this/ by value.
But that's a stylistic nit.
Preview Diff
1 | === modified file 'src/client/atomic_callback.h' |
2 | --- src/client/atomic_callback.h 2016-01-29 08:18:22 +0000 |
3 | +++ src/client/atomic_callback.h 2016-06-24 11:42:58 +0000 |
4 | @@ -35,6 +35,11 @@ |
5 | { |
6 | } |
7 | |
8 | + AtomicCallback(std::function<void(Args...)> const& fn) |
9 | + : callback(fn) |
10 | + { |
11 | + } |
12 | + |
13 | ~AtomicCallback() = default; |
14 | |
15 | void set_callback(std::function<void(Args...)> const& fn) |
16 | |
17 | === modified file 'src/client/buffer.cpp' |
18 | --- src/client/buffer.cpp 2016-06-06 11:51:31 +0000 |
19 | +++ src/client/buffer.cpp 2016-06-24 11:42:58 +0000 |
20 | @@ -28,10 +28,9 @@ |
21 | std::shared_ptr<ClientBuffer> const& buffer, |
22 | MirConnection* connection, |
23 | MirBufferUsage usage) : |
24 | - cb(cb), |
25 | - cb_context(context), |
26 | buffer_id(buffer_id), |
27 | buffer(buffer), |
28 | + cb([this, cb, context]{ (*cb)(reinterpret_cast<::MirBuffer*>(this), context); }), |
29 | owned(false), |
30 | connection(connection), |
31 | usage(usage) |
32 | @@ -60,8 +59,8 @@ |
33 | if (!owned) |
34 | owned = true; |
35 | } |
36 | - cb(reinterpret_cast<::MirBuffer*>(static_cast<mcl::MirBuffer*>(this)), cb_context); |
37 | |
38 | + cb(); |
39 | } |
40 | |
41 | void mcl::Buffer::received(MirBufferPackage const& update_package) |
42 | @@ -74,7 +73,8 @@ |
43 | buffer->update_from(update_package); |
44 | } |
45 | } |
46 | - cb(reinterpret_cast<::MirBuffer*>(static_cast<mcl::MirBuffer*>(this)), cb_context); |
47 | + |
48 | + cb(); |
49 | } |
50 | |
51 | MirGraphicsRegion mcl::Buffer::map_region() |
52 | @@ -138,3 +138,8 @@ |
53 | { |
54 | buffer->increment_age(); |
55 | } |
56 | + |
57 | +void mcl::Buffer::set_callback(mir_buffer_callback callback, void* context) |
58 | +{ |
59 | + cb.set_callback([&, callback, context]{ (*callback)(reinterpret_cast<::MirBuffer*>(this), context); }); |
60 | +} |
61 | |
62 | === modified file 'src/client/buffer.h' |
63 | --- src/client/buffer.h 2016-06-06 11:51:31 +0000 |
64 | +++ src/client/buffer.h 2016-06-24 11:42:58 +0000 |
65 | @@ -21,6 +21,7 @@ |
66 | |
67 | #include "mir_toolkit/mir_buffer.h" |
68 | #include "mir/geometry/size.h" |
69 | +#include "atomic_callback.h" |
70 | #include "mir_buffer.h" |
71 | #include <memory> |
72 | #include <chrono> |
73 | @@ -41,6 +42,7 @@ |
74 | std::shared_ptr<ClientBuffer> const& buffer, |
75 | MirConnection* connection, |
76 | MirBufferUsage usage); |
77 | + |
78 | int rpc_id() const override; |
79 | |
80 | void submitted() override; |
81 | @@ -62,11 +64,12 @@ |
82 | MirConnection* allocating_connection() const override; |
83 | |
84 | void increment_age() override; |
85 | + void set_callback(mir_buffer_callback callback, void* context) override; |
86 | private: |
87 | - mir_buffer_callback cb; |
88 | - void* cb_context; |
89 | int const buffer_id; |
90 | - std::shared_ptr<ClientBuffer> buffer; |
91 | + std::shared_ptr<ClientBuffer> const buffer; |
92 | + |
93 | + AtomicCallback<> cb; |
94 | |
95 | std::mutex mutex; |
96 | bool owned; |
97 | |
98 | === modified file 'src/client/error_buffer.cpp' |
99 | --- src/client/error_buffer.cpp 2016-05-19 13:22:43 +0000 |
100 | +++ src/client/error_buffer.cpp 2016-06-24 11:42:58 +0000 |
101 | @@ -68,3 +68,4 @@ |
102 | geom::Size mcl::ErrorBuffer::size() const THROW_EXCEPTION |
103 | MirConnection* mcl::ErrorBuffer::allocating_connection() const THROW_EXCEPTION |
104 | void mcl::ErrorBuffer::increment_age() THROW_EXCEPTION |
105 | +void mcl::ErrorBuffer::set_callback(mir_buffer_callback, void*) THROW_EXCEPTION |
106 | |
107 | === modified file 'src/client/error_buffer.h' |
108 | --- src/client/error_buffer.h 2016-05-19 13:22:43 +0000 |
109 | +++ src/client/error_buffer.h 2016-06-24 11:42:58 +0000 |
110 | @@ -47,6 +47,7 @@ |
111 | geometry::Size size() const override; |
112 | MirConnection* allocating_connection() const override; |
113 | void increment_age() override; |
114 | + void set_callback(mir_buffer_callback callback, void* context) override; |
115 | |
116 | bool valid() const; |
117 | char const* error_message() const; |
118 | |
119 | === modified file 'src/client/mir_buffer.h' |
120 | --- src/client/mir_buffer.h 2016-05-16 14:45:02 +0000 |
121 | +++ src/client/mir_buffer.h 2016-06-24 11:42:58 +0000 |
122 | @@ -52,6 +52,7 @@ |
123 | virtual geometry::Size size() const = 0; |
124 | virtual MirConnection* allocating_connection() const = 0; |
125 | virtual void increment_age() = 0; |
126 | + virtual void set_callback(mir_buffer_callback callback, void* context) = 0; |
127 | protected: |
128 | MirBuffer() = default; |
129 | MirBuffer(MirBuffer const&) = delete; |
130 | |
131 | === modified file 'src/client/mir_buffer_api.cpp' |
132 | --- src/client/mir_buffer_api.cpp 2016-06-06 11:51:31 +0000 |
133 | +++ src/client/mir_buffer_api.cpp 2016-06-24 11:42:58 +0000 |
134 | @@ -174,3 +174,16 @@ |
135 | MIR_LOG_UNCAUGHT_EXCEPTION(ex); |
136 | return mir_buffer_usage_hardware; |
137 | } |
138 | + |
139 | +void mir_buffer_set_callback( |
140 | + MirBuffer* b, mir_buffer_callback available_callback, void* available_context) |
141 | +try |
142 | +{ |
143 | + mir::require(b); |
144 | + auto buffer = reinterpret_cast<mcl::Buffer*>(b); |
145 | + buffer->set_callback(available_callback, available_context); |
146 | +} |
147 | +catch (std::exception const& ex) |
148 | +{ |
149 | + MIR_LOG_UNCAUGHT_EXCEPTION(ex); |
150 | +} |
151 | |
152 | === modified file 'src/client/symbols.map' |
153 | --- src/client/symbols.map 2016-06-09 17:42:21 +0000 |
154 | +++ src/client/symbols.map 2016-06-24 11:42:58 +0000 |
155 | @@ -366,6 +366,7 @@ |
156 | mir_buffer_wait_fence; |
157 | mir_buffer_get_native_buffer; |
158 | mir_buffer_get_graphics_region; |
159 | + mir_buffer_set_callback; |
160 | mir_buffer_release; |
161 | mir_connection_create_presentation_chain_sync; |
162 | mir_presentation_chain_is_valid; |
163 | |
164 | === modified file 'src/include/client/mir_toolkit/mir_buffer.h' |
165 | --- src/include/client/mir_toolkit/mir_buffer.h 2016-06-06 11:51:31 +0000 |
166 | +++ src/include/client/mir_toolkit/mir_buffer.h 2016-06-24 11:42:58 +0000 |
167 | @@ -50,6 +50,18 @@ |
168 | MirBufferUsage buffer_usage, |
169 | mir_buffer_callback available_callback, void* available_context); |
170 | |
171 | +/** Reassign the callback that the MirBuffer will call when the buffer is |
172 | + * available for use again |
173 | + * \param [in] buffer The buffer |
174 | + * \param [in] available_callback The callback called when the buffer |
175 | + * is available |
176 | + * \param [in] available_context The context for the available_callback |
177 | + **/ |
178 | + |
179 | +void mir_buffer_set_callback( |
180 | + MirBuffer* buffer, |
181 | + mir_buffer_callback available_callback, void* available_context); |
182 | + |
183 | /** @name Fenced Buffer content access functions. |
184 | * |
185 | * These functions will wait until it is safe to access the buffer for the given purpose. |
186 | |
187 | === modified file 'tests/acceptance-tests/throwback/test_presentation_chain.cpp' |
188 | --- tests/acceptance-tests/throwback/test_presentation_chain.cpp 2016-06-06 11:51:31 +0000 |
189 | +++ tests/acceptance-tests/throwback/test_presentation_chain.cpp 2016-06-24 11:42:58 +0000 |
190 | @@ -355,3 +355,41 @@ |
191 | EXPECT_THAT(mir_buffer_get_buffer_usage(buffer), Eq(usage)); |
192 | EXPECT_THAT(mir_buffer_get_pixel_format(buffer), Eq(format)); |
193 | } |
194 | + |
195 | +namespace |
196 | +{ |
197 | +void another_buffer_callback(MirBuffer* buffer, void* context) |
198 | +{ |
199 | + buffer_callback(buffer, context); |
200 | +} |
201 | +} |
202 | +TEST_F(PresentationChain, buffers_callback_can_be_reassigned) |
203 | +{ |
204 | + SurfaceWithChainFromStart surface(connection, size, pf); |
205 | + |
206 | + MirBufferSync second_buffer_context; |
207 | + MirBufferSync context; |
208 | + MirBufferSync another_context; |
209 | + mir_connection_allocate_buffer( |
210 | + connection, |
211 | + size.width.as_int(), size.height.as_int(), pf, usage, |
212 | + buffer_callback, &context); |
213 | + mir_connection_allocate_buffer( |
214 | + connection, |
215 | + size.width.as_int(), size.height.as_int(), pf, usage, |
216 | + buffer_callback, &second_buffer_context); |
217 | + |
218 | + ASSERT_TRUE(context.wait_for_buffer(10s)); |
219 | + ASSERT_THAT(context.buffer(), Ne(nullptr)); |
220 | + ASSERT_TRUE(second_buffer_context.wait_for_buffer(10s)); |
221 | + ASSERT_THAT(second_buffer_context.buffer(), Ne(nullptr)); |
222 | + |
223 | + mir_buffer_set_callback(context.buffer(), another_buffer_callback, &another_context); |
224 | + |
225 | + mir_presentation_chain_submit_buffer(surface.chain(), context.buffer()); |
226 | + //flush the 1st buffer out |
227 | + mir_presentation_chain_submit_buffer(surface.chain(), second_buffer_context.buffer()); |
228 | + |
229 | + ASSERT_TRUE(another_context.wait_for_buffer(10s)); |
230 | + ASSERT_THAT(another_context.buffer(), Ne(nullptr)); |
231 | +} |
232 | |
233 | === modified file 'tests/include/mir/test/doubles/mock_mir_buffer.h' |
234 | --- tests/include/mir/test/doubles/mock_mir_buffer.h 2016-05-13 18:55:24 +0000 |
235 | +++ tests/include/mir/test/doubles/mock_mir_buffer.h 2016-06-24 11:42:58 +0000 |
236 | @@ -55,6 +55,7 @@ |
237 | MOCK_CONST_METHOD0(size, geometry::Size()); |
238 | MOCK_CONST_METHOD0(allocating_connection, MirConnection*()); |
239 | MOCK_METHOD0(increment_age, void()); |
240 | + MOCK_METHOD2(set_callback, void(mir_buffer_callback callback, void* context)); |
241 | }; |
242 | |
243 | using StubMirBuffer = testing::NiceMock<MockMirBuffer>; |
244 | |
245 | === modified file 'tests/unit-tests/client/test_mir_buffer.cpp' |
246 | --- tests/unit-tests/client/test_mir_buffer.cpp 2016-06-06 11:51:31 +0000 |
247 | +++ tests/unit-tests/client/test_mir_buffer.cpp 2016-06-24 11:42:58 +0000 |
248 | @@ -177,6 +177,24 @@ |
249 | EXPECT_THAT(call_count, Eq(1)); |
250 | } |
251 | |
252 | +TEST_F(MirBufferTest, callback_called_after_change_when_available_from_creation) |
253 | +{ |
254 | + int call_count = 0; |
255 | + mcl::Buffer buffer(cb, nullptr, buffer_id, mock_client_buffer, nullptr, usage); |
256 | + buffer.set_callback(cb, &call_count); |
257 | + buffer.received(); |
258 | + EXPECT_THAT(call_count, Eq(1)); |
259 | +} |
260 | + |
261 | +TEST_F(MirBufferTest, callback_called_after_change_when_available_from_server_return) |
262 | +{ |
263 | + int call_count = 0; |
264 | + mcl::Buffer buffer(cb, nullptr, buffer_id, mock_client_buffer, nullptr, usage); |
265 | + buffer.set_callback(cb, &call_count); |
266 | + buffer.received(update_message); |
267 | + EXPECT_THAT(call_count, Eq(1)); |
268 | +} |
269 | + |
270 | TEST_F(MirBufferTest, updates_package_when_server_returns) |
271 | { |
272 | EXPECT_CALL(*mock_client_buffer, update_from(Ref(update_message))); |
LGTM.
Nit : Line #110 (extraneous space) and line #116 (split at the comma) could use better formatting. set_callback(
+/** Reassign the callback that the MirBuffer will call when the buffer is
107 + * available for use again
108 + * \param [in] buffer The buffer
109 + * \param [in] available_callback The callback called when the buffer
110 + * is available
111 + * \param [in] available_context The context for the available_callback
112 + **/
113 +
114 +void mir_buffer_
115 + MirBuffer* buffer,
116 + mir_buffer_callback available_callback, void* available_context);