summaryrefslogtreecommitdiffstats
path: root/hwc
diff options
context:
space:
mode:
Diffstat (limited to 'hwc')
-rw-r--r--hwc/hwc.c139
1 files changed, 99 insertions, 40 deletions
diff --git a/hwc/hwc.c b/hwc/hwc.c
index 4e67a70..af46847 100644
--- a/hwc/hwc.c
+++ b/hwc/hwc.c
@@ -30,6 +30,7 @@
#include <cutils/properties.h>
#include <cutils/log.h>
#include <cutils/native_handle.h>
+#define HWC_REMOVE_DEPRECATED_VERSIONS 1
#include <hardware/hardware.h>
#include <hardware/hwcomposer.h>
#include <EGL/egl.h>
@@ -163,7 +164,7 @@ struct counts {
struct omap4_hwc_device {
/* static data */
- hwc_composer_device_t base;
+ hwc_composer_device_1_t base;
hwc_procs_t *procs;
pthread_t hdmi_thread;
pthread_mutex_t lock;
@@ -263,7 +264,7 @@ static void showfps(void)
}
}
-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,
@@ -330,7 +331,7 @@ static void dump_printf(struct dump_buf *buf, const char *fmt, ...)
va_end(ap);
}
-static void dump_set_info(omap4_hwc_device_t *hwc_dev, hwc_layer_list_t* list)
+static void dump_set_info(omap4_hwc_device_t *hwc_dev, hwc_display_contents_1_t* list)
{
struct dsscomp_setup_dispc_data *dsscomp = &hwc_dev->comp_data.dsscomp_data;
char logbuf[1024];
@@ -344,7 +345,7 @@ static void dump_set_info(omap4_hwc_device_t *hwc_dev, hwc_layer_list_t* list)
for (i = 0; list && i < list->numHwLayers; i++) {
if (i)
dump_printf(&log, " ");
- hwc_layer_t *layer = &list->hwLayers[i];
+ hwc_layer_1_t *layer = &list->hwLayers[i];
IMG_native_handle_t *handle = (IMG_native_handle_t *)layer->handle;
if (hwc_dev->post2_blit_buffers) {
if ((i + 1) < hwc_dev->post2_layers)
@@ -415,18 +416,18 @@ static int omap4_hwc_is_valid_format(int format)
}
}
-static __u32 get_s3d_layout_type(hwc_layer_t *layer)
+static __u32 get_s3d_layout_type(hwc_layer_1_t *layer)
{
return (layer->flags & S3DLayoutTypeMask) >> S3DLayoutTypeShift;
}
-static __u32 get_s3d_layout_order(hwc_layer_t *layer)
+static __u32 get_s3d_layout_order(hwc_layer_1_t *layer)
{
return (layer->flags & S3DLayoutOrderMask) >> S3DLayoutOrderShift;
}
-static int scaled(hwc_layer_t *layer)
+static int scaled(hwc_layer_1_t *layer)
{
int w = WIDTH(layer->sourceCrop);
int h = HEIGHT(layer->sourceCrop);
@@ -439,7 +440,7 @@ static int scaled(hwc_layer_t *layer)
|| get_s3d_layout_type(layer) != eMono;
}
-static int is_protected(hwc_layer_t *layer)
+static int is_protected(hwc_layer_1_t *layer)
{
IMG_native_handle_t *handle = (IMG_native_handle_t *)layer->handle;
@@ -504,7 +505,7 @@ static int is_NV12(IMG_native_handle_t *handle)
}
}
-static int is_upscaled_NV12(omap4_hwc_device_t *hwc_dev, hwc_layer_t *layer)
+static int is_upscaled_NV12(omap4_hwc_device_t *hwc_dev, hwc_layer_1_t *layer)
{
if (!layer)
return 0;
@@ -523,7 +524,7 @@ static int is_upscaled_NV12(omap4_hwc_device_t *hwc_dev, hwc_layer_t *layer)
HEIGHT(layer->displayFrame) >= h * hwc_dev->upscaled_nv12_limit);
}
-static int dockable(hwc_layer_t *layer)
+static int dockable(hwc_layer_1_t *layer)
{
IMG_native_handle_t *handle = (IMG_native_handle_t *)layer->handle;
@@ -603,7 +604,7 @@ omap4_hwc_setup_layer_base(struct dss2_ovl_cfg *oc, int index, int format, int b
static void
omap4_hwc_setup_layer(omap4_hwc_device_t *hwc_dev, struct dss2_ovl_info *ovl,
- hwc_layer_t *layer, int index,
+ hwc_layer_1_t *layer, int index,
int format, int width, int height)
{
struct dss2_ovl_cfg *oc = &ovl->cfg;
@@ -915,7 +916,7 @@ static int omap4_hwc_can_scale(__u32 src_w, __u32 src_h, __u32 dst_w, __u32 dst_
return 1;
}
-static int omap4_hwc_can_scale_layer(omap4_hwc_device_t *hwc_dev, hwc_layer_t *layer, IMG_native_handle_t *handle)
+static int omap4_hwc_can_scale_layer(omap4_hwc_device_t *hwc_dev, hwc_layer_1_t *layer, IMG_native_handle_t *handle)
{
int src_w = WIDTH(layer->sourceCrop);
int src_h = HEIGHT(layer->sourceCrop);
@@ -933,7 +934,7 @@ static int omap4_hwc_can_scale_layer(omap4_hwc_device_t *hwc_dev, hwc_layer_t *l
}
static int omap4_hwc_is_valid_layer(omap4_hwc_device_t *hwc_dev,
- hwc_layer_t *layer,
+ hwc_layer_1_t *layer,
IMG_native_handle_t *handle)
{
/* Skip layers are handled by SF */
@@ -1109,13 +1110,14 @@ static int omap4_hwc_set_best_hdmi_mode(omap4_hwc_device_t *hwc_dev, __u32 xres,
return 0;
}
-static void gather_layer_statistics(omap4_hwc_device_t *hwc_dev, struct counts *num, hwc_layer_list_t *list)
+
+static void gather_layer_statistics(omap4_hwc_device_t *hwc_dev, struct counts *num, hwc_display_contents_1_t *list)
{
unsigned int i;
/* Figure out how many layers we can support via DSS */
for (i = 0; list && i < list->numHwLayers; i++) {
- hwc_layer_t *layer = &list->hwLayers[i];
+ hwc_layer_1_t *layer = &list->hwLayers[i];
IMG_native_handle_t *handle = (IMG_native_handle_t *)layer->handle;
__u32 s3d_layout_type = get_s3d_layout_type(layer);
@@ -1253,7 +1255,7 @@ static int can_dss_render_all(omap4_hwc_device_t *hwc_dev, struct counts *num)
}
static inline int can_dss_render_layer(omap4_hwc_device_t *hwc_dev,
- hwc_layer_t *layer)
+ hwc_layer_1_t *layer)
{
IMG_native_handle_t *handle = (IMG_native_handle_t *)layer->handle;
@@ -1520,6 +1522,36 @@ static int setup_mirroring(omap4_hwc_device_t *hwc_dev)
return 0;
}
+/*
+ * We're using "implicit" synchronization, so make sure we aren't passing any
+ * sync object descriptors around.
+ */
+static void check_sync_fds(size_t numDisplays, hwc_display_contents_1_t** displays)
+{
+ //ALOGD("checking sync FDs");
+ unsigned int i, j;
+ for (i = 0; i < numDisplays; i++) {
+ hwc_display_contents_1_t* list = displays[i];
+ if (list->retireFenceFd >= 0) {
+ ALOGW("retireFenceFd[%u] was %d", i, list->retireFenceFd);
+ list->retireFenceFd = -1;
+ }
+
+ for (j = 0; j < list->numHwLayers; j++) {
+ hwc_layer_1_t* layer = &list->hwLayers[j];
+ if (layer->acquireFenceFd >= 0) {
+ ALOGW("acquireFenceFd[%u][%u] was %d, closing", i, j, layer->acquireFenceFd);
+ close(layer->acquireFenceFd);
+ layer->acquireFenceFd = -1;
+ }
+ if (layer->releaseFenceFd >= 0) {
+ ALOGW("releaseFenceFd[%u][%u] was %d", i, j, layer->releaseFenceFd);
+ layer->releaseFenceFd = -1;
+ }
+ }
+ }
+}
+
static void blit_reset(omap4_hwc_device_t *hwc_dev, int flags)
{
hwc_dev->blit_flags = 0;
@@ -1532,7 +1564,7 @@ static void blit_reset(omap4_hwc_device_t *hwc_dev, int flags)
rgz_release(&grgz);
}
-static int blit_layers(omap4_hwc_device_t *hwc_dev, hwc_layer_list_t *list, int bufoff)
+static int blit_layers(omap4_hwc_device_t *hwc_dev, hwc_display_contents_1_t *list, int bufoff)
{
/* Do not blit if this frame will be composed entirely by the GPU */
if (!list || hwc_dev->force_sgx)
@@ -1686,8 +1718,15 @@ handle_error:
return -1;
}
-static int omap4_hwc_prepare(struct hwc_composer_device *dev, hwc_layer_list_t* list)
+
+static int omap4_hwc_prepare(struct hwc_composer_device_1 *dev, size_t numDisplays,
+ hwc_display_contents_1_t** displays)
{
+ if (!numDisplays || displays == NULL) {
+ return 0;
+ }
+
+ hwc_display_contents_1_t* list = displays[0]; // ignore displays beyond the first
omap4_hwc_device_t *hwc_dev = (omap4_hwc_device_t *)dev;
struct dsscomp_setup_dispc_data *dsscomp = &hwc_dev->comp_data.dsscomp_data;
struct counts num = { .composited_layers = list ? list->numHwLayers : 0 };
@@ -1743,8 +1782,9 @@ static int omap4_hwc_prepare(struct hwc_composer_device *dev, hwc_layer_list_t*
/* set up if DSS layers */
unsigned int mem_used = 0;
- for (i = 0; list && i < list->numHwLayers && !blit_all; i++) {
- hwc_layer_t *layer = &list->hwLayers[i];
+ hwc_dev->ovls_blending = 0;
+ for (i = 0; list && i < list->numHwLayers; i++) {
+ hwc_layer_1_t *layer = &list->hwLayers[i];
IMG_native_handle_t *handle = (IMG_native_handle_t *)layer->handle;
if (dsscomp->num_ovls < num.max_hw_overlays &&
@@ -2009,9 +2049,20 @@ static void omap4_hwc_reset_screen(omap4_hwc_device_t *hwc_dev)
}
}
-static int omap4_hwc_set(struct hwc_composer_device *dev, hwc_display_t dpy,
- hwc_surface_t sur, hwc_layer_list_t* list)
+static int omap4_hwc_set(struct hwc_composer_device_1 *dev,
+ size_t numDisplays, hwc_display_contents_1_t** displays)
{
+ if (!numDisplays || displays == NULL) {
+ ALOGD("set: empty display list");
+ return 0;
+ }
+ hwc_display_t dpy = NULL;
+ hwc_surface_t sur = NULL;
+ hwc_display_contents_1_t* list = displays[0]; // ignore displays beyond the first
+ if (list != NULL) {
+ dpy = list->dpy;
+ sur = list->sur;
+ }
omap4_hwc_device_t *hwc_dev = (omap4_hwc_device_t *)dev;
struct dsscomp_setup_dispc_data *dsscomp = &hwc_dev->comp_data.dsscomp_data;
int err = 0;
@@ -2089,16 +2140,18 @@ static int omap4_hwc_set(struct hwc_composer_device *dev, hwc_display_t dpy,
if (err)
ALOGE("Post2 error");
+ check_sync_fds(numDisplays, displays);
+
err_out:
pthread_mutex_unlock(&hwc_dev->lock);
- if (invalidate && hwc_dev->procs && hwc_dev->procs->invalidate)
+ if (invalidate)
hwc_dev->procs->invalidate(hwc_dev->procs);
return err;
}
-static void omap4_hwc_dump(struct hwc_composer_device *dev, char *buff, int buff_len)
+static void omap4_hwc_dump(struct hwc_composer_device_1 *dev, char *buff, int buff_len)
{
omap4_hwc_device_t *hwc_dev = (omap4_hwc_device_t *)dev;
struct dsscomp_setup_dispc_data *dsscomp = &hwc_dev->comp_data.dsscomp_data;
@@ -2463,8 +2516,11 @@ static void handle_hotplug(omap4_hwc_device_t *hwc_dev)
pthread_mutex_unlock(&hwc_dev->lock);
- if (hwc_dev->procs && hwc_dev->procs->invalidate)
- hwc_dev->procs->invalidate(hwc_dev->procs);
+ /* hwc_dev->procs is set right after the device is opened, but there is
+ * still a race condition where a hotplug event might occur after the open
+ * but before the procs are registered. */
+ if (hwc_dev->procs)
+ hwc_dev->procs->invalidate(hwc_dev->procs);
}
static void handle_uevents(omap4_hwc_device_t *hwc_dev, const char *buff, int len)
@@ -2500,9 +2556,8 @@ static void handle_uevents(omap4_hwc_device_t *hwc_dev, const char *buff, int le
}
if (vsync) {
- if (hwc_dev->procs && hwc_dev->procs->vsync) {
+ if (hwc_dev->procs)
hwc_dev->procs->vsync(hwc_dev->procs, 0, timestamp);
- }
} else {
if (dock)
hwc_dev->ext.force_dock = state == 1;
@@ -2539,7 +2594,7 @@ static void *omap4_hwc_hdmi_thread(void *data)
if (err == 0) {
if (hwc_dev->idle) {
- if (hwc_dev->procs && hwc_dev->procs->invalidate) {
+ if (hwc_dev->procs) {
pthread_mutex_lock(&hwc_dev->lock);
invalidate = hwc_dev->last_int_ovls > 1 && !hwc_dev->force_sgx;
if (invalidate) {
@@ -2580,7 +2635,7 @@ static void *omap4_hwc_hdmi_thread(void *data)
return NULL;
}
-static void omap4_hwc_registerProcs(struct hwc_composer_device* dev,
+static void omap4_hwc_registerProcs(struct hwc_composer_device_1* dev,
hwc_procs_t const* procs)
{
omap4_hwc_device_t *hwc_dev = (omap4_hwc_device_t *) dev;
@@ -2588,7 +2643,7 @@ static void omap4_hwc_registerProcs(struct hwc_composer_device* dev,
hwc_dev->procs = (typeof(hwc_dev->procs)) procs;
}
-static int omap4_hwc_query(struct hwc_composer_device* dev,
+static int omap4_hwc_query(struct hwc_composer_device_1* dev,
int what, int* value)
{
omap4_hwc_device_t *hwc_dev = (omap4_hwc_device_t *) dev;
@@ -2609,8 +2664,8 @@ static int omap4_hwc_query(struct hwc_composer_device* dev,
return 0;
}
-static int omap4_hwc_event_control(struct hwc_composer_device* dev,
- int event, int enabled)
+static int omap4_hwc_event_control(struct hwc_composer_device_1* dev,
+ int dpy, int event, int enabled)
{
omap4_hwc_device_t *hwc_dev = (omap4_hwc_device_t *) dev;
@@ -2631,9 +2686,12 @@ static int omap4_hwc_event_control(struct hwc_composer_device* dev,
}
}
-struct hwc_methods omap4_hwc_methods = {
- .eventControl = &omap4_hwc_event_control,
-};
+static int omap4_hwc_blank(struct hwc_composer_device_1 *dev, int dpy, int blank)
+{
+ // We're using an older method of screen blanking based on
+ // early_suspend in the kernel. No need to do anything here.
+ return 0;
+}
static int omap4_hwc_device_open(const hw_module_t* module, const char* name,
hw_device_t** device)
@@ -2665,7 +2723,7 @@ static int omap4_hwc_device_open(const hw_module_t* module, const char* name,
memset(hwc_dev, 0, sizeof(*hwc_dev));
hwc_dev->base.common.tag = HARDWARE_DEVICE_TAG;
- hwc_dev->base.common.version = HWC_DEVICE_API_VERSION_0_3;
+ hwc_dev->base.common.version = HWC_DEVICE_API_VERSION_1_0;
char value[PROPERTY_VALUE_MAX];
property_get("ro.product.board", value, "");
@@ -2682,10 +2740,11 @@ static int omap4_hwc_device_open(const hw_module_t* module, const char* name,
hwc_dev->base.common.close = omap4_hwc_device_close;
hwc_dev->base.prepare = omap4_hwc_prepare;
hwc_dev->base.set = omap4_hwc_set;
- hwc_dev->base.dump = omap4_hwc_dump;
- hwc_dev->base.registerProcs = omap4_hwc_registerProcs;
+ hwc_dev->base.eventControl = omap4_hwc_event_control;
+ hwc_dev->base.blank = omap4_hwc_blank;
hwc_dev->base.query = omap4_hwc_query;
- hwc_dev->base.methods = &omap4_hwc_methods;
+ hwc_dev->base.registerProcs = omap4_hwc_registerProcs;
+ hwc_dev->base.dump = omap4_hwc_dump;
hwc_dev->fb_dev = hwc_mod->fb_dev;
*device = &hwc_dev->base.common;