From 2197d5d9246d0009b63fa8333b5379f256d5f80a Mon Sep 17 00:00:00 2001 From: Naomi Luis Date: Tue, 6 Dec 2011 11:51:27 -0800 Subject: [PATCH 1/2] libcopybit: Add support for YUV destination targets. Add support in the c2d copybit for YUV destination. We support 2 and 3 plane yuv formats. Change-Id: Ia2b4dadf2966a324e011fea499da996eee8c8c3c --- libcopybit/copybit_c2d.cpp | 365 +++++++++++++++++++++++++++---------- 1 file changed, 273 insertions(+), 92 deletions(-) diff --git a/libcopybit/copybit_c2d.cpp b/libcopybit/copybit_c2d.cpp index f703f05..e3d6308 100644 --- a/libcopybit/copybit_c2d.cpp +++ b/libcopybit/copybit_c2d.cpp @@ -85,18 +85,26 @@ C2D_STATUS (*LINK_c2dDestroySurface)( uint32 surface_id ); #define COPYBIT_SUCCESS 0 #define COPYBIT_FAILURE -1 - -#define RGB_SURFACE 0 -#define YUV_SURFACE 1 -#define NUM_SRC_SURFACES 2 +#define NUM_SURFACES 3 #define ALIGN(x, align) (((x) + ((align)-1)) & ~((align)-1)) + +enum { + RGB_SURFACE, + YUV_SURFACE_2_PLANES, + YUV_SURFACE_3_PLANES +}; + +enum eC2DFlags { + FLAGS_PREMULTIPLIED_ALPHA = 1<<0, + FLAGS_YUV_DESTINATION = 1<<1 +}; /******************************************************************************/ /** State information for each device instance */ struct copybit_context_t { struct copybit_device_t device; - unsigned int src[NUM_SRC_SURFACES]; - unsigned int dst; /* dst surface */ + unsigned int src[NUM_SURFACES]; /* src surfaces */ + unsigned int dst[NUM_SURFACES]; /* dst surfaces */ unsigned int trg_transform; /* target transform */ C2D_OBJECT blitState; void *libc2d2; @@ -111,6 +119,21 @@ struct blitlist{ C2D_OBJECT blitObjects[12]; }; +struct bufferInfo { + int width; + int height; + int format; +}; + + +struct yuvPlaneInfo { + int yStride; //luma stride + int plane1_stride; + int plane2_stride; + int plane1_offset; + int plane2_offset; +}; + /** * Common hardware methods */ @@ -148,9 +171,25 @@ static int get_format(int format) { case HAL_PIXEL_FORMAT_RGBA_5551: return C2D_COLOR_FORMAT_5551_RGBA; case HAL_PIXEL_FORMAT_RGBA_4444: return C2D_COLOR_FORMAT_4444_RGBA; case HAL_PIXEL_FORMAT_YCbCr_420_SP: return C2D_COLOR_FORMAT_420_NV12; + case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:return C2D_COLOR_FORMAT_420_NV12; case HAL_PIXEL_FORMAT_YCrCb_420_SP: return C2D_COLOR_FORMAT_420_NV21; case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED: return C2D_COLOR_FORMAT_420_NV12 | C2D_FORMAT_MACROTILED; - default: return -EINVAL; + default: LOGE("%s: invalid format (0x%x", __FUNCTION__, format); return -EINVAL; + } + return -EINVAL; +} + +/* Get the C2D formats needed for conversion to YUV */ +static int get_c2d_format_for_yuv_destination(int halFormat) { + switch (halFormat) { + // We do not swap the RB when the target is YUV + case HAL_PIXEL_FORMAT_RGBX_8888: return C2D_COLOR_FORMAT_8888_ARGB | C2D_FORMAT_DISABLE_ALPHA; + case HAL_PIXEL_FORMAT_RGBA_8888: return C2D_COLOR_FORMAT_8888_ARGB; + // The U and V need to be interchanged when the target is YUV + case HAL_PIXEL_FORMAT_YCbCr_420_SP: return C2D_COLOR_FORMAT_420_NV21; + case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:return C2D_COLOR_FORMAT_420_NV21; + case HAL_PIXEL_FORMAT_YCrCb_420_SP: return C2D_COLOR_FORMAT_420_NV12; + default: return get_format(halFormat); } return -EINVAL; } @@ -254,11 +293,28 @@ static int is_supported_rgb_format(int format) } } +static int get_num_planes(int format) +{ + switch(format) { + case HAL_PIXEL_FORMAT_YCbCr_420_SP: + case HAL_PIXEL_FORMAT_YCrCb_420_SP: + case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED: { + return 2; + } + case HAL_PIXEL_FORMAT_YV12: { + return 3; + } + default: + return COPYBIT_FAILURE; + } +} + static int is_supported_yuv_format(int format) { switch(format) { case HAL_PIXEL_FORMAT_YCbCr_420_SP: case HAL_PIXEL_FORMAT_YCrCb_420_SP: + case HAL_PIXEL_FORMAT_NV12_ENCODEABLE: case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED: { return COPYBIT_SUCCESS; } @@ -267,8 +323,21 @@ static int is_supported_yuv_format(int format) } } -static int calculate_yuv_offset_and_stride(int format, int width, int height, int *offset, int *yStride, int *uvStride) +static int is_valid_destination_format(int format) { + if (format == HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED) { + // C2D does not support NV12Tile as a destination format. + return COPYBIT_FAILURE; + } + return COPYBIT_SUCCESS; +} + +static int calculate_yuv_offset_and_stride(const bufferInfo& info, yuvPlaneInfo& yuvInfo) +{ + int width = info.width; + int height = info.height; + int format = info.format; + int aligned_height = 0; int aligned_width = 0, size = 0; @@ -280,17 +349,23 @@ static int calculate_yuv_offset_and_stride(int format, int width, int height, in aligned_height = ALIGN(height, 32); aligned_width = ALIGN(width, 128); size = aligned_width * aligned_height; - *offset = ALIGN(size,8192); - *yStride = aligned_width; - *uvStride = aligned_width; + yuvInfo.plane1_offset = ALIGN(size,8192); + yuvInfo.yStride = aligned_width; + yuvInfo.plane1_stride = aligned_width; break; } case HAL_PIXEL_FORMAT_YCbCr_420_SP: + case HAL_PIXEL_FORMAT_NV12_ENCODEABLE: case HAL_PIXEL_FORMAT_YCrCb_420_SP: { aligned_width = ALIGN(width, 32); - *offset = aligned_width * height; - *yStride = aligned_width; - *uvStride = aligned_width; + yuvInfo.yStride = aligned_width; + yuvInfo.plane1_stride = aligned_width; + if (HAL_PIXEL_FORMAT_NV12_ENCODEABLE == format) { + // The encoder requires a 2K aligned chroma offset + yuvInfo.plane1_offset = ALIGN(aligned_width * height, 2048); + } else + yuvInfo.plane1_offset = aligned_width * height; + break; } default: { @@ -302,15 +377,20 @@ static int calculate_yuv_offset_and_stride(int format, int width, int height, in /** create C2D surface from copybit image */ static int set_image(int device_fd, uint32 surfaceId, const struct copybit_image_t *rhs, int *cformat, uint32_t *mapped, - const bool isPremultipliedAlpha) + const eC2DFlags flags) { struct private_handle_t* handle = (struct private_handle_t*)rhs->handle; C2D_SURFACE_TYPE surfaceType; int status = COPYBIT_SUCCESS; - *cformat = get_format(rhs->format); + if (flags & FLAGS_YUV_DESTINATION) { + *cformat = get_c2d_format_for_yuv_destination(rhs->format); + } else { + *cformat = get_format(rhs->format); + } + if(*cformat == -EINVAL) { - LOGE("%s: invalid format", __func__); + LOGE("%s: invalid format", __FUNCTION__); return -EINVAL; } @@ -322,6 +402,7 @@ static int set_image(int device_fd, uint32 surfaceId, const struct copybit_image if (handle->gpuaddr == 0) { handle->gpuaddr = c2d_get_gpuaddr(device_fd, handle); if(!handle->gpuaddr) { + LOGE("%s: c2d_get_gpuaddr failed", __FUNCTION__); return COPYBIT_FAILURE; } *mapped = 1; @@ -337,28 +418,31 @@ static int set_image(int device_fd, uint32 surfaceId, const struct copybit_image surfaceDef.phys = (void*) handle->gpuaddr; surfaceDef.buffer = (void*) (handle->base); - surfaceDef.format = *cformat | (isPremultipliedAlpha ? C2D_FORMAT_PREMULTIPLIED : 0); + surfaceDef.format = *cformat | ((flags & FLAGS_PREMULTIPLIED_ALPHA) ? C2D_FORMAT_PREMULTIPLIED : 0); surfaceDef.width = rhs->w; surfaceDef.height = rhs->h; surfaceDef.stride = ALIGN(((surfaceDef.width * c2diGetBpp(surfaceDef.format))>>3), 32); if(LINK_c2dUpdateSurface( surfaceId,C2D_TARGET | C2D_SOURCE, surfaceType, &surfaceDef)) { - LOGE("%s: RGB Surface c2dUpdateSurface ERROR", __func__); + LOGE("%s: RGB Surface c2dUpdateSurface ERROR", __FUNCTION__); goto error; status = COPYBIT_FAILURE; } } else if (is_supported_yuv_format(rhs->format) == COPYBIT_SUCCESS) { C2D_YUV_SURFACE_DEF surfaceDef; - int offset = 0; - int yStride = 0; - int uvStride = 0; memset(&surfaceDef, 0, sizeof(surfaceDef)); surfaceType = (C2D_SURFACE_TYPE)(C2D_SURFACE_YUV_HOST | C2D_SURFACE_WITH_PHYS); surfaceDef.format = *cformat; - status = calculate_yuv_offset_and_stride(rhs->format, rhs->w, rhs->h, &offset, &yStride, &uvStride); + bufferInfo info; + info.width = rhs->w; + info.height = rhs->h; + info.format = rhs->format; + + yuvPlaneInfo yuvInfo; + status = calculate_yuv_offset_and_stride(info, yuvInfo); if(status != COPYBIT_SUCCESS) { - LOGE("calculate_yuv_offset_and_stride error"); + LOGE("%s: calculate_yuv_offset_and_stride error", __FUNCTION__); goto error; } @@ -366,19 +450,24 @@ static int set_image(int device_fd, uint32 surfaceId, const struct copybit_image surfaceDef.height = rhs->h; surfaceDef.plane0 = (void*) (handle->base); surfaceDef.phys0 = (void*) (handle->gpuaddr); - surfaceDef.stride0 = yStride; + surfaceDef.stride0 = yuvInfo.yStride; - surfaceDef.plane1 = (void*) (handle->base + offset); - surfaceDef.phys1 = (void*) (handle->gpuaddr + offset); - surfaceDef.stride1 = uvStride; + surfaceDef.plane1 = (void*) (handle->base + yuvInfo.plane1_offset); + surfaceDef.phys1 = (void*) (handle->gpuaddr + yuvInfo.plane1_offset); + surfaceDef.stride1 = yuvInfo.plane1_stride; + if (3 == get_num_planes(rhs->format)) { + surfaceDef.plane2 = (void*) (handle->base + yuvInfo.plane2_offset); + surfaceDef.phys2 = (void*) (handle->gpuaddr + yuvInfo.plane2_offset); + surfaceDef.stride2 = yuvInfo.plane2_stride; + } if(LINK_c2dUpdateSurface( surfaceId,C2D_TARGET | C2D_SOURCE, surfaceType, &surfaceDef)) { - LOGE("%s: YUV Surface c2dUpdateSurface ERROR", __func__); + LOGE("%s: YUV Surface c2dUpdateSurface ERROR", __FUNCTION__); goto error; status = COPYBIT_FAILURE; } } else { - LOGE("%s: invalid format %x", __func__, rhs->format); + LOGE("%s: invalid format 0x%x", __FUNCTION__, rhs->format); goto error; status = COPYBIT_FAILURE; } @@ -427,7 +516,7 @@ static int set_src_image(int device_fd, uint32 *surfaceId, const struct copybit_ surfaceDef.stride = ALIGN(((surfaceDef.width * c2diGetBpp(surfaceDef.format))>>3), 32); if(LINK_c2dCreateSurface( surfaceId, C2D_TARGET, surfaceType,(void*)&surfaceDef)) { - LOGE("%s: LINK_c2dCreateSurface error", __func__); + LOGE("%s: LINK_c2dCreateSurface error", __FUNCTION__); status = COPYBIT_FAILURE; goto error; } @@ -441,9 +530,15 @@ static int set_src_image(int device_fd, uint32 *surfaceId, const struct copybit_ surfaceType = (C2D_SURFACE_TYPE)(C2D_SURFACE_YUV_HOST | C2D_SURFACE_WITH_PHYS); surfaceDef.format = get_format(rhs->format); - status = calculate_yuv_offset_and_stride(rhs->format, rhs->w, rhs->h, &offset, &yStride, &uvStride); + bufferInfo info; + info.width = rhs->w; + info.height = rhs->h; + info.format = rhs->format; + + yuvPlaneInfo yuvInfo; + status = calculate_yuv_offset_and_stride(info, yuvInfo); if(status != COPYBIT_SUCCESS) { - LOGE("calculate_yuv_offset_and_stride error"); + LOGE("%s: calculate_yuv_offset_and_stride error", __FUNCTION__); goto error; } @@ -451,11 +546,11 @@ static int set_src_image(int device_fd, uint32 *surfaceId, const struct copybit_ surfaceDef.height = rhs->h; surfaceDef.plane0 = (void*) (handle->base); surfaceDef.phys0 = (void*) handle->gpuaddr; - surfaceDef.stride0 = yStride; + surfaceDef.stride0 = yuvInfo.yStride; - surfaceDef.plane1 = (void*) (handle->base + offset); - surfaceDef.phys1 = (void*) (handle->gpuaddr + offset); - surfaceDef.stride1 = uvStride; + surfaceDef.plane1 = (void*) (handle->base + yuvInfo.plane1_offset); + surfaceDef.phys1 = (void*) (handle->gpuaddr + yuvInfo.plane1_offset); + surfaceDef.stride1 = yuvInfo.plane1_stride; if(LINK_c2dCreateSurface( surfaceId, C2D_TARGET | C2D_SOURCE, surfaceType, (void*)&surfaceDef)) { LOGE("%s: YUV surface LINK_c2dCreateSurface error", __func__); @@ -463,7 +558,7 @@ static int set_src_image(int device_fd, uint32 *surfaceId, const struct copybit_ goto error; } } else { - LOGE("%s: Invalid format %x", __func__, rhs->format); + LOGE("%s: Invalid format 0x%x", __FUNCTION__, rhs->format); status = COPYBIT_FAILURE; } @@ -598,7 +693,7 @@ static int msm_copybit(struct copybit_context_t *dev, blitlist *list, uint32 tar if(LINK_c2dDraw(target,dev->trg_transform, 0x0, 0, 0, list->blitObjects, list->count)) { - LOGE("%s: LINK_c2dDraw ERROR"); + LOGE("%s: LINK_c2dDraw ERROR", __FUNCTION__); return COPYBIT_FAILURE; } @@ -615,7 +710,7 @@ static int set_parameter_copybit( { struct copybit_context_t* ctx = (struct copybit_context_t*)dev; if (!ctx) { - LOGE("%s: null context", __func__); + LOGE("%s: null context", __FUNCTION__); return -EINVAL; } @@ -746,20 +841,20 @@ static int stretch_copybit_internal( memset(&list, 0, sizeof(list)); int cformat; c2d_ts_handle timestamp; - uint32 surface_index = 0; + uint32 src_surface_index = 0, dst_surface_index = 0; if (!ctx) { - LOGE("%s: null context error", __func__); + LOGE("%s: null context error", __FUNCTION__); return -EINVAL; } if (src->w > MAX_DIMENSION || src->h > MAX_DIMENSION) { - LOGE("%s: src dimension error", __func__); + LOGE("%s: src dimension error", __FUNCTION__); return -EINVAL; } if (dst->w > MAX_DIMENSION || dst->h > MAX_DIMENSION) { - LOGE("%s : dst dimension error dst w %d h %d", __func__, dst->w, dst->h); + LOGE("%s : dst dimension error dst w %d h %d", __FUNCTION__, dst->w, dst->h); return -EINVAL; } @@ -768,22 +863,63 @@ static int stretch_copybit_internal( struct copybit_rect_t clip; list.count = 0; - status = set_image(ctx->g12_device_fd, ctx->dst, dst, &cformat, &trg_mapped, ctx->isPremultipliedAlpha); + if (is_valid_destination_format(dst->format) == COPYBIT_FAILURE) { + LOGE("%s: Invalid destination format format = 0x%x", __FUNCTION__, dst->format); + return COPYBIT_FAILURE; + } + + bool isYUVDestination = false; + if (is_supported_rgb_format(dst->format) == COPYBIT_SUCCESS) { + dst_surface_index = RGB_SURFACE; + } else if (is_supported_yuv_format(dst->format) == COPYBIT_SUCCESS) { + isYUVDestination = true; + int num_planes = get_num_planes(dst->format); + if (num_planes == 2) { + dst_surface_index = YUV_SURFACE_2_PLANES; + } else if (num_planes == 3) { + dst_surface_index = YUV_SURFACE_3_PLANES; + } else { + LOGE("%s: dst number of YUV planes is invalid dst format = 0x%x", + __FUNCTION__, dst->format); + return COPYBIT_FAILURE; + } + } else { + LOGE("%s: Invalid dst surface format 0x%x", __FUNCTION__, dst->format); + return COPYBIT_FAILURE; + } + + + int flags = 0; + flags |= (ctx->isPremultipliedAlpha) ? FLAGS_PREMULTIPLIED_ALPHA : 0; + flags |= (isYUVDestination) ? FLAGS_YUV_DESTINATION : 0; + + status = set_image(ctx->g12_device_fd, ctx->dst[dst_surface_index], dst, &cformat, + &trg_mapped, (eC2DFlags)flags); if(status) { LOGE("%s: set_image error", __func__); return COPYBIT_FAILURE; } if(is_supported_rgb_format(src->format) == COPYBIT_SUCCESS) { - surface_index = RGB_SURFACE; + src_surface_index = RGB_SURFACE; } else if (is_supported_yuv_format(src->format) == COPYBIT_SUCCESS) { - surface_index = YUV_SURFACE; + int num_planes = get_num_planes(src->format); + if (num_planes == 2) { + src_surface_index = YUV_SURFACE_2_PLANES; + } else if (num_planes == 3) { + src_surface_index = YUV_SURFACE_3_PLANES; + } else { + LOGE("%s: src number of YUV planes is invalid src format = 0x%x", + __FUNCTION__, src->format); + return -EINVAL; + } } else { LOGE("%s: Invalid source surface format %x", __func__, src->format); return -EINVAL; } - status = set_image(ctx->g12_device_fd, ctx->src[surface_index], src, &cformat, &src_mapped, ctx->isPremultipliedAlpha); + status = set_image(ctx->g12_device_fd, ctx->src[src_surface_index], src, &cformat, + &src_mapped, (eC2DFlags)flags); if(status) { LOGE("%s: set_src_image error", __func__); return COPYBIT_FAILURE; @@ -794,8 +930,8 @@ static int stretch_copybit_internal( ctx->blitState.config_mask &= ~C2D_ALPHA_BLEND_NONE; if(!(ctx->blitState.global_alpha)) { // src alpha is zero - unset_image(ctx->g12_device_fd, ctx->src[surface_index], src, src_mapped); - unset_image(ctx->g12_device_fd, ctx->dst, dst, trg_mapped); + unset_image(ctx->g12_device_fd, ctx->src[src_surface_index], src, src_mapped); + unset_image(ctx->g12_device_fd, ctx->dst[dst_surface_index], dst, trg_mapped); return status; } } else { @@ -808,7 +944,7 @@ static int stretch_copybit_internal( ctx->blitState.config_mask |= C2D_ALPHA_BLEND_NONE; } - ctx->blitState.surface_id = ctx->src[surface_index]; + ctx->blitState.surface_id = ctx->src[src_surface_index]; while ((status == 0) && region->next(region, &clip)) { req = &(list.blitObjects[list.count]); @@ -817,21 +953,21 @@ static int stretch_copybit_internal( set_rects(ctx, req, dst_rect, src_rect, &clip); if (++list.count == maxCount) { - status = msm_copybit(ctx, &list, ctx->dst); + status = msm_copybit(ctx, &list, ctx->dst[dst_surface_index]); list.count = 0; } } if ((status == 0) && list.count) { - status = msm_copybit(ctx, &list, ctx->dst); + status = msm_copybit(ctx, &list, ctx->dst[dst_surface_index]); } - if(LINK_c2dFinish(ctx->dst)) { - LOGE("%s: LINK_c2dFinish ERROR", __func__); + if(LINK_c2dFinish(ctx->dst[dst_surface_index])) { + LOGE("%s: LINK_c2dFinish ERROR", __FUNCTION__); } - unset_image(ctx->g12_device_fd, ctx->src[surface_index], src, src_mapped); - unset_image(ctx->g12_device_fd, ctx->dst, dst, trg_mapped); + unset_image(ctx->g12_device_fd, ctx->src[src_surface_index], src, src_mapped); + unset_image(ctx->g12_device_fd, ctx->dst[dst_surface_index], dst, trg_mapped); ctx->isPremultipliedAlpha = false; return status; } @@ -866,8 +1002,8 @@ static int close_copybit(struct hw_device_t *dev) { struct copybit_context_t* ctx = (struct copybit_context_t*)dev; if (ctx) { - LINK_c2dDestroySurface(ctx->dst); - for(int i = 0; i dst[i]); LINK_c2dDestroySurface(ctx->src[i]); } @@ -903,13 +1039,18 @@ static int open_copybit(const struct hw_module_t* module, const char* name, ctx = (struct copybit_context_t *)malloc(sizeof(struct copybit_context_t)); if(!ctx) { - LOGE("%s: malloc failed", __func__); + LOGE("%s: malloc failed", __FUNCTION__); return COPYBIT_FAILURE; } /* initialize drawstate */ memset(ctx, 0, sizeof(*ctx)); + for (int i=0; i< NUM_SURFACES; i++) { + ctx->dst[i] = -1; + ctx->src[i] = -1; + } + ctx->libc2d2 = ::dlopen("libC2D2.so", RTLD_NOW); if (!ctx->libc2d2) { LOGE("FATAL ERROR: could not dlopen libc2d2.so: %s", dlerror()); @@ -929,11 +1070,11 @@ static int open_copybit(const struct hw_module_t* module, const char* name, *(void **)&LINK_c2dDestroySurface = ::dlsym(ctx->libc2d2, "c2dDestroySurface"); - if(!LINK_c2dCreateSurface || !LINK_c2dUpdateSurface || !LINK_c2dReadSurface + if (!LINK_c2dCreateSurface || !LINK_c2dUpdateSurface || !LINK_c2dReadSurface || !LINK_c2dDraw || !LINK_c2dFlush || !LINK_c2dWaitTimestamp || !LINK_c2dFinish || !LINK_c2dDestroySurface) { - LOGE("%s: dlsym ERROR", __func__); - goto error1; + LOGE("%s: dlsym ERROR", __FUNCTION__); + goto error; } ctx->device.common.tag = HARDWARE_DEVICE_TAG; @@ -947,9 +1088,9 @@ static int open_copybit(const struct hw_module_t* module, const char* name, ctx->blitState.config_mask = C2D_NO_BILINEAR_BIT | C2D_NO_ANTIALIASING_BIT; ctx->trg_transform = C2D_TARGET_ROTATE_0; ctx->g12_device_fd = open(G12_DEVICE_NAME, O_RDWR | O_SYNC); - if(ctx->g12_device_fd < 0) { - LOGE("%s: g12_device_fd open failed", __func__); - goto error1; + if (ctx->g12_device_fd < 0) { + LOGE("%s: g12_device_fd open failed", __FUNCTION__); + goto error; } /* Create RGB Surface */ @@ -959,19 +1100,21 @@ static int open_copybit(const struct hw_module_t* module, const char* name, surfDefinition.width = 1; surfDefinition.height = 1; surfDefinition.format = C2D_COLOR_FORMAT_8888_ARGB; - - if(LINK_c2dCreateSurface(&ctx->dst,C2D_TARGET | C2D_SOURCE, + if (LINK_c2dCreateSurface(&(ctx->dst[RGB_SURFACE]), C2D_TARGET | C2D_SOURCE, (C2D_SURFACE_TYPE)(C2D_SURFACE_RGB_HOST | C2D_SURFACE_WITH_PHYS), &surfDefinition)) { - LOGE("%s: create ctx->dst failed", __func__); - goto error2; + LOGE("%s: create ctx->dst[RGB_SURFACE] failed", __FUNCTION__); + ctx->dst[RGB_SURFACE] = -1; + goto error; } - if(LINK_c2dCreateSurface(&(ctx->src[RGB_SURFACE]), C2D_TARGET | C2D_SOURCE, + + if (LINK_c2dCreateSurface(&(ctx->src[RGB_SURFACE]), C2D_TARGET | C2D_SOURCE, (C2D_SURFACE_TYPE)(C2D_SURFACE_RGB_HOST | C2D_SURFACE_WITH_PHYS), &surfDefinition)) { - LOGE("%s: create ctx->src[RGB_SURFACE] failed", __func__); - goto error3; + LOGE("%s: create ctx->src[RGB_SURFACE] failed", __FUNCTION__); + ctx->src[RGB_SURFACE] = -1; + goto error; } /* Create YUV source surface */ @@ -987,11 +1130,41 @@ static int open_copybit(const struct hw_module_t* module, const char* name, yuvSurfaceDef.phys1 = (void*) 0xaaaaaaaa; yuvSurfaceDef.stride1 = 4; - if(LINK_c2dCreateSurface(&(ctx->src[YUV_SURFACE]),C2D_TARGET | C2D_SOURCE, + if (LINK_c2dCreateSurface(&(ctx->src[YUV_SURFACE_2_PLANES]),C2D_TARGET | C2D_SOURCE, (C2D_SURFACE_TYPE)(C2D_SURFACE_YUV_HOST | C2D_SURFACE_WITH_PHYS), &yuvSurfaceDef)) { - LOGE("%s: create ctx->src[YUV_SURFACE] failed", __func__); - goto error4; + LOGE("%s: create ctx->src[YUV_SURFACE_2_PLANES] failed", __FUNCTION__); + ctx->src[YUV_SURFACE_2_PLANES] = -1; + goto error; + } + + if (LINK_c2dCreateSurface(&(ctx->dst[YUV_SURFACE_2_PLANES]),C2D_TARGET | C2D_SOURCE, + (C2D_SURFACE_TYPE)(C2D_SURFACE_YUV_HOST | C2D_SURFACE_WITH_PHYS), + &yuvSurfaceDef)) { + LOGE("%s: create ctx->dst[YUV_SURFACE_2_PLANES] failed", __FUNCTION__); + ctx->dst[YUV_SURFACE_2_PLANES] = -1; + goto error; + } + + yuvSurfaceDef.format = C2D_COLOR_FORMAT_420_YV12; + yuvSurfaceDef.plane2 = (void*)0xaaaaaaaa; + yuvSurfaceDef.phys2 = (void*) 0xaaaaaaaa; + yuvSurfaceDef.stride2 = 4; + + if (LINK_c2dCreateSurface(&(ctx->src[YUV_SURFACE_3_PLANES]),C2D_TARGET | C2D_SOURCE, + (C2D_SURFACE_TYPE)(C2D_SURFACE_YUV_HOST | C2D_SURFACE_WITH_PHYS), + &yuvSurfaceDef)) { + LOGE("%s: create ctx->src[YUV_SURFACE_3_PLANES] failed", __FUNCTION__); + ctx->src[YUV_SURFACE_3_PLANES] = -1; + goto error; + } + + if (LINK_c2dCreateSurface(&(ctx->dst[YUV_SURFACE_3_PLANES]),C2D_TARGET | C2D_SOURCE, + (C2D_SURFACE_TYPE)(C2D_SURFACE_YUV_HOST | C2D_SURFACE_WITH_PHYS), + &yuvSurfaceDef)) { + LOGE("%s: create ctx->dst[YUV_SURFACE_3_PLANES] failed", __FUNCTION__); + ctx->dst[YUV_SURFACE_3_PLANES] = -1; + goto error; } *device = &ctx->device.common; @@ -1002,11 +1175,11 @@ static int open_copybit(const struct hw_module_t* module, const char* name, i++; } if (fd < 0) - goto error5; + goto error; struct fb_var_screeninfo info; if (ioctl(fd, FBIOGET_VSCREENINFO, &info) == -1) - goto error6; + goto error; ctx->fb_width = info.xres; ctx->fb_height = info.yres; @@ -1014,21 +1187,29 @@ static int open_copybit(const struct hw_module_t* module, const char* name, ctx->isPremultipliedAlpha = false; return status; -error6: - close(fd); - fd = -1; -error5: - LINK_c2dDestroySurface(ctx->src[YUV_SURFACE]); -error4: - LINK_c2dDestroySurface(ctx->src[RGB_SURFACE]); -error3: - LINK_c2dDestroySurface(ctx->dst); -error2: - close(ctx->g12_device_fd); -error1: - ::dlclose(ctx->libc2d2); error: - free(ctx); + if (fd >= 0) { + close(fd); + fd = -1; + } + + for (int i = 0; isrc[i])) { + LINK_c2dDestroySurface(ctx->src[i]); + ctx->src[i] = -1; + } + if (-1 != (ctx->dst[i])) { + LINK_c2dDestroySurface(ctx->dst[i]); + ctx->dst[i] = -1; + } + } + if (ctx->g12_device_fd >= 0) { + close(ctx->g12_device_fd); + } + if (ctx->libc2d2) + ::dlclose(ctx->libc2d2); + if (ctx) + free(ctx); status = COPYBIT_FAILURE; *device = NULL; From 90f0fc7201bff9823ed8ac63873be0bdec7ccb9b Mon Sep 17 00:00:00 2001 From: Naomi Luis Date: Tue, 6 Dec 2011 12:58:20 -0800 Subject: [PATCH 2/2] libcopybit: Add support for setting the Framebuffer info. Add support to set the framebuffer width and height in the copybit context. This parameter will be set for composition using c2d where the c2d target is calculated based on the framebuffer width and height. Change-Id: Ica0f7622bed305c0f56dd0a16b35406c28600fd8 --- libcopybit/copybit.h | 6 +++- libcopybit/copybit_c2d.cpp | 57 +++++++++++++++----------------------- 2 files changed, 27 insertions(+), 36 deletions(-) diff --git a/libcopybit/copybit.h b/libcopybit/copybit.h index 920f858..e6c55e0 100644 --- a/libcopybit/copybit.h +++ b/libcopybit/copybit.h @@ -65,7 +65,11 @@ enum { COPYBIT_BLUR = 5, /* Informs the copybit that the source and destination contains premultiplied alpha */ - COPYBIT_PREMULTIPLIED_ALPHA = 6 + COPYBIT_PREMULTIPLIED_ALPHA = 6, + /* FB width */ + COPYBIT_FRAMEBUFFER_WIDTH = 7, + /* FB height */ + COPYBIT_FRAMEBUFFER_HEIGHT = 8, }; /* values for copybit_set_parameter(COPYBIT_TRANSFORM) */ diff --git a/libcopybit/copybit_c2d.cpp b/libcopybit/copybit_c2d.cpp index e3d6308..93f2759 100644 --- a/libcopybit/copybit_c2d.cpp +++ b/libcopybit/copybit_c2d.cpp @@ -642,22 +642,26 @@ static void set_rects(struct copybit_context_t *ctx, const struct copybit_rect_t *src, const struct copybit_rect_t *scissor) { - + // Set the target rect. if((ctx->trg_transform & C2D_TARGET_ROTATE_90) && (ctx->trg_transform & C2D_TARGET_ROTATE_180)) { /* target rotation is 270 */ c2dObject->target_rect.x = (dst->t)<<16; - c2dObject->target_rect.y = (ALIGN(ctx->fb_width,32) - (dst->r))<<16; + c2dObject->target_rect.y = ctx->fb_width?(ALIGN(ctx->fb_width,32)- dst->r):dst->r; + c2dObject->target_rect.y = c2dObject->target_rect.y<<16; c2dObject->target_rect.height = ((dst->r) - (dst->l))<<16; c2dObject->target_rect.width = ((dst->b) - (dst->t))<<16; } else if(ctx->trg_transform & C2D_TARGET_ROTATE_90) { - c2dObject->target_rect.x = (ctx->fb_height - dst->b)<<16; + c2dObject->target_rect.x = ctx->fb_height?(ctx->fb_height - dst->b):dst->b; + c2dObject->target_rect.x = c2dObject->target_rect.x<<16; c2dObject->target_rect.y = (dst->l)<<16; c2dObject->target_rect.height = ((dst->r) - (dst->l))<<16; c2dObject->target_rect.width = ((dst->b) - (dst->t))<<16; } else if(ctx->trg_transform & C2D_TARGET_ROTATE_180) { - c2dObject->target_rect.y = (ctx->fb_height - dst->b)<<16; - c2dObject->target_rect.x = (ALIGN(ctx->fb_width,32) - dst->r)<<16; + c2dObject->target_rect.y = ctx->fb_height?(ctx->fb_height - dst->b):dst->b; + c2dObject->target_rect.y = c2dObject->target_rect.y<<16; + c2dObject->target_rect.x = ctx->fb_width?(ALIGN(ctx->fb_width,32) - dst->r):dst->r; + c2dObject->target_rect.x = c2dObject->target_rect.x<<16; c2dObject->target_rect.height = ((dst->b) - (dst->t))<<16; c2dObject->target_rect.width = ((dst->r) - (dst->l))<<16; } else { @@ -668,17 +672,18 @@ static void set_rects(struct copybit_context_t *ctx, } c2dObject->config_mask |= C2D_TARGET_RECT_BIT; + // Set the source rect c2dObject->source_rect.x = (src->l)<<16; c2dObject->source_rect.y = (src->t)<<16; c2dObject->source_rect.height = ((src->b) - (src->t))<<16; c2dObject->source_rect.width = ((src->r) - (src->l))<<16; c2dObject->config_mask |= C2D_SOURCE_RECT_BIT; + // Set the scissor rect c2dObject->scissor_rect.x = scissor->l; c2dObject->scissor_rect.y = scissor->t; c2dObject->scissor_rect.height = (scissor->b) - (scissor->t); c2dObject->scissor_rect.width = (scissor->r) - (scissor->l); - c2dObject->config_mask |= C2D_SCISSOR_RECT_BIT; } @@ -761,6 +766,12 @@ static int set_parameter_copybit( (value == COPYBIT_ENABLE) ? ctx->isPremultipliedAlpha = true : ctx->isPremultipliedAlpha = false; break; + case COPYBIT_FRAMEBUFFER_WIDTH: + ctx->fb_width = value; + break; + case COPYBIT_FRAMEBUFFER_HEIGHT: + ctx->fb_height = value; + break; default: LOGE("%s: default case", __func__); return -EINVAL; @@ -969,6 +980,8 @@ static int stretch_copybit_internal( unset_image(ctx->g12_device_fd, ctx->src[src_surface_index], src, src_mapped); unset_image(ctx->g12_device_fd, ctx->dst[dst_surface_index], dst, trg_mapped); ctx->isPremultipliedAlpha = false; + ctx->fb_width = 0; + ctx->fb_height = 0; return status; } @@ -1028,13 +1041,6 @@ static int open_copybit(const struct hw_module_t* module, const char* name, C2D_RGB_SURFACE_DEF surfDefinition = {0}; C2D_YUV_SURFACE_DEF yuvSurfaceDef = {0} ; struct copybit_context_t *ctx; - char const * const device_template[] = { - "/dev/graphics/fb%u", - "/dev/fb%u", - 0 }; - - int fd = -1; - int i=0; char fbName[64]; ctx = (struct copybit_context_t *)malloc(sizeof(struct copybit_context_t)); @@ -1167,32 +1173,13 @@ static int open_copybit(const struct hw_module_t* module, const char* name, goto error; } - *device = &ctx->device.common; - - while ((fd==-1) && device_template[i]) { - snprintf(fbName, 64, device_template[i], 0); - fd = open(fbName, O_RDWR, 0); - i++; - } - if (fd < 0) - goto error; - - struct fb_var_screeninfo info; - if (ioctl(fd, FBIOGET_VSCREENINFO, &info) == -1) - goto error; - - ctx->fb_width = info.xres; - ctx->fb_height = info.yres; - close(fd); + ctx->fb_width = 0; + ctx->fb_height = 0; ctx->isPremultipliedAlpha = false; + *device = &ctx->device.common; return status; error: - if (fd >= 0) { - close(fd); - fd = -1; - } - for (int i = 0; isrc[i])) { LINK_c2dDestroySurface(ctx->src[i]);