Merge lp:~kdub/mir/n10-support into lp:mir
- n10-support
- Merge into development-branch
Status: | Merged |
---|---|
Approved by: | Daniel van Vugt |
Approved revision: | no longer in the source branch. |
Merged at revision: | 1228 |
Proposed branch: | lp:~kdub/mir/n10-support |
Merge into: | lp:mir |
Diff against target: |
2330 lines (+686/-615) 36 files modified
include/shared/mir/graphics/android/mir_native_window.h (+1/-0) include/test/mir_test_doubles/mock_display_device.h (+1/-2) include/test/mir_test_doubles/mock_framebuffer_bundle.h (+50/-0) include/test/mir_test_doubles/mock_hwc_composer_device_1.h (+20/-4) include/test/mir_test_doubles/stub_display_device.h (+4/-2) src/server/graphics/android/CMakeLists.txt (+1/-1) src/server/graphics/android/android_buffer_allocator.cpp (+1/-1) src/server/graphics/android/android_graphic_buffer_allocator.h (+1/-1) src/server/graphics/android/display_device.h (+4/-3) src/server/graphics/android/fb_device.cpp (+18/-13) src/server/graphics/android/fb_device.h (+5/-1) src/server/graphics/android/framebuffer_bundle.h (+16/-11) src/server/graphics/android/framebuffers.cpp (+116/-10) src/server/graphics/android/framebuffers.h (+18/-13) src/server/graphics/android/graphic_buffer_allocator.h (+1/-1) src/server/graphics/android/hwc10_device.cpp (+6/-12) src/server/graphics/android/hwc10_device.h (+6/-4) src/server/graphics/android/hwc11_device.cpp (+27/-81) src/server/graphics/android/hwc11_device.h (+8/-5) src/server/graphics/android/hwc_layerlist.cpp (+8/-0) src/server/graphics/android/hwc_layerlist.h (+3/-0) src/server/graphics/android/resource_factory.cpp (+8/-14) src/server/graphics/android/server_render_window.cpp (+6/-10) src/server/graphics/android/server_render_window.h (+1/-4) src/shared/graphics/android/mir_native_window.cpp (+9/-3) tests/integration-tests/client/test_client_render.cpp (+4/-4) tests/integration-tests/graphics/android/test_display_integration.cpp (+7/-0) tests/unit-tests/client/android/test_android_native_window.cpp (+7/-3) tests/unit-tests/graphics/android/test_fb_device.cpp (+31/-59) tests/unit-tests/graphics/android/test_fb_simple_swapper.cpp (+179/-106) tests/unit-tests/graphics/android/test_hwc10_device.cpp (+17/-15) tests/unit-tests/graphics/android/test_hwc11_device.cpp (+62/-166) tests/unit-tests/graphics/android/test_hwc_device.cpp (+2/-2) tests/unit-tests/graphics/android/test_hwc_layerlist.cpp (+24/-3) tests/unit-tests/graphics/android/test_resource_factory.cpp (+2/-33) tests/unit-tests/graphics/android/test_server_interpreter.cpp (+12/-28) |
To merge this branch: | bzr merge lp:~kdub/mir/n10-support |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Daniel van Vugt | manual testing | Approve | |
PS Jenkins bot (community) | continuous-integration | Approve | |
Alexandros Frantzis (community) | Approve | ||
Alan Griffiths | Approve | ||
Review via email: mp+195323@code.launchpad.net |
Commit message
graphics: android:
1) change hwc1.1 to make use of sync fences during the compositor's gl renderloop. Note that we no longer wait for the render to complete, we pass this responsibility to the driver and the kernel.
2) support nexus 10
Description of the change
graphics: android:
1) change hwc1.1 to make use of sync fences during the compositor's gl renderloop. Note that we no longer wait for the render to complete, we pass this responsibility to the driver and the kernel.
2) support nexus 10
The big change in this review is the management of the android framebuffers state tracking. Previously, we simply had the framebuffers be owned in the dubiously-named FBSimpleSwapper, which was owned by the EGLNativeWindow
Furthermore, buffer fences are passed from the GL driver right to the HWC, and then from the HWC right to the GL driver. We never have to wait in mir for the GL fences in the composition/post new frame loop. This lets the mir better parallelize the gpu and cpu without waiting as much.
The astute reviewer might note that mga::DisplayDevice has become quite a strange... All the implementations of mga::DisplayDevice take a mga::Framebuffe
NB: i still haven't gotten the unity-mir stack tested on top of these changes on both the nexus 4 and nexus 10. The basic test programs look good though. Please don't land until we can get unity tested.
NB: this will let us drop the patches to hwc on the nexus 4 (that codepath is no longer hit)
Alexandros Frantzis (afrantzis) wrote : | # |
> I don't understand all the detail but I'm happy with what I do follow.
Likewise.
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:1245
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
Click here to trigger a rebuild:
http://
Daniel van Vugt (vanvugt) wrote : | # |
It's hard to judge the GL performance improvement as we're limited to vsync on Android. But confirmed software framerates are improved dramatically by this proposal. Bug 1252173 fixed!
I expect GL will benefit similarly.
Preview Diff
1 | === modified file 'include/shared/mir/graphics/android/mir_native_window.h' |
2 | --- include/shared/mir/graphics/android/mir_native_window.h 2013-10-28 16:35:51 +0000 |
3 | +++ include/shared/mir/graphics/android/mir_native_window.h 2013-11-14 23:10:20 +0000 |
4 | @@ -39,6 +39,7 @@ |
5 | int query(int key, int* value) const; |
6 | int perform(int key, va_list args ); |
7 | int dequeueBuffer(struct ANativeWindowBuffer** buffer, int* fence); |
8 | + int dequeueBufferAndWait(struct ANativeWindowBuffer** buffer); |
9 | int queueBuffer(struct ANativeWindowBuffer* buffer, int fence); |
10 | int cancelBuffer(struct ANativeWindowBuffer* buffer, int fence); |
11 | int setSwapInterval(int interval); |
12 | |
13 | === modified file 'include/test/mir_test_doubles/mock_display_device.h' |
14 | --- include/test/mir_test_doubles/mock_display_device.h 2013-10-25 16:39:50 +0000 |
15 | +++ include/test/mir_test_doubles/mock_display_device.h 2013-11-14 23:10:20 +0000 |
16 | @@ -34,8 +34,7 @@ |
17 | ~MockDisplayDevice() noexcept {} |
18 | MOCK_CONST_METHOD0(display_size, geometry::Size()); |
19 | MOCK_CONST_METHOD0(display_format, geometry::PixelFormat()); |
20 | - MOCK_CONST_METHOD0(number_of_framebuffers_available, unsigned int()); |
21 | - MOCK_METHOD1(set_next_frontbuffer, void(std::shared_ptr<mir::graphics::Buffer> const&)); |
22 | + MOCK_METHOD0(buffer_for_render, std::shared_ptr<graphics::Buffer>()); |
23 | MOCK_METHOD1(sync_to_display, void(bool)); |
24 | MOCK_METHOD1(mode, void(MirPowerMode)); |
25 | MOCK_METHOD2(commit_frame, void(EGLDisplay, EGLSurface)); |
26 | |
27 | === added file 'include/test/mir_test_doubles/mock_framebuffer_bundle.h' |
28 | --- include/test/mir_test_doubles/mock_framebuffer_bundle.h 1970-01-01 00:00:00 +0000 |
29 | +++ include/test/mir_test_doubles/mock_framebuffer_bundle.h 2013-11-14 23:10:20 +0000 |
30 | @@ -0,0 +1,50 @@ |
31 | +/* |
32 | + * Copyright © 2013 Canonical Ltd. |
33 | + * |
34 | + * This program is free software: you can redistribute it and/or modify |
35 | + * it under the terms of the GNU General Public License version 3 as |
36 | + * published by the Free Software Foundation. |
37 | + * |
38 | + * This program is distributed in the hope that it will be useful, |
39 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
40 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
41 | + * GNU General Public License for more details. |
42 | + * |
43 | + * You should have received a copy of the GNU General Public License |
44 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
45 | + * |
46 | + * Authored by: Kevin DuBois <kevin.dubois@canonical.com> |
47 | + */ |
48 | + |
49 | +#ifndef MIR_TEST_DOUBLES_MOCK_FRAMEBUFFER_BUNDLE_H_ |
50 | +#define MIR_TEST_DOUBLES_MOCK_FRAMEBUFFER_BUNDLE_H_ |
51 | + |
52 | +#include "src/server/graphics/android/framebuffer_bundle.h" |
53 | +#include "stub_buffer.h" |
54 | +#include <gmock/gmock.h> |
55 | + |
56 | +namespace mir |
57 | +{ |
58 | +namespace test |
59 | +{ |
60 | +namespace doubles |
61 | +{ |
62 | + |
63 | +struct MockFBBundle : public graphics::android::FramebufferBundle |
64 | +{ |
65 | + MockFBBundle() |
66 | + { |
67 | + using namespace testing; |
68 | + ON_CALL(*this, last_rendered_buffer()) |
69 | + .WillByDefault(Return(std::make_shared<StubBuffer>())); |
70 | + } |
71 | + MOCK_METHOD0(fb_format, geometry::PixelFormat()); |
72 | + MOCK_METHOD0(fb_size, geometry::Size()); |
73 | + MOCK_METHOD0(buffer_for_render, std::shared_ptr<graphics::Buffer>()); |
74 | + MOCK_METHOD0(last_rendered_buffer, std::shared_ptr<graphics::Buffer>()); |
75 | +}; |
76 | +} |
77 | +} |
78 | +} |
79 | + |
80 | +#endif /* MIR_TEST_DOUBLES_MOCK_FRAMEBUFFER_BUNDLE_H_ */ |
81 | |
82 | === modified file 'include/test/mir_test_doubles/mock_hwc_composer_device_1.h' |
83 | --- include/test/mir_test_doubles/mock_hwc_composer_device_1.h 2013-11-08 23:29:35 +0000 |
84 | +++ include/test/mir_test_doubles/mock_hwc_composer_device_1.h 2013-11-14 23:10:20 +0000 |
85 | @@ -64,19 +64,34 @@ |
86 | return 0; |
87 | } |
88 | |
89 | + void hwc_set_return_fence(int fence) |
90 | + { |
91 | + fb_fence = fence; |
92 | + } |
93 | + |
94 | int save_last_prepare_arguments(struct hwc_composer_device_1 *, size_t, hwc_display_contents_1_t** displays) |
95 | { |
96 | return save_args(&display0_prepare_content, displays); |
97 | } |
98 | |
99 | - int save_last_set_arguments(struct hwc_composer_device_1 *, size_t, hwc_display_contents_1_t** displays) |
100 | + int save_last_set_arguments( |
101 | + struct hwc_composer_device_1 *, size_t, hwc_display_contents_1_t** displays) |
102 | { |
103 | - hwc_display_contents_1_t* display = *displays; |
104 | - for(auto i = 0u; i < display->numHwLayers; i++) |
105 | + hwc_display_contents_1_t* primary_display = *displays; |
106 | + if (!primary_display) |
107 | + return -1; |
108 | + |
109 | + for(auto i = 0u; i < primary_display->numHwLayers; i++) |
110 | { |
111 | - set_layerlist.push_back(display->hwLayers[i]); |
112 | + set_layerlist.push_back(primary_display->hwLayers[i]); |
113 | set_layerlist.back().visibleRegionScreen = {0, nullptr}; |
114 | } |
115 | + |
116 | + if (primary_display->hwLayers) |
117 | + { |
118 | + primary_display->hwLayers[1].releaseFenceFd = fb_fence; |
119 | + } |
120 | + |
121 | return save_args(&display0_set_content, displays); |
122 | } |
123 | |
124 | @@ -129,6 +144,7 @@ |
125 | hwc_display_contents_1_t display0_set_content; |
126 | std::vector<hwc_layer_1> set_layerlist; |
127 | hwc_display_contents_1_t display0_prepare_content; |
128 | + int fb_fence; |
129 | }; |
130 | |
131 | } |
132 | |
133 | === modified file 'include/test/mir_test_doubles/stub_display_device.h' |
134 | --- include/test/mir_test_doubles/stub_display_device.h 2013-10-25 16:39:50 +0000 |
135 | +++ include/test/mir_test_doubles/stub_display_device.h 2013-11-14 23:10:20 +0000 |
136 | @@ -43,11 +43,13 @@ |
137 | |
138 | geometry::Size display_size() const { return sz; } |
139 | geometry::PixelFormat display_format() const { return geometry::PixelFormat::abgr_8888; } |
140 | - unsigned int number_of_framebuffers_available() const { return 0; } |
141 | - void set_next_frontbuffer(std::shared_ptr<mir::graphics::Buffer> const&) {} |
142 | void sync_to_display(bool) {} |
143 | void mode(MirPowerMode) {} |
144 | void commit_frame(EGLDisplay, EGLSurface) {} |
145 | + std::shared_ptr<graphics::Buffer> buffer_for_render() |
146 | + { |
147 | + return nullptr; |
148 | + } |
149 | |
150 | private: |
151 | geometry::Size sz; |
152 | |
153 | === modified file 'src/server/graphics/android/CMakeLists.txt' |
154 | --- src/server/graphics/android/CMakeLists.txt 2013-11-07 01:34:35 +0000 |
155 | +++ src/server/graphics/android/CMakeLists.txt 2013-11-14 23:10:20 +0000 |
156 | @@ -22,7 +22,7 @@ |
157 | android_alloc_adaptor.cpp |
158 | server_render_window.cpp |
159 | resource_factory.cpp |
160 | - fb_simple_swapper.cpp |
161 | + framebuffers.cpp |
162 | fb_device.cpp |
163 | internal_client_window.cpp |
164 | interpreter_cache.cpp |
165 | |
166 | === modified file 'src/server/graphics/android/android_buffer_allocator.cpp' |
167 | --- src/server/graphics/android/android_buffer_allocator.cpp 2013-10-15 08:53:10 +0000 |
168 | +++ src/server/graphics/android/android_buffer_allocator.cpp 2013-11-14 23:10:20 +0000 |
169 | @@ -77,7 +77,7 @@ |
170 | return alloc_buffer_platform(buffer_properties.size, buffer_properties.format, usage); |
171 | } |
172 | |
173 | -std::shared_ptr<mga::Buffer> mga::AndroidGraphicBufferAllocator::alloc_buffer_platform( |
174 | +std::shared_ptr<mg::Buffer> mga::AndroidGraphicBufferAllocator::alloc_buffer_platform( |
175 | geom::Size sz, geom::PixelFormat pf, mga::BufferUsage use) |
176 | { |
177 | auto native_handle = alloc_device->alloc_buffer(sz, pf, use); |
178 | |
179 | === modified file 'src/server/graphics/android/android_graphic_buffer_allocator.h' |
180 | --- src/server/graphics/android/android_graphic_buffer_allocator.h 2013-08-28 03:41:48 +0000 |
181 | +++ src/server/graphics/android/android_graphic_buffer_allocator.h 2013-11-14 23:10:20 +0000 |
182 | @@ -48,7 +48,7 @@ |
183 | std::shared_ptr<graphics::Buffer> alloc_buffer( |
184 | graphics::BufferProperties const& buffer_properties); |
185 | |
186 | - std::shared_ptr<Buffer> alloc_buffer_platform( |
187 | + std::shared_ptr<graphics::Buffer> alloc_buffer_platform( |
188 | geometry::Size sz, geometry::PixelFormat pf, BufferUsage use); |
189 | |
190 | std::vector<geometry::PixelFormat> supported_pixel_formats(); |
191 | |
192 | === modified file 'src/server/graphics/android/display_device.h' |
193 | --- src/server/graphics/android/display_device.h 2013-10-25 16:39:50 +0000 |
194 | +++ src/server/graphics/android/display_device.h 2013-11-14 23:10:20 +0000 |
195 | @@ -40,12 +40,13 @@ |
196 | public: |
197 | virtual ~DisplayDevice() = default; |
198 | |
199 | + //TODO: (kdub) these 4 functions should be removed from this interface. The classes currently using |
200 | + // these four functions will start to use mga::FramebufferBundle. |
201 | virtual geometry::Size display_size() const = 0; |
202 | virtual geometry::PixelFormat display_format() const = 0; |
203 | - virtual unsigned int number_of_framebuffers_available() const = 0; |
204 | - |
205 | - virtual void set_next_frontbuffer(std::shared_ptr<graphics::Buffer> const& buffer) = 0; |
206 | + virtual std::shared_ptr<graphics::Buffer> buffer_for_render() = 0; |
207 | virtual void sync_to_display(bool sync) = 0; |
208 | + |
209 | virtual void mode(MirPowerMode mode) = 0; |
210 | virtual void commit_frame(EGLDisplay dpy, EGLSurface sur) = 0; |
211 | |
212 | |
213 | === modified file 'src/server/graphics/android/fb_device.cpp' |
214 | --- src/server/graphics/android/fb_device.cpp 2013-10-24 19:10:34 +0000 |
215 | +++ src/server/graphics/android/fb_device.cpp 2013-11-14 23:10:20 +0000 |
216 | @@ -21,6 +21,7 @@ |
217 | #include "mir/graphics/android/native_buffer.h" |
218 | #include "android_format_conversion-inl.h" |
219 | #include "fb_device.h" |
220 | +#include "framebuffer_bundle.h" |
221 | #include "buffer.h" |
222 | |
223 | #include <boost/throw_exception.hpp> |
224 | @@ -30,8 +31,11 @@ |
225 | namespace mga=mir::graphics::android; |
226 | namespace geom=mir::geometry; |
227 | |
228 | -mga::FBDevice::FBDevice(std::shared_ptr<framebuffer_device_t> const& fbdev) |
229 | - : fb_device(fbdev) |
230 | +mga::FBDevice::FBDevice( |
231 | + std::shared_ptr<framebuffer_device_t> const& fbdev, |
232 | + std::shared_ptr<FramebufferBundle> const& bundle) |
233 | + : fb_device(fbdev), |
234 | + fb_bundle(bundle) |
235 | { |
236 | if (fb_device->setSwapInterval) |
237 | { |
238 | @@ -39,15 +43,8 @@ |
239 | } |
240 | } |
241 | |
242 | -void mga::FBDevice::set_next_frontbuffer(std::shared_ptr<mg::Buffer> const& buffer) |
243 | +void mga::FBDevice::set_next_frontbuffer(std::shared_ptr<mg::Buffer> const&) |
244 | { |
245 | - auto native_buffer = buffer->native_buffer_handle(); |
246 | - native_buffer->wait_for_content(); |
247 | - |
248 | - if (fb_device->post(fb_device.get(), native_buffer->handle()) != 0) |
249 | - { |
250 | - BOOST_THROW_EXCEPTION(std::runtime_error("error posting with fb device")); |
251 | - } |
252 | } |
253 | |
254 | geom::Size mga::FBDevice::display_size() const |
255 | @@ -60,10 +57,9 @@ |
256 | return to_mir_format(fb_device->format); |
257 | } |
258 | |
259 | -unsigned int mga::FBDevice::number_of_framebuffers_available() const |
260 | +std::shared_ptr<mg::Buffer> mga::FBDevice::buffer_for_render() |
261 | { |
262 | - auto fb_num = static_cast<unsigned int>(fb_device->numFramebuffers); |
263 | - return std::max(2u, fb_num); |
264 | + return fb_bundle->buffer_for_render(); |
265 | } |
266 | |
267 | void mga::FBDevice::sync_to_display(bool sync) |
268 | @@ -87,6 +83,15 @@ |
269 | { |
270 | BOOST_THROW_EXCEPTION(std::runtime_error("eglSwapBuffers failure\n")); |
271 | } |
272 | + |
273 | + auto buffer = fb_bundle->last_rendered_buffer(); |
274 | + auto native_buffer = buffer->native_buffer_handle(); |
275 | + native_buffer->wait_for_content(); |
276 | + |
277 | + if (fb_device->post(fb_device.get(), native_buffer->handle()) != 0) |
278 | + { |
279 | + BOOST_THROW_EXCEPTION(std::runtime_error("error posting with fb device")); |
280 | + } |
281 | } |
282 | |
283 | void mga::FBDevice::mode(MirPowerMode mode) |
284 | |
285 | === modified file 'src/server/graphics/android/fb_device.h' |
286 | --- src/server/graphics/android/fb_device.h 2013-10-25 16:39:50 +0000 |
287 | +++ src/server/graphics/android/fb_device.h 2013-11-14 23:10:20 +0000 |
288 | @@ -29,16 +29,19 @@ |
289 | { |
290 | namespace android |
291 | { |
292 | +class FramebufferBundle; |
293 | |
294 | class FBDevice : public DisplayDevice |
295 | { |
296 | public: |
297 | - FBDevice(std::shared_ptr<framebuffer_device_t> const&); |
298 | + FBDevice(std::shared_ptr<framebuffer_device_t> const& fbdev, |
299 | + std::shared_ptr<FramebufferBundle> const& bundle); |
300 | |
301 | geometry::Size display_size() const; |
302 | geometry::PixelFormat display_format() const; |
303 | unsigned int number_of_framebuffers_available() const; |
304 | |
305 | + std::shared_ptr<graphics::Buffer> buffer_for_render(); |
306 | void set_next_frontbuffer(std::shared_ptr<graphics::Buffer> const& buffer); |
307 | void sync_to_display(bool sync); |
308 | void mode(MirPowerMode mode); |
309 | @@ -47,6 +50,7 @@ |
310 | |
311 | private: |
312 | std::shared_ptr<framebuffer_device_t> const fb_device; |
313 | + std::shared_ptr<FramebufferBundle> const fb_bundle; |
314 | }; |
315 | |
316 | } |
317 | |
318 | === renamed file 'src/server/graphics/android/fb_swapper.h' => 'src/server/graphics/android/framebuffer_bundle.h' |
319 | --- src/server/graphics/android/fb_swapper.h 2013-10-15 08:53:10 +0000 |
320 | +++ src/server/graphics/android/framebuffer_bundle.h 2013-11-14 23:10:20 +0000 |
321 | @@ -17,9 +17,11 @@ |
322 | * Kevin DuBois <kevin.dubois@canonical.com> |
323 | */ |
324 | |
325 | -#ifndef MIR_GRAPHICS_ANDROID_FB_SWAPPER_H_ |
326 | -#define MIR_GRAPHICS_ANDROID_FB_SWAPPER_H_ |
327 | +#ifndef MIR_GRAPHICS_ANDROID_FRAMEBUFFER_BUNDLE_H_ |
328 | +#define MIR_GRAPHICS_ANDROID_FRAMEBUFFER_BUNDLE_H_ |
329 | |
330 | +#include "mir/geometry/pixel_format.h" |
331 | +#include "mir/geometry/size.h" |
332 | #include <memory> |
333 | |
334 | namespace mir |
335 | @@ -31,20 +33,23 @@ |
336 | namespace android |
337 | { |
338 | |
339 | -class FBSwapper{ |
340 | +class FramebufferBundle{ |
341 | public: |
342 | - virtual ~FBSwapper() = default; |
343 | - |
344 | - virtual std::shared_ptr<Buffer> compositor_acquire() = 0; |
345 | - virtual void compositor_release(std::shared_ptr<Buffer> const& released_buffer) = 0; |
346 | + virtual ~FramebufferBundle() = default; |
347 | + |
348 | + virtual geometry::PixelFormat fb_format() = 0; |
349 | + virtual geometry::Size fb_size() = 0; |
350 | + virtual std::shared_ptr<Buffer> buffer_for_render() = 0; |
351 | + virtual std::shared_ptr<Buffer> last_rendered_buffer() = 0; |
352 | + |
353 | protected: |
354 | - FBSwapper() = default; |
355 | - FBSwapper(FBSwapper const&) = delete; |
356 | - FBSwapper& operator=(FBSwapper const&) = delete; |
357 | + FramebufferBundle() = default; |
358 | + FramebufferBundle(FramebufferBundle const&) = delete; |
359 | + FramebufferBundle& operator=(FramebufferBundle const&) = delete; |
360 | }; |
361 | |
362 | } |
363 | } |
364 | } |
365 | |
366 | -#endif /* MIR_GRAPHICS_ANDROID_FB_SWAPPER_H_ */ |
367 | +#endif /* MIR_GRAPHICS_ANDROID_FRAMEBUFFER_BUNDLE_H_ */ |
368 | |
369 | === renamed file 'src/server/graphics/android/fb_simple_swapper.cpp' => 'src/server/graphics/android/framebuffers.cpp' |
370 | --- src/server/graphics/android/fb_simple_swapper.cpp 2013-08-28 03:41:48 +0000 |
371 | +++ src/server/graphics/android/framebuffers.cpp 2013-11-14 23:10:20 +0000 |
372 | @@ -17,31 +17,137 @@ |
373 | * Kevin DuBois <kevin.dubois@canonical.com> |
374 | */ |
375 | |
376 | -#include "fb_simple_swapper.h" |
377 | +#include "framebuffers.h" |
378 | +#include "android_format_conversion-inl.h" |
379 | +#include "graphic_buffer_allocator.h" |
380 | |
381 | +#include <algorithm> |
382 | +#include <EGL/egl.h> |
383 | +#include <EGL/eglext.h> |
384 | #include <boost/throw_exception.hpp> |
385 | #include <stdexcept> |
386 | |
387 | namespace mg = mir::graphics; |
388 | namespace mga=mir::graphics::android; |
389 | - |
390 | -std::shared_ptr<mg::Buffer> mga::FBSimpleSwapper::compositor_acquire() |
391 | +namespace geom=mir::geometry; |
392 | + |
393 | +namespace |
394 | +{ |
395 | +geom::PixelFormat determine_hwc11_fb_format() |
396 | +{ |
397 | + static EGLint const fb_egl_config_attr [] = |
398 | + { |
399 | + EGL_SURFACE_TYPE, EGL_WINDOW_BIT, |
400 | + EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, |
401 | + EGL_FRAMEBUFFER_TARGET_ANDROID, EGL_TRUE, |
402 | + EGL_NONE |
403 | + }; |
404 | + |
405 | + EGLConfig fb_egl_config; |
406 | + int matching_configs; |
407 | + EGLint major, minor; |
408 | + auto egl_display = eglGetDisplay(EGL_DEFAULT_DISPLAY); |
409 | + eglInitialize(egl_display, &major, &minor); |
410 | + eglChooseConfig(egl_display, fb_egl_config_attr, &fb_egl_config, 1, &matching_configs); |
411 | + |
412 | + geom::PixelFormat fb_format; |
413 | + if (matching_configs) |
414 | + { |
415 | + int visual_id; |
416 | + eglGetConfigAttrib(egl_display, fb_egl_config, EGL_NATIVE_VISUAL_ID, &visual_id); |
417 | + fb_format = mga::to_mir_format(visual_id); |
418 | + } |
419 | + else |
420 | + { |
421 | + //we couldn't figure out the fb format via egl. In this case, we |
422 | + //assume abgr_8888. HWC api really should provide this information directly. |
423 | + fb_format = geom::PixelFormat::abgr_8888; |
424 | + } |
425 | + |
426 | + eglTerminate(egl_display); |
427 | + return fb_format; |
428 | +} |
429 | + |
430 | +geom::Size determine_hwc11_size( |
431 | + std::shared_ptr<hwc_composer_device_1> const& hwc_device) |
432 | +{ |
433 | + size_t num_configs = 1; |
434 | + uint32_t primary_display_config; |
435 | + auto rc = hwc_device->getDisplayConfigs(hwc_device.get(), HWC_DISPLAY_PRIMARY, &primary_display_config, &num_configs); |
436 | + if (rc != 0) |
437 | + { |
438 | + BOOST_THROW_EXCEPTION(std::runtime_error("could not determine hwc display config")); |
439 | + } |
440 | + static uint32_t size_request[3] = { HWC_DISPLAY_WIDTH, |
441 | + HWC_DISPLAY_HEIGHT, |
442 | + HWC_DISPLAY_NO_ATTRIBUTE}; |
443 | + |
444 | + int size_values[2]; |
445 | + hwc_device->getDisplayAttributes(hwc_device.get(), HWC_DISPLAY_PRIMARY, primary_display_config, |
446 | + size_request, size_values); |
447 | + |
448 | + return {size_values[0], size_values[1]}; |
449 | +} |
450 | +} |
451 | + |
452 | +mga::Framebuffers::Framebuffers( |
453 | + std::shared_ptr<mga::GraphicBufferAllocator> const& buffer_allocator, |
454 | + std::shared_ptr<hwc_composer_device_1> const& hwc) |
455 | + : format(determine_hwc11_fb_format()), |
456 | + size(determine_hwc11_size(hwc)) |
457 | +{ |
458 | + for(auto i = 0u; i < 2; i++) |
459 | + { |
460 | + queue.push(buffer_allocator->alloc_buffer_platform(size, format, mga::BufferUsage::use_framebuffer_gles)); |
461 | + } |
462 | +} |
463 | + |
464 | +mga::Framebuffers::Framebuffers( |
465 | + std::shared_ptr<mga::GraphicBufferAllocator> const& buffer_allocator, |
466 | + std::shared_ptr<framebuffer_device_t> const& fb) |
467 | + : format{mga::to_mir_format(fb->format)}, |
468 | + size({fb->width, fb->height}) |
469 | +{ |
470 | + //guarantee always 2 fb's allocated |
471 | + auto fb_num = static_cast<unsigned int>(fb->numFramebuffers); |
472 | + fb_num = std::max(2u, fb_num); |
473 | + for(auto i = 0u; i < fb_num; i++) |
474 | + { |
475 | + queue.push(buffer_allocator->alloc_buffer_platform(size, format, mga::BufferUsage::use_framebuffer_gles)); |
476 | + } |
477 | +} |
478 | + |
479 | +geom::PixelFormat mga::Framebuffers::fb_format() |
480 | +{ |
481 | + return format; |
482 | +} |
483 | +geom::Size mga::Framebuffers::fb_size() |
484 | +{ |
485 | + return size; |
486 | +} |
487 | + |
488 | +std::shared_ptr<mg::Buffer> mga::Framebuffers::buffer_for_render() |
489 | { |
490 | std::unique_lock<std::mutex> lk(queue_lock); |
491 | - while (queue.empty()) |
492 | + while (buffer_being_rendered) |
493 | { |
494 | cv.wait(lk); |
495 | } |
496 | |
497 | - auto buffer = queue.front(); |
498 | + buffer_being_rendered = queue.front(); |
499 | queue.pop(); |
500 | - return buffer; |
501 | + return std::shared_ptr<mg::Buffer>(buffer_being_rendered.get(), |
502 | + [this](mg::Buffer*) |
503 | + { |
504 | + std::unique_lock<std::mutex> lk(queue_lock); |
505 | + queue.push(buffer_being_rendered); |
506 | + buffer_being_rendered.reset(); |
507 | + cv.notify_all(); |
508 | + }); |
509 | } |
510 | |
511 | -void mga::FBSimpleSwapper::compositor_release(std::shared_ptr<mg::Buffer> const& released_buffer) |
512 | +std::shared_ptr<mg::Buffer> mga::Framebuffers::last_rendered_buffer() |
513 | { |
514 | std::unique_lock<std::mutex> lk(queue_lock); |
515 | - |
516 | - queue.push(released_buffer); |
517 | - cv.notify_all(); |
518 | + return queue.back(); |
519 | } |
520 | |
521 | === renamed file 'src/server/graphics/android/fb_simple_swapper.h' => 'src/server/graphics/android/framebuffers.h' |
522 | --- src/server/graphics/android/fb_simple_swapper.h 2013-08-28 03:41:48 +0000 |
523 | +++ src/server/graphics/android/framebuffers.h 2013-11-14 23:10:20 +0000 |
524 | @@ -20,8 +20,11 @@ |
525 | #ifndef MIR_GRAPHICS_ANDROID_FB_SIMPLE_SWAPPER_H_ |
526 | #define MIR_GRAPHICS_ANDROID_FB_SIMPLE_SWAPPER_H_ |
527 | |
528 | -#include "fb_swapper.h" |
529 | +#include "framebuffer_bundle.h" |
530 | |
531 | +#include <hardware/gralloc.h> |
532 | +#include <hardware/fb.h> |
533 | +#include <hardware/hwcomposer.h> |
534 | #include <condition_variable> |
535 | #include <queue> |
536 | #include <vector> |
537 | @@ -33,26 +36,28 @@ |
538 | { |
539 | namespace android |
540 | { |
541 | +class GraphicBufferAllocator; |
542 | |
543 | -class FBSimpleSwapper : public FBSwapper |
544 | +class Framebuffers : public FramebufferBundle |
545 | { |
546 | public: |
547 | - template<typename BufferPtrContainer> |
548 | - explicit FBSimpleSwapper(BufferPtrContainer const& buffer_list) |
549 | - { |
550 | - for (auto& buffer : buffer_list) |
551 | - { |
552 | - queue.push(buffer); |
553 | - } |
554 | - } |
555 | + Framebuffers(std::shared_ptr<GraphicBufferAllocator> const& buffer_allocator, |
556 | + std::shared_ptr<hwc_composer_device_1> const& hwc); |
557 | + Framebuffers(std::shared_ptr<GraphicBufferAllocator> const& buffer_allocator, |
558 | + std::shared_ptr<framebuffer_device_t> const& fb); |
559 | |
560 | - std::shared_ptr<Buffer> compositor_acquire(); |
561 | - void compositor_release(std::shared_ptr<Buffer> const& released_buffer); |
562 | + geometry::PixelFormat fb_format(); |
563 | + geometry::Size fb_size(); |
564 | + std::shared_ptr<Buffer> buffer_for_render(); |
565 | + std::shared_ptr<Buffer> last_rendered_buffer(); |
566 | |
567 | private: |
568 | + geometry::PixelFormat const format; |
569 | + geometry::Size const size; |
570 | + |
571 | std::mutex queue_lock; |
572 | + std::shared_ptr<Buffer> buffer_being_rendered; |
573 | std::condition_variable cv; |
574 | - |
575 | std::queue<std::shared_ptr<graphics::Buffer>> queue; |
576 | }; |
577 | |
578 | |
579 | === modified file 'src/server/graphics/android/graphic_buffer_allocator.h' |
580 | --- src/server/graphics/android/graphic_buffer_allocator.h 2013-05-24 15:44:11 +0000 |
581 | +++ src/server/graphics/android/graphic_buffer_allocator.h 2013-11-14 23:10:20 +0000 |
582 | @@ -38,7 +38,7 @@ |
583 | class GraphicBufferAllocator |
584 | { |
585 | public: |
586 | - virtual std::shared_ptr<Buffer> alloc_buffer_platform( |
587 | + virtual std::shared_ptr<graphics::Buffer> alloc_buffer_platform( |
588 | geometry::Size sz, geometry::PixelFormat pf, BufferUsage use) = 0; |
589 | |
590 | protected: |
591 | |
592 | === modified file 'src/server/graphics/android/hwc10_device.cpp' |
593 | --- src/server/graphics/android/hwc10_device.cpp 2013-11-12 23:49:22 +0000 |
594 | +++ src/server/graphics/android/hwc10_device.cpp 2013-11-14 23:10:20 +0000 |
595 | @@ -19,6 +19,7 @@ |
596 | |
597 | #include "hwc10_device.h" |
598 | #include "hwc_vsync_coordinator.h" |
599 | +#include "framebuffer_bundle.h" |
600 | |
601 | #include <boost/throw_exception.hpp> |
602 | #include <stdexcept> |
603 | @@ -27,19 +28,17 @@ |
604 | namespace mga = mir::graphics::android; |
605 | namespace geom = mir::geometry; |
606 | mga::HWC10Device::HWC10Device(std::shared_ptr<hwc_composer_device_1> const& hwc_device, |
607 | + std::shared_ptr<FramebufferBundle> const& fb_bundle, |
608 | std::shared_ptr<DisplayDevice> const& fbdev, |
609 | std::shared_ptr<HWCVsyncCoordinator> const& coordinator) |
610 | : HWCCommonDevice(hwc_device, coordinator), |
611 | + fb_bundle(fb_bundle), |
612 | layer_list({mga::CompositionLayer{HWC_SKIP_LAYER}}), |
613 | fb_device(fbdev), |
614 | wait_for_vsync(true) |
615 | { |
616 | } |
617 | |
618 | -mga::HWC10Device::~HWC10Device() noexcept |
619 | -{ |
620 | -} |
621 | - |
622 | geom::Size mga::HWC10Device::display_size() const |
623 | { |
624 | return fb_device->display_size(); |
625 | @@ -50,14 +49,9 @@ |
626 | return fb_device->display_format(); |
627 | } |
628 | |
629 | -unsigned int mga::HWC10Device::number_of_framebuffers_available() const |
630 | -{ |
631 | - return fb_device->number_of_framebuffers_available(); |
632 | -} |
633 | - |
634 | -void mga::HWC10Device::set_next_frontbuffer(std::shared_ptr<mg::Buffer> const& buffer) |
635 | -{ |
636 | - fb_device->set_next_frontbuffer(buffer); |
637 | +std::shared_ptr<mg::Buffer> mga::HWC10Device::buffer_for_render() |
638 | +{ |
639 | + return fb_bundle->buffer_for_render(); |
640 | } |
641 | |
642 | void mga::HWC10Device::commit_frame(EGLDisplay dpy, EGLSurface sur) |
643 | |
644 | === modified file 'src/server/graphics/android/hwc10_device.h' |
645 | --- src/server/graphics/android/hwc10_device.h 2013-11-07 23:22:19 +0000 |
646 | +++ src/server/graphics/android/hwc10_device.h 2013-11-14 23:10:20 +0000 |
647 | @@ -28,23 +28,25 @@ |
648 | namespace android |
649 | { |
650 | class DisplayDevice; |
651 | +class FramebufferBundle; |
652 | |
653 | class HWC10Device : public HWCCommonDevice |
654 | { |
655 | public: |
656 | HWC10Device(std::shared_ptr<hwc_composer_device_1> const& hwc_device, |
657 | + std::shared_ptr<FramebufferBundle> const& fb_bundle, |
658 | std::shared_ptr<DisplayDevice> const& fbdev, |
659 | std::shared_ptr<HWCVsyncCoordinator> const& coordinator); |
660 | - ~HWC10Device() noexcept; |
661 | |
662 | geometry::Size display_size() const; |
663 | - geometry::PixelFormat display_format() const; |
664 | - unsigned int number_of_framebuffers_available() const; |
665 | - void set_next_frontbuffer(std::shared_ptr<graphics::Buffer> const& buffer); |
666 | + geometry::PixelFormat display_format() const; |
667 | + |
668 | + std::shared_ptr<graphics::Buffer> buffer_for_render(); |
669 | void sync_to_display(bool sync); |
670 | void commit_frame(EGLDisplay dpy, EGLSurface sur); |
671 | |
672 | private: |
673 | + std::shared_ptr<FramebufferBundle> const fb_bundle; |
674 | LayerList layer_list; |
675 | |
676 | std::shared_ptr<DisplayDevice> const fb_device; |
677 | |
678 | === modified file 'src/server/graphics/android/hwc11_device.cpp' |
679 | --- src/server/graphics/android/hwc11_device.cpp 2013-11-14 03:27:06 +0000 |
680 | +++ src/server/graphics/android/hwc11_device.cpp 2013-11-14 23:10:20 +0000 |
681 | @@ -20,7 +20,8 @@ |
682 | #include "hwc11_device.h" |
683 | #include "hwc_layerlist.h" |
684 | #include "hwc_vsync_coordinator.h" |
685 | -#include "android_format_conversion-inl.h" |
686 | +#include "framebuffer_bundle.h" |
687 | +#include "buffer.h" |
688 | #include "mir/graphics/android/sync_fence.h" |
689 | #include "mir/graphics/android/native_buffer.h" |
690 | #include "mir/graphics/buffer.h" |
691 | @@ -33,94 +34,29 @@ |
692 | namespace mga=mir::graphics::android; |
693 | namespace geom = mir::geometry; |
694 | |
695 | -namespace |
696 | -{ |
697 | -geom::PixelFormat determine_fb_format() |
698 | -{ |
699 | - static EGLint const fb_egl_config_attr [] = |
700 | - { |
701 | - EGL_SURFACE_TYPE, EGL_WINDOW_BIT, |
702 | - EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, |
703 | - EGL_FRAMEBUFFER_TARGET_ANDROID, EGL_TRUE, |
704 | - EGL_NONE |
705 | - }; |
706 | - |
707 | - EGLConfig fb_egl_config; |
708 | - int matching_configs; |
709 | - EGLint major, minor; |
710 | - auto egl_display = eglGetDisplay(EGL_DEFAULT_DISPLAY); |
711 | - eglInitialize(egl_display, &major, &minor); |
712 | - eglChooseConfig(egl_display, fb_egl_config_attr, &fb_egl_config, 1, &matching_configs); |
713 | - |
714 | - geom::PixelFormat fb_format; |
715 | - if (matching_configs) |
716 | - { |
717 | - int visual_id; |
718 | - eglGetConfigAttrib(egl_display, fb_egl_config, EGL_NATIVE_VISUAL_ID, &visual_id); |
719 | - fb_format = mga::to_mir_format(visual_id); |
720 | - } |
721 | - else |
722 | - { |
723 | - //we couldn't figure out the fb format via egl. In this case, we |
724 | - //assume abgr_8888. HWC api really should provide this information directly. |
725 | - fb_format = geom::PixelFormat::abgr_8888; |
726 | - } |
727 | - |
728 | - eglTerminate(egl_display); |
729 | - return fb_format; |
730 | -} |
731 | -} |
732 | - |
733 | mga::HWC11Device::HWC11Device(std::shared_ptr<hwc_composer_device_1> const& hwc_device, |
734 | + std::shared_ptr<FramebufferBundle> const& fb_bundle, |
735 | std::shared_ptr<HWCVsyncCoordinator> const& coordinator) |
736 | : HWCCommonDevice(hwc_device, coordinator), |
737 | - layer_list({mga::FramebufferLayer{}}), |
738 | - sync_ops(std::make_shared<mga::RealSyncFileOps>()), |
739 | - fb_format(determine_fb_format()) |
740 | -{ |
741 | - size_t num_configs = 1; |
742 | - auto rc = hwc_device->getDisplayConfigs(hwc_device.get(), HWC_DISPLAY_PRIMARY, &primary_display_config, &num_configs); |
743 | - if (rc != 0) |
744 | - { |
745 | - BOOST_THROW_EXCEPTION(std::runtime_error("could not determine hwc display config")); |
746 | - } |
747 | -} |
748 | - |
749 | -mga::HWC11Device::~HWC11Device() noexcept |
750 | + fb_bundle(fb_bundle), |
751 | + layer_list({mga::CompositionLayer{true}, mga::FramebufferLayer{}}), |
752 | + sync_ops(std::make_shared<mga::RealSyncFileOps>()) |
753 | { |
754 | } |
755 | |
756 | geom::Size mga::HWC11Device::display_size() const |
757 | { |
758 | - static uint32_t size_request[3] = { HWC_DISPLAY_WIDTH, |
759 | - HWC_DISPLAY_HEIGHT, |
760 | - HWC_DISPLAY_NO_ATTRIBUTE}; |
761 | - |
762 | - int size_values[2]; |
763 | - hwc_device->getDisplayAttributes(hwc_device.get(), HWC_DISPLAY_PRIMARY, primary_display_config, |
764 | - size_request, size_values); |
765 | - |
766 | - return {size_values[0], size_values[1]}; |
767 | + return fb_bundle->fb_size(); |
768 | } |
769 | |
770 | geom::PixelFormat mga::HWC11Device::display_format() const |
771 | { |
772 | - return fb_format; |
773 | -} |
774 | - |
775 | -unsigned int mga::HWC11Device::number_of_framebuffers_available() const |
776 | -{ |
777 | - //note: the default for hwc devices is 2 framebuffers. However, the hwcomposer api allows for the module to give |
778 | - //us a hint to triple buffer. Taking this hint is currently not supported. |
779 | - return 2u; |
780 | -} |
781 | - |
782 | -void mga::HWC11Device::set_next_frontbuffer(std::shared_ptr<mg::Buffer> const& buffer) |
783 | -{ |
784 | - layer_list.set_fb_target(buffer->native_buffer_handle()); |
785 | - //TODO: wait for framebuffer render to complete here. Eventually, we want to pass the fence right |
786 | - // into hwc_device->set() and let that wait for the render to complete. |
787 | - buffer->native_buffer_handle()->wait_for_content(); |
788 | + return fb_bundle->fb_format(); |
789 | +} |
790 | + |
791 | +std::shared_ptr<mg::Buffer> mga::HWC11Device::buffer_for_render() |
792 | +{ |
793 | + return fb_bundle->buffer_for_render(); |
794 | } |
795 | |
796 | void mga::HWC11Device::commit_frame(EGLDisplay dpy, EGLSurface sur) |
797 | @@ -136,19 +72,29 @@ |
798 | BOOST_THROW_EXCEPTION(std::runtime_error("error during hwc prepare()")); |
799 | } |
800 | |
801 | - /* note, swapbuffers will go around through the driver and call |
802 | - set_next_frontbuffer, updating the fb in layerlist before committing */ |
803 | if (eglSwapBuffers(dpy, sur) == EGL_FALSE) |
804 | { |
805 | BOOST_THROW_EXCEPTION(std::runtime_error("error during eglSwapBuffers")); |
806 | } |
807 | |
808 | + /* update gles rendered surface */ |
809 | + auto buffer = fb_bundle->last_rendered_buffer(); |
810 | + auto native_buffer = buffer->native_buffer_handle(); |
811 | + layer_list.set_fb_target(native_buffer); |
812 | + |
813 | if (hwc_device->set(hwc_device.get(), 1, displays)) |
814 | { |
815 | BOOST_THROW_EXCEPTION(std::runtime_error("error during hwc set()")); |
816 | } |
817 | - mga::SyncFence fence(sync_ops, displays[HWC_DISPLAY_PRIMARY]->retireFenceFd); |
818 | - fence.wait(); |
819 | + |
820 | + if (last_display_fence) |
821 | + last_display_fence->wait(); |
822 | + |
823 | + int framebuffer_fence = layer_list.framebuffer_fence(); |
824 | + native_buffer->update_fence(framebuffer_fence); |
825 | + |
826 | + last_display_fence = std::make_shared<mga::SyncFence>( |
827 | + sync_ops, displays[HWC_DISPLAY_PRIMARY]->retireFenceFd); |
828 | } |
829 | |
830 | void mga::HWC11Device::sync_to_display(bool) |
831 | |
832 | === modified file 'src/server/graphics/android/hwc11_device.h' |
833 | --- src/server/graphics/android/hwc11_device.h 2013-11-08 18:25:19 +0000 |
834 | +++ src/server/graphics/android/hwc11_device.h 2013-11-14 23:10:20 +0000 |
835 | @@ -32,25 +32,28 @@ |
836 | { |
837 | class HWCVsyncCoordinator; |
838 | class SyncFileOps; |
839 | +class SyncFence; |
840 | +class FramebufferBundle; |
841 | |
842 | class HWC11Device : public HWCCommonDevice |
843 | { |
844 | public: |
845 | HWC11Device(std::shared_ptr<hwc_composer_device_1> const& hwc_device, |
846 | + std::shared_ptr<FramebufferBundle> const& fb_bundle, |
847 | std::shared_ptr<HWCVsyncCoordinator> const& coordinator); |
848 | - ~HWC11Device() noexcept; |
849 | |
850 | geometry::Size display_size() const; |
851 | geometry::PixelFormat display_format() const; |
852 | - unsigned int number_of_framebuffers_available() const; |
853 | - void set_next_frontbuffer(std::shared_ptr<graphics::Buffer> const& buffer); |
854 | - void sync_to_display(bool sync); |
855 | - |
856 | + |
857 | + std::shared_ptr<graphics::Buffer> buffer_for_render(); |
858 | + void sync_to_display(bool sync); |
859 | void commit_frame(EGLDisplay dpy, EGLSurface sur); |
860 | |
861 | private: |
862 | + std::shared_ptr<FramebufferBundle> const fb_bundle; |
863 | LayerList layer_list; |
864 | |
865 | + std::shared_ptr<SyncFence> last_display_fence; |
866 | std::shared_ptr<SyncFileOps> const sync_ops; |
867 | unsigned int primary_display_config; |
868 | geometry::PixelFormat fb_format; |
869 | |
870 | === modified file 'src/server/graphics/android/hwc_layerlist.cpp' |
871 | --- src/server/graphics/android/hwc_layerlist.cpp 2013-11-11 21:34:15 +0000 |
872 | +++ src/server/graphics/android/hwc_layerlist.cpp 2013-11-14 23:10:20 +0000 |
873 | @@ -108,12 +108,20 @@ |
874 | void mga::LayerList::set_fb_target(std::shared_ptr<NativeBuffer> const& native_buffer) |
875 | { |
876 | auto fb_position = hwc_representation->numHwLayers - 1; |
877 | + |
878 | if (hwc_representation->hwLayers[fb_position].compositionType == HWC_FRAMEBUFFER_TARGET) |
879 | { |
880 | hwc_representation->hwLayers[fb_position] = mga::FramebufferLayer(*native_buffer); |
881 | + hwc_representation->hwLayers[fb_position].acquireFenceFd = native_buffer->copy_fence(); |
882 | } |
883 | } |
884 | |
885 | +mga::NativeFence mga::LayerList::framebuffer_fence() |
886 | +{ |
887 | + auto fb_position = hwc_representation->numHwLayers - 1; |
888 | + return hwc_representation->hwLayers[fb_position].releaseFenceFd; |
889 | +} |
890 | + |
891 | hwc_display_contents_1_t* mga::LayerList::native_list() const |
892 | { |
893 | return hwc_representation.get(); |
894 | |
895 | === modified file 'src/server/graphics/android/hwc_layerlist.h' |
896 | --- src/server/graphics/android/hwc_layerlist.h 2013-11-11 21:34:15 +0000 |
897 | +++ src/server/graphics/android/hwc_layerlist.h 2013-11-14 23:10:20 +0000 |
898 | @@ -19,6 +19,7 @@ |
899 | #ifndef MIR_GRAPHICS_ANDROID_HWC_LAYERLIST_H_ |
900 | #define MIR_GRAPHICS_ANDROID_HWC_LAYERLIST_H_ |
901 | |
902 | +#include "mir/graphics/android/fence.h" |
903 | #include "mir/geometry/rectangle.h" |
904 | #include <hardware/hwcomposer.h> |
905 | #include <memory> |
906 | @@ -67,7 +68,9 @@ |
907 | LayerList(std::initializer_list<HWCLayer> const& layers); |
908 | |
909 | hwc_display_contents_1_t* native_list() const; |
910 | + |
911 | void set_fb_target(std::shared_ptr<NativeBuffer> const&); |
912 | + NativeFence framebuffer_fence(); |
913 | |
914 | private: |
915 | std::shared_ptr<hwc_display_contents_1_t> hwc_representation; |
916 | |
917 | === modified file 'src/server/graphics/android/resource_factory.cpp' |
918 | --- src/server/graphics/android/resource_factory.cpp 2013-11-14 03:27:06 +0000 |
919 | +++ src/server/graphics/android/resource_factory.cpp 2013-11-14 23:10:20 +0000 |
920 | @@ -21,7 +21,7 @@ |
921 | #include "buffer.h" |
922 | #include "resource_factory.h" |
923 | #include "fb_device.h" |
924 | -#include "fb_simple_swapper.h" |
925 | +#include "framebuffers.h" |
926 | #include "graphic_buffer_allocator.h" |
927 | #include "server_render_window.h" |
928 | #include "interpreter_cache.h" |
929 | @@ -83,31 +83,24 @@ |
930 | std::shared_ptr<ANativeWindow> mga::ResourceFactory::create_native_window( |
931 | std::shared_ptr<mga::DisplayDevice> const& device) const |
932 | { |
933 | - auto size = device->display_size(); |
934 | - auto pf = device->display_format(); |
935 | - auto num_framebuffers = device->number_of_framebuffers_available(); |
936 | - std::vector<std::shared_ptr<mg::Buffer>> buffers; |
937 | - for (auto i = 0u; i < num_framebuffers; ++i) |
938 | - { |
939 | - buffers.push_back(buffer_allocator->alloc_buffer_platform(size, pf, mga::BufferUsage::use_framebuffer_gles)); |
940 | - } |
941 | - auto swapper = std::make_shared<mga::FBSimpleSwapper>(buffers); |
942 | auto cache = std::make_shared<mga::InterpreterCache>(); |
943 | - auto interpreter = std::make_shared<ServerRenderWindow>(swapper, device, cache); |
944 | + auto interpreter = std::make_shared<ServerRenderWindow>(device, cache); |
945 | return std::make_shared<MirNativeWindow>(interpreter); |
946 | } |
947 | |
948 | std::shared_ptr<mga::DisplayDevice> mga::ResourceFactory::create_fb_device( |
949 | std::shared_ptr<framebuffer_device_t> const& fb_native_device) const |
950 | { |
951 | - return std::make_shared<mga::FBDevice>(fb_native_device); |
952 | + auto framebuffers = std::make_shared<mga::Framebuffers>(buffer_allocator, fb_native_device); |
953 | + return std::make_shared<mga::FBDevice>(fb_native_device, framebuffers); |
954 | } |
955 | |
956 | std::shared_ptr<mga::DisplayDevice> mga::ResourceFactory::create_hwc11_device( |
957 | std::shared_ptr<hwc_composer_device_1> const& hwc_native_device) const |
958 | { |
959 | auto syncer = std::make_shared<mga::HWCVsync>(); |
960 | - return std::make_shared<mga::HWC11Device>(hwc_native_device, syncer); |
961 | + auto framebuffers = std::make_shared<mga::Framebuffers>(buffer_allocator, hwc_native_device); |
962 | + return std::make_shared<mga::HWC11Device>(hwc_native_device, framebuffers, syncer); |
963 | } |
964 | |
965 | std::shared_ptr<mga::DisplayDevice> mga::ResourceFactory::create_hwc10_device( |
966 | @@ -116,5 +109,6 @@ |
967 | { |
968 | auto syncer = std::make_shared<mga::HWCVsync>(); |
969 | auto fb_device = create_fb_device(fb_native_device); |
970 | - return std::make_shared<mga::HWC10Device>(hwc_native_device, fb_device, syncer); |
971 | + auto framebuffers = std::make_shared<mga::Framebuffers>(buffer_allocator, fb_native_device); |
972 | + return std::make_shared<mga::HWC10Device>(hwc_native_device, framebuffers, fb_device, syncer); |
973 | } |
974 | |
975 | === modified file 'src/server/graphics/android/server_render_window.cpp' |
976 | --- src/server/graphics/android/server_render_window.cpp 2013-10-25 16:39:50 +0000 |
977 | +++ src/server/graphics/android/server_render_window.cpp 2013-11-14 23:10:20 +0000 |
978 | @@ -21,7 +21,6 @@ |
979 | #include "mir/graphics/android/sync_fence.h" |
980 | #include "server_render_window.h" |
981 | #include "display_device.h" |
982 | -#include "fb_swapper.h" |
983 | #include "buffer.h" |
984 | #include "android_format_conversion-inl.h" |
985 | #include "interpreter_resource_cache.h" |
986 | @@ -34,11 +33,10 @@ |
987 | namespace mga=mir::graphics::android; |
988 | namespace geom=mir::geometry; |
989 | |
990 | -mga::ServerRenderWindow::ServerRenderWindow(std::shared_ptr<mga::FBSwapper> const& swapper, |
991 | - std::shared_ptr<mga::DisplayDevice> const& display_poster, |
992 | - std::shared_ptr<InterpreterResourceCache> const& cache) |
993 | - : swapper(swapper), |
994 | - poster(display_poster), |
995 | +mga::ServerRenderWindow::ServerRenderWindow( |
996 | + std::shared_ptr<mga::DisplayDevice> const& display_poster, |
997 | + std::shared_ptr<InterpreterResourceCache> const& cache) |
998 | + : poster(display_poster), |
999 | resource_cache(cache), |
1000 | format(mga::to_android_format(poster->display_format())) |
1001 | { |
1002 | @@ -46,7 +44,7 @@ |
1003 | |
1004 | mg::NativeBuffer* mga::ServerRenderWindow::driver_requests_buffer() |
1005 | { |
1006 | - auto buffer = swapper->compositor_acquire(); |
1007 | + auto buffer = poster->buffer_for_render(); |
1008 | auto handle = buffer->native_buffer_handle(); |
1009 | resource_cache->store_buffer(buffer, handle); |
1010 | return handle.get(); |
1011 | @@ -55,9 +53,7 @@ |
1012 | void mga::ServerRenderWindow::driver_returns_buffer(ANativeWindowBuffer* buffer, int fence_fd) |
1013 | { |
1014 | resource_cache->update_native_fence(buffer, fence_fd); |
1015 | - auto buffer_resource = resource_cache->retrieve_buffer(buffer); |
1016 | - poster->set_next_frontbuffer(buffer_resource); |
1017 | - swapper->compositor_release(buffer_resource); |
1018 | + resource_cache->retrieve_buffer(buffer); |
1019 | } |
1020 | |
1021 | void mga::ServerRenderWindow::dispatch_driver_request_format(int request_format) |
1022 | |
1023 | === modified file 'src/server/graphics/android/server_render_window.h' |
1024 | --- src/server/graphics/android/server_render_window.h 2013-10-25 16:39:50 +0000 |
1025 | +++ src/server/graphics/android/server_render_window.h 2013-11-14 23:10:20 +0000 |
1026 | @@ -32,14 +32,12 @@ |
1027 | namespace android |
1028 | { |
1029 | |
1030 | -class FBSwapper; |
1031 | class DisplayDevice; |
1032 | class InterpreterResourceCache; |
1033 | class ServerRenderWindow : public AndroidDriverInterpreter |
1034 | { |
1035 | public: |
1036 | - ServerRenderWindow(std::shared_ptr<FBSwapper> const& swapper, |
1037 | - std::shared_ptr<DisplayDevice> const& display_poster, |
1038 | + ServerRenderWindow(std::shared_ptr<DisplayDevice> const& display_poster, |
1039 | std::shared_ptr<InterpreterResourceCache> const&); |
1040 | |
1041 | graphics::NativeBuffer* driver_requests_buffer(); |
1042 | @@ -49,7 +47,6 @@ |
1043 | void sync_to_display(bool sync); |
1044 | |
1045 | private: |
1046 | - std::shared_ptr<FBSwapper> const swapper; |
1047 | std::shared_ptr<DisplayDevice> const poster; |
1048 | std::shared_ptr<InterpreterResourceCache> const resource_cache; |
1049 | |
1050 | |
1051 | === modified file 'src/shared/graphics/android/mir_native_window.cpp' |
1052 | --- src/shared/graphics/android/mir_native_window.cpp 2013-10-28 16:35:51 +0000 |
1053 | +++ src/shared/graphics/android/mir_native_window.cpp 2013-11-14 23:10:20 +0000 |
1054 | @@ -69,10 +69,8 @@ |
1055 | int dequeueBuffer_deprecated_static (struct ANativeWindow* window, |
1056 | struct ANativeWindowBuffer** buffer) |
1057 | { |
1058 | - int fence_fd = -1; |
1059 | auto self = static_cast<mga::MirNativeWindow*>(window); |
1060 | - //todo: we have to close the fence |
1061 | - return self->dequeueBuffer(buffer, &fence_fd); |
1062 | + return self->dequeueBufferAndWait(buffer); |
1063 | } |
1064 | |
1065 | int dequeueBuffer_static (struct ANativeWindow* window, |
1066 | @@ -169,6 +167,14 @@ |
1067 | return 0; |
1068 | } |
1069 | |
1070 | +int mga::MirNativeWindow::dequeueBufferAndWait(struct ANativeWindowBuffer** buffer_to_driver) |
1071 | +{ |
1072 | + auto buffer = driver_interpreter->driver_requests_buffer(); |
1073 | + *buffer_to_driver = buffer->anwb(); |
1074 | + buffer->wait_for_content(); |
1075 | + return 0; |
1076 | +} |
1077 | + |
1078 | int mga::MirNativeWindow::queueBuffer(struct ANativeWindowBuffer* buffer, int fence) |
1079 | { |
1080 | driver_interpreter->driver_returns_buffer(buffer, fence); |
1081 | |
1082 | === modified file 'tests/integration-tests/client/test_client_render.cpp' |
1083 | --- tests/integration-tests/client/test_client_render.cpp 2013-11-13 09:22:11 +0000 |
1084 | +++ tests/integration-tests/client/test_client_render.cpp 2013-11-14 23:10:20 +0000 |
1085 | @@ -274,13 +274,13 @@ |
1086 | return 0xFF00FF00; |
1087 | } |
1088 | |
1089 | - std::shared_ptr<mga::Buffer> second_to_last_posted_buffer() |
1090 | + std::shared_ptr<mg::Buffer> second_to_last_posted_buffer() |
1091 | { |
1092 | std::unique_lock<std::mutex> lk(buffer_mutex); |
1093 | return client_buffer; |
1094 | } |
1095 | |
1096 | - std::shared_ptr<mga::Buffer> last_posted_buffer() |
1097 | + std::shared_ptr<mg::Buffer> last_posted_buffer() |
1098 | { |
1099 | std::unique_lock<std::mutex> lk(buffer_mutex); |
1100 | return last_posted; |
1101 | @@ -288,8 +288,8 @@ |
1102 | |
1103 | private: |
1104 | std::shared_ptr<mga::AndroidGraphicBufferAllocator> allocator; |
1105 | - std::shared_ptr<mga::Buffer> client_buffer; |
1106 | - std::shared_ptr<mga::Buffer> last_posted; |
1107 | + std::shared_ptr<mg::Buffer> client_buffer; |
1108 | + std::shared_ptr<mg::Buffer> last_posted; |
1109 | std::mutex buffer_mutex; |
1110 | geom::PixelFormat surface_pf; |
1111 | }; |
1112 | |
1113 | === modified file 'tests/integration-tests/graphics/android/test_display_integration.cpp' |
1114 | --- tests/integration-tests/graphics/android/test_display_integration.cpp 2013-11-07 01:34:35 +0000 |
1115 | +++ tests/integration-tests/graphics/android/test_display_integration.cpp 2013-11-14 23:10:20 +0000 |
1116 | @@ -42,6 +42,10 @@ |
1117 | protected: |
1118 | static void SetUpTestCase() |
1119 | { |
1120 | + /* note: exynos5 hwc driver can sends sigterm to vsync thread when closing hwc. |
1121 | + the server can handle this, but we need the test to as well */ |
1122 | + original_sigterm_handler = signal(SIGTERM, [](int){}); |
1123 | + |
1124 | /* note about fb_device: OMAP4 drivers seem to only be able to open fb once |
1125 | per process (repeated framebuffer_{open,close}() doesn't seem to work). once we |
1126 | figure out why, we can remove fb_device in the test fixture */ |
1127 | @@ -52,14 +56,17 @@ |
1128 | |
1129 | static void TearDownTestCase() |
1130 | { |
1131 | + signal(SIGTERM, original_sigterm_handler); |
1132 | display_resource_factory.reset(); |
1133 | } |
1134 | |
1135 | md::glAnimationBasic gl_animation; |
1136 | |
1137 | static std::shared_ptr<mga::ResourceFactory> display_resource_factory; |
1138 | + static void (*original_sigterm_handler)(int); |
1139 | }; |
1140 | |
1141 | +void (*AndroidGPUDisplay::original_sigterm_handler)(int); |
1142 | std::shared_ptr<mga::ResourceFactory> AndroidGPUDisplay::display_resource_factory; |
1143 | } |
1144 | |
1145 | |
1146 | === modified file 'tests/unit-tests/client/android/test_android_native_window.cpp' |
1147 | --- tests/unit-tests/client/android/test_android_native_window.cpp 2013-10-28 16:35:51 +0000 |
1148 | +++ tests/unit-tests/client/android/test_android_native_window.cpp 2013-11-14 23:10:20 +0000 |
1149 | @@ -176,15 +176,19 @@ |
1150 | using namespace testing; |
1151 | |
1152 | ANativeWindowBuffer* returned_buffer; |
1153 | - auto fake_buffer = std::make_shared<mtd::StubAndroidNativeBuffer>(); |
1154 | + auto mock_buffer = std::make_shared<mtd::MockAndroidNativeBuffer>(); |
1155 | std::shared_ptr<ANativeWindow> window = std::make_shared<mga::MirNativeWindow>(mock_driver_interpreter); |
1156 | |
1157 | EXPECT_CALL(*mock_driver_interpreter, driver_requests_buffer()) |
1158 | .Times(1) |
1159 | - .WillOnce(Return(fake_buffer.get())); |
1160 | + .WillOnce(Return(mock_buffer.get())); |
1161 | + EXPECT_CALL(*mock_buffer, wait_for_content()) |
1162 | + .Times(1); |
1163 | + EXPECT_CALL(*mock_buffer, copy_fence()) |
1164 | + .Times(0); |
1165 | |
1166 | window->dequeueBuffer_DEPRECATED(window.get(), &returned_buffer); |
1167 | - EXPECT_EQ(fake_buffer->anwb(), returned_buffer); |
1168 | + EXPECT_EQ(mock_buffer->anwb(), returned_buffer); |
1169 | } |
1170 | |
1171 | /* queue hook tests */ |
1172 | |
1173 | === modified file 'tests/unit-tests/graphics/android/test_fb_device.cpp' |
1174 | --- tests/unit-tests/graphics/android/test_fb_device.cpp 2013-10-24 18:32:25 +0000 |
1175 | +++ tests/unit-tests/graphics/android/test_fb_device.cpp 2013-11-14 23:10:20 +0000 |
1176 | @@ -19,13 +19,16 @@ |
1177 | #include "mir_test_doubles/mock_fb_hal_device.h" |
1178 | #include "mir_test_doubles/mock_buffer.h" |
1179 | #include "src/server/graphics/android/fb_device.h" |
1180 | +#include "mir_test_doubles/mock_framebuffer_bundle.h" |
1181 | #include "mir_test_doubles/mock_android_hw.h" |
1182 | #include "mir_test_doubles/mock_egl.h" |
1183 | +#include "mir_test_doubles/stub_buffer.h" |
1184 | #include "mir_test_doubles/mock_android_native_buffer.h" |
1185 | |
1186 | #include <gtest/gtest.h> |
1187 | #include <stdexcept> |
1188 | |
1189 | +namespace mg=mir::graphics; |
1190 | namespace mtd=mir::test::doubles; |
1191 | namespace mga=mir::graphics::android; |
1192 | namespace geom=mir::geometry; |
1193 | @@ -42,15 +45,18 @@ |
1194 | fbnum = 4; |
1195 | format = HAL_PIXEL_FORMAT_RGBA_8888; |
1196 | |
1197 | + mock_fb_bundle = std::make_shared<testing::NiceMock<mtd::MockFBBundle>>(); |
1198 | fb_hal_mock = std::make_shared<mtd::MockFBHalDevice>(width, height, format, fbnum); |
1199 | mock_buffer = std::make_shared<NiceMock<mtd::MockBuffer>>(); |
1200 | - |
1201 | native_buffer = std::make_shared<mtd::StubAndroidNativeBuffer>(); |
1202 | ON_CALL(*mock_buffer, native_buffer_handle()) |
1203 | .WillByDefault(Return(native_buffer)); |
1204 | + ON_CALL(*mock_fb_bundle, last_rendered_buffer()) |
1205 | + .WillByDefault(Return(mock_buffer)); |
1206 | } |
1207 | |
1208 | unsigned int width, height, format, fbnum; |
1209 | + std::shared_ptr<mtd::MockFBBundle> mock_fb_bundle; |
1210 | std::shared_ptr<mtd::MockFBHalDevice> fb_hal_mock; |
1211 | std::shared_ptr<mtd::MockBuffer> mock_buffer; |
1212 | std::shared_ptr<mir::graphics::NativeBuffer> native_buffer; |
1213 | @@ -58,31 +64,6 @@ |
1214 | mtd::MockEGL mock_egl; |
1215 | }; |
1216 | |
1217 | -TEST_F(FBDevice, set_next_frontbuffer_ok) |
1218 | -{ |
1219 | - using namespace testing; |
1220 | - mga::FBDevice fbdev(fb_hal_mock); |
1221 | - |
1222 | - EXPECT_CALL(*fb_hal_mock, post_interface(fb_hal_mock.get(), native_buffer->handle())) |
1223 | - .Times(1); |
1224 | - |
1225 | - fbdev.set_next_frontbuffer(mock_buffer); |
1226 | -} |
1227 | - |
1228 | -TEST_F(FBDevice, set_next_frontbuffer_fail) |
1229 | -{ |
1230 | - using namespace testing; |
1231 | - mga::FBDevice fbdev(fb_hal_mock); |
1232 | - |
1233 | - EXPECT_CALL(*fb_hal_mock, post_interface(fb_hal_mock.get(),native_buffer->handle())) |
1234 | - .Times(1) |
1235 | - .WillOnce(Return(-1)); |
1236 | - |
1237 | - EXPECT_THROW({ |
1238 | - fbdev.set_next_frontbuffer(mock_buffer); |
1239 | - }, std::runtime_error); |
1240 | -} |
1241 | - |
1242 | TEST_F(FBDevice, commit_frame) |
1243 | { |
1244 | using namespace testing; |
1245 | @@ -90,24 +71,43 @@ |
1246 | EGLDisplay dpy = static_cast<EGLDisplay>(&bad); |
1247 | EGLSurface surf = static_cast<EGLSurface>(&bad); |
1248 | EXPECT_CALL(mock_egl, eglSwapBuffers(dpy,surf)) |
1249 | - .Times(2) |
1250 | + .Times(3) |
1251 | .WillOnce(Return(EGL_FALSE)) |
1252 | + .WillOnce(Return(EGL_TRUE)) |
1253 | .WillOnce(Return(EGL_TRUE)); |
1254 | |
1255 | - mga::FBDevice fbdev(fb_hal_mock); |
1256 | - |
1257 | + EXPECT_CALL(*fb_hal_mock, post_interface(fb_hal_mock.get(), native_buffer->handle())) |
1258 | + .Times(2) |
1259 | + .WillOnce(Return(-1)) |
1260 | + .WillOnce(Return(0)); |
1261 | + |
1262 | + mga::FBDevice fbdev(fb_hal_mock, mock_fb_bundle); |
1263 | + |
1264 | + EXPECT_THROW({ |
1265 | + fbdev.commit_frame(dpy, surf); |
1266 | + }, std::runtime_error); |
1267 | EXPECT_THROW({ |
1268 | fbdev.commit_frame(dpy, surf); |
1269 | }, std::runtime_error); |
1270 | fbdev.commit_frame(dpy, surf); |
1271 | } |
1272 | |
1273 | +TEST_F(FBDevice, buffer_for_render) |
1274 | +{ |
1275 | + using namespace testing; |
1276 | + EXPECT_CALL(*mock_fb_bundle, buffer_for_render()) |
1277 | + .Times(1) |
1278 | + .WillOnce(Return(mock_buffer)); |
1279 | + mga::FBDevice fbdev(fb_hal_mock, mock_fb_bundle); |
1280 | + |
1281 | + EXPECT_EQ(mock_buffer, fbdev.buffer_for_render()); |
1282 | +} |
1283 | |
1284 | TEST_F(FBDevice, set_swapinterval) |
1285 | { |
1286 | EXPECT_CALL(*fb_hal_mock, setSwapInterval_interface(fb_hal_mock.get(), 1)) |
1287 | .Times(1); |
1288 | - mga::FBDevice fbdev(fb_hal_mock); |
1289 | + mga::FBDevice fbdev(fb_hal_mock, mock_fb_bundle); |
1290 | |
1291 | testing::Mock::VerifyAndClearExpectations(fb_hal_mock.get()); |
1292 | |
1293 | @@ -119,34 +119,6 @@ |
1294 | TEST_F(FBDevice, set_swapinterval_with_nullhook) |
1295 | { |
1296 | fb_hal_mock->setSwapInterval = nullptr; |
1297 | - mga::FBDevice fbdev(fb_hal_mock); |
1298 | + mga::FBDevice fbdev(fb_hal_mock, mock_fb_bundle); |
1299 | fbdev.sync_to_display(false); |
1300 | } |
1301 | - |
1302 | -TEST_F(FBDevice, determine_size) |
1303 | -{ |
1304 | - mga::FBDevice fbdev(fb_hal_mock); |
1305 | - auto size = fbdev.display_size(); |
1306 | - EXPECT_EQ(width, size.width.as_uint32_t()); |
1307 | - EXPECT_EQ(height, size.height.as_uint32_t()); |
1308 | -} |
1309 | - |
1310 | -TEST_F(FBDevice, determine_fbnum) |
1311 | -{ |
1312 | - mga::FBDevice fbdev(fb_hal_mock); |
1313 | - EXPECT_EQ(fbnum, fbdev.number_of_framebuffers_available()); |
1314 | -} |
1315 | - |
1316 | -//some drivers incorrectly report 0 buffers available. if this is true, we should alloc 2, the minimum requirement |
1317 | -TEST_F(FBDevice, determine_fbnum_always_reports_2_minimum) |
1318 | -{ |
1319 | - auto slightly_malformed_fb_hal_mock = std::make_shared<mtd::MockFBHalDevice>(width, height, format, 0); |
1320 | - mga::FBDevice fbdev(slightly_malformed_fb_hal_mock); |
1321 | - EXPECT_EQ(2u, fbdev.number_of_framebuffers_available()); |
1322 | -} |
1323 | - |
1324 | -TEST_F(FBDevice, determine_pixformat) |
1325 | -{ |
1326 | - mga::FBDevice fbdev(fb_hal_mock); |
1327 | - EXPECT_EQ(geom::PixelFormat::abgr_8888, fbdev.display_format()); |
1328 | -} |
1329 | |
1330 | === modified file 'tests/unit-tests/graphics/android/test_fb_simple_swapper.cpp' |
1331 | --- tests/unit-tests/graphics/android/test_fb_simple_swapper.cpp 2013-08-28 03:41:48 +0000 |
1332 | +++ tests/unit-tests/graphics/android/test_fb_simple_swapper.cpp 2013-11-14 23:10:20 +0000 |
1333 | @@ -16,8 +16,12 @@ |
1334 | * Authored by: Kevin DuBois <kevin.dubois@canonical.com> |
1335 | */ |
1336 | |
1337 | -#include "src/server/graphics/android/fb_simple_swapper.h" |
1338 | +#include "src/server/graphics/android/framebuffers.h" |
1339 | +#include "src/server/graphics/android/graphic_buffer_allocator.h" |
1340 | #include "mir_test_doubles/mock_buffer.h" |
1341 | +#include "mir_test_doubles/mock_hwc_composer_device_1.h" |
1342 | +#include "mir_test_doubles/mock_egl.h" |
1343 | +#include "mir_test_doubles/mock_fb_hal_device.h" |
1344 | |
1345 | #include <future> |
1346 | #include <initializer_list> |
1347 | @@ -28,123 +32,192 @@ |
1348 | namespace mg=mir::graphics; |
1349 | namespace mga=mir::graphics::android; |
1350 | namespace mtd=mir::test::doubles; |
1351 | - |
1352 | -class FBSimpleSwapperTest : public ::testing::Test |
1353 | +namespace geom=mir::geometry; |
1354 | + |
1355 | +namespace |
1356 | +{ |
1357 | + |
1358 | +struct MockGraphicBufferAllocator : public mga::GraphicBufferAllocator |
1359 | +{ |
1360 | + MOCK_METHOD3(alloc_buffer_platform, std::shared_ptr<mg::Buffer>( |
1361 | + geom::Size, geom::PixelFormat, mga::BufferUsage use)); |
1362 | +}; |
1363 | + |
1364 | +static int const display_width = 180; |
1365 | +static int const display_height = 1010101; |
1366 | + |
1367 | +class PostingFBBundleTest : public ::testing::Test |
1368 | { |
1369 | public: |
1370 | virtual void SetUp() |
1371 | { |
1372 | + using namespace testing; |
1373 | + fbnum = 2; |
1374 | + format = HAL_PIXEL_FORMAT_RGBA_8888; |
1375 | buffer1 = std::make_shared<mtd::MockBuffer>(); |
1376 | buffer2 = std::make_shared<mtd::MockBuffer>(); |
1377 | buffer3 = std::make_shared<mtd::MockBuffer>(); |
1378 | + mock_allocator = std::make_shared<MockGraphicBufferAllocator>(); |
1379 | + mock_hwc_device = std::make_shared<testing::NiceMock<mtd::MockHWCComposerDevice1>>(); |
1380 | + mock_fb_hal = std::make_shared<mtd::MockFBHalDevice>(display_width, display_height, format, fbnum); |
1381 | + EXPECT_CALL(*mock_allocator, alloc_buffer_platform(_,_,_)) |
1382 | + .Times(AtLeast(0)) |
1383 | + .WillOnce(Return(buffer1)) |
1384 | + .WillOnce(Return(buffer2)) |
1385 | + .WillRepeatedly(Return(buffer3)); |
1386 | } |
1387 | |
1388 | + int format; |
1389 | + int fbnum; |
1390 | + std::shared_ptr<mtd::MockFBHalDevice> mock_fb_hal; |
1391 | + std::shared_ptr<MockGraphicBufferAllocator> mock_allocator; |
1392 | std::shared_ptr<mg::Buffer> buffer1; |
1393 | std::shared_ptr<mg::Buffer> buffer2; |
1394 | std::shared_ptr<mg::Buffer> buffer3; |
1395 | + std::shared_ptr<mtd::MockHWCComposerDevice1> mock_hwc_device; |
1396 | + testing::NiceMock<mtd::MockEGL> mock_egl; |
1397 | }; |
1398 | |
1399 | -TEST_F(FBSimpleSwapperTest, simple_swaps_returns_valid) |
1400 | -{ |
1401 | - std::initializer_list<std::shared_ptr<mg::Buffer>> double_list{buffer1, buffer2}; |
1402 | - mga::FBSimpleSwapper fb_swapper(double_list); |
1403 | - |
1404 | - auto test_buffer = fb_swapper.compositor_acquire(); |
1405 | - |
1406 | +static int display_attribute_handler(struct hwc_composer_device_1*, int, uint32_t, |
1407 | + const uint32_t* attribute_list, int32_t* values) |
1408 | +{ |
1409 | + EXPECT_EQ(attribute_list[0], HWC_DISPLAY_WIDTH); |
1410 | + EXPECT_EQ(attribute_list[1], HWC_DISPLAY_HEIGHT); |
1411 | + EXPECT_EQ(attribute_list[2], HWC_DISPLAY_NO_ATTRIBUTE); |
1412 | + |
1413 | + values[0] = display_width; |
1414 | + values[1] = display_height; |
1415 | + return 0; |
1416 | +} |
1417 | +} |
1418 | + |
1419 | +TEST_F(PostingFBBundleTest, hwc_fb_size_allocation) |
1420 | +{ |
1421 | + using namespace testing; |
1422 | + |
1423 | + unsigned int hwc_configs = 0xA1; |
1424 | + EXPECT_CALL(*mock_hwc_device, getDisplayConfigs_interface(mock_hwc_device.get(),HWC_DISPLAY_PRIMARY,_,Pointee(1))) |
1425 | + .Times(1) |
1426 | + .WillOnce(DoAll(SetArgPointee<2>(hwc_configs), Return(0))); |
1427 | + EXPECT_CALL(*mock_hwc_device, getDisplayAttributes_interface(mock_hwc_device.get(), HWC_DISPLAY_PRIMARY, hwc_configs,_,_)) |
1428 | + .Times(1) |
1429 | + .WillOnce(Invoke(display_attribute_handler)); |
1430 | + |
1431 | + auto display_size = mir::geometry::Size{display_width, display_height}; |
1432 | + EXPECT_CALL(*mock_allocator, alloc_buffer_platform(display_size, _, mga::BufferUsage::use_framebuffer_gles)) |
1433 | + .Times(2) |
1434 | + .WillRepeatedly(Return(nullptr)); |
1435 | + |
1436 | + mga::Framebuffers framebuffers(mock_allocator, mock_hwc_device); |
1437 | + EXPECT_EQ(display_size, framebuffers.fb_size()); |
1438 | +} |
1439 | + |
1440 | +TEST_F(PostingFBBundleTest, hwc_fb_format_selection) |
1441 | +{ |
1442 | + using namespace testing; |
1443 | + EGLint const expected_egl_config_attr [] = |
1444 | + { |
1445 | + EGL_SURFACE_TYPE, EGL_WINDOW_BIT, |
1446 | + EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, |
1447 | + EGL_FRAMEBUFFER_TARGET_ANDROID, EGL_TRUE, |
1448 | + EGL_NONE |
1449 | + }; |
1450 | + |
1451 | + int visual_id = HAL_PIXEL_FORMAT_BGRA_8888; |
1452 | + EGLDisplay fake_display = reinterpret_cast<EGLDisplay>(0x11235813); |
1453 | + EGLConfig fake_egl_config = reinterpret_cast<EGLConfig>(0x44); |
1454 | + |
1455 | + Sequence seq; |
1456 | + EXPECT_CALL(mock_egl, eglGetDisplay(EGL_DEFAULT_DISPLAY)) |
1457 | + .InSequence(seq) |
1458 | + .WillOnce(Return(fake_display)); |
1459 | + EXPECT_CALL(mock_egl, eglInitialize(fake_display,_,_)) |
1460 | + .InSequence(seq); |
1461 | + EXPECT_CALL(mock_egl, eglChooseConfig(fake_display,mtd::AttrMatches(expected_egl_config_attr),_,1,_)) |
1462 | + .InSequence(seq) |
1463 | + .WillOnce(DoAll(SetArgPointee<2>(fake_egl_config), SetArgPointee<4>(1), Return(EGL_TRUE))); |
1464 | + EXPECT_CALL(mock_egl, eglGetConfigAttrib(fake_display, fake_egl_config, EGL_NATIVE_VISUAL_ID, _)) |
1465 | + .InSequence(seq) |
1466 | + .WillOnce(DoAll(SetArgPointee<3>(visual_id), Return(EGL_TRUE))); |
1467 | + EXPECT_CALL(mock_egl, eglTerminate(fake_display)) |
1468 | + .InSequence(seq); |
1469 | + |
1470 | + mga::Framebuffers framebuffers(mock_allocator, mock_hwc_device); |
1471 | + EXPECT_EQ(geom::PixelFormat::argb_8888, framebuffers.fb_format()); |
1472 | +} |
1473 | + |
1474 | +//apparently this can happen if the display is in the 'unplugged state' |
1475 | +TEST_F(PostingFBBundleTest, test_hwc_device_display_config_failure_throws) |
1476 | +{ |
1477 | + using namespace testing; |
1478 | + EXPECT_CALL(*mock_hwc_device, getDisplayConfigs_interface(mock_hwc_device.get(),HWC_DISPLAY_PRIMARY,_,_)) |
1479 | + .Times(1) |
1480 | + .WillOnce(Return(-1)); |
1481 | + |
1482 | + EXPECT_THROW({ |
1483 | + mga::Framebuffers framebuffers(mock_allocator, mock_hwc_device); |
1484 | + }, std::runtime_error); |
1485 | +} |
1486 | + |
1487 | + |
1488 | +//not all hwc11 implementations give a hint about their framebuffer formats in their configuration. |
1489 | +//prefer abgr_8888 if we can't figure things out |
1490 | +TEST_F(PostingFBBundleTest, hwc_version_11_format_selection_failure) |
1491 | +{ |
1492 | + using namespace testing; |
1493 | + EGLDisplay fake_display = reinterpret_cast<EGLDisplay>(0x11235813); |
1494 | + |
1495 | + Sequence seq; |
1496 | + EXPECT_CALL(mock_egl, eglGetDisplay(EGL_DEFAULT_DISPLAY)) |
1497 | + .InSequence(seq) |
1498 | + .WillOnce(Return(fake_display)); |
1499 | + EXPECT_CALL(mock_egl, eglInitialize(fake_display,_,_)) |
1500 | + .InSequence(seq); |
1501 | + EXPECT_CALL(mock_egl, eglChooseConfig(_,_,_,_,_)) |
1502 | + .InSequence(seq) |
1503 | + .WillOnce(DoAll(SetArgPointee<4>(0), Return(EGL_TRUE))); |
1504 | + EXPECT_CALL(mock_egl, eglTerminate(fake_display)) |
1505 | + .InSequence(seq); |
1506 | + |
1507 | + mga::Framebuffers framebuffers(mock_allocator, mock_hwc_device); |
1508 | + EXPECT_EQ(geom::PixelFormat::abgr_8888, framebuffers.fb_format()); |
1509 | +} |
1510 | + |
1511 | +TEST_F(PostingFBBundleTest, bundle_from_fb) |
1512 | +{ |
1513 | + using namespace testing; |
1514 | + auto display_size = geom::Size{display_width, display_height}; |
1515 | + EXPECT_CALL(*mock_allocator, alloc_buffer_platform(display_size, geom::PixelFormat::abgr_8888, mga::BufferUsage::use_framebuffer_gles)) |
1516 | + .Times(fbnum) |
1517 | + .WillRepeatedly(Return(nullptr)); |
1518 | + |
1519 | + mga::Framebuffers framebuffers(mock_allocator, mock_fb_hal); |
1520 | + EXPECT_EQ(display_size, framebuffers.fb_size()); |
1521 | + EXPECT_EQ(geom::PixelFormat::abgr_8888, framebuffers.fb_format()); |
1522 | +} |
1523 | + |
1524 | +//some drivers incorrectly report 0 buffers available. if this is true, we should alloc 2, the minimum requirement |
1525 | +TEST_F(PostingFBBundleTest, determine_fbnum_always_reports_2_minimum) |
1526 | +{ |
1527 | + using namespace testing; |
1528 | + auto slightly_malformed_fb_hal_mock = std::make_shared<mtd::MockFBHalDevice>(display_width, display_height, format, 0); |
1529 | + EXPECT_CALL(*mock_allocator, alloc_buffer_platform(_,_,_)) |
1530 | + .Times(2) |
1531 | + .WillRepeatedly(Return(nullptr)); |
1532 | + |
1533 | + mga::Framebuffers framebuffers(mock_allocator, slightly_malformed_fb_hal_mock); |
1534 | +} |
1535 | + |
1536 | +TEST_F(PostingFBBundleTest, last_rendered_returns_valid) |
1537 | +{ |
1538 | + mga::Framebuffers framebuffers(mock_allocator, mock_fb_hal); |
1539 | + |
1540 | + auto test_buffer = framebuffers.last_rendered_buffer(); |
1541 | EXPECT_TRUE((test_buffer == buffer1) || (test_buffer == buffer2)); |
1542 | -} |
1543 | - |
1544 | -TEST_F(FBSimpleSwapperTest, simple_swaps_return_aba_pattern) |
1545 | -{ |
1546 | - std::initializer_list<std::shared_ptr<mg::Buffer>> double_list{buffer1, buffer2}; |
1547 | - mga::FBSimpleSwapper fb_swapper(double_list); |
1548 | - |
1549 | - auto test_buffer_1 = fb_swapper.compositor_acquire(); |
1550 | - fb_swapper.compositor_release(test_buffer_1); |
1551 | - |
1552 | - auto test_buffer_2 = fb_swapper.compositor_acquire(); |
1553 | - fb_swapper.compositor_release(test_buffer_2); |
1554 | - |
1555 | - auto test_buffer_3 = fb_swapper.compositor_acquire(); |
1556 | - fb_swapper.compositor_release(test_buffer_3); |
1557 | - |
1558 | - EXPECT_EQ(test_buffer_1, test_buffer_3); |
1559 | - EXPECT_NE(test_buffer_1, test_buffer_2); |
1560 | -} |
1561 | - |
1562 | -TEST_F(FBSimpleSwapperTest, triple_swaps_return_abcab_pattern) |
1563 | -{ |
1564 | - std::initializer_list<std::shared_ptr<mg::Buffer>> triple_list{buffer1, buffer2, buffer3}; |
1565 | - mga::FBSimpleSwapper fb_swapper(triple_list); |
1566 | - |
1567 | - auto test_buffer_1 = fb_swapper.compositor_acquire(); |
1568 | - fb_swapper.compositor_release(test_buffer_1); |
1569 | - |
1570 | - auto test_buffer_2 = fb_swapper.compositor_acquire(); |
1571 | - fb_swapper.compositor_release(test_buffer_2); |
1572 | - |
1573 | - auto test_buffer_3 = fb_swapper.compositor_acquire(); |
1574 | - fb_swapper.compositor_release(test_buffer_3); |
1575 | - |
1576 | - auto test_buffer_4 = fb_swapper.compositor_acquire(); |
1577 | - fb_swapper.compositor_release(test_buffer_4); |
1578 | - |
1579 | - auto test_buffer_5 = fb_swapper.compositor_acquire(); |
1580 | - fb_swapper.compositor_release(test_buffer_5); |
1581 | - |
1582 | - EXPECT_EQ(test_buffer_1, test_buffer_4); |
1583 | - EXPECT_NE(test_buffer_1, test_buffer_2); |
1584 | - EXPECT_NE(test_buffer_1, test_buffer_3); |
1585 | - |
1586 | - EXPECT_EQ(test_buffer_2, test_buffer_5); |
1587 | - EXPECT_NE(test_buffer_2, test_buffer_1); |
1588 | - EXPECT_NE(test_buffer_2, test_buffer_3); |
1589 | -} |
1590 | - |
1591 | -TEST_F(FBSimpleSwapperTest, synctest) |
1592 | -{ |
1593 | - std::vector<std::shared_ptr<mg::Buffer>> test_buffers{buffer1, buffer2}; |
1594 | - mga::FBSimpleSwapper fb_swapper(test_buffers); |
1595 | - |
1596 | - std::vector<std::shared_ptr<mg::Buffer>> blist; |
1597 | - std::mutex mut; |
1598 | - for(auto i=0u; i < 150; ++i) |
1599 | - { |
1600 | - auto buf1 = fb_swapper.compositor_acquire(); |
1601 | - auto buf2 = fb_swapper.compositor_acquire(); |
1602 | - |
1603 | - auto f = std::async(std::launch::async, |
1604 | - [&]() |
1605 | - { |
1606 | - /* driver will release in order */ |
1607 | - fb_swapper.compositor_release(buf1); |
1608 | - fb_swapper.compositor_release(buf2); |
1609 | - }); |
1610 | - |
1611 | - //this line will wait if f has not run |
1612 | - auto buf3 = fb_swapper.compositor_acquire(); |
1613 | - f.wait(); //make sure buf3 is released after buf2 to maintain order |
1614 | - fb_swapper.compositor_release(buf3); |
1615 | - |
1616 | - blist.push_back(buf1); |
1617 | - blist.push_back(buf2); |
1618 | - blist.push_back(buf3); |
1619 | - } |
1620 | - |
1621 | - //This chunk of code makes sure "ABABA..." or "BABAB..." pattern was produced |
1622 | - auto modcounter = 0u; |
1623 | - for(auto i : test_buffers) |
1624 | - { |
1625 | - if (blist[0] == i) |
1626 | - { |
1627 | - break; |
1628 | - } |
1629 | - modcounter++; |
1630 | - } |
1631 | - |
1632 | - for(auto i : blist) |
1633 | - { |
1634 | - EXPECT_EQ(test_buffers[(modcounter % test_buffers.size())], i); |
1635 | - modcounter++; |
1636 | - } |
1637 | -} |
1638 | + |
1639 | + auto first_buffer = framebuffers.buffer_for_render(); |
1640 | + auto first_buffer_ptr = first_buffer.get(); |
1641 | + EXPECT_NE(first_buffer, framebuffers.last_rendered_buffer()); |
1642 | + first_buffer.reset(); |
1643 | + EXPECT_EQ(first_buffer_ptr, framebuffers.last_rendered_buffer().get()); |
1644 | +} |
1645 | |
1646 | === modified file 'tests/unit-tests/graphics/android/test_hwc10_device.cpp' |
1647 | --- tests/unit-tests/graphics/android/test_hwc10_device.cpp 2013-11-08 18:44:35 +0000 |
1648 | +++ tests/unit-tests/graphics/android/test_hwc10_device.cpp 2013-11-14 23:10:20 +0000 |
1649 | @@ -21,6 +21,7 @@ |
1650 | #include "mir_test_doubles/mock_hwc_composer_device_1.h" |
1651 | #include "mir_test_doubles/mock_buffer.h" |
1652 | #include "mir_test_doubles/mock_hwc_vsync_coordinator.h" |
1653 | +#include "mir_test_doubles/mock_framebuffer_bundle.h" |
1654 | #include <gtest/gtest.h> |
1655 | #include <stdexcept> |
1656 | |
1657 | @@ -41,6 +42,8 @@ |
1658 | mock_device = std::make_shared<testing::NiceMock<mtd::MockHWCComposerDevice1>>(); |
1659 | mock_fbdev = std::make_shared<mtd::MockDisplayDevice>(); |
1660 | mock_vsync = std::make_shared<testing::NiceMock<mtd::MockVsyncCoordinator>>(); |
1661 | + mock_buffer = std::make_shared<NiceMock<mtd::MockBuffer>>(); |
1662 | + mock_fb_bundle = std::make_shared<testing::NiceMock<mtd::MockFBBundle>>(); |
1663 | } |
1664 | |
1665 | geom::PixelFormat test_pf; |
1666 | @@ -49,16 +52,19 @@ |
1667 | std::shared_ptr<mtd::MockHWCComposerDevice1> mock_device; |
1668 | std::shared_ptr<mtd::MockDisplayDevice> mock_fbdev; |
1669 | std::shared_ptr<mtd::MockVsyncCoordinator> mock_vsync; |
1670 | + std::shared_ptr<mtd::MockFBBundle> mock_fb_bundle; |
1671 | + std::shared_ptr<mtd::MockBuffer> mock_buffer; |
1672 | }; |
1673 | |
1674 | -TEST_F(HWC10Device, hwc10_set_next_frontbuffer) |
1675 | +TEST_F(HWC10Device, buffer_for_render) |
1676 | { |
1677 | - std::shared_ptr<mg::Buffer> mock_buffer = std::make_shared<mtd::MockBuffer>(); |
1678 | - EXPECT_CALL(*mock_fbdev, set_next_frontbuffer(mock_buffer)) |
1679 | - .Times(1); |
1680 | + using namespace testing; |
1681 | + EXPECT_CALL(*mock_fb_bundle, buffer_for_render()) |
1682 | + .Times(1) |
1683 | + .WillOnce(Return(mock_buffer)); |
1684 | + mga::HWC10Device device(mock_device, mock_fb_bundle, mock_fbdev, mock_vsync); |
1685 | |
1686 | - mga::HWC10Device device(mock_device, mock_fbdev, mock_vsync); |
1687 | - device.set_next_frontbuffer(mock_buffer); |
1688 | + EXPECT_EQ(mock_buffer, device.buffer_for_render()); |
1689 | } |
1690 | |
1691 | TEST_F(HWC10Device, hwc10_commit_frame_sync) |
1692 | @@ -77,7 +83,7 @@ |
1693 | EXPECT_CALL(*mock_vsync, wait_for_vsync()) |
1694 | .Times(1); |
1695 | |
1696 | - mga::HWC10Device device(mock_device, mock_fbdev, mock_vsync); |
1697 | + mga::HWC10Device device(mock_device, mock_fb_bundle, mock_fbdev, mock_vsync); |
1698 | |
1699 | device.commit_frame(dpy, sur); |
1700 | |
1701 | @@ -110,7 +116,7 @@ |
1702 | EXPECT_CALL(*mock_vsync, wait_for_vsync()) |
1703 | .Times(0); |
1704 | |
1705 | - mga::HWC10Device device(mock_device, mock_fbdev, mock_vsync); |
1706 | + mga::HWC10Device device(mock_device, mock_fb_bundle, mock_fbdev, mock_vsync); |
1707 | device.sync_to_display(false); |
1708 | |
1709 | device.commit_frame(dpy, sur); |
1710 | @@ -126,7 +132,7 @@ |
1711 | .Times(1) |
1712 | .WillOnce(Return(-1)); |
1713 | |
1714 | - mga::HWC10Device device(mock_device, mock_fbdev, mock_vsync); |
1715 | + mga::HWC10Device device(mock_device, mock_fb_bundle, mock_fbdev, mock_vsync); |
1716 | |
1717 | EXPECT_THROW({ |
1718 | device.commit_frame(dpy, sur); |
1719 | @@ -143,7 +149,7 @@ |
1720 | .Times(1) |
1721 | .WillOnce(Return(-1)); |
1722 | |
1723 | - mga::HWC10Device device(mock_device, mock_fbdev, mock_vsync); |
1724 | + mga::HWC10Device device(mock_device, mock_fb_bundle, mock_fbdev, mock_vsync); |
1725 | |
1726 | EXPECT_THROW({ |
1727 | device.commit_frame(dpy, sur); |
1728 | @@ -159,12 +165,8 @@ |
1729 | EXPECT_CALL(*mock_fbdev, display_format()) |
1730 | .Times(1) |
1731 | .WillOnce(Return(test_pf)); |
1732 | - EXPECT_CALL(*mock_fbdev, number_of_framebuffers_available()) |
1733 | - .Times(1) |
1734 | - .WillOnce(Return(test_numfb)); |
1735 | |
1736 | - mga::HWC10Device device(mock_device, mock_fbdev, mock_vsync); |
1737 | + mga::HWC10Device device(mock_device, mock_fb_bundle, mock_fbdev, mock_vsync); |
1738 | EXPECT_EQ(test_size, device.display_size()); |
1739 | EXPECT_EQ(test_pf, device.display_format()); |
1740 | - EXPECT_EQ(test_numfb, device.number_of_framebuffers_available()); |
1741 | } |
1742 | |
1743 | === modified file 'tests/unit-tests/graphics/android/test_hwc11_device.cpp' |
1744 | --- tests/unit-tests/graphics/android/test_hwc11_device.cpp 2013-11-08 18:25:19 +0000 |
1745 | +++ tests/unit-tests/graphics/android/test_hwc11_device.cpp 2013-11-14 23:10:20 +0000 |
1746 | @@ -16,12 +16,17 @@ |
1747 | * Authored by: Kevin DuBois <kevin.dubois@canonical.com> |
1748 | */ |
1749 | |
1750 | +#include "src/server/graphics/android/framebuffer_bundle.h" |
1751 | #include "src/server/graphics/android/hwc11_device.h" |
1752 | #include "src/server/graphics/android/hwc_layerlist.h" |
1753 | #include "mir_test_doubles/mock_hwc_composer_device_1.h" |
1754 | +#include "mir_test_doubles/mock_android_native_buffer.h" |
1755 | #include "mir_test_doubles/mock_buffer.h" |
1756 | #include "mir_test_doubles/mock_hwc_vsync_coordinator.h" |
1757 | #include "mir_test_doubles/mock_egl.h" |
1758 | +#include "mir_test_doubles/mock_framebuffer_bundle.h" |
1759 | +#include "mir_test_doubles/stub_buffer.h" |
1760 | +#include <gmock/gmock.h> |
1761 | #include <gtest/gtest.h> |
1762 | #include <stdexcept> |
1763 | |
1764 | @@ -35,207 +40,98 @@ |
1765 | protected: |
1766 | virtual void SetUp() |
1767 | { |
1768 | + using namespace testing; |
1769 | + |
1770 | + mock_native_buffer = std::make_shared<testing::NiceMock<mtd::MockAndroidNativeBuffer>>(); |
1771 | + mock_buffer = std::make_shared<testing::NiceMock<mtd::MockBuffer>>(); |
1772 | + mock_fb_bundle = std::make_shared<testing::NiceMock<mtd::MockFBBundle>>(); |
1773 | mock_device = std::make_shared<testing::NiceMock<mtd::MockHWCComposerDevice1>>(); |
1774 | mock_vsync = std::make_shared<testing::NiceMock<mtd::MockVsyncCoordinator>>(); |
1775 | + |
1776 | + ON_CALL(*mock_buffer, native_buffer_handle()) |
1777 | + .WillByDefault(Return(mock_native_buffer)); |
1778 | + ON_CALL(*mock_fb_bundle, last_rendered_buffer()) |
1779 | + .WillByDefault(Return(mock_buffer)); |
1780 | } |
1781 | |
1782 | + std::shared_ptr<mtd::MockFBBundle> mock_fb_bundle; |
1783 | std::shared_ptr<mtd::MockVsyncCoordinator> mock_vsync; |
1784 | std::shared_ptr<mtd::MockHWCComposerDevice1> mock_device; |
1785 | + std::shared_ptr<mtd::MockAndroidNativeBuffer> mock_native_buffer; |
1786 | + std::shared_ptr<mtd::MockBuffer> mock_buffer; |
1787 | EGLDisplay dpy; |
1788 | EGLSurface surf; |
1789 | testing::NiceMock<mtd::MockEGL> mock_egl; |
1790 | }; |
1791 | |
1792 | -TEST_F(HWC11Device, test_hwc_gles_set_empty_layerlist) |
1793 | -{ |
1794 | - using namespace testing; |
1795 | - |
1796 | - mga::HWC11Device device(mock_device, mock_vsync); |
1797 | - |
1798 | - EXPECT_CALL(*mock_device, set_interface(mock_device.get(), 1, _)) |
1799 | - .Times(1); |
1800 | - device.commit_frame(dpy, surf); |
1801 | - |
1802 | - EXPECT_EQ(1, mock_device->display0_set_content.numHwLayers); |
1803 | - EXPECT_EQ(-1, mock_device->display0_set_content.retireFenceFd); |
1804 | -} |
1805 | - |
1806 | -TEST_F(HWC11Device, test_hwc_gles_set_error) |
1807 | -{ |
1808 | - using namespace testing; |
1809 | - |
1810 | - mga::HWC11Device device(mock_device, mock_vsync); |
1811 | - |
1812 | - EXPECT_CALL(*mock_device, set_interface(mock_device.get(), 1, _)) |
1813 | - .Times(1) |
1814 | - .WillOnce(Return(-1)); |
1815 | - |
1816 | - EXPECT_THROW({ |
1817 | - device.commit_frame(dpy, surf); |
1818 | - }, std::runtime_error); |
1819 | -} |
1820 | - |
1821 | -TEST_F(HWC11Device, test_hwc_gles_commit_swapbuffers_failure) |
1822 | -{ |
1823 | - using namespace testing; |
1824 | - EXPECT_CALL(mock_egl, eglSwapBuffers(dpy,surf)) |
1825 | - .Times(1) |
1826 | - .WillOnce(Return(EGL_FALSE)); |
1827 | - |
1828 | - mga::HWC11Device device(mock_device, mock_vsync); |
1829 | - |
1830 | - EXPECT_THROW({ |
1831 | - device.commit_frame(dpy, surf); |
1832 | - }, std::runtime_error); |
1833 | -} |
1834 | - |
1835 | -TEST_F(HWC11Device, test_hwc_commit_order_with_vsync) |
1836 | -{ |
1837 | - using namespace testing; |
1838 | - |
1839 | - mga::HWC11Device device(mock_device, mock_vsync); |
1840 | - |
1841 | - //the order here is very important. eglSwapBuffers will alter the layerlist, |
1842 | - //so it must come before assembling the data for set |
1843 | +TEST_F(HWC11Device, test_hwc_commit_order) |
1844 | +{ |
1845 | + using namespace testing; |
1846 | + int hwc_return_fence = 94; |
1847 | + mock_device->hwc_set_return_fence(hwc_return_fence); |
1848 | + |
1849 | + mga::HWC11Device device(mock_device, mock_fb_bundle, mock_vsync); |
1850 | + |
1851 | InSequence seq; |
1852 | EXPECT_CALL(*mock_device, prepare_interface(mock_device.get(), 1, _)) |
1853 | .Times(1); |
1854 | EXPECT_CALL(mock_egl, eglSwapBuffers(dpy,surf)) |
1855 | .Times(1); |
1856 | + EXPECT_CALL(*mock_fb_bundle, last_rendered_buffer()) |
1857 | + .Times(1); |
1858 | EXPECT_CALL(*mock_device, set_interface(mock_device.get(), 1, _)) |
1859 | .Times(1); |
1860 | + EXPECT_CALL(*mock_native_buffer, update_fence(hwc_return_fence)) |
1861 | + .Times(1); |
1862 | |
1863 | device.commit_frame(dpy, surf); |
1864 | |
1865 | - EXPECT_EQ(1, mock_device->display0_prepare_content.numHwLayers); |
1866 | + EXPECT_EQ(2, mock_device->display0_prepare_content.numHwLayers); |
1867 | EXPECT_EQ(-1, mock_device->display0_prepare_content.retireFenceFd); |
1868 | - EXPECT_EQ(1, mock_device->display0_set_content.numHwLayers); |
1869 | + //set |
1870 | + EXPECT_EQ(2, mock_device->display0_set_content.numHwLayers); |
1871 | EXPECT_EQ(-1, mock_device->display0_set_content.retireFenceFd); |
1872 | + EXPECT_EQ(HWC_FRAMEBUFFER, mock_device->set_layerlist[0].compositionType); |
1873 | + EXPECT_EQ(HWC_SKIP_LAYER, mock_device->set_layerlist[0].flags); |
1874 | + EXPECT_EQ(HWC_FRAMEBUFFER_TARGET, mock_device->set_layerlist[1].compositionType); |
1875 | + EXPECT_EQ(0, mock_device->set_layerlist[1].flags); |
1876 | } |
1877 | |
1878 | -TEST_F(HWC11Device, test_hwc_device_display_config) |
1879 | +TEST_F(HWC11Device, buffer_for_render) |
1880 | { |
1881 | using namespace testing; |
1882 | - |
1883 | - unsigned int hwc_configs = 0xA1; |
1884 | - EXPECT_CALL(*mock_device, getDisplayConfigs_interface(mock_device.get(),HWC_DISPLAY_PRIMARY,_,Pointee(1))) |
1885 | + EXPECT_CALL(*mock_fb_bundle, buffer_for_render()) |
1886 | .Times(1) |
1887 | - .WillOnce(DoAll(SetArgPointee<2>(hwc_configs), Return(0))); |
1888 | - |
1889 | - mga::HWC11Device device(mock_device, mock_vsync); |
1890 | + .WillOnce(Return(mock_buffer)); |
1891 | + mga::HWC11Device device(mock_device, mock_fb_bundle, mock_vsync); |
1892 | + EXPECT_EQ(mock_buffer, device.buffer_for_render()); |
1893 | } |
1894 | |
1895 | - |
1896 | -//apparently this can happen if the display is in the 'unplugged state' |
1897 | -TEST_F(HWC11Device, test_hwc_device_display_config_failure_throws) |
1898 | +TEST_F(HWC11Device, test_hwc_commit_failure) |
1899 | { |
1900 | using namespace testing; |
1901 | |
1902 | - EXPECT_CALL(*mock_device, getDisplayConfigs_interface(mock_device.get(),HWC_DISPLAY_PRIMARY,_,_)) |
1903 | + mga::HWC11Device device(mock_device, mock_fb_bundle, mock_vsync); |
1904 | + |
1905 | + EXPECT_CALL(*mock_device, set_interface(mock_device.get(), 1, _)) |
1906 | .Times(1) |
1907 | .WillOnce(Return(-1)); |
1908 | |
1909 | EXPECT_THROW({ |
1910 | - mga::HWC11Device device(mock_device, mock_vsync); |
1911 | - }, std::runtime_error); |
1912 | -} |
1913 | - |
1914 | -namespace |
1915 | -{ |
1916 | -static int const display_width = 180; |
1917 | -static int const display_height = 1010101; |
1918 | - |
1919 | -static int display_attribute_handler(struct hwc_composer_device_1*, int, uint32_t, |
1920 | - const uint32_t* attribute_list, int32_t* values) |
1921 | -{ |
1922 | - EXPECT_EQ(attribute_list[0], HWC_DISPLAY_WIDTH); |
1923 | - EXPECT_EQ(attribute_list[1], HWC_DISPLAY_HEIGHT); |
1924 | - EXPECT_EQ(attribute_list[2], HWC_DISPLAY_NO_ATTRIBUTE); |
1925 | - |
1926 | - values[0] = display_width; |
1927 | - values[1] = display_height; |
1928 | - return 0; |
1929 | -} |
1930 | -} |
1931 | - |
1932 | -TEST_F(HWC11Device, test_hwc_device_display_width_height) |
1933 | -{ |
1934 | - using namespace testing; |
1935 | - |
1936 | - int hwc_configs = 0xA1; |
1937 | - EXPECT_CALL(*mock_device, getDisplayConfigs_interface(mock_device.get(),HWC_DISPLAY_PRIMARY,_,_)) |
1938 | - .Times(1) |
1939 | - .WillOnce(DoAll(SetArgPointee<2>(hwc_configs), Return(0))); |
1940 | - EXPECT_CALL(*mock_device, getDisplayAttributes_interface(mock_device.get(), HWC_DISPLAY_PRIMARY,hwc_configs,_,_)) |
1941 | - .Times(1) |
1942 | - .WillOnce(Invoke(display_attribute_handler)); |
1943 | - |
1944 | - mga::HWC11Device device(mock_device, mock_vsync); |
1945 | - |
1946 | - auto size = device.display_size(); |
1947 | - EXPECT_EQ(size.width.as_uint32_t(), static_cast<unsigned int>(display_width)); |
1948 | - EXPECT_EQ(size.height.as_uint32_t(), static_cast<unsigned int>(display_height)); |
1949 | -} |
1950 | - |
1951 | -TEST_F(HWC11Device, hwc_device_reports_2_fbs_available_by_default) |
1952 | -{ |
1953 | - mga::HWC11Device device(mock_device, mock_vsync); |
1954 | - EXPECT_EQ(2u, device.number_of_framebuffers_available()); |
1955 | -} |
1956 | - |
1957 | -TEST_F(HWC11Device, hwc_version_11_format_selection) |
1958 | -{ |
1959 | - using namespace testing; |
1960 | - EGLint const expected_egl_config_attr [] = |
1961 | - { |
1962 | - EGL_SURFACE_TYPE, EGL_WINDOW_BIT, |
1963 | - EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, |
1964 | - EGL_FRAMEBUFFER_TARGET_ANDROID, EGL_TRUE, |
1965 | - EGL_NONE |
1966 | - }; |
1967 | - |
1968 | - int visual_id = HAL_PIXEL_FORMAT_BGRA_8888; |
1969 | - EGLDisplay fake_display = reinterpret_cast<EGLDisplay>(0x11235813); |
1970 | - EGLConfig fake_egl_config = reinterpret_cast<EGLConfig>(0x44); |
1971 | - |
1972 | - Sequence seq; |
1973 | - EXPECT_CALL(mock_egl, eglGetDisplay(EGL_DEFAULT_DISPLAY)) |
1974 | - .InSequence(seq) |
1975 | - .WillOnce(Return(fake_display)); |
1976 | - EXPECT_CALL(mock_egl, eglInitialize(fake_display,_,_)) |
1977 | - .InSequence(seq); |
1978 | - EXPECT_CALL(mock_egl, eglChooseConfig(fake_display,mtd::AttrMatches(expected_egl_config_attr),_,1,_)) |
1979 | - .InSequence(seq) |
1980 | - .WillOnce(DoAll(SetArgPointee<2>(fake_egl_config), SetArgPointee<4>(1), Return(EGL_TRUE))); |
1981 | - EXPECT_CALL(mock_egl, eglGetConfigAttrib(fake_display, fake_egl_config, EGL_NATIVE_VISUAL_ID, _)) |
1982 | - .InSequence(seq) |
1983 | - .WillOnce(DoAll(SetArgPointee<3>(visual_id), Return(EGL_TRUE))); |
1984 | - EXPECT_CALL(mock_egl, eglTerminate(fake_display)) |
1985 | - .InSequence(seq); |
1986 | - |
1987 | - mga::HWC11Device device(mock_device, mock_vsync); |
1988 | - EXPECT_EQ(geom::PixelFormat::argb_8888, device.display_format()); |
1989 | -} |
1990 | - |
1991 | -//not all hwc11 implementations give a hint about their framebuffer formats in their configuration. |
1992 | -//prefer abgr_8888 if we can't figure things out |
1993 | -TEST_F(HWC11Device, hwc_version_11_format_selection_failure) |
1994 | -{ |
1995 | - using namespace testing; |
1996 | - EGLDisplay fake_display = reinterpret_cast<EGLDisplay>(0x11235813); |
1997 | - |
1998 | - Sequence seq; |
1999 | - EXPECT_CALL(mock_egl, eglGetDisplay(EGL_DEFAULT_DISPLAY)) |
2000 | - .InSequence(seq) |
2001 | - .WillOnce(Return(fake_display)); |
2002 | - EXPECT_CALL(mock_egl, eglInitialize(fake_display,_,_)) |
2003 | - .InSequence(seq); |
2004 | - EXPECT_CALL(mock_egl, eglChooseConfig(_,_,_,_,_)) |
2005 | - .InSequence(seq) |
2006 | - .WillOnce(DoAll(SetArgPointee<4>(0), Return(EGL_TRUE))); |
2007 | - EXPECT_CALL(mock_egl, eglTerminate(fake_display)) |
2008 | - .InSequence(seq); |
2009 | - |
2010 | - mga::HWC11Device device(mock_device, mock_vsync); |
2011 | - EXPECT_EQ(geom::PixelFormat::abgr_8888, device.display_format()); |
2012 | + device.commit_frame(dpy, surf); |
2013 | + }, std::runtime_error); |
2014 | +} |
2015 | + |
2016 | +TEST_F(HWC11Device, test_hwc_swapbuffers_failure) |
2017 | +{ |
2018 | + using namespace testing; |
2019 | + EXPECT_CALL(mock_egl, eglSwapBuffers(dpy,surf)) |
2020 | + .Times(1) |
2021 | + .WillOnce(Return(EGL_FALSE)); |
2022 | + |
2023 | + mga::HWC11Device device(mock_device, mock_fb_bundle, mock_vsync); |
2024 | + |
2025 | + EXPECT_THROW({ |
2026 | + device.commit_frame(dpy, surf); |
2027 | + }, std::runtime_error); |
2028 | } |
2029 | |
2030 | === modified file 'tests/unit-tests/graphics/android/test_hwc_device.cpp' |
2031 | --- tests/unit-tests/graphics/android/test_hwc_device.cpp 2013-11-08 18:25:19 +0000 |
2032 | +++ tests/unit-tests/graphics/android/test_hwc_device.cpp 2013-11-14 23:10:20 +0000 |
2033 | @@ -47,7 +47,7 @@ |
2034 | std::shared_ptr<mga::DisplayDevice> const& fbdev, |
2035 | std::shared_ptr<mga::HWCVsyncCoordinator> const& coordinator) |
2036 | { |
2037 | - return std::make_shared<mga::HWC10Device>(hwc_device, fbdev, coordinator); |
2038 | + return std::make_shared<mga::HWC10Device>(hwc_device, nullptr, fbdev, coordinator); |
2039 | } |
2040 | |
2041 | template <> |
2042 | @@ -56,7 +56,7 @@ |
2043 | std::shared_ptr<mga::DisplayDevice> const&, |
2044 | std::shared_ptr<mga::HWCVsyncCoordinator> const& coordinator) |
2045 | { |
2046 | - return std::make_shared<mga::HWC11Device>(hwc_device, coordinator); |
2047 | + return std::make_shared<mga::HWC11Device>(hwc_device, nullptr, coordinator); |
2048 | } |
2049 | |
2050 | template<typename T> |
2051 | |
2052 | === modified file 'tests/unit-tests/graphics/android/test_hwc_layerlist.cpp' |
2053 | --- tests/unit-tests/graphics/android/test_hwc_layerlist.cpp 2013-11-11 21:34:15 +0000 |
2054 | +++ tests/unit-tests/graphics/android/test_hwc_layerlist.cpp 2013-11-14 23:10:20 +0000 |
2055 | @@ -39,13 +39,13 @@ |
2056 | native_handle_1 = std::make_shared<mtd::StubAndroidNativeBuffer>(); |
2057 | native_handle_1->anwb()->width = width; |
2058 | native_handle_1->anwb()->height = height; |
2059 | - native_handle_2 = std::make_shared<mtd::StubAndroidNativeBuffer>(); |
2060 | + native_handle_2 = std::make_shared<mtd::MockAndroidNativeBuffer>(); |
2061 | } |
2062 | |
2063 | int width; |
2064 | int height; |
2065 | std::shared_ptr<mg::NativeBuffer> native_handle_1; |
2066 | - std::shared_ptr<mg::NativeBuffer> native_handle_2; |
2067 | + std::shared_ptr<mtd::MockAndroidNativeBuffer> native_handle_2; |
2068 | }; |
2069 | |
2070 | TEST_F(HWCLayerListTest, fb_target_layer) |
2071 | @@ -139,6 +139,12 @@ |
2072 | TEST_F(HWCLayerListTest, hwc_list_update) |
2073 | { |
2074 | using namespace testing; |
2075 | + |
2076 | + int handle_fence = 442; |
2077 | + EXPECT_CALL(*native_handle_2, copy_fence()) |
2078 | + .Times(1) |
2079 | + .WillOnce(Return(handle_fence)); |
2080 | + |
2081 | mga::LayerList layerlist({ |
2082 | mga::CompositionLayer(*native_handle_1, 0), |
2083 | mga::FramebufferLayer(*native_handle_1)}); |
2084 | @@ -146,6 +152,21 @@ |
2085 | |
2086 | auto list = layerlist.native_list(); |
2087 | ASSERT_EQ(2u, list->numHwLayers); |
2088 | - EXPECT_EQ(list->hwLayers[0].handle, native_handle_1->handle()); |
2089 | + EXPECT_EQ(native_handle_1->handle(), list->hwLayers[0].handle); |
2090 | + EXPECT_EQ(-1, list->hwLayers[0].acquireFenceFd); |
2091 | EXPECT_EQ(list->hwLayers[1].handle, native_handle_2->handle()); |
2092 | + EXPECT_EQ(handle_fence, list->hwLayers[1].acquireFenceFd); |
2093 | +} |
2094 | + |
2095 | +TEST_F(HWCLayerListTest, get_fb_fence) |
2096 | +{ |
2097 | + int release_fence = 381; |
2098 | + mga::LayerList layerlist({ |
2099 | + mga::CompositionLayer(*native_handle_1, 0), |
2100 | + mga::FramebufferLayer(*native_handle_1)}); |
2101 | + |
2102 | + auto list = layerlist.native_list(); |
2103 | + list->hwLayers[1].releaseFenceFd = release_fence; |
2104 | + |
2105 | + EXPECT_EQ(release_fence, layerlist.framebuffer_fence()); |
2106 | } |
2107 | |
2108 | === modified file 'tests/unit-tests/graphics/android/test_resource_factory.cpp' |
2109 | --- tests/unit-tests/graphics/android/test_resource_factory.cpp 2013-11-07 01:34:35 +0000 |
2110 | +++ tests/unit-tests/graphics/android/test_resource_factory.cpp 2013-11-14 23:10:20 +0000 |
2111 | @@ -42,7 +42,7 @@ |
2112 | { |
2113 | public: |
2114 | MOCK_METHOD1(alloc_buffer, std::shared_ptr<mg::Buffer>(mg::BufferProperties const&)); |
2115 | - MOCK_METHOD3(alloc_buffer_platform, std::shared_ptr<mga::Buffer>(geom::Size, geom::PixelFormat, mga::BufferUsage)); |
2116 | + MOCK_METHOD3(alloc_buffer_platform, std::shared_ptr<mg::Buffer>(geom::Size, geom::PixelFormat, mga::BufferUsage)); |
2117 | MOCK_METHOD0(supported_pixel_formats, std::vector<geom::PixelFormat>()); |
2118 | |
2119 | ~MockAndroidGraphicBufferAllocator() noexcept {} |
2120 | @@ -64,11 +64,9 @@ |
2121 | .WillByDefault(Return(geom::PixelFormat::abgr_8888)); |
2122 | ON_CALL(*mock_display_device, display_size()) |
2123 | .WillByDefault(Return(geom::Size{2, 3})); |
2124 | - ON_CALL(*mock_display_device, number_of_framebuffers_available()) |
2125 | - .WillByDefault(Return(fake_fb_num)); |
2126 | |
2127 | ON_CALL(*mock_buffer_allocator, alloc_buffer_platform(_,_,_)) |
2128 | - .WillByDefault(Return(std::shared_ptr<mga::Buffer>())); |
2129 | + .WillByDefault(Return(std::shared_ptr<mg::Buffer>())); |
2130 | } |
2131 | |
2132 | std::shared_ptr<mtd::MockDisplayReport> mock_report; |
2133 | @@ -79,34 +77,6 @@ |
2134 | testing::NiceMock<mtd::MockEGL> mock_egl; |
2135 | }; |
2136 | |
2137 | -//note: @kdub imo, the hwc api has a hole in it that it doesn't allow query for format. surfaceflinger code |
2138 | -// makes note of this api hole in its comments too. It always uses rgba8888, which we try to do too. |
2139 | -TEST_F(ResourceFactoryTest, test_native_window_creation_figures_out_fb_number) |
2140 | -{ |
2141 | - using namespace testing; |
2142 | - geom::Width disp_width{44}; |
2143 | - geom::Height disp_height{4567654}; |
2144 | - geom::Size disp_size{disp_width, disp_height}; |
2145 | - geom::PixelFormat pf = geom::PixelFormat::abgr_8888; |
2146 | - |
2147 | - EXPECT_CALL(*mock_display_device, number_of_framebuffers_available()) |
2148 | - .Times(AtLeast(1)) |
2149 | - .WillOnce(Return(fake_fb_num)); |
2150 | - EXPECT_CALL(*mock_display_device, display_size()) |
2151 | - .Times(AtLeast(1)) |
2152 | - .WillOnce(Return(disp_size)); |
2153 | - EXPECT_CALL(*mock_display_device, display_format()) |
2154 | - .Times(AtLeast(1)) |
2155 | - .WillOnce(Return(pf)); |
2156 | - |
2157 | - EXPECT_CALL(*mock_buffer_allocator, alloc_buffer_platform( |
2158 | - disp_size,pf,mga::BufferUsage::use_framebuffer_gles)) |
2159 | - .Times(fake_fb_num); |
2160 | - |
2161 | - mga::ResourceFactory factory(mock_buffer_allocator); |
2162 | - factory.create_native_window(mock_display_device); |
2163 | -} |
2164 | - |
2165 | TEST_F(ResourceFactoryTest, fb_native_creation_opens_and_closes_gralloc) |
2166 | { |
2167 | using namespace testing; |
2168 | @@ -140,7 +110,6 @@ |
2169 | EXPECT_THROW({ |
2170 | factory.create_fb_native_device(); |
2171 | }, std::runtime_error); |
2172 | - |
2173 | } |
2174 | |
2175 | TEST_F(ResourceFactoryTest, hwc_allocation) |
2176 | |
2177 | === modified file 'tests/unit-tests/graphics/android/test_server_interpreter.cpp' |
2178 | --- tests/unit-tests/graphics/android/test_server_interpreter.cpp 2013-10-25 16:39:50 +0000 |
2179 | +++ tests/unit-tests/graphics/android/test_server_interpreter.cpp 2013-11-14 23:10:20 +0000 |
2180 | @@ -17,7 +17,6 @@ |
2181 | */ |
2182 | |
2183 | #include "src/server/graphics/android/server_render_window.h" |
2184 | -#include "src/server/graphics/android/fb_swapper.h" |
2185 | |
2186 | #include "mir_test_doubles/mock_display_device.h" |
2187 | #include "mir_test_doubles/mock_buffer.h" |
2188 | @@ -30,7 +29,6 @@ |
2189 | #include <gmock/gmock.h> |
2190 | #include <stdexcept> |
2191 | |
2192 | - |
2193 | namespace mt=mir::test; |
2194 | namespace mtd=mir::test::doubles; |
2195 | namespace geom=mir::geometry; |
2196 | @@ -39,14 +37,6 @@ |
2197 | |
2198 | namespace |
2199 | { |
2200 | - |
2201 | -struct MockFBSwapper : public mga::FBSwapper |
2202 | -{ |
2203 | - ~MockFBSwapper() noexcept {} |
2204 | - MOCK_METHOD0(compositor_acquire, std::shared_ptr<mg::Buffer>()); |
2205 | - MOCK_METHOD1(compositor_release, void(std::shared_ptr<mg::Buffer> const& released_buffer)); |
2206 | -}; |
2207 | - |
2208 | struct ServerRenderWindowTest : public ::testing::Test |
2209 | { |
2210 | virtual void SetUp() |
2211 | @@ -55,7 +45,6 @@ |
2212 | mock_buffer1 = std::make_shared<NiceMock<mtd::MockBuffer>>(); |
2213 | mock_buffer2 = std::make_shared<NiceMock<mtd::MockBuffer>>(); |
2214 | mock_buffer3 = std::make_shared<NiceMock<mtd::MockBuffer>>(); |
2215 | - mock_swapper = std::make_shared<NiceMock<MockFBSwapper>>(); |
2216 | mock_display_device = std::make_shared<NiceMock<mtd::MockDisplayDevice>>(); |
2217 | mock_cache = std::make_shared<mtd::MockInterpreterResourceCache>(); |
2218 | ON_CALL(*mock_display_device, display_format()) |
2219 | @@ -66,7 +55,6 @@ |
2220 | std::shared_ptr<mtd::MockBuffer> mock_buffer2; |
2221 | std::shared_ptr<mtd::MockBuffer> mock_buffer3; |
2222 | std::shared_ptr<mtd::MockInterpreterResourceCache> mock_cache; |
2223 | - std::shared_ptr<MockFBSwapper> mock_swapper; |
2224 | std::shared_ptr<mtd::MockDisplayDevice> mock_display_device; |
2225 | }; |
2226 | } |
2227 | @@ -75,11 +63,11 @@ |
2228 | { |
2229 | using namespace testing; |
2230 | |
2231 | - mga::ServerRenderWindow render_window(mock_swapper, mock_display_device, mock_cache); |
2232 | + mga::ServerRenderWindow render_window(mock_display_device, mock_cache); |
2233 | |
2234 | auto stub_buffer = std::make_shared<mtd::StubAndroidNativeBuffer>(); |
2235 | |
2236 | - EXPECT_CALL(*mock_swapper, compositor_acquire()) |
2237 | + EXPECT_CALL(*mock_display_device, buffer_for_render()) |
2238 | .Times(1) |
2239 | .WillOnce(Return(mock_buffer1)); |
2240 | EXPECT_CALL(*mock_buffer1, native_buffer_handle()) |
2241 | @@ -101,9 +89,9 @@ |
2242 | int fake_fence = 488; |
2243 | auto stub_buffer = std::make_shared<mtd::StubAndroidNativeBuffer>(); |
2244 | |
2245 | - mga::ServerRenderWindow render_window(mock_swapper, mock_display_device, mock_cache); |
2246 | + mga::ServerRenderWindow render_window(mock_display_device, mock_cache); |
2247 | |
2248 | - EXPECT_CALL(*mock_swapper, compositor_acquire()) |
2249 | + EXPECT_CALL(*mock_display_device, buffer_for_render()) |
2250 | .Times(1) |
2251 | .WillOnce(Return(mock_buffer1)); |
2252 | EXPECT_CALL(*mock_buffer1, native_buffer_handle()) |
2253 | @@ -111,7 +99,7 @@ |
2254 | .WillOnce(Return(stub_buffer)); |
2255 | |
2256 | render_window.driver_requests_buffer(); |
2257 | - testing::Mock::VerifyAndClearExpectations(mock_swapper.get()); |
2258 | + testing::Mock::VerifyAndClearExpectations(mock_display_device.get()); |
2259 | |
2260 | std::shared_ptr<mg::Buffer> buf1 = mock_buffer1; |
2261 | EXPECT_CALL(*mock_cache, update_native_fence(stub_buffer->anwb(), fake_fence)) |
2262 | @@ -119,13 +107,9 @@ |
2263 | EXPECT_CALL(*mock_cache, retrieve_buffer(stub_buffer->anwb())) |
2264 | .Times(1) |
2265 | .WillOnce(Return(mock_buffer1)); |
2266 | - EXPECT_CALL(*mock_swapper, compositor_release(buf1)) |
2267 | - .Times(1); |
2268 | - EXPECT_CALL(*mock_display_device, set_next_frontbuffer(buf1)) |
2269 | - .Times(1); |
2270 | |
2271 | render_window.driver_returns_buffer(stub_buffer->anwb(), fake_fence); |
2272 | - testing::Mock::VerifyAndClearExpectations(mock_swapper.get()); |
2273 | + testing::Mock::VerifyAndClearExpectations(mock_display_device.get()); |
2274 | } |
2275 | |
2276 | TEST_F(ServerRenderWindowTest, driver_inquires_about_format) |
2277 | @@ -136,7 +120,7 @@ |
2278 | .Times(1) |
2279 | .WillOnce(Return(geom::PixelFormat::abgr_8888)); |
2280 | |
2281 | - mga::ServerRenderWindow render_window(mock_swapper, mock_display_device, mock_cache); |
2282 | + mga::ServerRenderWindow render_window(mock_display_device, mock_cache); |
2283 | |
2284 | EXPECT_EQ(HAL_PIXEL_FORMAT_RGBA_8888, render_window.driver_requests_info(NATIVE_WINDOW_FORMAT)); |
2285 | } |
2286 | @@ -145,7 +129,7 @@ |
2287 | { |
2288 | using namespace testing; |
2289 | |
2290 | - mga::ServerRenderWindow render_window(mock_swapper, mock_display_device, mock_cache); |
2291 | + mga::ServerRenderWindow render_window(mock_display_device, mock_cache); |
2292 | |
2293 | render_window.dispatch_driver_request_format(HAL_PIXEL_FORMAT_RGBX_8888); |
2294 | auto rc_format = render_window.driver_requests_info(NATIVE_WINDOW_FORMAT); |
2295 | @@ -160,7 +144,7 @@ |
2296 | .Times(4) |
2297 | .WillRepeatedly(Return(test_size)); |
2298 | |
2299 | - mga::ServerRenderWindow render_window(mock_swapper, mock_display_device, mock_cache); |
2300 | + mga::ServerRenderWindow render_window(mock_display_device, mock_cache); |
2301 | |
2302 | unsigned int rc_width = render_window.driver_requests_info(NATIVE_WINDOW_DEFAULT_WIDTH); |
2303 | unsigned int rc_height = render_window.driver_requests_info(NATIVE_WINDOW_DEFAULT_HEIGHT); |
2304 | @@ -177,7 +161,7 @@ |
2305 | { |
2306 | using namespace testing; |
2307 | |
2308 | - mga::ServerRenderWindow render_window(mock_swapper, mock_display_device, mock_cache); |
2309 | + mga::ServerRenderWindow render_window(mock_display_device, mock_cache); |
2310 | |
2311 | EXPECT_EQ(0, render_window.driver_requests_info(NATIVE_WINDOW_TRANSFORM_HINT)); |
2312 | } |
2313 | @@ -185,7 +169,7 @@ |
2314 | TEST_F(ServerRenderWindowTest, driver_unknown_inquiry) |
2315 | { |
2316 | using namespace testing; |
2317 | - mga::ServerRenderWindow render_window(mock_swapper, mock_display_device, mock_cache); |
2318 | + mga::ServerRenderWindow render_window(mock_display_device, mock_cache); |
2319 | |
2320 | EXPECT_THROW({ |
2321 | render_window.driver_requests_info(NATIVE_WINDOW_CONSUMER_RUNNING_BEHIND); |
2322 | @@ -194,7 +178,7 @@ |
2323 | |
2324 | TEST_F(ServerRenderWindowTest, driver_swapinterval_request) |
2325 | { |
2326 | - mga::ServerRenderWindow render_window(mock_swapper, mock_display_device, mock_cache); |
2327 | + mga::ServerRenderWindow render_window(mock_display_device, mock_cache); |
2328 | |
2329 | EXPECT_CALL(*mock_display_device, sync_to_display(false)) |
2330 | .Times(1); |
I don't understand all the detail but I'm happy with what I do follow.