summaryrefslogtreecommitdiffstats
path: root/hwc
diff options
context:
space:
mode:
authorGustavo Diaz Prado <a0273371@ti.com>2012-07-23 16:04:08 -0500
committerDaniel Levin <dendy@ti.com>2012-11-28 21:16:25 +0200
commit94913f85bd0d1e79f803e901a804413e6130db54 (patch)
tree4a8186d4d72823294758bd23b59fb0e849b0c479 /hwc
parent84274e25fb00d2516c564c339549195155fd97d7 (diff)
downloadhardware_ti_omap4-94913f85bd0d1e79f803e901a804413e6130db54.zip
hardware_ti_omap4-94913f85bd0d1e79f803e901a804413e6130db54.tar.gz
hardware_ti_omap4-94913f85bd0d1e79f803e901a804413e6130db54.tar.bz2
hwc: rgz: Refactor how the blit parameters are set
This patch basically refactors the way the blit parameters are set per subregion. The intention is to make the code ready to introduce the scaling support easier and reduce greatly redundant code as well Change-Id: I2b32056bf2fec1b636fda1c8df9964d90d51192c Signed-off-by: Gustavo Diaz Prado <a0273371@ti.com>
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;
}