summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--hwc/rgz_2d.c66
1 files changed, 59 insertions, 7 deletions
diff --git a/hwc/rgz_2d.c b/hwc/rgz_2d.c
index 7bdaaf1..3814118 100644
--- a/hwc/rgz_2d.c
+++ b/hwc/rgz_2d.c
@@ -346,14 +346,30 @@ static int rgz_out_bvcmd_paint(rgz_t *rgz, rgz_out_params_t *params)
rgz_blts_init(&blts);
rgz_out_clrdst(params, NULL);
- unsigned int i;
+ unsigned int i, j;
/* Begin from index 1 to remove the background layer from the output */
- for (i = 1; i < rgz->rgz_layerno; i++) {
- hwc_layer_t *l = rgz->rgz_layers[i].hwc_layer;
+ for (i = 1, j = 0; i < rgz->rgz_layerno; i++) {
+ rgz_layer_t *rgz_layer = &rgz->rgz_layers[i];
+ hwc_layer_t *l = rgz_layer->hwc_layer;
//OUTP("blitting meminfo %d", rgz->rgz_layers[i].buffidx);
+ /*
+ * See if it is needed to put transparent pixels where this layer
+ * is located in the screen
+ */
+ if (rgz_layer->buffidx == -1) {
+ struct bvsurfgeom *scrgeom = params->data.bvc.dstgeom;
+ blit_rect_t srcregion;
+ srcregion.left = max(0, l->displayFrame.left);
+ srcregion.top = max(0, l->displayFrame.top);
+ srcregion.bottom = min(scrgeom->height, l->displayFrame.bottom);
+ srcregion.right = min(scrgeom->width, l->displayFrame.right);
+ rgz_out_clrdst(params, &srcregion);
+ continue;
+ }
+
rv = rgz_hwc_layer_blit(l, params, rgz->rgz_layers[i].buffidx);
if (rv) {
OUTE("bvcmd_paint: error in layer %d: %d", i, rv);
@@ -361,7 +377,7 @@ static int rgz_out_bvcmd_paint(rgz_t *rgz, rgz_out_params_t *params)
rgz_blts_free(&blts);
return rv;
}
- params->data.bvc.out_hndls[i-1] = l->handle;
+ params->data.bvc.out_hndls[j++] = l->handle;
params->data.bvc.out_nhndls++;
}
@@ -608,6 +624,23 @@ static int rgz_in_hwccheck(rgz_in_params_t *p, rgz_t *rgz)
}
possible_blit++;
}
+ continue;
+ }
+
+ if (layers[l].hints & HWC_HINT_CLEAR_FB) {
+ candidates++;
+ if (possible_blit < RGZ_INPUT_MAXLAYERS) {
+ /*
+ * Use only the layer rectangle as an input to regionize when the clear
+ * fb hint is present, mark this layer to identify it.
+ */
+ rgz_layer_t *rgz_layer = &rgz->rgz_layers[possible_blit+1];
+ rgz_layer->buffidx = -1;
+ rgz_layer->dirty_count = 0;
+ rgz_layer->dirty_hndl = NULL;
+ rgz_layer->hwc_layer = &layers[l];
+ possible_blit++;
+ }
}
}
@@ -1189,6 +1222,20 @@ static int rgz_hwc_subregion_blit(blit_hregion_t *hregion, int sidx, rgz_out_par
}
}
+ /*
+ * See if the depth most layer needs to be ignored. If this layer is the
+ * only operation, we need to clear this subregion.
+ */
+ if (hregion->rgz_layers[lix]->buffidx == -1) {
+ ldepth--;
+ if (!ldepth) {
+ if (screen_isdirty)
+ rgz_out_clrdst(params, &hregion->blitrects[lix][sidx]);
+ return 0;
+ }
+ lix = get_layer_ops_next(hregion, sidx, lix);
+ }
+
/* Determine if this region is dirty */
int dirty = 0, dirtylix = lix;
while (dirtylix != -1) {
@@ -1367,9 +1414,13 @@ static int rgz_out_region(rgz_t *rgz, rgz_out_params_t *params)
unsigned int j;
params->data.bvc.out_nhndls = 0;
/* Begin from index 1 to remove the background layer from the output */
- for (j = 1; j < rgz->rgz_layerno; j++) {
- hwc_layer_t *layer = rgz->rgz_layers[j].hwc_layer;
- params->data.bvc.out_hndls[j-1] = layer->handle;
+ for (j = 1, i = 0; j < rgz->rgz_layerno; j++) {
+ rgz_layer_t *rgz_layer = &rgz->rgz_layers[j];
+ /* We don't need the handles for layers marked as -1 */
+ if (rgz_layer->buffidx == -1)
+ continue;
+ hwc_layer_t *layer = rgz_layer->hwc_layer;
+ params->data.bvc.out_hndls[i++] = layer->handle;
params->data.bvc.out_nhndls++;
}
@@ -1469,6 +1520,7 @@ int rgz_get_screengeometry(int fd, struct bvsurfgeom *geom, int fmt)
return -EINVAL;
}
+ bzero(&bg_layer, sizeof(bg_layer));
bg_layer.displayFrame.left = bg_layer.displayFrame.top = 0;
bg_layer.displayFrame.right = fb_varinfo.xres;
bg_layer.displayFrame.bottom = fb_varinfo.yres;