summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSunita Nadampalli <sunitan@ti.com>2012-05-13 15:00:22 -0700
committerJason Simmons <jsimmons@google.com>2012-10-22 15:50:47 -0700
commit83f80658d865b741a024515c523e373df50c091e (patch)
treeaff40a39cc9a74443297924fb3f05388d914f988
parent362d76501749eaa6221ebbb63fcf58542449a391 (diff)
downloadomap4-aah-83f80658d865b741a024515c523e373df50c091e.tar.gz
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> (cherry picked from commit 5d7b83b7ee03be090076d9aefd40dac294377aac) Conflicts: hwc/hwc.c
-rw-r--r--hwc/Android.mk3
-rw-r--r--hwc/hwc.c90
2 files changed, 89 insertions, 4 deletions
diff --git a/hwc/Android.mk b/hwc/Android.mk
index b31fb61..81ad059 100644
--- a/hwc/Android.mk
+++ b/hwc/Android.mk
@@ -7,7 +7,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_ti
LOCAL_SRC_FILES := hwc.c rgz_2d.c
LOCAL_STATIC_LIBRARIES := libpng
diff --git a/hwc/hwc.c b/hwc/hwc.c
index cdbc8e2..174c18b 100644
--- a/hwc/hwc.c
+++ b/hwc/hwc.c
@@ -60,9 +60,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 MAX_TILER_SLOT (32 << 20)
+#define NUM_EXT_DISPLAY_BACK_BUFFERS 2
struct ext_transform_t {
__u8 rotation : 3; /* 90-degree clockwise rotations */
@@ -199,6 +203,8 @@ 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];
/* fake vsync event state */
pthread_mutex_t vsync_lock;
@@ -1336,8 +1342,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;
@@ -1567,6 +1586,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_1 *dev, size_t numDisplays,
hwc_display_contents_1_t** displays)
{
@@ -2151,6 +2211,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);
pthread_mutex_destroy(&hwc_dev->vsync_lock);
@@ -2291,8 +2354,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",
@@ -2676,6 +2750,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) {