diff options
author | Gustavo Diaz Prado <a0273371@ti.com> | 2012-06-13 15:28:13 -0500 |
---|---|---|
committer | Jason Simmons <jsimmons@google.com> | 2012-10-22 15:39:55 -0700 |
commit | db987b5b5c7421a5f3de3ba284e1efa015351712 (patch) | |
tree | 2c66bb0f8da428adc4d3c0365282028e6a72da42 | |
parent | e90714f1863dc151fb2bb7374c0c7ed0b7d75a14 (diff) | |
download | omap4-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.c | 212 |
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; } |