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