Merge changes Ica0f7622,Ia2b4dadf into ics

* changes:
  libcopybit: Add support for setting the Framebuffer info.
  libcopybit: Add support for YUV destination targets.
This commit is contained in:
Linux Build Service Account
2011-12-09 05:05:31 -08:00
committed by QuIC Gerrit Code Review
2 changed files with 290 additions and 118 deletions

View File

@@ -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) */

View File

@@ -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;
}
@@ -547,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 {
@@ -573,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;
}
@@ -598,7 +698,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 +715,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;
}
@@ -666,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;
@@ -746,20 +852,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 +874,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 +941,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 +955,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,22 +964,24 @@ 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;
ctx->fb_width = 0;
ctx->fb_height = 0;
return status;
}
@@ -866,8 +1015,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 <NUM_SRC_SURFACES; i++) {
for(int i = 0; i <NUM_SURFACES; i++) {
LINK_c2dDestroySurface(ctx->dst[i]);
LINK_c2dDestroySurface(ctx->src[i]);
}
@@ -892,24 +1041,22 @@ 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));
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 +1076,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 +1094,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 +1106,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,48 +1136,67 @@ 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;
}
*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 (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;
}
if (fd < 0)
goto error5;
struct fb_var_screeninfo info;
if (ioctl(fd, FBIOGET_VSCREENINFO, &info) == -1)
goto error6;
yuvSurfaceDef.format = C2D_COLOR_FORMAT_420_YV12;
yuvSurfaceDef.plane2 = (void*)0xaaaaaaaa;
yuvSurfaceDef.phys2 = (void*) 0xaaaaaaaa;
yuvSurfaceDef.stride2 = 4;
ctx->fb_width = info.xres;
ctx->fb_height = info.yres;
close(fd);
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;
}
ctx->fb_width = 0;
ctx->fb_height = 0;
ctx->isPremultipliedAlpha = false;
*device = &ctx->device.common;
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);
for (int i = 0; i<NUM_SURFACES; i++) {
if (-1 != (ctx->src[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;