1 /* 2 * Copyright (C) 2008 The Android Open Source Project 3 * Copyright (c) 2010-2013, The Linux Foundation. All rights reserved. 4 * 5 * Not a Contribution, Apache license notifications and license are retained 6 * for attribution purposes only. 7 * 8 * Licensed under the Apache License, Version 2.0 (the "License"); 9 * you may not use this file except in compliance with the License. 10 * You may obtain a copy of the License at 11 * 12 * http://www.apache.org/licenses/LICENSE-2.0 13 * 14 * Unless required by applicable law or agreed to in writing, software 15 * distributed under the License is distributed on an "AS IS" BASIS, 16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 * See the License for the specific language governing permissions and 18 * limitations under the License. 19 */ 20 #include <cutils/log.h> 21 #include <sys/resource.h> 22 #include <sys/prctl.h> 23 24 #include <stdint.h> 25 #include <string.h> 26 #include <unistd.h> 27 #include <errno.h> 28 #include <fcntl.h> 29 30 #include <sys/ioctl.h> 31 #include <sys/types.h> 32 #include <sys/mman.h> 33 34 #include <linux/msm_kgsl.h> 35 36 #include <EGL/eglplatform.h> 37 #include <cutils/native_handle.h> 38 #include <cutils/ashmem.h> 39 #include <linux/ashmem.h> 40 #include <gralloc_priv.h> 41 42 #include <copybit.h> 43 #include <alloc_controller.h> 44 #include <memalloc.h> 45 46 #include "c2d2.h" 47 #include "software_converter.h" 48 49 #include <dlfcn.h> 50 51 using gralloc::IMemAlloc; 52 using gralloc::IonController; 53 using gralloc::alloc_data; 54 55 C2D_STATUS (*LINK_c2dCreateSurface)( uint32 *surface_id, 56 uint32 surface_bits, 57 C2D_SURFACE_TYPE surface_type, 58 void *surface_definition ); 59 60 C2D_STATUS (*LINK_c2dUpdateSurface)( uint32 surface_id, 61 uint32 surface_bits, 62 C2D_SURFACE_TYPE surface_type, 63 void *surface_definition ); 64 65 C2D_STATUS (*LINK_c2dReadSurface)( uint32 surface_id, 66 C2D_SURFACE_TYPE surface_type, 67 void *surface_definition, 68 int32 x, int32 y ); 69 70 C2D_STATUS (*LINK_c2dDraw)( uint32 target_id, 71 uint32 target_config, C2D_RECT *target_scissor, 72 uint32 target_mask_id, uint32 target_color_key, 73 C2D_OBJECT *objects_list, uint32 num_objects ); 74 75 C2D_STATUS (*LINK_c2dFinish)( uint32 target_id); 76 77 C2D_STATUS (*LINK_c2dFlush)( uint32 target_id, c2d_ts_handle *timestamp); 78 79 C2D_STATUS (*LINK_c2dWaitTimestamp)( c2d_ts_handle timestamp ); 80 81 C2D_STATUS (*LINK_c2dDestroySurface)( uint32 surface_id ); 82 83 C2D_STATUS (*LINK_c2dMapAddr) ( int mem_fd, void * hostptr, uint32 len, 84 uint32 offset, uint32 flags, void ** gpuaddr); 85 86 C2D_STATUS (*LINK_c2dUnMapAddr) ( void * gpuaddr); 87 88 C2D_STATUS (*LINK_c2dGetDriverCapabilities) ( C2D_DRIVER_INFO * driver_info); 89 90 /* create a fence fd for the timestamp */ 91 C2D_STATUS (*LINK_c2dCreateFenceFD) ( uint32 target_id, c2d_ts_handle timestamp, 92 int32 *fd); 93 94 C2D_STATUS (*LINK_c2dFillSurface) ( uint32 surface_id, uint32 fill_color, 95 C2D_RECT * fill_rect); 96 97 /******************************************************************************/ 98 99 #if defined(COPYBIT_Z180) 100 #define MAX_SCALE_FACTOR (4096) 101 #define MAX_DIMENSION (4096) 102 #else 103 #error "Unsupported HW version" 104 #endif 105 106 // The following defines can be changed as required i.e. as we encounter 107 // complex use cases. 108 #define MAX_RGB_SURFACES 8 // Max. RGB layers currently supported per draw 109 #define MAX_YUV_2_PLANE_SURFACES 4// Max. 2-plane YUV layers currently supported per draw 110 #define MAX_YUV_3_PLANE_SURFACES 1// Max. 3-plane YUV layers currently supported per draw 111 // +1 for the destination surface. We cannot have multiple destination surfaces. 112 #define MAX_SURFACES (MAX_RGB_SURFACES + MAX_YUV_2_PLANE_SURFACES + MAX_YUV_3_PLANE_SURFACES + 1) 113 #define NUM_SURFACE_TYPES 3 // RGB_SURFACE + YUV_SURFACE_2_PLANES + YUV_SURFACE_3_PLANES 114 #define MAX_BLIT_OBJECT_COUNT 50 // Max. blit objects that can be passed per draw 115 116 enum { 117 RGB_SURFACE, 118 YUV_SURFACE_2_PLANES, 119 YUV_SURFACE_3_PLANES 120 }; 121 122 enum eConversionType { 123 CONVERT_TO_ANDROID_FORMAT, 124 CONVERT_TO_C2D_FORMAT 125 }; 126 127 enum eC2DFlags { 128 FLAGS_PREMULTIPLIED_ALPHA = 1<<0, 129 FLAGS_YUV_DESTINATION = 1<<1, 130 FLAGS_TEMP_SRC_DST = 1<<2 131 }; 132 133 static gralloc::IAllocController* sAlloc = 0; 134 /******************************************************************************/ 135 136 /** State information for each device instance */ 137 struct copybit_context_t { 138 struct copybit_device_t device; 139 // Templates for the various source surfaces. These templates are created 140 // to avoid the expensive create/destroy C2D Surfaces 141 C2D_OBJECT_STR blit_rgb_object[MAX_RGB_SURFACES]; 142 C2D_OBJECT_STR blit_yuv_2_plane_object[MAX_YUV_2_PLANE_SURFACES]; 143 C2D_OBJECT_STR blit_yuv_3_plane_object[MAX_YUV_3_PLANE_SURFACES]; 144 C2D_OBJECT_STR blit_list[MAX_BLIT_OBJECT_COUNT]; // Z-ordered list of blit objects 145 C2D_DRIVER_INFO c2d_driver_info; 146 void *libc2d2; 147 alloc_data temp_src_buffer; 148 alloc_data temp_dst_buffer; 149 unsigned int dst[NUM_SURFACE_TYPES]; // dst surfaces 150 unsigned int mapped_gpu_addr[MAX_SURFACES]; // GPU addresses mapped inside copybit 151 int blit_rgb_count; // Total RGB surfaces being blit 152 int blit_yuv_2_plane_count; // Total 2 plane YUV surfaces being 153 int blit_yuv_3_plane_count; // Total 3 plane YUV surfaces being blit 154 int blit_count; // Total blit objects. 155 unsigned int trg_transform; /* target transform */ 156 int fb_width; 157 int fb_height; 158 int src_global_alpha; 159 int config_mask; 160 int dst_surface_type; 161 bool is_premultiplied_alpha; 162 void* time_stamp; 163 164 // used for signaling the wait thread 165 bool wait_timestamp; 166 pthread_t wait_thread_id; 167 bool stop_thread; 168 pthread_mutex_t wait_cleanup_lock; 169 pthread_cond_t wait_cleanup_cond; 170 171 }; 172 173 struct bufferInfo { 174 int width; 175 int height; 176 int format; 177 }; 178 179 struct yuvPlaneInfo { 180 int yStride; //luma stride 181 int plane1_stride; 182 int plane2_stride; 183 int plane1_offset; 184 int plane2_offset; 185 }; 186 187 /** 188 * Common hardware methods 189 */ 190 191 static int open_copybit(const struct hw_module_t* module, const char* name, 192 struct hw_device_t** device); 193 194 static struct hw_module_methods_t copybit_module_methods = { 195 open: open_copybit 196 }; 197 198 /* 199 * The COPYBIT Module 200 */ 201 struct copybit_module_t HAL_MODULE_INFO_SYM = { 202 common: { 203 tag: HARDWARE_MODULE_TAG, 204 version_major: 1, 205 version_minor: 0, 206 id: COPYBIT_HARDWARE_MODULE_ID, 207 name: "QCT COPYBIT C2D 2.0 Module", 208 author: "Qualcomm", 209 methods: ©bit_module_methods 210 } 211 }; 212 213 214 /* thread function which waits on the timeStamp and cleans up the surfaces */ 215 static void* c2d_wait_loop(void* ptr) { 216 copybit_context_t* ctx = (copybit_context_t*)(ptr); 217 char thread_name[64] = "copybitWaitThr"; 218 prctl(PR_SET_NAME, (unsigned long) &thread_name, 0, 0, 0); 219 setpriority(PRIO_PROCESS, 0, HAL_PRIORITY_URGENT_DISPLAY); 220 221 while(ctx->stop_thread == false) { 222 pthread_mutex_lock(&ctx->wait_cleanup_lock); 223 while(ctx->wait_timestamp == false && !ctx->stop_thread) { 224 pthread_cond_wait(&(ctx->wait_cleanup_cond), 225 &(ctx->wait_cleanup_lock)); 226 } 227 if(ctx->wait_timestamp) { 228 if(LINK_c2dWaitTimestamp(ctx->time_stamp)) { 229 ALOGE("%s: LINK_c2dWaitTimeStamp ERROR!!", __FUNCTION__); 230 } 231 ctx->wait_timestamp = false; 232 // Unmap any mapped addresses. 233 for (int i = 0; i < MAX_SURFACES; i++) { 234 if (ctx->mapped_gpu_addr[i]) { 235 LINK_c2dUnMapAddr( (void*)ctx->mapped_gpu_addr[i]); 236 ctx->mapped_gpu_addr[i] = 0; 237 } 238 } 239 // Reset the counts after the draw. 240 ctx->blit_rgb_count = 0; 241 ctx->blit_yuv_2_plane_count = 0; 242 ctx->blit_yuv_3_plane_count = 0; 243 ctx->blit_count = 0; 244 } 245 pthread_mutex_unlock(&ctx->wait_cleanup_lock); 246 if(ctx->stop_thread) 247 break; 248 } 249 pthread_exit(NULL); 250 return NULL; 251 } 252 253 254 /* convert COPYBIT_FORMAT to C2D format */ 255 static int get_format(int format) { 256 switch (format) { 257 case HAL_PIXEL_FORMAT_RGB_565: return C2D_COLOR_FORMAT_565_RGB; 258 case HAL_PIXEL_FORMAT_RGBX_8888: return C2D_COLOR_FORMAT_8888_ARGB | 259 C2D_FORMAT_SWAP_RB | 260 C2D_FORMAT_DISABLE_ALPHA; 261 case HAL_PIXEL_FORMAT_RGBA_8888: return C2D_COLOR_FORMAT_8888_ARGB | 262 C2D_FORMAT_SWAP_RB; 263 case HAL_PIXEL_FORMAT_BGRA_8888: return C2D_COLOR_FORMAT_8888_ARGB; 264 case HAL_PIXEL_FORMAT_RGBA_5551: return C2D_COLOR_FORMAT_5551_RGBA; 265 case HAL_PIXEL_FORMAT_RGBA_4444: return C2D_COLOR_FORMAT_4444_RGBA; 266 case HAL_PIXEL_FORMAT_YCbCr_420_SP: return C2D_COLOR_FORMAT_420_NV12; 267 case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:return C2D_COLOR_FORMAT_420_NV12; 268 case HAL_PIXEL_FORMAT_YCrCb_420_SP: return C2D_COLOR_FORMAT_420_NV21; 269 case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED: return C2D_COLOR_FORMAT_420_NV12 | 270 C2D_FORMAT_MACROTILED; 271 default: ALOGE("%s: invalid format (0x%x", 272 __FUNCTION__, format); 273 return -EINVAL; 274 } 275 return -EINVAL; 276 } 277 278 /* Get the C2D formats needed for conversion to YUV */ 279 static int get_c2d_format_for_yuv_destination(int halFormat) { 280 switch (halFormat) { 281 // We do not swap the RB when the target is YUV 282 case HAL_PIXEL_FORMAT_RGBX_8888: return C2D_COLOR_FORMAT_8888_ARGB | 283 C2D_FORMAT_DISABLE_ALPHA; 284 case HAL_PIXEL_FORMAT_RGBA_8888: return C2D_COLOR_FORMAT_8888_ARGB; 285 // The U and V need to be interchanged when the target is YUV 286 case HAL_PIXEL_FORMAT_YCbCr_420_SP: return C2D_COLOR_FORMAT_420_NV21; 287 case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:return C2D_COLOR_FORMAT_420_NV21; 288 case HAL_PIXEL_FORMAT_YCrCb_420_SP: return C2D_COLOR_FORMAT_420_NV12; 289 default: return get_format(halFormat); 290 } 291 return -EINVAL; 292 } 293 294 /* ------------------------------------------------------------------- *//*! 295 * \internal 296 * \brief Get the bpp for a particular color format 297 * \param color format 298 * \return bits per pixel 299 *//* ------------------------------------------------------------------- */ 300 int c2diGetBpp(int32 colorformat) 301 { 302 303 int c2dBpp = 0; 304 305 switch(colorformat&0xFF) 306 { 307 case C2D_COLOR_FORMAT_4444_RGBA: 308 case C2D_COLOR_FORMAT_4444_ARGB: 309 case C2D_COLOR_FORMAT_1555_ARGB: 310 case C2D_COLOR_FORMAT_565_RGB: 311 case C2D_COLOR_FORMAT_5551_RGBA: 312 c2dBpp = 16; 313 break; 314 case C2D_COLOR_FORMAT_8888_RGBA: 315 case C2D_COLOR_FORMAT_8888_ARGB: 316 c2dBpp = 32; 317 break; 318 case C2D_COLOR_FORMAT_8_L: 319 case C2D_COLOR_FORMAT_8_A: 320 c2dBpp = 8; 321 break; 322 case C2D_COLOR_FORMAT_4_A: 323 c2dBpp = 4; 324 break; 325 case C2D_COLOR_FORMAT_1: 326 c2dBpp = 1; 327 break; 328 default: 329 ALOGE("%s ERROR", __func__); 330 break; 331 } 332 return c2dBpp; 333 } 334 335 static uint32 c2d_get_gpuaddr(copybit_context_t* ctx, struct private_handle_t *handle, 336 int &mapped_idx) 337 { 338 uint32 memtype, *gpuaddr; 339 C2D_STATUS rc; 340 341 if(!handle) 342 return 0; 343 344 if (handle->flags & (private_handle_t::PRIV_FLAGS_USES_PMEM | 345 private_handle_t::PRIV_FLAGS_USES_PMEM_ADSP)) 346 memtype = KGSL_USER_MEM_TYPE_PMEM; 347 else if (handle->flags & private_handle_t::PRIV_FLAGS_USES_ASHMEM) 348 memtype = KGSL_USER_MEM_TYPE_ASHMEM; 349 else if (handle->flags & private_handle_t::PRIV_FLAGS_USES_ION) 350 memtype = KGSL_USER_MEM_TYPE_ION; 351 else { 352 ALOGE("Invalid handle flags: 0x%x", handle->flags); 353 return 0; 354 } 355 356 rc = LINK_c2dMapAddr(handle->fd, (void*)handle->base, handle->size, 357 handle->offset, memtype, (void**)&gpuaddr); 358 359 if (rc == C2D_STATUS_OK) { 360 // We have mapped the GPU address inside copybit. We need to unmap this 361 // address after the blit. Store this address 362 for (int i = 0; i < MAX_SURFACES; i++) { 363 if (ctx->mapped_gpu_addr[i] == 0) { 364 ctx->mapped_gpu_addr[i] = (uint32) gpuaddr; 365 mapped_idx = i; 366 break; 367 } 368 } 369 370 return (uint32) gpuaddr; 371 } 372 return 0; 373 } 374 375 static void unmap_gpuaddr(copybit_context_t* ctx, int mapped_idx) 376 { 377 if (!ctx || (mapped_idx == -1)) 378 return; 379 380 if (ctx->mapped_gpu_addr[mapped_idx]) { 381 LINK_c2dUnMapAddr( (void*)ctx->mapped_gpu_addr[mapped_idx]); 382 ctx->mapped_gpu_addr[mapped_idx] = 0; 383 } 384 } 385 386 static int is_supported_rgb_format(int format) 387 { 388 switch(format) { 389 case HAL_PIXEL_FORMAT_RGBA_8888: 390 case HAL_PIXEL_FORMAT_RGBX_8888: 391 case HAL_PIXEL_FORMAT_RGB_565: 392 case HAL_PIXEL_FORMAT_BGRA_8888: 393 case HAL_PIXEL_FORMAT_RGBA_5551: 394 case HAL_PIXEL_FORMAT_RGBA_4444: { 395 return COPYBIT_SUCCESS; 396 } 397 default: 398 return COPYBIT_FAILURE; 399 } 400 } 401 402 static int get_num_planes(int format) 403 { 404 switch(format) { 405 case HAL_PIXEL_FORMAT_YCbCr_420_SP: 406 case HAL_PIXEL_FORMAT_YCrCb_420_SP: 407 case HAL_PIXEL_FORMAT_NV12_ENCODEABLE: 408 case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED: { 409 return 2; 410 } 411 case HAL_PIXEL_FORMAT_YV12: { 412 return 3; 413 } 414 default: 415 return COPYBIT_FAILURE; 416 } 417 } 418 419 static int is_supported_yuv_format(int format) 420 { 421 switch(format) { 422 case HAL_PIXEL_FORMAT_YCbCr_420_SP: 423 case HAL_PIXEL_FORMAT_YCrCb_420_SP: 424 case HAL_PIXEL_FORMAT_NV12_ENCODEABLE: 425 case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED: { 426 return COPYBIT_SUCCESS; 427 } 428 default: 429 return COPYBIT_FAILURE; 430 } 431 } 432 433 static int is_valid_destination_format(int format) 434 { 435 if (format == HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED) { 436 // C2D does not support NV12Tile as a destination format. 437 return COPYBIT_FAILURE; 438 } 439 return COPYBIT_SUCCESS; 440 } 441 442 static int calculate_yuv_offset_and_stride(const bufferInfo& info, 443 yuvPlaneInfo& yuvInfo) 444 { 445 int width = info.width; 446 int height = info.height; 447 int format = info.format; 448 449 int aligned_height = 0; 450 int aligned_width = 0, size = 0; 451 452 switch (format) { 453 case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED: { 454 /* NV12 Tile buffers have their luma height aligned to 32bytes and width 455 * aligned to 128 bytes. The chroma offset starts at an 8K boundary 456 */ 457 aligned_height = ALIGN(height, 32); 458 aligned_width = ALIGN(width, 128); 459 size = aligned_width * aligned_height; 460 yuvInfo.plane1_offset = ALIGN(size,8192); 461 yuvInfo.yStride = aligned_width; 462 yuvInfo.plane1_stride = aligned_width; 463 break; 464 } 465 case HAL_PIXEL_FORMAT_YCbCr_420_SP: 466 case HAL_PIXEL_FORMAT_NV12_ENCODEABLE: 467 case HAL_PIXEL_FORMAT_YCrCb_420_SP: { 468 aligned_width = ALIGN(width, 32); 469 yuvInfo.yStride = aligned_width; 470 yuvInfo.plane1_stride = aligned_width; 471 if (HAL_PIXEL_FORMAT_NV12_ENCODEABLE == format) { 472 // The encoder requires a 2K aligned chroma offset 473 yuvInfo.plane1_offset = ALIGN(aligned_width * height, 2048); 474 } else 475 yuvInfo.plane1_offset = aligned_width * height; 476 477 break; 478 } 479 default: { 480 return COPYBIT_FAILURE; 481 } 482 } 483 return COPYBIT_SUCCESS; 484 } 485 486 /** create C2D surface from copybit image */ 487 static int set_image(copybit_context_t* ctx, uint32 surfaceId, 488 const struct copybit_image_t *rhs, 489 const eC2DFlags flags, int &mapped_idx) 490 { 491 struct private_handle_t* handle = (struct private_handle_t*)rhs->handle; 492 C2D_SURFACE_TYPE surfaceType; 493 int status = COPYBIT_SUCCESS; 494 uint32 gpuaddr = 0; 495 int c2d_format; 496 mapped_idx = -1; 497 498 if (flags & FLAGS_YUV_DESTINATION) { 499 c2d_format = get_c2d_format_for_yuv_destination(rhs->format); 500 } else { 501 c2d_format = get_format(rhs->format); 502 } 503 504 if(c2d_format == -EINVAL) { 505 ALOGE("%s: invalid format", __FUNCTION__); 506 return -EINVAL; 507 } 508 509 if(handle == NULL) { 510 ALOGE("%s: invalid handle", __func__); 511 return -EINVAL; 512 } 513 514 if (handle->gpuaddr == 0) { 515 gpuaddr = c2d_get_gpuaddr(ctx, handle, mapped_idx); 516 if(!gpuaddr) { 517 ALOGE("%s: c2d_get_gpuaddr failed", __FUNCTION__); 518 return COPYBIT_FAILURE; 519 } 520 } else { 521 gpuaddr = handle->gpuaddr; 522 } 523 524 /* create C2D surface */ 525 if(is_supported_rgb_format(rhs->format) == COPYBIT_SUCCESS) { 526 /* RGB */ 527 C2D_RGB_SURFACE_DEF surfaceDef; 528 529 surfaceType = (C2D_SURFACE_TYPE) (C2D_SURFACE_RGB_HOST | C2D_SURFACE_WITH_PHYS); 530 531 surfaceDef.phys = (void*) gpuaddr; 532 surfaceDef.buffer = (void*) (handle->base); 533 534 surfaceDef.format = c2d_format | 535 ((flags & FLAGS_PREMULTIPLIED_ALPHA) ? C2D_FORMAT_PREMULTIPLIED : 0); 536 surfaceDef.width = rhs->w; 537 surfaceDef.height = rhs->h; 538 int aligned_width = ALIGN(surfaceDef.width,32); 539 surfaceDef.stride = (aligned_width * c2diGetBpp(surfaceDef.format))>>3; 540 541 if(LINK_c2dUpdateSurface( surfaceId,C2D_TARGET | C2D_SOURCE, surfaceType, 542 &surfaceDef)) { 543 ALOGE("%s: RGB Surface c2dUpdateSurface ERROR", __FUNCTION__); 544 unmap_gpuaddr(ctx, mapped_idx); 545 status = COPYBIT_FAILURE; 546 } 547 } else if (is_supported_yuv_format(rhs->format) == COPYBIT_SUCCESS) { 548 C2D_YUV_SURFACE_DEF surfaceDef; 549 memset(&surfaceDef, 0, sizeof(surfaceDef)); 550 surfaceType = (C2D_SURFACE_TYPE)(C2D_SURFACE_YUV_HOST | C2D_SURFACE_WITH_PHYS); 551 surfaceDef.format = c2d_format; 552 553 bufferInfo info; 554 info.width = rhs->w; 555 info.height = rhs->h; 556 info.format = rhs->format; 557 558 yuvPlaneInfo yuvInfo = {0}; 559 status = calculate_yuv_offset_and_stride(info, yuvInfo); 560 if(status != COPYBIT_SUCCESS) { 561 ALOGE("%s: calculate_yuv_offset_and_stride error", __FUNCTION__); 562 unmap_gpuaddr(ctx, mapped_idx); 563 } 564 565 surfaceDef.width = rhs->w; 566 surfaceDef.height = rhs->h; 567 surfaceDef.plane0 = (void*) (handle->base); 568 surfaceDef.phys0 = (void*) (gpuaddr); 569 surfaceDef.stride0 = yuvInfo.yStride; 570 571 surfaceDef.plane1 = (void*) (handle->base + yuvInfo.plane1_offset); 572 surfaceDef.phys1 = (void*) (gpuaddr + yuvInfo.plane1_offset); 573 surfaceDef.stride1 = yuvInfo.plane1_stride; 574 if (3 == get_num_planes(rhs->format)) { 575 surfaceDef.plane2 = (void*) (handle->base + yuvInfo.plane2_offset); 576 surfaceDef.phys2 = (void*) (gpuaddr + yuvInfo.plane2_offset); 577 surfaceDef.stride2 = yuvInfo.plane2_stride; 578 } 579 580 if(LINK_c2dUpdateSurface( surfaceId,C2D_TARGET | C2D_SOURCE, surfaceType, 581 &surfaceDef)) { 582 ALOGE("%s: YUV Surface c2dUpdateSurface ERROR", __FUNCTION__); 583 unmap_gpuaddr(ctx, mapped_idx); 584 status = COPYBIT_FAILURE; 585 } 586 } else { 587 ALOGE("%s: invalid format 0x%x", __FUNCTION__, rhs->format); 588 unmap_gpuaddr(ctx, mapped_idx); 589 status = COPYBIT_FAILURE; 590 } 591 592 return status; 593 } 594 595 /** copy the bits */ 596 static int msm_copybit(struct copybit_context_t *ctx, unsigned int target) 597 { 598 if (ctx->blit_count == 0) { 599 return COPYBIT_SUCCESS; 600 } 601 602 for (int i = 0; i < ctx->blit_count; i++) 603 { 604 ctx->blit_list[i].next = &(ctx->blit_list[i+1]); 605 } 606 ctx->blit_list[ctx->blit_count-1].next = NULL; 607 uint32_t target_transform = ctx->trg_transform; 608 if (ctx->c2d_driver_info.capabilities_mask & 609 C2D_DRIVER_SUPPORTS_OVERRIDE_TARGET_ROTATE_OP) { 610 // For A3xx - set 0x0 as the transform is set in the config_mask 611 target_transform = 0x0; 612 } 613 if(LINK_c2dDraw(target, target_transform, 0x0, 0, 0, ctx->blit_list, 614 ctx->blit_count)) { 615 ALOGE("%s: LINK_c2dDraw ERROR", __FUNCTION__); 616 return COPYBIT_FAILURE; 617 } 618 return COPYBIT_SUCCESS; 619 } 620 621 622 623 static int flush_get_fence_copybit (struct copybit_device_t *dev, int* fd) 624 { 625 struct copybit_context_t* ctx = (struct copybit_context_t*)dev; 626 int status = COPYBIT_FAILURE; 627 if (!ctx) 628 return COPYBIT_FAILURE; 629 pthread_mutex_lock(&ctx->wait_cleanup_lock); 630 status = msm_copybit(ctx, ctx->dst[ctx->dst_surface_type]); 631 632 if(LINK_c2dFlush(ctx->dst[ctx->dst_surface_type], &ctx->time_stamp)) { 633 ALOGE("%s: LINK_c2dFlush ERROR", __FUNCTION__); 634 // unlock the mutex and return failure 635 pthread_mutex_unlock(&ctx->wait_cleanup_lock); 636 return COPYBIT_FAILURE; 637 } 638 if(LINK_c2dCreateFenceFD(ctx->dst[ctx->dst_surface_type], ctx->time_stamp, 639 fd)) { 640 ALOGE("%s: LINK_c2dCreateFenceFD ERROR", __FUNCTION__); 641 status = COPYBIT_FAILURE; 642 } 643 if(status == COPYBIT_SUCCESS) { 644 //signal the wait_thread 645 ctx->wait_timestamp = true; 646 pthread_cond_signal(&ctx->wait_cleanup_cond); 647 } 648 pthread_mutex_unlock(&ctx->wait_cleanup_lock); 649 return status; 650 } 651 652 static int finish_copybit(struct copybit_device_t *dev) 653 { 654 struct copybit_context_t* ctx = (struct copybit_context_t*)dev; 655 if (!ctx) 656 return COPYBIT_FAILURE; 657 658 int status = msm_copybit(ctx, ctx->dst[ctx->dst_surface_type]); 659 660 if(LINK_c2dFinish(ctx->dst[ctx->dst_surface_type])) { 661 ALOGE("%s: LINK_c2dFinish ERROR", __FUNCTION__); 662 return COPYBIT_FAILURE; 663 } 664 665 // Unmap any mapped addresses. 666 for (int i = 0; i < MAX_SURFACES; i++) { 667 if (ctx->mapped_gpu_addr[i]) { 668 LINK_c2dUnMapAddr( (void*)ctx->mapped_gpu_addr[i]); 669 ctx->mapped_gpu_addr[i] = 0; 670 } 671 } 672 673 // Reset the counts after the draw. 674 ctx->blit_rgb_count = 0; 675 ctx->blit_yuv_2_plane_count = 0; 676 ctx->blit_yuv_3_plane_count = 0; 677 ctx->blit_count = 0; 678 return status; 679 } 680 681 static int clear_copybit(struct copybit_device_t *dev, 682 struct copybit_image_t const *buf, 683 struct copybit_rect_t *rect) 684 { 685 int ret = COPYBIT_SUCCESS; 686 int flags = FLAGS_PREMULTIPLIED_ALPHA; 687 int mapped_dst_idx = -1; 688 struct copybit_context_t* ctx = (struct copybit_context_t*)dev; 689 C2D_RECT c2drect = {rect->l, rect->t, rect->r - rect->l, rect->b - rect->t}; 690 pthread_mutex_lock(&ctx->wait_cleanup_lock); 691 ret = set_image(ctx, ctx->dst[RGB_SURFACE], buf, 692 (eC2DFlags)flags, mapped_dst_idx); 693 if(ret) { 694 ALOGE("%s: set_image error", __FUNCTION__); 695 unmap_gpuaddr(ctx, mapped_dst_idx); 696 pthread_mutex_unlock(&ctx->wait_cleanup_lock); 697 return COPYBIT_FAILURE; 698 } 699 700 ret = LINK_c2dFillSurface(ctx->dst[RGB_SURFACE], 0x0, &c2drect); 701 pthread_mutex_unlock(&ctx->wait_cleanup_lock); 702 return ret; 703 } 704 705 706 /** setup rectangles */ 707 static void set_rects(struct copybit_context_t *ctx, 708 C2D_OBJECT *c2dObject, 709 const struct copybit_rect_t *dst, 710 const struct copybit_rect_t *src, 711 const struct copybit_rect_t *scissor) 712 { 713 // Set the target rect. 714 if((ctx->trg_transform & C2D_TARGET_ROTATE_90) && 715 (ctx->trg_transform & C2D_TARGET_ROTATE_180)) { 716 /* target rotation is 270 */ 717 c2dObject->target_rect.x = (dst->t)<<16; 718 c2dObject->target_rect.y = ctx->fb_width?(ALIGN(ctx->fb_width,32)- dst->r):dst->r; 719 c2dObject->target_rect.y = c2dObject->target_rect.y<<16; 720 c2dObject->target_rect.height = ((dst->r) - (dst->l))<<16; 721 c2dObject->target_rect.width = ((dst->b) - (dst->t))<<16; 722 } else if(ctx->trg_transform & C2D_TARGET_ROTATE_90) { 723 c2dObject->target_rect.x = ctx->fb_height?(ctx->fb_height - dst->b):dst->b; 724 c2dObject->target_rect.x = c2dObject->target_rect.x<<16; 725 c2dObject->target_rect.y = (dst->l)<<16; 726 c2dObject->target_rect.height = ((dst->r) - (dst->l))<<16; 727 c2dObject->target_rect.width = ((dst->b) - (dst->t))<<16; 728 } else if(ctx->trg_transform & C2D_TARGET_ROTATE_180) { 729 c2dObject->target_rect.y = ctx->fb_height?(ctx->fb_height - dst->b):dst->b; 730 c2dObject->target_rect.y = c2dObject->target_rect.y<<16; 731 c2dObject->target_rect.x = ctx->fb_width?(ALIGN(ctx->fb_width,32) - dst->r):dst->r; 732 c2dObject->target_rect.x = c2dObject->target_rect.x<<16; 733 c2dObject->target_rect.height = ((dst->b) - (dst->t))<<16; 734 c2dObject->target_rect.width = ((dst->r) - (dst->l))<<16; 735 } else { 736 c2dObject->target_rect.x = (dst->l)<<16; 737 c2dObject->target_rect.y = (dst->t)<<16; 738 c2dObject->target_rect.height = ((dst->b) - (dst->t))<<16; 739 c2dObject->target_rect.width = ((dst->r) - (dst->l))<<16; 740 } 741 c2dObject->config_mask |= C2D_TARGET_RECT_BIT; 742 743 // Set the source rect 744 c2dObject->source_rect.x = (src->l)<<16; 745 c2dObject->source_rect.y = (src->t)<<16; 746 c2dObject->source_rect.height = ((src->b) - (src->t))<<16; 747 c2dObject->source_rect.width = ((src->r) - (src->l))<<16; 748 c2dObject->config_mask |= C2D_SOURCE_RECT_BIT; 749 750 // Set the scissor rect 751 c2dObject->scissor_rect.x = scissor->l; 752 c2dObject->scissor_rect.y = scissor->t; 753 c2dObject->scissor_rect.height = (scissor->b) - (scissor->t); 754 c2dObject->scissor_rect.width = (scissor->r) - (scissor->l); 755 c2dObject->config_mask |= C2D_SCISSOR_RECT_BIT; 756 } 757 758 /*****************************************************************************/ 759 760 /** Set a parameter to value */ 761 static int set_parameter_copybit( 762 struct copybit_device_t *dev, 763 int name, 764 int value) 765 { 766 struct copybit_context_t* ctx = (struct copybit_context_t*)dev; 767 int status = COPYBIT_SUCCESS; 768 if (!ctx) { 769 ALOGE("%s: null context", __FUNCTION__); 770 return -EINVAL; 771 } 772 773 pthread_mutex_lock(&ctx->wait_cleanup_lock); 774 switch(name) { 775 case COPYBIT_PLANE_ALPHA: 776 { 777 if (value < 0) value = 0; 778 if (value >= 256) value = 255; 779 780 ctx->src_global_alpha = value; 781 if (value < 255) 782 ctx->config_mask |= C2D_GLOBAL_ALPHA_BIT; 783 else 784 ctx->config_mask &= ~C2D_GLOBAL_ALPHA_BIT; 785 } 786 break; 787 case COPYBIT_BLEND_MODE: 788 { 789 if (value == COPYBIT_BLENDING_NONE) { 790 ctx->config_mask |= C2D_ALPHA_BLEND_NONE; 791 ctx->is_premultiplied_alpha = true; 792 } else if (value == COPYBIT_BLENDING_PREMULT) { 793 ctx->is_premultiplied_alpha = true; 794 } else { 795 ctx->config_mask &= ~C2D_ALPHA_BLEND_NONE; 796 } 797 } 798 break; 799 case COPYBIT_TRANSFORM: 800 { 801 unsigned int transform = 0; 802 uint32 config_mask = 0; 803 config_mask |= C2D_OVERRIDE_GLOBAL_TARGET_ROTATE_CONFIG; 804 if((value & 0x7) == COPYBIT_TRANSFORM_ROT_180) { 805 transform = C2D_TARGET_ROTATE_180; 806 config_mask |= C2D_OVERRIDE_TARGET_ROTATE_180; 807 } else if((value & 0x7) == COPYBIT_TRANSFORM_ROT_270) { 808 transform = C2D_TARGET_ROTATE_90; 809 config_mask |= C2D_OVERRIDE_TARGET_ROTATE_90; 810 } else if(value == COPYBIT_TRANSFORM_ROT_90) { 811 transform = C2D_TARGET_ROTATE_270; 812 config_mask |= C2D_OVERRIDE_TARGET_ROTATE_270; 813 } else { 814 config_mask |= C2D_OVERRIDE_TARGET_ROTATE_0; 815 if(value & COPYBIT_TRANSFORM_FLIP_H) { 816 config_mask |= C2D_MIRROR_H_BIT; 817 } else if(value & COPYBIT_TRANSFORM_FLIP_V) { 818 config_mask |= C2D_MIRROR_V_BIT; 819 } 820 } 821 822 if (ctx->c2d_driver_info.capabilities_mask & 823 C2D_DRIVER_SUPPORTS_OVERRIDE_TARGET_ROTATE_OP) { 824 ctx->config_mask |= config_mask; 825 } else { 826 // The transform for this surface does not match the current 827 // target transform. Draw all previous surfaces. This will be 828 // changed once we have a new mechanism to send different 829 // target rotations to c2d. 830 finish_copybit(dev); 831 } 832 ctx->trg_transform = transform; 833 } 834 break; 835 case COPYBIT_FRAMEBUFFER_WIDTH: 836 ctx->fb_width = value; 837 break; 838 case COPYBIT_FRAMEBUFFER_HEIGHT: 839 ctx->fb_height = value; 840 break; 841 case COPYBIT_ROTATION_DEG: 842 case COPYBIT_DITHER: 843 case COPYBIT_BLUR: 844 case COPYBIT_BLIT_TO_FRAMEBUFFER: 845 // Do nothing 846 break; 847 default: 848 ALOGE("%s: default case param=0x%x", __FUNCTION__, name); 849 status = -EINVAL; 850 break; 851 } 852 pthread_mutex_unlock(&ctx->wait_cleanup_lock); 853 return status; 854 } 855 856 /** Get a static info value */ 857 static int get(struct copybit_device_t *dev, int name) 858 { 859 struct copybit_context_t* ctx = (struct copybit_context_t*)dev; 860 int value; 861 862 if (!ctx) { 863 ALOGE("%s: null context error", __FUNCTION__); 864 return -EINVAL; 865 } 866 867 switch(name) { 868 case COPYBIT_MINIFICATION_LIMIT: 869 value = MAX_SCALE_FACTOR; 870 break; 871 case COPYBIT_MAGNIFICATION_LIMIT: 872 value = MAX_SCALE_FACTOR; 873 break; 874 case COPYBIT_SCALING_FRAC_BITS: 875 value = 32; 876 break; 877 case COPYBIT_ROTATION_STEP_DEG: 878 value = 1; 879 break; 880 default: 881 ALOGE("%s: default case param=0x%x", __FUNCTION__, name); 882 value = -EINVAL; 883 } 884 return value; 885 } 886 887 static int is_alpha(int cformat) 888 { 889 int alpha = 0; 890 switch (cformat & 0xFF) { 891 case C2D_COLOR_FORMAT_8888_ARGB: 892 case C2D_COLOR_FORMAT_8888_RGBA: 893 case C2D_COLOR_FORMAT_5551_RGBA: 894 case C2D_COLOR_FORMAT_4444_ARGB: 895 alpha = 1; 896 break; 897 default: 898 alpha = 0; 899 break; 900 } 901 902 if(alpha && (cformat&C2D_FORMAT_DISABLE_ALPHA)) 903 alpha = 0; 904 905 return alpha; 906 } 907 908 /* Function to check if we need a temporary buffer for the blit. 909 * This would happen if the requested destination stride and the 910 * C2D stride do not match. We ignore RGB buffers, since their 911 * stride is always aligned to 32. 912 */ 913 static bool need_temp_buffer(struct copybit_image_t const *img) 914 { 915 if (COPYBIT_SUCCESS == is_supported_rgb_format(img->format)) 916 return false; 917 918 struct private_handle_t* handle = (struct private_handle_t*)img->handle; 919 920 // The width parameter in the handle contains the aligned_w. We check if we 921 // need to convert based on this param. YUV formats have bpp=1, so checking 922 // if the requested stride is aligned should suffice. 923 if (0 == (handle->width)%32) { 924 return false; 925 } 926 927 return true; 928 } 929 930 /* Function to extract the information from the copybit image and set the corresponding 931 * values in the bufferInfo struct. 932 */ 933 static void populate_buffer_info(struct copybit_image_t const *img, bufferInfo& info) 934 { 935 info.width = img->w; 936 info.height = img->h; 937 info.format = img->format; 938 } 939 940 /* Function to get the required size for a particular format, inorder for C2D to perform 941 * the blit operation. 942 */ 943 static size_t get_size(const bufferInfo& info) 944 { 945 size_t size = 0; 946 int w = info.width; 947 int h = info.height; 948 int aligned_w = ALIGN(w, 32); 949 switch(info.format) { 950 case HAL_PIXEL_FORMAT_NV12_ENCODEABLE: 951 { 952 // Chroma for this format is aligned to 2K. 953 size = ALIGN((aligned_w*h), 2048) + 954 ALIGN(aligned_w/2, 32) * (h/2) *2; 955 size = ALIGN(size, 4096); 956 } break; 957 case HAL_PIXEL_FORMAT_YCbCr_420_SP: 958 case HAL_PIXEL_FORMAT_YCrCb_420_SP: 959 { 960 size = aligned_w * h + 961 ALIGN(aligned_w/2, 32) * (h/2) * 2; 962 size = ALIGN(size, 4096); 963 } break; 964 default: break; 965 } 966 return size; 967 } 968 969 /* Function to allocate memory for the temporary buffer. This memory is 970 * allocated from Ashmem. It is the caller's responsibility to free this 971 * memory. 972 */ 973 static int get_temp_buffer(const bufferInfo& info, alloc_data& data) 974 { 975 ALOGD("%s E", __FUNCTION__); 976 // Alloc memory from system heap 977 data.base = 0; 978 data.fd = -1; 979 data.offset = 0; 980 data.size = get_size(info); 981 data.align = getpagesize(); 982 data.uncached = true; 983 int allocFlags = GRALLOC_USAGE_PRIVATE_SYSTEM_HEAP; 984 985 if (sAlloc == 0) { 986 sAlloc = gralloc::IAllocController::getInstance(); 987 } 988 989 if (sAlloc == 0) { 990 ALOGE("%s: sAlloc is still NULL", __FUNCTION__); 991 return COPYBIT_FAILURE; 992 } 993 994 int err = sAlloc->allocate(data, allocFlags); 995 if (0 != err) { 996 ALOGE("%s: allocate failed", __FUNCTION__); 997 return COPYBIT_FAILURE; 998 } 999 1000 ALOGD("%s X", __FUNCTION__); 1001 return err; 1002 } 1003 1004 /* Function to free the temporary allocated memory.*/ 1005 static void free_temp_buffer(alloc_data &data) 1006 { 1007 if (-1 != data.fd) { 1008 IMemAlloc* memalloc = sAlloc->getAllocator(data.allocType); 1009 memalloc->free_buffer(data.base, data.size, 0, data.fd); 1010 } 1011 } 1012 1013 /* Function to perform the software color conversion. Convert the 1014 * C2D compatible format to the Android compatible format 1015 */ 1016 static int copy_image(private_handle_t *src_handle, 1017 struct copybit_image_t const *rhs, 1018 eConversionType conversionType) 1019 { 1020 if (src_handle->fd == -1) { 1021 ALOGE("%s: src_handle fd is invalid", __FUNCTION__); 1022 return COPYBIT_FAILURE; 1023 } 1024 1025 // Copy the info. 1026 int ret = COPYBIT_SUCCESS; 1027 switch(rhs->format) { 1028 case HAL_PIXEL_FORMAT_NV12_ENCODEABLE: 1029 case HAL_PIXEL_FORMAT_YCbCr_420_SP: 1030 case HAL_PIXEL_FORMAT_YCrCb_420_SP: 1031 { 1032 if (CONVERT_TO_ANDROID_FORMAT == conversionType) { 1033 return convert_yuv_c2d_to_yuv_android(src_handle, rhs); 1034 } else { 1035 return convert_yuv_android_to_yuv_c2d(src_handle, rhs); 1036 } 1037 1038 } break; 1039 default: { 1040 ALOGE("%s: invalid format 0x%x", __FUNCTION__, rhs->format); 1041 ret = COPYBIT_FAILURE; 1042 } break; 1043 } 1044 return ret; 1045 } 1046 1047 static void delete_handle(private_handle_t *handle) 1048 { 1049 if (handle) { 1050 delete handle; 1051 handle = 0; 1052 } 1053 } 1054 1055 static bool need_to_execute_draw(struct copybit_context_t* ctx, 1056 eC2DFlags flags) 1057 { 1058 if (flags & FLAGS_TEMP_SRC_DST) { 1059 return true; 1060 } 1061 if (flags & FLAGS_YUV_DESTINATION) { 1062 return true; 1063 } 1064 return false; 1065 } 1066 1067 /** do a stretch blit type operation */ 1068 static int stretch_copybit_internal( 1069 struct copybit_device_t *dev, 1070 struct copybit_image_t const *dst, 1071 struct copybit_image_t const *src, 1072 struct copybit_rect_t const *dst_rect, 1073 struct copybit_rect_t const *src_rect, 1074 struct copybit_region_t const *region, 1075 bool enableBlend) 1076 { 1077 struct copybit_context_t* ctx = (struct copybit_context_t*)dev; 1078 int status = COPYBIT_SUCCESS; 1079 int flags = 0; 1080 int src_surface_type; 1081 int mapped_src_idx = -1, mapped_dst_idx = -1; 1082 C2D_OBJECT_STR src_surface; 1083 1084 if (!ctx) { 1085 ALOGE("%s: null context error", __FUNCTION__); 1086 return -EINVAL; 1087 } 1088 1089 if (src->w > MAX_DIMENSION || src->h > MAX_DIMENSION) { 1090 ALOGE("%s: src dimension error", __FUNCTION__); 1091 return -EINVAL; 1092 } 1093 1094 if (dst->w > MAX_DIMENSION || dst->h > MAX_DIMENSION) { 1095 ALOGE("%s : dst dimension error dst w %d h %d", __FUNCTION__, dst->w, 1096 dst->h); 1097 return -EINVAL; 1098 } 1099 1100 if (is_valid_destination_format(dst->format) == COPYBIT_FAILURE) { 1101 ALOGE("%s: Invalid destination format format = 0x%x", __FUNCTION__, 1102 dst->format); 1103 return COPYBIT_FAILURE; 1104 } 1105 1106 int dst_surface_type; 1107 if (is_supported_rgb_format(dst->format) == COPYBIT_SUCCESS) { 1108 dst_surface_type = RGB_SURFACE; 1109 flags |= FLAGS_PREMULTIPLIED_ALPHA; 1110 } else if (is_supported_yuv_format(dst->format) == COPYBIT_SUCCESS) { 1111 int num_planes = get_num_planes(dst->format); 1112 flags |= FLAGS_YUV_DESTINATION; 1113 if (num_planes == 2) { 1114 dst_surface_type = YUV_SURFACE_2_PLANES; 1115 } else if (num_planes == 3) { 1116 dst_surface_type = YUV_SURFACE_3_PLANES; 1117 } else { 1118 ALOGE("%s: dst number of YUV planes is invalid dst format = 0x%x", 1119 __FUNCTION__, dst->format); 1120 return COPYBIT_FAILURE; 1121 } 1122 } else { 1123 ALOGE("%s: Invalid dst surface format 0x%x", __FUNCTION__, 1124 dst->format); 1125 return COPYBIT_FAILURE; 1126 } 1127 1128 if (ctx->blit_rgb_count == MAX_RGB_SURFACES || 1129 ctx->blit_yuv_2_plane_count == MAX_YUV_2_PLANE_SURFACES || 1130 ctx->blit_yuv_3_plane_count == MAX_YUV_2_PLANE_SURFACES || 1131 ctx->blit_count == MAX_BLIT_OBJECT_COUNT || 1132 ctx->dst_surface_type != dst_surface_type) { 1133 // we have reached the max. limits of our internal structures or 1134 // changed the target. 1135 // Draw the remaining surfaces. We need to do the finish here since 1136 // we need to free up the surface templates. 1137 finish_copybit(dev); 1138 } 1139 1140 ctx->dst_surface_type = dst_surface_type; 1141 1142 // Update the destination 1143 copybit_image_t dst_image; 1144 dst_image.w = dst->w; 1145 dst_image.h = dst->h; 1146 dst_image.format = dst->format; 1147 dst_image.handle = dst->handle; 1148 // Check if we need a temp. copy for the destination. We'd need this the destination 1149 // width is not aligned to 32. This case occurs for YUV formats. RGB formats are 1150 // aligned to 32. 1151 bool need_temp_dst = need_temp_buffer(dst); 1152 bufferInfo dst_info; 1153 populate_buffer_info(dst, dst_info); 1154 private_handle_t* dst_hnd = new private_handle_t(-1, 0, 0, 0, dst_info.format, 1155 dst_info.width, dst_info.height); 1156 if (dst_hnd == NULL) { 1157 ALOGE("%s: dst_hnd is null", __FUNCTION__); 1158 return COPYBIT_FAILURE; 1159 } 1160 if (need_temp_dst) { 1161 if (get_size(dst_info) != ctx->temp_dst_buffer.size) { 1162 free_temp_buffer(ctx->temp_dst_buffer); 1163 // Create a temp buffer and set that as the destination. 1164 if (COPYBIT_FAILURE == get_temp_buffer(dst_info, ctx->temp_dst_buffer)) { 1165 ALOGE("%s: get_temp_buffer(dst) failed", __FUNCTION__); 1166 delete_handle(dst_hnd); 1167 return COPYBIT_FAILURE; 1168 } 1169 } 1170 dst_hnd->fd = ctx->temp_dst_buffer.fd; 1171 dst_hnd->size = ctx->temp_dst_buffer.size; 1172 dst_hnd->flags = ctx->temp_dst_buffer.allocType; 1173 dst_hnd->base = (int)(ctx->temp_dst_buffer.base); 1174 dst_hnd->offset = ctx->temp_dst_buffer.offset; 1175 dst_hnd->gpuaddr = 0; 1176 dst_image.handle = dst_hnd; 1177 } 1178 1179 status = set_image(ctx, ctx->dst[ctx->dst_surface_type], &dst_image, 1180 (eC2DFlags)flags, mapped_dst_idx); 1181 if(status) { 1182 ALOGE("%s: dst: set_image error", __FUNCTION__); 1183 delete_handle(dst_hnd); 1184 unmap_gpuaddr(ctx, mapped_dst_idx); 1185 return COPYBIT_FAILURE; 1186 } 1187 1188 // Update the source 1189 flags = 0; 1190 if(is_supported_rgb_format(src->format) == COPYBIT_SUCCESS) { 1191 src_surface_type = RGB_SURFACE; 1192 src_surface = ctx->blit_rgb_object[ctx->blit_rgb_count]; 1193 } else if (is_supported_yuv_format(src->format) == COPYBIT_SUCCESS) { 1194 int num_planes = get_num_planes(src->format); 1195 if (num_planes == 2) { 1196 src_surface_type = YUV_SURFACE_2_PLANES; 1197 src_surface = ctx->blit_yuv_2_plane_object[ctx->blit_yuv_2_plane_count]; 1198 } else if (num_planes == 3) { 1199 src_surface_type = YUV_SURFACE_3_PLANES; 1200 src_surface = ctx->blit_yuv_3_plane_object[ctx->blit_yuv_2_plane_count]; 1201 } else { 1202 ALOGE("%s: src number of YUV planes is invalid src format = 0x%x", 1203 __FUNCTION__, src->format); 1204 delete_handle(dst_hnd); 1205 unmap_gpuaddr(ctx, mapped_dst_idx); 1206 return -EINVAL; 1207 } 1208 } else { 1209 ALOGE("%s: Invalid source surface format 0x%x", __FUNCTION__, 1210 src->format); 1211 delete_handle(dst_hnd); 1212 unmap_gpuaddr(ctx, mapped_dst_idx); 1213 return -EINVAL; 1214 } 1215 1216 copybit_image_t src_image; 1217 src_image.w = src->w; 1218 src_image.h = src->h; 1219 src_image.format = src->format; 1220 src_image.handle = src->handle; 1221 1222 bool need_temp_src = need_temp_buffer(src); 1223 bufferInfo src_info; 1224 populate_buffer_info(src, src_info); 1225 private_handle_t* src_hnd = new private_handle_t(-1, 0, 0, 0, src_info.format, 1226 src_info.width, src_info.height); 1227 if (NULL == src_hnd) { 1228 ALOGE("%s: src_hnd is null", __FUNCTION__); 1229 delete_handle(dst_hnd); 1230 unmap_gpuaddr(ctx, mapped_dst_idx); 1231 return COPYBIT_FAILURE; 1232 } 1233 if (need_temp_src) { 1234 if (get_size(src_info) != ctx->temp_src_buffer.size) { 1235 free_temp_buffer(ctx->temp_src_buffer); 1236 // Create a temp buffer and set that as the destination. 1237 if (COPYBIT_SUCCESS != get_temp_buffer(src_info, 1238 ctx->temp_src_buffer)) { 1239 ALOGE("%s: get_temp_buffer(src) failed", __FUNCTION__); 1240 delete_handle(dst_hnd); 1241 delete_handle(src_hnd); 1242 unmap_gpuaddr(ctx, mapped_dst_idx); 1243 return COPYBIT_FAILURE; 1244 } 1245 } 1246 src_hnd->fd = ctx->temp_src_buffer.fd; 1247 src_hnd->size = ctx->temp_src_buffer.size; 1248 src_hnd->flags = ctx->temp_src_buffer.allocType; 1249 src_hnd->base = (int)(ctx->temp_src_buffer.base); 1250 src_hnd->offset = ctx->temp_src_buffer.offset; 1251 src_hnd->gpuaddr = 0; 1252 src_image.handle = src_hnd; 1253 1254 // Copy the source. 1255 status = copy_image((private_handle_t *)src->handle, &src_image, 1256 CONVERT_TO_C2D_FORMAT); 1257 if (status == COPYBIT_FAILURE) { 1258 ALOGE("%s:copy_image failed in temp source",__FUNCTION__); 1259 delete_handle(dst_hnd); 1260 delete_handle(src_hnd); 1261 unmap_gpuaddr(ctx, mapped_dst_idx); 1262 return status; 1263 } 1264 1265 // Clean the cache 1266 IMemAlloc* memalloc = sAlloc->getAllocator(src_hnd->flags); 1267 if (memalloc->clean_buffer((void *)(src_hnd->base), src_hnd->size, 1268 src_hnd->offset, src_hnd->fd, 1269 gralloc::CACHE_CLEAN)) { 1270 ALOGE("%s: clean_buffer failed", __FUNCTION__); 1271 delete_handle(dst_hnd); 1272 delete_handle(src_hnd); 1273 unmap_gpuaddr(ctx, mapped_dst_idx); 1274 return COPYBIT_FAILURE; 1275 } 1276 } 1277 1278 flags |= (ctx->is_premultiplied_alpha) ? FLAGS_PREMULTIPLIED_ALPHA : 0; 1279 flags |= (ctx->dst_surface_type != RGB_SURFACE) ? FLAGS_YUV_DESTINATION : 0; 1280 status = set_image(ctx, src_surface.surface_id, &src_image, 1281 (eC2DFlags)flags, mapped_src_idx); 1282 if(status) { 1283 ALOGE("%s: set_image (src) error", __FUNCTION__); 1284 delete_handle(dst_hnd); 1285 delete_handle(src_hnd); 1286 unmap_gpuaddr(ctx, mapped_dst_idx); 1287 unmap_gpuaddr(ctx, mapped_src_idx); 1288 return COPYBIT_FAILURE; 1289 } 1290 1291 src_surface.config_mask = C2D_NO_ANTIALIASING_BIT | ctx->config_mask; 1292 src_surface.global_alpha = ctx->src_global_alpha; 1293 if (enableBlend) { 1294 if(src_surface.config_mask & C2D_GLOBAL_ALPHA_BIT) { 1295 src_surface.config_mask &= ~C2D_ALPHA_BLEND_NONE; 1296 if(!(src_surface.global_alpha)) { 1297 // src alpha is zero 1298 delete_handle(dst_hnd); 1299 delete_handle(src_hnd); 1300 unmap_gpuaddr(ctx, mapped_dst_idx); 1301 unmap_gpuaddr(ctx, mapped_src_idx); 1302 return COPYBIT_FAILURE; 1303 } 1304 } 1305 } else { 1306 src_surface.config_mask |= C2D_ALPHA_BLEND_NONE; 1307 } 1308 1309 if (src_surface_type == RGB_SURFACE) { 1310 ctx->blit_rgb_object[ctx->blit_rgb_count] = src_surface; 1311 ctx->blit_rgb_count++; 1312 } else if (src_surface_type == YUV_SURFACE_2_PLANES) { 1313 ctx->blit_yuv_2_plane_object[ctx->blit_yuv_2_plane_count] = src_surface; 1314 ctx->blit_yuv_2_plane_count++; 1315 } else { 1316 ctx->blit_yuv_3_plane_object[ctx->blit_yuv_3_plane_count] = src_surface; 1317 ctx->blit_yuv_3_plane_count++; 1318 } 1319 1320 struct copybit_rect_t clip; 1321 while ((status == 0) && region->next(region, &clip)) { 1322 set_rects(ctx, &(src_surface), dst_rect, src_rect, &clip); 1323 if (ctx->blit_count == MAX_BLIT_OBJECT_COUNT) { 1324 ALOGW("Reached end of blit count"); 1325 finish_copybit(dev); 1326 } 1327 ctx->blit_list[ctx->blit_count] = src_surface; 1328 ctx->blit_count++; 1329 } 1330 1331 // Check if we need to perform an early draw-finish. 1332 flags |= (need_temp_dst || need_temp_src) ? FLAGS_TEMP_SRC_DST : 0; 1333 if (need_to_execute_draw(ctx, (eC2DFlags)flags)) 1334 { 1335 finish_copybit(dev); 1336 } 1337 1338 if (need_temp_dst) { 1339 // copy the temp. destination without the alignment to the actual 1340 // destination. 1341 status = copy_image(dst_hnd, dst, CONVERT_TO_ANDROID_FORMAT); 1342 if (status == COPYBIT_FAILURE) { 1343 ALOGE("%s:copy_image failed in temp Dest",__FUNCTION__); 1344 delete_handle(dst_hnd); 1345 delete_handle(src_hnd); 1346 unmap_gpuaddr(ctx, mapped_dst_idx); 1347 unmap_gpuaddr(ctx, mapped_src_idx); 1348 return status; 1349 } 1350 // Clean the cache. 1351 IMemAlloc* memalloc = sAlloc->getAllocator(dst_hnd->flags); 1352 memalloc->clean_buffer((void *)(dst_hnd->base), dst_hnd->size, 1353 dst_hnd->offset, dst_hnd->fd, 1354 gralloc::CACHE_CLEAN); 1355 } 1356 delete_handle(dst_hnd); 1357 delete_handle(src_hnd); 1358 1359 ctx->is_premultiplied_alpha = false; 1360 ctx->fb_width = 0; 1361 ctx->fb_height = 0; 1362 ctx->config_mask = 0; 1363 return status; 1364 } 1365 1366 1367 static int stretch_copybit( 1368 struct copybit_device_t *dev, 1369 struct copybit_image_t const *dst, 1370 struct copybit_image_t const *src, 1371 struct copybit_rect_t const *dst_rect, 1372 struct copybit_rect_t const *src_rect, 1373 struct copybit_region_t const *region) 1374 { 1375 struct copybit_context_t* ctx = (struct copybit_context_t*)dev; 1376 int status = COPYBIT_SUCCESS; 1377 bool needsBlending = (ctx->src_global_alpha != 0); 1378 pthread_mutex_lock(&ctx->wait_cleanup_lock); 1379 status = stretch_copybit_internal(dev, dst, src, dst_rect, src_rect, 1380 region, needsBlending); 1381 pthread_mutex_unlock(&ctx->wait_cleanup_lock); 1382 return status; 1383 } 1384 1385 /** Perform a blit type operation */ 1386 static int blit_copybit( 1387 struct copybit_device_t *dev, 1388 struct copybit_image_t const *dst, 1389 struct copybit_image_t const *src, 1390 struct copybit_region_t const *region) 1391 { 1392 int status = COPYBIT_SUCCESS; 1393 struct copybit_context_t* ctx = (struct copybit_context_t*)dev; 1394 struct copybit_rect_t dr = { 0, 0, dst->w, dst->h }; 1395 struct copybit_rect_t sr = { 0, 0, src->w, src->h }; 1396 pthread_mutex_lock(&ctx->wait_cleanup_lock); 1397 status = stretch_copybit_internal(dev, dst, src, &dr, &sr, region, false); 1398 pthread_mutex_unlock(&ctx->wait_cleanup_lock); 1399 return status; 1400 } 1401 1402 /*****************************************************************************/ 1403 1404 static void clean_up(copybit_context_t* ctx) 1405 { 1406 void* ret; 1407 if (!ctx) 1408 return; 1409 1410 // stop the wait_cleanup_thread 1411 pthread_mutex_lock(&ctx->wait_cleanup_lock); 1412 ctx->stop_thread = true; 1413 // Signal waiting thread 1414 pthread_cond_signal(&ctx->wait_cleanup_cond); 1415 pthread_mutex_unlock(&ctx->wait_cleanup_lock); 1416 // waits for the cleanup thread to exit 1417 pthread_join(ctx->wait_thread_id, &ret); 1418 pthread_mutex_destroy(&ctx->wait_cleanup_lock); 1419 pthread_cond_destroy (&ctx->wait_cleanup_cond); 1420 1421 for (int i = 0; i < NUM_SURFACE_TYPES; i++) { 1422 if (ctx->dst[i]) 1423 LINK_c2dDestroySurface(ctx->dst[i]); 1424 } 1425 1426 for (int i = 0; i < MAX_RGB_SURFACES; i++) { 1427 if (ctx->blit_rgb_object[i].surface_id) 1428 LINK_c2dDestroySurface(ctx->blit_rgb_object[i].surface_id); 1429 } 1430 1431 for (int i = 0; i < MAX_YUV_2_PLANE_SURFACES; i++) { 1432 if (ctx->blit_yuv_2_plane_object[i].surface_id) 1433 LINK_c2dDestroySurface(ctx->blit_yuv_2_plane_object[i].surface_id); 1434 } 1435 1436 for (int i = 0; i < MAX_YUV_3_PLANE_SURFACES; i++) { 1437 if (ctx->blit_yuv_3_plane_object[i].surface_id) 1438 LINK_c2dDestroySurface(ctx->blit_yuv_3_plane_object[i].surface_id); 1439 } 1440 1441 if (ctx->libc2d2) { 1442 ::dlclose(ctx->libc2d2); 1443 ALOGV("dlclose(libc2d2)"); 1444 } 1445 1446 free(ctx); 1447 } 1448 1449 /** Close the copybit device */ 1450 static int close_copybit(struct hw_device_t *dev) 1451 { 1452 struct copybit_context_t* ctx = (struct copybit_context_t*)dev; 1453 if (ctx) { 1454 free_temp_buffer(ctx->temp_src_buffer); 1455 free_temp_buffer(ctx->temp_dst_buffer); 1456 } 1457 clean_up(ctx); 1458 return 0; 1459 } 1460 1461 /** Open a new instance of a copybit device using name */ 1462 static int open_copybit(const struct hw_module_t* module, const char* name, 1463 struct hw_device_t** device) 1464 { 1465 int status = COPYBIT_SUCCESS; 1466 C2D_RGB_SURFACE_DEF surfDefinition = {0}; 1467 C2D_YUV_SURFACE_DEF yuvSurfaceDef = {0} ; 1468 struct copybit_context_t *ctx; 1469 char fbName[64]; 1470 1471 ctx = (struct copybit_context_t *)malloc(sizeof(struct copybit_context_t)); 1472 if(!ctx) { 1473 ALOGE("%s: malloc failed", __FUNCTION__); 1474 return COPYBIT_FAILURE; 1475 } 1476 1477 /* initialize drawstate */ 1478 memset(ctx, 0, sizeof(*ctx)); 1479 ctx->libc2d2 = ::dlopen("libC2D2.so", RTLD_NOW); 1480 if (!ctx->libc2d2) { 1481 ALOGE("FATAL ERROR: could not dlopen libc2d2.so: %s", dlerror()); 1482 clean_up(ctx); 1483 status = COPYBIT_FAILURE; 1484 *device = NULL; 1485 return status; 1486 } 1487 *(void **)&LINK_c2dCreateSurface = ::dlsym(ctx->libc2d2, 1488 "c2dCreateSurface"); 1489 *(void **)&LINK_c2dUpdateSurface = ::dlsym(ctx->libc2d2, 1490 "c2dUpdateSurface"); 1491 *(void **)&LINK_c2dReadSurface = ::dlsym(ctx->libc2d2, 1492 "c2dReadSurface"); 1493 *(void **)&LINK_c2dDraw = ::dlsym(ctx->libc2d2, "c2dDraw"); 1494 *(void **)&LINK_c2dFlush = ::dlsym(ctx->libc2d2, "c2dFlush"); 1495 *(void **)&LINK_c2dFinish = ::dlsym(ctx->libc2d2, "c2dFinish"); 1496 *(void **)&LINK_c2dWaitTimestamp = ::dlsym(ctx->libc2d2, 1497 "c2dWaitTimestamp"); 1498 *(void **)&LINK_c2dDestroySurface = ::dlsym(ctx->libc2d2, 1499 "c2dDestroySurface"); 1500 *(void **)&LINK_c2dMapAddr = ::dlsym(ctx->libc2d2, 1501 "c2dMapAddr"); 1502 *(void **)&LINK_c2dUnMapAddr = ::dlsym(ctx->libc2d2, 1503 "c2dUnMapAddr"); 1504 *(void **)&LINK_c2dGetDriverCapabilities = ::dlsym(ctx->libc2d2, 1505 "c2dGetDriverCapabilities"); 1506 *(void **)&LINK_c2dCreateFenceFD = ::dlsym(ctx->libc2d2, 1507 "c2dCreateFenceFD"); 1508 *(void **)&LINK_c2dFillSurface = ::dlsym(ctx->libc2d2, 1509 "c2dFillSurface"); 1510 1511 if (!LINK_c2dCreateSurface || !LINK_c2dUpdateSurface || !LINK_c2dReadSurface 1512 || !LINK_c2dDraw || !LINK_c2dFlush || !LINK_c2dWaitTimestamp || 1513 !LINK_c2dFinish || !LINK_c2dDestroySurface || 1514 !LINK_c2dGetDriverCapabilities || !LINK_c2dCreateFenceFD || 1515 !LINK_c2dFillSurface) { 1516 ALOGE("%s: dlsym ERROR", __FUNCTION__); 1517 clean_up(ctx); 1518 status = COPYBIT_FAILURE; 1519 *device = NULL; 1520 return status; 1521 } 1522 1523 ctx->device.common.tag = HARDWARE_DEVICE_TAG; 1524 ctx->device.common.version = 1; 1525 ctx->device.common.module = (hw_module_t*)(module); 1526 ctx->device.common.close = close_copybit; 1527 ctx->device.set_parameter = set_parameter_copybit; 1528 ctx->device.get = get; 1529 ctx->device.blit = blit_copybit; 1530 ctx->device.stretch = stretch_copybit; 1531 ctx->device.finish = finish_copybit; 1532 ctx->device.flush_get_fence = flush_get_fence_copybit; 1533 ctx->device.clear = clear_copybit; 1534 1535 /* Create RGB Surface */ 1536 surfDefinition.buffer = (void*)0xdddddddd; 1537 surfDefinition.phys = (void*)0xdddddddd; 1538 surfDefinition.stride = 1 * 4; 1539 surfDefinition.width = 1; 1540 surfDefinition.height = 1; 1541 surfDefinition.format = C2D_COLOR_FORMAT_8888_ARGB; 1542 if (LINK_c2dCreateSurface(&(ctx->dst[RGB_SURFACE]), C2D_TARGET | C2D_SOURCE, 1543 (C2D_SURFACE_TYPE)(C2D_SURFACE_RGB_HOST | 1544 C2D_SURFACE_WITH_PHYS | 1545 C2D_SURFACE_WITH_PHYS_DUMMY ), 1546 &surfDefinition)) { 1547 ALOGE("%s: create ctx->dst_surface[RGB_SURFACE] failed", __FUNCTION__); 1548 ctx->dst[RGB_SURFACE] = 0; 1549 clean_up(ctx); 1550 status = COPYBIT_FAILURE; 1551 *device = NULL; 1552 return status; 1553 } 1554 1555 unsigned int surface_id = 0; 1556 for (int i = 0; i < MAX_RGB_SURFACES; i++) 1557 { 1558 if (LINK_c2dCreateSurface(&surface_id, C2D_TARGET | C2D_SOURCE, 1559 (C2D_SURFACE_TYPE)(C2D_SURFACE_RGB_HOST | 1560 C2D_SURFACE_WITH_PHYS | 1561 C2D_SURFACE_WITH_PHYS_DUMMY ), 1562 &surfDefinition)) { 1563 ALOGE("%s: create RGB source surface %d failed", __FUNCTION__, i); 1564 ctx->blit_rgb_object[i].surface_id = 0; 1565 status = COPYBIT_FAILURE; 1566 break; 1567 } else { 1568 ctx->blit_rgb_object[i].surface_id = surface_id; 1569 ALOGW("%s i = %d surface_id=%d", __FUNCTION__, i, 1570 ctx->blit_rgb_object[i].surface_id); 1571 } 1572 } 1573 1574 if (status == COPYBIT_FAILURE) { 1575 clean_up(ctx); 1576 status = COPYBIT_FAILURE; 1577 *device = NULL; 1578 return status; 1579 } 1580 1581 // Create 2 plane YUV surfaces 1582 yuvSurfaceDef.format = C2D_COLOR_FORMAT_420_NV12; 1583 yuvSurfaceDef.width = 4; 1584 yuvSurfaceDef.height = 4; 1585 yuvSurfaceDef.plane0 = (void*)0xaaaaaaaa; 1586 yuvSurfaceDef.phys0 = (void*) 0xaaaaaaaa; 1587 yuvSurfaceDef.stride0 = 4; 1588 1589 yuvSurfaceDef.plane1 = (void*)0xaaaaaaaa; 1590 yuvSurfaceDef.phys1 = (void*) 0xaaaaaaaa; 1591 yuvSurfaceDef.stride1 = 4; 1592 if (LINK_c2dCreateSurface(&(ctx->dst[YUV_SURFACE_2_PLANES]), 1593 C2D_TARGET | C2D_SOURCE, 1594 (C2D_SURFACE_TYPE)(C2D_SURFACE_YUV_HOST | 1595 C2D_SURFACE_WITH_PHYS | 1596 C2D_SURFACE_WITH_PHYS_DUMMY), 1597 &yuvSurfaceDef)) { 1598 ALOGE("%s: create ctx->dst[YUV_SURFACE_2_PLANES] failed", __FUNCTION__); 1599 ctx->dst[YUV_SURFACE_2_PLANES] = 0; 1600 clean_up(ctx); 1601 status = COPYBIT_FAILURE; 1602 *device = NULL; 1603 return status; 1604 } 1605 1606 for (int i=0; i < MAX_YUV_2_PLANE_SURFACES; i++) 1607 { 1608 if (LINK_c2dCreateSurface(&surface_id, C2D_TARGET | C2D_SOURCE, 1609 (C2D_SURFACE_TYPE)(C2D_SURFACE_YUV_HOST | 1610 C2D_SURFACE_WITH_PHYS | 1611 C2D_SURFACE_WITH_PHYS_DUMMY ), 1612 &yuvSurfaceDef)) { 1613 ALOGE("%s: create YUV source %d failed", __FUNCTION__, i); 1614 ctx->blit_yuv_2_plane_object[i].surface_id = 0; 1615 status = COPYBIT_FAILURE; 1616 break; 1617 } else { 1618 ctx->blit_yuv_2_plane_object[i].surface_id = surface_id; 1619 ALOGW("%s: 2 Plane YUV i=%d surface_id=%d", __FUNCTION__, i, 1620 ctx->blit_yuv_2_plane_object[i].surface_id); 1621 } 1622 } 1623 1624 if (status == COPYBIT_FAILURE) { 1625 clean_up(ctx); 1626 status = COPYBIT_FAILURE; 1627 *device = NULL; 1628 return status; 1629 } 1630 1631 // Create YUV 3 plane surfaces 1632 yuvSurfaceDef.format = C2D_COLOR_FORMAT_420_YV12; 1633 yuvSurfaceDef.plane2 = (void*)0xaaaaaaaa; 1634 yuvSurfaceDef.phys2 = (void*) 0xaaaaaaaa; 1635 yuvSurfaceDef.stride2 = 4; 1636 1637 if (LINK_c2dCreateSurface(&(ctx->dst[YUV_SURFACE_3_PLANES]), 1638 C2D_TARGET | C2D_SOURCE, 1639 (C2D_SURFACE_TYPE)(C2D_SURFACE_YUV_HOST | 1640 C2D_SURFACE_WITH_PHYS | 1641 C2D_SURFACE_WITH_PHYS_DUMMY), 1642 &yuvSurfaceDef)) { 1643 ALOGE("%s: create ctx->dst[YUV_SURFACE_3_PLANES] failed", __FUNCTION__); 1644 ctx->dst[YUV_SURFACE_3_PLANES] = 0; 1645 clean_up(ctx); 1646 status = COPYBIT_FAILURE; 1647 *device = NULL; 1648 return status; 1649 } 1650 1651 for (int i=0; i < MAX_YUV_3_PLANE_SURFACES; i++) 1652 { 1653 if (LINK_c2dCreateSurface(&(surface_id), 1654 C2D_TARGET | C2D_SOURCE, 1655 (C2D_SURFACE_TYPE)(C2D_SURFACE_YUV_HOST | 1656 C2D_SURFACE_WITH_PHYS | 1657 C2D_SURFACE_WITH_PHYS_DUMMY), 1658 &yuvSurfaceDef)) { 1659 ALOGE("%s: create 3 plane YUV surface %d failed", __FUNCTION__, i); 1660 ctx->blit_yuv_3_plane_object[i].surface_id = 0; 1661 status = COPYBIT_FAILURE; 1662 break; 1663 } else { 1664 ctx->blit_yuv_3_plane_object[i].surface_id = surface_id; 1665 ALOGW("%s: 3 Plane YUV i=%d surface_id=%d", __FUNCTION__, i, 1666 ctx->blit_yuv_3_plane_object[i].surface_id); 1667 } 1668 } 1669 1670 if (status == COPYBIT_FAILURE) { 1671 clean_up(ctx); 1672 status = COPYBIT_FAILURE; 1673 *device = NULL; 1674 return status; 1675 } 1676 1677 if (LINK_c2dGetDriverCapabilities(&(ctx->c2d_driver_info))) { 1678 ALOGE("%s: LINK_c2dGetDriverCapabilities failed", __FUNCTION__); 1679 clean_up(ctx); 1680 status = COPYBIT_FAILURE; 1681 *device = NULL; 1682 return status; 1683 } 1684 // Initialize context variables. 1685 ctx->trg_transform = C2D_TARGET_ROTATE_0; 1686 1687 ctx->temp_src_buffer.fd = -1; 1688 ctx->temp_src_buffer.base = 0; 1689 ctx->temp_src_buffer.size = 0; 1690 1691 ctx->temp_dst_buffer.fd = -1; 1692 ctx->temp_dst_buffer.base = 0; 1693 ctx->temp_dst_buffer.size = 0; 1694 1695 ctx->fb_width = 0; 1696 ctx->fb_height = 0; 1697 1698 ctx->blit_rgb_count = 0; 1699 ctx->blit_yuv_2_plane_count = 0; 1700 ctx->blit_yuv_3_plane_count = 0; 1701 ctx->blit_count = 0; 1702 1703 ctx->wait_timestamp = false; 1704 ctx->stop_thread = false; 1705 pthread_mutex_init(&(ctx->wait_cleanup_lock), NULL); 1706 pthread_cond_init(&(ctx->wait_cleanup_cond), NULL); 1707 /* Start the wait thread */ 1708 pthread_attr_t attr; 1709 pthread_attr_init(&attr); 1710 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); 1711 1712 pthread_create(&ctx->wait_thread_id, &attr, &c2d_wait_loop, 1713 (void *)ctx); 1714 pthread_attr_destroy(&attr); 1715 1716 *device = &ctx->device.common; 1717 return status; 1718 } 1719