diff options
author | Gustavo Diaz Prado <a0273371@ti.com> | 2012-08-03 14:56:33 -0500 |
---|---|---|
committer | Daniel Levin <dendy@ti.com> | 2012-11-28 21:16:24 +0200 |
commit | a5f87d7c75ca4b2b6da8082d513f1581fb4569f4 (patch) | |
tree | 0ccb1524732ee67ae0610507a29fcd9f11170c35 /hwc | |
parent | 9e02bb877675934edd3803cf6cbeb597e965b716 (diff) | |
download | hardware_ti_omap4-a5f87d7c75ca4b2b6da8082d513f1581fb4569f4.zip hardware_ti_omap4-a5f87d7c75ca4b2b6da8082d513f1581fb4569f4.tar.gz hardware_ti_omap4-a5f87d7c75ca4b2b6da8082d513f1581fb4569f4.tar.bz2 |
hwc: rgz: Fix invalid dirty region state when HDMI is connected
It is possible when the HDMI cable is plugged in a geometry change
doesn't happen, hence the layers handled by the DSS and the
regionizer differ, since the dirty region counters are only reset
when a geometry change happens, this causes them to enter into
an invalid state leading to visual artifacts.
This fix compares if at any given time, the layers handled in the
regionizer differ in number from the previous frame, if that happens,
the dirty region counters are reset for all the layers.
Change-Id: If756b526cf52d66612729d7367c26d131c8a1ac0
Signed-off-by: Gustavo Diaz Prado <a0273371@ti.com>
Diffstat (limited to 'hwc')
-rw-r--r-- | hwc/rgz_2d.c | 53 |
1 files changed, 32 insertions, 21 deletions
diff --git a/hwc/rgz_2d.c b/hwc/rgz_2d.c index 63dfaf1..33f04b2 100644 --- a/hwc/rgz_2d.c +++ b/hwc/rgz_2d.c @@ -600,6 +600,32 @@ static int rgz_in_valid_hwc_layer(hwc_layer_t *layer) return 1; } +static void rgz_handle_dirty_region(rgz_t *rgz, int reset_counters) +{ + unsigned int i; + for (i = 0; i < rgz->rgz_layerno; i++) { + rgz_layer_t *rgz_layer = &rgz->rgz_layers[i]; + void *new_handle; + + /* + * We don't care about the handle for background and layers with the + * clear fb hint, but we want to maintain a layer state for dirty + * region handling. + */ + if (i == 0 || rgz_layer->buffidx == -1) + new_handle = (void*)0x1; + else + new_handle = (void*)rgz_layer->hwc_layer->handle; + + if (reset_counters || new_handle != rgz_layer->dirty_hndl) { + rgz_layer->dirty_count = RGZ_NUM_FB; + rgz_layer->dirty_hndl = new_handle; + } else + rgz_layer->dirty_count -= rgz_layer->dirty_count ? 1 : 0; + + } +} + static int rgz_in_hwccheck(rgz_in_params_t *p, rgz_t *rgz) { hwc_layer_t *layers = p->data.hwc.layers; @@ -631,11 +657,6 @@ static int rgz_in_hwccheck(rgz_in_params_t *p, rgz_t *rgz) */ rgz_layer_t *rgz_layer = &rgz->rgz_layers[0]; rgz_layer->hwc_layer = &bg_layer; - if (!rgz_layer->dirty_hndl) { - rgz_layer->dirty_hndl = (void*)0x1; - rgz_layer->dirty_count = RGZ_NUM_FB; - } else - rgz_layer->dirty_count -= rgz_layer->dirty_count ? 1 : 0; for (l = 0; l < layerno; l++) { if (layers[l].compositionType == HWC_FRAMEBUFFER) { @@ -645,12 +666,6 @@ static int rgz_in_hwccheck(rgz_in_params_t *p, rgz_t *rgz) rgz_layer_t *rgz_layer = &rgz->rgz_layers[possible_blit+1]; rgz_layer->hwc_layer = &layers[l]; rgz_layer->buffidx = memidx++; - if (rgz_layer->hwc_layer->handle != rgz_layer->dirty_hndl) { - rgz_layer->dirty_count = RGZ_NUM_FB; - rgz_layer->dirty_hndl = (void*)rgz_layer->hwc_layer->handle; - } else - rgz_layer->dirty_count -= rgz_layer->dirty_count ? 1 : 0; - possible_blit++; } continue; @@ -666,15 +681,6 @@ static int rgz_in_hwccheck(rgz_in_params_t *p, rgz_t *rgz) rgz_layer_t *rgz_layer = &rgz->rgz_layers[possible_blit+1]; rgz_layer->buffidx = -1; rgz_layer->hwc_layer = &layers[l]; - /* - * We don't care about the handle but we want to maintain a layer state for - * dirty region handling - */ - if (!rgz_layer->dirty_hndl) { - rgz_layer->dirty_hndl = (void*)0x1; - rgz_layer->dirty_count = RGZ_NUM_FB; - } else - rgz_layer->dirty_count -= rgz_layer->dirty_count ? 1 : 0; possible_blit++; } } @@ -684,8 +690,13 @@ static int rgz_in_hwccheck(rgz_in_params_t *p, rgz_t *rgz) return -1; } + unsigned int blit_layers = possible_blit + 1; /* Account for background layer */ + int reset_dirty_counters = rgz->rgz_layerno != blit_layers ? 1 : 0; + rgz->state |= RGZ_STATE_INIT; - rgz->rgz_layerno = possible_blit + 1; /* Account for background layer */ + rgz->rgz_layerno = blit_layers; + + rgz_handle_dirty_region(rgz, reset_dirty_counters); return RGZ_ALL; } |