summaryrefslogtreecommitdiffstats
path: root/hwc
diff options
context:
space:
mode:
Diffstat (limited to 'hwc')
-rw-r--r--hwc/rgz_2d.c533
1 files changed, 206 insertions, 327 deletions
diff --git a/hwc/rgz_2d.c b/hwc/rgz_2d.c
index 9da80e5..bcd66a3 100644
--- a/hwc/rgz_2d.c
+++ b/hwc/rgz_2d.c
@@ -95,12 +95,15 @@ struct rgz_blts {
};
-static int rgz_hwc_layer_blit(hwc_layer_t *l, rgz_out_params_t *params, int buff_idx);
+static int rgz_hwc_layer_blit(rgz_out_params_t *params, rgz_layer_t *rgz_layer);
static void rgz_blts_init(struct rgz_blts *blts);
static void rgz_blts_free(struct rgz_blts *blts);
static struct rgz_blt_entry* rgz_blts_get(struct rgz_blts *blts, rgz_out_params_t *params);
static int rgz_blts_bvdirect(rgz_t* rgz, struct rgz_blts *blts, rgz_out_params_t *params);
static void rgz_get_src_rect(hwc_layer_t* layer, blit_rect_t *subregion_rect, blit_rect_t *res_rect);
+static int hal_to_ocd(int color);
+static int rgz_get_orientation(unsigned int transform);
+static int rgz_get_flip_flags(unsigned int transform, int use_src2_flags);
int debug = 0;
struct rgz_blts blts;
@@ -273,9 +276,7 @@ static int rgz_out_bvdirect_paint(rgz_t *rgz, rgz_out_params_t *params)
/* 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;
-
- rv = rgz_hwc_layer_blit(l, params, -1);
+ rv = rgz_hwc_layer_blit(params, &rgz->rgz_layers[i]);
if (rv) {
OUTE("bvdirect_paint: error in layer %d: %d", i, rv);
dump_all(rgz->rgz_layers, rgz->rgz_layerno, i);
@@ -293,56 +294,197 @@ static void rgz_set_async(struct rgz_blt_entry *e, int async)
e->bp.flags = async ? e->bp.flags | BVFLAG_ASYNC : e->bp.flags & ~BVFLAG_ASYNC;
}
+static void rgz_get_screen_info(rgz_out_params_t *params, struct bvsurfgeom **screen_geom)
+{
+ *screen_geom = params->data.bvc.dstgeom;
+}
+
+static int rgz_is_blending_disabled(rgz_out_params_t *params)
+{
+ return params->data.bvc.noblend;
+}
+
+static void rgz_set_dst_data(rgz_out_params_t *params, blit_rect_t *subregion_rect,
+ struct rgz_blt_entry* e)
+{
+ struct bvsurfgeom *screen_geom;
+ rgz_get_screen_info(params, &screen_geom);
+
+ /* omaplfb is in charge of assigning the correct dstdesc in the kernel */
+ e->dstgeom.structsize = sizeof(struct bvsurfgeom);
+ e->dstgeom.format = screen_geom->format;
+ e->dstgeom.width = screen_geom->width;
+ e->dstgeom.height = screen_geom->height;
+ e->dstgeom.orientation = screen_geom->orientation;
+ e->dstgeom.virtstride = DSTSTRIDE(screen_geom);
+
+ e->bp.dstrect.left = subregion_rect->left;
+ e->bp.dstrect.top = subregion_rect->top;
+ e->bp.dstrect.width = WIDTH(*subregion_rect);
+ e->bp.dstrect.height = HEIGHT(*subregion_rect);
+}
+
+static void rgz_set_src_data(rgz_out_params_t *params, rgz_layer_t *rgz_layer,
+ blit_rect_t *subregion_rect, struct rgz_blt_entry* e, int is_src2)
+{
+ hwc_layer_t *hwc_layer = rgz_layer->hwc_layer;
+ struct bvbuffdesc *srcdesc = is_src2 ? &e->src2desc : &e->src1desc;
+ struct bvsurfgeom *srcgeom = is_src2 ? &e->src2geom : &e->src1geom;
+ struct bvrect *srcrect = is_src2 ? &e->bp.src2rect : &e->bp.src1rect;
+ IMG_native_handle_t *handle = (IMG_native_handle_t *)hwc_layer->handle;
+
+ srcdesc->structsize = sizeof(struct bvbuffdesc);
+ srcdesc->length = handle->iHeight * HANDLE_TO_STRIDE(handle);
+ srcdesc->auxptr = (void*)rgz_layer->buffidx;
+ srcgeom->structsize = sizeof(struct bvsurfgeom);
+ srcgeom->format = hal_to_ocd(handle->iFormat);
+ srcgeom->width = handle->iWidth;
+ srcgeom->height = handle->iHeight;
+ srcgeom->orientation = rgz_get_orientation(hwc_layer->transform);
+ srcgeom->virtstride = HANDLE_TO_STRIDE(handle);
+ if (hwc_layer->transform & HAL_TRANSFORM_ROT_90)
+ swap(srcgeom->width, srcgeom->height);
+
+ /* Find out what portion of the src we want to use for the blit */
+ blit_rect_t res_rect;
+ rgz_get_src_rect(hwc_layer, subregion_rect, &res_rect);
+ srcrect->left = res_rect.left;
+ srcrect->top = res_rect.top;
+ srcrect->width = WIDTH(res_rect);
+ srcrect->height = HEIGHT(res_rect);
+}
+
+/*
+ * Set the clipping rectangle, if part of the subregion rectangle is outside
+ * the boundaries of the destination, remove only the out-of-bounds area
+ */
+static void rgz_set_clip_rect(rgz_out_params_t *params, blit_rect_t *subregion_rect,
+ struct rgz_blt_entry* e)
+{
+ struct bvsurfgeom *screen_geom;
+ rgz_get_screen_info(params, &screen_geom);
+
+ blit_rect_t clip_rect;
+ clip_rect.left = max(0, subregion_rect->left);
+ clip_rect.top = max(0, subregion_rect->top);
+ clip_rect.bottom = min(screen_geom->height, subregion_rect->bottom);
+ clip_rect.right = min(screen_geom->width, subregion_rect->right);
+
+ e->bp.cliprect.left = clip_rect.left;
+ e->bp.cliprect.top = clip_rect.top;
+ e->bp.cliprect.width = WIDTH(clip_rect);
+ e->bp.cliprect.height = HEIGHT(clip_rect);
+}
+
+/*
+ * Configures blit entry to set src2 is the same as the destination
+ */
+static void rgz_set_src2_is_dst(rgz_out_params_t *params, struct rgz_blt_entry* e)
+{
+ /* omaplfb is in charge of assigning the correct src2desc in the kernel */
+ e->src2geom = e->dstgeom;
+ e->src2desc.structsize = sizeof(struct bvbuffdesc);
+ e->src2desc.auxptr = (void*)HWC_BLT_DESC_FB_FN(0);
+ e->bp.src2rect = e->bp.dstrect;
+}
+
+/*
+ * Copies src1 into the framebuffer
+ */
+static struct rgz_blt_entry* rgz_hwc_subregion_copy(rgz_out_params_t *params,
+ blit_rect_t *subregion_rect, rgz_layer_t *rgz_src1)
+{
+ struct rgz_blt_entry* e = rgz_blts_get(&blts, params);
+ hwc_layer_t *hwc_src1 = rgz_src1->hwc_layer;
+ e->bp.structsize = sizeof(struct bvbltparams);
+ e->bp.op.rop = 0xCCCC; /* SRCCOPY */
+ e->bp.flags = BVFLAG_CLIP | BVFLAG_ROP;
+ e->bp.flags |= rgz_get_flip_flags(hwc_src1->transform, 0);
+ rgz_set_async(e, 1);
+
+ rgz_set_src_data(params, rgz_src1, subregion_rect, e, 0);
+ rgz_set_dst_data(params, subregion_rect, e);
+ rgz_set_clip_rect(params, subregion_rect, e);
+
+ if((e->src1geom.format == OCDFMT_BGR124) ||
+ (e->src1geom.format == OCDFMT_RGB124) ||
+ (e->src1geom.format == OCDFMT_RGB16))
+ e->dstgeom.format = OCDFMT_BGR124;
+
+ return e;
+}
+
+/*
+ * Blends two layers and write the result in the framebuffer, src1 must be the
+ * top most layer while src2 is the one behind. If src2 is NULL means src1 will
+ * be blended with the current content of the framebuffer.
+ */
+static struct rgz_blt_entry* rgz_hwc_subregion_blend(rgz_out_params_t *params,
+ blit_rect_t *subregion_rect, rgz_layer_t *rgz_src1, rgz_layer_t *rgz_src2)
+{
+ struct rgz_blt_entry* e = rgz_blts_get(&blts, params);
+ hwc_layer_t *hwc_src1 = rgz_src1->hwc_layer;
+ e->bp.structsize = sizeof(struct bvbltparams);
+ e->bp.op.blend = BVBLEND_SRC1OVER;
+ e->bp.flags = BVFLAG_CLIP | BVFLAG_BLEND;
+ e->bp.flags |= rgz_get_flip_flags(hwc_src1->transform, 0);
+ rgz_set_async(e, 1);
+
+ rgz_set_src_data(params, rgz_src1, subregion_rect, e, 0);
+ rgz_set_dst_data(params, subregion_rect, e);
+ rgz_set_clip_rect(params, subregion_rect, e);
+
+ if (rgz_src2) {
+ hwc_layer_t *hwc_src2 = rgz_src2->hwc_layer;
+ e->bp.flags |= rgz_get_flip_flags(hwc_src2->transform, 1);
+ rgz_set_src_data(params, rgz_src2, subregion_rect, e, 1);
+ } else
+ rgz_set_src2_is_dst(params, e);
+
+ return e;
+}
+
/*
* Clear the destination buffer, if rect is NULL means the whole screen, rect
* cannot be outside the boundaries of the screen
*/
static void rgz_out_clrdst(rgz_out_params_t *params, blit_rect_t *rect)
{
- struct bvsurfgeom *scrgeom = params->data.bvc.dstgeom;
+ struct rgz_blt_entry* e = rgz_blts_get(&blts, params);
+ e->bp.structsize = sizeof(struct bvbltparams);
+ e->bp.op.rop = 0xCCCC; /* SRCCOPY */
+ e->bp.flags = BVFLAG_CLIP | BVFLAG_ROP;
+ rgz_set_async(e, 1);
- struct rgz_blt_entry* e;
- e = rgz_blts_get(&blts, params);
+ struct bvsurfgeom *screen_geom;
+ rgz_get_screen_info(params, &screen_geom);
- struct bvbuffdesc *src1desc = &e->src1desc;
- src1desc->structsize = sizeof(struct bvbuffdesc);
- src1desc->length = 4;
+ e->src1desc.structsize = sizeof(struct bvbuffdesc);
+ e->src1desc.length = 4; /* 1 pixel, 32bpp */
/*
* With the HWC we don't bother having a buffer for the fill we'll get the
- * OMAPLFB to fixup the src1desc if this address is -1
+ * OMAPLFB to fixup the src1desc and stride if the auxiliary pointer is -1
*/
- src1desc->auxptr = (void*)-1;
- struct bvsurfgeom *src1geom = &e->src1geom;
- src1geom->structsize = sizeof(struct bvsurfgeom);
- src1geom->format = OCDFMT_RGBA24;
- src1geom->width = src1geom->height = 1;
- src1geom->orientation = 0;
- src1geom->virtstride = 1;
-
- struct bvsurfgeom *dstgeom = &e->dstgeom;
- dstgeom->structsize = sizeof(struct bvsurfgeom);
- dstgeom->format = scrgeom->format;
- dstgeom->width = scrgeom->width;
- dstgeom->height = scrgeom->height;
- dstgeom->orientation = 0; /* TODO */
- dstgeom->virtstride = DSTSTRIDE(scrgeom);
-
- struct bvbltparams *bp = &e->bp;
- bp->structsize = sizeof(struct bvbltparams);
- bp->dstgeom = dstgeom;
- bp->src1.desc = src1desc;
- bp->src1geom = src1geom;
- bp->src1rect.left = 0;
- bp->src1rect.top = 0;
- bp->src1rect.width = bp->src1rect.height = 1;
- bp->cliprect.left = bp->dstrect.left = rect ? rect->left : 0;
- bp->cliprect.top = bp->dstrect.top = rect ? rect->top : 0;
- bp->cliprect.width = bp->dstrect.width = rect ? (unsigned int) WIDTH(*rect) : scrgeom->width;
- bp->cliprect.height = bp->dstrect.height = rect ? (unsigned int) HEIGHT(*rect) : scrgeom->height;
-
- bp->flags = BVFLAG_CLIP | BVFLAG_ROP;
- bp->op.rop = 0xCCCC; /* SRCCOPY */
- rgz_set_async(e, 1);
+ e->src1desc.auxptr = (void*)-1;
+ e->src1geom.structsize = sizeof(struct bvsurfgeom);
+ e->src1geom.format = OCDFMT_RGBA24;
+ e->bp.src1rect.left = e->bp.src1rect.top = e->src1geom.orientation = 0;
+ e->src1geom.height = e->src1geom.width = e->bp.src1rect.height = e->bp.src1rect.width = 1;
+
+ blit_rect_t clear_rect;
+ if (rect) {
+ clear_rect.left = rect->left;
+ clear_rect.top = rect->top;
+ clear_rect.right = rect->right;
+ clear_rect.bottom = rect->bottom;
+ } else {
+ clear_rect.left = clear_rect.top = 0;
+ clear_rect.right = screen_geom->width;
+ clear_rect.bottom = screen_geom->height;
+ }
+
+ rgz_set_dst_data(params, &clear_rect, e);
+ rgz_set_clip_rect(params, &clear_rect, e);
}
static int rgz_out_bvcmd_paint(rgz_t *rgz, rgz_out_params_t *params)
@@ -377,7 +519,7 @@ static int rgz_out_bvcmd_paint(rgz_t *rgz, rgz_out_params_t *params)
continue;
}
- rv = rgz_hwc_layer_blit(l, params, rgz->rgz_layers[i].buffidx);
+ rv = rgz_hwc_layer_blit(params, rgz_layer);
if (rv) {
OUTE("bvcmd_paint: error in layer %d: %d", i, rv);
dump_all(rgz->rgz_layers, rgz->rgz_layerno, i);
@@ -1012,119 +1154,24 @@ static int rgz_get_flip_flags(unsigned int transform, int use_src2_flags)
return flip_flags;
}
-static int rgz_hwc_layer_blit(hwc_layer_t *l, rgz_out_params_t *params, int buff_idx)
+static int rgz_hwc_layer_blit(rgz_out_params_t *params, rgz_layer_t *rgz_layer)
{
- IMG_native_handle_t *handle = (IMG_native_handle_t *)l->handle;
- if (!handle || l->flags & HWC_SKIP_LAYER) {
- /*
- * This shouldn't happen regionizer should reject compositions w/ skip
- * layers
- */
- OUTP("Cannot handle skip layers\n");
- return -1;
- }
static int loaded = 0;
if (!loaded)
loaded = loadbltsville() ? : 1; /* attempt load once */
- struct bvbuffdesc *scrdesc;
- struct bvsurfgeom *scrgeom;
- int noblend;
-
- if (IS_BVCMD(params)) {
- scrdesc = NULL;
- scrgeom = params->data.bvc.dstgeom;
- noblend = params->data.bvc.noblend;
- } else {
- scrdesc = params->data.bv.dstdesc;
- scrgeom = params->data.bv.dstgeom;
- noblend = params->data.bv.noblend;
- }
-
- struct rgz_blt_entry* e;
- e = rgz_blts_get(&blts, params);
-
- struct bvbuffdesc *src1desc = &e->src1desc;
- src1desc->structsize = sizeof(struct bvbuffdesc);
- src1desc->length = handle->iHeight * HANDLE_TO_STRIDE(handle);
- /*
- * The virtaddr isn't going to be used in the final 2D h/w integration
- * because we will be handling buffers differently
- */
- src1desc->auxptr = buff_idx == -1 ? HANDLE_TO_BUFFER(handle) : (void*)buff_idx; /* FIXME: revisit this later */
-
- struct bvsurfgeom *src1geom = &e->src1geom;
- src1geom->structsize = sizeof(struct bvsurfgeom);
- src1geom->format = hal_to_ocd(handle->iFormat);
- src1geom->width = handle->iWidth;
- src1geom->height = handle->iHeight;
- if (l->transform & HAL_TRANSFORM_ROT_90)
- swap(src1geom->width, src1geom->height);
- src1geom->orientation = rgz_get_orientation(l->transform);
- src1geom->virtstride = HANDLE_TO_STRIDE(handle);
-
- struct bvsurfgeom *dstgeom = &e->dstgeom;
- dstgeom->structsize = sizeof(struct bvsurfgeom);
- dstgeom->format = scrgeom->format;
- dstgeom->width = scrgeom->width;
- dstgeom->height = scrgeom->height;
- /* Destination always set to 0, src buffers will contain rotation values as needed */
- dstgeom->orientation = 0;
- dstgeom->virtstride = DSTSTRIDE(scrgeom);
-
- struct bvbltparams *bp = &e->bp;
- bp->structsize = sizeof(struct bvbltparams);
- bp->dstdesc = scrdesc;
- bp->dstgeom = dstgeom;
- bp->dstrect.left = l->displayFrame.left;
- bp->dstrect.top = l->displayFrame.top;
- bp->dstrect.width = WIDTH(l->displayFrame);
- bp->dstrect.height = HEIGHT(l->displayFrame);
- bp->src1.desc = src1desc;
- bp->src1geom = src1geom;
- bp->cliprect.left = bp->cliprect.top = 0;
- bp->cliprect.width = scrgeom->width;
- bp->cliprect.height = scrgeom->height;
-
- blit_rect_t src1rect;
- blit_rect_t src1region;
- src1region.left = l->displayFrame.left;
- src1region.top = l->displayFrame.top;
- src1region.bottom = l->displayFrame.bottom;
- src1region.right = l->displayFrame.right;
- rgz_get_src_rect(l, &src1region, &src1rect);
- bp->src1rect.left = src1rect.left;
- bp->src1rect.top = src1rect.top;
- bp->src1rect.width = WIDTH(src1rect);
- bp->src1rect.height = HEIGHT(src1rect);
-
- unsigned long bpflags = BVFLAG_CLIP;
- if (!noblend && l->blending == HWC_BLENDING_PREMULT) {
- struct bvsurfgeom *src2geom = &e->src2geom;
- struct bvbuffdesc *src2desc = &e->src2desc;
- *src2geom = *dstgeom;
- src2desc->structsize = sizeof(struct bvbuffdesc);
- src2desc->auxptr = (void*)HWC_BLT_DESC_FB_FN(0);
- bpflags |= BVFLAG_BLEND;
- bp->op.blend = BVBLEND_SRC1OVER;
- bp->src2.desc = scrdesc;
- bp->src2geom = dstgeom;
- bp->src2rect.left = l->displayFrame.left;
- bp->src2rect.top = l->displayFrame.top;
- bp->src2rect.width = WIDTH(l->displayFrame);
- bp->src2rect.height = HEIGHT(l->displayFrame);
- } else {
- bpflags |= BVFLAG_ROP;
- bp->op.rop = 0xCCCC; /* SRCCOPY */
- if((src1geom->format == OCDFMT_BGR124) ||
- (src1geom->format == OCDFMT_RGB124) ||
- (src1geom->format == OCDFMT_RGB16))
- dstgeom->format = OCDFMT_BGR124;
- }
+ hwc_layer_t* layer = rgz_layer->hwc_layer;
+ blit_rect_t srcregion;
+ srcregion.left = layer->displayFrame.left;
+ srcregion.top = layer->displayFrame.top;
+ srcregion.bottom = layer->displayFrame.bottom;
+ srcregion.right = layer->displayFrame.right;
- bpflags |= rgz_get_flip_flags(l->transform, 0);
- bp->flags = bpflags;
- rgz_set_async(e, 1);
+ int noblend = rgz_is_blending_disabled(params);
+ if (!noblend && layer->blending == HWC_BLENDING_PREMULT)
+ rgz_hwc_subregion_blend(params, &srcregion, rgz_layer, NULL);
+ else
+ rgz_hwc_subregion_copy(params, &srcregion, rgz_layer);
return 0;
}
@@ -1133,14 +1180,9 @@ static int rgz_hwc_layer_blit(hwc_layer_t *l, rgz_out_params_t *params, int buff
* Calculate the src rectangle on the basis of the layer display, source crop
* and subregion rectangles. Additionally any rotation will be taken in
* account. The resulting rectangle is written in res_rect.
- * Note: This doesn't work if the layer is scaled, another approach must be
- * taken in this situation.
*/
static void rgz_get_src_rect(hwc_layer_t* layer, blit_rect_t *subregion_rect, blit_rect_t *res_rect)
{
- if (rgz_hwc_scaled(layer))
- ALOGE("%s: layer %p is scaled", __func__, layer);
-
IMG_native_handle_t *handle = (IMG_native_handle_t *)layer->handle;
int res_left = 0;
int res_top = 0;
@@ -1178,132 +1220,6 @@ static void rgz_get_src_rect(hwc_layer_t* layer, blit_rect_t *subregion_rect, bl
res_rect->bottom = res_top + HEIGHT(*subregion_rect);
}
-
-/*
- * Setup the src2 rectangle and the passed descriptor and
- * geometry
- */
-static void rgz_src2blend_prep2(
- struct rgz_blt_entry* e, unsigned int hwc_transform, blit_rect_t *rect,
- struct bvbuffdesc *dstdesc, struct bvsurfgeom *dstgeom, int is_fb_dest)
-{
- unsigned long bpflags = BVFLAG_CLIP;
-
- struct bvbltparams *bp = &e->bp;
- bpflags |= BVFLAG_BLEND;
- bp->op.blend = BVBLEND_SRC1OVER;
- bp->src2.desc = dstdesc;
- bp->src2geom = dstgeom;
-
- if (is_fb_dest) {
- struct bvsurfgeom *src2geom = &e->src2geom;
- struct bvbuffdesc *src2desc = &e->src2desc;
- *src2geom = *dstgeom;
- src2desc->structsize = sizeof(struct bvbuffdesc);
- src2desc->auxptr = (void*)HWC_BLT_DESC_FB_FN(0);
- /* Destination always set to 0, src buffers will contain rotation values as needed */
- src2geom->orientation = 0;
- bp->src2rect.left = rect->left;
- bp->src2rect.top = rect->top;
- bp->src2rect.width = WIDTH(*rect);
- bp->src2rect.height = HEIGHT(*rect);
- } else {
- struct bvsurfgeom *src2geom = &e->src2geom;
- src2geom->orientation = rgz_get_orientation(hwc_transform);
- bpflags |= rgz_get_flip_flags(hwc_transform, 1);
- }
-
- bp->flags |= bpflags;
-}
-
-static void rgz_src2blend_prep(
- struct rgz_blt_entry* e, rgz_layer_t *rgz_layer, blit_rect_t *rect, rgz_out_params_t *params)
-{
- hwc_layer_t *l = rgz_layer->hwc_layer;
- IMG_native_handle_t *handle = (IMG_native_handle_t *)l->handle;
-
- struct bvbuffdesc *src2desc = &e->src2desc;
- src2desc->structsize = sizeof(struct bvbuffdesc);
- src2desc->length = handle->iHeight * HANDLE_TO_STRIDE(handle);
- src2desc->auxptr = IS_BVCMD(params)?
- (void*)rgz_layer->buffidx : HANDLE_TO_BUFFER(handle);
-
- struct bvsurfgeom *src2geom = &e->src2geom;
- src2geom->structsize = sizeof(struct bvsurfgeom);
- src2geom->format = hal_to_ocd(handle->iFormat);
- src2geom->width = handle->iWidth;
- src2geom->height = handle->iHeight;
- src2geom->virtstride = HANDLE_TO_STRIDE(handle);
- if (l->transform & HAL_TRANSFORM_ROT_90)
- swap(src2geom->width, src2geom->height);
-
- struct bvbltparams *bp = &e->bp;
- blit_rect_t src2rect;
- rgz_get_src_rect(l, rect, &src2rect);
- bp->src2rect.left = src2rect.left;
- bp->src2rect.top = src2rect.top;
- bp->src2rect.width = WIDTH(src2rect);
- bp->src2rect.height = HEIGHT(src2rect);
-
- rgz_src2blend_prep2(e, l->transform, rect, src2desc, src2geom, 0);
-}
-
-static void rgz_src1_prep(
- struct rgz_blt_entry* e, rgz_layer_t *rgz_layer,
- blit_rect_t *rect,
- struct bvbuffdesc *scrdesc, struct bvsurfgeom *scrgeom, rgz_out_params_t *params)
-{
- hwc_layer_t *l = rgz_layer->hwc_layer;
- if (!l)
- return;
-
- IMG_native_handle_t *handle = (IMG_native_handle_t *)l->handle;
-
- struct bvbuffdesc *src1desc = &e->src1desc;
- src1desc->structsize = sizeof(struct bvbuffdesc);
- src1desc->length = handle->iHeight * HANDLE_TO_STRIDE(handle);
- src1desc->auxptr = IS_BVCMD(params) ?
- (void*)rgz_layer->buffidx : HANDLE_TO_BUFFER(handle);
-
- struct bvsurfgeom *src1geom = &e->src1geom;
- src1geom->structsize = sizeof(struct bvsurfgeom);
- src1geom->format = hal_to_ocd(handle->iFormat);
- src1geom->width = handle->iWidth;
- src1geom->height = handle->iHeight;
- src1geom->orientation = rgz_get_orientation(l->transform);
- src1geom->virtstride = HANDLE_TO_STRIDE(handle);
- if (l->transform & HAL_TRANSFORM_ROT_90)
- swap(src1geom->width, src1geom->height);
-
- struct bvsurfgeom *dstgeom = &e->dstgeom;
- dstgeom->structsize = sizeof(struct bvsurfgeom);
- dstgeom->format = scrgeom->format;
- dstgeom->width = scrgeom->width;
- dstgeom->height = scrgeom->height;
- /* Destination always set to 0, src buffers will contain rotation values as needed */
- dstgeom->orientation = 0;
- dstgeom->virtstride = DSTSTRIDE(scrgeom);
-
- struct bvbltparams *bp = &e->bp;
- bp->structsize = sizeof(struct bvbltparams);
- bp->dstdesc = scrdesc;
- bp->dstgeom = dstgeom;
- bp->cliprect.left = bp->dstrect.left = rect->left;
- bp->cliprect.top = bp->dstrect.top = rect->top;
- bp->cliprect.width = bp->dstrect.width = WIDTH(*rect);
- bp->cliprect.height = bp->dstrect.height = HEIGHT(*rect);
- bp->src1.desc = src1desc;
- bp->src1geom = src1geom;
-
- blit_rect_t src1rect;
- rgz_get_src_rect(l, rect, &src1rect);
- bp->src1rect.left = src1rect.left;
- bp->src1rect.top = src1rect.top;
- bp->src1rect.width = WIDTH(src1rect);
- bp->src1rect.height = HEIGHT(src1rect);
- bp->flags |= rgz_get_flip_flags(l->transform, 0);
-}
-
static void rgz_batch_entry(struct rgz_blt_entry* e, unsigned int flag, unsigned int set)
{
e->bp.flags &= ~BVFLAG_BATCH_MASK;
@@ -1317,20 +1233,6 @@ static int rgz_hwc_subregion_blit(blit_hregion_t *hregion, int sidx, rgz_out_par
if (!loaded)
loaded = loadbltsville() ? : 1; /* attempt load once */
- struct bvbuffdesc *scrdesc;
- struct bvsurfgeom *scrgeom;
- int noblend;
-
- if (IS_BVCMD(params)) {
- scrdesc = NULL;
- scrgeom = params->data.bvc.dstgeom;
- noblend = params->data.bvc.noblend;
- } else {
- scrdesc = params->data.bv.dstdesc;
- scrgeom = params->data.bv.dstgeom;
- noblend = params->data.bv.noblend;
- }
-
int lix;
int ldepth = get_layer_ops(hregion, sidx, &lix);
if (ldepth == 0) {
@@ -1384,9 +1286,11 @@ static int rgz_hwc_subregion_blit(blit_hregion_t *hregion, int sidx, rgz_out_par
lix = get_layer_ops_next(hregion, sidx, lix);
}
+ int noblend = rgz_is_blending_disabled(params);
+
if (!noblend && ldepth > 1) { /* BLEND */
blit_rect_t *rect = &hregion->blitrects[lix][sidx];
- struct rgz_blt_entry* e = rgz_blts_get(&blts, params);
+ struct rgz_blt_entry* e;
int s2lix = lix;
lix = get_layer_ops_next(hregion, sidx, lix);
@@ -1395,31 +1299,21 @@ static int rgz_hwc_subregion_blit(blit_hregion_t *hregion, int sidx, rgz_out_par
* We save a read and a write from the FB if we blend the bottom
* two layers
*/
- rgz_src1_prep(e, hregion->rgz_layers[lix], rect, scrdesc, scrgeom, params);
- rgz_src2blend_prep(e, hregion->rgz_layers[s2lix], rect, params);
+ e = rgz_hwc_subregion_blend(params, rect, hregion->rgz_layers[lix],
+ hregion->rgz_layers[s2lix]);
rgz_batch_entry(e, BVFLAG_BATCH_BEGIN, 0);
- rgz_set_async(e, 1);
/* Rest of layers blended with FB */
int first = 1;
while((lix = get_layer_ops_next(hregion, sidx, lix)) != -1) {
int batchflags = 0;
- e = rgz_blts_get(&blts, params);
-
- rgz_layer_t *rgz_layer = hregion->rgz_layers[lix];
- hwc_layer_t *layer = rgz_layer->hwc_layer;
- rgz_src1_prep(e, rgz_layer, rect, scrdesc, scrgeom, params);
- rgz_src2blend_prep2(e, layer->transform, rect, scrdesc, scrgeom, 1);
-
+ e = rgz_hwc_subregion_blend(params, rect, hregion->rgz_layers[lix], NULL);
if (first) {
first = 0;
batchflags |= BVBATCH_SRC2 | BVBATCH_SRC2RECT_ORIGIN;
}
batchflags |= BVBATCH_SRC1 | BVBATCH_SRC1RECT_ORIGIN;
- if (rgz_hwc_scaled(layer))
- batchflags |= BVBATCH_SRC1RECT_ORIGIN | BVBATCH_SRC1RECT_SIZE;
rgz_batch_entry(e, BVFLAG_BATCH_CONTINUE, batchflags);
- rgz_set_async(e, 1);
}
if (e->bp.flags & BVFLAG_BATCH_BEGIN)
@@ -1431,23 +1325,7 @@ static int rgz_hwc_subregion_blit(blit_hregion_t *hregion, int sidx, rgz_out_par
blit_rect_t *rect = &hregion->blitrects[lix][sidx];
if (noblend) /* get_layer_ops() doesn't understand this so get the top */
lix = get_top_rect(hregion, sidx, &rect);
-
- struct rgz_blt_entry* e = rgz_blts_get(&blts, params);
-
- rgz_layer_t *rgz_layer = hregion->rgz_layers[lix];
- hwc_layer_t *l = rgz_layer->hwc_layer;
- rgz_src1_prep(e, rgz_layer, rect, scrdesc, scrgeom, params);
-
- struct bvsurfgeom *src1geom = &e->src1geom;
- unsigned long bpflags = BVFLAG_CLIP | BVFLAG_ROP;
- e->bp.op.rop = 0xCCCC; /* SRCCOPY */
- if((src1geom->format == OCDFMT_BGR124) ||
- (src1geom->format == OCDFMT_RGB124) ||
- (src1geom->format == OCDFMT_RGB16))
- e->dstgeom.format = OCDFMT_BGR124;
-
- rgz_set_async(e, 1);
- e->bp.flags |= bpflags;
+ rgz_hwc_subregion_copy(params, rect, hregion->rgz_layers[lix]);
}
return 0;
}
@@ -1667,6 +1545,7 @@ int rgz_get_screengeometry(int fd, struct bvsurfgeom *geom, int fmt)
geom->height = fb_varinfo.yres;
geom->virtstride = fb_fixinfo.line_length;
geom->format = hal_to_ocd(fmt);
+ /* Always set to 0, src buffers will contain rotation values as needed */
geom->orientation = 0;
return 0;
}