Mir

Merge lp:~kdub/mir/n10-support into lp:mir

Proposed by Kevin DuBois
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
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 EGLNativeWindowType. This caused some problems because we had the native window, the state tracker and the display poster all having to keep track of the buffer state.

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::FramebufferBundle and simply passthrough the functions. I made note of this in line 199. My plan is to remove the four noted functions from mga::DisplayDevice at the same that I address the strange mga::DisplayBufferFactory class. After addressing all that, the mga::DisplayBuffer will own a mga::FramebuffeBundle, which it will use to manage the framebuffers, and it will also have a mga::DisplayDevice class that is solely in change of posting a buffer and turning on/off the display. (no more buffer tracking in DisplayDevice)

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)

To post a comment you must log in.
Revision history for this message
Alan Griffiths (alan-griffiths) wrote :

I don't understand all the detail but I'm happy with what I do follow.

review: Approve
Revision history for this message
Alexandros Frantzis (afrantzis) wrote :

> I don't understand all the detail but I'm happy with what I do follow.

Likewise.

review: Approve
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
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.

review: Approve (manual testing)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
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);

Subscribers

People subscribed via source and target branches