diff options
-rw-r--r-- | include/hardware/hwcomposer.h | 122 | ||||
-rw-r--r-- | include/hardware/hwcomposer_defs.h | 2 | ||||
-rw-r--r-- | include/hardware/hwcomposer_v0.h | 272 | ||||
-rw-r--r-- | modules/hwcomposer/hwcomposer.cpp | 12 |
4 files changed, 359 insertions, 49 deletions
diff --git a/include/hardware/hwcomposer.h b/include/hardware/hwcomposer.h index 98e665c..4af5c69 100644 --- a/include/hardware/hwcomposer.h +++ b/include/hardware/hwcomposer.h @@ -30,11 +30,25 @@ __BEGIN_DECLS /*****************************************************************************/ -// for compatibility +/* for compatibility */ #define HWC_MODULE_API_VERSION HWC_MODULE_API_VERSION_0_1 #define HWC_DEVICE_API_VERSION HWC_DEVICE_API_VERSION_0_1 #define HWC_API_VERSION HWC_DEVICE_API_VERSION +/* Users of this header can define HWC_REMOVE_DEPRECATED_VERSIONS to test that + * they still work with just the current version declared, before the + * deprecated versions are actually removed. + * + * To find code that still depends on the old versions, set the #define to 1 + * here. Code that explicitly sets it to zero (rather than simply not defining + * it) will still see the old versions. + */ +#if !defined(HWC_REMOVE_DEPRECATED_VERSIONS) +#define HWC_REMOVE_DEPRECATED_VERSIONS 0 +#endif + +/*****************************************************************************/ + /** * The id of this module */ @@ -45,21 +59,8 @@ __BEGIN_DECLS */ #define HWC_HARDWARE_COMPOSER "composer" - -struct hwc_composer_device; - -/* - * availability: HWC_DEVICE_API_VERSION_0_3 - * - * struct hwc_methods cannot be embedded in other structures as - * sizeof(struct hwc_methods) cannot be relied upon. - * - */ -typedef struct hwc_methods { - - /************************************************************************* - * HWC_DEVICE_API_VERSION_0_3 - *************************************************************************/ +struct hwc_composer_device_1; +typedef struct hwc_methods_1 { /* * eventControl(..., event, enabled) @@ -76,9 +77,9 @@ typedef struct hwc_methods { */ int (*eventControl)( - struct hwc_composer_device* dev, int event, int enabled); + struct hwc_composer_device_1* dev, int event, int enabled); -} hwc_methods_t; +} hwc_methods_1_t; typedef struct hwc_rect { int left; @@ -99,7 +100,7 @@ typedef struct hwc_color { uint8_t a; } hwc_color_t; -typedef struct hwc_layer { +typedef struct hwc_layer_1 { /* * initially set to HWC_FRAMEBUFFER or HWC_BACKGROUND. * HWC_FRAMEBUFFER @@ -158,10 +159,46 @@ typedef struct hwc_layer { * The visible region INCLUDES areas overlapped by a translucent layer. */ hwc_region_t visibleRegionScreen; + + /* Sync fence object that will be signaled when the buffer's + * contents are available. May be -1 if the contents are already + * available. This field is only valid during set(), and should be + * ignored during prepare(). The set() call must not wait for the + * fence to be signaled before returning, but the HWC must wait for + * all buffers to be signaled before reading from them. + * + * The HWC takes ownership of the acquireFenceFd and is responsible + * for closing it when no longer needed. + */ + int acquireFenceFd; + + /* During set() the HWC must set this field to a file descriptor for + * a sync fence object that will signal after the HWC has finished + * reading from the buffer. The field is ignored by prepare(). Each + * layer should have a unique file descriptor, even if more than one + * refer to the same underlying fence object; this allows each to be + * closed independently. + * + * If buffer reads can complete at significantly different times, + * then using independent fences is preferred. For example, if the + * HWC handles some layers with a blit engine and others with + * overlays, then the blit layers can be reused immediately after + * the blit completes, but the overlay layers can't be reused until + * a subsequent frame has been displayed. + * + * The HWC client taks ownership of the releaseFenceFd and is + * responsible for closing it when no longer needed. + */ + int releaseFenceFd; }; }; -} hwc_layer_t; + /* Allow for expansion w/o breaking binary compatibility. + * Pad layer to 96 bytes, assuming 32-bit pointers. + */ + int32_t reserved[24 - 18]; + +} hwc_layer_1_t; /* * hwc_layer_list_t::flags values @@ -169,7 +206,8 @@ typedef struct hwc_layer { enum { /* * HWC_GEOMETRY_CHANGED is set by SurfaceFlinger to indicate that the list - * passed to (*prepare)() has changed by more than just the buffer handles. + * passed to (*prepare)() has changed by more than just the buffer handles + * and acquire fences. */ HWC_GEOMETRY_CHANGED = 0x00000001, }; @@ -178,11 +216,11 @@ enum { * List of layers. * The handle members of hwLayers elements must be unique. */ -typedef struct hwc_layer_list { +typedef struct hwc_layer_list_1 { uint32_t flags; size_t numHwLayers; - hwc_layer_t hwLayers[0]; -} hwc_layer_list_t; + hwc_layer_1_t hwLayers[0]; +} hwc_layer_list_1_t; /* This represents a display, typically an EGLDisplay object */ typedef void* hwc_display_t; @@ -237,8 +275,7 @@ typedef struct hwc_module { struct hw_module_t common; } hwc_module_t; - -typedef struct hwc_composer_device { +typedef struct hwc_composer_device_1 { struct hw_device_t common; /* @@ -264,8 +301,8 @@ typedef struct hwc_composer_device { * returned, SurfaceFlinger will assume that none of the layer will be * handled by the HWC. */ - int (*prepare)(struct hwc_composer_device *dev, hwc_layer_list_t* list); - + int (*prepare)(struct hwc_composer_device_1 *dev, + hwc_layer_list_1_t* list); /* * (*set)() is used in place of eglSwapBuffers(), and assumes the same @@ -309,16 +346,17 @@ typedef struct hwc_composer_device { * Another code for non EGL errors. * */ - int (*set)(struct hwc_composer_device *dev, + int (*set)(struct hwc_composer_device_1 *dev, hwc_display_t dpy, hwc_surface_t sur, - hwc_layer_list_t* list); + hwc_layer_list_1_t* list); + /* * This field is OPTIONAL and can be NULL. * * If non NULL it will be called by SurfaceFlinger on dumpsys */ - void (*dump)(struct hwc_composer_device* dev, char *buff, int buff_len); + void (*dump)(struct hwc_composer_device_1* dev, char *buff, int buff_len); /* * This field is OPTIONAL and can be NULL. @@ -333,18 +371,17 @@ typedef struct hwc_composer_device { * Any of the callbacks can be NULL, in which case the corresponding * functionality is not supported. */ - void (*registerProcs)(struct hwc_composer_device* dev, + void (*registerProcs)(struct hwc_composer_device_1* dev, hwc_procs_t const* procs); /* * This field is OPTIONAL and can be NULL. - * availability: HWC_DEVICE_API_VERSION_0_2 * * Used to retrieve information about the h/w composer * * Returns 0 on success or -errno on error. */ - int (*query)(struct hwc_composer_device* dev, int what, int* value); + int (*query)(struct hwc_composer_device_1* dev, int what, int* value); /* * Reserved for future use. Must be NULL. @@ -353,28 +390,29 @@ typedef struct hwc_composer_device { /* * This field is OPTIONAL and can be NULL. - * availability: HWC_DEVICE_API_VERSION_0_3 */ - hwc_methods_t const *methods; - -} hwc_composer_device_t; + hwc_methods_1_t const *methods; +} hwc_composer_device_1_t; /** convenience API for opening and closing a device */ -static inline int hwc_open(const struct hw_module_t* module, - hwc_composer_device_t** device) { +static inline int hwc_open_1(const struct hw_module_t* module, + hwc_composer_device_1_t** device) { return module->methods->open(module, HWC_HARDWARE_COMPOSER, (struct hw_device_t**)device); } -static inline int hwc_close(hwc_composer_device_t* device) { +static inline int hwc_close_1(hwc_composer_device_1_t* device) { return device->common.close(&device->common); } - /*****************************************************************************/ +#if !HWC_REMOVE_DEPRECATED_VERSIONS +#include <hardware/hwcomposer_v0.h> +#endif + __END_DECLS #endif /* ANDROID_INCLUDE_HARDWARE_HWCOMPOSER_H */ diff --git a/include/hardware/hwcomposer_defs.h b/include/hardware/hwcomposer_defs.h index 99465d3..02b8e50 100644 --- a/include/hardware/hwcomposer_defs.h +++ b/include/hardware/hwcomposer_defs.h @@ -33,7 +33,7 @@ __BEGIN_DECLS #define HWC_DEVICE_API_VERSION_0_1 HARDWARE_DEVICE_API_VERSION(0, 1) #define HWC_DEVICE_API_VERSION_0_2 HARDWARE_DEVICE_API_VERSION(0, 2) #define HWC_DEVICE_API_VERSION_0_3 HARDWARE_DEVICE_API_VERSION(0, 3) - +#define HWC_DEVICE_API_VERSION_1_0 HARDWARE_DEVICE_API_VERSION(1, 0) enum { /* hwc_composer_device_t::set failed in EGL */ diff --git a/include/hardware/hwcomposer_v0.h b/include/hardware/hwcomposer_v0.h new file mode 100644 index 0000000..473819b --- /dev/null +++ b/include/hardware/hwcomposer_v0.h @@ -0,0 +1,272 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* This header contains deprecated HWCv0 interface declarations. Don't include + * this header directly; it will be included by <hardware/hwcomposer.h> unless + * HWC_REMOVE_DEPRECATED_VERSIONS is defined to non-zero. + */ +#ifndef ANDROID_INCLUDE_HARDWARE_HWCOMPOSER_H +#error "This header should only be included by hardware/hwcomposer.h" +#endif + +#ifndef ANDROID_INCLUDE_HARDWARE_HWCOMPOSER_V0_H +#define ANDROID_INCLUDE_HARDWARE_HWCOMPOSER_V0_H + +struct hwc_composer_device; + +/* + * availability: HWC_DEVICE_API_VERSION_0_3 + * + * struct hwc_methods cannot be embedded in other structures as + * sizeof(struct hwc_methods) cannot be relied upon. + * + */ +typedef struct hwc_methods { + + /************************************************************************* + * HWC_DEVICE_API_VERSION_0_3 + *************************************************************************/ + + /* + * eventControl(..., event, enabled) + * Enables or disables h/w composer events. + * + * eventControl can be called from any thread and takes effect + * immediately. + * + * Supported events are: + * HWC_EVENT_VSYNC + * + * returns -EINVAL if the "event" parameter is not one of the value above + * or if the "enabled" parameter is not 0 or 1. + */ + + int (*eventControl)( + struct hwc_composer_device* dev, int event, int enabled); + +} hwc_methods_t; + +typedef struct hwc_layer { + /* + * initially set to HWC_FRAMEBUFFER or HWC_BACKGROUND. + * HWC_FRAMEBUFFER + * indicates the layer will be drawn into the framebuffer + * using OpenGL ES. + * The HWC can toggle this value to HWC_OVERLAY, to indicate + * it will handle the layer. + * + * HWC_BACKGROUND + * indicates this is a special "background" layer. The only valid + * field is backgroundColor. HWC_BACKGROUND can only be used with + * HWC_API_VERSION >= 0.2 + * The HWC can toggle this value to HWC_FRAMEBUFFER, to indicate + * it CANNOT handle the background color + * + */ + int32_t compositionType; + + /* see hwc_layer_t::hints above */ + uint32_t hints; + + /* see hwc_layer_t::flags above */ + uint32_t flags; + + union { + /* color of the background. hwc_color_t.a is ignored */ + hwc_color_t backgroundColor; + + struct { + /* handle of buffer to compose. This handle is guaranteed to have been + * allocated from gralloc using the GRALLOC_USAGE_HW_COMPOSER usage flag. If + * the layer's handle is unchanged across two consecutive prepare calls and + * the HWC_GEOMETRY_CHANGED flag is not set for the second call then the + * HWComposer implementation may assume that the contents of the buffer have + * not changed. */ + buffer_handle_t handle; + + /* transformation to apply to the buffer during composition */ + uint32_t transform; + + /* blending to apply during composition */ + int32_t blending; + + /* area of the source to consider, the origin is the top-left corner of + * the buffer */ + hwc_rect_t sourceCrop; + + /* where to composite the sourceCrop onto the display. The sourceCrop + * is scaled using linear filtering to the displayFrame. The origin is the + * top-left corner of the screen. + */ + hwc_rect_t displayFrame; + + /* visible region in screen space. The origin is the + * top-left corner of the screen. + * The visible region INCLUDES areas overlapped by a translucent layer. + */ + hwc_region_t visibleRegionScreen; + }; + }; +} hwc_layer_t; + +/* + * List of layers. + * The handle members of hwLayers elements must be unique. + */ +typedef struct hwc_layer_list { + uint32_t flags; + size_t numHwLayers; + hwc_layer_t hwLayers[0]; +} hwc_layer_list_t; + +/*****************************************************************************/ + +typedef struct hwc_composer_device { + struct hw_device_t common; + + /* + * (*prepare)() is called for each frame before composition and is used by + * SurfaceFlinger to determine what composition steps the HWC can handle. + * + * (*prepare)() can be called more than once, the last call prevails. + * + * The HWC responds by setting the compositionType field to either + * HWC_FRAMEBUFFER or HWC_OVERLAY. In the former case, the composition for + * this layer is handled by SurfaceFlinger with OpenGL ES, in the later + * case, the HWC will have to handle this layer's composition. + * + * (*prepare)() is called with HWC_GEOMETRY_CHANGED to indicate that the + * list's geometry has changed, that is, when more than just the buffer's + * handles have been updated. Typically this happens (but is not limited to) + * when a window is added, removed, resized or moved. + * + * a NULL list parameter or a numHwLayers of zero indicates that the + * entire composition will be handled by SurfaceFlinger with OpenGL ES. + * + * returns: 0 on success. An negative error code on error. If an error is + * returned, SurfaceFlinger will assume that none of the layer will be + * handled by the HWC. + */ + int (*prepare)(struct hwc_composer_device *dev, hwc_layer_list_t* list); + + /* + * (*set)() is used in place of eglSwapBuffers(), and assumes the same + * functionality, except it also commits the work list atomically with + * the actual eglSwapBuffers(). + * + * The list parameter is guaranteed to be the same as the one returned + * from the last call to (*prepare)(). + * + * When this call returns the caller assumes that: + * + * - the display will be updated in the near future with the content + * of the work list, without artifacts during the transition from the + * previous frame. + * + * - all objects are available for immediate access or destruction, in + * particular, hwc_region_t::rects data and hwc_layer_t::layer's buffer. + * Note that this means that immediately accessing (potentially from a + * different process) a buffer used in this call will not result in + * screen corruption, the driver must apply proper synchronization or + * scheduling (eg: block the caller, such as gralloc_module_t::lock(), + * OpenGL ES, Camera, Codecs, etc..., or schedule the caller's work + * after the buffer is freed from the actual composition). + * + * a NULL list parameter or a numHwLayers of zero indicates that the + * entire composition has been handled by SurfaceFlinger with OpenGL ES. + * In this case, (*set)() behaves just like eglSwapBuffers(). + * + * dpy, sur, and list are set to NULL to indicate that the screen is + * turning off. This happens WITHOUT prepare() being called first. + * This is a good time to free h/w resources and/or power + * the relevant h/w blocks down. + * + * IMPORTANT NOTE: there is an implicit layer containing opaque black + * pixels behind all the layers in the list. + * It is the responsibility of the hwcomposer module to make + * sure black pixels are output (or blended from). + * + * returns: 0 on success. An negative error code on error: + * HWC_EGL_ERROR: eglGetError() will provide the proper error code + * Another code for non EGL errors. + * + */ + int (*set)(struct hwc_composer_device *dev, + hwc_display_t dpy, + hwc_surface_t sur, + hwc_layer_list_t* list); + + /* + * This field is OPTIONAL and can be NULL. + * + * If non NULL it will be called by SurfaceFlinger on dumpsys + */ + void (*dump)(struct hwc_composer_device* dev, char *buff, int buff_len); + + /* + * This field is OPTIONAL and can be NULL. + * + * (*registerProcs)() registers a set of callbacks the h/w composer HAL + * can later use. It is FORBIDDEN to call any of the callbacks from + * within registerProcs(). registerProcs() must save the hwc_procs_t pointer + * which is needed when calling a registered callback. + * Each call to registerProcs replaces the previous set of callbacks. + * registerProcs is called with NULL to unregister all callbacks. + * + * Any of the callbacks can be NULL, in which case the corresponding + * functionality is not supported. + */ + void (*registerProcs)(struct hwc_composer_device* dev, + hwc_procs_t const* procs); + + /* + * This field is OPTIONAL and can be NULL. + * availability: HWC_DEVICE_API_VERSION_0_2 + * + * Used to retrieve information about the h/w composer + * + * Returns 0 on success or -errno on error. + */ + int (*query)(struct hwc_composer_device* dev, int what, int* value); + + /* + * Reserved for future use. Must be NULL. + */ + void* reserved_proc[4]; + + /* + * This field is OPTIONAL and can be NULL. + * availability: HWC_DEVICE_API_VERSION_0_3 + */ + hwc_methods_t const *methods; + +} hwc_composer_device_t; + +/** convenience API for opening and closing a device */ + +static inline int hwc_open(const struct hw_module_t* module, + hwc_composer_device_t** device) { + return module->methods->open(module, + HWC_HARDWARE_COMPOSER, (struct hw_device_t**)device); +} + +static inline int hwc_close(hwc_composer_device_t* device) { + return device->common.close(&device->common); +} + +/*****************************************************************************/ + +#endif /* ANDROID_INCLUDE_HARDWARE_HWCOMPOSER_V0_H */ diff --git a/modules/hwcomposer/hwcomposer.cpp b/modules/hwcomposer/hwcomposer.cpp index 0e04cac..0e49e4c 100644 --- a/modules/hwcomposer/hwcomposer.cpp +++ b/modules/hwcomposer/hwcomposer.cpp @@ -29,7 +29,7 @@ /*****************************************************************************/ struct hwc_context_t { - hwc_composer_device_t device; + hwc_composer_device_1_t device; /* our private state goes below here */ }; @@ -54,7 +54,7 @@ hwc_module_t HAL_MODULE_INFO_SYM = { /*****************************************************************************/ -static void dump_layer(hwc_layer_t const* l) { +static void dump_layer(hwc_layer_1_t const* l) { ALOGD("\ttype=%d, flags=%08x, handle=%p, tr=%02x, blend=%04x, {%d,%d,%d,%d}, {%d,%d,%d,%d}", l->compositionType, l->flags, l->handle, l->transform, l->blending, l->sourceCrop.left, @@ -67,7 +67,7 @@ static void dump_layer(hwc_layer_t const* l) { l->displayFrame.bottom); } -static int hwc_prepare(hwc_composer_device_t *dev, hwc_layer_list_t* list) { +static int hwc_prepare(hwc_composer_device_1_t *dev, hwc_layer_list_1_t* list) { if (list && (list->flags & HWC_GEOMETRY_CHANGED)) { for (size_t i=0 ; i<list->numHwLayers ; i++) { //dump_layer(&list->hwLayers[i]); @@ -77,10 +77,10 @@ static int hwc_prepare(hwc_composer_device_t *dev, hwc_layer_list_t* list) { return 0; } -static int hwc_set(hwc_composer_device_t *dev, +static int hwc_set(hwc_composer_device_1_t *dev, hwc_display_t dpy, hwc_surface_t sur, - hwc_layer_list_t* list) + hwc_layer_list_1_t* list) { //for (size_t i=0 ; i<list->numHwLayers ; i++) { // dump_layer(&list->hwLayers[i]); @@ -117,7 +117,7 @@ static int hwc_device_open(const struct hw_module_t* module, const char* name, /* initialize the procs */ dev->device.common.tag = HARDWARE_DEVICE_TAG; - dev->device.common.version = 0; + dev->device.common.version = HWC_DEVICE_API_VERSION_1_0; dev->device.common.module = const_cast<hw_module_t*>(module); dev->device.common.close = hwc_device_close; |