diff options
author | Travis Geiselbrecht <travisg@google.com> | 2012-03-19 15:09:39 -0700 |
---|---|---|
committer | Mike J. Chen <mjchen@google.com> | 2012-10-16 17:53:26 -0700 |
commit | fc13c9292160e3eb83fe5b4f191d1ccee2fd67d9 (patch) | |
tree | 5714e1427b6c3a5346238b8b0504d34a50f220d9 /hwc/hwc.c | |
parent | 5db21d521ed41e2e2cc110b698981e841e027287 (diff) | |
download | omap4-aah-fc13c9292160e3eb83fe5b4f191d1ccee2fd67d9.tar.gz |
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.
(cherry picked from commit 299fdc0df5540a56df0796ff82d153f637c26fa1)
Conflicts:
hwc/hwc.c
Change-Id: I095180dedaf16955996804f795a474c08e47a349
Diffstat (limited to 'hwc/hwc.c')
-rw-r--r-- | hwc/hwc.c | 32 |
1 files changed, 31 insertions, 1 deletions
@@ -337,6 +337,18 @@ static int is_protected(hwc_layer_1_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) @@ -1280,6 +1292,16 @@ static void check_sync_fds(size_t numDisplays, hwc_display_contents_1_t** displa } } +/* test if layer appears to be RGB32 (4 Bpp) and > 1280x720 */ +static int is_large_rgb32_layer(const hwc_layer_1_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_1 *dev, size_t numDisplays, hwc_display_contents_1_t** displays) { @@ -1322,6 +1344,7 @@ static int omap4_hwc_prepare(struct hwc_composer_device_1 *dev, size_t numDispla 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; @@ -1338,7 +1361,9 @@ static int omap4_hwc_prepare(struct hwc_composer_device_1 *dev, size_t numDispla (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); @@ -1384,6 +1409,11 @@ static int omap4_hwc_prepare(struct hwc_composer_device_1 *dev, size_t numDispla 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 */ |