1/* 2 * Copyright (C) Texas Instruments - http://www.ti.com/ 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#include <errno.h> 18#include <malloc.h> 19#include <stdlib.h> 20#include <stdarg.h> 21#include <fcntl.h> 22#include <poll.h> 23#include <sys/eventfd.h> 24#include <sys/ioctl.h> 25#include <linux/fb.h> 26#include <linux/omapfb.h> 27#include <sys/mman.h> 28#include <sys/resource.h> 29 30#include <cutils/properties.h> 31#include <cutils/log.h> 32#include <cutils/native_handle.h> 33#define HWC_REMOVE_DEPRECATED_VERSIONS 0 34#include <hardware/hardware.h> 35#include <hardware/hwcomposer.h> 36#include <EGL/egl.h> 37#include <hardware_legacy/uevent.h> 38#include <png.h> 39#include <utils/Timers.h> 40 41#include <system/graphics.h> 42#include <linux/bltsville.h> 43 44#define MAX_HWC_LAYERS 32 45 46#define ASPECT_RATIO_TOLERANCE 0.02f 47 48#define min(a, b) ( { typeof(a) __a = (a), __b = (b); __a < __b ? __a : __b; } ) 49#define max(a, b) ( { typeof(a) __a = (a), __b = (b); __a > __b ? __a : __b; } ) 50#define swap(a, b) do { typeof(a) __a = (a); (a) = (b); (b) = __a; } while (0) 51 52#define WIDTH(rect) ((rect).right - (rect).left) 53#define HEIGHT(rect) ((rect).bottom - (rect).top) 54 55#define DIV_ROUND_UP(a, b) (((a) + (b) - 1) / (b)) 56 57#include <video/dsscomp.h> 58#include <video/omap_hwc.h> 59 60#include "hal_public.h" 61#include "rgz_2d.h" 62 63#include <linux/ion.h> 64#include <linux/omap_ion.h> 65#include <ion/ion.h> 66 67#define MAX_HW_OVERLAYS 4 68#define NUM_NONSCALING_OVERLAYS 1 69#define NUM_EXT_DISPLAY_BACK_BUFFERS 2 70 71struct ext_transform_t { 72 __u8 rotation : 3; /* 90-degree clockwise rotations */ 73 __u8 hflip : 1; /* flip l-r (after rotation) */ 74 __u8 enabled : 1; /* cloning enabled */ 75 __u8 docking : 1; /* docking vs. mirroring - used for state */ 76}; 77 78/* cloning support and state */ 79struct omap4_hwc_ext { 80 /* support */ 81 struct ext_transform_t mirror; /* mirroring settings */ 82 struct ext_transform_t dock; /* docking settings */ 83 float lcd_xpy; /* pixel ratio for UI */ 84 __u8 avoid_mode_change; /* use HDMI mode used for mirroring if possible */ 85 __u8 force_dock; /* must dock */ 86 __u8 hdmi_state; /* whether HDMI is connected */ 87 88 /* state */ 89 __u8 on_tv; /* using a tv */ 90 struct ext_transform_t current; /* current settings */ 91 struct ext_transform_t last; /* last-used settings */ 92 93 /* configuration */ 94 __u32 last_xres_used; /* resolution and pixel ratio used for mode selection */ 95 __u32 last_yres_used; 96 __u32 last_mode; /* 2-s complement of last HDMI mode set, 0 if none */ 97 __u32 mirror_mode; /* 2-s complement of mode used when mirroring */ 98 float last_xpy; 99 __u16 width; /* external screen dimensions */ 100 __u16 height; 101 __u32 xres; /* external screen resolution */ 102 __u32 yres; 103 float m[2][3]; /* external transformation matrix */ 104 hwc_rect_t mirror_region; /* region of screen to mirror */ 105}; 106typedef struct omap4_hwc_ext omap4_hwc_ext_t; 107 108/* used by property settings */ 109enum { 110 EXT_ROTATION = 3, /* rotation while mirroring */ 111 EXT_HFLIP = (1 << 2), /* flip l-r on output (after rotation) */ 112}; 113 114enum bltpolicy { 115 BLTPOLICY_DISABLED = 0, 116 BLTPOLICY_DEFAULT = 1, /* Default blit policy */ 117 BLTPOLICY_ALL, /* Test mode to attempt to blit all */ 118}; 119 120enum bltmode { 121 BLTMODE_PAINT = 0, /* Attempt to blit layer by layer */ 122 BLTMODE_REGION = 1, /* Attempt to blit layers via regions */ 123}; 124 125/* ARGB image */ 126struct omap4_hwc_img { 127 int width; 128 int height; 129 int rowbytes; 130 int size; 131 unsigned char *ptr; 132} dock_image = { .rowbytes = 0 }; 133 134struct omap4_hwc_module { 135 hwc_module_t base; 136 137 IMG_framebuffer_device_public_t *fb_dev; 138}; 139typedef struct omap4_hwc_module omap4_hwc_module_t; 140 141struct counts { 142 unsigned int possible_overlay_layers; 143 unsigned int composited_layers; 144 unsigned int scaled_layers; 145 unsigned int RGB; 146 unsigned int BGR; 147 unsigned int NV12; 148 unsigned int dockable; 149 unsigned int protected; 150 151 unsigned int max_hw_overlays; 152 unsigned int max_scaling_overlays; 153 unsigned int mem; 154 unsigned int s3d; 155 156 unsigned int large_rgb32_layers; 157}; 158 159struct omap4_hwc_device { 160 /* static data */ 161 hwc_composer_device_1_t base; 162 hwc_procs_t *procs; 163 pthread_t hdmi_thread; 164 pthread_mutex_t lock; 165 166 IMG_framebuffer_device_public_t *fb_dev; 167 struct dsscomp_display_info fb_dis; 168 int fb_fd; /* file descriptor for /dev/fb0 */ 169 int dsscomp_fd; /* file descriptor for /dev/dsscomp */ 170 int hdmi_fb_fd; /* file descriptor for /dev/fb1 */ 171 int wakeup_evt; /* eventfd used to wakeup event thread */ 172 173 int img_mem_size; /* size of fb for hdmi */ 174 void *img_mem_ptr; /* start of fb for hdmi */ 175 176 int flags_rgb_order; 177 int flags_nv12_only; 178 float upscaled_nv12_limit; 179 180 int on_tv; /* using a tv */ 181 int force_sgx; 182 omap4_hwc_ext_t ext; /* external mirroring data */ 183 int idle; 184 185 float primary_m[2][3]; /* internal transformation matrix */ 186 int primary_transform; 187 int primary_rotation; 188 hwc_rect_t primary_region; 189 190 buffer_handle_t *buffers; 191 int use_sgx; 192 int swap_rb; 193 unsigned int post2_layers; /* Buffers used with DSS pipes*/ 194 unsigned int post2_blit_buffers; /* Buffers used with blit */ 195 int ext_ovls; /* # of overlays on external display for current composition */ 196 int ext_ovls_wanted; /* # of overlays that should be on external display for current composition */ 197 int last_ext_ovls; /* # of overlays on external/internal display for last composition */ 198 int last_int_ovls; 199 200 enum bltmode blt_mode; 201 enum bltpolicy blt_policy; 202 203 int blit_flags; 204 int blit_num; 205 struct omap_hwc_data comp_data; /* This is a kernel data structure */ 206 struct rgz_blt_entry blit_ops[RGZ_MAX_BLITS]; 207 struct counts stats; 208 int ion_fd; 209 struct ion_handle *ion_handles[2]; 210 211 /* fake vsync event state */ 212 pthread_mutex_t vsync_lock; 213 int vsync_enabled; 214 uint64_t last_vsync_time; 215 int last_vsync_time_valid; 216 uint64_t fake_vsync_period; 217}; 218typedef struct omap4_hwc_device omap4_hwc_device_t; 219 220#define HAL_FMT(f) ((f) == HAL_PIXEL_FORMAT_TI_NV12 ? "NV12" : \ 221 (f) == HAL_PIXEL_FORMAT_TI_NV12_1D ? "NV12" : \ 222 (f) == HAL_PIXEL_FORMAT_YV12 ? "YV12" : \ 223 (f) == HAL_PIXEL_FORMAT_BGRX_8888 ? "xRGB32" : \ 224 (f) == HAL_PIXEL_FORMAT_RGBX_8888 ? "xBGR32" : \ 225 (f) == HAL_PIXEL_FORMAT_BGRA_8888 ? "ARGB32" : \ 226 (f) == HAL_PIXEL_FORMAT_RGBA_8888 ? "ABGR32" : \ 227 (f) == HAL_PIXEL_FORMAT_RGB_565 ? "RGB565" : "??") 228 229#define DSS_FMT(f) ((f) == OMAP_DSS_COLOR_NV12 ? "NV12" : \ 230 (f) == OMAP_DSS_COLOR_RGB24U ? "xRGB32" : \ 231 (f) == OMAP_DSS_COLOR_ARGB32 ? "ARGB32" : \ 232 (f) == OMAP_DSS_COLOR_RGB16 ? "RGB565" : "??") 233 234static int debug = 0; 235static int debugpost2 = 0; 236static int debugblt = 0; 237static rgz_t grgz; 238static struct bvsurfgeom gscrngeom; 239 240static void showfps(void) 241{ 242 static int framecount = 0; 243 static int lastframecount = 0; 244 static nsecs_t lastfpstime = 0; 245 static float fps = 0; 246 char value[PROPERTY_VALUE_MAX]; 247 248 property_get("debug.hwc.showfps", value, "0"); 249 if (!atoi(value)) { 250 return; 251 } 252 253 framecount++; 254 if (!(framecount & 0x7)) { 255 nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC); 256 nsecs_t diff = now - lastfpstime; 257 fps = ((framecount - lastframecount) * (float)(s2ns(1))) / diff; 258 lastfpstime = now; 259 lastframecount = framecount; 260 ALOGI("%d Frames, %f FPS", framecount, fps); 261 } 262} 263 264static void dump_layer(hwc_layer_1_t const* l) 265{ 266 ALOGD("\ttype=%d, flags=%08x, handle=%p, tr=%02x, blend=%04x, {%d,%d,%d,%d}, {%d,%d,%d,%d}", 267 l->compositionType, l->flags, l->handle, l->transform, l->blending, 268 l->sourceCrop.left, 269 l->sourceCrop.top, 270 l->sourceCrop.right, 271 l->sourceCrop.bottom, 272 l->displayFrame.left, 273 l->displayFrame.top, 274 l->displayFrame.right, 275 l->displayFrame.bottom); 276} 277 278static void dump_dsscomp(struct dsscomp_setup_dispc_data *d) 279{ 280 unsigned i; 281 282 ALOGD("[%08x] set: %c%c%c %d ovls\n", 283 d->sync_id, 284 (d->mode & DSSCOMP_SETUP_MODE_APPLY) ? 'A' : '-', 285 (d->mode & DSSCOMP_SETUP_MODE_DISPLAY) ? 'D' : '-', 286 (d->mode & DSSCOMP_SETUP_MODE_CAPTURE) ? 'C' : '-', 287 d->num_ovls); 288 289 for (i = 0; i < d->num_mgrs; i++) { 290 struct dss2_mgr_info *mi = &d->mgrs[i]; 291 ALOGD(" (dis%d alpha=%d col=%08x ilace=%d)\n", 292 mi->ix, 293 mi->alpha_blending, mi->default_color, 294 mi->interlaced); 295 } 296 297 for (i = 0; i < d->num_ovls; i++) { 298 struct dss2_ovl_info *oi = &d->ovls[i]; 299 struct dss2_ovl_cfg *c = &oi->cfg; 300 if (c->zonly) 301 ALOGD("ovl%d(%s z%d)\n", 302 c->ix, c->enabled ? "ON" : "off", c->zorder); 303 else 304 ALOGD("ovl%d(%s z%d %s%s *%d%% %d*%d:%d,%d+%d,%d rot%d%s => %d,%d+%d,%d %p/%p|%d)\n", 305 c->ix, c->enabled ? "ON" : "off", c->zorder, DSS_FMT(c->color_mode), 306 c->pre_mult_alpha ? " premult" : "", 307 (c->global_alpha * 100 + 128) / 255, 308 c->width, c->height, c->crop.x, c->crop.y, 309 c->crop.w, c->crop.h, 310 c->rotation, c->mirror ? "+mir" : "", 311 c->win.x, c->win.y, c->win.w, c->win.h, 312 (void *) oi->ba, (void *) oi->uv, c->stride); 313 } 314} 315 316struct dump_buf { 317 char *buf; 318 int buf_len; 319 int len; 320}; 321 322static void dump_printf(struct dump_buf *buf, const char *fmt, ...) 323{ 324 va_list ap; 325 326 va_start(ap, fmt); 327 buf->len += vsnprintf(buf->buf + buf->len, buf->buf_len - buf->len, fmt, ap); 328 va_end(ap); 329} 330 331static void dump_set_info(omap4_hwc_device_t *hwc_dev, hwc_display_contents_1_t* list) 332{ 333 struct dsscomp_setup_dispc_data *dsscomp = &hwc_dev->comp_data.dsscomp_data; 334 char logbuf[1024]; 335 struct dump_buf log = { 336 .buf = logbuf, 337 .buf_len = sizeof(logbuf), 338 }; 339 unsigned int i; 340 341 dump_printf(&log, "set H{"); 342 for (i = 0; list && i < list->numHwLayers; i++) { 343 if (i) 344 dump_printf(&log, " "); 345 hwc_layer_1_t *layer = &list->hwLayers[i]; 346 IMG_native_handle_t *handle = (IMG_native_handle_t *)layer->handle; 347 if (hwc_dev->post2_blit_buffers) { 348 if ((i + 1) < hwc_dev->post2_layers) 349 dump_printf(&log, "%p:%s,", handle, "DSS"); 350 else 351 dump_printf(&log, "%p:%s,", handle, "BV2D"); 352 } 353 else 354 dump_printf(&log, "%p:%s,", handle, layer->compositionType == HWC_OVERLAY ? "DSS" : "SGX"); 355 if ((layer->flags & HWC_SKIP_LAYER) || !handle) { 356 dump_printf(&log, "SKIP"); 357 continue; 358 } 359 if (layer->flags & HWC_HINT_CLEAR_FB) 360 dump_printf(&log, "CLR,"); 361 dump_printf(&log, "%d*%d(%s)", handle->iWidth, handle->iHeight, HAL_FMT(handle->iFormat)); 362 if (layer->transform) 363 dump_printf(&log, "~%d", layer->transform); 364 } 365 dump_printf(&log, "} D{"); 366 for (i = 0; i < dsscomp->num_ovls; i++) { 367 if (i) 368 dump_printf(&log, " "); 369 dump_printf(&log, "%d=", dsscomp->ovls[i].cfg.ix); 370 if (dsscomp->ovls[i].cfg.enabled) 371 dump_printf(&log, "%08x:%d*%d,%s", 372 dsscomp->ovls[i].ba, 373 dsscomp->ovls[i].cfg.width, 374 dsscomp->ovls[i].cfg.height, 375 DSS_FMT(dsscomp->ovls[i].cfg.color_mode)); 376 else 377 dump_printf(&log, "-"); 378 } 379 dump_printf(&log, "} L{"); 380 for (i = 0; i < hwc_dev->post2_layers; i++) { 381 if (i) 382 dump_printf(&log, " "); 383 dump_printf(&log, "%p", hwc_dev->buffers[i]); 384 } 385 if (hwc_dev->post2_blit_buffers) { 386 dump_printf(&log, "} B{"); 387 for (i = hwc_dev->post2_layers; 388 i < hwc_dev->post2_blit_buffers + hwc_dev->post2_layers; i++) { 389 dump_printf(&log, "%p ", hwc_dev->buffers[i]); 390 } 391 } 392 dump_printf(&log, "}%s\n", hwc_dev->use_sgx ? " swap" : ""); 393 394 ALOGD("%s", log.buf); 395} 396 397static int sync_id = 0; 398 399static int omap4_hwc_is_valid_format(int format) 400{ 401 switch(format) { 402 case HAL_PIXEL_FORMAT_RGB_565: 403 case HAL_PIXEL_FORMAT_RGBX_8888: 404 case HAL_PIXEL_FORMAT_RGBA_8888: 405 case HAL_PIXEL_FORMAT_BGRA_8888: 406 case HAL_PIXEL_FORMAT_BGRX_8888: 407 case HAL_PIXEL_FORMAT_TI_NV12: 408 case HAL_PIXEL_FORMAT_TI_NV12_1D: 409 return 1; 410 411 default: 412 return 0; 413 } 414} 415 416static int scaled(hwc_layer_1_t *layer) 417{ 418 int w = WIDTH(layer->sourceCrop); 419 int h = HEIGHT(layer->sourceCrop); 420 421 if (layer->transform & HWC_TRANSFORM_ROT_90) 422 swap(w, h); 423 424 return WIDTH(layer->displayFrame) != w || HEIGHT(layer->displayFrame) != h; 425} 426 427static int is_protected(hwc_layer_1_t *layer) 428{ 429 IMG_native_handle_t *handle = (IMG_native_handle_t *)layer->handle; 430 431 return (handle->usage & GRALLOC_USAGE_PROTECTED); 432} 433 434#define is_BLENDED(layer) ((layer)->blending != HWC_BLENDING_NONE) 435 436static int is_RGB32(IMG_native_handle_t *handle) 437{ 438 switch(handle->iFormat) 439 { 440 case HAL_PIXEL_FORMAT_BGRA_8888: 441 case HAL_PIXEL_FORMAT_BGRX_8888: 442 return 1; 443 default: 444 return 0; 445 } 446} 447 448static int is_RGB(IMG_native_handle_t *handle) 449{ 450 switch(handle->iFormat) 451 { 452 case HAL_PIXEL_FORMAT_BGRA_8888: 453 case HAL_PIXEL_FORMAT_BGRX_8888: 454 case HAL_PIXEL_FORMAT_RGB_565: 455 return 1; 456 default: 457 return 0; 458 } 459} 460static int get_rgb_bpp(IMG_native_handle_t *handle) 461{ 462 switch(handle->iFormat) 463 { 464 case HAL_PIXEL_FORMAT_BGRA_8888: 465 case HAL_PIXEL_FORMAT_BGRX_8888: 466 case HAL_PIXEL_FORMAT_RGBX_8888: 467 case HAL_PIXEL_FORMAT_RGBA_8888: 468 return 32; 469 case HAL_PIXEL_FORMAT_RGB_565: 470 return 16; 471 default: 472 return 0; 473 } 474} 475 476static int is_BGR_format(int format) 477{ 478 switch (format) { 479 case HAL_PIXEL_FORMAT_RGBX_8888: 480 case HAL_PIXEL_FORMAT_RGBA_8888: 481 return 1; 482 default: 483 return 0; 484 } 485} 486 487static int is_BGR(IMG_native_handle_t *handle) 488{ 489 return is_BGR_format(handle->iFormat); 490} 491 492static int is_NV12(IMG_native_handle_t *handle) 493{ 494 switch(handle->iFormat) 495 { 496 case HAL_PIXEL_FORMAT_TI_NV12: 497 case HAL_PIXEL_FORMAT_TI_NV12_1D: 498 return 1; 499 default: 500 return 0; 501 } 502} 503 504static int is_upscaled_NV12(omap4_hwc_device_t *hwc_dev, hwc_layer_1_t *layer) 505{ 506 if (!layer) 507 return 0; 508 509 IMG_native_handle_t *handle = (IMG_native_handle_t *)layer->handle; 510 if (!is_NV12(handle)) 511 return 0; 512 513 int w = WIDTH(layer->sourceCrop); 514 int h = HEIGHT(layer->sourceCrop); 515 516 if (layer->transform & HWC_TRANSFORM_ROT_90) 517 swap(w, h); 518 519 return (WIDTH(layer->displayFrame) >= w * hwc_dev->upscaled_nv12_limit || 520 HEIGHT(layer->displayFrame) >= h * hwc_dev->upscaled_nv12_limit); 521} 522 523static int dockable(hwc_layer_1_t *layer) 524{ 525 IMG_native_handle_t *handle = (IMG_native_handle_t *)layer->handle; 526 527 return (handle->usage & GRALLOC_USAGE_EXTERNAL_DISP); 528} 529 530/* test if layer appears to be RGB32 (4 Bpp) and > 1280x720 */ 531static int is_large_rgb32_layer(const hwc_layer_1_t *layer) 532{ 533 IMG_native_handle_t *handle = (IMG_native_handle_t *)layer->handle; 534 535 return is_RGB32(handle) && 536 (((layer->sourceCrop.right - layer->sourceCrop.left) > 1280) || 537 ((layer->sourceCrop.bottom - layer->sourceCrop.top) > 720)); 538} 539 540static uint64_t vsync_clock_now() 541{ 542 uint64_t now = 0; 543 struct timespec ts; 544 545 if (!clock_gettime(CLOCK_MONOTONIC, &ts)) 546 now = ((uint64_t)ts.tv_sec) * 1000000000ull + ts.tv_nsec; 547 548 return now; 549} 550 551static void wakeup_hdmi_thread(omap4_hwc_device_t *hwc_dev) 552{ 553 uint64_t tmp = 1; 554 write(hwc_dev->wakeup_evt, &tmp, sizeof(tmp)); 555} 556 557static void fire_vsync_event(omap4_hwc_device_t *hwc_dev, uint64_t timestamp) 558{ 559 pthread_mutex_lock(&hwc_dev->vsync_lock); 560 561 hwc_dev->last_vsync_time_valid = 1; 562 hwc_dev->last_vsync_time = timestamp; 563 564 pthread_mutex_unlock(&hwc_dev->vsync_lock); 565 566 if (hwc_dev->procs && hwc_dev->procs->vsync) 567 hwc_dev->procs->vsync(hwc_dev->procs, 0, timestamp); 568} 569 570static unsigned int mem1d(IMG_native_handle_t *handle) 571{ 572 if (handle == NULL || is_NV12(handle)) 573 return 0; 574 575 int bpp = handle->iFormat == HAL_PIXEL_FORMAT_RGB_565 ? 2 : 4; 576 int stride = ALIGN(handle->iWidth, HW_ALIGN) * bpp; 577 return stride * handle->iHeight; 578} 579 580static void 581omap4_hwc_setup_layer_base(struct dss2_ovl_cfg *oc, int index, int format, int blended, int width, int height) 582{ 583 unsigned int bits_per_pixel; 584 585 /* YUV2RGB conversion */ 586 const struct omap_dss_cconv_coefs ctbl_bt601_5 = { 587 298, 409, 0, 298, -208, -100, 298, 0, 517, 0, 588 }; 589 590 /* convert color format */ 591 switch (format) { 592 case HAL_PIXEL_FORMAT_RGBA_8888: 593 case HAL_PIXEL_FORMAT_BGRA_8888: 594 oc->color_mode = OMAP_DSS_COLOR_ARGB32; 595 bits_per_pixel = 32; 596 if (blended) 597 break; 598 599 case HAL_PIXEL_FORMAT_RGBX_8888: 600 case HAL_PIXEL_FORMAT_BGRX_8888: 601 oc->color_mode = OMAP_DSS_COLOR_RGB24U; 602 bits_per_pixel = 32; 603 break; 604 605 case HAL_PIXEL_FORMAT_RGB_565: 606 oc->color_mode = OMAP_DSS_COLOR_RGB16; 607 bits_per_pixel = 16; 608 break; 609 610 case HAL_PIXEL_FORMAT_TI_NV12: 611 case HAL_PIXEL_FORMAT_TI_NV12_1D: 612 oc->color_mode = OMAP_DSS_COLOR_NV12; 613 bits_per_pixel = 8; 614 oc->cconv = ctbl_bt601_5; 615 break; 616 617 default: 618 /* Should have been filtered out */ 619 ALOGV("Unsupported pixel format"); 620 return; 621 } 622 623 oc->width = width; 624 oc->height = height; 625 oc->stride = ALIGN(width, HW_ALIGN) * bits_per_pixel / 8; 626 627 oc->enabled = 1; 628 oc->global_alpha = 255; 629 oc->zorder = index; 630 oc->ix = 0; 631 632 /* defaults for SGX framebuffer renders */ 633 oc->crop.w = oc->win.w = width; 634 oc->crop.h = oc->win.h = height; 635 636 /* for now interlacing and vc1 info is not supplied */ 637 oc->ilace = OMAP_DSS_ILACE_NONE; 638 oc->vc1.enable = 0; 639} 640 641static void 642omap4_hwc_setup_layer(omap4_hwc_device_t *hwc_dev, struct dss2_ovl_info *ovl, 643 hwc_layer_1_t *layer, int index, 644 int format, int width, int height) 645{ 646 struct dss2_ovl_cfg *oc = &ovl->cfg; 647 648 //dump_layer(layer); 649 650 omap4_hwc_setup_layer_base(oc, index, format, is_BLENDED(layer), width, height); 651 652 /* convert transformation - assuming 0-set config */ 653 if (layer->transform & HWC_TRANSFORM_FLIP_H) 654 oc->mirror = 1; 655 if (layer->transform & HWC_TRANSFORM_FLIP_V) { 656 oc->rotation = 2; 657 oc->mirror = !oc->mirror; 658 } 659 if (layer->transform & HWC_TRANSFORM_ROT_90) { 660 oc->rotation += oc->mirror ? -1 : 1; 661 oc->rotation &= 3; 662 } 663 664 oc->pre_mult_alpha = layer->blending == HWC_BLENDING_PREMULT; 665 666 /* display position */ 667 oc->win.x = layer->displayFrame.left; 668 oc->win.y = layer->displayFrame.top; 669 oc->win.w = WIDTH(layer->displayFrame); 670 oc->win.h = HEIGHT(layer->displayFrame); 671 672 /* crop */ 673 oc->crop.x = layer->sourceCrop.left; 674 oc->crop.y = layer->sourceCrop.top; 675 oc->crop.w = WIDTH(layer->sourceCrop); 676 oc->crop.h = HEIGHT(layer->sourceCrop); 677} 678 679const float m_unit[2][3] = { { 1., 0., 0. }, { 0., 1., 0. } }; 680 681static inline void m_translate(float m[2][3], int dx, int dy) 682{ 683 m[0][2] += dx; 684 m[1][2] += dy; 685} 686 687static inline void m_scale1(float m[3], int from, int to) 688{ 689 m[0] = m[0] * to / from; 690 m[1] = m[1] * to / from; 691 m[2] = m[2] * to / from; 692} 693 694static inline void m_scale(float m[2][3], int x_from, int x_to, int y_from, int y_to) 695{ 696 m_scale1(m[0], x_from, x_to); 697 m_scale1(m[1], y_from, y_to); 698} 699 700static void m_rotate(float m[2][3], int quarter_turns) 701{ 702 if (quarter_turns & 2) 703 m_scale(m, 1, -1, 1, -1); 704 if (quarter_turns & 1) { 705 int q; 706 q = m[0][0]; m[0][0] = -m[1][0]; m[1][0] = q; 707 q = m[0][1]; m[0][1] = -m[1][1]; m[1][1] = q; 708 q = m[0][2]; m[0][2] = -m[1][2]; m[1][2] = q; 709 } 710} 711 712static inline int m_round(float x) 713{ 714 /* int truncates towards 0 */ 715 return (int) (x < 0 ? x - 0.5 : x + 0.5); 716} 717 718/* 719 * assuming xpy (xratio:yratio) original pixel ratio, calculate the adjusted width 720 * and height for a screen of xres/yres and physical size of width/height. 721 * The adjusted size is the largest that fits into the screen. 722 */ 723static void get_max_dimensions(__u32 orig_xres, __u32 orig_yres, 724 float xpy, 725 __u32 scr_xres, __u32 scr_yres, 726 __u32 scr_width, __u32 scr_height, 727 __u32 *adj_xres, __u32 *adj_yres) 728{ 729 /* assume full screen (largest size)*/ 730 *adj_xres = scr_xres; 731 *adj_yres = scr_yres; 732 733 /* assume 1:1 pixel ratios if none supplied */ 734 if (!scr_width || !scr_height) { 735 scr_width = scr_xres; 736 scr_height = scr_yres; 737 } 738 739 /* trim to keep aspect ratio */ 740 float x_factor = orig_xres * xpy * scr_height; 741 float y_factor = orig_yres * scr_width; 742 743 /* allow for tolerance so we avoid scaling if framebuffer is standard size */ 744 if (x_factor < y_factor * (1.f - ASPECT_RATIO_TOLERANCE)) 745 *adj_xres = (__u32) (x_factor * *adj_xres / y_factor + 0.5); 746 else if (x_factor * (1.f - ASPECT_RATIO_TOLERANCE) > y_factor) 747 *adj_yres = (__u32) (y_factor * *adj_yres / x_factor + 0.5); 748} 749 750static void set_ext_matrix(omap4_hwc_ext_t *ext, struct hwc_rect region) 751{ 752 int orig_w = WIDTH(region); 753 int orig_h = HEIGHT(region); 754 float xpy = ext->lcd_xpy; 755 756 /* reorientation matrix is: 757 m = (center-from-target-center) * (scale-to-target) * (mirror) * (rotate) * (center-to-original-center) */ 758 759 memcpy(ext->m, m_unit, sizeof(m_unit)); 760 m_translate(ext->m, -(orig_w >> 1) - region.left, -(orig_h >> 1) - region.top); 761 m_rotate(ext->m, ext->current.rotation); 762 if (ext->current.hflip) 763 m_scale(ext->m, 1, -1, 1, 1); 764 765 if (ext->current.rotation & 1) { 766 swap(orig_w, orig_h); 767 xpy = 1. / xpy; 768 } 769 770 /* get target size */ 771 __u32 adj_xres, adj_yres; 772 get_max_dimensions(orig_w, orig_h, xpy, 773 ext->xres, ext->yres, ext->width, ext->height, 774 &adj_xres, &adj_yres); 775 776 m_scale(ext->m, orig_w, adj_xres, orig_h, adj_yres); 777 m_translate(ext->m, ext->xres >> 1, ext->yres >> 1); 778} 779 780static int 781crop_to_rect(struct dss2_ovl_cfg *cfg, struct hwc_rect vis_rect) 782{ 783 struct { 784 int xy[2]; 785 int wh[2]; 786 } crop, win; 787 struct { 788 int lt[2]; 789 int rb[2]; 790 } vis; 791 win.xy[0] = cfg->win.x; win.xy[1] = cfg->win.y; 792 win.wh[0] = cfg->win.w; win.wh[1] = cfg->win.h; 793 crop.xy[0] = cfg->crop.x; crop.xy[1] = cfg->crop.y; 794 crop.wh[0] = cfg->crop.w; crop.wh[1] = cfg->crop.h; 795 vis.lt[0] = vis_rect.left; vis.lt[1] = vis_rect.top; 796 vis.rb[0] = vis_rect.right; vis.rb[1] = vis_rect.bottom; 797 798 int c, swap = cfg->rotation & 1; 799 800 /* align crop window with display coordinates */ 801 if (swap) 802 crop.xy[1] -= (crop.wh[1] = -crop.wh[1]); 803 if (cfg->rotation & 2) 804 crop.xy[!swap] -= (crop.wh[!swap] = -crop.wh[!swap]); 805 if ((!cfg->mirror) ^ !(cfg->rotation & 2)) 806 crop.xy[swap] -= (crop.wh[swap] = -crop.wh[swap]); 807 808 for (c = 0; c < 2; c++) { 809 /* see if complete buffer is outside the vis or it is 810 fully cropped or scaled to 0 */ 811 if (win.wh[c] <= 0 || vis.rb[c] <= vis.lt[c] || 812 win.xy[c] + win.wh[c] <= vis.lt[c] || 813 win.xy[c] >= vis.rb[c] || 814 !crop.wh[c ^ swap]) 815 return -ENOENT; 816 817 /* crop left/top */ 818 if (win.xy[c] < vis.lt[c]) { 819 /* correction term */ 820 int a = (vis.lt[c] - win.xy[c]) * crop.wh[c ^ swap] / win.wh[c]; 821 crop.xy[c ^ swap] += a; 822 crop.wh[c ^ swap] -= a; 823 win.wh[c] -= vis.lt[c] - win.xy[c]; 824 win.xy[c] = vis.lt[c]; 825 } 826 /* crop right/bottom */ 827 if (win.xy[c] + win.wh[c] > vis.rb[c]) { 828 crop.wh[c ^ swap] = crop.wh[c ^ swap] * (vis.rb[c] - win.xy[c]) / win.wh[c]; 829 win.wh[c] = vis.rb[c] - win.xy[c]; 830 } 831 832 if (!crop.wh[c ^ swap] || !win.wh[c]) 833 return -ENOENT; 834 } 835 836 /* realign crop window to buffer coordinates */ 837 if (cfg->rotation & 2) 838 crop.xy[!swap] -= (crop.wh[!swap] = -crop.wh[!swap]); 839 if ((!cfg->mirror) ^ !(cfg->rotation & 2)) 840 crop.xy[swap] -= (crop.wh[swap] = -crop.wh[swap]); 841 if (swap) 842 crop.xy[1] -= (crop.wh[1] = -crop.wh[1]); 843 844 cfg->win.x = win.xy[0]; cfg->win.y = win.xy[1]; 845 cfg->win.w = win.wh[0]; cfg->win.h = win.wh[1]; 846 cfg->crop.x = crop.xy[0]; cfg->crop.y = crop.xy[1]; 847 cfg->crop.w = crop.wh[0]; cfg->crop.h = crop.wh[1]; 848 849 return 0; 850} 851 852static void 853omap4_hwc_apply_transform(float transform[2][3],struct dss2_ovl_cfg *oc) 854{ 855 float x, y, w, h; 856 857 /* display position */ 858 x = transform[0][0] * oc->win.x + transform[0][1] * oc->win.y + transform[0][2]; 859 y = transform[1][0] * oc->win.x + transform[1][1] * oc->win.y + transform[1][2]; 860 w = transform[0][0] * oc->win.w + transform[0][1] * oc->win.h; 861 h = transform[1][0] * oc->win.w + transform[1][1] * oc->win.h; 862 oc->win.x = m_round(w > 0 ? x : x + w); 863 oc->win.y = m_round(h > 0 ? y : y + h); 864 oc->win.w = m_round(w > 0 ? w : -w); 865 oc->win.h = m_round(h > 0 ? h : -h); 866} 867 868static void 869omap4_hwc_adjust_ext_layer(omap4_hwc_ext_t *ext, struct dss2_ovl_info *ovl) 870{ 871 struct dss2_ovl_cfg *oc = &ovl->cfg; 872 873 /* crop to clone region if mirroring */ 874 if (!ext->current.docking && 875 crop_to_rect(&ovl->cfg, ext->mirror_region) != 0) { 876 ovl->cfg.enabled = 0; 877 return; 878 } 879 880 omap4_hwc_apply_transform(ext->m, oc); 881 882 /* combining transformations: F^a*R^b*F^i*R^j = F^(a+b)*R^(j+b*(-1)^i), because F*R = R^(-1)*F */ 883 oc->rotation += (oc->mirror ? -1 : 1) * ext->current.rotation; 884 oc->rotation &= 3; 885 if (ext->current.hflip) 886 oc->mirror = !oc->mirror; 887} 888 889static struct dsscomp_platform_info limits; 890 891static void 892omap4_hwc_adjust_primary_display_layer(omap4_hwc_device_t *hwc_dev, struct dss2_ovl_info *ovl) 893{ 894 struct dss2_ovl_cfg *oc = &ovl->cfg; 895 896 if (crop_to_rect(&ovl->cfg, hwc_dev->primary_region) != 0) { 897 ovl->cfg.enabled = 0; 898 return; 899 } 900 901 omap4_hwc_apply_transform(hwc_dev->primary_m, oc); 902 903 /* combining transformations: F^a*R^b*F^i*R^j = F^(a+b)*R^(j+b*(-1)^i), because F*R = R^(-1)*F */ 904 oc->rotation += (oc->mirror ? -1 : 1) * hwc_dev->primary_rotation; 905 oc->rotation &= 3; 906} 907 908static int omap4_hwc_can_scale(__u32 src_w, __u32 src_h, __u32 dst_w, __u32 dst_h, int is_2d, 909 struct dsscomp_display_info *dis, struct dsscomp_platform_info *limits, 910 __u32 pclk, void *handle) 911{ 912 __u32 fclk = limits->fclk / 1000; 913 __u32 min_src_w = DIV_ROUND_UP(src_w, is_2d ? limits->max_xdecim_2d : limits->max_xdecim_1d); 914 __u32 min_src_h = DIV_ROUND_UP(src_h, is_2d ? limits->max_ydecim_2d : limits->max_ydecim_1d); 915 916 /* ERRATAs */ 917 /* cannot render 1-width layers on DSI video mode panels - we just disallow all 1-width LCD layers */ 918 if (dis->channel != OMAP_DSS_CHANNEL_DIGIT && dst_w < limits->min_width) 919 return 0; 920 921 /* NOTE: no support for checking YUV422 layers that are tricky to scale */ 922 923 /* FIXME: limit vertical downscale well below theoretical limit as we saw display artifacts */ 924 if (dst_h < src_h / 4) 925 return 0; 926 927 /* max downscale */ 928 if (dst_h * limits->max_downscale < min_src_h) 929 return 0; 930 931 /* for manual panels pclk is 0, and there are no pclk based scaling limits */ 932 if (!pclk) 933 return !(dst_w < src_w / limits->max_downscale / (is_2d ? limits->max_xdecim_2d : limits->max_xdecim_1d)); 934 935 /* :HACK: limit horizontal downscale well below theoretical limit as we saw display artifacts */ 936 if (dst_w * 4 < src_w) 937 return 0; 938 939 if (handle) 940 if (get_rgb_bpp(handle) == 32 && src_w > 1280 && dst_w * 3 < src_w) 941 return 0; 942 943 /* max horizontal downscale is 4, or the fclk/pixclk */ 944 if (fclk > pclk * limits->max_downscale) 945 fclk = pclk * limits->max_downscale; 946 /* for small parts, we need to use integer fclk/pixclk */ 947 if (src_w < limits->integer_scale_ratio_limit) 948 fclk = fclk / pclk * pclk; 949 if ((__u32) dst_w * fclk < min_src_w * pclk) 950 return 0; 951 952 return 1; 953} 954 955static int omap4_hwc_can_scale_layer(omap4_hwc_device_t *hwc_dev, hwc_layer_1_t *layer, IMG_native_handle_t *handle) 956{ 957 int src_w = WIDTH(layer->sourceCrop); 958 int src_h = HEIGHT(layer->sourceCrop); 959 int dst_w = WIDTH(layer->displayFrame); 960 int dst_h = HEIGHT(layer->displayFrame); 961 962 /* account for 90-degree rotation */ 963 if (layer->transform & HWC_TRANSFORM_ROT_90) 964 swap(src_w, src_h); 965 966 /* NOTE: layers should be able to be scaled externally since 967 framebuffer is able to be scaled on selected external resolution */ 968 return omap4_hwc_can_scale(src_w, src_h, dst_w, dst_h, is_NV12(handle), &hwc_dev->fb_dis, &limits, 969 hwc_dev->fb_dis.timings.pixel_clock, handle); 970} 971 972static int omap4_hwc_is_valid_layer(omap4_hwc_device_t *hwc_dev, 973 hwc_layer_1_t *layer, 974 IMG_native_handle_t *handle) 975{ 976 /* Skip layers are handled by SF */ 977 if ((layer->flags & HWC_SKIP_LAYER) || !handle) 978 return 0; 979 980 if (!omap4_hwc_is_valid_format(handle->iFormat)) 981 return 0; 982 983 /* 1D buffers: no transform, must fit in TILER slot */ 984 if (!is_NV12(handle)) { 985 if (layer->transform) 986 return 0; 987 if (mem1d(handle) > limits.tiler1d_slot_size) 988 return 0; 989 } 990 991 return omap4_hwc_can_scale_layer(hwc_dev, layer, handle); 992} 993 994static __u32 add_scaling_score(__u32 score, 995 __u32 xres, __u32 yres, __u32 refresh, 996 __u32 ext_xres, __u32 ext_yres, 997 __u32 mode_xres, __u32 mode_yres, __u32 mode_refresh) 998{ 999 __u32 area = xres * yres; 1000 __u32 ext_area = ext_xres * ext_yres; 1001 __u32 mode_area = mode_xres * mode_yres; 1002 1003 /* prefer to upscale (1% tolerance) [0..1] (insert after 1st bit) */ 1004 int upscale = (ext_xres >= xres * 99 / 100 && ext_yres >= yres * 99 / 100); 1005 score = (((score & ~1) | upscale) << 1) | (score & 1); 1006 1007 /* pick minimum scaling [0..16] */ 1008 if (ext_area > area) 1009 score = (score << 5) | (16 * area / ext_area); 1010 else 1011 score = (score << 5) | (16 * ext_area / area); 1012 1013 /* pick smallest leftover area [0..16] */ 1014 score = (score << 5) | ((16 * ext_area + (mode_area >> 1)) / mode_area); 1015 1016 /* adjust mode refresh rate */ 1017 mode_refresh += mode_refresh % 6 == 5; 1018 1019 /* prefer same or higher frame rate */ 1020 upscale = (mode_refresh >= refresh); 1021 score = (score << 1) | upscale; 1022 1023 /* pick closest frame rate */ 1024 if (mode_refresh > refresh) 1025 score = (score << 8) | (240 * refresh / mode_refresh); 1026 else 1027 score = (score << 8) | (240 * mode_refresh / refresh); 1028 1029 return score; 1030} 1031 1032static int omap4_hwc_set_best_hdmi_mode(omap4_hwc_device_t *hwc_dev, __u32 xres, __u32 yres, 1033 float xpy) 1034{ 1035 int dis_ix = hwc_dev->on_tv ? 0 : 1; 1036 int forced_preferred_mode = 0; 1037 1038 struct _qdis { 1039 struct dsscomp_display_info dis; 1040 struct dsscomp_videomode modedb[32]; 1041 } d = { .dis = { .ix = dis_ix } }; 1042 omap4_hwc_ext_t *ext = &hwc_dev->ext; 1043 1044 d.dis.modedb_len = sizeof(d.modedb) / sizeof(*d.modedb); 1045 int ret = ioctl(hwc_dev->dsscomp_fd, DSSCIOC_QUERY_DISPLAY, &d); 1046 if (ret) 1047 return ret; 1048 1049 if (d.dis.timings.x_res * d.dis.timings.y_res == 0 || 1050 xres * yres == 0) 1051 return -EINVAL; 1052 1053 __u32 i, best = ~0, best_score = 0; 1054 ext->width = d.dis.width_in_mm; 1055 ext->height = d.dis.height_in_mm; 1056 ext->xres = d.dis.timings.x_res; 1057 ext->yres = d.dis.timings.y_res; 1058 1059 /* use VGA external resolution as default */ 1060 if (!ext->xres || !ext->yres) { 1061 ext->xres = 640; 1062 ext->yres = 480; 1063 } 1064 1065 /* 1066 * copy the xres/yres from the preferred mode 1067 */ 1068 __u32 preferred_mode_xres = 0; 1069 __u32 preferred_mode_yres = 0; 1070 1071 char value[PROPERTY_VALUE_MAX]; 1072 if (property_get("persist.hwc.preferred_mode", value, "") <= 0 || 1073 sscanf(value, "%dx%d", &preferred_mode_xres, 1074 &preferred_mode_yres) != 2) { 1075 for (i = 0; i < d.dis.modedb_len; i++) { 1076 if (d.modedb[i].flag & FB_FLAG_PREFERRED) { 1077 preferred_mode_xres = d.modedb[i].xres; 1078 preferred_mode_yres = d.modedb[i].yres; 1079 ALOGD("preferred mode %d: xres %u yres %u\n", 1080 i, d.modedb[i].xres, d.modedb[i].yres); 1081 break; 1082 } 1083 } 1084 } else { 1085 ALOGD("forced preferred mode xres %u yres %u\n", 1086 preferred_mode_xres, preferred_mode_yres); 1087 forced_preferred_mode = 1; 1088 } 1089 1090 __u32 ext_fb_xres, ext_fb_yres; 1091 for (i = 0; i < d.dis.modedb_len; i++) { 1092 __u32 score = 0; 1093 __u32 mode_xres = d.modedb[i].xres; 1094 __u32 mode_yres = d.modedb[i].yres; 1095 __u32 ext_width = d.dis.width_in_mm; 1096 __u32 ext_height = d.dis.height_in_mm; 1097 1098 /* reject it because the hw says it can't actually use this mode */ 1099 if ((d.modedb[i].flag & FB_FLAG_HW_CAPABLE) == 0) 1100 continue; 1101 1102 if (d.modedb[i].vmode & FB_VMODE_INTERLACED) 1103 mode_yres /= 2; 1104 1105 if (d.modedb[i].flag & FB_FLAG_RATIO_4_3) { 1106 ext_width = 4; 1107 ext_height = 3; 1108 } else if (d.modedb[i].flag & FB_FLAG_RATIO_16_9) { 1109 ext_width = 16; 1110 ext_height = 9; 1111 } 1112 1113 if (!mode_xres || !mode_yres) 1114 continue; 1115 1116 get_max_dimensions(xres, yres, xpy, mode_xres, mode_yres, 1117 ext_width, ext_height, &ext_fb_xres, &ext_fb_yres); 1118 1119 /* we need to ensure that even TILER2D buffers can be scaled */ 1120 if (!d.modedb[i].pixclock || 1121 (d.modedb[i].vmode & ~FB_VMODE_INTERLACED) || 1122 !omap4_hwc_can_scale(xres, yres, ext_fb_xres, ext_fb_yres, 1123 1, &d.dis, &limits, 1124 1000000000 / d.modedb[i].pixclock, NULL)) 1125 continue; 1126 1127 /* prefer CEA modes */ 1128 if (d.modedb[i].flag & (FB_FLAG_RATIO_4_3 | FB_FLAG_RATIO_16_9)) 1129 score += 1; 1130 1131 /* prefer modes that match the preferred mode's resolution */ 1132 if (d.modedb[i].xres == preferred_mode_xres && 1133 d.modedb[i].yres == preferred_mode_yres) { 1134 if (forced_preferred_mode) 1135 score += 10; 1136 else 1137 score += 1; 1138 } 1139 1140 /* prefer modes the kernel has hinted is the correct mode */ 1141 if (!forced_preferred_mode && (d.modedb[i].flag & FB_FLAG_PREFERRED)) 1142 score += 1; 1143 1144 /* prefer the same mode as we use for mirroring to avoid mode change */ 1145 score = (score << 1) | (i == ~ext->mirror_mode && ext->avoid_mode_change); 1146 1147 score = add_scaling_score(score, xres, yres, 60, ext_fb_xres, ext_fb_yres, 1148 mode_xres, mode_yres, d.modedb[i].refresh ? : 1); 1149 1150 ALOGD("#%d: %dx%d %dHz flag 0x%x vmode 0x%x, score 0x%x", 1151 i, mode_xres, mode_yres, 1152 d.modedb[i].refresh, d.modedb[i].flag, d.modedb[i].vmode, 1153 score); 1154 1155 if (debug) 1156 ALOGD(" score=0x%x adj.res=%dx%d", score, ext_fb_xres, ext_fb_yres); 1157 if (best_score < score) { 1158 ext->width = ext_width; 1159 ext->height = ext_height; 1160 ext->xres = mode_xres; 1161 ext->yres = mode_yres; 1162 best = i; 1163 best_score = score; 1164 } 1165 } 1166 if (~best) { 1167 struct dsscomp_setup_display_data sdis = { .ix = dis_ix, }; 1168 sdis.mode = d.dis.modedb[best]; 1169 ALOGD("picking #%d", best); 1170 /* only reconfigure on change */ 1171 if (ext->last_mode != ~best) { 1172 /* set a property that apps that care (e.g. YouTube) can use 1173 * to determine whether or not to stream lower resolution 1174 * videos when the hdmi mode is < 1080p. 1175 * otherwise, they'd give us 1080p and we'd just scale it 1176 * down to the hdmi mode res. UI apps are always going 1177 * to draw at 1080p and we'll scale down because the 1178 * system can't support dynamic dpi changes. 1179 */ 1180 char display[PROPERTY_VALUE_MAX]; 1181 snprintf(display, sizeof(display), "%dx%d", 1182 d.modedb[best].xres, d.modedb[best].yres); 1183 ALOGD("setting property sys.display-size to %s", display); 1184 property_set("sys.display-size", display); 1185 1186 ioctl(hwc_dev->dsscomp_fd, DSSCIOC_SETUP_DISPLAY, &sdis); 1187 } 1188 ext->last_mode = ~best; 1189 } else { 1190 __u32 ext_width = d.dis.width_in_mm; 1191 __u32 ext_height = d.dis.height_in_mm; 1192 __u32 ext_fb_xres, ext_fb_yres; 1193 1194 get_max_dimensions(xres, yres, xpy, d.dis.timings.x_res, d.dis.timings.y_res, 1195 ext_width, ext_height, &ext_fb_xres, &ext_fb_yres); 1196 if (!d.dis.timings.pixel_clock || 1197 !omap4_hwc_can_scale(xres, yres, ext_fb_xres, ext_fb_yres, 1198 1, &d.dis, &limits, 1199 d.dis.timings.pixel_clock, NULL)) { 1200 ALOGW("DSS scaler cannot support HDMI cloning"); 1201 return -1; 1202 } 1203 } 1204 ext->last_xres_used = xres; 1205 ext->last_yres_used = yres; 1206 ext->last_xpy = xpy; 1207 if (d.dis.channel == OMAP_DSS_CHANNEL_DIGIT) 1208 ext->on_tv = 1; 1209 return 0; 1210} 1211 1212static void gather_layer_statistics(omap4_hwc_device_t *hwc_dev, struct counts *num, hwc_display_contents_1_t *list) 1213{ 1214 unsigned int i; 1215 1216 /* Figure out how many layers we can support via DSS */ 1217 for (i = 0; list && i < list->numHwLayers; i++) { 1218 hwc_layer_1_t *layer = &list->hwLayers[i]; 1219 IMG_native_handle_t *handle = (IMG_native_handle_t *)layer->handle; 1220 1221 layer->compositionType = HWC_FRAMEBUFFER; 1222 1223 if (omap4_hwc_is_valid_layer(hwc_dev, layer, handle)) { 1224 num->possible_overlay_layers++; 1225 1226 /* NV12 layers can only be rendered on scaling overlays */ 1227 if (scaled(layer) || is_NV12(handle) || hwc_dev->primary_transform) 1228 num->scaled_layers++; 1229 1230 if (is_BGR(handle)) 1231 num->BGR++; 1232 else if (is_RGB(handle)) 1233 num->RGB++; 1234 else if (is_NV12(handle)) 1235 num->NV12++; 1236 1237 if (dockable(layer)) 1238 num->dockable++; 1239 1240 if (is_protected(layer)) 1241 num->protected++; 1242 1243 num->mem += mem1d(handle); 1244 1245 if (is_large_rgb32_layer(layer)) 1246 num->large_rgb32_layers++; 1247 } 1248 } 1249 hwc_dev->stats = *num; 1250} 1251 1252static void decide_supported_cloning(omap4_hwc_device_t *hwc_dev, struct counts *num) 1253{ 1254 omap4_hwc_ext_t *ext = &hwc_dev->ext; 1255 int nonscaling_ovls = NUM_NONSCALING_OVERLAYS; 1256 num->max_hw_overlays = MAX_HW_OVERLAYS; 1257 1258 /* 1259 * We cannot atomically switch overlays from one display to another. First, they 1260 * have to be disabled, and the disabling has to take effect on the current display. 1261 * We keep track of the available number of overlays here. 1262 */ 1263 if (ext->dock.enabled && !(ext->mirror.enabled && !(num->dockable || ext->force_dock))) { 1264 /* some overlays may already be used by the external display, so we account for this */ 1265 1266 /* reserve just a video pipeline for HDMI if docking */ 1267 hwc_dev->ext_ovls = (num->dockable || ext->force_dock) ? 1 : 0; 1268 num->max_hw_overlays -= max(hwc_dev->ext_ovls, hwc_dev->last_ext_ovls); 1269 1270 /* use mirroring transform if we are auto-switching to docking mode while mirroring*/ 1271 if (ext->mirror.enabled) { 1272 ext->current = ext->mirror; 1273 ext->current.docking = 1; 1274 } else { 1275 ext->current = ext->dock; 1276 } 1277 } else if (ext->mirror.enabled) { 1278 /* 1279 * otherwise, manage just from half the pipelines. NOTE: there is 1280 * no danger of having used too many overlays for external display here. 1281 */ 1282 1283 num->max_hw_overlays >>= 1; 1284 nonscaling_ovls >>= 1; 1285 hwc_dev->ext_ovls = MAX_HW_OVERLAYS - num->max_hw_overlays; 1286 ext->current = ext->mirror; 1287 } else { 1288 num->max_hw_overlays -= hwc_dev->last_ext_ovls; 1289 hwc_dev->ext_ovls = 0; 1290 ext->current.enabled = 0; 1291 } 1292 1293 /* 1294 * :TRICKY: We may not have enough overlays on the external display. We "reserve" them 1295 * here to figure out if mirroring is supported, but may not do mirroring for the first 1296 * frame while the overlays required for it are cleared. 1297 */ 1298 hwc_dev->ext_ovls_wanted = hwc_dev->ext_ovls; 1299 hwc_dev->ext_ovls = min(MAX_HW_OVERLAYS - hwc_dev->last_int_ovls, hwc_dev->ext_ovls); 1300 1301 /* if mirroring, we are limited by both internal and external overlays. However, 1302 ext_ovls is always <= MAX_HW_OVERLAYS / 2 <= max_hw_overlays */ 1303 if (!num->protected && hwc_dev->ext_ovls && ext->current.enabled && !ext->current.docking) 1304 num->max_hw_overlays = hwc_dev->ext_ovls; 1305 1306 /* If FB is not same resolution as LCD don't use GFX pipe line*/ 1307 if (hwc_dev->primary_transform) { 1308 num->max_hw_overlays -= NUM_NONSCALING_OVERLAYS; 1309 num->max_scaling_overlays = num->max_hw_overlays; 1310 } else 1311 num->max_scaling_overlays = num->max_hw_overlays - nonscaling_ovls; 1312} 1313 1314/* how many large layers can be composited by the DSS */ 1315static const unsigned int MAX_DSS_LARGE_LAYERS = 4; 1316 1317static int can_dss_render_all(omap4_hwc_device_t *hwc_dev, struct counts *num) 1318{ 1319 omap4_hwc_ext_t *ext = &hwc_dev->ext; 1320 int on_tv = hwc_dev->on_tv || (ext->on_tv && ext->current.enabled); 1321 int tform = ext->current.enabled && (ext->current.rotation || ext->current.hflip); 1322 1323 return !hwc_dev->force_sgx && 1324 /* must have at least one layer if using composition bypass to get sync object */ 1325 num->possible_overlay_layers && 1326 num->possible_overlay_layers <= num->max_hw_overlays && 1327 num->possible_overlay_layers == num->composited_layers && 1328 num->scaled_layers <= num->max_scaling_overlays && 1329 num->NV12 <= num->max_scaling_overlays && 1330 /* fits into TILER slot */ 1331 num->mem <= limits.tiler1d_slot_size && 1332 /* we cannot clone non-NV12 transformed layers */ 1333 (!tform || (num->NV12 == num->possible_overlay_layers) || 1334 (num->NV12 && ext->current.docking)) && 1335 /* HDMI cannot display BGR */ 1336 (num->BGR == 0 || (num->RGB == 0 && !on_tv) || !hwc_dev->flags_rgb_order) && 1337 /* current hardware can only handle a limited number of 'large' RGB32 layers */ 1338 num->large_rgb32_layers <= MAX_DSS_LARGE_LAYERS; 1339} 1340 1341static inline int can_dss_render_layer(omap4_hwc_device_t *hwc_dev, 1342 hwc_layer_1_t *layer) 1343{ 1344 IMG_native_handle_t *handle = (IMG_native_handle_t *)layer->handle; 1345 1346 omap4_hwc_ext_t *ext = &hwc_dev->ext; 1347 int cloning = ext->current.enabled && (!ext->current.docking || (handle!=NULL ? dockable(layer) : 0)); 1348 int on_tv = hwc_dev->on_tv || (ext->on_tv && cloning); 1349 int tform = cloning && (ext->current.rotation || ext->current.hflip); 1350 1351 return omap4_hwc_is_valid_layer(hwc_dev, layer, handle) && 1352 /* cannot rotate non-NV12 layers on external display */ 1353 (!tform || is_NV12(handle)) && 1354 /* skip non-NV12 layers if also using SGX (if nv12_only flag is set) */ 1355 (!hwc_dev->flags_nv12_only || (!hwc_dev->use_sgx || is_NV12(handle))) && 1356 /* make sure RGB ordering is consistent (if rgb_order flag is set) */ 1357 (!(hwc_dev->swap_rb ? is_RGB(handle) : is_BGR(handle)) || 1358 !hwc_dev->flags_rgb_order) && 1359 /* TV can only render RGB */ 1360 !(on_tv && is_BGR(handle)); 1361} 1362 1363static inline int display_area(struct dss2_ovl_info *o) 1364{ 1365 return o->cfg.win.w * o->cfg.win.h; 1366} 1367 1368static int clone_layer(omap4_hwc_device_t *hwc_dev, int ix) { 1369 struct dsscomp_setup_dispc_data *dsscomp = &hwc_dev->comp_data.dsscomp_data; 1370 omap4_hwc_ext_t *ext = &hwc_dev->ext; 1371 int ext_ovl_ix = dsscomp->num_ovls - hwc_dev->post2_layers; 1372 struct dss2_ovl_info *o = &dsscomp->ovls[dsscomp->num_ovls]; 1373 1374 if (dsscomp->num_ovls >= MAX_HW_OVERLAYS) { 1375 ALOGE("**** cannot clone layer #%d. using all %d overlays.", ix, dsscomp->num_ovls); 1376 return -EBUSY; 1377 } 1378 1379 memcpy(o, dsscomp->ovls + ix, sizeof(*o)); 1380 1381 /* reserve overlays at end for other display */ 1382 o->cfg.ix = MAX_HW_OVERLAYS - 1 - ext_ovl_ix; 1383 o->cfg.mgr_ix = 1; 1384 /* 1385 * Here the assumption is that overlay0 is the one attached to FB. 1386 * Hence this clone_layer call is for FB cloning (provided use_sgx is true). 1387 */ 1388 /* For the external displays whose transform is the same as 1389 * that of primary display, ion_handles would be NULL hence 1390 * the below logic doesn't execute. 1391 */ 1392 if (ix == 0 && hwc_dev->ion_handles[sync_id%2] && hwc_dev->use_sgx) { 1393 o->addressing = OMAP_DSS_BUFADDR_ION; 1394 o->ba = (int)hwc_dev->ion_handles[sync_id%2]; 1395 } else { 1396 o->addressing = OMAP_DSS_BUFADDR_OVL_IX; 1397 o->ba = ix; 1398 } 1399 1400 /* use distinct z values (to simplify z-order checking) */ 1401 o->cfg.zorder += hwc_dev->post2_layers; 1402 1403 omap4_hwc_adjust_ext_layer(&hwc_dev->ext, o); 1404 dsscomp->num_ovls++; 1405 return 0; 1406} 1407 1408static int clone_external_layer(omap4_hwc_device_t *hwc_dev, int ix) { 1409 struct dsscomp_setup_dispc_data *dsscomp = &hwc_dev->comp_data.dsscomp_data; 1410 omap4_hwc_ext_t *ext = &hwc_dev->ext; 1411 1412 /* mirror only 1 external layer */ 1413 struct dss2_ovl_info *o = &dsscomp->ovls[ix]; 1414 1415 /* full screen video after transformation */ 1416 __u32 xres = o->cfg.crop.w, yres = o->cfg.crop.h; 1417 if ((ext->current.rotation + o->cfg.rotation) & 1) 1418 swap(xres, yres); 1419 float xpy = ext->lcd_xpy * o->cfg.win.w / o->cfg.win.h; 1420 if (o->cfg.rotation & 1) 1421 xpy = o->cfg.crop.h / xpy / o->cfg.crop.w; 1422 else 1423 xpy = o->cfg.crop.h * xpy / o->cfg.crop.w; 1424 if (ext->current.rotation & 1) 1425 xpy = 1. / xpy; 1426 1427 /* adjust hdmi mode based on resolution */ 1428 if (xres != ext->last_xres_used || 1429 yres != ext->last_yres_used || 1430 xpy < ext->last_xpy * (1.f - ASPECT_RATIO_TOLERANCE) || 1431 xpy * (1.f - ASPECT_RATIO_TOLERANCE) > ext->last_xpy) { 1432 ALOGD("set up HDMI for %d*%d\n", xres, yres); 1433 if (omap4_hwc_set_best_hdmi_mode(hwc_dev, xres, yres, xpy)) { 1434 ext->current.enabled = 0; 1435 return -ENODEV; 1436 } 1437 } 1438 1439 struct hwc_rect region = { 1440 .left = o->cfg.win.x, .top = o->cfg.win.y, 1441 .right = o->cfg.win.x + o->cfg.win.w, 1442 .bottom = o->cfg.win.y + o->cfg.win.h 1443 }; 1444 set_ext_matrix(&hwc_dev->ext, region); 1445 1446 return clone_layer(hwc_dev, ix); 1447} 1448 1449static int setup_mirroring(omap4_hwc_device_t *hwc_dev) 1450{ 1451 omap4_hwc_ext_t *ext = &hwc_dev->ext; 1452 1453 __u32 xres = WIDTH(ext->mirror_region); 1454 __u32 yres = HEIGHT(ext->mirror_region); 1455 if (ext->current.rotation & 1) 1456 swap(xres, yres); 1457 if (omap4_hwc_set_best_hdmi_mode(hwc_dev, xres, yres, ext->lcd_xpy)) 1458 return -ENODEV; 1459 set_ext_matrix(ext, ext->mirror_region); 1460 return 0; 1461} 1462 1463/* 1464 * We're using "implicit" synchronization, so make sure we aren't passing any 1465 * sync object descriptors around. 1466 */ 1467static void check_sync_fds(size_t numDisplays, hwc_display_contents_1_t** displays) 1468{ 1469 //ALOGD("checking sync FDs"); 1470 unsigned int i, j; 1471 for (i = 0; i < numDisplays; i++) { 1472 hwc_display_contents_1_t* list = displays[i]; 1473 if (list->retireFenceFd >= 0) { 1474 ALOGW("retireFenceFd[%u] was %d", i, list->retireFenceFd); 1475 list->retireFenceFd = -1; 1476 } 1477 1478 for (j = 0; j < list->numHwLayers; j++) { 1479 hwc_layer_1_t* layer = &list->hwLayers[j]; 1480 if (layer->acquireFenceFd >= 0) { 1481 ALOGW("acquireFenceFd[%u][%u] was %d, closing", i, j, layer->acquireFenceFd); 1482 close(layer->acquireFenceFd); 1483 layer->acquireFenceFd = -1; 1484 } 1485 if (layer->releaseFenceFd >= 0) { 1486 ALOGW("releaseFenceFd[%u][%u] was %d", i, j, layer->releaseFenceFd); 1487 layer->releaseFenceFd = -1; 1488 } 1489 } 1490 } 1491} 1492 1493static void blit_reset(omap4_hwc_device_t *hwc_dev, int flags) 1494{ 1495 hwc_dev->blit_flags = 0; 1496 hwc_dev->blit_num = 0; 1497 hwc_dev->post2_blit_buffers = 0; 1498 hwc_dev->comp_data.blit_data.rgz_items = 0; 1499 1500 /* We want to maintain the rgz dirty region data if there are no geometry changes */ 1501 if (flags & HWC_GEOMETRY_CHANGED) 1502 rgz_release(&grgz); 1503} 1504 1505static int blit_layers(omap4_hwc_device_t *hwc_dev, hwc_display_contents_1_t *list, int bufoff) 1506{ 1507 /* Do not blit if this frame will be composed entirely by the GPU */ 1508 if (!list || hwc_dev->force_sgx) 1509 goto err_out; 1510 1511 int rgz_in_op; 1512 int rgz_out_op; 1513 1514 switch (hwc_dev->blt_mode) { 1515 case BLTMODE_PAINT: 1516 rgz_in_op = RGZ_IN_HWCCHK; 1517 rgz_out_op = RGZ_OUT_BVCMD_PAINT; 1518 break; 1519 case BLTMODE_REGION: 1520 default: 1521 rgz_in_op = RGZ_IN_HWC; 1522 rgz_out_op = RGZ_OUT_BVCMD_REGION; 1523 break; 1524 } 1525 1526 rgz_in_params_t in = { 1527 .op = rgz_in_op, 1528 .data = { 1529 .hwc = { 1530 .dstgeom = &gscrngeom, 1531 .layers = list->hwLayers, 1532 .layerno = list->numHwLayers 1533 } 1534 } 1535 }; 1536 1537 /* 1538 * This means if all the layers marked for the FRAMEBUFFER cannot be 1539 * blitted, do not blit, for e.g. SKIP layers 1540 */ 1541 if (rgz_in(&in, &grgz) != RGZ_ALL) 1542 goto err_out; 1543 1544 unsigned int i, count = 0; 1545 for (i = 0; i < list->numHwLayers; i++) { 1546 if (list->hwLayers[i].compositionType != HWC_OVERLAY) { 1547 count++; 1548 } 1549 } 1550 1551 rgz_out_params_t out = { 1552 .op = rgz_out_op, 1553 .data = { 1554 .bvc = { 1555 .dstgeom = &gscrngeom, 1556 .noblend = 0, 1557 } 1558 } 1559 }; 1560 1561 if (rgz_out(&grgz, &out) != 0) { 1562 ALOGE("Failed generating blits"); 1563 goto err_out; 1564 } 1565 1566 /* This is a special situation where the regionizer decided no blits are 1567 * needed for this frame but there are blit buffers to synchronize with. Can 1568 * happen only if the regionizer is enabled otherwise it's likely a bug 1569 */ 1570 if (rgz_out_op != RGZ_OUT_BVCMD_REGION && out.data.bvc.out_blits == 0 && out.data.bvc.out_nhndls > 0) { 1571 ALOGE("Regionizer invalid output blit_num %d, post2_blit_buffers %d", out.data.bvc.out_blits, out.data.bvc.out_nhndls); 1572 goto err_out; 1573 } 1574 1575 hwc_dev->blit_flags |= HWC_BLT_FLAG_USE_FB; 1576 hwc_dev->blit_num = out.data.bvc.out_blits; 1577 hwc_dev->post2_blit_buffers = out.data.bvc.out_nhndls; 1578 for (i = 0; i < hwc_dev->post2_blit_buffers; i++) { 1579 //ALOGI("blit buffers[%d] = %p", bufoff, out.data.bvc.out_hndls[i]); 1580 hwc_dev->buffers[bufoff++] = out.data.bvc.out_hndls[i]; 1581 } 1582 1583 struct rgz_blt_entry *res_blit_ops = (struct rgz_blt_entry *) out.data.bvc.cmdp; 1584 memcpy(hwc_dev->comp_data.blit_data.rgz_blts, res_blit_ops, sizeof(*res_blit_ops) * out.data.bvc.cmdlen); 1585 ALOGI_IF(debugblt, "blt struct sz %d", sizeof(*res_blit_ops) * out.data.bvc.cmdlen); 1586 ALOGE_IF(hwc_dev->blit_num != out.data.bvc.cmdlen,"blit_num != out.data.bvc.cmdlen, %d != %d", hwc_dev->blit_num, out.data.bvc.cmdlen); 1587 1588 /* all layers will be rendered without SGX help either via DSS or blitter */ 1589 for (i = 0; i < list->numHwLayers; i++) { 1590 if (list->hwLayers[i].compositionType != HWC_OVERLAY) { 1591 list->hwLayers[i].compositionType = HWC_OVERLAY; 1592 //ALOGI("blitting layer %d", i); 1593 list->hwLayers[i].hints &= ~HWC_HINT_TRIPLE_BUFFER; 1594 } 1595 list->hwLayers[i].hints &= ~HWC_HINT_CLEAR_FB; 1596 } 1597 return 1; 1598 1599err_out: 1600 rgz_release(&grgz); 1601 return 0; 1602} 1603 1604void debug_post2(omap4_hwc_device_t *hwc_dev, int nbufs) 1605{ 1606 if (!debugpost2) 1607 return; 1608 struct dsscomp_setup_dispc_data *dsscomp = &hwc_dev->comp_data.dsscomp_data; 1609 int i; 1610 for (i=0; i<nbufs; i++) { 1611 ALOGI("buf[%d] hndl %p", i, hwc_dev->buffers[i]); 1612 } 1613 for (i=0; i < dsscomp->num_ovls; i++) { 1614 ALOGI("ovl[%d] ba %d", i, dsscomp->ovls[i].ba); 1615 } 1616} 1617 1618static int free_tiler2d_buffers(omap4_hwc_device_t *hwc_dev) 1619{ 1620 int i; 1621 1622 for (i = 0 ; i < NUM_EXT_DISPLAY_BACK_BUFFERS; i++) { 1623 ion_free(hwc_dev->ion_fd, hwc_dev->ion_handles[i]); 1624 hwc_dev->ion_handles[i] = NULL; 1625 } 1626 return 0; 1627} 1628 1629static int allocate_tiler2d_buffers(omap4_hwc_device_t *hwc_dev) 1630{ 1631 int ret, i; 1632 size_t stride; 1633 1634 if (hwc_dev->ion_fd < 0) { 1635 ALOGE("No ion fd, hence can't allocate tiler2d buffers"); 1636 return -1; 1637 } 1638 1639 for (i = 0; i < NUM_EXT_DISPLAY_BACK_BUFFERS; i++) { 1640 if (hwc_dev->ion_handles[i]) 1641 return 0; 1642 } 1643 1644 for (i = 0 ; i < NUM_EXT_DISPLAY_BACK_BUFFERS; i++) { 1645 ret = ion_alloc_tiler(hwc_dev->ion_fd, hwc_dev->fb_dev->base.width, hwc_dev->fb_dev->base.height, 1646 TILER_PIXEL_FMT_32BIT, 0, &hwc_dev->ion_handles[i], &stride); 1647 if (ret) 1648 goto handle_error; 1649 1650 ALOGI("ion handle[%d][%p]", i, hwc_dev->ion_handles[i]); 1651 } 1652 return 0; 1653 1654handle_error: 1655 free_tiler2d_buffers(hwc_dev); 1656 return -1; 1657} 1658 1659static int omap4_hwc_prepare(struct hwc_composer_device_1 *dev, size_t numDisplays, 1660 hwc_display_contents_1_t** displays) 1661{ 1662 if (!numDisplays || displays == NULL) { 1663 return 0; 1664 } 1665 1666 hwc_display_contents_1_t* list = displays[0]; // ignore displays beyond the first 1667 omap4_hwc_device_t *hwc_dev = (omap4_hwc_device_t *)dev; 1668 struct dsscomp_setup_dispc_data *dsscomp = &hwc_dev->comp_data.dsscomp_data; 1669 struct counts num = { .composited_layers = list ? list->numHwLayers : 0 }; 1670 unsigned int i, ix; 1671 1672 pthread_mutex_lock(&hwc_dev->lock); 1673 memset(dsscomp, 0x0, sizeof(*dsscomp)); 1674 dsscomp->sync_id = sync_id++; 1675 1676 gather_layer_statistics(hwc_dev, &num, list); 1677 1678 decide_supported_cloning(hwc_dev, &num); 1679 1680 /* phase 3 logic */ 1681 if (can_dss_render_all(hwc_dev, &num)) { 1682 /* All layers can be handled by the DSS -- don't use SGX for composition */ 1683 hwc_dev->use_sgx = 0; 1684 hwc_dev->swap_rb = num.BGR != 0; 1685 } else { 1686 /* Use SGX for composition plus first 3 layers that are DSS renderable */ 1687 hwc_dev->use_sgx = 1; 1688 hwc_dev->swap_rb = is_BGR_format(hwc_dev->fb_dev->base.format); 1689 } 1690 1691 /* setup pipes */ 1692 int z = 0; 1693 int fb_z = -1; 1694 int scaled_gfx = 0; 1695 int ix_docking = -1; 1696 unsigned int big_layers = 0; 1697 1698 int blit_all = 0; 1699 blit_reset(hwc_dev, list ? list->flags : 0); 1700 1701 /* If the SGX is used or we are going to blit something we need a framebuffer 1702 * and a DSS pipe 1703 */ 1704 int needs_fb = hwc_dev->use_sgx; 1705 1706 if (hwc_dev->blt_policy == BLTPOLICY_ALL) { 1707 /* Check if we can blit everything */ 1708 blit_all = blit_layers(hwc_dev, list, 0); 1709 if (blit_all) { 1710 needs_fb = 1; 1711 hwc_dev->use_sgx = 0; 1712 } 1713 } 1714 1715 /* If a framebuffer is needed, begin using VID1 for DSS overlay layers, 1716 * we need GFX for FB 1717 */ 1718 dsscomp->num_ovls = needs_fb ? 1 /*VID1*/ : 0 /*GFX*/; 1719 1720 /* set up if DSS layers */ 1721 unsigned int mem_used = 0; 1722 for (i = 0; list && i < list->numHwLayers && !blit_all; i++) { 1723 hwc_layer_1_t *layer = &list->hwLayers[i]; 1724 IMG_native_handle_t *handle = (IMG_native_handle_t *)layer->handle; 1725 1726 if (dsscomp->num_ovls < num.max_hw_overlays && 1727 can_dss_render_layer(hwc_dev, layer) && 1728 (!hwc_dev->force_sgx || 1729 /* render protected and dockable layers via DSS */ 1730 is_protected(layer) || 1731 is_upscaled_NV12(hwc_dev, layer) || 1732 (hwc_dev->ext.current.docking && hwc_dev->ext.current.enabled && dockable(layer))) && 1733 mem_used + mem1d(handle) <= limits.tiler1d_slot_size && 1734 /* can't have a transparent overlay in the middle of the framebuffer stack */ 1735 !(is_BLENDED(layer) && fb_z >= 0) && 1736 /* current hardware can only handle a limited number of 'large' RGB32 layers */ 1737 !(is_large_rgb32_layer(layer) && big_layers >= MAX_DSS_LARGE_LAYERS)) { 1738 1739 /* render via DSS overlay */ 1740 mem_used += mem1d(handle); 1741 layer->compositionType = HWC_OVERLAY; 1742 /* 1743 * This hint will not be used in vanilla ICS, but maybe in 1744 * JellyBean, it is useful to distinguish between blts and true 1745 * overlays 1746 */ 1747 layer->hints |= HWC_HINT_TRIPLE_BUFFER; 1748 1749 /* clear FB above all opaque layers if rendering via SGX */ 1750 if (hwc_dev->use_sgx && !is_BLENDED(layer)) 1751 layer->hints |= HWC_HINT_CLEAR_FB; 1752 1753 hwc_dev->buffers[dsscomp->num_ovls] = layer->handle; 1754 1755 omap4_hwc_setup_layer(hwc_dev, 1756 &dsscomp->ovls[dsscomp->num_ovls], 1757 layer, 1758 z, 1759 handle->iFormat, 1760 handle->iWidth, 1761 handle->iHeight); 1762 1763 dsscomp->ovls[dsscomp->num_ovls].cfg.ix = dsscomp->num_ovls + hwc_dev->primary_transform; 1764 dsscomp->ovls[dsscomp->num_ovls].addressing = OMAP_DSS_BUFADDR_LAYER_IX; 1765 dsscomp->ovls[dsscomp->num_ovls].ba = dsscomp->num_ovls; 1766 1767 /* ensure GFX layer is never scaled */ 1768 if ((dsscomp->num_ovls == 0) && (!hwc_dev->primary_transform)) { 1769 scaled_gfx = scaled(layer) || is_NV12(handle); 1770 } else if (scaled_gfx && !scaled(layer) && !is_NV12(handle)) { 1771 /* swap GFX layer with this one */ 1772 dsscomp->ovls[dsscomp->num_ovls].cfg.ix = 0; 1773 dsscomp->ovls[0].cfg.ix = dsscomp->num_ovls; 1774 scaled_gfx = 0; 1775 } 1776 1777 /* remember largest dockable layer */ 1778 if (dockable(layer) && 1779 (ix_docking < 0 || 1780 display_area(&dsscomp->ovls[dsscomp->num_ovls]) > display_area(&dsscomp->ovls[ix_docking]))) 1781 ix_docking = dsscomp->num_ovls; 1782 1783 dsscomp->num_ovls++; 1784 z++; 1785 1786 /* record whether or not this was a 'big' RGB32 layer */ 1787 if (is_large_rgb32_layer(layer)) { 1788 big_layers++; 1789 } 1790 } else if (hwc_dev->use_sgx) { 1791 if (fb_z < 0) { 1792 /* NOTE: we are not handling transparent cutout for now */ 1793 fb_z = z; 1794 z++; 1795 } else { 1796 /* move fb z-order up (by lowering dss layers) */ 1797 while (fb_z < z - 1) 1798 dsscomp->ovls[1 + fb_z++].cfg.zorder--; 1799 } 1800 } 1801 } 1802 1803 /* if scaling GFX (e.g. only 1 scaled surface) use a VID pipe */ 1804 if (scaled_gfx) 1805 dsscomp->ovls[0].cfg.ix = dsscomp->num_ovls; 1806 1807 if (hwc_dev->blt_policy == BLTPOLICY_DEFAULT) { 1808 if (hwc_dev->use_sgx) { 1809 if (blit_layers(hwc_dev, list, dsscomp->num_ovls == 1 ? 0 : dsscomp->num_ovls)) { 1810 hwc_dev->use_sgx = 0; 1811 } 1812 } 1813 } 1814 1815 /* If the SGX is not used and there is blit data we need a framebuffer and 1816 * a DSS pipe well configured for it 1817 */ 1818 if (needs_fb) { 1819 /* assign a z-layer for fb */ 1820 if (fb_z < 0) { 1821 if (!hwc_dev->blt_policy != BLTPOLICY_DISABLED && num.composited_layers) 1822 ALOGE("**** should have assigned z-layer for fb"); 1823 fb_z = z++; 1824 } 1825 /* 1826 * This is needed because if we blit all we would lose the handle of 1827 * the first layer 1828 */ 1829 if (hwc_dev->use_sgx) { 1830 hwc_dev->buffers[0] = NULL; 1831 } 1832 omap4_hwc_setup_layer_base(&dsscomp->ovls[0].cfg, fb_z, 1833 hwc_dev->fb_dev->base.format, 1834 1, /* FB is always premultiplied */ 1835 hwc_dev->fb_dev->base.width, 1836 hwc_dev->fb_dev->base.height); 1837 dsscomp->ovls[0].cfg.pre_mult_alpha = 1; 1838 dsscomp->ovls[0].addressing = OMAP_DSS_BUFADDR_LAYER_IX; 1839 dsscomp->ovls[0].ba = 0; 1840 dsscomp->ovls[0].cfg.ix = hwc_dev->primary_transform; 1841 } 1842 1843 /* mirror layers */ 1844 hwc_dev->post2_layers = dsscomp->num_ovls; 1845 1846 omap4_hwc_ext_t *ext = &hwc_dev->ext; 1847 if (ext->current.enabled && hwc_dev->ext_ovls) { 1848 if (ext->current.docking && ix_docking >= 0) { 1849 if (clone_external_layer(hwc_dev, ix_docking) == 0) 1850 dsscomp->ovls[dsscomp->num_ovls - 1].cfg.zorder = z++; 1851 } else if (ext->current.docking && ix_docking < 0 && ext->force_dock) { 1852 ix_docking = dsscomp->num_ovls; 1853 struct dss2_ovl_info *oi = &dsscomp->ovls[ix_docking]; 1854 omap4_hwc_setup_layer_base(&oi->cfg, 0, HAL_PIXEL_FORMAT_BGRA_8888, 1, 1855 dock_image.width, dock_image.height); 1856 oi->cfg.stride = dock_image.rowbytes; 1857 if (clone_external_layer(hwc_dev, ix_docking) == 0) { 1858 oi->addressing = OMAP_DSS_BUFADDR_FB; 1859 oi->ba = 0; 1860 z++; 1861 } 1862 } else if (!ext->current.docking) { 1863 int res = 0; 1864 1865 /* reset mode if we are coming from docking */ 1866 if (ext->last.docking) 1867 res = setup_mirroring(hwc_dev); 1868 1869 /* mirror all layers */ 1870 for (ix = 0; res == 0 && ix < hwc_dev->post2_layers; ix++) { 1871 if (clone_layer(hwc_dev, ix)) 1872 break; 1873 z++; 1874 } 1875 } 1876 } 1877 1878 /* Apply transform for primary display */ 1879 if (hwc_dev->primary_transform) 1880 for (i = 0; i < dsscomp->num_ovls; i++) { 1881 if(dsscomp->ovls[i].cfg.mgr_ix == 0) 1882 omap4_hwc_adjust_primary_display_layer(hwc_dev, &dsscomp->ovls[i]); 1883 } 1884 1885 ext->last = ext->current; 1886 1887 if (z != dsscomp->num_ovls || dsscomp->num_ovls > MAX_HW_OVERLAYS) 1888 ALOGE("**** used %d z-layers for %d overlays\n", z, dsscomp->num_ovls); 1889 1890 /* verify all z-orders and overlay indices are distinct */ 1891 for (i = z = ix = 0; i < dsscomp->num_ovls; i++) { 1892 struct dss2_ovl_cfg *c = &dsscomp->ovls[i].cfg; 1893 1894 if (z & (1 << c->zorder)) 1895 ALOGE("**** used z-order #%d multiple times", c->zorder); 1896 if (ix & (1 << c->ix)) 1897 ALOGE("**** used ovl index #%d multiple times", c->ix); 1898 z |= 1 << c->zorder; 1899 ix |= 1 << c->ix; 1900 } 1901 dsscomp->mode = DSSCOMP_SETUP_DISPLAY; 1902 dsscomp->mgrs[0].ix = 0; 1903 dsscomp->mgrs[0].alpha_blending = 1; 1904 dsscomp->mgrs[0].swap_rb = hwc_dev->swap_rb; 1905 dsscomp->num_mgrs = 1; 1906 1907 if (ext->current.enabled || hwc_dev->last_ext_ovls) { 1908 dsscomp->mgrs[1] = dsscomp->mgrs[0]; 1909 dsscomp->mgrs[1].ix = 1; 1910 dsscomp->num_mgrs++; 1911 hwc_dev->ext_ovls = dsscomp->num_ovls - hwc_dev->post2_layers; 1912 } 1913 1914 /* 1915 * Whilst the mode of the display is being changed drop compositions to the 1916 * display 1917 */ 1918 if (ext->last_mode == 0 && hwc_dev->on_tv) { 1919 dsscomp->num_ovls = 0; 1920 } 1921 1922 if (debug) { 1923 ALOGD("prepare (%d) - %s (comp=%d, poss=%d/%d scaled, RGB=%d,BGR=%d,NV12=%d) (ext=%s%s%ddeg%s %dex/%dmx (last %dex,%din)\n", 1924 dsscomp->sync_id, 1925 hwc_dev->use_sgx ? "SGX+OVL" : "all-OVL", 1926 num.composited_layers, 1927 num.possible_overlay_layers, num.scaled_layers, 1928 num.RGB, num.BGR, num.NV12, 1929 ext->on_tv ? "tv+" : "", 1930 ext->current.enabled ? ext->current.docking ? "dock+" : "mirror+" : "OFF+", 1931 ext->current.rotation * 90, 1932 ext->current.hflip ? "+hflip" : "", 1933 hwc_dev->ext_ovls, num.max_hw_overlays, hwc_dev->last_ext_ovls, hwc_dev->last_int_ovls); 1934 } 1935 1936 pthread_mutex_unlock(&hwc_dev->lock); 1937 return 0; 1938} 1939 1940static void omap4_hwc_reset_screen(omap4_hwc_device_t *hwc_dev) 1941{ 1942 static int first_set = 1; 1943 int ret; 1944 1945 if (first_set) { 1946 first_set = 0; 1947 struct dsscomp_setup_dispc_data d = { 1948 .num_mgrs = 1, 1949 }; 1950 /* remove bootloader image from the screen as blank/unblank does not change the composition */ 1951 ret = ioctl(hwc_dev->dsscomp_fd, DSSCIOC_SETUP_DISPC, &d); 1952 if (ret) 1953 ALOGW("failed to remove bootloader image"); 1954 1955 /* blank and unblank fd to make sure display is properly programmed on boot. 1956 * This is needed because the bootloader can not be trusted. 1957 */ 1958 ret = ioctl(hwc_dev->fb_fd, FBIOBLANK, FB_BLANK_POWERDOWN); 1959 if (ret) 1960 ALOGW("failed to blank display"); 1961 1962 ret = ioctl(hwc_dev->fb_fd, FBIOBLANK, FB_BLANK_UNBLANK); 1963 if (ret) 1964 ALOGW("failed to blank display"); 1965 } 1966} 1967 1968static int omap4_hwc_set(struct hwc_composer_device_1 *dev, 1969 size_t numDisplays, hwc_display_contents_1_t** displays) 1970{ 1971 if (!numDisplays || displays == NULL) { 1972 ALOGD("set: empty display list"); 1973 return 0; 1974 } 1975 hwc_display_t dpy = NULL; 1976 hwc_surface_t sur = NULL; 1977 hwc_display_contents_1_t* list = displays[0]; // ignore displays beyond the first 1978 if (list != NULL) { 1979 dpy = list->dpy; 1980 sur = list->sur; 1981 } 1982 omap4_hwc_device_t *hwc_dev = (omap4_hwc_device_t *)dev; 1983 struct dsscomp_setup_dispc_data *dsscomp = &hwc_dev->comp_data.dsscomp_data; 1984 int err = 0; 1985 int invalidate; 1986 1987 pthread_mutex_lock(&hwc_dev->lock); 1988 1989 /* disable resetting the screen on the first boot for devices 1990 * with hdmi as primary input. 1991 */ 1992 if (!hwc_dev->on_tv) 1993 omap4_hwc_reset_screen(hwc_dev); 1994 1995 invalidate = hwc_dev->ext_ovls_wanted && (hwc_dev->ext_ovls < hwc_dev->ext_ovls_wanted) && 1996 (hwc_dev->stats.protected || !hwc_dev->ext_ovls); 1997 1998 if (debug) 1999 dump_set_info(hwc_dev, list); 2000 2001 if (dpy && sur) { 2002 // list can be NULL which means hwc is temporarily disabled. 2003 // however, if dpy and sur are null it means we're turning the 2004 // screen off. no shall not call eglSwapBuffers() in that case. 2005 2006 if (hwc_dev->use_sgx) { 2007 if (!eglSwapBuffers((EGLDisplay)dpy, (EGLSurface)sur)) { 2008 ALOGE("eglSwapBuffers error"); 2009 err = HWC_EGL_ERROR; 2010 goto err_out; 2011 } 2012 } 2013 2014 //dump_dsscomp(dsscomp); 2015 2016 // signal the event thread that a post has happened 2017 wakeup_hdmi_thread(hwc_dev); 2018 if (hwc_dev->force_sgx > 0) 2019 hwc_dev->force_sgx--; 2020 2021 hwc_dev->comp_data.blit_data.rgz_flags = hwc_dev->blit_flags; 2022 hwc_dev->comp_data.blit_data.rgz_items = hwc_dev->blit_num; 2023 int omaplfb_comp_data_sz = sizeof(hwc_dev->comp_data) + 2024 (hwc_dev->comp_data.blit_data.rgz_items * sizeof(struct rgz_blt_entry)); 2025 2026 2027 unsigned int nbufs = hwc_dev->post2_layers; 2028 if (hwc_dev->post2_blit_buffers) { 2029 /* 2030 * We don't want to pass a NULL entry in the Post2, but we need to 2031 * fix up buffer handle array and overlay indexes to account for 2032 * this 2033 */ 2034 nbufs += hwc_dev->post2_blit_buffers - 1; 2035 2036 if (hwc_dev->post2_layers > 1) { 2037 unsigned int i, j; 2038 for (i = 0; i < nbufs; i++) { 2039 hwc_dev->buffers[i] = hwc_dev->buffers[i+1]; 2040 } 2041 for (i = 1, j= 1; j < hwc_dev->post2_layers; i++, j++) { 2042 dsscomp->ovls[j].ba = i; 2043 } 2044 } 2045 } 2046 ALOGI_IF(debugblt && hwc_dev->blt_policy != BLTPOLICY_DISABLED, 2047 "Post2, blits %d, ovl_buffers %d, blit_buffers %d sgx %d", 2048 hwc_dev->blit_num, hwc_dev->post2_layers, hwc_dev->post2_blit_buffers, 2049 hwc_dev->use_sgx); 2050 2051 debug_post2(hwc_dev, nbufs); 2052 err = hwc_dev->fb_dev->Post2((framebuffer_device_t *)hwc_dev->fb_dev, 2053 hwc_dev->buffers, 2054 nbufs, 2055 dsscomp, omaplfb_comp_data_sz); 2056 showfps(); 2057 2058#if 0 2059 if (!hwc_dev->use_sgx) { 2060 __u32 crt = 0; 2061 int err2 = ioctl(hwc_dev->fb_fd, FBIO_WAITFORVSYNC, &crt); 2062 if (err2) { 2063 ALOGE("failed to wait for vsync (%d)", errno); 2064 err = err ? : -errno; 2065 } 2066 } 2067#endif 2068 } 2069 hwc_dev->last_ext_ovls = hwc_dev->ext_ovls; 2070 hwc_dev->last_int_ovls = hwc_dev->post2_layers; 2071 if (err) 2072 ALOGE("Post2 error"); 2073 2074 check_sync_fds(numDisplays, displays); 2075 2076err_out: 2077 pthread_mutex_unlock(&hwc_dev->lock); 2078 2079 if (invalidate && hwc_dev->procs && hwc_dev->procs->invalidate) 2080 hwc_dev->procs->invalidate(hwc_dev->procs); 2081 2082 return err; 2083} 2084 2085static void omap4_hwc_dump(struct hwc_composer_device_1 *dev, char *buff, int buff_len) 2086{ 2087 omap4_hwc_device_t *hwc_dev = (omap4_hwc_device_t *)dev; 2088 struct dsscomp_setup_dispc_data *dsscomp = &hwc_dev->comp_data.dsscomp_data; 2089 struct dump_buf log = { 2090 .buf = buff, 2091 .buf_len = buff_len, 2092 }; 2093 int i; 2094 2095 dump_printf(&log, "omap4_hwc %d:\n", dsscomp->num_ovls); 2096 dump_printf(&log, " idle timeout: %dms\n", hwc_dev->idle); 2097 2098 for (i = 0; i < dsscomp->num_ovls; i++) { 2099 struct dss2_ovl_cfg *cfg = &dsscomp->ovls[i].cfg; 2100 2101 dump_printf(&log, " layer %d:\n", i); 2102 dump_printf(&log, " enabled:%s buff:%p %dx%d stride:%d\n", 2103 cfg->enabled ? "true" : "false", hwc_dev->buffers[i], 2104 cfg->width, cfg->height, cfg->stride); 2105 dump_printf(&log, " src:(%d,%d) %dx%d dst:(%d,%d) %dx%d ix:%d zorder:%d\n", 2106 cfg->crop.x, cfg->crop.y, cfg->crop.w, cfg->crop.h, 2107 cfg->win.x, cfg->win.y, cfg->win.w, cfg->win.h, 2108 cfg->ix, cfg->zorder); 2109 } 2110 2111 if (hwc_dev->blt_policy != BLTPOLICY_DISABLED) { 2112 dump_printf(&log, " bltpolicy: %s, bltmode: %s\n", 2113 hwc_dev->blt_policy == BLTPOLICY_DEFAULT ? "default" : 2114 hwc_dev->blt_policy == BLTPOLICY_ALL ? "all" : "unknown", 2115 hwc_dev->blt_mode == BLTMODE_PAINT ? "paint" : "regionize"); 2116 } 2117 dump_printf(&log, "\n"); 2118} 2119 2120static void free_png_image(omap4_hwc_device_t *hwc_dev, struct omap4_hwc_img *img) 2121{ 2122 memset(img, 0, sizeof(*img)); 2123} 2124 2125static int load_png_image(omap4_hwc_device_t *hwc_dev, char *path, struct omap4_hwc_img *img) 2126{ 2127 void *ptr = NULL; 2128 png_bytepp row_pointers = NULL; 2129 2130 FILE *fd = fopen(path, "rb"); 2131 if (!fd) { 2132 ALOGE("failed to open PNG file %s: (%d)", path, errno); 2133 return -EINVAL; 2134 } 2135 2136 const int SIZE_PNG_HEADER = 8; 2137 __u8 header[SIZE_PNG_HEADER]; 2138 fread(header, 1, SIZE_PNG_HEADER, fd); 2139 if (png_sig_cmp(header, 0, SIZE_PNG_HEADER)) { 2140 ALOGE("%s is not a PNG file", path); 2141 goto fail; 2142 } 2143 2144 png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); 2145 if (!png_ptr) 2146 goto fail_alloc; 2147 png_infop info_ptr = png_create_info_struct(png_ptr); 2148 if (!info_ptr) 2149 goto fail_alloc; 2150 2151 if (setjmp(png_jmpbuf(png_ptr))) 2152 goto fail_alloc; 2153 2154 png_init_io(png_ptr, fd); 2155 png_set_sig_bytes(png_ptr, SIZE_PNG_HEADER); 2156 png_set_user_limits(png_ptr, limits.max_width, limits.max_height); 2157 png_read_info(png_ptr, info_ptr); 2158 2159 __u8 bit_depth = png_get_bit_depth(png_ptr, info_ptr); 2160 __u32 width = png_get_image_width(png_ptr, info_ptr); 2161 __u32 height = png_get_image_height(png_ptr, info_ptr); 2162 __u8 color_type = png_get_color_type(png_ptr, info_ptr); 2163 2164 switch (color_type) { 2165 case PNG_COLOR_TYPE_PALETTE: 2166 png_set_palette_to_rgb(png_ptr); 2167 png_set_filler(png_ptr, 128, PNG_FILLER_AFTER); 2168 break; 2169 case PNG_COLOR_TYPE_GRAY: 2170 if (bit_depth < 8) { 2171 png_set_expand_gray_1_2_4_to_8(png_ptr); 2172 if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) 2173 png_set_tRNS_to_alpha(png_ptr); 2174 } else { 2175 png_set_filler(png_ptr, 128, PNG_FILLER_AFTER); 2176 } 2177 /* fall through */ 2178 case PNG_COLOR_TYPE_GRAY_ALPHA: 2179 png_set_gray_to_rgb(png_ptr); 2180 break; 2181 case PNG_COLOR_TYPE_RGB: 2182 png_set_filler(png_ptr, 128, PNG_FILLER_AFTER); 2183 /* fall through */ 2184 case PNG_COLOR_TYPE_RGB_ALPHA: 2185 png_set_bgr(png_ptr); 2186 break; 2187 default: 2188 ALOGE("unsupported PNG color: %x", color_type); 2189 goto fail_alloc; 2190 } 2191 2192 if (bit_depth == 16) 2193 png_set_strip_16(png_ptr); 2194 2195 const int bpp = 4; 2196 img->size = ALIGN(width * height * bpp, 4096); 2197 if (img->size > hwc_dev->img_mem_size) { 2198 ALOGE("image does not fit into framebuffer area (%d > %d)", img->size, hwc_dev->img_mem_size); 2199 goto fail_alloc; 2200 } 2201 img->ptr = hwc_dev->img_mem_ptr; 2202 2203 row_pointers = calloc(height, sizeof(*row_pointers)); 2204 if (!row_pointers) { 2205 ALOGE("failed to allocate row pointers"); 2206 goto fail_alloc; 2207 } 2208 __u32 i; 2209 for (i = 0; i < height; i++) 2210 row_pointers[i] = img->ptr + i * width * bpp; 2211 png_set_rows(png_ptr, info_ptr, row_pointers); 2212 png_read_update_info(png_ptr, info_ptr); 2213 img->rowbytes = png_get_rowbytes(png_ptr, info_ptr); 2214 2215 png_read_image(png_ptr, row_pointers); 2216 png_read_end(png_ptr, NULL); 2217 free(row_pointers); 2218 png_destroy_read_struct(&png_ptr, &info_ptr, NULL); 2219 fclose(fd); 2220 img->width = width; 2221 img->height = height; 2222 return 0; 2223 2224fail_alloc: 2225 free_png_image(hwc_dev, img); 2226 free(row_pointers); 2227 if (!png_ptr || !info_ptr) 2228 ALOGE("failed to allocate PNG structures"); 2229 png_destroy_read_struct(&png_ptr, &info_ptr, NULL); 2230fail: 2231 fclose(fd); 2232 return -EINVAL; 2233} 2234 2235 2236static int omap4_hwc_device_close(hw_device_t* device) 2237{ 2238 omap4_hwc_device_t *hwc_dev = (omap4_hwc_device_t *) device;; 2239 2240 if (hwc_dev) { 2241 if (hwc_dev->dsscomp_fd >= 0) 2242 close(hwc_dev->dsscomp_fd); 2243 if (hwc_dev->hdmi_fb_fd >= 0) 2244 close(hwc_dev->hdmi_fb_fd); 2245 if (hwc_dev->fb_fd >= 0) 2246 close(hwc_dev->fb_fd); 2247 if (hwc_dev->ion_fd >= 0) 2248 ion_close(hwc_dev->ion_fd); 2249 2250 /* pthread will get killed when parent process exits */ 2251 pthread_mutex_destroy(&hwc_dev->lock); 2252 pthread_mutex_destroy(&hwc_dev->vsync_lock); 2253 free(hwc_dev); 2254 } 2255 2256 return 0; 2257} 2258 2259static int omap4_hwc_open_fb_hal(IMG_framebuffer_device_public_t **fb_dev) 2260{ 2261 const struct hw_module_t *psModule; 2262 IMG_gralloc_module_public_t *psGrallocModule; 2263 int err; 2264 2265 err = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &psModule); 2266 psGrallocModule = (IMG_gralloc_module_public_t *) psModule; 2267 2268 if(err) 2269 goto err_out; 2270 2271 if (strcmp(psGrallocModule->base.common.author, "Imagination Technologies")) { 2272 err = -EINVAL; 2273 goto err_out; 2274 } 2275 2276 *fb_dev = psGrallocModule->psFrameBufferDevice; 2277 2278 return 0; 2279 2280err_out: 2281 ALOGE("Composer HAL failed to load compatible Graphics HAL"); 2282 return err; 2283} 2284 2285static void set_primary_display_transform_matrix(omap4_hwc_device_t *hwc_dev) 2286{ 2287 /* create primary display translation matrix */ 2288 hwc_dev->fb_dis.ix = 0;/*Default display*/ 2289 2290 int ret = ioctl(hwc_dev->dsscomp_fd, DSSCIOC_QUERY_DISPLAY, &hwc_dev->fb_dis); 2291 if (ret) 2292 ALOGE("failed to get display info (%d): %m", errno); 2293 2294 int lcd_w = hwc_dev->fb_dis.timings.x_res; 2295 int lcd_h = hwc_dev->fb_dis.timings.y_res; 2296 int orig_w = hwc_dev->fb_dev->base.width; 2297 int orig_h = hwc_dev->fb_dev->base.height; 2298 hwc_rect_t region = {.left = 0, .top = 0, .right = orig_w, .bottom = orig_h}; 2299 hwc_dev->primary_region = region; 2300 hwc_dev->primary_rotation = ((lcd_w > lcd_h) ^ (orig_w > orig_h)) ? 1 : 0; 2301 hwc_dev->primary_transform = ((lcd_w != orig_w)||(lcd_h != orig_h)) ? 1 : 0; 2302 2303 ALOGI("transforming FB (%dx%d) => (%dx%d) rot%d", orig_w, orig_h, lcd_w, lcd_h, hwc_dev->primary_rotation); 2304 2305 /* reorientation matrix is: 2306 m = (center-from-target-center) * (scale-to-target) * (mirror) * (rotate) * (center-to-original-center) */ 2307 2308 memcpy(hwc_dev->primary_m, m_unit, sizeof(m_unit)); 2309 m_translate(hwc_dev->primary_m, -(orig_w >> 1), -(orig_h >> 1)); 2310 m_rotate(hwc_dev->primary_m, hwc_dev->primary_rotation); 2311 if (hwc_dev->primary_rotation & 1) 2312 swap(orig_w, orig_h); 2313 m_scale(hwc_dev->primary_m, orig_w, lcd_w, orig_h, lcd_h); 2314 m_translate(hwc_dev->primary_m, lcd_w >> 1, lcd_h >> 1); 2315} 2316 2317 2318static void handle_hotplug(omap4_hwc_device_t *hwc_dev) 2319{ 2320 omap4_hwc_ext_t *ext = &hwc_dev->ext; 2321 __u8 state = ext->hdmi_state; 2322 2323 /* Ignore external HDMI logic if the primary display is HDMI */ 2324 if (hwc_dev->on_tv) { 2325 ALOGI("Primary display is HDMI - skip clone/dock logic"); 2326 2327 if (state) { 2328 __u32 xres = hwc_dev->fb_dev->base.width; 2329 __u32 yres = hwc_dev->fb_dev->base.height; 2330 if (omap4_hwc_set_best_hdmi_mode(hwc_dev, xres, yres, ext->lcd_xpy)) { 2331 ALOGE("Failed to set HDMI mode"); 2332 } 2333 set_primary_display_transform_matrix(hwc_dev); 2334 2335 ioctl(hwc_dev->fb_fd, FBIOBLANK, FB_BLANK_UNBLANK); 2336 2337 if (hwc_dev->procs && hwc_dev->procs->invalidate) { 2338 hwc_dev->procs->invalidate(hwc_dev->procs); 2339 } 2340 } else 2341 ext->last_mode = 0; 2342 2343 return; 2344 } 2345 2346 pthread_mutex_lock(&hwc_dev->lock); 2347 ext->dock.enabled = ext->mirror.enabled = 0; 2348 if (state) { 2349 /* check whether we can clone and/or dock */ 2350 char value[PROPERTY_VALUE_MAX]; 2351 property_get("persist.hwc.docking.enabled", value, "1"); 2352 ext->dock.enabled = atoi(value) > 0; 2353 property_get("persist.hwc.mirroring.enabled", value, "1"); 2354 ext->mirror.enabled = atoi(value) > 0; 2355 property_get("persist.hwc.avoid_mode_change", value, "1"); 2356 ext->avoid_mode_change = atoi(value) > 0; 2357 2358 /* get cloning transformation */ 2359 property_get("persist.hwc.docking.transform", value, "0"); 2360 ext->dock.rotation = atoi(value) & EXT_ROTATION; 2361 ext->dock.hflip = (atoi(value) & EXT_HFLIP) > 0; 2362 ext->dock.docking = 1; 2363 property_get("persist.hwc.mirroring.transform", value, hwc_dev->fb_dis.timings.y_res > hwc_dev->fb_dis.timings.x_res ? "3" : "0"); 2364 ext->mirror.rotation = atoi(value) & EXT_ROTATION; 2365 ext->mirror.hflip = (atoi(value) & EXT_HFLIP) > 0; 2366 ext->mirror.docking = 0; 2367 2368 if (ext->force_dock) { 2369 /* restrict to docking with no transform */ 2370 ext->mirror.enabled = 0; 2371 ext->dock.rotation = 0; 2372 ext->dock.hflip = 0; 2373 2374 if (!dock_image.rowbytes) { 2375 property_get("persist.hwc.dock_image", value, "/vendor/res/images/dock/dock.png"); 2376 load_png_image(hwc_dev, value, &dock_image); 2377 } 2378 } 2379 2380 /* select best mode for mirroring */ 2381 if (ext->mirror.enabled) { 2382 ext->current = ext->mirror; 2383 ext->mirror_mode = 0; 2384 if (setup_mirroring(hwc_dev) == 0) { 2385 ext->mirror_mode = ext->last_mode; 2386 ioctl(hwc_dev->hdmi_fb_fd, FBIOBLANK, FB_BLANK_UNBLANK); 2387 } else 2388 ext->mirror.enabled = 0; 2389 } 2390 /* Allocate backup buffers for FB rotation 2391 * This is required only if the FB tranform is different from that 2392 * of the external display and the FB is not in TILER2D space 2393 */ 2394 if (ext->mirror.rotation && (limits.fbmem_type != DSSCOMP_FBMEM_TILER2D)) 2395 allocate_tiler2d_buffers(hwc_dev); 2396 2397 } else { 2398 ext->last_mode = 0; 2399 if (ext->mirror.rotation && (limits.fbmem_type != DSSCOMP_FBMEM_TILER2D)) { 2400 /* free tiler 2D buffer on detach */ 2401 free_tiler2d_buffers(hwc_dev); 2402 } 2403 } 2404 ALOGI("external display changed (state=%d, mirror={%s tform=%ddeg%s}, dock={%s tform=%ddeg%s%s}, tv=%d", state, 2405 ext->mirror.enabled ? "enabled" : "disabled", 2406 ext->mirror.rotation * 90, 2407 ext->mirror.hflip ? "+hflip" : "", 2408 ext->dock.enabled ? "enabled" : "disabled", 2409 ext->dock.rotation * 90, 2410 ext->dock.hflip ? "+hflip" : "", 2411 ext->force_dock ? " forced" : "", 2412 ext->on_tv); 2413 2414 pthread_mutex_unlock(&hwc_dev->lock); 2415 2416 /* hwc_dev->procs is set right after the device is opened, but there is 2417 * still a race condition where a hotplug event might occur after the open 2418 * but before the procs are registered. */ 2419 if (hwc_dev->procs && hwc_dev->procs->invalidate) 2420 hwc_dev->procs->invalidate(hwc_dev->procs); 2421} 2422 2423static void handle_uevents(omap4_hwc_device_t *hwc_dev, const char *buff, int len) 2424{ 2425 int dock; 2426 int hdmi; 2427 int vsync; 2428 int state = 0; 2429 uint64_t timestamp = 0; 2430 const char *s = buff; 2431 2432 dock = !strcmp(s, "change@/devices/virtual/switch/dock"); 2433 hdmi = !strcmp(s, "change@/devices/virtual/switch/hdmi"); 2434 vsync = !strcmp(s, "change@/devices/platform/omapfb") || 2435 !strcmp(s, "change@/devices/virtual/switch/omapfb-vsync"); 2436 2437 if (!dock && !vsync && !hdmi) 2438 return; 2439 2440 s += strlen(s) + 1; 2441 2442 while(*s) { 2443 if (!strncmp(s, "SWITCH_STATE=", strlen("SWITCH_STATE="))) 2444 state = atoi(s + strlen("SWITCH_STATE=")); 2445 else if (!strncmp(s, "SWITCH_TIME=", strlen("SWITCH_TIME="))) 2446 timestamp = strtoull(s + strlen("SWITCH_TIME="), NULL, 0); 2447 else if (!strncmp(s, "VSYNC=", strlen("VSYNC="))) 2448 timestamp = strtoull(s + strlen("VSYNC="), NULL, 0); 2449 2450 s += strlen(s) + 1; 2451 if (s - buff >= len) 2452 break; 2453 } 2454 2455 if (vsync) { 2456 fire_vsync_event(hwc_dev, timestamp); 2457 } else { 2458 if (dock) { 2459 hwc_dev->ext.force_dock = state == 1; 2460 } else { 2461 /* If the primary display is HDMI, VSYNC is enabled, and HDMI's plug 2462 * state has just gone from 1->0, then we need to be sure to start 2463 * faking the VSYNC events. 2464 */ 2465 if (hwc_dev->on_tv) { 2466 int new_state, state_change; 2467 2468 pthread_mutex_lock(&hwc_dev->vsync_lock); 2469 2470 new_state = state == 1; 2471 state_change = (new_state != hwc_dev->ext.hdmi_state); 2472 hwc_dev->ext.hdmi_state = new_state; 2473 if (state_change && !new_state) 2474 wakeup_hdmi_thread(hwc_dev); 2475 2476 pthread_mutex_unlock(&hwc_dev->vsync_lock); 2477 } else { 2478 hwc_dev->ext.hdmi_state = state == 1; 2479 } 2480 } 2481 handle_hotplug(hwc_dev); 2482 } 2483} 2484 2485static void *omap4_hwc_hdmi_thread(void *data) 2486{ 2487 omap4_hwc_device_t *hwc_dev = data; 2488 static char uevent_desc[4096]; 2489 struct pollfd fds[2]; 2490 int invalidate = 0; 2491 int timeout; 2492 int err; 2493 2494 setpriority(PRIO_PROCESS, 0, HAL_PRIORITY_URGENT_DISPLAY); 2495 2496 uevent_init(); 2497 2498 fds[0].fd = uevent_get_fd(); 2499 fds[0].events = POLLIN; 2500 fds[1].fd = hwc_dev->wakeup_evt; 2501 fds[1].events = POLLIN; 2502 2503 timeout = hwc_dev->idle ? hwc_dev->idle : -1; 2504 2505 memset(uevent_desc, 0, sizeof(uevent_desc)); 2506 2507 do { 2508 uint64_t idle_wakeup = (uint64_t)(-1); 2509 uint64_t vsync_wakeup = (uint64_t)(-1); 2510 uint64_t now = vsync_clock_now(); 2511 uint64_t effective_wakeup; 2512 int effective_timeout; 2513 2514 if (timeout >= 0) 2515 idle_wakeup = now + (((uint64_t)timeout) * 1000000); 2516 2517 if (hwc_dev->on_tv) { 2518 pthread_mutex_lock(&hwc_dev->vsync_lock); 2519 2520 if (!hwc_dev->ext.hdmi_state && hwc_dev->vsync_enabled) { 2521 vsync_wakeup = hwc_dev->last_vsync_time_valid 2522 ? hwc_dev->last_vsync_time 2523 : now; 2524 2525 vsync_wakeup += hwc_dev->fake_vsync_period; 2526 2527 if (vsync_wakeup < now) 2528 vsync_wakeup = now; 2529 } 2530 2531 pthread_mutex_unlock(&hwc_dev->vsync_lock); 2532 } 2533 2534 effective_wakeup = idle_wakeup < vsync_wakeup 2535 ? idle_wakeup 2536 : vsync_wakeup; 2537 if (effective_wakeup == (uint64_t)(-1)) 2538 effective_timeout = -1; 2539 else if (effective_wakeup <= now) 2540 effective_timeout = 0; 2541 else 2542 effective_timeout = (int)((effective_wakeup - now + 999999) / 1000000); 2543 2544 if (effective_timeout) 2545 err = poll(fds, 2, effective_timeout); 2546 else 2547 err = 0; 2548 2549 now = vsync_clock_now(); 2550 2551 if (err == 0) { 2552 int fired = 0; 2553 2554 if (now >= vsync_wakeup) { 2555 fire_vsync_event(hwc_dev, vsync_wakeup); 2556 fired = 1; 2557 } 2558 2559 if (hwc_dev->idle && (now >= idle_wakeup)) { 2560 if (hwc_dev->procs) { 2561 pthread_mutex_lock(&hwc_dev->lock); 2562 invalidate = hwc_dev->last_int_ovls > 1 && !hwc_dev->force_sgx; 2563 if (invalidate) { 2564 hwc_dev->force_sgx = 2; 2565 } 2566 pthread_mutex_unlock(&hwc_dev->lock); 2567 2568 if (invalidate) { 2569 hwc_dev->procs->invalidate(hwc_dev->procs); 2570 timeout = -1; 2571 } 2572 } 2573 2574 fired = 1; 2575 } 2576 2577 if (fired) 2578 continue; 2579 } 2580 2581 if (err == -1) { 2582 if (errno != EINTR) 2583 ALOGE("event error: %m"); 2584 continue; 2585 } 2586 2587 if (fds[1].revents & POLLIN) { 2588 uint64_t tmp; 2589 2590 read(hwc_dev->wakeup_evt, &tmp, sizeof(tmp)); 2591 2592 if (!hwc_dev->force_sgx) 2593 timeout = hwc_dev->idle ? hwc_dev->idle : -1; 2594 } 2595 2596 if (fds[0].revents & POLLIN) { 2597 /* keep last 2 zeroes to ensure double 0 termination */ 2598 int len = uevent_next_event(uevent_desc, sizeof(uevent_desc) - 2); 2599 handle_uevents(hwc_dev, uevent_desc, len); 2600 } 2601 } while (1); 2602 2603 return NULL; 2604} 2605 2606static void omap4_hwc_registerProcs(struct hwc_composer_device_1* dev, 2607 hwc_procs_t const* procs) 2608{ 2609 omap4_hwc_device_t *hwc_dev = (omap4_hwc_device_t *) dev; 2610 2611 hwc_dev->procs = (typeof(hwc_dev->procs)) procs; 2612} 2613 2614static int omap4_hwc_query(struct hwc_composer_device_1* dev, 2615 int what, int* value) 2616{ 2617 omap4_hwc_device_t *hwc_dev = (omap4_hwc_device_t *) dev; 2618 2619 switch (what) { 2620 case HWC_BACKGROUND_LAYER_SUPPORTED: 2621 // we don't support the background layer yet 2622 value[0] = 0; 2623 break; 2624 case HWC_VSYNC_PERIOD: 2625 // vsync period in nanosecond 2626 value[0] = 1000000000.0 / hwc_dev->fb_dev->base.fps; 2627 break; 2628 default: 2629 // unsupported query 2630 return -EINVAL; 2631 } 2632 return 0; 2633} 2634 2635static int omap4_hwc_event_control(struct hwc_composer_device_1* dev, 2636 int dpy, int event, int enabled) 2637{ 2638 omap4_hwc_device_t *hwc_dev = (omap4_hwc_device_t *) dev; 2639 2640 switch (event) { 2641 case HWC_EVENT_VSYNC: 2642 { 2643 int val = !!enabled; 2644 int err; 2645 2646 /* If the primary display is HDMI, then we need to be sure to fake a 2647 * stream vsync events if vsync is enabled, but HDMI happens to be 2648 * disconnected. 2649 */ 2650 if (hwc_dev->on_tv) { 2651 pthread_mutex_lock(&hwc_dev->vsync_lock); 2652 2653 if (!val) 2654 hwc_dev->last_vsync_time_valid = 0; 2655 2656 /* If VSYNC is enabled, but HDMI is not actually plugged in, we need 2657 * to fake it. Poke the work thread to make sure it is taking care 2658 * of things. 2659 */ 2660 if (!hwc_dev->ext.hdmi_state && !hwc_dev->vsync_enabled && val) 2661 wakeup_hdmi_thread(hwc_dev); 2662 2663 hwc_dev->vsync_enabled = val; 2664 2665 err = ioctl(hwc_dev->fb_fd, OMAPFB_ENABLEVSYNC, &val); 2666 pthread_mutex_unlock(&hwc_dev->vsync_lock); 2667 } else { 2668 err = ioctl(hwc_dev->fb_fd, OMAPFB_ENABLEVSYNC, &val); 2669 } 2670 2671 if (err < 0) 2672 return -errno; 2673 2674 return 0; 2675 } 2676 default: 2677 return -EINVAL; 2678 } 2679} 2680 2681static int omap4_hwc_blank(struct hwc_composer_device_1 *dev, int dpy, int blank) 2682{ 2683 // We're using an older method of screen blanking based on 2684 // early_suspend in the kernel. No need to do anything here. 2685 return 0; 2686} 2687 2688static int omap4_hwc_device_open(const hw_module_t* module, const char* name, 2689 hw_device_t** device) 2690{ 2691 omap4_hwc_module_t *hwc_mod = (omap4_hwc_module_t *)module; 2692 omap4_hwc_device_t *hwc_dev; 2693 int err = 0; 2694 2695 if (strcmp(name, HWC_HARDWARE_COMPOSER)) { 2696 return -EINVAL; 2697 } 2698 2699 if (!hwc_mod->fb_dev) { 2700 err = omap4_hwc_open_fb_hal(&hwc_mod->fb_dev); 2701 if (err) 2702 return err; 2703 2704 if (!hwc_mod->fb_dev) { 2705 ALOGE("Framebuffer HAL not opened before HWC"); 2706 return -EFAULT; 2707 } 2708 hwc_mod->fb_dev->bBypassPost = 1; 2709 } 2710 2711 hwc_dev = (omap4_hwc_device_t *)malloc(sizeof(*hwc_dev)); 2712 if (hwc_dev == NULL) 2713 return -ENOMEM; 2714 2715 memset(hwc_dev, 0, sizeof(*hwc_dev)); 2716 2717 hwc_dev->base.common.tag = HARDWARE_DEVICE_TAG; 2718 hwc_dev->base.common.version = HWC_DEVICE_API_VERSION_1_0; 2719 hwc_dev->base.common.module = (hw_module_t *)module; 2720 hwc_dev->base.common.close = omap4_hwc_device_close; 2721 hwc_dev->base.prepare = omap4_hwc_prepare; 2722 hwc_dev->base.set = omap4_hwc_set; 2723 hwc_dev->base.eventControl = omap4_hwc_event_control; 2724 hwc_dev->base.blank = omap4_hwc_blank; 2725 hwc_dev->base.query = omap4_hwc_query; 2726 hwc_dev->base.registerProcs = omap4_hwc_registerProcs; 2727 hwc_dev->base.dump = omap4_hwc_dump; 2728 hwc_dev->fb_dev = hwc_mod->fb_dev; 2729 hwc_dev->wakeup_evt = -1; 2730 *device = &hwc_dev->base.common; 2731 2732 hwc_dev->vsync_enabled = 0; 2733 hwc_dev->last_vsync_time_valid = 0; 2734 hwc_dev->fake_vsync_period = 1000000000ull/60; 2735 2736 hwc_dev->dsscomp_fd = open("/dev/dsscomp", O_RDWR); 2737 if (hwc_dev->dsscomp_fd < 0) { 2738 ALOGE("failed to open dsscomp (%d)", errno); 2739 err = -errno; 2740 goto done; 2741 } 2742 2743 int ret = ioctl(hwc_dev->dsscomp_fd, DSSCIOC_QUERY_PLATFORM, &limits); 2744 if (ret) { 2745 ALOGE("failed to get platform limits (%d): %m", errno); 2746 err = -errno; 2747 goto done; 2748 } 2749 2750 hwc_dev->fb_fd = open("/dev/graphics/fb0", O_RDWR); 2751 if (hwc_dev->fb_fd < 0) { 2752 ALOGE("failed to open fb (%d)", errno); 2753 err = -errno; 2754 goto done; 2755 } 2756 2757 struct fb_fix_screeninfo fix; 2758 if (ioctl(hwc_dev->fb_fd, FBIOGET_FSCREENINFO, &fix)) { 2759 ALOGE("failed to get fb info (%d)", errno); 2760 err = -errno; 2761 goto done; 2762 } 2763 2764 hwc_dev->img_mem_size = fix.smem_len; 2765 hwc_dev->img_mem_ptr = mmap(NULL, fix.smem_len, PROT_WRITE, MAP_SHARED, hwc_dev->fb_fd, 0); 2766 if (hwc_dev->img_mem_ptr == MAP_FAILED) { 2767 ALOGE("failed to map fb memory"); 2768 err = -errno; 2769 goto done; 2770 } 2771 2772 /* Allocate the maximum buffers that we can receive from HWC */ 2773 hwc_dev->buffers = malloc(sizeof(buffer_handle_t) * MAX_HWC_LAYERS); 2774 if (!hwc_dev->buffers) { 2775 err = -ENOMEM; 2776 goto done; 2777 } 2778 2779 ret = ioctl(hwc_dev->dsscomp_fd, DSSCIOC_QUERY_DISPLAY, &hwc_dev->fb_dis); 2780 if (ret) { 2781 ALOGE("failed to get display info (%d): %m", errno); 2782 err = -errno; 2783 goto done; 2784 } 2785 2786 hwc_dev->ion_fd = ion_open(); 2787 if (hwc_dev->ion_fd < 0) { 2788 ALOGE("failed to open ion driver (%d)", errno); 2789 } 2790 2791 int i; 2792 for (i = 0; i < NUM_EXT_DISPLAY_BACK_BUFFERS; i++) { 2793 hwc_dev->ion_handles[i] = NULL; 2794 } 2795 2796 /* use default value in case some of requested display parameters missing */ 2797 hwc_dev->ext.lcd_xpy = 1.0; 2798 if (hwc_dev->fb_dis.timings.x_res && hwc_dev->fb_dis.height_in_mm) { 2799 hwc_dev->ext.lcd_xpy = (float) 2800 hwc_dev->fb_dis.width_in_mm / hwc_dev->fb_dis.timings.x_res / 2801 hwc_dev->fb_dis.height_in_mm * hwc_dev->fb_dis.timings.y_res; 2802 } 2803 2804 if (hwc_dev->fb_dis.channel == OMAP_DSS_CHANNEL_DIGIT) { 2805 ALOGI("Primary display is HDMI"); 2806 hwc_dev->on_tv = 1; 2807 } 2808 else { 2809 hwc_dev->hdmi_fb_fd = open("/dev/graphics/fb1", O_RDWR); 2810 if (hwc_dev->hdmi_fb_fd < 0) { 2811 ALOGE("failed to open hdmi fb (%d)", errno); 2812 err = -errno; 2813 goto done; 2814 } 2815 } 2816 set_primary_display_transform_matrix(hwc_dev); 2817 2818 if ((hwc_dev->wakeup_evt = eventfd(0, EFD_NONBLOCK)) < 0) { 2819 ALOGE("failed to eventfd (%d): %m", errno); 2820 err = -errno; 2821 goto done; 2822 } 2823 2824 if (pthread_mutex_init(&hwc_dev->lock, NULL)) { 2825 ALOGE("failed to create mutex (%d): %m", errno); 2826 err = -errno; 2827 goto done; 2828 } 2829 2830 if (pthread_mutex_init(&hwc_dev->vsync_lock, NULL)) { 2831 ALOGE("failed to create vsync mutex (%d): %m", errno); 2832 err = -errno; 2833 goto done; 2834 } 2835 2836 if (pthread_create(&hwc_dev->hdmi_thread, NULL, omap4_hwc_hdmi_thread, hwc_dev)) 2837 { 2838 ALOGE("failed to create HDMI listening thread (%d): %m", errno); 2839 err = -errno; 2840 goto done; 2841 } 2842 2843 /* get debug properties */ 2844 2845 /* see if hwc is enabled at all */ 2846 char value[PROPERTY_VALUE_MAX]; 2847 property_get("debug.hwc.rgb_order", value, "1"); 2848 hwc_dev->flags_rgb_order = atoi(value); 2849 property_get("debug.hwc.nv12_only", value, "0"); 2850 hwc_dev->flags_nv12_only = atoi(value); 2851 property_get("debug.hwc.idle", value, "250"); 2852 hwc_dev->idle = atoi(value); 2853 2854 /* get the board specific clone properties */ 2855 /* 0:0:1280:720 */ 2856 if (property_get("persist.hwc.mirroring.region", value, "") <= 0 || 2857 sscanf(value, "%d:%d:%d:%d", 2858 &hwc_dev->ext.mirror_region.left, &hwc_dev->ext.mirror_region.top, 2859 &hwc_dev->ext.mirror_region.right, &hwc_dev->ext.mirror_region.bottom) != 4 || 2860 hwc_dev->ext.mirror_region.left >= hwc_dev->ext.mirror_region.right || 2861 hwc_dev->ext.mirror_region.top >= hwc_dev->ext.mirror_region.bottom) { 2862 struct hwc_rect fb_region = { .right = hwc_dev->fb_dev->base.width, .bottom = hwc_dev->fb_dev->base.height }; 2863 hwc_dev->ext.mirror_region = fb_region; 2864 } 2865 ALOGI("clone region is set to (%d,%d) to (%d,%d)", 2866 hwc_dev->ext.mirror_region.left, hwc_dev->ext.mirror_region.top, 2867 hwc_dev->ext.mirror_region.right, hwc_dev->ext.mirror_region.bottom); 2868 2869 /* read switch state */ 2870 int sw_fd = open("/sys/class/switch/hdmi/state", O_RDONLY); 2871 if (sw_fd >= 0) { 2872 char value; 2873 if (read(sw_fd, &value, 1) == 1) 2874 hwc_dev->ext.hdmi_state = value == '1'; 2875 close(sw_fd); 2876 } 2877 sw_fd = open("/sys/class/switch/dock/state", O_RDONLY); 2878 if (sw_fd >= 0) { 2879 char value; 2880 if (read(sw_fd, &value, 1) == 1) 2881 hwc_dev->ext.force_dock = value == '1'; 2882 close(sw_fd); 2883 } 2884 handle_hotplug(hwc_dev); 2885 2886 ALOGI("omap4_hwc_device_open(rgb_order=%d nv12_only=%d)", 2887 hwc_dev->flags_rgb_order, hwc_dev->flags_nv12_only); 2888 2889 int gc2d_fd = open("/dev/gcioctl", O_RDWR); 2890 if (gc2d_fd < 0) { 2891 ALOGI("Unable to open gc-core device (%d), blits disabled", errno); 2892 hwc_dev->blt_policy = BLTPOLICY_DISABLED; 2893 } else { 2894 property_get("persist.hwc.bltmode", value, "1"); 2895 hwc_dev->blt_mode = atoi(value); 2896 property_get("persist.hwc.bltpolicy", value, "1"); 2897 hwc_dev->blt_policy = atoi(value); 2898 ALOGI("blitter present, blits mode %d, blits policy %d", hwc_dev->blt_mode, hwc_dev->blt_policy); 2899 close(gc2d_fd); 2900 2901 if (rgz_get_screengeometry(hwc_dev->fb_fd, &gscrngeom, 2902 hwc_dev->fb_dev->base.format) != 0) { 2903 err = -EINVAL; 2904 goto done; 2905 } 2906 } 2907 2908 property_get("persist.hwc.upscaled_nv12_limit", value, "2."); 2909 sscanf(value, "%f", &hwc_dev->upscaled_nv12_limit); 2910 if (hwc_dev->upscaled_nv12_limit < 0. || hwc_dev->upscaled_nv12_limit > 2048.) { 2911 ALOGW("Invalid upscaled_nv12_limit (%s), setting to 2.", value); 2912 hwc_dev->upscaled_nv12_limit = 2.; 2913 } 2914 2915done: 2916 if (err && hwc_dev) { 2917 if (hwc_dev->dsscomp_fd >= 0) 2918 close(hwc_dev->dsscomp_fd); 2919 if (hwc_dev->hdmi_fb_fd >= 0) 2920 close(hwc_dev->hdmi_fb_fd); 2921 if (hwc_dev->fb_fd >= 0) 2922 close(hwc_dev->fb_fd); 2923 if (hwc_dev->wakeup_evt >= 0) 2924 close(hwc_dev->wakeup_evt); 2925 pthread_mutex_destroy(&hwc_dev->lock); 2926 pthread_mutex_destroy(&hwc_dev->vsync_lock); 2927 free(hwc_dev->buffers); 2928 free(hwc_dev); 2929 } 2930 2931 return err; 2932} 2933 2934static struct hw_module_methods_t omap4_hwc_module_methods = { 2935 .open = omap4_hwc_device_open, 2936}; 2937 2938omap4_hwc_module_t HAL_MODULE_INFO_SYM = { 2939 .base = { 2940 .common = { 2941 .tag = HARDWARE_MODULE_TAG, 2942 .module_api_version = HWC_MODULE_API_VERSION_0_1, 2943 .hal_api_version = HARDWARE_HAL_API_VERSION, 2944 .id = HWC_HARDWARE_MODULE_ID, 2945 .name = "OMAP 44xx Hardware Composer HAL", 2946 .author = "Texas Instruments", 2947 .methods = &omap4_hwc_module_methods, 2948 }, 2949 }, 2950}; 2951