diff options
author | Sunita Nadampalli <sunitan@ti.com> | 2012-05-13 15:00:22 -0700 |
---|---|---|
committer | Daniel Levin <dendy@ti.com> | 2012-11-28 21:16:24 +0200 |
commit | 9e02bb877675934edd3803cf6cbeb597e965b716 (patch) | |
tree | afe71ed6706068f1beeae20d95640bb2ca697f65 | |
parent | 8bc5a728d1553a4d0b97c9ec61c12a6a5bb54949 (diff) | |
download | hardware_ti_omap4-9e02bb877675934edd3803cf6cbeb597e965b716.zip hardware_ti_omap4-9e02bb877675934edd3803cf6cbeb597e965b716.tar.gz hardware_ti_omap4-9e02bb877675934edd3803cf6cbeb597e965b716.tar.bz2 |
hwc: added support for ext display back buffer allocation
When the ext display transform is different from the FB,
the mirroring/cloning is achived with the help of back-buffers,
which are allocated in TILER2D space to get the required
transformation. This patch adds support in HWC to detect
the ext display transform and allocate back buffers from
TILER2D space and program dsscomp accordingly.
Signed-off-by: Sunita Nadampalli <sunitan@ti.com>
hwc: make file fix for local include path
the local include path for ion is changed from base level
to local. this is required to allow compiling at hwc level.
Change-Id: Ie1e9e6688652fdc8aa496dfc367d385aca362a27
Signed-off-by: Sunita Nadampalli <sunitan@ti.com>
-rw-r--r-- | hwc/Android.mk | 3 | ||||
-rw-r--r-- | hwc/hwc.c | 90 |
2 files changed, 90 insertions, 3 deletions
diff --git a/hwc/Android.mk b/hwc/Android.mk index e158863..489d739 100644 --- a/hwc/Android.mk +++ b/hwc/Android.mk @@ -6,7 +6,8 @@ include $(CLEAR_VARS) LOCAL_PRELINK_MODULE := false LOCAL_ARM_MODE := arm LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/../vendor/lib/hw -LOCAL_SHARED_LIBRARIES := liblog libEGL libcutils libutils libhardware libhardware_legacy libz +LOCAL_SHARED_LIBRARIES := liblog libEGL libcutils libutils libhardware libhardware_legacy libz \ + libion LOCAL_SRC_FILES := hwc.c rgz_2d.c LOCAL_STATIC_LIBRARIES := libpng @@ -58,8 +58,13 @@ #include "hal_public.h" #include "rgz_2d.h" +#include <linux/ion.h> +#include <linux/omap_ion.h> +#include <ion/ion.h> + #define MAX_HW_OVERLAYS 4 #define NUM_NONSCALING_OVERLAYS 1 +#define NUM_EXT_DISPLAY_BACK_BUFFERS 2 struct ext_transform_t { __u8 rotation : 3; /* 90-degree clockwise rotations */ @@ -196,6 +201,9 @@ struct omap4_hwc_device { struct omap_hwc_data comp_data; /* This is a kernel data structure */ struct rgz_blt_entry blit_ops[RGZ_MAX_BLITS]; struct counts stats; + int ion_fd; + struct ion_handle *ion_handles[2]; + }; typedef struct omap4_hwc_device omap4_hwc_device_t; @@ -1220,8 +1228,21 @@ static int clone_layer(omap4_hwc_device_t *hwc_dev, int ix) { /* reserve overlays at end for other display */ o->cfg.ix = MAX_HW_OVERLAYS - 1 - ext_ovl_ix; o->cfg.mgr_ix = 1; - o->addressing = OMAP_DSS_BUFADDR_OVL_IX; - o->ba = ix; + /* + * Here the assumption is that overlay0 is the one attached to FB. + * Hence this clone_layer call is for FB cloning (provided use_sgx is true). + */ + /* For the external displays whose transform is the same as + * that of primary display, ion_handles would be NULL hence + * the below logic doesn't execute. + */ + if (ix == 0 && hwc_dev->ion_handles[sync_id%2] && hwc_dev->use_sgx) { + o->addressing = OMAP_DSS_BUFADDR_ION; + o->ba = (int)hwc_dev->ion_handles[sync_id%2]; + } else { + o->addressing = OMAP_DSS_BUFADDR_OVL_IX; + o->ba = ix; + } /* use distinct z values (to simplify z-order checking) */ o->cfg.zorder += hwc_dev->post2_layers; @@ -1411,6 +1432,47 @@ void debug_post2(omap4_hwc_device_t *hwc_dev, int nbufs) } } +static int free_tiler2d_buffers(omap4_hwc_device_t *hwc_dev) +{ + int i; + + for (i = 0 ; i < NUM_EXT_DISPLAY_BACK_BUFFERS; i++) { + ion_free(hwc_dev->ion_fd, hwc_dev->ion_handles[i]); + hwc_dev->ion_handles[i] = NULL; + } + return 0; +} + +static int allocate_tiler2d_buffers(omap4_hwc_device_t *hwc_dev) +{ + int ret, i; + size_t stride; + + if (hwc_dev->ion_fd < 0) { + ALOGE("No ion fd, hence can't allocate tiler2d buffers"); + return -1; + } + + for (i = 0; i < NUM_EXT_DISPLAY_BACK_BUFFERS; i++) { + if (hwc_dev->ion_handles[i]) + return 0; + } + + for (i = 0 ; i < NUM_EXT_DISPLAY_BACK_BUFFERS; i++) { + ret = ion_alloc_tiler(hwc_dev->ion_fd, hwc_dev->fb_dev->base.width, hwc_dev->fb_dev->base.height, + TILER_PIXEL_FMT_32BIT, 0, &hwc_dev->ion_handles[i], &stride); + if (ret) + goto handle_error; + + ALOGI("ion handle[%d][%p]", i, hwc_dev->ion_handles[i]); + } + return 0; + +handle_error: + free_tiler2d_buffers(hwc_dev); + return -1; +} + static int omap4_hwc_prepare(struct hwc_composer_device *dev, hwc_layer_list_t* list) { omap4_hwc_device_t *hwc_dev = (omap4_hwc_device_t *)dev; @@ -1954,6 +2016,9 @@ static int omap4_hwc_device_close(hw_device_t* device) close(hwc_dev->hdmi_fb_fd); if (hwc_dev->fb_fd >= 0) close(hwc_dev->fb_fd); + if (hwc_dev->ion_fd >= 0) + ion_close(hwc_dev->ion_fd); + /* pthread will get killed when parent process exits */ pthread_mutex_destroy(&hwc_dev->lock); free(hwc_dev); @@ -2093,8 +2158,19 @@ static void handle_hotplug(omap4_hwc_device_t *hwc_dev) } else ext->mirror.enabled = 0; } + /* Allocate backup buffers for FB rotation + * This is required only if the FB tranform is different from that + * of the external display and the FB is not in TILER2D space + */ + if (ext->mirror.rotation && (limits.fbmem_type != DSSCOMP_FBMEM_TILER2D)) + allocate_tiler2d_buffers(hwc_dev); + } else { ext->last_mode = 0; + if (ext->mirror.rotation && (limits.fbmem_type != DSSCOMP_FBMEM_TILER2D)) { + /* free tiler 2D buffer on detach */ + free_tiler2d_buffers(hwc_dev); + } } ALOGI("external display changed (state=%d, mirror={%s tform=%ddeg%s}, dock={%s tform=%ddeg%s%s}, tv=%d", state, ext->mirror.enabled ? "enabled" : "disabled", @@ -2384,6 +2460,16 @@ static int omap4_hwc_device_open(const hw_module_t* module, const char* name, goto done; } + hwc_dev->ion_fd = ion_open(); + if (hwc_dev->ion_fd < 0) { + ALOGE("failed to open ion driver (%d)", errno); + } + + int i; + for (i = 0; i < NUM_EXT_DISPLAY_BACK_BUFFERS; i++) { + hwc_dev->ion_handles[i] = NULL; + } + /* use default value in case some of requested display parameters missing */ hwc_dev->ext.lcd_xpy = 1.0; if (hwc_dev->fb_dis.timings.x_res && hwc_dev->fb_dis.height_in_mm) { |