1 /* 2 * Copyright (C) 2008 The Android Open Source Project 3 * Copyright (c) 2010 - 2014, 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 <errno.h> 22 #include <fcntl.h> 23 #include <linux/msm_mdp.h> 24 #include <linux/fb.h> 25 #include <stdint.h> 26 #include <string.h> 27 #include <sys/ioctl.h> 28 #include <sys/mman.h> 29 #include <sys/types.h> 30 #include <unistd.h> 31 32 #include <log/log.h> 33 34 #include <copybit.h> 35 36 #include "gralloc_priv.h" 37 #include "software_converter.h" 38 #include <qdMetaData.h> 39 40 #define DEBUG_MDP_ERRORS 1 41 42 /******************************************************************************/ 43 44 #define MAX_SCALE_FACTOR (4) 45 #define MAX_DIMENSION (4096) 46 47 /******************************************************************************/ 48 struct blitReq{ 49 struct mdp_buf_sync sync; 50 uint32_t count; 51 struct mdp_blit_req req[10]; 52 }; 53 54 /** State information for each device instance */ 55 struct copybit_context_t { 56 struct copybit_device_t device; 57 int mFD; 58 uint8_t mAlpha; 59 int mFlags; 60 bool mBlitToFB; 61 int acqFence[MDP_MAX_FENCE_FD]; 62 int relFence; 63 struct mdp_buf_sync sync; 64 struct blitReq list; 65 uint8_t dynamic_fps; 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 static bool validateCopybitRect(struct copybit_rect_t *rect) { 125 return ((rect->b > rect->t) && (rect->r > rect->l)) ; 126 } 127 128 /** convert COPYBIT_FORMAT to MDP format */ 129 static int get_format(int format) { 130 switch (format) { 131 case HAL_PIXEL_FORMAT_RGB_565: return MDP_RGB_565; 132 case HAL_PIXEL_FORMAT_RGBA_5551: return MDP_RGBA_5551; 133 case HAL_PIXEL_FORMAT_RGBA_4444: return MDP_RGBA_4444; 134 case HAL_PIXEL_FORMAT_RGBX_8888: return MDP_RGBX_8888; 135 case HAL_PIXEL_FORMAT_BGRX_8888: return MDP_BGRX_8888; 136 case HAL_PIXEL_FORMAT_RGB_888: return MDP_RGB_888; 137 case HAL_PIXEL_FORMAT_RGBA_8888: return MDP_RGBA_8888; 138 case HAL_PIXEL_FORMAT_BGRA_8888: return MDP_BGRA_8888; 139 case HAL_PIXEL_FORMAT_YCrCb_422_I: return MDP_YCRYCB_H2V1; 140 case HAL_PIXEL_FORMAT_YCbCr_422_I: return MDP_YCBYCR_H2V1; 141 case HAL_PIXEL_FORMAT_YCrCb_422_SP: return MDP_Y_CRCB_H2V1; 142 case HAL_PIXEL_FORMAT_YCrCb_420_SP: return MDP_Y_CRCB_H2V2; 143 case HAL_PIXEL_FORMAT_YCbCr_422_SP: return MDP_Y_CBCR_H2V1; 144 case HAL_PIXEL_FORMAT_YCbCr_420_SP: return MDP_Y_CBCR_H2V2; 145 case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO: return MDP_Y_CBCR_H2V2_ADRENO; 146 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS: return MDP_Y_CBCR_H2V2_VENUS; 147 case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS: return MDP_Y_CRCB_H2V2_VENUS; 148 case HAL_PIXEL_FORMAT_NV12_ENCODEABLE: return MDP_Y_CBCR_H2V2; 149 case HAL_PIXEL_FORMAT_CbYCrY_422_I: return MDP_CBYCRY_H2V1; 150 case HAL_PIXEL_FORMAT_BGR_888: return MDP_BGR_888; 151 } 152 return -1; 153 } 154 155 /** convert from copybit image to mdp image structure */ 156 static void set_image(struct mdp_img *img, const struct copybit_image_t *rhs) 157 { 158 private_handle_t* hnd = (private_handle_t*)rhs->handle; 159 if(hnd == NULL){ 160 ALOGE("copybit: Invalid handle"); 161 return; 162 } 163 img->width = rhs->w; 164 img->height = rhs->h; 165 img->format = get_format(rhs->format); 166 img->offset = (uint32_t)hnd->offset; 167 img->memory_id = hnd->fd; 168 } 169 /** setup rectangles */ 170 static bool set_rects(struct copybit_context_t *dev, 171 struct mdp_blit_req *e, 172 const struct copybit_rect_t *dst, 173 const struct copybit_rect_t *src, 174 const struct copybit_rect_t *scissor) { 175 struct copybit_rect_t clip; 176 intersect(&clip, scissor, dst); 177 178 if (!validateCopybitRect(&clip)) 179 return false; 180 181 e->dst_rect.x = clip.l; 182 e->dst_rect.y = clip.t; 183 e->dst_rect.w = clip.r - clip.l; 184 e->dst_rect.h = clip.b - clip.t; 185 186 uint32_t W, H, delta_x, delta_y; 187 if (dev->mFlags & COPYBIT_TRANSFORM_ROT_90) { 188 delta_x = (clip.t - dst->t); 189 delta_y = (dst->r - clip.r); 190 e->src_rect.w = (clip.b - clip.t); 191 e->src_rect.h = (clip.r - clip.l); 192 W = dst->b - dst->t; 193 H = dst->r - dst->l; 194 } else { 195 delta_x = (clip.l - dst->l); 196 delta_y = (clip.t - dst->t); 197 e->src_rect.w = (clip.r - clip.l); 198 e->src_rect.h = (clip.b - clip.t); 199 W = dst->r - dst->l; 200 H = dst->b - dst->t; 201 } 202 203 MULDIV(&delta_x, &e->src_rect.w, src->r - src->l, W); 204 MULDIV(&delta_y, &e->src_rect.h, src->b - src->t, H); 205 206 e->src_rect.x = delta_x + src->l; 207 e->src_rect.y = delta_y + src->t; 208 209 if (dev->mFlags & COPYBIT_TRANSFORM_FLIP_V) { 210 if (dev->mFlags & COPYBIT_TRANSFORM_ROT_90) { 211 e->src_rect.x = (src->l + src->r) - (e->src_rect.x + e->src_rect.w); 212 }else{ 213 e->src_rect.y = (src->t + src->b) - (e->src_rect.y + e->src_rect.h); 214 } 215 } 216 217 if (dev->mFlags & COPYBIT_TRANSFORM_FLIP_H) { 218 if (dev->mFlags & COPYBIT_TRANSFORM_ROT_90) { 219 e->src_rect.y = (src->t + src->b) - (e->src_rect.y + e->src_rect.h); 220 }else{ 221 e->src_rect.x = (src->l + src->r) - (e->src_rect.x + e->src_rect.w); 222 } 223 } 224 return true; 225 } 226 227 /** setup mdp request */ 228 static void set_infos(struct copybit_context_t *dev, 229 struct mdp_blit_req *req, int flags) 230 { 231 req->alpha = dev->mAlpha; 232 req->fps = dev->dynamic_fps; 233 req->transp_mask = MDP_TRANSP_NOP; 234 req->flags = dev->mFlags | flags; 235 // check if we are blitting to f/b 236 if (COPYBIT_ENABLE == dev->mBlitToFB) { 237 req->flags |= MDP_MEMORY_ID_TYPE_FB; 238 } 239 #if defined(COPYBIT_QSD8K) 240 req->flags |= MDP_BLEND_FG_PREMULT; 241 #endif 242 } 243 244 /** copy the bits */ 245 static int msm_copybit(struct copybit_context_t *dev, void const *list) 246 { 247 int err; 248 if (dev->relFence != -1) { 249 close(dev->relFence); 250 dev->relFence = -1; 251 } 252 err = ioctl(dev->mFD, MSMFB_ASYNC_BLIT, 253 (struct mdp_async_blit_req_list const*)list); 254 ALOGE_IF(err<0, "copyBits failed (%s)", strerror(errno)); 255 if (err == 0) { 256 return 0; 257 } else { 258 #if DEBUG_MDP_ERRORS 259 struct mdp_async_blit_req_list const* l = 260 (struct mdp_async_blit_req_list const*)list; 261 for (unsigned int i=0 ; i<l->count ; i++) { 262 ALOGE("%d: src={w=%d, h=%d, f=%d, rect={%d,%d,%d,%d}}\n" 263 " dst={w=%d, h=%d, f=%d, rect={%d,%d,%d,%d}}\n" 264 " flags=%08x, fps=%d" 265 , 266 i, 267 l->req[i].src.width, 268 l->req[i].src.height, 269 l->req[i].src.format, 270 l->req[i].src_rect.x, 271 l->req[i].src_rect.y, 272 l->req[i].src_rect.w, 273 l->req[i].src_rect.h, 274 l->req[i].dst.width, 275 l->req[i].dst.height, 276 l->req[i].dst.format, 277 l->req[i].dst_rect.x, 278 l->req[i].dst_rect.y, 279 l->req[i].dst_rect.w, 280 l->req[i].dst_rect.h, 281 l->req[i].flags, 282 l->req[i].fps 283 ); 284 } 285 #endif 286 return -errno; 287 } 288 } 289 290 /*****************************************************************************/ 291 292 /** Set a parameter to value */ 293 static int set_parameter_copybit( 294 struct copybit_device_t *dev, 295 int name, 296 int value) 297 { 298 struct copybit_context_t* ctx = (struct copybit_context_t*)dev; 299 int status = 0; 300 if (ctx) { 301 switch(name) { 302 case COPYBIT_ROTATION_DEG: 303 switch (value) { 304 case 0: 305 ctx->mFlags &= ~0x7; 306 break; 307 case 90: 308 ctx->mFlags &= ~0x7; 309 ctx->mFlags |= MDP_ROT_90; 310 break; 311 case 180: 312 ctx->mFlags &= ~0x7; 313 ctx->mFlags |= MDP_ROT_180; 314 break; 315 case 270: 316 ctx->mFlags &= ~0x7; 317 ctx->mFlags |= MDP_ROT_270; 318 break; 319 default: 320 ALOGE("Invalid value for COPYBIT_ROTATION_DEG"); 321 status = -EINVAL; 322 break; 323 } 324 break; 325 case COPYBIT_PLANE_ALPHA: 326 if (value < 0) value = MDP_ALPHA_NOP; 327 if (value >= 256) value = 255; 328 ctx->mAlpha = (uint8_t)value; 329 break; 330 case COPYBIT_DYNAMIC_FPS: 331 ctx->dynamic_fps = (uint8_t)value; 332 break; 333 case COPYBIT_DITHER: 334 if (value == COPYBIT_ENABLE) { 335 ctx->mFlags |= MDP_DITHER; 336 } else if (value == COPYBIT_DISABLE) { 337 ctx->mFlags &= ~MDP_DITHER; 338 } 339 break; 340 case COPYBIT_BLUR: 341 if (value == COPYBIT_ENABLE) { 342 ctx->mFlags |= MDP_BLUR; 343 } else if (value == COPYBIT_DISABLE) { 344 ctx->mFlags &= ~MDP_BLUR; 345 } 346 break; 347 case COPYBIT_BLEND_MODE: 348 if(value == COPYBIT_BLENDING_PREMULT) { 349 ctx->mFlags |= MDP_BLEND_FG_PREMULT; 350 } else { 351 ctx->mFlags &= ~MDP_BLEND_FG_PREMULT; 352 } 353 break; 354 case COPYBIT_TRANSFORM: 355 ctx->mFlags &= ~0x7; 356 ctx->mFlags |= value & 0x7; 357 break; 358 case COPYBIT_BLIT_TO_FRAMEBUFFER: 359 if (COPYBIT_ENABLE == value) { 360 ctx->mBlitToFB = value; 361 } else if (COPYBIT_DISABLE == value) { 362 ctx->mBlitToFB = value; 363 } else { 364 ALOGE ("%s:Invalid input for COPYBIT_BLIT_TO_FRAMEBUFFER : %d", 365 __FUNCTION__, value); 366 } 367 break; 368 case COPYBIT_FG_LAYER: 369 if(value == COPYBIT_ENABLE) { 370 ctx->mFlags |= MDP_IS_FG; 371 } else if (value == COPYBIT_DISABLE) { 372 ctx->mFlags &= ~MDP_IS_FG; 373 } 374 break ; 375 default: 376 status = -EINVAL; 377 break; 378 } 379 } else { 380 status = -EINVAL; 381 } 382 return status; 383 } 384 385 /** Get a static info value */ 386 static int get(struct copybit_device_t *dev, int name) 387 { 388 struct copybit_context_t* ctx = (struct copybit_context_t*)dev; 389 int value; 390 if (ctx) { 391 switch(name) { 392 case COPYBIT_MINIFICATION_LIMIT: 393 value = MAX_SCALE_FACTOR; 394 break; 395 case COPYBIT_MAGNIFICATION_LIMIT: 396 value = MAX_SCALE_FACTOR; 397 break; 398 case COPYBIT_SCALING_FRAC_BITS: 399 value = 32; 400 break; 401 case COPYBIT_ROTATION_STEP_DEG: 402 value = 90; 403 break; 404 default: 405 value = -EINVAL; 406 } 407 } else { 408 value = -EINVAL; 409 } 410 return value; 411 } 412 413 static int set_sync_copybit(struct copybit_device_t *dev, 414 int acquireFenceFd) 415 { 416 struct copybit_context_t* ctx = (struct copybit_context_t*)dev; 417 if (acquireFenceFd != -1) { 418 if (ctx->list.sync.acq_fen_fd_cnt < (MDP_MAX_FENCE_FD - 1)) { 419 ctx->acqFence[ctx->list.sync.acq_fen_fd_cnt++] = acquireFenceFd; 420 } else { 421 int ret = -EINVAL; 422 struct blitReq *list = &ctx->list; 423 424 // Since fence is full kick off what is already in the list 425 ret = msm_copybit(ctx, list); 426 if (ret < 0) { 427 ALOGE("%s: Blit call failed", __FUNCTION__); 428 return -EINVAL; 429 } 430 list->count = 0; 431 list->sync.acq_fen_fd_cnt = 0; 432 ctx->acqFence[list->sync.acq_fen_fd_cnt++] = acquireFenceFd; 433 } 434 } 435 return 0; 436 } 437 438 /** do a stretch blit type operation */ 439 static int stretch_copybit( 440 struct copybit_device_t *dev, 441 struct copybit_image_t const *dst, 442 struct copybit_image_t const *src, 443 struct copybit_rect_t const *dst_rect, 444 struct copybit_rect_t const *src_rect, 445 struct copybit_region_t const *region) 446 { 447 struct copybit_context_t* ctx = (struct copybit_context_t*)dev; 448 struct blitReq *list; 449 int status = 0; 450 private_handle_t *yv12_handle = NULL; 451 452 if (ctx) { 453 list = &ctx->list; 454 455 if (ctx->mAlpha < 255) { 456 switch (src->format) { 457 // we don't support plane alpha with RGBA formats 458 case HAL_PIXEL_FORMAT_RGBA_8888: 459 case HAL_PIXEL_FORMAT_BGRA_8888: 460 case HAL_PIXEL_FORMAT_RGBA_5551: 461 case HAL_PIXEL_FORMAT_RGBA_4444: 462 ALOGE ("%s : Unsupported Pixel format %d", __FUNCTION__, 463 src->format); 464 return -EINVAL; 465 } 466 } 467 468 if (src_rect->l < 0 || (uint32_t)src_rect->r > src->w || 469 src_rect->t < 0 || (uint32_t)src_rect->b > src->h) { 470 // this is always invalid 471 ALOGE ("%s : Invalid source rectangle : src_rect l %d t %d r %d b %d",\ 472 __FUNCTION__, src_rect->l, src_rect->t, src_rect->r, src_rect->b); 473 474 return -EINVAL; 475 } 476 477 if (src->w > MAX_DIMENSION || src->h > MAX_DIMENSION) { 478 ALOGE ("%s : Invalid source dimensions w %d h %d", __FUNCTION__, src->w, src->h); 479 return -EINVAL; 480 } 481 482 if (dst->w > MAX_DIMENSION || dst->h > MAX_DIMENSION) { 483 ALOGE ("%s : Invalid DST dimensions w %d h %d", __FUNCTION__, dst->w, dst->h); 484 return -EINVAL; 485 } 486 487 if(src->format == HAL_PIXEL_FORMAT_YV12) { 488 int usage = 489 GRALLOC_USAGE_PRIVATE_IOMMU_HEAP | GRALLOC_USAGE_PRIVATE_UNCACHED; 490 if (0 == alloc_buffer(&yv12_handle,src->w,src->h, 491 src->format, usage)){ 492 if(0 == convertYV12toYCrCb420SP(src,yv12_handle)){ 493 (const_cast<copybit_image_t *>(src))->format = 494 HAL_PIXEL_FORMAT_YCrCb_420_SP; 495 (const_cast<copybit_image_t *>(src))->handle = 496 yv12_handle; 497 (const_cast<copybit_image_t *>(src))->base = 498 (void *)yv12_handle->base; 499 } 500 else{ 501 ALOGE("Error copybit conversion from yv12 failed"); 502 if(yv12_handle) 503 free_buffer(yv12_handle); 504 return -EINVAL; 505 } 506 } 507 else{ 508 ALOGE("Error:unable to allocate memeory for yv12 software conversion"); 509 return -EINVAL; 510 } 511 } 512 const uint32_t maxCount = 513 (uint32_t)(sizeof(list->req)/sizeof(list->req[0])); 514 const struct copybit_rect_t bounds = { 0, 0, (int)dst->w, (int)dst->h }; 515 struct copybit_rect_t clip; 516 status = 0; 517 while ((status == 0) && region->next(region, &clip)) { 518 intersect(&clip, &bounds, &clip); 519 mdp_blit_req* req = &list->req[list->count]; 520 int flags = 0; 521 522 private_handle_t* src_hnd = (private_handle_t*)src->handle; 523 if(src_hnd != NULL && 524 (!(src_hnd->flags & private_handle_t::PRIV_FLAGS_CACHED))) { 525 flags |= MDP_BLIT_NON_CACHED; 526 } 527 528 // Set Color Space for MDP to configure CSC matrix 529 req->color_space = ITU_R_601; 530 MetaData_t *metadata = NULL; 531 532 if (src_hnd != NULL) 533 metadata = (MetaData_t *)src_hnd->base_metadata; 534 535 if (metadata && (metadata->operation & UPDATE_COLOR_SPACE)) { 536 req->color_space = metadata->colorSpace; 537 } 538 539 set_infos(ctx, req, flags); 540 set_image(&req->dst, dst); 541 set_image(&req->src, src); 542 if (set_rects(ctx, req, dst_rect, src_rect, &clip) == false) 543 continue; 544 545 if (req->src_rect.w<=0 || req->src_rect.h<=0) 546 continue; 547 548 if (req->dst_rect.w<=0 || req->dst_rect.h<=0) 549 continue; 550 551 if (++list->count == maxCount) { 552 status = msm_copybit(ctx, list); 553 list->sync.acq_fen_fd_cnt = 0; 554 list->count = 0; 555 } 556 } 557 if(yv12_handle) { 558 //Before freeing the buffer we need buffer passed through blit call 559 if (list->count != 0) { 560 status = msm_copybit(ctx, list); 561 list->sync.acq_fen_fd_cnt = 0; 562 list->count = 0; 563 } 564 free_buffer(yv12_handle); 565 } 566 } else { 567 ALOGE ("%s : Invalid COPYBIT context", __FUNCTION__); 568 status = -EINVAL; 569 } 570 return status; 571 } 572 573 /** Perform a blit type operation */ 574 static int blit_copybit( 575 struct copybit_device_t *dev, 576 struct copybit_image_t const *dst, 577 struct copybit_image_t const *src, 578 struct copybit_region_t const *region) 579 { 580 struct copybit_rect_t dr = { 0, 0, (int)dst->w, (int)dst->h }; 581 struct copybit_rect_t sr = { 0, 0, (int)src->w, (int)src->h }; 582 return stretch_copybit(dev, dst, src, &dr, &sr, region); 583 } 584 585 static int finish_copybit(struct copybit_device_t *dev) 586 { 587 // NOP for MDP copybit 588 if(!dev) 589 return -EINVAL; 590 591 return 0; 592 } 593 static int clear_copybit(struct copybit_device_t *dev, 594 struct copybit_image_t const *buf, 595 struct copybit_rect_t *rect) 596 { 597 struct copybit_context_t* ctx = (struct copybit_context_t*)dev; 598 uint32_t color = 0; // black color 599 600 if (!ctx) { 601 ALOGE ("%s: Invalid copybit context", __FUNCTION__); 602 return -EINVAL; 603 } 604 605 struct blitReq list1; 606 memset((char *)&list1 , 0 ,sizeof (struct blitReq) ); 607 list1.count = 1; 608 int my_tmp_get_fence = -1; 609 610 list1.sync.acq_fen_fd = ctx->acqFence; 611 list1.sync.rel_fen_fd = &my_tmp_get_fence; 612 list1.sync.acq_fen_fd_cnt = ctx->list.sync.acq_fen_fd_cnt; 613 mdp_blit_req* req = &list1.req[0]; 614 615 if(!req) { 616 ALOGE ("%s : Invalid request", __FUNCTION__); 617 return -EINVAL; 618 } 619 620 set_image(&req->dst, buf); 621 set_image(&req->src, buf); 622 623 if (rect->l < 0 || (uint32_t)(rect->r - rect->l) > req->dst.width || 624 rect->t < 0 || (uint32_t)(rect->b - rect->t) > req->dst.height) { 625 ALOGE ("%s : Invalid rect : src_rect l %d t %d r %d b %d",\ 626 __FUNCTION__, rect->l, rect->t, rect->r, rect->b); 627 return -EINVAL; 628 } 629 630 req->dst_rect.x = rect->l; 631 req->dst_rect.y = rect->t; 632 req->dst_rect.w = rect->r - rect->l; 633 req->dst_rect.h = rect->b - rect->t; 634 635 req->src_rect = req->dst_rect; 636 637 req->const_color.b = (uint32_t)((color >> 16) & 0xff); 638 req->const_color.g = (uint32_t)((color >> 8) & 0xff); 639 req->const_color.r = (uint32_t)((color >> 0) & 0xff); 640 req->const_color.alpha = MDP_ALPHA_NOP; 641 642 req->transp_mask = MDP_TRANSP_NOP; 643 req->flags = MDP_SOLID_FILL | MDP_MEMORY_ID_TYPE_FB | MDP_BLEND_FG_PREMULT; 644 int status = msm_copybit(ctx, &list1); 645 646 ctx->list.sync.acq_fen_fd_cnt = 0; 647 if (my_tmp_get_fence != -1) 648 close(my_tmp_get_fence); 649 650 return status; 651 } 652 653 /** Fill the rect on dst with RGBA color **/ 654 static int fill_color(struct copybit_device_t *dev, 655 struct copybit_image_t const *dst, 656 struct copybit_rect_t const *rect, 657 uint32_t color) 658 { 659 struct copybit_context_t* ctx = (struct copybit_context_t*)dev; 660 if (!ctx) { 661 ALOGE("%s: Invalid copybit context", __FUNCTION__); 662 return -EINVAL; 663 } 664 665 if (dst->w > MAX_DIMENSION || dst->h > MAX_DIMENSION) { 666 ALOGE("%s: Invalid DST w=%d h=%d", __FUNCTION__, dst->w, dst->h); 667 return -EINVAL; 668 } 669 670 if (rect->l < 0 || (uint32_t)(rect->r - rect->l) > dst->w || 671 rect->t < 0 || (uint32_t)(rect->b - rect->t) > dst->h) { 672 ALOGE("%s: Invalid destination rect: l=%d t=%d r=%d b=%d", 673 __FUNCTION__, rect->l, rect->t, rect->r, rect->b); 674 return -EINVAL; 675 } 676 677 int status = 0; 678 struct blitReq* list = &ctx->list; 679 mdp_blit_req* req = &list->req[list->count++]; 680 set_infos(ctx, req, MDP_SOLID_FILL); 681 set_image(&req->src, dst); 682 set_image(&req->dst, dst); 683 684 req->dst_rect.x = rect->l; 685 req->dst_rect.y = rect->t; 686 req->dst_rect.w = rect->r - rect->l; 687 req->dst_rect.h = rect->b - rect->t; 688 req->src_rect = req->dst_rect; 689 690 req->const_color.r = (uint32_t)((color >> 0) & 0xff); 691 req->const_color.g = (uint32_t)((color >> 8) & 0xff); 692 req->const_color.b = (uint32_t)((color >> 16) & 0xff); 693 req->const_color.alpha = (uint32_t)((color >> 24) & 0xff); 694 695 if (list->count == sizeof(list->req)/sizeof(list->req[0])) { 696 status = msm_copybit(ctx, list); 697 list->sync.acq_fen_fd_cnt = 0; 698 list->count = 0; 699 } 700 return status; 701 } 702 703 /*****************************************************************************/ 704 705 /** Close the copybit device */ 706 static int close_copybit(struct hw_device_t *dev) 707 { 708 struct copybit_context_t* ctx = (struct copybit_context_t*)dev; 709 if (ctx) { 710 close(ctx->mFD); 711 free(ctx); 712 } 713 return 0; 714 } 715 716 static int flush_get_fence(struct copybit_device_t *dev, int* fd) 717 { 718 struct copybit_context_t* ctx = (struct copybit_context_t*)dev; 719 struct blitReq *list = &ctx->list; 720 int ret = -EINVAL; 721 722 if (list->count) { 723 ret = msm_copybit(ctx, list); 724 if (ret < 0) 725 ALOGE("%s: Blit call failed", __FUNCTION__); 726 list->count = 0; 727 } 728 *fd = ctx->relFence; 729 list->sync.acq_fen_fd_cnt = 0; 730 ctx->relFence = -1; 731 return ret; 732 } 733 734 /** Open a new instance of a copybit device using name */ 735 static int open_copybit(const struct hw_module_t* module, const char* name, 736 struct hw_device_t** device) 737 { 738 int status = -EINVAL; 739 740 if (strcmp(name, COPYBIT_HARDWARE_COPYBIT0)) { 741 return COPYBIT_FAILURE; 742 } 743 copybit_context_t *ctx; 744 ctx = (copybit_context_t *)malloc(sizeof(copybit_context_t)); 745 746 if (ctx == NULL ) { 747 return COPYBIT_FAILURE; 748 } 749 750 memset(ctx, 0, sizeof(*ctx)); 751 752 ctx->device.common.tag = HARDWARE_DEVICE_TAG; 753 ctx->device.common.version = 1; 754 ctx->device.common.module = const_cast<hw_module_t*>(module); 755 ctx->device.common.close = close_copybit; 756 ctx->device.set_parameter = set_parameter_copybit; 757 ctx->device.get = get; 758 ctx->device.blit = blit_copybit; 759 ctx->device.set_sync = set_sync_copybit; 760 ctx->device.stretch = stretch_copybit; 761 ctx->device.finish = finish_copybit; 762 ctx->device.fill_color = fill_color; 763 ctx->device.flush_get_fence = flush_get_fence; 764 ctx->device.clear = clear_copybit; 765 ctx->mAlpha = MDP_ALPHA_NOP; 766 //dynamic_fps is zero means default 767 //panel refresh rate for driver. 768 ctx->dynamic_fps = 0; 769 ctx->mFlags = 0; 770 ctx->sync.flags = 0; 771 ctx->relFence = -1; 772 for (int i=0; i < MDP_MAX_FENCE_FD; i++) { 773 ctx->acqFence[i] = -1; 774 } 775 ctx->sync.acq_fen_fd = ctx->acqFence; 776 ctx->sync.rel_fen_fd = &ctx->relFence; 777 ctx->list.count = 0; 778 ctx->list.sync.acq_fen_fd_cnt = 0; 779 ctx->list.sync.rel_fen_fd = ctx->sync.rel_fen_fd; 780 ctx->list.sync.acq_fen_fd = ctx->sync.acq_fen_fd; 781 ctx->mFD = open("/dev/graphics/fb0", O_RDWR, 0); 782 if (ctx->mFD < 0) { 783 status = errno; 784 ALOGE("Error opening frame buffer errno=%d (%s)", 785 status, strerror(status)); 786 status = -status; 787 } else { 788 status = 0; 789 *device = &ctx->device.common; 790 } 791 return status; 792 } 793