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
						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