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 21 #include <cutils/log.h> 22 23 #include <linux/msm_mdp.h> 24 #include <linux/fb.h> 25 26 #include <stdint.h> 27 #include <string.h> 28 #include <unistd.h> 29 #include <errno.h> 30 #include <fcntl.h> 31 32 #include <sys/ioctl.h> 33 #include <sys/types.h> 34 #include <sys/mman.h> 35 36 #include <copybit.h> 37 38 #include "gralloc_priv.h" 39 #include "software_converter.h" 40 41 #define DEBUG_MDP_ERRORS 1 42 43 /******************************************************************************/ 44 45 #define MAX_SCALE_FACTOR (4) 46 #define MAX_DIMENSION (4096) 47 48 /******************************************************************************/ 49 struct blitReq{ 50 struct mdp_buf_sync sync; 51 uint32_t count; 52 struct mdp_blit_req req[10]; 53 }; 54 55 /** State information for each device instance */ 56 struct copybit_context_t { 57 struct copybit_device_t device; 58 int mFD; 59 uint8_t mAlpha; 60 int mFlags; 61 bool mBlitToFB; 62 int acqFence[MDP_MAX_FENCE_FD]; 63 int relFence; 64 struct mdp_buf_sync sync; 65 struct blitReq list; 66 }; 67 68 /** 69 * Common hardware methods 70 */ 71 72 static int open_copybit(const struct hw_module_t* module, const char* name, 73 struct hw_device_t** device); 74 75 static struct hw_module_methods_t copybit_module_methods = { 76 open: open_copybit 77 }; 78 79 /* 80 * The COPYBIT Module 81 */ 82 struct copybit_module_t HAL_MODULE_INFO_SYM = { 83 common: { 84 tag: HARDWARE_MODULE_TAG, 85 version_major: 1, 86 version_minor: 0, 87 id: COPYBIT_HARDWARE_MODULE_ID, 88 name: "QCT MSM7K COPYBIT Module", 89 author: "Google, Inc.", 90 methods: ©bit_module_methods 91 } 92 }; 93 94 /******************************************************************************/ 95 96 /** min of int a, b */ 97 static inline int min(int a, int b) { 98 return (a<b) ? a : b; 99 } 100 101 /** max of int a, b */ 102 static inline int max(int a, int b) { 103 return (a>b) ? a : b; 104 } 105 106 /** scale each parameter by mul/div. Assume div isn't 0 */ 107 static inline void MULDIV(uint32_t *a, uint32_t *b, int mul, int div) { 108 if (mul != div) { 109 *a = (mul * *a) / div; 110 *b = (mul * *b) / div; 111 } 112 } 113 114 /** Determine the intersection of lhs & rhs store in out */ 115 static void intersect(struct copybit_rect_t *out, 116 const struct copybit_rect_t *lhs, 117 const struct copybit_rect_t *rhs) { 118 out->l = max(lhs->l, rhs->l); 119 out->t = max(lhs->t, rhs->t); 120 out->r = min(lhs->r, rhs->r); 121 out->b = min(lhs->b, rhs->b); 122 } 123 124 /** convert COPYBIT_FORMAT to MDP format */ 125 static int get_format(int format) { 126 switch (format) { 127 case HAL_PIXEL_FORMAT_RGB_565: return MDP_RGB_565; 128 case HAL_PIXEL_FORMAT_RGBX_8888: return MDP_RGBX_8888; 129 case HAL_PIXEL_FORMAT_RGB_888: return MDP_RGB_888; 130 case HAL_PIXEL_FORMAT_RGBA_8888: return MDP_RGBA_8888; 131 case HAL_PIXEL_FORMAT_BGRA_8888: return MDP_BGRA_8888; 132 case HAL_PIXEL_FORMAT_YCrCb_422_SP: return MDP_Y_CRCB_H2V1; 133 case HAL_PIXEL_FORMAT_YCrCb_420_SP: return MDP_Y_CRCB_H2V2; 134 case HAL_PIXEL_FORMAT_YCbCr_422_SP: return MDP_Y_CBCR_H2V1; 135 case HAL_PIXEL_FORMAT_YCbCr_420_SP: return MDP_Y_CBCR_H2V2; 136 case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO: return MDP_Y_CBCR_H2V2_ADRENO; 137 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS: return MDP_Y_CBCR_H2V2_VENUS; 138 case HAL_PIXEL_FORMAT_NV12_ENCODEABLE: return MDP_Y_CBCR_H2V2; 139 } 140 return -1; 141 } 142 143 /** convert from copybit image to mdp image structure */ 144 static void set_image(struct mdp_img *img, const struct copybit_image_t *rhs) 145 { 146 private_handle_t* hnd = (private_handle_t*)rhs->handle; 147 if(hnd == NULL){ 148 ALOGE("copybit: Invalid handle"); 149 return; 150 } 151 img->width = rhs->w; 152 img->height = rhs->h; 153 img->format = get_format(rhs->format); 154 img->offset = hnd->offset; 155 img->memory_id = hnd->fd; 156 } 157 /** setup rectangles */ 158 static void set_rects(struct copybit_context_t *dev, 159 struct mdp_blit_req *e, 160 const struct copybit_rect_t *dst, 161 const struct copybit_rect_t *src, 162 const struct copybit_rect_t *scissor, 163 uint32_t horiz_padding, 164 uint32_t vert_padding) { 165 struct copybit_rect_t clip; 166 intersect(&clip, scissor, dst); 167 168 e->dst_rect.x = clip.l; 169 e->dst_rect.y = clip.t; 170 e->dst_rect.w = clip.r - clip.l; 171 e->dst_rect.h = clip.b - clip.t; 172 173 uint32_t W, H, delta_x, delta_y; 174 if (dev->mFlags & COPYBIT_TRANSFORM_ROT_90) { 175 delta_x = (clip.t - dst->t); 176 delta_y = (dst->r - clip.r); 177 e->src_rect.w = (clip.b - clip.t); 178 e->src_rect.h = (clip.r - clip.l); 179 W = dst->b - dst->t; 180 H = dst->r - dst->l; 181 } else { 182 delta_x = (clip.l - dst->l); 183 delta_y = (clip.t - dst->t); 184 e->src_rect.w = (clip.r - clip.l); 185 e->src_rect.h = (clip.b - clip.t); 186 W = dst->r - dst->l; 187 H = dst->b - dst->t; 188 } 189 190 MULDIV(&delta_x, &e->src_rect.w, src->r - src->l, W); 191 MULDIV(&delta_y, &e->src_rect.h, src->b - src->t, H); 192 193 e->src_rect.x = delta_x + src->l; 194 e->src_rect.y = delta_y + src->t; 195 196 if (dev->mFlags & COPYBIT_TRANSFORM_FLIP_V) { 197 if (dev->mFlags & COPYBIT_TRANSFORM_ROT_90) { 198 e->src_rect.x = (src->l + src->r) - (e->src_rect.x + e->src_rect.w); 199 }else{ 200 e->src_rect.y = (src->t + src->b) - (e->src_rect.y + e->src_rect.h); 201 } 202 } 203 204 if (dev->mFlags & COPYBIT_TRANSFORM_FLIP_H) { 205 if (dev->mFlags & COPYBIT_TRANSFORM_ROT_90) { 206 e->src_rect.y = (src->t + src->b) - (e->src_rect.y + e->src_rect.h); 207 }else{ 208 e->src_rect.x = (src->l + src->r) - (e->src_rect.x + e->src_rect.w); 209 } 210 } 211 } 212 213 /** setup mdp request */ 214 static void set_infos(struct copybit_context_t *dev, 215 struct mdp_blit_req *req, int flags) 216 { 217 req->alpha = dev->mAlpha; 218 req->transp_mask = MDP_TRANSP_NOP; 219 req->flags = dev->mFlags | flags; 220 // check if we are blitting to f/b 221 if (COPYBIT_ENABLE == dev->mBlitToFB) { 222 req->flags |= MDP_MEMORY_ID_TYPE_FB; 223 } 224 #if defined(COPYBIT_QSD8K) 225 req->flags |= MDP_BLEND_FG_PREMULT; 226 #endif 227 } 228 229 /** copy the bits */ 230 static int msm_copybit(struct copybit_context_t *dev, void const *list) 231 { 232 int err = ioctl(dev->mFD, MSMFB_ASYNC_BLIT, 233 (struct mdp_async_blit_req_list const*)list); 234 ALOGE_IF(err<0, "copyBits failed (%s)", strerror(errno)); 235 if (err == 0) { 236 return 0; 237 } else { 238 #if DEBUG_MDP_ERRORS 239 struct mdp_async_blit_req_list const* l = 240 (struct mdp_async_blit_req_list const*)list; 241 for (unsigned int i=0 ; i<l->count ; i++) { 242 ALOGE("%d: src={w=%d, h=%d, f=%d, rect={%d,%d,%d,%d}}\n" 243 " dst={w=%d, h=%d, f=%d, rect={%d,%d,%d,%d}}\n" 244 " flags=%08x" 245 , 246 i, 247 l->req[i].src.width, 248 l->req[i].src.height, 249 l->req[i].src.format, 250 l->req[i].src_rect.x, 251 l->req[i].src_rect.y, 252 l->req[i].src_rect.w, 253 l->req[i].src_rect.h, 254 l->req[i].dst.width, 255 l->req[i].dst.height, 256 l->req[i].dst.format, 257 l->req[i].dst_rect.x, 258 l->req[i].dst_rect.y, 259 l->req[i].dst_rect.w, 260 l->req[i].dst_rect.h, 261 l->req[i].flags 262 ); 263 } 264 #endif 265 return -errno; 266 } 267 } 268 269 /*****************************************************************************/ 270 271 /** Set a parameter to value */ 272 static int set_parameter_copybit( 273 struct copybit_device_t *dev, 274 int name, 275 int value) 276 { 277 struct copybit_context_t* ctx = (struct copybit_context_t*)dev; 278 int status = 0; 279 if (ctx) { 280 switch(name) { 281 case COPYBIT_ROTATION_DEG: 282 switch (value) { 283 case 0: 284 ctx->mFlags &= ~0x7; 285 break; 286 case 90: 287 ctx->mFlags &= ~0x7; 288 ctx->mFlags |= MDP_ROT_90; 289 break; 290 case 180: 291 ctx->mFlags &= ~0x7; 292 ctx->mFlags |= MDP_ROT_180; 293 break; 294 case 270: 295 ctx->mFlags &= ~0x7; 296 ctx->mFlags |= MDP_ROT_270; 297 break; 298 default: 299 ALOGE("Invalid value for COPYBIT_ROTATION_DEG"); 300 status = -EINVAL; 301 break; 302 } 303 break; 304 case COPYBIT_PLANE_ALPHA: 305 if (value < 0) value = MDP_ALPHA_NOP; 306 if (value >= 256) value = 255; 307 ctx->mAlpha = value; 308 break; 309 case COPYBIT_DITHER: 310 if (value == COPYBIT_ENABLE) { 311 ctx->mFlags |= MDP_DITHER; 312 } else if (value == COPYBIT_DISABLE) { 313 ctx->mFlags &= ~MDP_DITHER; 314 } 315 break; 316 case COPYBIT_BLUR: 317 if (value == COPYBIT_ENABLE) { 318 ctx->mFlags |= MDP_BLUR; 319 } else if (value == COPYBIT_DISABLE) { 320 ctx->mFlags &= ~MDP_BLUR; 321 } 322 break; 323 case COPYBIT_BLEND_MODE: 324 if(value == COPYBIT_BLENDING_PREMULT) { 325 ctx->mFlags |= MDP_BLEND_FG_PREMULT; 326 } else { 327 ctx->mFlags &= ~MDP_BLEND_FG_PREMULT; 328 } 329 break; 330 case COPYBIT_TRANSFORM: 331 ctx->mFlags &= ~0x7; 332 ctx->mFlags |= value & 0x7; 333 break; 334 case COPYBIT_BLIT_TO_FRAMEBUFFER: 335 if (COPYBIT_ENABLE == value) { 336 ctx->mBlitToFB = value; 337 } else if (COPYBIT_DISABLE == value) { 338 ctx->mBlitToFB = value; 339 } else { 340 ALOGE ("%s:Invalid input for COPYBIT_BLIT_TO_FRAMEBUFFER : %d", 341 __FUNCTION__, value); 342 } 343 break; 344 case COPYBIT_FG_LAYER: 345 if(value == COPYBIT_ENABLE) { 346 ctx->mFlags |= MDP_IS_FG; 347 } else if (value == COPYBIT_DISABLE) { 348 ctx->mFlags &= ~MDP_IS_FG; 349 } 350 break ; 351 default: 352 status = -EINVAL; 353 break; 354 } 355 } else { 356 status = -EINVAL; 357 } 358 return status; 359 } 360 361 /** Get a static info value */ 362 static int get(struct copybit_device_t *dev, int name) 363 { 364 struct copybit_context_t* ctx = (struct copybit_context_t*)dev; 365 int value; 366 if (ctx) { 367 switch(name) { 368 case COPYBIT_MINIFICATION_LIMIT: 369 value = MAX_SCALE_FACTOR; 370 break; 371 case COPYBIT_MAGNIFICATION_LIMIT: 372 value = MAX_SCALE_FACTOR; 373 break; 374 case COPYBIT_SCALING_FRAC_BITS: 375 value = 32; 376 break; 377 case COPYBIT_ROTATION_STEP_DEG: 378 value = 90; 379 break; 380 default: 381 value = -EINVAL; 382 } 383 } else { 384 value = -EINVAL; 385 } 386 return value; 387 } 388 389 static int set_sync_copybit(struct copybit_device_t *dev, 390 int acquireFenceFd) 391 { 392 struct copybit_context_t* ctx = (struct copybit_context_t*)dev; 393 if (acquireFenceFd != -1) { 394 if (ctx->list.sync.acq_fen_fd_cnt < (MDP_MAX_FENCE_FD - 1)) { 395 ctx->acqFence[ctx->list.sync.acq_fen_fd_cnt++] = acquireFenceFd; 396 } else { 397 int ret = -EINVAL; 398 struct blitReq *list = &ctx->list; 399 400 // Since fence is full kick off what is already in the list 401 ret = msm_copybit(ctx, list); 402 if (ret < 0) { 403 ALOGE("%s: Blit call failed", __FUNCTION__); 404 return -EINVAL; 405 } 406 list->count = 0; 407 list->sync.acq_fen_fd_cnt = 0; 408 ctx->acqFence[list->sync.acq_fen_fd_cnt++] = acquireFenceFd; 409 ctx->relFence = -1; 410 } 411 } 412 return 0; 413 } 414 415 /** do a stretch blit type operation */ 416 static int stretch_copybit( 417 struct copybit_device_t *dev, 418 struct copybit_image_t const *dst, 419 struct copybit_image_t const *src, 420 struct copybit_rect_t const *dst_rect, 421 struct copybit_rect_t const *src_rect, 422 struct copybit_region_t const *region) 423 { 424 struct copybit_context_t* ctx = (struct copybit_context_t*)dev; 425 struct blitReq *list; 426 int status = 0; 427 private_handle_t *yv12_handle = NULL; 428 429 if (ctx) { 430 list = &ctx->list; 431 432 if (ctx->mAlpha < 255) { 433 switch (src->format) { 434 // we don't support plane alpha with RGBA formats 435 case HAL_PIXEL_FORMAT_RGBA_8888: 436 case HAL_PIXEL_FORMAT_BGRA_8888: 437 ALOGE ("%s : Unsupported Pixel format %d", __FUNCTION__, 438 src->format); 439 return -EINVAL; 440 } 441 } 442 443 if (src_rect->l < 0 || (uint32_t)src_rect->r > src->w || 444 src_rect->t < 0 || (uint32_t)src_rect->b > src->h) { 445 // this is always invalid 446 ALOGE ("%s : Invalid source rectangle : src_rect l %d t %d r %d b %d",\ 447 __FUNCTION__, src_rect->l, src_rect->t, src_rect->r, src_rect->b); 448 449 return -EINVAL; 450 } 451 452 if (src->w > MAX_DIMENSION || src->h > MAX_DIMENSION) { 453 ALOGE ("%s : Invalid source dimensions w %d h %d", __FUNCTION__, src->w, src->h); 454 return -EINVAL; 455 } 456 457 if (dst->w > MAX_DIMENSION || dst->h > MAX_DIMENSION) { 458 ALOGE ("%s : Invalid DST dimensions w %d h %d", __FUNCTION__, dst->w, dst->h); 459 return -EINVAL; 460 } 461 462 if(src->format == HAL_PIXEL_FORMAT_YV12) { 463 int usage = 464 GRALLOC_USAGE_PRIVATE_IOMMU_HEAP | GRALLOC_USAGE_PRIVATE_UNCACHED; 465 if (0 == alloc_buffer(&yv12_handle,src->w,src->h, 466 src->format, usage)){ 467 if(0 == convertYV12toYCrCb420SP(src,yv12_handle)){ 468 (const_cast<copybit_image_t *>(src))->format = 469 HAL_PIXEL_FORMAT_YCrCb_420_SP; 470 (const_cast<copybit_image_t *>(src))->handle = 471 yv12_handle; 472 (const_cast<copybit_image_t *>(src))->base = 473 (void *)yv12_handle->base; 474 } 475 else{ 476 ALOGE("Error copybit conversion from yv12 failed"); 477 if(yv12_handle) 478 free_buffer(yv12_handle); 479 return -EINVAL; 480 } 481 } 482 else{ 483 ALOGE("Error:unable to allocate memeory for yv12 software conversion"); 484 return -EINVAL; 485 } 486 } 487 const uint32_t maxCount = sizeof(list->req)/sizeof(list->req[0]); 488 const struct copybit_rect_t bounds = { 0, 0, (int)dst->w, (int)dst->h }; 489 struct copybit_rect_t clip; 490 status = 0; 491 while ((status == 0) && region->next(region, &clip)) { 492 intersect(&clip, &bounds, &clip); 493 mdp_blit_req* req = &list->req[list->count]; 494 int flags = 0; 495 496 private_handle_t* src_hnd = (private_handle_t*)src->handle; 497 if(src_hnd != NULL && src_hnd->flags & private_handle_t::PRIV_FLAGS_DO_NOT_FLUSH) { 498 flags |= MDP_BLIT_NON_CACHED; 499 } 500 501 set_infos(ctx, req, flags); 502 set_image(&req->dst, dst); 503 set_image(&req->src, src); 504 set_rects(ctx, req, dst_rect, src_rect, &clip, src->horiz_padding, src->vert_padding); 505 506 if (req->src_rect.w<=0 || req->src_rect.h<=0) 507 continue; 508 509 if (req->dst_rect.w<=0 || req->dst_rect.h<=0) 510 continue; 511 512 if (++list->count == maxCount) { 513 status = msm_copybit(ctx, list); 514 if (ctx->relFence != -1) { 515 list->sync.acq_fen_fd_cnt = 0; 516 } 517 list->count = 0; 518 } 519 } 520 if(yv12_handle) { 521 //Before freeing the buffer we need buffer passed through blit call 522 if (list->count != 0) { 523 status = msm_copybit(ctx, list); 524 if (ctx->relFence != -1) { 525 list->sync.acq_fen_fd_cnt = 0; 526 } 527 list->count = 0; 528 } 529 free_buffer(yv12_handle); 530 } 531 } else { 532 ALOGE ("%s : Invalid COPYBIT context", __FUNCTION__); 533 status = -EINVAL; 534 } 535 return status; 536 } 537 538 /** Perform a blit type operation */ 539 static int blit_copybit( 540 struct copybit_device_t *dev, 541 struct copybit_image_t const *dst, 542 struct copybit_image_t const *src, 543 struct copybit_region_t const *region) 544 { 545 struct copybit_rect_t dr = { 0, 0, (int)dst->w, (int)dst->h }; 546 struct copybit_rect_t sr = { 0, 0, (int)src->w, (int)src->h }; 547 return stretch_copybit(dev, dst, src, &dr, &sr, region); 548 } 549 550 static int finish_copybit(struct copybit_device_t *dev) 551 { 552 // NOP for MDP copybit 553 return 0; 554 } 555 556 /*****************************************************************************/ 557 558 /** Close the copybit device */ 559 static int close_copybit(struct hw_device_t *dev) 560 { 561 struct copybit_context_t* ctx = (struct copybit_context_t*)dev; 562 if (ctx) { 563 close(ctx->mFD); 564 free(ctx); 565 } 566 return 0; 567 } 568 569 static int flush_get_fence(struct copybit_device_t *dev, int* fd) 570 { 571 struct copybit_context_t* ctx = (struct copybit_context_t*)dev; 572 struct blitReq *list = &ctx->list; 573 int ret = -EINVAL; 574 575 if (list->count) { 576 ret = msm_copybit(ctx, list); 577 if (ret < 0) 578 ALOGE("%s: Blit call failed", __FUNCTION__); 579 list->count = 0; 580 } 581 *fd = ctx->relFence; 582 list->sync.acq_fen_fd_cnt = 0; 583 ctx->relFence = -1; 584 return ret; 585 } 586 587 /** Open a new instance of a copybit device using name */ 588 static int open_copybit(const struct hw_module_t* module, const char* name, 589 struct hw_device_t** device) 590 { 591 int status = -EINVAL; 592 copybit_context_t *ctx; 593 ctx = (copybit_context_t *)malloc(sizeof(copybit_context_t)); 594 memset(ctx, 0, sizeof(*ctx)); 595 596 ctx->device.common.tag = HARDWARE_DEVICE_TAG; 597 ctx->device.common.version = 1; 598 ctx->device.common.module = const_cast<hw_module_t*>(module); 599 ctx->device.common.close = close_copybit; 600 ctx->device.set_parameter = set_parameter_copybit; 601 ctx->device.get = get; 602 ctx->device.blit = blit_copybit; 603 ctx->device.set_sync = set_sync_copybit; 604 ctx->device.stretch = stretch_copybit; 605 ctx->device.finish = finish_copybit; 606 ctx->device.flush_get_fence = flush_get_fence; 607 ctx->mAlpha = MDP_ALPHA_NOP; 608 ctx->mFlags = 0; 609 ctx->sync.flags = 0; 610 ctx->sync.acq_fen_fd = ctx->acqFence; 611 ctx->sync.rel_fen_fd = &ctx->relFence; 612 ctx->list.count = 0; 613 ctx->list.sync.acq_fen_fd_cnt = 0; 614 ctx->list.sync.rel_fen_fd = ctx->sync.rel_fen_fd; 615 ctx->list.sync.acq_fen_fd = ctx->sync.acq_fen_fd; 616 ctx->mFD = open("/dev/graphics/fb0", O_RDWR, 0); 617 if (ctx->mFD < 0) { 618 status = errno; 619 ALOGE("Error opening frame buffer errno=%d (%s)", 620 status, strerror(status)); 621 status = -status; 622 } else { 623 status = 0; 624 *device = &ctx->device.common; 625 } 626 return status; 627 } 628