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/ioctl.h> 24 #include <linux/fb.h> 25 #include <linux/omapfb.h> 26 #include <sys/mman.h> 27 #include <sys/resource.h> 28 29 #include <cutils/properties.h> 30 #include <cutils/log.h> 31 #include <cutils/native_handle.h> 32 #define HWC_REMOVE_DEPRECATED_VERSIONS 1 33 #include <hardware/hardware.h> 34 #include <hardware/hwcomposer.h> 35 #include <EGL/egl.h> 36 #include <hardware_legacy/uevent.h> 37 #include <png.h> 38 39 #include <system/graphics.h> 40 41 #define ASPECT_RATIO_TOLERANCE 0.02f 42 43 #define min(a, b) ( { typeof(a) __a = (a), __b = (b); __a < __b ? __a : __b; } ) 44 #define max(a, b) ( { typeof(a) __a = (a), __b = (b); __a > __b ? __a : __b; } ) 45 #define swap(a, b) do { typeof(a) __a = (a); (a) = (b); (b) = __a; } while (0) 46 47 #define WIDTH(rect) ((rect).right - (rect).left) 48 #define HEIGHT(rect) ((rect).bottom - (rect).top) 49 50 #define DIV_ROUND_UP(a, b) (((a) + (b) - 1) / (b)) 51 52 #include <video/dsscomp.h> 53 54 #include "hal_public.h" 55 56 #define MAX_HW_OVERLAYS 4 57 #define NUM_NONSCALING_OVERLAYS 1 58 #define HAL_PIXEL_FORMAT_BGRX_8888 0x1FF 59 #define HAL_PIXEL_FORMAT_TI_NV12 0x100 60 #define HAL_PIXEL_FORMAT_TI_NV12_PADDED 0x101 61 #define MAX_TILER_SLOT (16 << 20) 62 63 struct ext_transform_t { 64 __u8 rotation : 3; /* 90-degree clockwise rotations */ 65 __u8 hflip : 1; /* flip l-r (after rotation) */ 66 __u8 enabled : 1; /* cloning enabled */ 67 __u8 docking : 1; /* docking vs. mirroring - used for state */ 68 }; 69 70 /* cloning support and state */ 71 struct omap4_hwc_ext { 72 /* support */ 73 struct ext_transform_t mirror; /* mirroring settings */ 74 struct ext_transform_t dock; /* docking settings */ 75 float lcd_xpy; /* pixel ratio for UI */ 76 __u8 avoid_mode_change; /* use HDMI mode used for mirroring if possible */ 77 __u8 force_dock; /* must dock */ 78 __u8 hdmi_state; /* whether HDMI is connected */ 79 80 /* state */ 81 __u8 on_tv; /* using a tv */ 82 struct ext_transform_t current; /* current settings */ 83 struct ext_transform_t last; /* last-used settings */ 84 85 /* configuration */ 86 __u32 last_xres_used; /* resolution and pixel ratio used for mode selection */ 87 __u32 last_yres_used; 88 __u32 last_mode; /* 2-s complement of last HDMI mode set, 0 if none */ 89 __u32 mirror_mode; /* 2-s complement of mode used when mirroring */ 90 float last_xpy; 91 __u16 width; /* external screen dimensions */ 92 __u16 height; 93 __u32 xres; /* external screen resolution */ 94 __u32 yres; 95 float m[2][3]; /* external transformation matrix */ 96 hwc_rect_t mirror_region; /* region of screen to mirror */ 97 }; 98 typedef struct omap4_hwc_ext omap4_hwc_ext_t; 99 100 /* used by property settings */ 101 enum { 102 EXT_ROTATION = 3, /* rotation while mirroring */ 103 EXT_HFLIP = (1 << 2), /* flip l-r on output (after rotation) */ 104 }; 105 106 /* ARGB image */ 107 struct omap4_hwc_img { 108 int width; 109 int height; 110 int rowbytes; 111 int size; 112 unsigned char *ptr; 113 } dock_image = { .rowbytes = 0 }; 114 115 struct omap4_hwc_module { 116 hwc_module_t base; 117 118 IMG_framebuffer_device_public_t *fb_dev; 119 }; 120 typedef struct omap4_hwc_module omap4_hwc_module_t; 121 122 struct omap4_hwc_device { 123 /* static data */ 124 hwc_composer_device_1_t base; 125 hwc_procs_t *procs; 126 pthread_t hdmi_thread; 127 pthread_mutex_t lock; 128 129 IMG_framebuffer_device_public_t *fb_dev; 130 struct dsscomp_display_info fb_dis; 131 int fb_fd; /* file descriptor for /dev/fb0 */ 132 int dsscomp_fd; /* file descriptor for /dev/dsscomp */ 133 int hdmi_fb_fd; /* file descriptor for /dev/fb1 */ 134 int pipe_fds[2]; /* pipe to event thread */ 135 136 int img_mem_size; /* size of fb for hdmi */ 137 void *img_mem_ptr; /* start of fb for hdmi */ 138 139 int flags_rgb_order; 140 int flags_nv12_only; 141 142 int force_sgx; 143 omap4_hwc_ext_t ext; /* external mirroring data */ 144 int idle; 145 int ovls_blending; 146 147 /* composition data */ 148 struct dsscomp_setup_dispc_data dsscomp_data; 149 buffer_handle_t *buffers; 150 int use_sgx; 151 int swap_rb; 152 unsigned int post2_layers; 153 int ext_ovls; /* # of overlays on external display for current composition */ 154 int ext_ovls_wanted; /* # of overlays that should be on external display for current composition */ 155 int last_ext_ovls; /* # of overlays on external/internal display for last composition */ 156 int last_int_ovls; 157 }; 158 typedef struct omap4_hwc_device omap4_hwc_device_t; 159 160 #define HAL_FMT(f) ((f) == HAL_PIXEL_FORMAT_TI_NV12 ? "NV12" : \ 161 (f) == HAL_PIXEL_FORMAT_YV12 ? "YV12" : \ 162 (f) == HAL_PIXEL_FORMAT_BGRX_8888 ? "xRGB32" : \ 163 (f) == HAL_PIXEL_FORMAT_RGBX_8888 ? "xBGR32" : \ 164 (f) == HAL_PIXEL_FORMAT_BGRA_8888 ? "ARGB32" : \ 165 (f) == HAL_PIXEL_FORMAT_RGBA_8888 ? "ABGR32" : \ 166 (f) == HAL_PIXEL_FORMAT_RGB_565 ? "RGB565" : "??") 167 168 #define DSS_FMT(f) ((f) == OMAP_DSS_COLOR_NV12 ? "NV12" : \ 169 (f) == OMAP_DSS_COLOR_RGB24U ? "xRGB32" : \ 170 (f) == OMAP_DSS_COLOR_ARGB32 ? "ARGB32" : \ 171 (f) == OMAP_DSS_COLOR_RGB16 ? "RGB565" : "??") 172 173 static int debug = 0; 174 175 static void dump_layer(hwc_layer_1_t const* l) 176 { 177 ALOGD("\ttype=%d, flags=%08x, handle=%p, tr=%02x, blend=%04x, {%d,%d,%d,%d}, {%d,%d,%d,%d}", 178 l->compositionType, l->flags, l->handle, l->transform, l->blending, 179 l->sourceCrop.left, 180 l->sourceCrop.top, 181 l->sourceCrop.right, 182 l->sourceCrop.bottom, 183 l->displayFrame.left, 184 l->displayFrame.top, 185 l->displayFrame.right, 186 l->displayFrame.bottom); 187 } 188 189 static void dump_dsscomp(struct dsscomp_setup_dispc_data *d) 190 { 191 unsigned i; 192 193 ALOGD("[%08x] set: %c%c%c %d ovls\n", 194 d->sync_id, 195 (d->mode & DSSCOMP_SETUP_MODE_APPLY) ? 'A' : '-', 196 (d->mode & DSSCOMP_SETUP_MODE_DISPLAY) ? 'D' : '-', 197 (d->mode & DSSCOMP_SETUP_MODE_CAPTURE) ? 'C' : '-', 198 d->num_ovls); 199 200 for (i = 0; i < d->num_mgrs; i++) { 201 struct dss2_mgr_info *mi = &d->mgrs[i]; 202 ALOGD(" (dis%d alpha=%d col=%08x ilace=%d)\n", 203 mi->ix, 204 mi->alpha_blending, mi->default_color, 205 mi->interlaced); 206 } 207 208 for (i = 0; i < d->num_ovls; i++) { 209 struct dss2_ovl_info *oi = &d->ovls[i]; 210 struct dss2_ovl_cfg *c = &oi->cfg; 211 if (c->zonly) 212 ALOGD("ovl%d(%s z%d)\n", 213 c->ix, c->enabled ? "ON" : "off", c->zorder); 214 else 215 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", 216 c->ix, c->enabled ? "ON" : "off", c->zorder, DSS_FMT(c->color_mode), 217 c->pre_mult_alpha ? " premult" : "", 218 (c->global_alpha * 100 + 128) / 255, 219 c->width, c->height, c->crop.x, c->crop.y, 220 c->crop.w, c->crop.h, 221 c->rotation, c->mirror ? "+mir" : "", 222 c->win.x, c->win.y, c->win.w, c->win.h, 223 (void *) oi->ba, (void *) oi->uv, c->stride); 224 } 225 } 226 227 struct dump_buf { 228 char *buf; 229 int buf_len; 230 int len; 231 }; 232 233 static void dump_printf(struct dump_buf *buf, const char *fmt, ...) 234 { 235 va_list ap; 236 237 va_start(ap, fmt); 238 buf->len += vsnprintf(buf->buf + buf->len, buf->buf_len - buf->len, fmt, ap); 239 va_end(ap); 240 } 241 242 static void dump_set_info(omap4_hwc_device_t *hwc_dev, hwc_display_contents_1_t* list) 243 { 244 struct dsscomp_setup_dispc_data *dsscomp = &hwc_dev->dsscomp_data; 245 char logbuf[1024]; 246 struct dump_buf log = { 247 .buf = logbuf, 248 .buf_len = sizeof(logbuf), 249 }; 250 unsigned int i; 251 252 dump_printf(&log, "set H{"); 253 for (i = 0; list && i < list->numHwLayers; i++) { 254 if (i) 255 dump_printf(&log, " "); 256 hwc_layer_1_t *layer = &list->hwLayers[i]; 257 IMG_native_handle_t *handle = (IMG_native_handle_t *)layer->handle; 258 dump_printf(&log, "%p:%s,", handle, layer->compositionType == HWC_OVERLAY ? "DSS" : "SGX"); 259 if ((layer->flags & HWC_SKIP_LAYER) || !handle) { 260 dump_printf(&log, "SKIP"); 261 continue; 262 } 263 if (layer->flags & HWC_HINT_CLEAR_FB) 264 dump_printf(&log, "CLR,"); 265 dump_printf(&log, "%d*%d(%s)", handle->iWidth, handle->iHeight, HAL_FMT(handle->iFormat)); 266 if (layer->transform) 267 dump_printf(&log, "~%d", layer->transform); 268 } 269 dump_printf(&log, "} D{"); 270 for (i = 0; i < dsscomp->num_ovls; i++) { 271 if (i) 272 dump_printf(&log, " "); 273 dump_printf(&log, "%d=", dsscomp->ovls[i].cfg.ix); 274 if (dsscomp->ovls[i].cfg.enabled) 275 dump_printf(&log, "%08x:%d*%d,%s", 276 dsscomp->ovls[i].ba, 277 dsscomp->ovls[i].cfg.width, 278 dsscomp->ovls[i].cfg.height, 279 DSS_FMT(dsscomp->ovls[i].cfg.color_mode)); 280 else 281 dump_printf(&log, "-"); 282 } 283 dump_printf(&log, "} L{"); 284 for (i = 0; i < hwc_dev->post2_layers; i++) { 285 if (i) 286 dump_printf(&log, " "); 287 dump_printf(&log, "%p", hwc_dev->buffers[i]); 288 } 289 dump_printf(&log, "}%s\n", hwc_dev->use_sgx ? " swap" : ""); 290 291 ALOGD("%s", log.buf); 292 } 293 294 static int sync_id = 0; 295 296 static int omap4_hwc_is_valid_format(int format) 297 { 298 switch(format) { 299 case HAL_PIXEL_FORMAT_RGB_565: 300 case HAL_PIXEL_FORMAT_RGBX_8888: 301 case HAL_PIXEL_FORMAT_RGBA_8888: 302 case HAL_PIXEL_FORMAT_BGRA_8888: 303 case HAL_PIXEL_FORMAT_BGRX_8888: 304 case HAL_PIXEL_FORMAT_TI_NV12: 305 case HAL_PIXEL_FORMAT_TI_NV12_PADDED: 306 return 1; 307 308 default: 309 return 0; 310 } 311 } 312 313 static int scaled(hwc_layer_1_t *layer) 314 { 315 int w = WIDTH(layer->sourceCrop); 316 int h = HEIGHT(layer->sourceCrop); 317 318 if (layer->transform & HWC_TRANSFORM_ROT_90) 319 swap(w, h); 320 321 return WIDTH(layer->displayFrame) != w || HEIGHT(layer->displayFrame) != h; 322 } 323 324 static int is_protected(hwc_layer_1_t *layer) 325 { 326 IMG_native_handle_t *handle = (IMG_native_handle_t *)layer->handle; 327 328 return (handle->usage & GRALLOC_USAGE_PROTECTED); 329 } 330 331 #define is_BLENDED(layer) ((layer)->blending != HWC_BLENDING_NONE) 332 333 static int is_RGB(IMG_native_handle_t *handle) 334 { 335 switch(handle->iFormat) 336 { 337 case HAL_PIXEL_FORMAT_BGRA_8888: 338 case HAL_PIXEL_FORMAT_BGRX_8888: 339 case HAL_PIXEL_FORMAT_RGB_565: 340 return 1; 341 default: 342 return 0; 343 } 344 } 345 346 static int is_BGR_format(int format) 347 { 348 switch (format) { 349 case HAL_PIXEL_FORMAT_RGBX_8888: 350 case HAL_PIXEL_FORMAT_RGBA_8888: 351 return 1; 352 default: 353 return 0; 354 } 355 } 356 357 static int is_BGR(IMG_native_handle_t *handle) 358 { 359 return is_BGR_format(handle->iFormat); 360 } 361 362 static int is_NV12(IMG_native_handle_t *handle) 363 { 364 switch(handle->iFormat) 365 { 366 case HAL_PIXEL_FORMAT_TI_NV12: 367 case HAL_PIXEL_FORMAT_TI_NV12_PADDED: 368 return 1; 369 default: 370 return 0; 371 } 372 } 373 374 static int dockable(hwc_layer_1_t *layer) 375 { 376 IMG_native_handle_t *handle = (IMG_native_handle_t *)layer->handle; 377 378 return (handle->usage & GRALLOC_USAGE_EXTERNAL_DISP); 379 } 380 381 static unsigned int mem1d(IMG_native_handle_t *handle) 382 { 383 if (handle == NULL || is_NV12(handle)) 384 return 0; 385 386 int bpp = handle->iFormat == HAL_PIXEL_FORMAT_RGB_565 ? 2 : 4; 387 int stride = ALIGN(handle->iWidth, HW_ALIGN) * bpp; 388 return stride * handle->iHeight; 389 } 390 391 static void 392 omap4_hwc_setup_layer_base(struct dss2_ovl_cfg *oc, int index, int format, int blended, int width, int height) 393 { 394 unsigned int bits_per_pixel; 395 396 /* YUV2RGB conversion */ 397 const struct omap_dss_cconv_coefs ctbl_bt601_5 = { 398 298, 409, 0, 298, -208, -100, 298, 0, 517, 0, 399 }; 400 401 /* convert color format */ 402 switch (format) { 403 case HAL_PIXEL_FORMAT_RGBA_8888: 404 case HAL_PIXEL_FORMAT_BGRA_8888: 405 oc->color_mode = OMAP_DSS_COLOR_ARGB32; 406 bits_per_pixel = 32; 407 if (blended) 408 break; 409 410 case HAL_PIXEL_FORMAT_RGBX_8888: 411 case HAL_PIXEL_FORMAT_BGRX_8888: 412 oc->color_mode = OMAP_DSS_COLOR_RGB24U; 413 bits_per_pixel = 32; 414 break; 415 416 case HAL_PIXEL_FORMAT_RGB_565: 417 oc->color_mode = OMAP_DSS_COLOR_RGB16; 418 bits_per_pixel = 16; 419 break; 420 421 case HAL_PIXEL_FORMAT_TI_NV12: 422 case HAL_PIXEL_FORMAT_TI_NV12_PADDED: 423 oc->color_mode = OMAP_DSS_COLOR_NV12; 424 bits_per_pixel = 8; 425 oc->cconv = ctbl_bt601_5; 426 break; 427 428 default: 429 /* Should have been filtered out */ 430 ALOGV("Unsupported pixel format"); 431 return; 432 } 433 434 oc->width = width; 435 oc->height = height; 436 oc->stride = ALIGN(width, HW_ALIGN) * bits_per_pixel / 8; 437 438 oc->enabled = 1; 439 oc->global_alpha = 255; 440 oc->zorder = index; 441 oc->ix = 0; 442 443 /* defaults for SGX framebuffer renders */ 444 oc->crop.w = oc->win.w = width; 445 oc->crop.h = oc->win.h = height; 446 447 /* for now interlacing and vc1 info is not supplied */ 448 oc->ilace = OMAP_DSS_ILACE_NONE; 449 oc->vc1.enable = 0; 450 } 451 452 static void 453 omap4_hwc_setup_layer(omap4_hwc_device_t *hwc_dev, struct dss2_ovl_info *ovl, 454 hwc_layer_1_t *layer, int index, 455 int format, int width, int height) 456 { 457 struct dss2_ovl_cfg *oc = &ovl->cfg; 458 459 //dump_layer(layer); 460 461 omap4_hwc_setup_layer_base(oc, index, format, is_BLENDED(layer), width, height); 462 463 /* convert transformation - assuming 0-set config */ 464 if (layer->transform & HWC_TRANSFORM_FLIP_H) 465 oc->mirror = 1; 466 if (layer->transform & HWC_TRANSFORM_FLIP_V) { 467 oc->rotation = 2; 468 oc->mirror = !oc->mirror; 469 } 470 if (layer->transform & HWC_TRANSFORM_ROT_90) { 471 oc->rotation += oc->mirror ? -1 : 1; 472 oc->rotation &= 3; 473 } 474 475 oc->pre_mult_alpha = layer->blending == HWC_BLENDING_PREMULT; 476 477 /* display position */ 478 oc->win.x = layer->displayFrame.left; 479 oc->win.y = layer->displayFrame.top; 480 oc->win.w = WIDTH(layer->displayFrame); 481 oc->win.h = HEIGHT(layer->displayFrame); 482 483 /* crop */ 484 oc->crop.x = layer->sourceCrop.left; 485 oc->crop.y = layer->sourceCrop.top; 486 oc->crop.w = WIDTH(layer->sourceCrop); 487 oc->crop.h = HEIGHT(layer->sourceCrop); 488 } 489 490 const float m_unit[2][3] = { { 1., 0., 0. }, { 0., 1., 0. } }; 491 492 static inline void m_translate(float m[2][3], int dx, int dy) 493 { 494 m[0][2] += dx; 495 m[1][2] += dy; 496 } 497 498 static inline void m_scale1(float m[3], int from, int to) 499 { 500 m[0] = m[0] * to / from; 501 m[1] = m[1] * to / from; 502 m[2] = m[2] * to / from; 503 } 504 505 static inline void m_scale(float m[2][3], int x_from, int x_to, int y_from, int y_to) 506 { 507 m_scale1(m[0], x_from, x_to); 508 m_scale1(m[1], y_from, y_to); 509 } 510 511 static void m_rotate(float m[2][3], int quarter_turns) 512 { 513 if (quarter_turns & 2) 514 m_scale(m, 1, -1, 1, -1); 515 if (quarter_turns & 1) { 516 int q; 517 q = m[0][0]; m[0][0] = -m[1][0]; m[1][0] = q; 518 q = m[0][1]; m[0][1] = -m[1][1]; m[1][1] = q; 519 q = m[0][2]; m[0][2] = -m[1][2]; m[1][2] = q; 520 } 521 } 522 523 static inline int m_round(float x) 524 { 525 /* int truncates towards 0 */ 526 return (int) (x < 0 ? x - 0.5 : x + 0.5); 527 } 528 529 /* 530 * assuming xpy (xratio:yratio) original pixel ratio, calculate the adjusted width 531 * and height for a screen of xres/yres and physical size of width/height. 532 * The adjusted size is the largest that fits into the screen. 533 */ 534 static void get_max_dimensions(__u32 orig_xres, __u32 orig_yres, 535 float xpy, 536 __u32 scr_xres, __u32 scr_yres, 537 __u32 scr_width, __u32 scr_height, 538 __u32 *adj_xres, __u32 *adj_yres) 539 { 540 /* assume full screen (largest size)*/ 541 *adj_xres = scr_xres; 542 *adj_yres = scr_yres; 543 544 /* assume 1:1 pixel ratios if none supplied */ 545 if (!scr_width || !scr_height) { 546 scr_width = scr_xres; 547 scr_height = scr_yres; 548 } 549 550 /* trim to keep aspect ratio */ 551 float x_factor = orig_xres * xpy * scr_height; 552 float y_factor = orig_yres * scr_width; 553 554 /* allow for tolerance so we avoid scaling if framebuffer is standard size */ 555 if (x_factor < y_factor * (1.f - ASPECT_RATIO_TOLERANCE)) 556 *adj_xres = (__u32) (x_factor * *adj_xres / y_factor + 0.5); 557 else if (x_factor * (1.f - ASPECT_RATIO_TOLERANCE) > y_factor) 558 *adj_yres = (__u32) (y_factor * *adj_yres / x_factor + 0.5); 559 } 560 561 static void set_ext_matrix(omap4_hwc_ext_t *ext, struct hwc_rect region) 562 { 563 int orig_w = WIDTH(region); 564 int orig_h = HEIGHT(region); 565 float xpy = ext->lcd_xpy; 566 567 /* reorientation matrix is: 568 m = (center-from-target-center) * (scale-to-target) * (mirror) * (rotate) * (center-to-original-center) */ 569 570 memcpy(ext->m, m_unit, sizeof(m_unit)); 571 m_translate(ext->m, -(orig_w >> 1) - region.left, -(orig_h >> 1) - region.top); 572 m_rotate(ext->m, ext->current.rotation); 573 if (ext->current.hflip) 574 m_scale(ext->m, 1, -1, 1, 1); 575 576 if (ext->current.rotation & 1) { 577 swap(orig_w, orig_h); 578 xpy = 1. / xpy; 579 } 580 581 /* get target size */ 582 __u32 adj_xres, adj_yres; 583 get_max_dimensions(orig_w, orig_h, xpy, 584 ext->xres, ext->yres, ext->width, ext->height, 585 &adj_xres, &adj_yres); 586 587 m_scale(ext->m, orig_w, adj_xres, orig_h, adj_yres); 588 m_translate(ext->m, ext->xres >> 1, ext->yres >> 1); 589 } 590 591 static int 592 crop_to_rect(struct dss2_ovl_cfg *cfg, struct hwc_rect vis_rect) 593 { 594 struct { 595 int xy[2]; 596 int wh[2]; 597 } crop, win; 598 struct { 599 int lt[2]; 600 int rb[2]; 601 } vis; 602 win.xy[0] = cfg->win.x; win.xy[1] = cfg->win.y; 603 win.wh[0] = cfg->win.w; win.wh[1] = cfg->win.h; 604 crop.xy[0] = cfg->crop.x; crop.xy[1] = cfg->crop.y; 605 crop.wh[0] = cfg->crop.w; crop.wh[1] = cfg->crop.h; 606 vis.lt[0] = vis_rect.left; vis.lt[1] = vis_rect.top; 607 vis.rb[0] = vis_rect.right; vis.rb[1] = vis_rect.bottom; 608 609 int c, swap = cfg->rotation & 1; 610 611 /* align crop window with display coordinates */ 612 if (swap) 613 crop.xy[1] -= (crop.wh[1] = -crop.wh[1]); 614 if (cfg->rotation & 2) 615 crop.xy[!swap] -= (crop.wh[!swap] = -crop.wh[!swap]); 616 if ((!cfg->mirror) ^ !(cfg->rotation & 2)) 617 crop.xy[swap] -= (crop.wh[swap] = -crop.wh[swap]); 618 619 for (c = 0; c < 2; c++) { 620 /* see if complete buffer is outside the vis or it is 621 fully cropped or scaled to 0 */ 622 if (win.wh[c] <= 0 || vis.rb[c] <= vis.lt[c] || 623 win.xy[c] + win.wh[c] <= vis.lt[c] || 624 win.xy[c] >= vis.rb[c] || 625 !crop.wh[c ^ swap]) 626 return -ENOENT; 627 628 /* crop left/top */ 629 if (win.xy[c] < vis.lt[c]) { 630 /* correction term */ 631 int a = (vis.lt[c] - win.xy[c]) * crop.wh[c ^ swap] / win.wh[c]; 632 crop.xy[c ^ swap] += a; 633 crop.wh[c ^ swap] -= a; 634 win.wh[c] -= vis.lt[c] - win.xy[c]; 635 win.xy[c] = vis.lt[c]; 636 } 637 /* crop right/bottom */ 638 if (win.xy[c] + win.wh[c] > vis.rb[c]) { 639 crop.wh[c ^ swap] = crop.wh[c ^ swap] * (vis.rb[c] - win.xy[c]) / win.wh[c]; 640 win.wh[c] = vis.rb[c] - win.xy[c]; 641 } 642 643 if (!crop.wh[c ^ swap] || !win.wh[c]) 644 return -ENOENT; 645 } 646 647 /* realign crop window to buffer coordinates */ 648 if (cfg->rotation & 2) 649 crop.xy[!swap] -= (crop.wh[!swap] = -crop.wh[!swap]); 650 if ((!cfg->mirror) ^ !(cfg->rotation & 2)) 651 crop.xy[swap] -= (crop.wh[swap] = -crop.wh[swap]); 652 if (swap) 653 crop.xy[1] -= (crop.wh[1] = -crop.wh[1]); 654 655 cfg->win.x = win.xy[0]; cfg->win.y = win.xy[1]; 656 cfg->win.w = win.wh[0]; cfg->win.h = win.wh[1]; 657 cfg->crop.x = crop.xy[0]; cfg->crop.y = crop.xy[1]; 658 cfg->crop.w = crop.wh[0]; cfg->crop.h = crop.wh[1]; 659 660 return 0; 661 } 662 663 static void 664 omap4_hwc_adjust_ext_layer(omap4_hwc_ext_t *ext, struct dss2_ovl_info *ovl) 665 { 666 struct dss2_ovl_cfg *oc = &ovl->cfg; 667 float x, y, w, h; 668 669 /* crop to clone region if mirroring */ 670 if (!ext->current.docking && 671 crop_to_rect(&ovl->cfg, ext->mirror_region) != 0) { 672 ovl->cfg.enabled = 0; 673 return; 674 } 675 676 /* display position */ 677 x = ext->m[0][0] * oc->win.x + ext->m[0][1] * oc->win.y + ext->m[0][2]; 678 y = ext->m[1][0] * oc->win.x + ext->m[1][1] * oc->win.y + ext->m[1][2]; 679 w = ext->m[0][0] * oc->win.w + ext->m[0][1] * oc->win.h; 680 h = ext->m[1][0] * oc->win.w + ext->m[1][1] * oc->win.h; 681 oc->win.x = m_round(w > 0 ? x : x + w); 682 oc->win.y = m_round(h > 0 ? y : y + h); 683 oc->win.w = m_round(w > 0 ? w : -w); 684 oc->win.h = m_round(h > 0 ? h : -h); 685 686 /* combining transformations: F^a*R^b*F^i*R^j = F^(a+b)*R^(j+b*(-1)^i), because F*R = R^(-1)*F */ 687 oc->rotation += (oc->mirror ? -1 : 1) * ext->current.rotation; 688 oc->rotation &= 3; 689 if (ext->current.hflip) 690 oc->mirror = !oc->mirror; 691 } 692 693 static struct dsscomp_dispc_limitations { 694 __u8 max_xdecim_2d; 695 __u8 max_ydecim_2d; 696 __u8 max_xdecim_1d; 697 __u8 max_ydecim_1d; 698 __u32 fclk; 699 __u8 max_downscale; 700 __u8 min_width; 701 __u16 integer_scale_ratio_limit; 702 __u16 max_width; 703 __u16 max_height; 704 } limits = { 705 .max_xdecim_1d = 16, 706 .max_xdecim_2d = 16, 707 .max_ydecim_1d = 16, 708 .max_ydecim_2d = 2, 709 .fclk = 170666666, 710 .max_downscale = 4, 711 .min_width = 2, 712 .integer_scale_ratio_limit = 2048, 713 .max_width = 2048, 714 .max_height = 2048, 715 }; 716 717 static int omap4_hwc_can_scale(__u32 src_w, __u32 src_h, __u32 dst_w, __u32 dst_h, int is_2d, 718 struct dsscomp_display_info *dis, struct dsscomp_dispc_limitations *limits, 719 __u32 pclk) 720 { 721 __u32 fclk = limits->fclk / 1000; 722 __u32 min_src_w = DIV_ROUND_UP(src_w, is_2d ? limits->max_xdecim_2d : limits->max_xdecim_1d); 723 __u32 min_src_h = DIV_ROUND_UP(src_h, is_2d ? limits->max_ydecim_2d : limits->max_ydecim_1d); 724 725 /* ERRATAs */ 726 /* cannot render 1-width layers on DSI video mode panels - we just disallow all 1-width LCD layers */ 727 if (dis->channel != OMAP_DSS_CHANNEL_DIGIT && dst_w < limits->min_width) 728 return 0; 729 730 /* NOTE: no support for checking YUV422 layers that are tricky to scale */ 731 732 /* FIXME: limit vertical downscale well below theoretical limit as we saw display artifacts */ 733 if (dst_h < src_h / 4) 734 return 0; 735 736 /* max downscale */ 737 if (dst_h * limits->max_downscale < min_src_h) 738 return 0; 739 740 /* for manual panels pclk is 0, and there are no pclk based scaling limits */ 741 if (!pclk) 742 return !(dst_w * limits->max_downscale < min_src_w); 743 744 /* :HACK: limit horizontal downscale well below theoretical limit as we saw display artifacts */ 745 if (dst_w * 4 < src_w) 746 return 0; 747 748 /* max horizontal downscale is 4, or the fclk/pixclk */ 749 if (fclk > pclk * limits->max_downscale) 750 fclk = pclk * limits->max_downscale; 751 /* for small parts, we need to use integer fclk/pixclk */ 752 if (src_w < limits->integer_scale_ratio_limit) 753 fclk = fclk / pclk * pclk; 754 if ((__u32) dst_w * fclk < min_src_w * pclk) 755 return 0; 756 757 return 1; 758 } 759 760 static int omap4_hwc_can_scale_layer(omap4_hwc_device_t *hwc_dev, hwc_layer_1_t *layer, IMG_native_handle_t *handle) 761 { 762 int src_w = WIDTH(layer->sourceCrop); 763 int src_h = HEIGHT(layer->sourceCrop); 764 int dst_w = WIDTH(layer->displayFrame); 765 int dst_h = HEIGHT(layer->displayFrame); 766 767 /* account for 90-degree rotation */ 768 if (layer->transform & HWC_TRANSFORM_ROT_90) 769 swap(src_w, src_h); 770 771 /* NOTE: layers should be able to be scaled externally since 772 framebuffer is able to be scaled on selected external resolution */ 773 return omap4_hwc_can_scale(src_w, src_h, dst_w, dst_h, is_NV12(handle), &hwc_dev->fb_dis, &limits, 774 hwc_dev->fb_dis.timings.pixel_clock); 775 } 776 777 static int omap4_hwc_is_valid_layer(omap4_hwc_device_t *hwc_dev, 778 hwc_layer_1_t *layer, 779 IMG_native_handle_t *handle) 780 { 781 /* Skip layers are handled by SF */ 782 if ((layer->flags & HWC_SKIP_LAYER) || !handle) 783 return 0; 784 785 if (!omap4_hwc_is_valid_format(handle->iFormat)) 786 return 0; 787 788 /* 1D buffers: no transform, must fit in TILER slot */ 789 if (!is_NV12(handle)) { 790 if (layer->transform) 791 return 0; 792 if (mem1d(handle) > MAX_TILER_SLOT) 793 return 0; 794 } 795 796 return omap4_hwc_can_scale_layer(hwc_dev, layer, handle); 797 } 798 799 static __u32 add_scaling_score(__u32 score, 800 __u32 xres, __u32 yres, __u32 refresh, 801 __u32 ext_xres, __u32 ext_yres, 802 __u32 mode_xres, __u32 mode_yres, __u32 mode_refresh) 803 { 804 __u32 area = xres * yres; 805 __u32 ext_area = ext_xres * ext_yres; 806 __u32 mode_area = mode_xres * mode_yres; 807 808 /* prefer to upscale (1% tolerance) [0..1] (insert after 1st bit) */ 809 int upscale = (ext_xres >= xres * 99 / 100 && ext_yres >= yres * 99 / 100); 810 score = (((score & ~1) | upscale) << 1) | (score & 1); 811 812 /* pick minimum scaling [0..16] */ 813 if (ext_area > area) 814 score = (score << 5) | (16 * area / ext_area); 815 else 816 score = (score << 5) | (16 * ext_area / area); 817 818 /* pick smallest leftover area [0..16] */ 819 score = (score << 5) | ((16 * ext_area + (mode_area >> 1)) / mode_area); 820 821 /* adjust mode refresh rate */ 822 mode_refresh += mode_refresh % 6 == 5; 823 824 /* prefer same or higher frame rate */ 825 upscale = (mode_refresh >= refresh); 826 score = (score << 1) | upscale; 827 828 /* pick closest frame rate */ 829 if (mode_refresh > refresh) 830 score = (score << 8) | (240 * refresh / mode_refresh); 831 else 832 score = (score << 8) | (240 * mode_refresh / refresh); 833 834 return score; 835 } 836 837 static int omap4_hwc_set_best_hdmi_mode(omap4_hwc_device_t *hwc_dev, __u32 xres, __u32 yres, 838 float xpy) 839 { 840 struct _qdis { 841 struct dsscomp_display_info dis; 842 struct dsscomp_videomode modedb[32]; 843 } d = { .dis = { .ix = 1 } }; 844 omap4_hwc_ext_t *ext = &hwc_dev->ext; 845 846 d.dis.modedb_len = sizeof(d.modedb) / sizeof(*d.modedb); 847 int ret = ioctl(hwc_dev->dsscomp_fd, DSSCIOC_QUERY_DISPLAY, &d); 848 if (ret) 849 return ret; 850 851 if (d.dis.timings.x_res * d.dis.timings.y_res == 0 || 852 xres * yres == 0) 853 return -EINVAL; 854 855 __u32 i, best = ~0, best_score = 0; 856 ext->width = d.dis.width_in_mm; 857 ext->height = d.dis.height_in_mm; 858 ext->xres = d.dis.timings.x_res; 859 ext->yres = d.dis.timings.y_res; 860 861 /* use VGA external resolution as default */ 862 if (!ext->xres || !ext->yres) { 863 ext->xres = 640; 864 ext->yres = 480; 865 } 866 867 __u32 ext_fb_xres, ext_fb_yres; 868 for (i = 0; i < d.dis.modedb_len; i++) { 869 __u32 score = 0; 870 __u32 mode_xres = d.modedb[i].xres; 871 __u32 mode_yres = d.modedb[i].yres; 872 __u32 ext_width = d.dis.width_in_mm; 873 __u32 ext_height = d.dis.height_in_mm; 874 875 if (d.modedb[i].flag & FB_FLAG_RATIO_4_3) { 876 ext_width = 4; 877 ext_height = 3; 878 } else if (d.modedb[i].flag & FB_FLAG_RATIO_16_9) { 879 ext_width = 16; 880 ext_height = 9; 881 } 882 883 if (!mode_xres || !mode_yres) 884 continue; 885 886 get_max_dimensions(xres, yres, xpy, mode_xres, mode_yres, 887 ext_width, ext_height, &ext_fb_xres, &ext_fb_yres); 888 889 /* we need to ensure that even TILER2D buffers can be scaled */ 890 if (!d.modedb[i].pixclock || 891 d.modedb[i].vmode || 892 !omap4_hwc_can_scale(xres, yres, ext_fb_xres, ext_fb_yres, 893 1, &d.dis, &limits, 894 1000000000 / d.modedb[i].pixclock)) 895 continue; 896 897 /* prefer CEA modes */ 898 if (d.modedb[i].flag & (FB_FLAG_RATIO_4_3 | FB_FLAG_RATIO_16_9)) 899 score = 1; 900 901 /* prefer the same mode as we use for mirroring to avoid mode change */ 902 score = (score << 1) | (i == ~ext->mirror_mode && ext->avoid_mode_change); 903 904 score = add_scaling_score(score, xres, yres, 60, ext_fb_xres, ext_fb_yres, 905 mode_xres, mode_yres, d.modedb[i].refresh ? : 1); 906 907 ALOGD("#%d: %dx%d %dHz", i, mode_xres, mode_yres, d.modedb[i].refresh); 908 if (debug) 909 ALOGD(" score=0x%x adj.res=%dx%d", score, ext_fb_xres, ext_fb_yres); 910 if (best_score < score) { 911 ext->width = ext_width; 912 ext->height = ext_height; 913 ext->xres = mode_xres; 914 ext->yres = mode_yres; 915 best = i; 916 best_score = score; 917 } 918 } 919 if (~best) { 920 struct dsscomp_setup_display_data sdis = { .ix = 1, }; 921 sdis.mode = d.dis.modedb[best]; 922 ALOGD("picking #%d", best); 923 /* only reconfigure on change */ 924 if (ext->last_mode != ~best) 925 ioctl(hwc_dev->dsscomp_fd, DSSCIOC_SETUP_DISPLAY, &sdis); 926 ext->last_mode = ~best; 927 } else { 928 __u32 ext_width = d.dis.width_in_mm; 929 __u32 ext_height = d.dis.height_in_mm; 930 __u32 ext_fb_xres, ext_fb_yres; 931 932 get_max_dimensions(xres, yres, xpy, d.dis.timings.x_res, d.dis.timings.y_res, 933 ext_width, ext_height, &ext_fb_xres, &ext_fb_yres); 934 if (!d.dis.timings.pixel_clock || 935 d.dis.mgr.interlaced || 936 !omap4_hwc_can_scale(xres, yres, ext_fb_xres, ext_fb_yres, 937 1, &d.dis, &limits, 938 d.dis.timings.pixel_clock)) { 939 ALOGW("DSS scaler cannot support HDMI cloning"); 940 return -1; 941 } 942 } 943 ext->last_xres_used = xres; 944 ext->last_yres_used = yres; 945 ext->last_xpy = xpy; 946 if (d.dis.channel == OMAP_DSS_CHANNEL_DIGIT) 947 ext->on_tv = 1; 948 return 0; 949 } 950 951 struct counts { 952 unsigned int possible_overlay_layers; 953 unsigned int composited_layers; 954 unsigned int scaled_layers; 955 unsigned int RGB; 956 unsigned int BGR; 957 unsigned int NV12; 958 unsigned int dockable; 959 unsigned int protected; 960 961 unsigned int max_hw_overlays; 962 unsigned int max_scaling_overlays; 963 unsigned int mem; 964 }; 965 966 static void gather_layer_statistics(omap4_hwc_device_t *hwc_dev, struct counts *num, hwc_display_contents_1_t *list) 967 { 968 unsigned int i; 969 970 /* Figure out how many layers we can support via DSS */ 971 for (i = 0; list && i < list->numHwLayers; i++) { 972 hwc_layer_1_t *layer = &list->hwLayers[i]; 973 IMG_native_handle_t *handle = (IMG_native_handle_t *)layer->handle; 974 975 layer->compositionType = HWC_FRAMEBUFFER; 976 977 if (omap4_hwc_is_valid_layer(hwc_dev, layer, handle)) { 978 num->possible_overlay_layers++; 979 980 /* NV12 layers can only be rendered on scaling overlays */ 981 if (scaled(layer) || is_NV12(handle)) 982 num->scaled_layers++; 983 984 if (is_BGR(handle)) 985 num->BGR++; 986 else if (is_RGB(handle)) 987 num->RGB++; 988 else if (is_NV12(handle)) 989 num->NV12++; 990 991 if (dockable(layer)) 992 num->dockable++; 993 994 if (is_protected(layer)) 995 num->protected++; 996 997 num->mem += mem1d(handle); 998 } 999 } 1000 } 1001 1002 static void decide_supported_cloning(omap4_hwc_device_t *hwc_dev, struct counts *num) 1003 { 1004 omap4_hwc_ext_t *ext = &hwc_dev->ext; 1005 int nonscaling_ovls = NUM_NONSCALING_OVERLAYS; 1006 num->max_hw_overlays = MAX_HW_OVERLAYS; 1007 1008 /* 1009 * We cannot atomically switch overlays from one display to another. First, they 1010 * have to be disabled, and the disabling has to take effect on the current display. 1011 * We keep track of the available number of overlays here. 1012 */ 1013 if (ext->dock.enabled && !(ext->mirror.enabled && !(num->dockable || ext->force_dock))) { 1014 /* some overlays may already be used by the external display, so we account for this */ 1015 1016 /* reserve just a video pipeline for HDMI if docking */ 1017 hwc_dev->ext_ovls = (num->dockable || ext->force_dock) ? 1 : 0; 1018 num->max_hw_overlays -= max(hwc_dev->ext_ovls, hwc_dev->last_ext_ovls); 1019 1020 /* use mirroring transform if we are auto-switching to docking mode while mirroring*/ 1021 if (ext->mirror.enabled) { 1022 ext->current = ext->mirror; 1023 ext->current.docking = 1; 1024 } else { 1025 ext->current = ext->dock; 1026 } 1027 } else if (ext->mirror.enabled) { 1028 /* 1029 * otherwise, manage just from half the pipelines. NOTE: there is 1030 * no danger of having used too many overlays for external display here. 1031 */ 1032 num->max_hw_overlays >>= 1; 1033 nonscaling_ovls >>= 1; 1034 hwc_dev->ext_ovls = MAX_HW_OVERLAYS - num->max_hw_overlays; 1035 ext->current = ext->mirror; 1036 } else { 1037 num->max_hw_overlays -= hwc_dev->last_ext_ovls; 1038 hwc_dev->ext_ovls = 0; 1039 ext->current.enabled = 0; 1040 } 1041 1042 /* 1043 * :TRICKY: We may not have enough overlays on the external display. We "reserve" them 1044 * here to figure out if mirroring is supported, but may not do mirroring for the first 1045 * frame while the overlays required for it are cleared. 1046 */ 1047 hwc_dev->ext_ovls_wanted = hwc_dev->ext_ovls; 1048 hwc_dev->ext_ovls = min(MAX_HW_OVERLAYS - hwc_dev->last_int_ovls, hwc_dev->ext_ovls); 1049 1050 /* if mirroring, we are limited by both internal and external overlays. However, 1051 ext_ovls is always <= MAX_HW_OVERLAYS / 2 <= max_hw_overlays */ 1052 if (hwc_dev->ext_ovls && ext->current.enabled && !ext->current.docking) 1053 num->max_hw_overlays = hwc_dev->ext_ovls; 1054 1055 num->max_scaling_overlays = num->max_hw_overlays - nonscaling_ovls; 1056 } 1057 1058 static int can_dss_render_all(omap4_hwc_device_t *hwc_dev, struct counts *num) 1059 { 1060 omap4_hwc_ext_t *ext = &hwc_dev->ext; 1061 int on_tv = ext->on_tv && ext->current.enabled; 1062 int tform = ext->current.enabled && (ext->current.rotation || ext->current.hflip); 1063 1064 return !hwc_dev->force_sgx && 1065 /* must have at least one layer if using composition bypass to get sync object */ 1066 num->possible_overlay_layers && 1067 num->possible_overlay_layers <= num->max_hw_overlays && 1068 num->possible_overlay_layers == num->composited_layers && 1069 num->scaled_layers <= num->max_scaling_overlays && 1070 num->NV12 <= num->max_scaling_overlays && 1071 /* fits into TILER slot */ 1072 num->mem <= MAX_TILER_SLOT && 1073 /* we cannot clone non-NV12 transformed layers */ 1074 (!tform || num->NV12 == num->possible_overlay_layers) && 1075 /* HDMI cannot display BGR */ 1076 (num->BGR == 0 || (num->RGB == 0 && !on_tv) || !hwc_dev->flags_rgb_order); 1077 } 1078 1079 static inline int can_dss_render_layer(omap4_hwc_device_t *hwc_dev, 1080 hwc_layer_1_t *layer) 1081 { 1082 IMG_native_handle_t *handle = (IMG_native_handle_t *)layer->handle; 1083 1084 omap4_hwc_ext_t *ext = &hwc_dev->ext; 1085 int on_tv = ext->on_tv && ext->current.enabled; 1086 int tform = ext->current.enabled && (ext->current.rotation || ext->current.hflip); 1087 1088 return omap4_hwc_is_valid_layer(hwc_dev, layer, handle) && 1089 /* cannot rotate non-NV12 layers on external display */ 1090 (!tform || is_NV12(handle)) && 1091 /* skip non-NV12 layers if also using SGX (if nv12_only flag is set) */ 1092 (!hwc_dev->flags_nv12_only || (!hwc_dev->use_sgx || is_NV12(handle))) && 1093 /* make sure RGB ordering is consistent (if rgb_order flag is set) */ 1094 (!(hwc_dev->swap_rb ? is_RGB(handle) : is_BGR(handle)) || 1095 !hwc_dev->flags_rgb_order) && 1096 /* TV can only render RGB */ 1097 !(on_tv && is_BGR(handle)); 1098 } 1099 1100 static inline int display_area(struct dss2_ovl_info *o) 1101 { 1102 return o->cfg.win.w * o->cfg.win.h; 1103 } 1104 1105 static int clone_layer(omap4_hwc_device_t *hwc_dev, int ix) { 1106 struct dsscomp_setup_dispc_data *dsscomp = &hwc_dev->dsscomp_data; 1107 omap4_hwc_ext_t *ext = &hwc_dev->ext; 1108 int ext_ovl_ix = dsscomp->num_ovls - hwc_dev->post2_layers; 1109 struct dss2_ovl_info *o = &dsscomp->ovls[dsscomp->num_ovls]; 1110 1111 if (dsscomp->num_ovls >= MAX_HW_OVERLAYS) { 1112 ALOGE("**** cannot clone layer #%d. using all %d overlays.", ix, dsscomp->num_ovls); 1113 return -EBUSY; 1114 } 1115 1116 memcpy(o, dsscomp->ovls + ix, sizeof(*o)); 1117 1118 /* reserve overlays at end for other display */ 1119 o->cfg.ix = MAX_HW_OVERLAYS - 1 - ext_ovl_ix; 1120 o->cfg.mgr_ix = 1; 1121 o->addressing = OMAP_DSS_BUFADDR_OVL_IX; 1122 o->ba = ix; 1123 1124 /* use distinct z values (to simplify z-order checking) */ 1125 o->cfg.zorder += hwc_dev->post2_layers; 1126 1127 omap4_hwc_adjust_ext_layer(&hwc_dev->ext, o); 1128 dsscomp->num_ovls++; 1129 return 0; 1130 } 1131 1132 static int clone_external_layer(omap4_hwc_device_t *hwc_dev, int ix) { 1133 struct dsscomp_setup_dispc_data *dsscomp = &hwc_dev->dsscomp_data; 1134 omap4_hwc_ext_t *ext = &hwc_dev->ext; 1135 1136 /* mirror only 1 external layer */ 1137 struct dss2_ovl_info *o = &dsscomp->ovls[ix]; 1138 1139 /* full screen video after transformation */ 1140 __u32 xres = o->cfg.crop.w, yres = o->cfg.crop.h; 1141 if ((ext->current.rotation + o->cfg.rotation) & 1) 1142 swap(xres, yres); 1143 float xpy = ext->lcd_xpy * o->cfg.win.w / o->cfg.win.h; 1144 if (o->cfg.rotation & 1) 1145 xpy = o->cfg.crop.h / xpy / o->cfg.crop.w; 1146 else 1147 xpy = o->cfg.crop.h * xpy / o->cfg.crop.w; 1148 if (ext->current.rotation & 1) 1149 xpy = 1. / xpy; 1150 1151 /* adjust hdmi mode based on resolution */ 1152 if (xres != ext->last_xres_used || 1153 yres != ext->last_yres_used || 1154 xpy < ext->last_xpy * (1.f - ASPECT_RATIO_TOLERANCE) || 1155 xpy * (1.f - ASPECT_RATIO_TOLERANCE) > ext->last_xpy) { 1156 ALOGD("set up HDMI for %d*%d\n", xres, yres); 1157 if (omap4_hwc_set_best_hdmi_mode(hwc_dev, xres, yres, xpy)) { 1158 ext->current.enabled = 0; 1159 return -ENODEV; 1160 } 1161 } 1162 1163 struct hwc_rect region = { 1164 .left = o->cfg.win.x, .top = o->cfg.win.y, 1165 .right = o->cfg.win.x + o->cfg.win.w, 1166 .bottom = o->cfg.win.y + o->cfg.win.h 1167 }; 1168 set_ext_matrix(&hwc_dev->ext, region); 1169 1170 return clone_layer(hwc_dev, ix); 1171 } 1172 1173 static int setup_mirroring(omap4_hwc_device_t *hwc_dev) 1174 { 1175 omap4_hwc_ext_t *ext = &hwc_dev->ext; 1176 1177 __u32 xres = WIDTH(ext->mirror_region); 1178 __u32 yres = HEIGHT(ext->mirror_region); 1179 if (ext->current.rotation & 1) 1180 swap(xres, yres); 1181 if (omap4_hwc_set_best_hdmi_mode(hwc_dev, xres, yres, ext->lcd_xpy)) 1182 return -ENODEV; 1183 set_ext_matrix(ext, ext->mirror_region); 1184 return 0; 1185 } 1186 1187 /* 1188 * We're using "implicit" synchronization, so make sure we aren't passing any 1189 * sync object descriptors around. 1190 */ 1191 static void check_sync_fds(size_t numDisplays, hwc_display_contents_1_t** displays) 1192 { 1193 //ALOGD("checking sync FDs"); 1194 unsigned int i, j; 1195 for (i = 0; i < numDisplays; i++) { 1196 hwc_display_contents_1_t* list = displays[i]; 1197 if (list->retireFenceFd >= 0) { 1198 ALOGW("retireFenceFd[%u] was %d", i, list->retireFenceFd); 1199 list->retireFenceFd = -1; 1200 } 1201 1202 for (j = 0; j < list->numHwLayers; j++) { 1203 hwc_layer_1_t* layer = &list->hwLayers[j]; 1204 if (layer->acquireFenceFd >= 0) { 1205 ALOGW("acquireFenceFd[%u][%u] was %d, closing", i, j, layer->acquireFenceFd); 1206 close(layer->acquireFenceFd); 1207 layer->acquireFenceFd = -1; 1208 } 1209 if (layer->releaseFenceFd >= 0) { 1210 ALOGW("releaseFenceFd[%u][%u] was %d", i, j, layer->releaseFenceFd); 1211 layer->releaseFenceFd = -1; 1212 } 1213 } 1214 } 1215 } 1216 1217 static int omap4_hwc_prepare(struct hwc_composer_device_1 *dev, size_t numDisplays, 1218 hwc_display_contents_1_t** displays) 1219 { 1220 if (!numDisplays || displays == NULL) { 1221 return 0; 1222 } 1223 1224 hwc_display_contents_1_t* list = displays[0]; // ignore displays beyond the first 1225 omap4_hwc_device_t *hwc_dev = (omap4_hwc_device_t *)dev; 1226 struct dsscomp_setup_dispc_data *dsscomp = &hwc_dev->dsscomp_data; 1227 struct counts num = { .composited_layers = list ? list->numHwLayers : 0 }; 1228 unsigned int i, ix; 1229 1230 pthread_mutex_lock(&hwc_dev->lock); 1231 memset(dsscomp, 0x0, sizeof(*dsscomp)); 1232 dsscomp->sync_id = sync_id++; 1233 1234 gather_layer_statistics(hwc_dev, &num, list); 1235 1236 decide_supported_cloning(hwc_dev, &num); 1237 1238 /* Disable the forced SGX rendering if there is only one layer */ 1239 if (hwc_dev->force_sgx && num.composited_layers <= 1) 1240 hwc_dev->force_sgx = 0; 1241 1242 /* phase 3 logic */ 1243 if (can_dss_render_all(hwc_dev, &num)) { 1244 /* All layers can be handled by the DSS -- don't use SGX for composition */ 1245 hwc_dev->use_sgx = 0; 1246 hwc_dev->swap_rb = num.BGR != 0; 1247 } else { 1248 /* Use SGX for composition plus first 3 layers that are DSS renderable */ 1249 hwc_dev->use_sgx = 1; 1250 hwc_dev->swap_rb = is_BGR_format(hwc_dev->fb_dev->base.format); 1251 } 1252 1253 /* setup pipes */ 1254 dsscomp->num_ovls = hwc_dev->use_sgx; 1255 int z = 0; 1256 int fb_z = -1; 1257 int scaled_gfx = 0; 1258 int ix_docking = -1; 1259 1260 /* set up if DSS layers */ 1261 unsigned int mem_used = 0; 1262 hwc_dev->ovls_blending = 0; 1263 for (i = 0; list && i < list->numHwLayers; i++) { 1264 hwc_layer_1_t *layer = &list->hwLayers[i]; 1265 IMG_native_handle_t *handle = (IMG_native_handle_t *)layer->handle; 1266 1267 if (dsscomp->num_ovls < num.max_hw_overlays && 1268 can_dss_render_layer(hwc_dev, layer) && 1269 (!hwc_dev->force_sgx || 1270 /* render protected and dockable layers via DSS */ 1271 is_protected(layer) || 1272 (hwc_dev->ext.current.docking && hwc_dev->ext.current.enabled && dockable(layer))) && 1273 mem_used + mem1d(handle) < MAX_TILER_SLOT && 1274 /* can't have a transparent overlay in the middle of the framebuffer stack */ 1275 !(is_BLENDED(layer) && fb_z >= 0)) { 1276 1277 /* render via DSS overlay */ 1278 mem_used += mem1d(handle); 1279 layer->compositionType = HWC_OVERLAY; 1280 1281 /* clear FB above all opaque layers if rendering via SGX */ 1282 if (hwc_dev->use_sgx && !is_BLENDED(layer)) 1283 layer->hints |= HWC_HINT_CLEAR_FB; 1284 /* see if any of the (non-backmost) overlays are doing blending */ 1285 else if (is_BLENDED(layer) && i > 0) 1286 hwc_dev->ovls_blending = 1; 1287 1288 hwc_dev->buffers[dsscomp->num_ovls] = layer->handle; 1289 1290 omap4_hwc_setup_layer(hwc_dev, 1291 &dsscomp->ovls[dsscomp->num_ovls], 1292 layer, 1293 z, 1294 handle->iFormat, 1295 handle->iWidth, 1296 handle->iHeight); 1297 1298 dsscomp->ovls[dsscomp->num_ovls].cfg.ix = dsscomp->num_ovls; 1299 dsscomp->ovls[dsscomp->num_ovls].addressing = OMAP_DSS_BUFADDR_LAYER_IX; 1300 dsscomp->ovls[dsscomp->num_ovls].ba = dsscomp->num_ovls; 1301 1302 /* ensure GFX layer is never scaled */ 1303 if (dsscomp->num_ovls == 0) { 1304 scaled_gfx = scaled(layer) || is_NV12(handle); 1305 } else if (scaled_gfx && !scaled(layer) && !is_NV12(handle)) { 1306 /* swap GFX layer with this one */ 1307 dsscomp->ovls[dsscomp->num_ovls].cfg.ix = 0; 1308 dsscomp->ovls[0].cfg.ix = dsscomp->num_ovls; 1309 scaled_gfx = 0; 1310 } 1311 1312 /* remember largest dockable layer */ 1313 if (dockable(layer) && 1314 (ix_docking < 0 || 1315 display_area(&dsscomp->ovls[dsscomp->num_ovls]) > display_area(&dsscomp->ovls[ix_docking]))) 1316 ix_docking = dsscomp->num_ovls; 1317 1318 dsscomp->num_ovls++; 1319 z++; 1320 } else if (hwc_dev->use_sgx) { 1321 if (fb_z < 0) { 1322 /* NOTE: we are not handling transparent cutout for now */ 1323 fb_z = z; 1324 z++; 1325 } else { 1326 /* move fb z-order up (by lowering dss layers) */ 1327 while (fb_z < z - 1) 1328 dsscomp->ovls[1 + fb_z++].cfg.zorder--; 1329 } 1330 } 1331 } 1332 1333 /* if scaling GFX (e.g. only 1 scaled surface) use a VID pipe */ 1334 if (scaled_gfx) 1335 dsscomp->ovls[0].cfg.ix = dsscomp->num_ovls; 1336 1337 if (hwc_dev->use_sgx) { 1338 /* assign a z-layer for fb */ 1339 if (fb_z < 0) { 1340 if (num.composited_layers) 1341 ALOGE("**** should have assigned z-layer for fb"); 1342 fb_z = z++; 1343 } 1344 1345 hwc_dev->buffers[0] = NULL; 1346 omap4_hwc_setup_layer_base(&dsscomp->ovls[0].cfg, fb_z, 1347 hwc_dev->fb_dev->base.format, 1348 1, /* FB is always premultiplied */ 1349 hwc_dev->fb_dev->base.width, 1350 hwc_dev->fb_dev->base.height); 1351 dsscomp->ovls[0].cfg.pre_mult_alpha = 1; 1352 dsscomp->ovls[0].addressing = OMAP_DSS_BUFADDR_LAYER_IX; 1353 dsscomp->ovls[0].ba = 0; 1354 } 1355 1356 /* mirror layers */ 1357 hwc_dev->post2_layers = dsscomp->num_ovls; 1358 1359 omap4_hwc_ext_t *ext = &hwc_dev->ext; 1360 if (ext->current.enabled && hwc_dev->ext_ovls) { 1361 if (ext->current.docking && ix_docking >= 0) { 1362 if (clone_external_layer(hwc_dev, ix_docking) == 0) 1363 dsscomp->ovls[dsscomp->num_ovls - 1].cfg.zorder = z++; 1364 } else if (ext->current.docking && ix_docking < 0 && ext->force_dock) { 1365 ix_docking = dsscomp->num_ovls; 1366 struct dss2_ovl_info *oi = &dsscomp->ovls[ix_docking]; 1367 omap4_hwc_setup_layer_base(&oi->cfg, 0, HAL_PIXEL_FORMAT_BGRA_8888, 1, 1368 dock_image.width, dock_image.height); 1369 oi->cfg.stride = dock_image.rowbytes; 1370 if (clone_external_layer(hwc_dev, ix_docking) == 0) { 1371 oi->addressing = OMAP_DSS_BUFADDR_FB; 1372 oi->ba = 0; 1373 z++; 1374 } 1375 } else if (!ext->current.docking) { 1376 int res = 0; 1377 1378 /* reset mode if we are coming from docking */ 1379 if (ext->last.docking) 1380 res = setup_mirroring(hwc_dev); 1381 1382 /* mirror all layers */ 1383 for (ix = 0; res == 0 && ix < hwc_dev->post2_layers; ix++) { 1384 if (clone_layer(hwc_dev, ix)) 1385 break; 1386 z++; 1387 } 1388 } 1389 } 1390 ext->last = ext->current; 1391 1392 if (z != dsscomp->num_ovls || dsscomp->num_ovls > MAX_HW_OVERLAYS) 1393 ALOGE("**** used %d z-layers for %d overlays\n", z, dsscomp->num_ovls); 1394 1395 /* verify all z-orders and overlay indices are distinct */ 1396 for (i = z = ix = 0; i < dsscomp->num_ovls; i++) { 1397 struct dss2_ovl_cfg *c = &dsscomp->ovls[i].cfg; 1398 1399 if (z & (1 << c->zorder)) 1400 ALOGE("**** used z-order #%d multiple times", c->zorder); 1401 if (ix & (1 << c->ix)) 1402 ALOGE("**** used ovl index #%d multiple times", c->ix); 1403 z |= 1 << c->zorder; 1404 ix |= 1 << c->ix; 1405 } 1406 dsscomp->mode = DSSCOMP_SETUP_DISPLAY; 1407 dsscomp->mgrs[0].ix = 0; 1408 dsscomp->mgrs[0].alpha_blending = 1; 1409 dsscomp->mgrs[0].swap_rb = hwc_dev->swap_rb; 1410 dsscomp->num_mgrs = 1; 1411 1412 if (ext->current.enabled || hwc_dev->last_ext_ovls) { 1413 dsscomp->mgrs[1] = dsscomp->mgrs[0]; 1414 dsscomp->mgrs[1].ix = 1; 1415 dsscomp->num_mgrs++; 1416 hwc_dev->ext_ovls = dsscomp->num_ovls - hwc_dev->post2_layers; 1417 } 1418 1419 if (debug) { 1420 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", 1421 dsscomp->sync_id, 1422 hwc_dev->use_sgx ? "SGX+OVL" : "all-OVL", 1423 num.composited_layers, 1424 num.possible_overlay_layers, num.scaled_layers, 1425 num.RGB, num.BGR, num.NV12, 1426 ext->on_tv ? "tv+" : "", 1427 ext->current.enabled ? ext->current.docking ? "dock+" : "mirror+" : "OFF+", 1428 ext->current.rotation * 90, 1429 ext->current.hflip ? "+hflip" : "", 1430 hwc_dev->ext_ovls, num.max_hw_overlays, hwc_dev->last_ext_ovls, hwc_dev->last_int_ovls); 1431 } 1432 1433 pthread_mutex_unlock(&hwc_dev->lock); 1434 return 0; 1435 } 1436 1437 static void omap4_hwc_reset_screen(omap4_hwc_device_t *hwc_dev) 1438 { 1439 static int first_set = 1; 1440 int ret; 1441 1442 if (first_set) { 1443 first_set = 0; 1444 struct dsscomp_setup_dispc_data d = { 1445 .num_mgrs = 1, 1446 }; 1447 /* remove bootloader image from the screen as blank/unblank does not change the composition */ 1448 ret = ioctl(hwc_dev->dsscomp_fd, DSSCIOC_SETUP_DISPC, &d); 1449 if (ret) 1450 ALOGW("failed to remove bootloader image"); 1451 1452 /* blank and unblank fd to make sure display is properly programmed on boot. 1453 * This is needed because the bootloader can not be trusted. 1454 */ 1455 ret = ioctl(hwc_dev->fb_fd, FBIOBLANK, FB_BLANK_POWERDOWN); 1456 if (ret) 1457 ALOGW("failed to blank display"); 1458 1459 ret = ioctl(hwc_dev->fb_fd, FBIOBLANK, FB_BLANK_UNBLANK); 1460 if (ret) 1461 ALOGW("failed to blank display"); 1462 } 1463 } 1464 1465 static int omap4_hwc_set(struct hwc_composer_device_1 *dev, 1466 size_t numDisplays, hwc_display_contents_1_t** displays) 1467 { 1468 if (!numDisplays || displays == NULL) { 1469 ALOGD("set: empty display list"); 1470 return 0; 1471 } 1472 hwc_display_t dpy = NULL; 1473 hwc_surface_t sur = NULL; 1474 hwc_display_contents_1_t* list = displays[0]; // ignore displays beyond the first 1475 if (list != NULL) { 1476 dpy = list->dpy; 1477 sur = list->sur; 1478 } 1479 omap4_hwc_device_t *hwc_dev = (omap4_hwc_device_t *)dev; 1480 struct dsscomp_setup_dispc_data *dsscomp = &hwc_dev->dsscomp_data; 1481 int err = 0; 1482 int invalidate; 1483 1484 pthread_mutex_lock(&hwc_dev->lock); 1485 1486 omap4_hwc_reset_screen(hwc_dev); 1487 1488 invalidate = hwc_dev->ext_ovls_wanted && !hwc_dev->ext_ovls; 1489 1490 if (debug) 1491 dump_set_info(hwc_dev, list); 1492 1493 if (dpy && sur) { 1494 // list can be NULL which means hwc is temporarily disabled. 1495 // however, if dpy and sur are null it means we're turning the 1496 // screen off. no shall not call eglSwapBuffers() in that case. 1497 1498 if (hwc_dev->use_sgx) { 1499 if (!eglSwapBuffers((EGLDisplay)dpy, (EGLSurface)sur)) { 1500 ALOGE("eglSwapBuffers error"); 1501 err = HWC_EGL_ERROR; 1502 goto err_out; 1503 } 1504 } 1505 1506 //dump_dsscomp(dsscomp); 1507 1508 // signal the event thread that a post has happened 1509 write(hwc_dev->pipe_fds[1], "s", 1); 1510 if (hwc_dev->force_sgx > 0) 1511 hwc_dev->force_sgx--; 1512 1513 err = hwc_dev->fb_dev->Post2((framebuffer_device_t *)hwc_dev->fb_dev, 1514 hwc_dev->buffers, 1515 hwc_dev->post2_layers, 1516 dsscomp, sizeof(*dsscomp)); 1517 } 1518 hwc_dev->last_ext_ovls = hwc_dev->ext_ovls; 1519 hwc_dev->last_int_ovls = hwc_dev->post2_layers; 1520 if (err) 1521 ALOGE("Post2 error"); 1522 1523 check_sync_fds(numDisplays, displays); 1524 1525 err_out: 1526 pthread_mutex_unlock(&hwc_dev->lock); 1527 1528 if (invalidate) 1529 hwc_dev->procs->invalidate(hwc_dev->procs); 1530 1531 return err; 1532 } 1533 1534 static void omap4_hwc_dump(struct hwc_composer_device_1 *dev, char *buff, int buff_len) 1535 { 1536 omap4_hwc_device_t *hwc_dev = (omap4_hwc_device_t *)dev; 1537 struct dsscomp_setup_dispc_data *dsscomp = &hwc_dev->dsscomp_data; 1538 struct dump_buf log = { 1539 .buf = buff, 1540 .buf_len = buff_len, 1541 }; 1542 int i; 1543 1544 dump_printf(&log, "omap4_hwc %d:\n", dsscomp->num_ovls); 1545 dump_printf(&log, " idle timeout: %dms\n", hwc_dev->idle); 1546 1547 for (i = 0; i < dsscomp->num_ovls; i++) { 1548 struct dss2_ovl_cfg *cfg = &dsscomp->ovls[i].cfg; 1549 1550 dump_printf(&log, " layer %d:\n", i); 1551 dump_printf(&log, " enabled: %s\n", 1552 cfg->enabled ? "true" : "false"); 1553 dump_printf(&log, " buff: %p %dx%d stride: %d\n", 1554 hwc_dev->buffers[i], cfg->width, cfg->height, cfg->stride); 1555 dump_printf(&log, " src: (%d,%d) %dx%d\n", 1556 cfg->crop.x, cfg->crop.y, cfg->crop.w, cfg->crop.h); 1557 dump_printf(&log, " dst: (%d,%d) %dx%d\n", 1558 cfg->win.x, cfg->win.y, cfg->win.w, cfg->win.h); 1559 dump_printf(&log, " ix: %d\n", cfg->ix); 1560 dump_printf(&log, " zorder: %d\n\n", cfg->zorder); 1561 } 1562 } 1563 1564 static void free_png_image(omap4_hwc_device_t *hwc_dev, struct omap4_hwc_img *img) 1565 { 1566 memset(img, 0, sizeof(*img)); 1567 } 1568 1569 static int load_png_image(omap4_hwc_device_t *hwc_dev, char *path, struct omap4_hwc_img *img) 1570 { 1571 void *ptr = NULL; 1572 png_bytepp row_pointers = NULL; 1573 1574 FILE *fd = fopen(path, "rb"); 1575 if (!fd) { 1576 ALOGE("failed to open PNG file %s: (%d)", path, errno); 1577 return -EINVAL; 1578 } 1579 1580 const int SIZE_PNG_HEADER = 8; 1581 __u8 header[SIZE_PNG_HEADER]; 1582 fread(header, 1, SIZE_PNG_HEADER, fd); 1583 if (png_sig_cmp(header, 0, SIZE_PNG_HEADER)) { 1584 ALOGE("%s is not a PNG file", path); 1585 goto fail; 1586 } 1587 1588 png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); 1589 if (!png_ptr) 1590 goto fail_alloc; 1591 png_infop info_ptr = png_create_info_struct(png_ptr); 1592 if (!info_ptr) 1593 goto fail_alloc; 1594 1595 if (setjmp(png_jmpbuf(png_ptr))) 1596 goto fail_alloc; 1597 1598 png_init_io(png_ptr, fd); 1599 png_set_sig_bytes(png_ptr, SIZE_PNG_HEADER); 1600 png_set_user_limits(png_ptr, limits.max_width, limits.max_height); 1601 png_read_info(png_ptr, info_ptr); 1602 1603 __u8 bit_depth = png_get_bit_depth(png_ptr, info_ptr); 1604 __u32 width = png_get_image_width(png_ptr, info_ptr); 1605 __u32 height = png_get_image_height(png_ptr, info_ptr); 1606 __u8 color_type = png_get_color_type(png_ptr, info_ptr); 1607 1608 switch (color_type) { 1609 case PNG_COLOR_TYPE_PALETTE: 1610 png_set_palette_to_rgb(png_ptr); 1611 png_set_filler(png_ptr, 128, PNG_FILLER_AFTER); 1612 break; 1613 case PNG_COLOR_TYPE_GRAY: 1614 if (bit_depth < 8) { 1615 png_set_expand_gray_1_2_4_to_8(png_ptr); 1616 if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) 1617 png_set_tRNS_to_alpha(png_ptr); 1618 } else { 1619 png_set_filler(png_ptr, 128, PNG_FILLER_AFTER); 1620 } 1621 /* fall through */ 1622 case PNG_COLOR_TYPE_GRAY_ALPHA: 1623 png_set_gray_to_rgb(png_ptr); 1624 break; 1625 case PNG_COLOR_TYPE_RGB: 1626 png_set_filler(png_ptr, 128, PNG_FILLER_AFTER); 1627 /* fall through */ 1628 case PNG_COLOR_TYPE_RGB_ALPHA: 1629 png_set_bgr(png_ptr); 1630 break; 1631 default: 1632 ALOGE("unsupported PNG color: %x", color_type); 1633 goto fail_alloc; 1634 } 1635 1636 if (bit_depth == 16) 1637 png_set_strip_16(png_ptr); 1638 1639 const int bpp = 4; 1640 img->size = ALIGN(width * height * bpp, 4096); 1641 if (img->size > hwc_dev->img_mem_size) { 1642 ALOGE("image does not fit into framebuffer area (%d > %d)", img->size, hwc_dev->img_mem_size); 1643 goto fail_alloc; 1644 } 1645 img->ptr = hwc_dev->img_mem_ptr; 1646 1647 row_pointers = calloc(height, sizeof(*row_pointers)); 1648 if (!row_pointers) { 1649 ALOGE("failed to allocate row pointers"); 1650 goto fail_alloc; 1651 } 1652 __u32 i; 1653 for (i = 0; i < height; i++) 1654 row_pointers[i] = img->ptr + i * width * bpp; 1655 png_set_rows(png_ptr, info_ptr, row_pointers); 1656 png_read_update_info(png_ptr, info_ptr); 1657 img->rowbytes = png_get_rowbytes(png_ptr, info_ptr); 1658 1659 png_read_image(png_ptr, row_pointers); 1660 png_read_end(png_ptr, NULL); 1661 free(row_pointers); 1662 png_destroy_read_struct(&png_ptr, &info_ptr, NULL); 1663 fclose(fd); 1664 img->width = width; 1665 img->height = height; 1666 return 0; 1667 1668 fail_alloc: 1669 free_png_image(hwc_dev, img); 1670 free(row_pointers); 1671 if (!png_ptr || !info_ptr) 1672 ALOGE("failed to allocate PNG structures"); 1673 png_destroy_read_struct(&png_ptr, &info_ptr, NULL); 1674 fail: 1675 fclose(fd); 1676 return -EINVAL; 1677 } 1678 1679 1680 static int omap4_hwc_device_close(hw_device_t* device) 1681 { 1682 omap4_hwc_device_t *hwc_dev = (omap4_hwc_device_t *) device;; 1683 1684 if (hwc_dev) { 1685 if (hwc_dev->dsscomp_fd >= 0) 1686 close(hwc_dev->dsscomp_fd); 1687 if (hwc_dev->hdmi_fb_fd >= 0) 1688 close(hwc_dev->hdmi_fb_fd); 1689 if (hwc_dev->fb_fd >= 0) 1690 close(hwc_dev->fb_fd); 1691 /* pthread will get killed when parent process exits */ 1692 pthread_mutex_destroy(&hwc_dev->lock); 1693 free(hwc_dev); 1694 } 1695 1696 return 0; 1697 } 1698 1699 static int omap4_hwc_open_fb_hal(IMG_framebuffer_device_public_t **fb_dev) 1700 { 1701 const struct hw_module_t *psModule; 1702 IMG_gralloc_module_public_t *psGrallocModule; 1703 int err; 1704 1705 err = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &psModule); 1706 psGrallocModule = (IMG_gralloc_module_public_t *) psModule; 1707 1708 if(err) 1709 goto err_out; 1710 1711 if (strcmp(psGrallocModule->base.common.author, "Imagination Technologies")) { 1712 err = -EINVAL; 1713 goto err_out; 1714 } 1715 1716 *fb_dev = psGrallocModule->psFrameBufferDevice; 1717 1718 return 0; 1719 1720 err_out: 1721 ALOGE("Composer HAL failed to load compatible Graphics HAL"); 1722 return err; 1723 } 1724 1725 static void handle_hotplug(omap4_hwc_device_t *hwc_dev) 1726 { 1727 omap4_hwc_ext_t *ext = &hwc_dev->ext; 1728 __u8 state = ext->hdmi_state; 1729 1730 pthread_mutex_lock(&hwc_dev->lock); 1731 ext->dock.enabled = ext->mirror.enabled = 0; 1732 if (state) { 1733 /* check whether we can clone and/or dock */ 1734 char value[PROPERTY_VALUE_MAX]; 1735 property_get("persist.hwc.docking.enabled", value, "1"); 1736 ext->dock.enabled = atoi(value) > 0; 1737 property_get("persist.hwc.mirroring.enabled", value, "1"); 1738 ext->mirror.enabled = atoi(value) > 0; 1739 property_get("persist.hwc.avoid_mode_change", value, "1"); 1740 ext->avoid_mode_change = atoi(value) > 0; 1741 1742 /* get cloning transformation */ 1743 property_get("persist.hwc.docking.transform", value, "0"); 1744 ext->dock.rotation = atoi(value) & EXT_ROTATION; 1745 ext->dock.hflip = (atoi(value) & EXT_HFLIP) > 0; 1746 ext->dock.docking = 1; 1747 property_get("persist.hwc.mirroring.transform", value, hwc_dev->fb_dev->base.height > hwc_dev->fb_dev->base.width ? "3" : "0"); 1748 ext->mirror.rotation = atoi(value) & EXT_ROTATION; 1749 ext->mirror.hflip = (atoi(value) & EXT_HFLIP) > 0; 1750 ext->mirror.docking = 0; 1751 1752 if (ext->force_dock) { 1753 /* restrict to docking with no transform */ 1754 ext->mirror.enabled = 0; 1755 ext->dock.rotation = 0; 1756 ext->dock.hflip = 0; 1757 1758 if (!dock_image.rowbytes) { 1759 property_get("persist.hwc.dock_image", value, "/vendor/res/images/dock/dock.png"); 1760 load_png_image(hwc_dev, value, &dock_image); 1761 } 1762 } 1763 1764 /* select best mode for mirroring */ 1765 if (ext->mirror.enabled) { 1766 ext->current = ext->mirror; 1767 ext->mirror_mode = 0; 1768 if (setup_mirroring(hwc_dev) == 0) { 1769 ext->mirror_mode = ext->last_mode; 1770 ioctl(hwc_dev->hdmi_fb_fd, FBIOBLANK, FB_BLANK_UNBLANK); 1771 } else 1772 ext->mirror.enabled = 0; 1773 } 1774 } else { 1775 ext->last_mode = 0; 1776 } 1777 ALOGI("external display changed (state=%d, mirror={%s tform=%ddeg%s}, dock={%s tform=%ddeg%s%s}, tv=%d", state, 1778 ext->mirror.enabled ? "enabled" : "disabled", 1779 ext->mirror.rotation * 90, 1780 ext->mirror.hflip ? "+hflip" : "", 1781 ext->dock.enabled ? "enabled" : "disabled", 1782 ext->dock.rotation * 90, 1783 ext->dock.hflip ? "+hflip" : "", 1784 ext->force_dock ? " forced" : "", 1785 ext->on_tv); 1786 1787 pthread_mutex_unlock(&hwc_dev->lock); 1788 1789 /* hwc_dev->procs is set right after the device is opened, but there is 1790 * still a race condition where a hotplug event might occur after the open 1791 * but before the procs are registered. */ 1792 if (hwc_dev->procs) 1793 hwc_dev->procs->invalidate(hwc_dev->procs); 1794 } 1795 1796 static void handle_uevents(omap4_hwc_device_t *hwc_dev, const char *buff, int len) 1797 { 1798 int dock; 1799 int hdmi; 1800 int vsync; 1801 int state = 0; 1802 uint64_t timestamp = 0; 1803 const char *s = buff; 1804 1805 dock = !strcmp(s, "change@/devices/virtual/switch/dock"); 1806 hdmi = !strcmp(s, "change@/devices/virtual/switch/hdmi"); 1807 vsync = !strcmp(s, "change@/devices/platform/omapfb") || 1808 !strcmp(s, "change@/devices/virtual/switch/omapfb-vsync"); 1809 1810 if (!dock && !vsync && !hdmi) 1811 return; 1812 1813 s += strlen(s) + 1; 1814 1815 while(*s) { 1816 if (!strncmp(s, "SWITCH_STATE=", strlen("SWITCH_STATE="))) 1817 state = atoi(s + strlen("SWITCH_STATE=")); 1818 else if (!strncmp(s, "SWITCH_TIME=", strlen("SWITCH_TIME="))) 1819 timestamp = strtoull(s + strlen("SWITCH_TIME="), NULL, 0); 1820 else if (!strncmp(s, "VSYNC=", strlen("VSYNC="))) 1821 timestamp = strtoull(s + strlen("VSYNC="), NULL, 0); 1822 1823 s += strlen(s) + 1; 1824 if (s - buff >= len) 1825 break; 1826 } 1827 1828 if (vsync) { 1829 if (hwc_dev->procs) 1830 hwc_dev->procs->vsync(hwc_dev->procs, 0, timestamp); 1831 } else { 1832 if (dock) 1833 hwc_dev->ext.force_dock = state == 1; 1834 else 1835 hwc_dev->ext.hdmi_state = state == 1; 1836 handle_hotplug(hwc_dev); 1837 } 1838 } 1839 1840 static void *omap4_hwc_hdmi_thread(void *data) 1841 { 1842 omap4_hwc_device_t *hwc_dev = data; 1843 static char uevent_desc[4096]; 1844 struct pollfd fds[2]; 1845 int invalidate = 0; 1846 int timeout; 1847 int err; 1848 1849 setpriority(PRIO_PROCESS, 0, HAL_PRIORITY_URGENT_DISPLAY); 1850 1851 uevent_init(); 1852 1853 fds[0].fd = uevent_get_fd(); 1854 fds[0].events = POLLIN; 1855 fds[1].fd = hwc_dev->pipe_fds[0]; 1856 fds[1].events = POLLIN; 1857 1858 timeout = hwc_dev->idle ? hwc_dev->idle : -1; 1859 1860 memset(uevent_desc, 0, sizeof(uevent_desc)); 1861 1862 do { 1863 err = poll(fds, hwc_dev->idle ? 2 : 1, timeout); 1864 1865 if (err == 0) { 1866 if (hwc_dev->idle) { 1867 if (hwc_dev->procs) { 1868 pthread_mutex_lock(&hwc_dev->lock); 1869 invalidate = !hwc_dev->force_sgx && hwc_dev->ovls_blending; 1870 if (invalidate) { 1871 hwc_dev->force_sgx = 2; 1872 } 1873 pthread_mutex_unlock(&hwc_dev->lock); 1874 1875 if (invalidate) { 1876 hwc_dev->procs->invalidate(hwc_dev->procs); 1877 timeout = -1; 1878 } 1879 } 1880 1881 continue; 1882 } 1883 } 1884 1885 if (err == -1) { 1886 if (errno != EINTR) 1887 ALOGE("event error: %m"); 1888 continue; 1889 } 1890 1891 if (hwc_dev->idle && fds[1].revents & POLLIN) { 1892 char c; 1893 read(hwc_dev->pipe_fds[0], &c, 1); 1894 if (!hwc_dev->force_sgx) 1895 timeout = hwc_dev->idle ? hwc_dev->idle : -1; 1896 } 1897 1898 if (fds[0].revents & POLLIN) { 1899 /* keep last 2 zeroes to ensure double 0 termination */ 1900 int len = uevent_next_event(uevent_desc, sizeof(uevent_desc) - 2); 1901 handle_uevents(hwc_dev, uevent_desc, len); 1902 } 1903 } while (1); 1904 1905 return NULL; 1906 } 1907 1908 static void omap4_hwc_registerProcs(struct hwc_composer_device_1* dev, 1909 hwc_procs_t const* procs) 1910 { 1911 omap4_hwc_device_t *hwc_dev = (omap4_hwc_device_t *) dev; 1912 1913 hwc_dev->procs = (typeof(hwc_dev->procs)) procs; 1914 } 1915 1916 static int omap4_hwc_query(struct hwc_composer_device_1* dev, 1917 int what, int* value) 1918 { 1919 omap4_hwc_device_t *hwc_dev = (omap4_hwc_device_t *) dev; 1920 1921 switch (what) { 1922 case HWC_BACKGROUND_LAYER_SUPPORTED: 1923 // we don't support the background layer yet 1924 value[0] = 0; 1925 break; 1926 case HWC_VSYNC_PERIOD: 1927 // vsync period in nanosecond 1928 value[0] = 1000000000.0 / hwc_dev->fb_dev->base.fps; 1929 break; 1930 default: 1931 // unsupported query 1932 return -EINVAL; 1933 } 1934 return 0; 1935 } 1936 1937 static int omap4_hwc_event_control(struct hwc_composer_device_1* dev, 1938 int dpy, int event, int enabled) 1939 { 1940 omap4_hwc_device_t *hwc_dev = (omap4_hwc_device_t *) dev; 1941 1942 switch (event) { 1943 case HWC_EVENT_VSYNC: 1944 { 1945 int val = !!enabled; 1946 int err; 1947 1948 err = ioctl(hwc_dev->fb_fd, OMAPFB_ENABLEVSYNC, &val); 1949 if (err < 0) 1950 return -errno; 1951 1952 return 0; 1953 } 1954 default: 1955 return -EINVAL; 1956 } 1957 } 1958 1959 static int omap4_hwc_blank(struct hwc_composer_device_1 *dev, int dpy, int blank) 1960 { 1961 // We're using an older method of screen blanking based on 1962 // early_suspend in the kernel. No need to do anything here. 1963 return 0; 1964 } 1965 1966 static int omap4_hwc_device_open(const hw_module_t* module, const char* name, 1967 hw_device_t** device) 1968 { 1969 omap4_hwc_module_t *hwc_mod = (omap4_hwc_module_t *)module; 1970 omap4_hwc_device_t *hwc_dev; 1971 int err = 0; 1972 1973 if (strcmp(name, HWC_HARDWARE_COMPOSER)) { 1974 return -EINVAL; 1975 } 1976 1977 if (!hwc_mod->fb_dev) { 1978 err = omap4_hwc_open_fb_hal(&hwc_mod->fb_dev); 1979 if (err) 1980 return err; 1981 1982 if (!hwc_mod->fb_dev) { 1983 ALOGE("Framebuffer HAL not opened before HWC"); 1984 return -EFAULT; 1985 } 1986 hwc_mod->fb_dev->bBypassPost = 1; 1987 } 1988 1989 hwc_dev = (omap4_hwc_device_t *)malloc(sizeof(*hwc_dev)); 1990 if (hwc_dev == NULL) 1991 return -ENOMEM; 1992 1993 memset(hwc_dev, 0, sizeof(*hwc_dev)); 1994 1995 hwc_dev->base.common.tag = HARDWARE_DEVICE_TAG; 1996 hwc_dev->base.common.version = HWC_DEVICE_API_VERSION_1_0; 1997 hwc_dev->base.common.module = (hw_module_t *)module; 1998 hwc_dev->base.common.close = omap4_hwc_device_close; 1999 hwc_dev->base.prepare = omap4_hwc_prepare; 2000 hwc_dev->base.set = omap4_hwc_set; 2001 hwc_dev->base.eventControl = omap4_hwc_event_control; 2002 hwc_dev->base.blank = omap4_hwc_blank; 2003 hwc_dev->base.query = omap4_hwc_query; 2004 hwc_dev->base.registerProcs = omap4_hwc_registerProcs; 2005 hwc_dev->base.dump = omap4_hwc_dump; 2006 hwc_dev->fb_dev = hwc_mod->fb_dev; 2007 *device = &hwc_dev->base.common; 2008 2009 hwc_dev->dsscomp_fd = open("/dev/dsscomp", O_RDWR); 2010 if (hwc_dev->dsscomp_fd < 0) { 2011 ALOGE("failed to open dsscomp (%d)", errno); 2012 err = -errno; 2013 goto done; 2014 } 2015 2016 hwc_dev->hdmi_fb_fd = open("/dev/graphics/fb1", O_RDWR); 2017 if (hwc_dev->hdmi_fb_fd < 0) { 2018 ALOGE("failed to open hdmi fb (%d)", errno); 2019 err = -errno; 2020 goto done; 2021 } 2022 2023 hwc_dev->fb_fd = open("/dev/graphics/fb0", O_RDWR); 2024 if (hwc_dev->fb_fd < 0) { 2025 ALOGE("failed to open fb (%d)", errno); 2026 err = -errno; 2027 goto done; 2028 } 2029 2030 struct fb_fix_screeninfo fix; 2031 if (ioctl(hwc_dev->fb_fd, FBIOGET_FSCREENINFO, &fix)) { 2032 ALOGE("failed to get fb info (%d)", errno); 2033 err = -errno; 2034 goto done; 2035 } 2036 2037 hwc_dev->img_mem_size = fix.smem_len; 2038 hwc_dev->img_mem_ptr = mmap(NULL, fix.smem_len, PROT_WRITE, MAP_SHARED, hwc_dev->fb_fd, 0); 2039 if (hwc_dev->img_mem_ptr == MAP_FAILED) { 2040 ALOGE("failed to map fb memory"); 2041 err = -errno; 2042 goto done; 2043 } 2044 2045 hwc_dev->buffers = malloc(sizeof(buffer_handle_t) * MAX_HW_OVERLAYS); 2046 if (!hwc_dev->buffers) { 2047 err = -ENOMEM; 2048 goto done; 2049 } 2050 2051 int ret = ioctl(hwc_dev->dsscomp_fd, DSSCIOC_QUERY_DISPLAY, &hwc_dev->fb_dis); 2052 if (ret) { 2053 ALOGE("failed to get display info (%d): %m", errno); 2054 err = -errno; 2055 goto done; 2056 } 2057 2058 if (hwc_dev->fb_dis.timings.x_res && hwc_dev->fb_dis.height_in_mm) { 2059 hwc_dev->ext.lcd_xpy = (float) 2060 hwc_dev->fb_dis.width_in_mm / hwc_dev->fb_dis.timings.x_res / 2061 hwc_dev->fb_dis.height_in_mm * hwc_dev->fb_dis.timings.y_res; 2062 } else { 2063 ALOGE("x resolution or the height is not populated setting lcd_xpy to 1.0\n"); 2064 hwc_dev->ext.lcd_xpy = 1.0; 2065 } 2066 2067 if (pipe(hwc_dev->pipe_fds) == -1) { 2068 ALOGE("failed to event pipe (%d): %m", errno); 2069 err = -errno; 2070 goto done; 2071 } 2072 2073 if (pthread_mutex_init(&hwc_dev->lock, NULL)) { 2074 ALOGE("failed to create mutex (%d): %m", errno); 2075 err = -errno; 2076 goto done; 2077 } 2078 if (pthread_create(&hwc_dev->hdmi_thread, NULL, omap4_hwc_hdmi_thread, hwc_dev)) 2079 { 2080 ALOGE("failed to create HDMI listening thread (%d): %m", errno); 2081 err = -errno; 2082 goto done; 2083 } 2084 2085 /* get debug properties */ 2086 2087 /* see if hwc is enabled at all */ 2088 char value[PROPERTY_VALUE_MAX]; 2089 property_get("debug.hwc.rgb_order", value, "1"); 2090 hwc_dev->flags_rgb_order = atoi(value); 2091 property_get("debug.hwc.nv12_only", value, "0"); 2092 hwc_dev->flags_nv12_only = atoi(value); 2093 property_get("debug.hwc.idle", value, "250"); 2094 hwc_dev->idle = atoi(value); 2095 2096 /* get the board specific clone properties */ 2097 /* 0:0:1280:720 */ 2098 if (property_get("persist.hwc.mirroring.region", value, "") <= 0 || 2099 sscanf(value, "%d:%d:%d:%d", 2100 &hwc_dev->ext.mirror_region.left, &hwc_dev->ext.mirror_region.top, 2101 &hwc_dev->ext.mirror_region.right, &hwc_dev->ext.mirror_region.bottom) != 4 || 2102 hwc_dev->ext.mirror_region.left >= hwc_dev->ext.mirror_region.right || 2103 hwc_dev->ext.mirror_region.top >= hwc_dev->ext.mirror_region.bottom) { 2104 struct hwc_rect fb_region = { .right = hwc_dev->fb_dev->base.width, .bottom = hwc_dev->fb_dev->base.height }; 2105 hwc_dev->ext.mirror_region = fb_region; 2106 } 2107 ALOGI("clone region is set to (%d,%d) to (%d,%d)", 2108 hwc_dev->ext.mirror_region.left, hwc_dev->ext.mirror_region.top, 2109 hwc_dev->ext.mirror_region.right, hwc_dev->ext.mirror_region.bottom); 2110 2111 /* read switch state */ 2112 int sw_fd = open("/sys/class/switch/hdmi/state", O_RDONLY); 2113 if (sw_fd >= 0) { 2114 char value; 2115 if (read(sw_fd, &value, 1) == 1) 2116 hwc_dev->ext.hdmi_state = value == '1'; 2117 close(sw_fd); 2118 } 2119 sw_fd = open("/sys/class/switch/dock/state", O_RDONLY); 2120 if (sw_fd >= 0) { 2121 char value; 2122 if (read(sw_fd, &value, 1) == 1) 2123 hwc_dev->ext.force_dock = value == '1'; 2124 close(sw_fd); 2125 } 2126 handle_hotplug(hwc_dev); 2127 2128 ALOGI("omap4_hwc_device_open(rgb_order=%d nv12_only=%d)", 2129 hwc_dev->flags_rgb_order, hwc_dev->flags_nv12_only); 2130 2131 done: 2132 if (err && hwc_dev) { 2133 if (hwc_dev->dsscomp_fd >= 0) 2134 close(hwc_dev->dsscomp_fd); 2135 if (hwc_dev->hdmi_fb_fd >= 0) 2136 close(hwc_dev->hdmi_fb_fd); 2137 if (hwc_dev->fb_fd >= 0) 2138 close(hwc_dev->fb_fd); 2139 pthread_mutex_destroy(&hwc_dev->lock); 2140 free(hwc_dev->buffers); 2141 free(hwc_dev); 2142 } 2143 2144 return err; 2145 } 2146 2147 static struct hw_module_methods_t omap4_hwc_module_methods = { 2148 .open = omap4_hwc_device_open, 2149 }; 2150 2151 omap4_hwc_module_t HAL_MODULE_INFO_SYM = { 2152 .base = { 2153 .common = { 2154 .tag = HARDWARE_MODULE_TAG, 2155 .module_api_version = HWC_MODULE_API_VERSION_0_1, 2156 .hal_api_version = HARDWARE_HAL_API_VERSION, 2157 .id = HWC_HARDWARE_MODULE_ID, 2158 .name = "OMAP 44xx Hardware Composer HAL", 2159 .author = "Texas Instruments", 2160 .methods = &omap4_hwc_module_methods, 2161 }, 2162 }, 2163 }; 2164