summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGustavo Diaz Prado <a0273371@ti.com>2012-06-13 15:28:13 -0500
committerJason Simmons <jsimmons@google.com>2012-10-22 15:39:55 -0700
commitdb987b5b5c7421a5f3de3ba284e1efa015351712 (patch)
tree2c66bb0f8da428adc4d3c0365282028e6a72da42
parente90714f1863dc151fb2bb7374c0c7ed0b7d75a14 (diff)
downloadomap4-aah-db987b5b5c7421a5f3de3ba284e1efa015351712.tar.gz
hwc: regionizer: Give support for rotation with Bltsville
Enables the regionizer to support rotation with Bltsville. This patch doesn't enable horizontal/vertical flips yet. Rebased from p-ics-mr1: bd6d0b5 hwc: regionizer: Give support for rotation with Bltsville Change-Id: I595debea076727ef2c442d7544c1e355aef04808 Signed-off-by: Gustavo Diaz Prado <a0273371@ti.com> Signed-off-by: Tony Lofthouse <a0741364@ti.com> (cherry picked from commit eb5940af48a3b9bd029a5c70d7838d89a03c302b)
-rw-r--r--hwc/rgz_2d.c212
1 files changed, 141 insertions, 71 deletions
diff --git a/hwc/rgz_2d.c b/hwc/rgz_2d.c
index b87478f..8aa0866 100644
--- a/hwc/rgz_2d.c
+++ b/hwc/rgz_2d.c
@@ -100,6 +100,7 @@ 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);
int debug = 0;
struct rgz_blts blts;
@@ -568,12 +569,24 @@ static int rgz_in_valid_hwc_layer(hwc_layer_t *layer)
if ((layer->flags & HWC_SKIP_LAYER) || !handle)
return 0;
- if (layer->transform || rgz_hwc_scaled(layer))
+ if (rgz_hwc_scaled(layer))
return 0;
if (is_NV12(handle->iFormat))
return (handle->iFormat == HAL_PIXEL_FORMAT_TI_NV12);
+ /* FIXME: The following must be removed when GC supports vertical/horizontal
+ * buffer flips, please note having a FLIP_H and FLIP_V means 180 rotation
+ * which is supported indeed
+ */
+ if (layer->transform) {
+ int is_flipped = !!(layer->transform & HWC_TRANSFORM_FLIP_H) ^ !!(layer->transform & HWC_TRANSFORM_FLIP_V);
+ if (is_flipped) {
+ ALOGE("Layer %p is flipped %d", layer, layer->transform);
+ return 0;
+ }
+ }
+
switch(handle->iFormat) {
case HAL_PIXEL_FORMAT_BGRX_8888:
case HAL_PIXEL_FORMAT_RGBX_8888:
@@ -924,6 +937,31 @@ static int rgz_handle_to_stride(IMG_native_handle_t *h)
extern void BVDump(const char* prefix, const char* tab, const struct bvbltparams* parms);
+static int rgz_get_orientation(unsigned int transform)
+{
+ int orientation = 0;
+ if ((transform & HWC_TRANSFORM_FLIP_H) && (transform & HWC_TRANSFORM_FLIP_V))
+ orientation += 180;
+ if (transform & HWC_TRANSFORM_ROT_90)
+ orientation += 90;
+
+ return orientation;
+}
+
+static int rgz_get_flip_flags(unsigned int transform, int use_src2_flags)
+{
+ /*
+ * If vertical and horizontal flip flags are set it means a 180 rotation
+ * (with no flip) is intended for the layer, so we return 0 in that case.
+ */
+ int flip_flags = 0;
+ if (transform & HWC_TRANSFORM_FLIP_H)
+ flip_flags |= (use_src2_flags ? BVFLAG_HORZ_FLIP_SRC2 : BVFLAG_HORZ_FLIP_SRC1);
+ if (transform & HWC_TRANSFORM_FLIP_V)
+ flip_flags = flip_flags ? 0 : flip_flags | (use_src2_flags ? BVFLAG_VERT_FLIP_SRC2 : BVFLAG_VERT_FLIP_SRC1);
+ return flip_flags;
+}
+
static int rgz_hwc_layer_blit(hwc_layer_t *l, rgz_out_params_t *params, int buff_idx)
{
IMG_native_handle_t *handle = (IMG_native_handle_t *)l->handle;
@@ -970,9 +1008,9 @@ static int rgz_hwc_layer_blit(hwc_layer_t *l, rgz_out_params_t *params, int buff
src1geom->format = hal_to_ocd(handle->iFormat);
src1geom->width = handle->iWidth;
src1geom->height = handle->iHeight;
- src1geom->orientation = l->transform & HWC_TRANSFORM_ROT_90 ? 90 :
- l->transform & HWC_TRANSFORM_ROT_180 ? 180 :
- l->transform & HWC_TRANSFORM_ROT_270 ? 270 : 0;
+ 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;
@@ -980,7 +1018,8 @@ static int rgz_hwc_layer_blit(hwc_layer_t *l, rgz_out_params_t *params, int buff
dstgeom->format = scrgeom->format;
dstgeom->width = scrgeom->width;
dstgeom->height = scrgeom->height;
- dstgeom->orientation = 0; /* TODO */
+ /* 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;
@@ -993,14 +1032,22 @@ static int rgz_hwc_layer_blit(hwc_layer_t *l, rgz_out_params_t *params, int buff
bp->dstrect.height = HEIGHT(l->displayFrame);
bp->src1.desc = src1desc;
bp->src1geom = src1geom;
- bp->src1rect.left = l->sourceCrop.left;
- bp->src1rect.top = l->sourceCrop.top;
- bp->src1rect.width = WIDTH(l->sourceCrop);
- bp->src1rect.height = HEIGHT(l->sourceCrop);
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;
@@ -1025,12 +1072,7 @@ static int rgz_hwc_layer_blit(hwc_layer_t *l, rgz_out_params_t *params, int buff
dstgeom->format = OCDFMT_BGR124;
}
- /* TODO regionizer won't permit transforms yet */
- if (l->transform & HWC_TRANSFORM_FLIP_H)
- bpflags |= BVFLAG_HORZ_FLIP_SRC1;
- if (l->transform & HWC_TRANSFORM_FLIP_V)
- bpflags |= BVFLAG_VERT_FLIP_SRC1;
-
+ bpflags |= rgz_get_flip_flags(l->transform, 0);
bp->flags = bpflags;
rgz_set_async(e, 1);
@@ -1038,23 +1080,55 @@ static int rgz_hwc_layer_blit(hwc_layer_t *l, rgz_out_params_t *params, int buff
}
/*
- * Calculate the left coord of the source on the basis of the location of the
- * blit subregion relative to the HWC layer display frame
+ * 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 int effective_srcleft(hwc_layer_t* l, blit_rect_t *rect)
+static void rgz_get_src_rect(hwc_layer_t* layer, blit_rect_t *subregion_rect, blit_rect_t *res_rect)
{
- // Assert rect->left >= l->sourceCrop.left
- // Assert rect->left < l->sourceCrop.left + WIDTH(l->sourceCrop)
- return l->sourceCrop.left + ((WIDTH(l->sourceCrop) * (rect->left - l->displayFrame.left)) / WIDTH(l->displayFrame));
-}
+ if (rgz_hwc_scaled(layer))
+ ALOGE("%s: layer %p is scaled", __func__, layer);
-static int effective_srctop(hwc_layer_t* l, blit_rect_t *rect)
-{
- // Assert rect->top >= l->sourceCrop.top
- // Assert rect->top < l->sourceCrop.top + HEIGHT(l->sourceCrop)
- return l->sourceCrop.top + ((HEIGHT(l->sourceCrop) * (rect->top - l->displayFrame.top)) / HEIGHT(l->displayFrame));
+ IMG_native_handle_t *handle = (IMG_native_handle_t *)layer->handle;
+ int res_left = 0;
+ int res_top = 0;
+ int delta_left = subregion_rect->left - layer->displayFrame.left;
+ int delta_top = subregion_rect->top - layer->displayFrame.top;
+ /*
+ * Calculate the top, left offset from the source cropping rectangle
+ * depending on the rotation
+ */
+ switch(layer->transform) {
+ case 0:
+ res_left = layer->sourceCrop.left + delta_left;
+ res_top = layer->sourceCrop.top + delta_top;
+ break;
+ case HAL_TRANSFORM_ROT_90:
+ res_left = handle->iHeight - layer->sourceCrop.bottom + delta_left;
+ res_top = layer->sourceCrop.left + delta_top;
+ break;
+ case HAL_TRANSFORM_ROT_180:
+ res_left = handle->iWidth - layer->sourceCrop.right + delta_left;
+ res_top = handle->iHeight - layer->sourceCrop.bottom + delta_top;
+ break;
+ case HAL_TRANSFORM_ROT_270:
+ res_left = layer->sourceCrop.top + delta_left;
+ res_top = handle->iWidth - layer->sourceCrop.right + delta_top;
+ break;
+ default:
+ OUTE("Invalid transform value %d", layer->transform);
+ }
+
+ /* Resulting rectangle has the subregion dimensions */
+ res_rect->left = res_left;
+ res_rect->top = res_top;
+ res_rect->right = res_left + WIDTH(*subregion_rect);
+ res_rect->bottom = res_top + HEIGHT(*subregion_rect);
}
+
/*
* Setup the src2 rectangle and the passed descriptor and
* geometry
@@ -1066,14 +1140,10 @@ static void rgz_src2blend_prep2(
unsigned long bpflags = BVFLAG_CLIP;
struct bvbltparams *bp = &e->bp;
- bpflags |= BVFLAG_BLEND; // FIXME batch?
+ bpflags |= BVFLAG_BLEND;
bp->op.blend = BVBLEND_SRC1OVER;
bp->src2.desc = dstdesc;
bp->src2geom = dstgeom;
- bp->src2rect.left = rect->left;
- bp->src2rect.top = rect->top;
- bp->src2rect.width = WIDTH(*rect);
- bp->src2rect.height = HEIGHT(*rect);
if (is_fb_dest) {
struct bvsurfgeom *src2geom = &e->src2geom;
@@ -1081,14 +1151,19 @@ static void rgz_src2blend_prep2(
*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);
}
- if (hwc_transform & HWC_TRANSFORM_FLIP_H)
- bpflags |= BVFLAG_HORZ_FLIP_SRC1;
- if (hwc_transform & HWC_TRANSFORM_FLIP_V)
- bpflags |= BVFLAG_VERT_FLIP_SRC1;
-
- bp->flags = bpflags;
+ bp->flags |= bpflags;
}
static void rgz_src2blend_prep(
@@ -1108,22 +1183,19 @@ static void rgz_src2blend_prep(
src2geom->format = hal_to_ocd(handle->iFormat);
src2geom->width = handle->iWidth;
src2geom->height = handle->iHeight;
- src2geom->orientation = l->transform & HWC_TRANSFORM_ROT_90 ? 90 :
- l->transform & HWC_TRANSFORM_ROT_180 ? 180 :
- l->transform & HWC_TRANSFORM_ROT_270 ? 270 : 0;
src2geom->virtstride = HANDLE_TO_STRIDE(handle);
+ if (l->transform & HAL_TRANSFORM_ROT_90)
+ swap(src2geom->width, src2geom->height);
- /*
- * This looks a little odd but what we need to do here is take the
- * rectangle which has coordinates in terms of the display dimensions
- * and find the offset of the source buffer for the layer
- */
- blit_rect_t src2rect = *rect;
- src2rect.top = effective_srctop(l, rect);
- src2rect.left = effective_srcleft(l, rect);
- src2rect.bottom = src2rect.top + HEIGHT(*rect);
- src2rect.right = src2rect.left + WIDTH(*rect);
- rgz_src2blend_prep2(e, l->transform, &src2rect, src2desc, src2geom, 0);
+ 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(
@@ -1148,16 +1220,17 @@ static void rgz_src1_prep(
src1geom->format = hal_to_ocd(handle->iFormat);
src1geom->width = handle->iWidth;
src1geom->height = handle->iHeight;
- src1geom->orientation = l->transform & HWC_TRANSFORM_ROT_90 ? 90 :
- l->transform & HWC_TRANSFORM_ROT_180 ? 180 :
- l->transform & HWC_TRANSFORM_ROT_270 ? 270 : 0;
+ 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);
@@ -1165,19 +1238,20 @@ static void rgz_src1_prep(
bp->structsize = sizeof(struct bvbltparams);
bp->dstdesc = scrdesc;
bp->dstgeom = dstgeom;
- bp->dstrect.left = rect->left;
- bp->dstrect.top = rect->top;
- bp->dstrect.width = WIDTH(*rect);
- bp->dstrect.height = HEIGHT(*rect);
+ 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;
- bp->src1rect.left = effective_srcleft(l, rect);
- bp->src1rect.top = effective_srctop(l, rect);
- bp->src1rect.width = WIDTH(*rect); // XXX fixme - effective width/height?
- bp->src1rect.height = HEIGHT(*rect);
- bp->cliprect.left = bp->cliprect.top = 0;
- bp->cliprect.width = scrgeom->width;
- bp->cliprect.height = scrgeom->height;
+
+ 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)
@@ -1324,12 +1398,8 @@ static int rgz_hwc_subregion_blit(blit_hregion_t *hregion, int sidx, rgz_out_par
(src1geom->format == OCDFMT_RGB16))
e->dstgeom.format = OCDFMT_BGR124;
- if (l->transform & HWC_TRANSFORM_FLIP_H)
- bpflags |= BVFLAG_HORZ_FLIP_SRC1;
- if (l->transform & HWC_TRANSFORM_FLIP_V)
- bpflags |= BVFLAG_VERT_FLIP_SRC1;
- e->bp.flags = bpflags;
rgz_set_async(e, 1);
+ e->bp.flags |= bpflags;
}
return 0;
}