summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/hardware/hwcomposer.h122
-rw-r--r--include/hardware/hwcomposer_defs.h2
-rw-r--r--include/hardware/hwcomposer_v0.h272
-rw-r--r--modules/hwcomposer/hwcomposer.cpp12
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;