copybit.cpp revision b46eaaa52014d32f650fa50b6896fee179d9e721
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/******************************************************************************/ 49struct 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 */ 56struct 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 72static int open_copybit(const struct hw_module_t* module, const char* name, 73 struct hw_device_t** device); 74 75static struct hw_module_methods_t copybit_module_methods = { 76open: open_copybit 77}; 78 79/* 80 * The COPYBIT Module 81 */ 82struct copybit_module_t HAL_MODULE_INFO_SYM = { 83common: { 84tag: 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 */ 97static inline int min(int a, int b) { 98 return (a<b) ? a : b; 99} 100 101/** max of int a, b */ 102static 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 */ 107static 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 */ 115static 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 */ 125static 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_CBCR_H2V1; 133 case HAL_PIXEL_FORMAT_YCrCb_420_SP: return MDP_Y_CBCR_H2V2; 134 case HAL_PIXEL_FORMAT_YCbCr_422_SP: return MDP_Y_CRCB_H2V1; 135 case HAL_PIXEL_FORMAT_YCbCr_420_SP: return MDP_Y_CRCB_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_ADRENO; 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 */ 144static 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 */ 158static 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 */ 214static 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 */ 230static 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 */ 272static 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 default: 345 status = -EINVAL; 346 break; 347 } 348 } else { 349 status = -EINVAL; 350 } 351 return status; 352} 353 354/** Get a static info value */ 355static int get(struct copybit_device_t *dev, int name) 356{ 357 struct copybit_context_t* ctx = (struct copybit_context_t*)dev; 358 int value; 359 if (ctx) { 360 switch(name) { 361 case COPYBIT_MINIFICATION_LIMIT: 362 value = MAX_SCALE_FACTOR; 363 break; 364 case COPYBIT_MAGNIFICATION_LIMIT: 365 value = MAX_SCALE_FACTOR; 366 break; 367 case COPYBIT_SCALING_FRAC_BITS: 368 value = 32; 369 break; 370 case COPYBIT_ROTATION_STEP_DEG: 371 value = 90; 372 break; 373 default: 374 value = -EINVAL; 375 } 376 } else { 377 value = -EINVAL; 378 } 379 return value; 380} 381 382static int set_sync_copybit(struct copybit_device_t *dev, 383 int acquireFenceFd) 384{ 385 struct copybit_context_t* ctx = (struct copybit_context_t*)dev; 386 if (acquireFenceFd != -1) { 387 if (ctx->sync.acq_fen_fd_cnt < (MDP_MAX_FENCE_FD - 1)) { 388 ctx->acqFence[ctx->sync.acq_fen_fd_cnt++] = acquireFenceFd; 389 } else { 390 int ret = -EINVAL; 391 struct blitReq *list = &ctx->list; 392 393 // Since fence is full kick off what is already in the list 394 ret = msm_copybit(ctx, list); 395 if (ret < 0) { 396 ALOGE("%s: Blit call failed", __FUNCTION__); 397 return -EINVAL; 398 } 399 list->count = 0; 400 ctx->sync.acq_fen_fd_cnt = 0; 401 ctx->acqFence[ctx->sync.acq_fen_fd_cnt++] = ctx->relFence; 402 ctx->acqFence[ctx->sync.acq_fen_fd_cnt++] = acquireFenceFd; 403 ctx->relFence = -1; 404 } 405 } 406 return 0; 407} 408 409/** do a stretch blit type operation */ 410static int stretch_copybit( 411 struct copybit_device_t *dev, 412 struct copybit_image_t const *dst, 413 struct copybit_image_t const *src, 414 struct copybit_rect_t const *dst_rect, 415 struct copybit_rect_t const *src_rect, 416 struct copybit_region_t const *region) 417{ 418 struct copybit_context_t* ctx = (struct copybit_context_t*)dev; 419 struct blitReq *list; 420 int status = 0; 421 private_handle_t *yv12_handle = NULL; 422 423 if (ctx) { 424 list = &ctx->list; 425 426 if (ctx->mAlpha < 255) { 427 switch (src->format) { 428 // we don't support plane alpha with RGBA formats 429 case HAL_PIXEL_FORMAT_RGBA_8888: 430 case HAL_PIXEL_FORMAT_BGRA_8888: 431 case HAL_PIXEL_FORMAT_RGBA_5551: 432 case HAL_PIXEL_FORMAT_RGBA_4444: 433 ALOGE ("%s : Unsupported Pixel format %d", __FUNCTION__, 434 src->format); 435 return -EINVAL; 436 } 437 } 438 439 if (src_rect->l < 0 || (uint32_t)src_rect->r > src->w || 440 src_rect->t < 0 || (uint32_t)src_rect->b > src->h) { 441 // this is always invalid 442 ALOGE ("%s : Invalid source rectangle : src_rect l %d t %d r %d b %d",\ 443 __FUNCTION__, src_rect->l, src_rect->t, src_rect->r, src_rect->b); 444 445 return -EINVAL; 446 } 447 448 if (src->w > MAX_DIMENSION || src->h > MAX_DIMENSION) { 449 ALOGE ("%s : Invalid source dimensions w %d h %d", __FUNCTION__, src->w, src->h); 450 return -EINVAL; 451 } 452 453 if (dst->w > MAX_DIMENSION || dst->h > MAX_DIMENSION) { 454 ALOGE ("%s : Invalid DST dimensions w %d h %d", __FUNCTION__, dst->w, dst->h); 455 return -EINVAL; 456 } 457 458 if(src->format == HAL_PIXEL_FORMAT_YV12) { 459 int usage = 460 GRALLOC_USAGE_PRIVATE_IOMMU_HEAP | GRALLOC_USAGE_PRIVATE_UNCACHED; 461 if (0 == alloc_buffer(&yv12_handle,src->w,src->h, 462 src->format, usage)){ 463 if(0 == convertYV12toYCrCb420SP(src,yv12_handle)){ 464 (const_cast<copybit_image_t *>(src))->format = 465 HAL_PIXEL_FORMAT_YCrCb_420_SP; 466 (const_cast<copybit_image_t *>(src))->handle = 467 yv12_handle; 468 (const_cast<copybit_image_t *>(src))->base = 469 (void *)yv12_handle->base; 470 } 471 else{ 472 ALOGE("Error copybit conversion from yv12 failed"); 473 if(yv12_handle) 474 free_buffer(yv12_handle); 475 return -EINVAL; 476 } 477 } 478 else{ 479 ALOGE("Error:unable to allocate memeory for yv12 software conversion"); 480 return -EINVAL; 481 } 482 } 483 const uint32_t maxCount = sizeof(list->req)/sizeof(list->req[0]); 484 const struct copybit_rect_t bounds = { 0, 0, (int)dst->w, (int)dst->h }; 485 struct copybit_rect_t clip; 486 status = 0; 487 while ((status == 0) && region->next(region, &clip)) { 488 intersect(&clip, &bounds, &clip); 489 mdp_blit_req* req = &list->req[list->count]; 490 int flags = 0; 491 492 private_handle_t* src_hnd = (private_handle_t*)src->handle; 493 if(src_hnd != NULL && src_hnd->flags & private_handle_t::PRIV_FLAGS_DO_NOT_FLUSH) { 494 flags |= MDP_BLIT_NON_CACHED; 495 } 496 497 set_infos(ctx, req, flags); 498 set_image(&req->dst, dst); 499 set_image(&req->src, src); 500 set_rects(ctx, req, dst_rect, src_rect, &clip, src->horiz_padding, src->vert_padding); 501 502 if (req->src_rect.w<=0 || req->src_rect.h<=0) 503 continue; 504 505 if (req->dst_rect.w<=0 || req->dst_rect.h<=0) 506 continue; 507 508 if (++list->count == maxCount) { 509 status = msm_copybit(ctx, list); 510 if (ctx->relFence != -1) { 511 ctx->sync.acq_fen_fd_cnt = 1; 512 ctx->sync.acq_fen_fd[0] = ctx->relFence; 513 } else { 514 ctx->sync.acq_fen_fd_cnt = 0; 515 } 516 list->count = 0; 517 } 518 } 519 } else { 520 ALOGE ("%s : Invalid COPYBIT context", __FUNCTION__); 521 status = -EINVAL; 522 } 523 if(yv12_handle) 524 free_buffer(yv12_handle); 525 return status; 526} 527 528/** Perform a blit type operation */ 529static int blit_copybit( 530 struct copybit_device_t *dev, 531 struct copybit_image_t const *dst, 532 struct copybit_image_t const *src, 533 struct copybit_region_t const *region) 534{ 535 struct copybit_rect_t dr = { 0, 0, (int)dst->w, (int)dst->h }; 536 struct copybit_rect_t sr = { 0, 0, (int)src->w, (int)src->h }; 537 return stretch_copybit(dev, dst, src, &dr, &sr, region); 538} 539 540static int finish_copybit(struct copybit_device_t *dev) 541{ 542 // NOP for MDP copybit 543 return 0; 544} 545 546/*****************************************************************************/ 547 548/** Close the copybit device */ 549static int close_copybit(struct hw_device_t *dev) 550{ 551 struct copybit_context_t* ctx = (struct copybit_context_t*)dev; 552 if (ctx) { 553 close(ctx->mFD); 554 free(ctx); 555 } 556 return 0; 557} 558 559static int flush_get_fence(struct copybit_device_t *dev, int* fd) 560{ 561 struct copybit_context_t* ctx = (struct copybit_context_t*)dev; 562 struct blitReq *list = &ctx->list; 563 int ret = -EINVAL; 564 565 if (list->count) { 566 ret = msm_copybit(ctx, list); 567 if (ret < 0) 568 ALOGE("%s: Blit call failed", __FUNCTION__); 569 list->count = 0; 570 ctx->sync.acq_fen_fd_cnt = 0; 571 } 572 *fd = ctx->relFence; 573 ctx->relFence = -1; 574 return ret; 575} 576 577/** Open a new instance of a copybit device using name */ 578static int open_copybit(const struct hw_module_t* module, const char* name, 579 struct hw_device_t** device) 580{ 581 int status = -EINVAL; 582 copybit_context_t *ctx; 583 ctx = (copybit_context_t *)malloc(sizeof(copybit_context_t)); 584 memset(ctx, 0, sizeof(*ctx)); 585 586 ctx->device.common.tag = HARDWARE_DEVICE_TAG; 587 ctx->device.common.version = 1; 588 ctx->device.common.module = const_cast<hw_module_t*>(module); 589 ctx->device.common.close = close_copybit; 590 ctx->device.set_parameter = set_parameter_copybit; 591 ctx->device.get = get; 592 ctx->device.blit = blit_copybit; 593 ctx->device.set_sync = set_sync_copybit; 594 ctx->device.stretch = stretch_copybit; 595 ctx->device.finish = finish_copybit; 596 ctx->device.flush_get_fence = flush_get_fence; 597 ctx->mAlpha = MDP_ALPHA_NOP; 598 ctx->mFlags = 0; 599 ctx->sync.flags = 0; 600 ctx->sync.acq_fen_fd_cnt = 0; 601 ctx->sync.acq_fen_fd = ctx->acqFence; 602 ctx->sync.rel_fen_fd = &ctx->relFence; 603 ctx->list.count = 0; 604 ctx->list.sync.rel_fen_fd = ctx->sync.rel_fen_fd; 605 ctx->list.sync.acq_fen_fd = ctx->sync.acq_fen_fd; 606 ctx->mFD = open("/dev/graphics/fb0", O_RDWR, 0); 607 if (ctx->mFD < 0) { 608 status = errno; 609 ALOGE("Error opening frame buffer errno=%d (%s)", 610 status, strerror(status)); 611 status = -status; 612 } else { 613 status = 0; 614 *device = &ctx->device.common; 615 } 616 return status; 617} 618