Mir

Merge lp:~kdub/mir/android-display-factory into lp:~mir-team/mir/trunk

Proposed by Kevin DuBois
Status: Merged
Approved by: Kevin DuBois
Approved revision: no longer in the source branch.
Merged at revision: 528
Proposed branch: lp:~kdub/mir/android-display-factory
Merge into: lp:~mir-team/mir/trunk
Diff against target: 1393 lines (+1156/-23)
20 files modified
3rd_party/android-deps/hardware/hwcomposer_defs.h (+205/-0)
3rd_party/android-deps/hardware/hwcomposer_v0.h (+272/-0)
include/test/mir_test/hw_mock.h (+64/-0)
include/test/mir_test_doubles/mock_hwc_composer_device_1.h (+44/-0)
src/server/graphics/android/CMakeLists.txt (+2/-0)
src/server/graphics/android/android_alloc_adaptor.cpp (+1/-0)
src/server/graphics/android/android_display_selector.cpp (+58/-0)
src/server/graphics/android/android_display_selector.h (+52/-0)
src/server/graphics/android/android_fb_factory.cpp (+44/-0)
src/server/graphics/android/android_fb_factory.h (+42/-0)
src/server/graphics/android/android_platform.cpp (+5/-10)
src/server/graphics/android/display_selector.h (+49/-0)
src/server/graphics/android/fb_factory.h (+56/-0)
tests/unit-tests/client/test_client_platform.cpp (+14/-3)
tests/unit-tests/graphics/android/CMakeLists.txt (+1/-0)
tests/unit-tests/graphics/android/test_android_buffer_allocator.cpp (+15/-3)
tests/unit-tests/graphics/android/test_android_framebuffer_selector.cpp (+127/-0)
tests/unit-tests/graphics/egl_mock/CMakeLists.txt (+9/-2)
tests/unit-tests/graphics/egl_mock/hw_mock.cpp (+86/-0)
tests/unit-tests/graphics/test_graphics_platform.cpp (+10/-5)
To merge this branch: bzr merge lp:~kdub/mir/android-display-factory
Reviewer Review Type Date Requested Status
PS Jenkins bot (community) continuous-integration Approve
Alexandros Frantzis (community) Approve
Alan Griffiths Approve
Review via email: mp+153907@code.launchpad.net

Commit message

change construction of android output so that the best available output path can be used

Description of the change

change construction of android output so that the best available output path can be used

Android has different output paths. Mir is using the fallback gpu output path at the moment. Most android devices use their HWC module as the output path and fall back to the GPU mode if the hwc is not available. This change detects the output paths available on the device at mg::Display construction and allocs the best display type.

Specifically, this change detects if we have HWC 1.1 (the version that the nexus 4 uses) available, and constructs using a different function if it is. If it is not, it constructs the gpu display.

I anticipate we'll have to eventually support gpu (the fallback), hwc 1.0 (galaxy nexus), 1.1 (nexus4) and 1.2 (most recent hwc version). These versions have some commonality, but the versions were undergoing sufficiently rapid changes that we should construct different HWC objects for the different versions.

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Kevin DuBois (kdub) wrote :

also, there are 2 files (hwcomposer_deps.h and hwcomposer_v0.h) that have been added from the android hardware libraries, which are needed, but were left out when I add hwcomposer.h

Revision history for this message
Alan Griffiths (alan-griffiths) wrote :

504 - mc::Compositor compositor{surface_stack,gl_renderer};
505 + mc::DefaultCompositingStrategy compositing_strategy{surface_stack,gl_renderer};

This reminds me we should rewrite render_surfaces to use DefaultServerConfiguration to configure things, rather than code the knowledge here too.

Revision history for this message
Alan Griffiths (alan-griffiths) wrote :

Hmm, there are a lot of lines in the web diff that don't belong. I guess a missing pre-req has landed.

Revision history for this message
Alan Griffiths (alan-griffiths) wrote :

1402 + if (display_type == mga::DisplayType::HWC_1_1)
1403 + {
1404 + return fb_factory->create_hwc1_1_gpu_display();
1405 + } else {
1406 + return fb_factory->create_gpu_display();
1407 + }

I'm not sure why we need DisplayType to support this use.

Polymorphism (or a function pointer) would seem more natural.

Anyway "} else {" appears a few times and isn't our style.

review: Needs Fixing
Revision history for this message
Kevin DuBois (kdub) wrote :

> 1402 + if (display_type == mga::DisplayType::HWC_1_1)
> 1403 + {
> 1404 + return fb_factory->create_hwc1_1_gpu_display();
> 1405 + } else {
> 1406 + return fb_factory->create_gpu_display();
> 1407 + }
>
> I'm not sure why we need DisplayType to support this use.
>

good point, i'll rework

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Alan Griffiths (alan-griffiths) wrote :

741 + std::function<std::shared_ptr<Display>()> allocate_primary_fb;

This could be a simple pointer to member function. Vis:

typedef std::shared_ptr<Display>() (FBFactory::*AllocatePrimaryFb)();
AllocatePrimaryFb allocate_primary_fb;

Revision history for this message
Alan Griffiths (alan-griffiths) :
review: Approve
Revision history for this message
Alexandros Frantzis (afrantzis) wrote :

1083 -class AndroidBufferAllocatorTest : public ::testing::Test
1084 +struct AndroidBufferAllocatorTest : public ::testing::Test
1085 {
1086 + testing::NiceMock<mt::HardwareAccessMock> hw_access_mock;
1087 public:

Remove "public" (since this is now a struct)?

1232 +set(C_MOCKS_SOURCES

What does the C in C_MOCKS_SOURCES mean. C code?

663 + : fb_factory(factory)
1281 + : mock_hw_device(device)
... and other places

There are inconsistencies in the way the constructor lists are indented. Our guidelines say 4 spaces.

675 + hw_device_t* hwc_device;
676 + hw_module->methods->open(hw_module, HWC_HARDWARE_COMPOSER, &hwc_device);
678 + if (hwc_device->version == HWC_DEVICE_API_VERSION_1_1)

Shouldn't we be checking if the operation succeeds before using the hwc_device pointer?

975 + virtual ~FBFactory() {};

-;

1332 + ADD_FAILURE_AT(__FILE__,__LINE__);

An assertion would probably be a better choice here, or is there a test case in which we need to continue regardless of the error?

review: Needs Fixing
Revision history for this message
Kevin DuBois (kdub) wrote :

should have addressed the concerns, except
> 1332 + ADD_FAILURE_AT(__FILE__,__LINE__);
>
> An assertion would probably be a better choice here, or is there a test case
> in which we need to continue regardless of the error?

gtest's ASSERT_ macros didn't work here, I think thats why we did this way with the egl/gl mocks as well

Revision history for this message
Kevin DuBois (kdub) wrote :

> 1232 +set(C_MOCKS_SOURCES
>
> What does the C in C_MOCKS_SOURCES mean. C code?
that was the idea, but i changed it to be consistent with the name of the library

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

Looks good.

review: Approve
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== added file '3rd_party/android-deps/hardware/hwcomposer_defs.h'
2--- 3rd_party/android-deps/hardware/hwcomposer_defs.h 1970-01-01 00:00:00 +0000
3+++ 3rd_party/android-deps/hardware/hwcomposer_defs.h 2013-03-22 15:42:23 +0000
4@@ -0,0 +1,205 @@
5+/*
6+ * Copyright (C) 2010 The Android Open Source Project
7+ *
8+ * Licensed under the Apache License, Version 2.0 (the "License");
9+ * you may not use this file except in compliance with the License.
10+ * You may obtain a copy of the License at
11+ *
12+ * http://www.apache.org/licenses/LICENSE-2.0
13+ *
14+ * Unless required by applicable law or agreed to in writing, software
15+ * distributed under the License is distributed on an "AS IS" BASIS,
16+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17+ * See the License for the specific language governing permissions and
18+ * limitations under the License.
19+ */
20+
21+#ifndef ANDROID_INCLUDE_HARDWARE_HWCOMPOSER_DEFS_H
22+#define ANDROID_INCLUDE_HARDWARE_HWCOMPOSER_DEFS_H
23+
24+#include <stdint.h>
25+#include <sys/cdefs.h>
26+
27+#include <hardware/gralloc.h>
28+#include <hardware/hardware.h>
29+#include <cutils/native_handle.h>
30+
31+__BEGIN_DECLS
32+
33+/*****************************************************************************/
34+
35+#define HWC_HEADER_VERSION 1
36+
37+#define HWC_MODULE_API_VERSION_0_1 HARDWARE_MODULE_API_VERSION(0, 1)
38+
39+#define HWC_DEVICE_API_VERSION_0_1 HARDWARE_DEVICE_API_VERSION_2(0, 1, HWC_HEADER_VERSION)
40+#define HWC_DEVICE_API_VERSION_0_2 HARDWARE_DEVICE_API_VERSION_2(0, 2, HWC_HEADER_VERSION)
41+#define HWC_DEVICE_API_VERSION_0_3 HARDWARE_DEVICE_API_VERSION_2(0, 3, HWC_HEADER_VERSION)
42+#define HWC_DEVICE_API_VERSION_1_0 HARDWARE_DEVICE_API_VERSION_2(1, 0, HWC_HEADER_VERSION)
43+#define HWC_DEVICE_API_VERSION_1_1 HARDWARE_DEVICE_API_VERSION_2(1, 1, HWC_HEADER_VERSION)
44+#define HWC_DEVICE_API_VERSION_1_2 HARDWARE_DEVICE_API_VERSION_2(1, 2, HWC_HEADER_VERSION)
45+
46+enum {
47+ /* hwc_composer_device_t::set failed in EGL */
48+ HWC_EGL_ERROR = -1
49+};
50+
51+/*
52+ * hwc_layer_t::hints values
53+ * Hints are set by the HAL and read by SurfaceFlinger
54+ */
55+enum {
56+ /*
57+ * HWC can set the HWC_HINT_TRIPLE_BUFFER hint to indicate to SurfaceFlinger
58+ * that it should triple buffer this layer. Typically HWC does this when
59+ * the layer will be unavailable for use for an extended period of time,
60+ * e.g. if the display will be fetching data directly from the layer and
61+ * the layer can not be modified until after the next set().
62+ */
63+ HWC_HINT_TRIPLE_BUFFER = 0x00000001,
64+
65+ /*
66+ * HWC sets HWC_HINT_CLEAR_FB to tell SurfaceFlinger that it should clear the
67+ * framebuffer with transparent pixels where this layer would be.
68+ * SurfaceFlinger will only honor this flag when the layer has no blending
69+ *
70+ */
71+ HWC_HINT_CLEAR_FB = 0x00000002
72+};
73+
74+/*
75+ * hwc_layer_t::flags values
76+ * Flags are set by SurfaceFlinger and read by the HAL
77+ */
78+enum {
79+ /*
80+ * HWC_SKIP_LAYER is set by SurfaceFlnger to indicate that the HAL
81+ * shall not consider this layer for composition as it will be handled
82+ * by SurfaceFlinger (just as if compositionType was set to HWC_OVERLAY).
83+ */
84+ HWC_SKIP_LAYER = 0x00000001,
85+};
86+
87+/*
88+ * hwc_layer_t::compositionType values
89+ */
90+enum {
91+ /* this layer is to be drawn into the framebuffer by SurfaceFlinger */
92+ HWC_FRAMEBUFFER = 0,
93+
94+ /* this layer will be handled in the HWC */
95+ HWC_OVERLAY = 1,
96+
97+ /* this is the background layer. it's used to set the background color.
98+ * there is only a single background layer */
99+ HWC_BACKGROUND = 2,
100+
101+ /* this layer holds the result of compositing the HWC_FRAMEBUFFER layers.
102+ * Added in HWC_DEVICE_API_VERSION_1_1. */
103+ HWC_FRAMEBUFFER_TARGET = 3,
104+
105+ /* this layer will be handled in the HWC, using a blit engine */
106+ HWC_BLIT = 4,
107+};
108+
109+/*
110+ * hwc_layer_t::blending values
111+ */
112+enum {
113+ /* no blending */
114+ HWC_BLENDING_NONE = 0x0100,
115+
116+ /* ONE / ONE_MINUS_SRC_ALPHA */
117+ HWC_BLENDING_PREMULT = 0x0105,
118+
119+ /* SRC_ALPHA / ONE_MINUS_SRC_ALPHA */
120+ HWC_BLENDING_COVERAGE = 0x0405
121+};
122+
123+/*
124+ * hwc_layer_t::transform values
125+ */
126+enum {
127+ /* flip source image horizontally */
128+ HWC_TRANSFORM_FLIP_H = HAL_TRANSFORM_FLIP_H,
129+ /* flip source image vertically */
130+ HWC_TRANSFORM_FLIP_V = HAL_TRANSFORM_FLIP_V,
131+ /* rotate source image 90 degrees clock-wise */
132+ HWC_TRANSFORM_ROT_90 = HAL_TRANSFORM_ROT_90,
133+ /* rotate source image 180 degrees */
134+ HWC_TRANSFORM_ROT_180 = HAL_TRANSFORM_ROT_180,
135+ /* rotate source image 270 degrees clock-wise */
136+ HWC_TRANSFORM_ROT_270 = HAL_TRANSFORM_ROT_270,
137+};
138+
139+/* attributes queriable with query() */
140+enum {
141+ /*
142+ * Availability: HWC_DEVICE_API_VERSION_0_2
143+ * Must return 1 if the background layer is supported, 0 otherwise.
144+ */
145+ HWC_BACKGROUND_LAYER_SUPPORTED = 0,
146+
147+ /*
148+ * Availability: HWC_DEVICE_API_VERSION_0_3
149+ * Returns the vsync period in nanoseconds.
150+ *
151+ * This query is not used for HWC_DEVICE_API_VERSION_1_1 and later.
152+ * Instead, the per-display attribute HWC_DISPLAY_VSYNC_PERIOD is used.
153+ */
154+ HWC_VSYNC_PERIOD = 1,
155+
156+ /*
157+ * Availability: HWC_DEVICE_API_VERSION_1_1
158+ * Returns a mask of supported display types.
159+ */
160+ HWC_DISPLAY_TYPES_SUPPORTED = 2,
161+};
162+
163+/* display attributes returned by getDisplayAttributes() */
164+enum {
165+ /* Indicates the end of an attribute list */
166+ HWC_DISPLAY_NO_ATTRIBUTE = 0,
167+
168+ /* The vsync period in nanoseconds */
169+ HWC_DISPLAY_VSYNC_PERIOD = 1,
170+
171+ /* The number of pixels in the horizontal and vertical directions. */
172+ HWC_DISPLAY_WIDTH = 2,
173+ HWC_DISPLAY_HEIGHT = 3,
174+
175+ /* The number of pixels per thousand inches of this configuration.
176+ *
177+ * Scaling DPI by 1000 allows it to be stored in an int without losing
178+ * too much precision.
179+ *
180+ * If the DPI for a configuration is unavailable or the HWC implementation
181+ * considers it unreliable, it should set these attributes to zero.
182+ */
183+ HWC_DISPLAY_DPI_X = 4,
184+ HWC_DISPLAY_DPI_Y = 5,
185+};
186+
187+/* Allowed events for hwc_methods::eventControl() */
188+enum {
189+ HWC_EVENT_VSYNC = 0,
190+ HWC_EVENT_ORIENTATION // To notify HWC about the device orientation
191+};
192+
193+/* Display types and associated mask bits. */
194+enum {
195+ HWC_DISPLAY_PRIMARY = 0,
196+ HWC_DISPLAY_EXTERNAL = 1, // HDMI, DP, etc.
197+ HWC_NUM_DISPLAY_TYPES
198+};
199+
200+enum {
201+ HWC_DISPLAY_PRIMARY_BIT = 1 << HWC_DISPLAY_PRIMARY,
202+ HWC_DISPLAY_EXTERNAL_BIT = 1 << HWC_DISPLAY_EXTERNAL,
203+};
204+
205+/*****************************************************************************/
206+
207+__END_DECLS
208+
209+#endif /* ANDROID_INCLUDE_HARDWARE_HWCOMPOSER_DEFS_H */
210
211=== added file '3rd_party/android-deps/hardware/hwcomposer_v0.h'
212--- 3rd_party/android-deps/hardware/hwcomposer_v0.h 1970-01-01 00:00:00 +0000
213+++ 3rd_party/android-deps/hardware/hwcomposer_v0.h 2013-03-22 15:42:23 +0000
214@@ -0,0 +1,272 @@
215+/*
216+ * Copyright (C) 2010 The Android Open Source Project
217+ *
218+ * Licensed under the Apache License, Version 2.0 (the "License");
219+ * you may not use this file except in compliance with the License.
220+ * You may obtain a copy of the License at
221+ *
222+ * http://www.apache.org/licenses/LICENSE-2.0
223+ *
224+ * Unless required by applicable law or agreed to in writing, software
225+ * distributed under the License is distributed on an "AS IS" BASIS,
226+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
227+ * See the License for the specific language governing permissions and
228+ * limitations under the License.
229+ */
230+
231+/* This header contains deprecated HWCv0 interface declarations. Don't include
232+ * this header directly; it will be included by <hardware/hwcomposer.h> unless
233+ * HWC_REMOVE_DEPRECATED_VERSIONS is defined to non-zero.
234+ */
235+#ifndef ANDROID_INCLUDE_HARDWARE_HWCOMPOSER_H
236+#error "This header should only be included by hardware/hwcomposer.h"
237+#endif
238+
239+#ifndef ANDROID_INCLUDE_HARDWARE_HWCOMPOSER_V0_H
240+#define ANDROID_INCLUDE_HARDWARE_HWCOMPOSER_V0_H
241+
242+struct hwc_composer_device;
243+
244+/*
245+ * availability: HWC_DEVICE_API_VERSION_0_3
246+ *
247+ * struct hwc_methods cannot be embedded in other structures as
248+ * sizeof(struct hwc_methods) cannot be relied upon.
249+ *
250+ */
251+typedef struct hwc_methods {
252+
253+ /*************************************************************************
254+ * HWC_DEVICE_API_VERSION_0_3
255+ *************************************************************************/
256+
257+ /*
258+ * eventControl(..., event, enabled)
259+ * Enables or disables h/w composer events.
260+ *
261+ * eventControl can be called from any thread and takes effect
262+ * immediately.
263+ *
264+ * Supported events are:
265+ * HWC_EVENT_VSYNC
266+ *
267+ * returns -EINVAL if the "event" parameter is not one of the value above
268+ * or if the "enabled" parameter is not 0 or 1.
269+ */
270+
271+ int (*eventControl)(
272+ struct hwc_composer_device* dev, int event, int enabled);
273+
274+} hwc_methods_t;
275+
276+typedef struct hwc_layer {
277+ /*
278+ * initially set to HWC_FRAMEBUFFER or HWC_BACKGROUND.
279+ * HWC_FRAMEBUFFER
280+ * indicates the layer will be drawn into the framebuffer
281+ * using OpenGL ES.
282+ * The HWC can toggle this value to HWC_OVERLAY, to indicate
283+ * it will handle the layer.
284+ *
285+ * HWC_BACKGROUND
286+ * indicates this is a special "background" layer. The only valid
287+ * field is backgroundColor. HWC_BACKGROUND can only be used with
288+ * HWC_API_VERSION >= 0.2
289+ * The HWC can toggle this value to HWC_FRAMEBUFFER, to indicate
290+ * it CANNOT handle the background color
291+ *
292+ */
293+ int32_t compositionType;
294+
295+ /* see hwc_layer_t::hints above */
296+ uint32_t hints;
297+
298+ /* see hwc_layer_t::flags above */
299+ uint32_t flags;
300+
301+ union {
302+ /* color of the background. hwc_color_t.a is ignored */
303+ hwc_color_t backgroundColor;
304+
305+ struct {
306+ /* handle of buffer to compose. This handle is guaranteed to have been
307+ * allocated from gralloc using the GRALLOC_USAGE_HW_COMPOSER usage flag. If
308+ * the layer's handle is unchanged across two consecutive prepare calls and
309+ * the HWC_GEOMETRY_CHANGED flag is not set for the second call then the
310+ * HWComposer implementation may assume that the contents of the buffer have
311+ * not changed. */
312+ buffer_handle_t handle;
313+
314+ /* transformation to apply to the buffer during composition */
315+ uint32_t transform;
316+
317+ /* blending to apply during composition */
318+ int32_t blending;
319+
320+ /* area of the source to consider, the origin is the top-left corner of
321+ * the buffer */
322+ hwc_rect_t sourceCrop;
323+
324+ /* where to composite the sourceCrop onto the display. The sourceCrop
325+ * is scaled using linear filtering to the displayFrame. The origin is the
326+ * top-left corner of the screen.
327+ */
328+ hwc_rect_t displayFrame;
329+
330+ /* visible region in screen space. The origin is the
331+ * top-left corner of the screen.
332+ * The visible region INCLUDES areas overlapped by a translucent layer.
333+ */
334+ hwc_region_t visibleRegionScreen;
335+ };
336+ };
337+} hwc_layer_t;
338+
339+/*
340+ * List of layers.
341+ * The handle members of hwLayers elements must be unique.
342+ */
343+typedef struct hwc_layer_list {
344+ uint32_t flags;
345+ size_t numHwLayers;
346+ hwc_layer_t hwLayers[0];
347+} hwc_layer_list_t;
348+
349+/*****************************************************************************/
350+
351+typedef struct hwc_composer_device {
352+ struct hw_device_t common;
353+
354+ /*
355+ * (*prepare)() is called for each frame before composition and is used by
356+ * SurfaceFlinger to determine what composition steps the HWC can handle.
357+ *
358+ * (*prepare)() can be called more than once, the last call prevails.
359+ *
360+ * The HWC responds by setting the compositionType field to either
361+ * HWC_FRAMEBUFFER or HWC_OVERLAY. In the former case, the composition for
362+ * this layer is handled by SurfaceFlinger with OpenGL ES, in the later
363+ * case, the HWC will have to handle this layer's composition.
364+ *
365+ * (*prepare)() is called with HWC_GEOMETRY_CHANGED to indicate that the
366+ * list's geometry has changed, that is, when more than just the buffer's
367+ * handles have been updated. Typically this happens (but is not limited to)
368+ * when a window is added, removed, resized or moved.
369+ *
370+ * a NULL list parameter or a numHwLayers of zero indicates that the
371+ * entire composition will be handled by SurfaceFlinger with OpenGL ES.
372+ *
373+ * returns: 0 on success. An negative error code on error. If an error is
374+ * returned, SurfaceFlinger will assume that none of the layer will be
375+ * handled by the HWC.
376+ */
377+ int (*prepare)(struct hwc_composer_device *dev, hwc_layer_list_t* list);
378+
379+ /*
380+ * (*set)() is used in place of eglSwapBuffers(), and assumes the same
381+ * functionality, except it also commits the work list atomically with
382+ * the actual eglSwapBuffers().
383+ *
384+ * The list parameter is guaranteed to be the same as the one returned
385+ * from the last call to (*prepare)().
386+ *
387+ * When this call returns the caller assumes that:
388+ *
389+ * - the display will be updated in the near future with the content
390+ * of the work list, without artifacts during the transition from the
391+ * previous frame.
392+ *
393+ * - all objects are available for immediate access or destruction, in
394+ * particular, hwc_region_t::rects data and hwc_layer_t::layer's buffer.
395+ * Note that this means that immediately accessing (potentially from a
396+ * different process) a buffer used in this call will not result in
397+ * screen corruption, the driver must apply proper synchronization or
398+ * scheduling (eg: block the caller, such as gralloc_module_t::lock(),
399+ * OpenGL ES, Camera, Codecs, etc..., or schedule the caller's work
400+ * after the buffer is freed from the actual composition).
401+ *
402+ * a NULL list parameter or a numHwLayers of zero indicates that the
403+ * entire composition has been handled by SurfaceFlinger with OpenGL ES.
404+ * In this case, (*set)() behaves just like eglSwapBuffers().
405+ *
406+ * dpy, sur, and list are set to NULL to indicate that the screen is
407+ * turning off. This happens WITHOUT prepare() being called first.
408+ * This is a good time to free h/w resources and/or power
409+ * the relevant h/w blocks down.
410+ *
411+ * IMPORTANT NOTE: there is an implicit layer containing opaque black
412+ * pixels behind all the layers in the list.
413+ * It is the responsibility of the hwcomposer module to make
414+ * sure black pixels are output (or blended from).
415+ *
416+ * returns: 0 on success. An negative error code on error:
417+ * HWC_EGL_ERROR: eglGetError() will provide the proper error code
418+ * Another code for non EGL errors.
419+ *
420+ */
421+ int (*set)(struct hwc_composer_device *dev,
422+ hwc_display_t dpy,
423+ hwc_surface_t sur,
424+ hwc_layer_list_t* list);
425+
426+ /*
427+ * This field is OPTIONAL and can be NULL.
428+ *
429+ * If non NULL it will be called by SurfaceFlinger on dumpsys
430+ */
431+ void (*dump)(struct hwc_composer_device* dev, char *buff, int buff_len);
432+
433+ /*
434+ * This field is OPTIONAL and can be NULL.
435+ *
436+ * (*registerProcs)() registers a set of callbacks the h/w composer HAL
437+ * can later use. It is FORBIDDEN to call any of the callbacks from
438+ * within registerProcs(). registerProcs() must save the hwc_procs_t pointer
439+ * which is needed when calling a registered callback.
440+ * Each call to registerProcs replaces the previous set of callbacks.
441+ * registerProcs is called with NULL to unregister all callbacks.
442+ *
443+ * Any of the callbacks can be NULL, in which case the corresponding
444+ * functionality is not supported.
445+ */
446+ void (*registerProcs)(struct hwc_composer_device* dev,
447+ hwc_procs_t const* procs);
448+
449+ /*
450+ * This field is OPTIONAL and can be NULL.
451+ * availability: HWC_DEVICE_API_VERSION_0_2
452+ *
453+ * Used to retrieve information about the h/w composer
454+ *
455+ * Returns 0 on success or -errno on error.
456+ */
457+ int (*query)(struct hwc_composer_device* dev, int what, int* value);
458+
459+ /*
460+ * Reserved for future use. Must be NULL.
461+ */
462+ void* reserved_proc[4];
463+
464+ /*
465+ * This field is OPTIONAL and can be NULL.
466+ * availability: HWC_DEVICE_API_VERSION_0_3
467+ */
468+ hwc_methods_t const *methods;
469+
470+} hwc_composer_device_t;
471+
472+/** convenience API for opening and closing a device */
473+
474+static inline int hwc_open(const struct hw_module_t* module,
475+ hwc_composer_device_t** device) {
476+ return module->methods->open(module,
477+ HWC_HARDWARE_COMPOSER, (struct hw_device_t**)device);
478+}
479+
480+static inline int hwc_close(hwc_composer_device_t* device) {
481+ return device->common.close(&device->common);
482+}
483+
484+/*****************************************************************************/
485+
486+#endif /* ANDROID_INCLUDE_HARDWARE_HWCOMPOSER_V0_H */
487
488=== added file 'include/test/mir_test/hw_mock.h'
489--- include/test/mir_test/hw_mock.h 1970-01-01 00:00:00 +0000
490+++ include/test/mir_test/hw_mock.h 2013-03-22 15:42:23 +0000
491@@ -0,0 +1,64 @@
492+/*
493+ * Copyright © 2013 Canonical Ltd.
494+ *
495+ * This program is free software: you can redistribute it and/or modify it
496+ * under the terms of the GNU Lesser General Public License version 3,
497+ * as published by the Free Software Foundation.
498+ *
499+ * This program is distributed in the hope that it will be useful,
500+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
501+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
502+ * GNU General Public License for more details.
503+ *
504+ * You should have received a copy of the GNU Lesser General Public License
505+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
506+ *
507+ * Authored by: Kevin DuBois <kevin.dubois@canonical.com>
508+ */
509+#ifndef MIR_TEST_DOUBLES_MOCK_ANDROID_HWC_DEVICE_H_
510+#define MIR_TEST_DOUBLES_MOCK_ANDROID_HWC_DEVICE_H_
511+
512+#include "mir_test_doubles/mock_android_alloc_device.h"
513+#include "mir_test_doubles/mock_hwc_composer_device_1.h"
514+
515+#include <hardware/hardware.h>
516+#include <gmock/gmock.h>
517+#include <memory>
518+
519+namespace mir
520+{
521+namespace test
522+{
523+
524+typedef struct hw_module_t hw_module;
525+class HardwareModuleStub : public hw_module
526+{
527+public:
528+ HardwareModuleStub(hw_device_t& device);
529+
530+ static int hw_open(const struct hw_module_t* module, const char*, struct hw_device_t** device);
531+ static int hw_close(struct hw_device_t*);
532+
533+ hw_module_methods_t gr_methods;
534+ hw_device_t& mock_hw_device;
535+};
536+
537+class HardwareAccessMock
538+{
539+public:
540+ HardwareAccessMock();
541+ ~HardwareAccessMock();
542+
543+ MOCK_METHOD2(hw_get_module, int(const char *id, const struct hw_module_t**));
544+
545+ std::shared_ptr<alloc_device_t> mock_alloc_device;
546+ std::shared_ptr<hwc_composer_device_1> mock_hwc_device;
547+
548+ std::shared_ptr<HardwareModuleStub> mock_gralloc_module;
549+ std::shared_ptr<HardwareModuleStub> mock_hwc_module;
550+};
551+
552+}
553+}
554+
555+#endif /* MIR_TEST_DOUBLES_MOCK_ANDROID_HWC_DEVICE_H_ */
556
557=== added file 'include/test/mir_test_doubles/mock_hwc_composer_device_1.h'
558--- include/test/mir_test_doubles/mock_hwc_composer_device_1.h 1970-01-01 00:00:00 +0000
559+++ include/test/mir_test_doubles/mock_hwc_composer_device_1.h 2013-03-22 15:42:23 +0000
560@@ -0,0 +1,44 @@
561+/*
562+ * Copyright © 2013 Canonical Ltd.
563+ *
564+ * This program is free software: you can redistribute it and/or modify it
565+ * under the terms of the GNU Lesser General Public License version 3,
566+ * as published by the Free Software Foundation.
567+ *
568+ * This program is distributed in the hope that it will be useful,
569+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
570+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
571+ * GNU General Public License for more details.
572+ *
573+ * You should have received a copy of the GNU Lesser General Public License
574+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
575+ *
576+ * Authored by: Kevin DuBois <kevin.dubois@canonical.com>
577+ */
578+
579+#ifndef MIR_TEST_DOUBLES_MOCK_HWC_COMPOSER_DEVICE_1_H_
580+#define MIR_TEST_DOUBLES_MOCK_HWC_COMPOSER_DEVICE_1_H_
581+
582+#include <hardware/hwcomposer.h>
583+
584+namespace mir
585+{
586+namespace test
587+{
588+namespace doubles
589+{
590+
591+class MockHWCComposerDevice1 : public hwc_composer_device_1
592+{
593+public:
594+ MockHWCComposerDevice1()
595+ {
596+ common.version = HWC_DEVICE_API_VERSION_1_1;
597+ }
598+};
599+
600+}
601+}
602+}
603+
604+#endif /* MIR_TEST_DOUBLES_MOCK_HWC_COMPOSER_DEVICE_1_H_ */
605
606=== modified file 'src/server/graphics/android/CMakeLists.txt'
607--- src/server/graphics/android/CMakeLists.txt 2013-03-21 03:32:59 +0000
608+++ src/server/graphics/android/CMakeLists.txt 2013-03-22 15:42:23 +0000
609@@ -12,7 +12,9 @@
610 android_buffer.cpp
611 android_buffer_handle.cpp
612 android_display.cpp
613+ android_display_selector.cpp
614 android_framebuffer_window.cpp
615+ android_fb_factory.cpp
616 android_alloc_adaptor.cpp
617 )
618
619
620=== modified file 'src/server/graphics/android/android_alloc_adaptor.cpp'
621--- src/server/graphics/android/android_alloc_adaptor.cpp 2013-03-13 04:54:15 +0000
622+++ src/server/graphics/android/android_alloc_adaptor.cpp 2013-03-22 15:42:23 +0000
623@@ -74,6 +74,7 @@
624 ret = alloc_dev->alloc(alloc_dev.get(), (int) size.width.as_uint32_t(), (int) size.height.as_uint32_t(),
625 format, usage_flag, &buf_handle, &stride_as_int);
626
627+ //todo: kdub we should not be passing an empty ptr around like this
628 AndroidBufferHandleEmptyDeleter empty_del;
629 AndroidBufferHandle *null_handle = NULL;
630 if (( ret ) || (buf_handle == NULL) || (stride_as_int == 0))
631
632=== added file 'src/server/graphics/android/android_display_selector.cpp'
633--- src/server/graphics/android/android_display_selector.cpp 1970-01-01 00:00:00 +0000
634+++ src/server/graphics/android/android_display_selector.cpp 2013-03-22 15:42:23 +0000
635@@ -0,0 +1,58 @@
636+/*
637+ * Copyright © 2013 Canonical Ltd.
638+ *
639+ * This program is free software: you can redistribute it and/or modify
640+ * it under the terms of the GNU General Public License version 3 as
641+ * published by the Free Software Foundation.
642+ *
643+ * This program is distributed in the hope that it will be useful,
644+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
645+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
646+ * GNU General Public License for more details.
647+ *
648+ * You should have received a copy of the GNU General Public License
649+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
650+ *
651+ * Authored by: Kevin DuBois <kevin.dubois@canonical.com>
652+ */
653+
654+#include "android_display_selector.h"
655+#include "android_fb_factory.h"
656+
657+#include <hardware/hwcomposer.h>
658+
659+namespace mg=mir::graphics;
660+namespace mga=mir::graphics::android;
661+
662+mga::AndroidDisplaySelector::AndroidDisplaySelector(std::shared_ptr<mga::FBFactory> const& factory)
663+ : fb_factory(factory)
664+{
665+ const hw_module_t *hw_module;
666+ int rc = hw_get_module(HWC_HARDWARE_MODULE_ID, &hw_module);
667+
668+ if (rc != 0)
669+ {
670+ /* could not find hw module. use GL fallback */
671+ allocate_primary_fb = std::bind(&FBFactory::create_gpu_display, fb_factory);
672+ return;
673+ }
674+
675+ hw_device_t* hwc_device;
676+ rc = hw_module->methods->open(hw_module, HWC_HARDWARE_COMPOSER, &hwc_device);
677+
678+ if ((hwc_device != nullptr) &&
679+ (rc == 0 ) &&
680+ (hwc_device->version == HWC_DEVICE_API_VERSION_1_1))
681+ {
682+ allocate_primary_fb = std::bind(&FBFactory::create_hwc1_1_gpu_display, fb_factory);
683+ }
684+ else
685+ {
686+ allocate_primary_fb = std::bind(&FBFactory::create_gpu_display, fb_factory);
687+ }
688+}
689+
690+std::shared_ptr<mg::Display> mga::AndroidDisplaySelector::primary_display()
691+{
692+ return allocate_primary_fb();
693+}
694
695=== added file 'src/server/graphics/android/android_display_selector.h'
696--- src/server/graphics/android/android_display_selector.h 1970-01-01 00:00:00 +0000
697+++ src/server/graphics/android/android_display_selector.h 2013-03-22 15:42:23 +0000
698@@ -0,0 +1,52 @@
699+/*
700+ * Copyright © 2013 Canonical Ltd.
701+ *
702+ * This program is free software: you can redistribute it and/or modify
703+ * it under the terms of the GNU General Public License version 3 as
704+ * published by the Free Software Foundation.
705+ *
706+ * This program is distributed in the hope that it will be useful,
707+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
708+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
709+ * GNU General Public License for more details.
710+ *
711+ * You should have received a copy of the GNU General Public License
712+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
713+ *
714+ * Authored by: Kevin DuBois <kevin.dubois@canonical.com>
715+ */
716+
717+#ifndef MIR_GRAPHICS_ANDROID_ANDROID_DISPLAY_SELECTOR_H_
718+#define MIR_GRAPHICS_ANDROID_ANDROID_DISPLAY_SELECTOR_H_
719+
720+#include "display_selector.h"
721+
722+namespace mir
723+{
724+namespace graphics
725+{
726+
727+class Display;
728+
729+namespace android
730+{
731+
732+class FBFactory;
733+
734+class AndroidDisplaySelector : public DisplaySelector
735+{
736+public:
737+ AndroidDisplaySelector(std::shared_ptr<FBFactory> const& factory);
738+ std::shared_ptr<Display> primary_display();
739+
740+private:
741+ std::shared_ptr<FBFactory> fb_factory;
742+ std::shared_ptr<Display> primary_hwc_display;
743+ std::function<std::shared_ptr<Display>()> allocate_primary_fb;
744+};
745+
746+}
747+}
748+}
749+
750+#endif /* MIR_GRAPHICS_ANDROID_ANDROID_DISPLAY_SELECTOR_H_ */
751
752=== added file 'src/server/graphics/android/android_fb_factory.cpp'
753--- src/server/graphics/android/android_fb_factory.cpp 1970-01-01 00:00:00 +0000
754+++ src/server/graphics/android/android_fb_factory.cpp 2013-03-22 15:42:23 +0000
755@@ -0,0 +1,44 @@
756+/*
757+ * Copyright © 2013 Canonical Ltd.
758+ *
759+ * This program is free software: you can redistribute it and/or modify
760+ * it under the terms of the GNU General Public License version 3 as
761+ * published by the Free Software Foundation.
762+ *
763+ * This program is distributed in the hope that it will be useful,
764+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
765+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
766+ * GNU General Public License for more details.
767+ *
768+ * You should have received a copy of the GNU General Public License
769+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
770+ *
771+ * Authored by: Kevin DuBois <kevin.dubois@canonical.com>
772+ */
773+
774+#include "android_fb_factory.h"
775+#include "android_framebuffer_window.h"
776+#include "android_display.h"
777+
778+#include <ui/FramebufferNativeWindow.h>
779+#include <boost/throw_exception.hpp>
780+
781+namespace mg=mir::graphics;
782+namespace mga=mir::graphics::android;
783+
784+std::shared_ptr<mg::Display> mga::AndroidFBFactory::create_hwc1_1_gpu_display() const
785+{
786+ //TODO: this will construct the hwc 1.1 framebuffer later
787+ return create_gpu_display();
788+}
789+
790+/* note: gralloc seems to choke when this is opened/closed more than once per process. must investigate drivers further */
791+std::shared_ptr<mg::Display> mga::AndroidFBFactory::create_gpu_display() const
792+{
793+ auto android_window = std::make_shared< ::android::FramebufferNativeWindow>();
794+ if (!android_window.get())
795+ BOOST_THROW_EXCEPTION(std::runtime_error("could not open FB window"));
796+ auto window = std::make_shared<mga::AndroidFramebufferWindow> (android_window);
797+
798+ return std::make_shared<mga::AndroidDisplay>(window);
799+}
800
801=== added file 'src/server/graphics/android/android_fb_factory.h'
802--- src/server/graphics/android/android_fb_factory.h 1970-01-01 00:00:00 +0000
803+++ src/server/graphics/android/android_fb_factory.h 2013-03-22 15:42:23 +0000
804@@ -0,0 +1,42 @@
805+/*
806+ * Copyright © 2013 Canonical Ltd.
807+ *
808+ * This program is free software: you can redistribute it and/or modify
809+ * it under the terms of the GNU General Public License version 3 as
810+ * published by the Free Software Foundation.
811+ *
812+ * This program is distributed in the hope that it will be useful,
813+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
814+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
815+ * GNU General Public License for more details.
816+ *
817+ * You should have received a copy of the GNU General Public License
818+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
819+ *
820+ * Authored by: Kevin DuBois <kevin.dubois@canonical.com>
821+ */
822+
823+#ifndef MIR_GRAPHICS_ANDROID_ANDROID_FB_FACTORY_H_
824+#define MIR_GRAPHICS_ANDROID_ANDROID_FB_FACTORY_H_
825+
826+#include "fb_factory.h"
827+
828+namespace mir
829+{
830+namespace graphics
831+{
832+namespace android
833+{
834+
835+class AndroidFBFactory : public FBFactory
836+{
837+public:
838+ std::shared_ptr<Display> create_hwc1_1_gpu_display() const;
839+ std::shared_ptr<Display> create_gpu_display() const;
840+};
841+
842+}
843+}
844+}
845+
846+#endif /* MIR_GRAPHICS_ANDROID_ANDROID_FB_FACTORY_H_ */
847
848=== modified file 'src/server/graphics/android/android_platform.cpp'
849--- src/server/graphics/android/android_platform.cpp 2013-03-21 03:32:59 +0000
850+++ src/server/graphics/android/android_platform.cpp 2013-03-22 15:42:23 +0000
851@@ -20,16 +20,11 @@
852 #include "android_platform.h"
853 #include "android_buffer_allocator.h"
854 #include "android_display.h"
855-#include "android_framebuffer_window.h"
856+#include "android_display_selector.h"
857+#include "android_fb_factory.h"
858 #include "mir/graphics/platform_ipc_package.h"
859 #include "mir/compositor/buffer_id.h"
860
861-#include <ui/FramebufferNativeWindow.h>
862-
863-#include <boost/throw_exception.hpp>
864-
865-#include <stdexcept>
866-
867 namespace mg=mir::graphics;
868 namespace mga=mir::graphics::android;
869 namespace mc=mir::compositor;
870@@ -42,9 +37,9 @@
871
872 std::shared_ptr<mg::Display> mga::AndroidPlatform::create_display()
873 {
874- auto android_window = std::make_shared< ::android::FramebufferNativeWindow>();
875- auto window = std::make_shared<mga::AndroidFramebufferWindow> (android_window);
876- return std::make_shared<mga::AndroidDisplay>(window);
877+ auto fb_factory = std::make_shared<mga::AndroidFBFactory>();
878+ auto selector = std::make_shared<mga::AndroidDisplaySelector>(fb_factory);
879+ return selector->primary_display();
880 }
881
882 std::shared_ptr<mg::PlatformIPCPackage> mga::AndroidPlatform::get_ipc_package()
883
884=== added file 'src/server/graphics/android/display_selector.h'
885--- src/server/graphics/android/display_selector.h 1970-01-01 00:00:00 +0000
886+++ src/server/graphics/android/display_selector.h 2013-03-22 15:42:23 +0000
887@@ -0,0 +1,49 @@
888+/*
889+ * Copyright © 2013 Canonical Ltd.
890+ *
891+ * This program is free software: you can redistribute it and/or modify
892+ * it under the terms of the GNU General Public License version 3 as
893+ * published by the Free Software Foundation.
894+ *
895+ * This program is distributed in the hope that it will be useful,
896+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
897+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
898+ * GNU General Public License for more details.
899+ *
900+ * You should have received a copy of the GNU General Public License
901+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
902+ *
903+ * Authored by: Kevin DuBois <kevin.dubois@canonical.com>
904+ */
905+
906+#ifndef MIR_GRAPHICS_ANDROID_DISPLAY_SELECTOR_H_
907+#define MIR_GRAPHICS_ANDROID_DISPLAY_SELECTOR_H_
908+
909+#include <memory>
910+
911+namespace mir
912+{
913+namespace graphics
914+{
915+
916+class Display;
917+namespace android
918+{
919+
920+class DisplaySelector
921+{
922+public:
923+ virtual std::shared_ptr<Display> primary_display() = 0;
924+ virtual ~DisplaySelector() {}
925+
926+protected:
927+ DisplaySelector() = default;
928+ DisplaySelector& operator=(DisplaySelector const&) = delete;
929+ DisplaySelector(DisplaySelector const&) = delete;
930+};
931+
932+}
933+}
934+}
935+
936+#endif /* MIR_GRAPHICS_ANDROID_DISPLAY_SELECTOR_H_ */
937
938=== added file 'src/server/graphics/android/fb_factory.h'
939--- src/server/graphics/android/fb_factory.h 1970-01-01 00:00:00 +0000
940+++ src/server/graphics/android/fb_factory.h 2013-03-22 15:42:23 +0000
941@@ -0,0 +1,56 @@
942+/*
943+ * Copyright © 2013 Canonical Ltd.
944+ *
945+ * This program is free software: you can redistribute it and/or modify
946+ * it under the terms of the GNU General Public License version 3 as
947+ * published by the Free Software Foundation.
948+ *
949+ * This program is distributed in the hope that it will be useful,
950+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
951+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
952+ * GNU General Public License for more details.
953+ *
954+ * You should have received a copy of the GNU General Public License
955+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
956+ *
957+ * Authored by: Kevin DuBois <kevin.dubois@canonical.com>
958+ */
959+
960+#ifndef MIR_GRAPHICS_ANDROID_FB_FACTORY_H_
961+#define MIR_GRAPHICS_ANDROID_FB_FACTORY_H_
962+
963+#include <memory>
964+
965+namespace mir
966+{
967+namespace graphics
968+{
969+class Display;
970+
971+namespace android
972+{
973+
974+class FBFactory
975+{
976+public:
977+ virtual ~FBFactory() {}
978+
979+ //creates a display that will render primarily via the gpu and OpenGLES 2.0, but will use the hwc
980+ //module (version 1.1) for additional functionality, such as vsync timings, and hotplug detection
981+ virtual std::shared_ptr<Display> create_hwc1_1_gpu_display() const = 0;
982+
983+ //creates a display that will render primarily via the gpu and OpenGLES 2.0. Primarily a fall-back mode,
984+ //this display is similar to what Android does when /system/lib/hw/hwcomposer.*.so modules are not present
985+ virtual std::shared_ptr<Display> create_gpu_display() const = 0;
986+
987+protected:
988+ FBFactory() = default;
989+ FBFactory& operator=(FBFactory const&) = delete;
990+ FBFactory(FBFactory const&) = delete;
991+};
992+
993+}
994+}
995+}
996+
997+#endif /* MIR_GRAPHICS_ANDROID_FB_FACTORY_H_ */
998
999=== modified file 'tests/unit-tests/client/test_client_platform.cpp'
1000--- tests/unit-tests/client/test_client_platform.cpp 2013-01-02 15:57:13 +0000
1001+++ tests/unit-tests/client/test_client_platform.cpp 2013-03-22 15:42:23 +0000
1002@@ -22,6 +22,10 @@
1003 #include "mir_test_doubles/mock_client_context.h"
1004 #include "mir_test_doubles/mock_client_surface.h"
1005
1006+#ifdef ANDROID
1007+#include "mir_test/hw_mock.h"
1008+#endif
1009+
1010 #include <gmock/gmock.h>
1011 #include <gtest/gtest.h>
1012
1013@@ -29,7 +33,14 @@
1014 namespace mt = mir::test;
1015 namespace mtd = mt::doubles;
1016
1017-TEST(ClientPlatformTest, platform_creates )
1018+class ClientPlatformTest : public ::testing::Test
1019+{
1020+#ifdef ANDROID
1021+ testing::NiceMock<mt::HardwareAccessMock> hw_access_mock;
1022+#endif
1023+};
1024+
1025+TEST_F(ClientPlatformTest, platform_creates)
1026 {
1027 mtd::MockClientContext context;
1028 mcl::NativeClientPlatformFactory factory;
1029@@ -38,7 +49,7 @@
1030 EXPECT_NE( depository.get(), (mcl::ClientBufferDepository*) NULL);
1031 }
1032
1033-TEST(ClientPlatformTest, platform_creates_native_window )
1034+TEST_F(ClientPlatformTest, platform_creates_native_window)
1035 {
1036 mtd::MockClientContext context;
1037 mcl::NativeClientPlatformFactory factory;
1038@@ -48,7 +59,7 @@
1039 EXPECT_NE( *native_window, (EGLNativeWindowType) NULL);
1040 }
1041
1042-TEST(ClientPlatformTest, platform_creates_egl_native_display)
1043+TEST_F(ClientPlatformTest, platform_creates_egl_native_display)
1044 {
1045 mtd::MockClientContext context;
1046 mcl::NativeClientPlatformFactory factory;
1047
1048=== modified file 'tests/unit-tests/graphics/android/CMakeLists.txt'
1049--- tests/unit-tests/graphics/android/CMakeLists.txt 2013-03-13 04:54:15 +0000
1050+++ tests/unit-tests/graphics/android/CMakeLists.txt 2013-03-22 15:42:23 +0000
1051@@ -3,6 +3,7 @@
1052 ${CMAKE_CURRENT_SOURCE_DIR}/test_android_buffer_allocator.cpp
1053 ${CMAKE_CURRENT_SOURCE_DIR}/test_android_buffer_tex_bind.cpp
1054 ${CMAKE_CURRENT_SOURCE_DIR}/test_android_fb.cpp
1055+ ${CMAKE_CURRENT_SOURCE_DIR}/test_android_framebuffer_selector.cpp
1056 ${CMAKE_CURRENT_SOURCE_DIR}/test_android_framebuffer_window.cpp
1057 ${CMAKE_CURRENT_SOURCE_DIR}/test_android_alloc_adaptor.cpp
1058 ${CMAKE_CURRENT_SOURCE_DIR}/test_android_alloc_adaptor_native_win.cpp
1059
1060=== modified file 'tests/unit-tests/graphics/android/test_android_buffer_allocator.cpp'
1061--- tests/unit-tests/graphics/android/test_android_buffer_allocator.cpp 2013-03-21 03:32:59 +0000
1062+++ tests/unit-tests/graphics/android/test_android_buffer_allocator.cpp 2013-03-22 15:42:23 +0000
1063@@ -17,32 +17,44 @@
1064 */
1065
1066 #include "src/server/graphics/android/android_buffer_allocator.h"
1067+#include "mir_test/hw_mock.h"
1068 #include "mir/graphics/buffer_initializer.h"
1069 #include "mir/compositor/buffer_properties.h"
1070
1071 #include "mir_test_doubles/mock_buffer_initializer.h"
1072
1073+#include <hardware/gralloc.h>
1074 #include <gtest/gtest.h>
1075-
1076 #include <algorithm>
1077
1078 namespace mg = mir::graphics;
1079 namespace mga = mir::graphics::android;
1080 namespace geom = mir::geometry;
1081+namespace mt = mir::test;
1082 namespace mc = mir::compositor;
1083 namespace mtd = mir::test::doubles;
1084
1085-class AndroidBufferAllocatorTest : public ::testing::Test
1086+struct AndroidBufferAllocatorTest : public ::testing::Test
1087 {
1088-public:
1089 AndroidBufferAllocatorTest()
1090 : null_buffer_initializer{std::make_shared<mg::NullBufferInitializer>()}
1091 {
1092 }
1093
1094 std::shared_ptr<mg::BufferInitializer> const null_buffer_initializer;
1095+ testing::NiceMock<mt::HardwareAccessMock> hw_access_mock;
1096 };
1097
1098+TEST_F(AndroidBufferAllocatorTest, allocator_accesses_gralloc_module)
1099+{
1100+ using namespace testing;
1101+
1102+ EXPECT_CALL(hw_access_mock, hw_get_module(StrEq(GRALLOC_HARDWARE_MODULE_ID), _))
1103+ .Times(1);
1104+
1105+ mga::AndroidBufferAllocator allocator(null_buffer_initializer);
1106+}
1107+
1108 TEST_F(AndroidBufferAllocatorTest, supported_pixel_formats_contain_common_formats)
1109 {
1110 mga::AndroidBufferAllocator allocator{null_buffer_initializer};
1111
1112=== added file 'tests/unit-tests/graphics/android/test_android_framebuffer_selector.cpp'
1113--- tests/unit-tests/graphics/android/test_android_framebuffer_selector.cpp 1970-01-01 00:00:00 +0000
1114+++ tests/unit-tests/graphics/android/test_android_framebuffer_selector.cpp 2013-03-22 15:42:23 +0000
1115@@ -0,0 +1,127 @@
1116+/*
1117+ * Copyright © 2013 Canonical Ltd.
1118+ *
1119+ * This program is free software: you can redistribute it and/or modify
1120+ * it under the terms of the GNU General Public License version 3 as
1121+ * published by the Free Software Foundation.
1122+ *
1123+ * This program is distributed in the hope that it will be useful,
1124+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1125+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1126+ * GNU General Public License for more details.
1127+ *
1128+ * You should have received a copy of the GNU General Public License
1129+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1130+ *
1131+ * Authored by: Kevin DuBois <kevin.dubois@canonical.com>
1132+ */
1133+
1134+#include "src/server/graphics/android/fb_factory.h"
1135+#include "src/server/graphics/android/android_display_selector.h"
1136+
1137+#include "mir_test/hw_mock.h"
1138+#include "mir_test_doubles/null_display.h"
1139+
1140+#include <hardware/hwcomposer.h>
1141+#include <gtest/gtest.h>
1142+#include <gmock/gmock.h>
1143+
1144+namespace mt=mir::test;
1145+namespace mtd=mir::test::doubles;
1146+namespace mga=mir::graphics::android;
1147+namespace mg=mir::graphics;
1148+namespace geom=mir::geometry;
1149+
1150+struct MockFbFactory : public mga::FBFactory
1151+{
1152+ MockFbFactory()
1153+ {
1154+ using namespace testing;
1155+ ON_CALL(*this, create_hwc1_1_gpu_display())
1156+ .WillByDefault(Return(std::make_shared<mtd::NullDisplay>()));
1157+ ON_CALL(*this, create_gpu_display())
1158+ .WillByDefault(Return(std::make_shared<mtd::NullDisplay>()));
1159+ }
1160+ MOCK_CONST_METHOD0(create_hwc1_1_gpu_display, std::shared_ptr<mg::Display>());
1161+ MOCK_CONST_METHOD0(create_gpu_display, std::shared_ptr<mg::Display>());
1162+
1163+};
1164+
1165+class AndroidFramebufferSelectorTest : public ::testing::Test
1166+{
1167+public:
1168+ AndroidFramebufferSelectorTest()
1169+ : mock_fb_factory(std::make_shared<testing::NiceMock<MockFbFactory>>())
1170+ {
1171+ }
1172+
1173+ std::shared_ptr<MockFbFactory> mock_fb_factory;
1174+ mt::HardwareAccessMock hw_access_mock;
1175+};
1176+
1177+TEST_F(AndroidFramebufferSelectorTest, hwc_selection_gets_hwc_device)
1178+{
1179+ using namespace testing;
1180+
1181+ EXPECT_CALL(hw_access_mock, hw_get_module(StrEq(HWC_HARDWARE_MODULE_ID), _))
1182+ .Times(1);
1183+
1184+ mga::AndroidDisplaySelector selector(mock_fb_factory);
1185+ selector.primary_display();
1186+}
1187+
1188+TEST_F(AndroidFramebufferSelectorTest, hwc_with_hwc_device_success)
1189+{
1190+ using namespace testing;
1191+
1192+ EXPECT_CALL(hw_access_mock, hw_get_module(_, _))
1193+ .Times(1);
1194+ EXPECT_CALL(*mock_fb_factory, create_hwc1_1_gpu_display())
1195+ .Times(1);
1196+
1197+ mga::AndroidDisplaySelector selector(mock_fb_factory);
1198+ selector.primary_display();
1199+}
1200+
1201+TEST_F(AndroidFramebufferSelectorTest, hwc_with_hwc_device_failure_because_module_not_found)
1202+{
1203+ using namespace testing;
1204+
1205+ EXPECT_CALL(hw_access_mock, hw_get_module(_, _))
1206+ .Times(1)
1207+ .WillOnce(Return(-1));
1208+ EXPECT_CALL(*mock_fb_factory, create_gpu_display())
1209+ .Times(1);
1210+
1211+ mga::AndroidDisplaySelector selector(mock_fb_factory);
1212+ selector.primary_display();
1213+}
1214+
1215+TEST_F(AndroidFramebufferSelectorTest, hwc_with_hwc_device_failure_because_hwc_does_not_open)
1216+{
1217+ using namespace testing;
1218+
1219+ EXPECT_CALL(hw_access_mock, hw_get_module(StrEq(HWC_HARDWARE_MODULE_ID), _))
1220+ .Times(1)
1221+ .WillOnce(DoAll(SetArgPointee<1>(nullptr), Return(-1)));
1222+;
1223+ EXPECT_CALL(*mock_fb_factory, create_gpu_display())
1224+ .Times(1);
1225+
1226+ mga::AndroidDisplaySelector selector(mock_fb_factory);
1227+ selector.primary_display();
1228+}
1229+
1230+TEST_F(AndroidFramebufferSelectorTest, hwc_with_hwc_device_failure_because_hwc_version_not_supported)
1231+{
1232+ using namespace testing;
1233+
1234+ hw_access_mock.mock_hwc_device->common.version = HWC_DEVICE_API_VERSION_1_0;
1235+ EXPECT_CALL(hw_access_mock, hw_get_module(_, _))
1236+ .Times(1);
1237+ EXPECT_CALL(*mock_fb_factory, create_gpu_display())
1238+ .Times(1);
1239+
1240+ mga::AndroidDisplaySelector selector(mock_fb_factory);
1241+ selector.primary_display();
1242+}
1243
1244=== modified file 'tests/unit-tests/graphics/egl_mock/CMakeLists.txt'
1245--- tests/unit-tests/graphics/egl_mock/CMakeLists.txt 2013-03-13 04:54:15 +0000
1246+++ tests/unit-tests/graphics/egl_mock/CMakeLists.txt 2013-03-22 15:42:23 +0000
1247@@ -4,9 +4,16 @@
1248
1249 set(UNIT_TEST_SOURCES ${UNIT_TEST_SOURCES} PARENT_SCOPE)
1250
1251+set(MIRTEST_EGLMOCK_SOURCES
1252+ gl_mock.cpp
1253+ egl_mock.cpp )
1254+
1255+if (MIR_PLATFORM STREQUAL "android")
1256+ list( APPEND MIRTEST_EGLMOCK_SOURCES hw_mock.cpp )
1257+endif()
1258+
1259 add_library(
1260 mirtest_eglmock STATIC
1261
1262- gl_mock.cpp
1263- egl_mock.cpp
1264+ ${MIRTEST_EGLMOCK_SOURCES}
1265 )
1266
1267=== added file 'tests/unit-tests/graphics/egl_mock/hw_mock.cpp'
1268--- tests/unit-tests/graphics/egl_mock/hw_mock.cpp 1970-01-01 00:00:00 +0000
1269+++ tests/unit-tests/graphics/egl_mock/hw_mock.cpp 2013-03-22 15:42:23 +0000
1270@@ -0,0 +1,86 @@
1271+/*
1272+ * Copyright © 2013 Canonical Ltd.
1273+ *
1274+ * This program is free software: you can redistribute it and/or modify
1275+ * it under the terms of the GNU General Public License version 3 as
1276+ * published by the Free Software Foundation.
1277+ *
1278+ * This program is distributed in the hope that it will be useful,
1279+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1280+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1281+ * GNU General Public License for more details.
1282+ *
1283+ * You should have received a copy of the GNU General Public License
1284+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1285+ *
1286+ * Authored by: Kevin DuBois <kevin.dubois@canonical.com>
1287+ */
1288+
1289+#include "mir_test/hw_mock.h"
1290+#include "mir_test_doubles/mock_hwc_composer_device_1.h"
1291+
1292+#include <hardware/gralloc.h>
1293+#include <system/window.h>
1294+#include <memory>
1295+
1296+namespace mt = mir::test;
1297+namespace mtd = mir::test::doubles;
1298+
1299+mt::HardwareModuleStub::HardwareModuleStub(hw_device_t& device)
1300+ : mock_hw_device(device)
1301+{
1302+ gr_methods.open = hw_open;
1303+ methods = &gr_methods;
1304+}
1305+
1306+int mt::HardwareModuleStub::hw_open(const struct hw_module_t* module, const char*, struct hw_device_t** device)
1307+{
1308+ auto self = static_cast<HardwareModuleStub const*>(module);
1309+ self->mock_hw_device.close = hw_close;
1310+ *device = static_cast<hw_device_t*>(&self->mock_hw_device);
1311+ return 0;
1312+}
1313+
1314+int mt::HardwareModuleStub::hw_close(struct hw_device_t*)
1315+{
1316+ return 0;
1317+}
1318+
1319+namespace
1320+{
1321+mt::HardwareAccessMock* global_hw_mock = NULL;
1322+}
1323+
1324+mt::HardwareAccessMock::HardwareAccessMock()
1325+{
1326+ using namespace testing;
1327+ assert(global_hw_mock == NULL && "Only one mock object per process is allowed");
1328+ global_hw_mock = this;
1329+
1330+ mock_alloc_device = std::make_shared<mtd::MockAllocDevice>();
1331+ mock_gralloc_module = std::make_shared<mt::HardwareModuleStub>(mock_alloc_device->common);
1332+
1333+ mock_hwc_device = std::make_shared<mtd::MockHWCComposerDevice1>();
1334+ mock_hwc_module = std::make_shared<mt::HardwareModuleStub>(mock_hwc_device->common);
1335+
1336+ ON_CALL(*this, hw_get_module(StrEq(GRALLOC_HARDWARE_MODULE_ID),_))
1337+ .WillByDefault(DoAll(SetArgPointee<1>(mock_gralloc_module.get()), Return(0)));
1338+ ON_CALL(*this, hw_get_module(StrEq(HWC_HARDWARE_MODULE_ID),_))
1339+ .WillByDefault(DoAll(SetArgPointee<1>(mock_hwc_module.get()), Return(0)));
1340+}
1341+
1342+mt::HardwareAccessMock::~HardwareAccessMock()
1343+{
1344+ global_hw_mock = NULL;
1345+}
1346+
1347+int hw_get_module(const char *id, const struct hw_module_t **module)
1348+{
1349+ if (!global_hw_mock)
1350+ {
1351+ ADD_FAILURE_AT(__FILE__,__LINE__); \
1352+ return -1;
1353+ }
1354+ int rc = global_hw_mock->hw_get_module(id, module);
1355+ return rc;
1356+}
1357
1358=== modified file 'tests/unit-tests/graphics/test_graphics_platform.cpp'
1359--- tests/unit-tests/graphics/test_graphics_platform.cpp 2013-03-13 04:54:15 +0000
1360+++ tests/unit-tests/graphics/test_graphics_platform.cpp 2013-03-22 15:42:23 +0000
1361@@ -20,11 +20,13 @@
1362 #include "mir/graphics/platform.h"
1363 #include "mir/compositor/graphic_buffer_allocator.h"
1364 #include "mir/compositor/buffer_properties.h"
1365+#include "mir_test/egl_mock.h"
1366+#include "mir_test/gl_mock.h"
1367 #ifndef ANDROID
1368 #include "gbm/mock_drm.h"
1369 #include "gbm/mock_gbm.h"
1370-#include "mir_test/egl_mock.h"
1371-#include "mir_test/gl_mock.h"
1372+#else
1373+#include "mir_test/hw_mock.h"
1374 #endif
1375 #include "mir/graphics/buffer_initializer.h"
1376 #include "mir/logging/dumb_console_logger.h"
1377@@ -69,11 +71,14 @@
1378
1379 std::shared_ptr<ml::Logger> logger;
1380 std::shared_ptr<mg::BufferInitializer> buffer_initializer;
1381-#ifndef ANDROID
1382+
1383+ ::testing::NiceMock<mir::EglMock> mock_egl;
1384+ ::testing::NiceMock<mir::GLMock> mock_gl;
1385+#ifdef ANDROID
1386+ mir::test::HardwareAccessMock hw_access_mock;
1387+#else
1388 ::testing::NiceMock<mg::gbm::MockDRM> mock_drm;
1389 ::testing::NiceMock<mg::gbm::MockGBM> mock_gbm;
1390- ::testing::NiceMock<mir::EglMock> mock_egl;
1391- ::testing::NiceMock<mir::GLMock> mock_gl;
1392 #endif
1393 };
1394

Subscribers

People subscribed via source and target branches