summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTravis Geiselbrecht <travisg@google.com>2012-03-19 15:09:39 -0700
committerTravis Geiselbrecht <travisg@google.com>2012-03-22 12:37:40 -0700
commitf693bd80586d880a48946ffc121e2b150fdd77f5 (patch)
tree4fd90398fd92f95714c0a7a0fd0d6a54bd747501
parentf56e5739bba0ea7ade6c3fe22f84a1ab812f4e2f (diff)
downloadhardware_ti_omap4-f693bd80586d880a48946ffc121e2b150fdd77f5.zip
hardware_ti_omap4-f693bd80586d880a48946ffc121e2b150fdd77f5.tar.gz
hardware_ti_omap4-f693bd80586d880a48946ffc121e2b150fdd77f5.tar.bz2
DO NOT MERGE
hwc: disable using DSS for more than one hw RGB32 layer > 1280x720 Current dss hardware seems to be able to handle 2 layers of 1080p RGB32 content before buffer underrunning. One layer (OVL3) is always consumed by the framebuffer, so we're left with at most one 1080p layer from surfaceflinger. Add code to punt the 2nd and above 1080p RGB32 layer to the SGX. This works great for games and video content, since they seem to generally be RGB16 and NV12 layers, which DSS can deal with. Change-Id: I3566181b218d4babf588c98737c90eb22d32668e
-rw-r--r--hwc/hwc.c32
1 files changed, 31 insertions, 1 deletions
diff --git a/hwc/hwc.c b/hwc/hwc.c
index 4ff0754..cbb0d9b 100644
--- a/hwc/hwc.c
+++ b/hwc/hwc.c
@@ -335,6 +335,18 @@ static int is_protected(hwc_layer_t *layer)
#define is_BLENDED(layer) ((layer)->blending != HWC_BLENDING_NONE)
+static int is_RGB32(IMG_native_handle_t *handle)
+{
+ switch(handle->iFormat)
+ {
+ case HAL_PIXEL_FORMAT_BGRA_8888:
+ case HAL_PIXEL_FORMAT_BGRX_8888:
+ return 1;
+ default:
+ return 0;
+ }
+}
+
static int is_RGB(IMG_native_handle_t *handle)
{
switch(handle->iFormat)
@@ -1242,6 +1254,16 @@ static int setup_mirroring(omap4_hwc_device_t *hwc_dev)
return 0;
}
+/* test if layer appears to be RGB32 (4 Bpp) and > 1280x720 */
+static int is_large_rgb32_layer(const hwc_layer_t *layer)
+{
+ IMG_native_handle_t *handle = (IMG_native_handle_t *)layer->handle;
+
+ return is_RGB32(handle) &&
+ (((layer->sourceCrop.right - layer->sourceCrop.left) > 1280) ||
+ ((layer->sourceCrop.bottom - layer->sourceCrop.top) > 720));
+}
+
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;
@@ -1278,6 +1300,7 @@ static int omap4_hwc_prepare(struct hwc_composer_device *dev, hwc_layer_list_t*
int fb_z = -1;
int scaled_gfx = 0;
int ix_docking = -1;
+ int big_layers = 0;
/* set up if DSS layers */
unsigned int mem_used = 0;
@@ -1294,7 +1317,9 @@ static int omap4_hwc_prepare(struct hwc_composer_device *dev, hwc_layer_list_t*
(hwc_dev->ext.current.docking && hwc_dev->ext.current.enabled && dockable(layer))) &&
mem_used + mem1d(handle) < MAX_TILER_SLOT &&
/* can't have a transparent overlay in the middle of the framebuffer stack */
- !(is_BLENDED(layer) && fb_z >= 0)) {
+ !(is_BLENDED(layer) && fb_z >= 0) &&
+ /* current hardware is unable to keep up with more than 1 'large' RGB32 layer */
+ !(is_large_rgb32_layer(layer) && big_layers > 0)) {
/* render via DSS overlay */
mem_used += mem1d(handle);
@@ -1340,6 +1365,11 @@ static int omap4_hwc_prepare(struct hwc_composer_device *dev, hwc_layer_list_t*
omap4_hwc_adjust_lcd_layer(hwc_dev, &dsscomp->ovls[dsscomp->num_ovls]);
dsscomp->num_ovls++;
z++;
+
+ /* record whether or not this was a 'big' RGB32 layer */
+ if (is_large_rgb32_layer(layer)) {
+ big_layers++;
+ }
} else if (hwc_dev->use_sgx) {
if (fb_z < 0) {
/* NOTE: we are not handling transparent cutout for now */