summaryrefslogtreecommitdiffstats
path: root/hwc
diff options
context:
space:
mode:
authorGustavo Diaz Prado <a0273371@ti.com>2012-08-03 14:56:33 -0500
committerDaniel Levin <dendy@ti.com>2012-11-28 21:16:24 +0200
commita5f87d7c75ca4b2b6da8082d513f1581fb4569f4 (patch)
tree0ccb1524732ee67ae0610507a29fcd9f11170c35 /hwc
parent9e02bb877675934edd3803cf6cbeb597e965b716 (diff)
downloadhardware_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.c53
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;
}