diff options
Diffstat (limited to 'hwc')
-rw-r--r-- | hwc/hwc.c | 139 |
1 files changed, 99 insertions, 40 deletions
@@ -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; |