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