diff options
author | Travis Geiselbrecht <travisg@google.com> | 2012-03-19 15:09:39 -0700 |
---|---|---|
committer | Travis Geiselbrecht <travisg@google.com> | 2012-03-22 12:37:40 -0700 |
commit | f693bd80586d880a48946ffc121e2b150fdd77f5 (patch) | |
tree | 4fd90398fd92f95714c0a7a0fd0d6a54bd747501 | |
parent | f56e5739bba0ea7ade6c3fe22f84a1ab812f4e2f (diff) | |
download | hardware_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.c | 32 |
1 files changed, 31 insertions, 1 deletions
@@ -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 */ |