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:
committed by
QuIC Gerrit Code Review
commit
9cc133f454
@@ -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) */
|
||||
|
@@ -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;
|
||||
|
||||
|
Reference in New Issue
Block a user