summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJesse Hall <jessehall@google.com>2012-07-25 15:11:41 -0700
committerJesse Hall <jessehall@google.com>2012-07-30 16:52:21 -0700
commit65bed1f947ad9eb992c02a3563bd64ef05c4e268 (patch)
tree2af87ed51899469ff10e3b5e5f358c0acf69d160
parentd294b9ffa1569dfc95cdc28a5955caea60950a20 (diff)
downloadhardware_libhardware-65bed1f947ad9eb992c02a3563bd64ef05c4e268.zip
hardware_libhardware-65bed1f947ad9eb992c02a3563bd64ef05c4e268.tar.gz
hardware_libhardware-65bed1f947ad9eb992c02a3563bd64ef05c4e268.tar.bz2
Add multi-display and flip fence to HWC
Change-Id: I31b4fc293220bc51169971df93347dd35fdc30ef
-rw-r--r--include/hardware/hwcomposer.h117
-rw-r--r--modules/hwcomposer/hwcomposer.cpp16
2 files changed, 69 insertions, 64 deletions
diff --git a/include/hardware/hwcomposer.h b/include/hardware/hwcomposer.h
index a036da3..11176ec 100644
--- a/include/hardware/hwcomposer.h
+++ b/include/hardware/hwcomposer.h
@@ -64,7 +64,7 @@ typedef struct hwc_methods_1 {
/*
* eventControl(..., event, enabled)
- * Enables or disables h/w composer events.
+ * Enables or disables h/w composer events for a display.
*
* eventControl can be called from any thread and takes effect
* immediately.
@@ -77,13 +77,14 @@ typedef struct hwc_methods_1 {
*/
int (*eventControl)(
- struct hwc_composer_device_1* dev, int event, int enabled);
+ struct hwc_composer_device_1* dev, int dpy,
+ int event, int enabled);
/*
* This field is OPTIONAL and can be NULL.
*
* blank(..., blank)
- * Blanks or unblanks the screen.
+ * Blanks or unblanks a display's screen.
*
* Turns the screen off when blank is nonzero, on when blank is zero.
* Blanking may also be triggered by a call to set..., 0, 0, 0). Multiple
@@ -92,7 +93,7 @@ typedef struct hwc_methods_1 {
* returns 0 on success, negative on error.
*/
- int (*blank)(struct hwc_composer_device_1* dev, int blank);
+ int (*blank)(struct hwc_composer_device_1* dev, int dpy, int blank);
} hwc_methods_1_t;
@@ -215,8 +216,14 @@ typedef struct hwc_layer_1 {
} hwc_layer_1_t;
+/* This represents a display, typically an EGLDisplay object */
+typedef void* hwc_display_t;
+
+/* This represents a surface, typically an EGLSurface object */
+typedef void* hwc_surface_t;
+
/*
- * hwc_layer_list_t::flags values
+ * hwc_display_contents_1_t::flags values
*/
enum {
/*
@@ -228,21 +235,36 @@ enum {
};
/*
- * List of layers.
- * The handle members of hwLayers elements must be unique.
+ * Description of the contents to output on a display.
+ *
+ * This is the top-level structure passed to the prepare and set calls to
+ * negotiate and commit the composition of a display image.
*/
-typedef struct hwc_layer_list_1 {
+typedef struct hwc_display_contents_1 {
+ /* File descriptor referring to a Sync HAL fence object which will signal
+ * when this display image is no longer visible, i.e. when the following
+ * set() takes effect. The fence object is created and returned by the set
+ * call; this field will be -1 on entry to prepare and set. SurfaceFlinger
+ * will close the returned file descriptor.
+ */
+ int flipFenceFd;
+
+ /* (dpy, sur) is the target of SurfaceFlinger's OpenGL ES composition.
+ * They aren't relevant to prepare. The set call should commit this surface
+ * atomically to the display along with any overlay layers.
+ */
+ hwc_display_t dpy;
+ hwc_surface_t sur;
+
+ /* List of layers that will be composed on the display. The buffer handles
+ * in the list will be unique. If numHwLayers is 0 and/or hwLayers is NULL,
+ * all composition will be performed by SurfaceFlinger.
+ */
uint32_t flags;
size_t numHwLayers;
hwc_layer_1_t hwLayers[0];
-} hwc_layer_list_1_t;
-
-/* This represents a display, typically an EGLDisplay object */
-typedef void* hwc_display_t;
-
-/* This represents a surface, typically an EGLSurface object */
-typedef void* hwc_surface_t;
+} hwc_display_contents_1_t;
/* see hwc_composer_device::registerProcs()
* Any of the callbacks can be NULL, in which case the corresponding
@@ -262,9 +284,10 @@ typedef struct hwc_procs {
/*
* (*vsync)() is called by the h/w composer HAL when a vsync event is
- * received and HWC_EVENT_VSYNC is enabled (see: hwc_event_control).
+ * received and HWC_EVENT_VSYNC is enabled on a display
+ * (see: hwc_event_control).
*
- * the "zero" parameter must always be 0.
+ * the "dpy" parameter indicates which display the vsync event is for.
* the "timestamp" parameter is the system monotonic clock timestamp in
* nanosecond of when the vsync event happened.
*
@@ -278,9 +301,8 @@ typedef struct hwc_procs {
* hwc_composer_device.set(..., 0, 0, 0) (screen off). The implementation
* can either stop or continue to process VSYNC events, but must not
* crash or cause other problems.
- *
*/
- void (*vsync)(struct hwc_procs* procs, int zero, int64_t timestamp);
+ void (*vsync)(struct hwc_procs* procs, int dpy, int64_t timestamp);
} hwc_procs_t;
@@ -299,72 +321,55 @@ typedef struct hwc_composer_device_1 {
*
* (*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.
+ * The HWC responds by setting the compositionType field in each layer to
+ * either HWC_FRAMEBUFFER or HWC_OVERLAY. In the former case, the
+ * composition for the layer is handled by SurfaceFlinger with OpenGL ES,
+ * in the later case, the HWC will have to handle the 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_1 *dev,
- hwc_layer_list_1_t* list);
+ size_t numDisplays, hwc_display_contents_1_t** displays);
/*
* (*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 layer lists are guaranteed to be the same as the ones returned from
+ * the last call to (*prepare)().
*
- * - 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.
+ * When this call returns the caller assumes that the displays will be
+ * updated in the near future with the content of their work lists, 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.
+ * A display with a NULL layer list 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.
+ * The dpy, surf, and layers fields 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 down the relevant
+ * h/w blocks.
*
* 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).
+ * 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_1 *dev,
- hwc_display_t dpy,
- hwc_surface_t sur,
- hwc_layer_list_1_t* list);
+ size_t numDisplays, hwc_display_contents_1_t** displays);
/*
* This field is OPTIONAL and can be NULL.
diff --git a/modules/hwcomposer/hwcomposer.cpp b/modules/hwcomposer/hwcomposer.cpp
index 0e49e4c..f0a5512 100644
--- a/modules/hwcomposer/hwcomposer.cpp
+++ b/modules/hwcomposer/hwcomposer.cpp
@@ -67,26 +67,26 @@ static void dump_layer(hwc_layer_1_t const* l) {
l->displayFrame.bottom);
}
-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++) {
+static int hwc_prepare(hwc_composer_device_1_t *dev,
+ size_t numDisplays, hwc_display_contents_1_t** displays) {
+ if (displays && (displays[0]->flags & HWC_GEOMETRY_CHANGED)) {
+ for (size_t i=0 ; i<displays[0]->numHwLayers ; i++) {
//dump_layer(&list->hwLayers[i]);
- list->hwLayers[i].compositionType = HWC_FRAMEBUFFER;
+ displays[0]->hwLayers[i].compositionType = HWC_FRAMEBUFFER;
}
}
return 0;
}
static int hwc_set(hwc_composer_device_1_t *dev,
- hwc_display_t dpy,
- hwc_surface_t sur,
- hwc_layer_list_1_t* list)
+ size_t numDisplays, hwc_display_contents_1_t** displays)
{
//for (size_t i=0 ; i<list->numHwLayers ; i++) {
// dump_layer(&list->hwLayers[i]);
//}
- EGLBoolean sucess = eglSwapBuffers((EGLDisplay)dpy, (EGLSurface)sur);
+ EGLBoolean sucess = eglSwapBuffers((EGLDisplay)displays[0]->dpy,
+ (EGLSurface)displays[0]->sur);
if (!sucess) {
return HWC_EGL_ERROR;
}