hwc.cpp revision 23cd5951dcf20c282d91cd8e897f4e88c1cffcb2
1/* 2 * Copyright (C) 2012 The Android Open Source Project 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#include <errno.h> 17#include <fcntl.h> 18#include <poll.h> 19#include <pthread.h> 20#include <stdio.h> 21#include <stdlib.h> 22 23#include <sys/ioctl.h> 24#include <sys/mman.h> 25#include <sys/time.h> 26#include <sys/resource.h> 27 28#include <s3c-fb.h> 29 30#include <EGL/egl.h> 31 32#define HWC_REMOVE_DEPRECATED_VERSIONS 1 33 34#include <cutils/log.h> 35#include <hardware/gralloc.h> 36#include <hardware/hardware.h> 37#include <hardware/hwcomposer.h> 38#include <hardware_legacy/uevent.h> 39#include <utils/String8.h> 40#include <utils/Vector.h> 41 42#include <sync/sync.h> 43 44#include "ion.h" 45#include "gralloc_priv.h" 46#include "exynos_gscaler.h" 47#include "exynos_format.h" 48#include "exynos_v4l2.h" 49#include "s5p_tvout_v4l2.h" 50 51struct hwc_callback_entry { 52 void (*callback)(void *, private_handle_t *); 53 void *data; 54}; 55typedef android::Vector<struct hwc_callback_entry> hwc_callback_queue_t; 56 57const int MEMIF_CONFIGURATION[] = { 0, 1, 1, 1, 0 }; 58const size_t NUM_HW_WINDOWS = sizeof(MEMIF_CONFIGURATION) / 59 sizeof(MEMIF_CONFIGURATION[0]); 60const size_t NO_FB_NEEDED = NUM_HW_WINDOWS + 1; 61const size_t MAX_PIXELS_PER_MEMIF = 2560 * 1600; 62const size_t MAX_PIXELS = MAX_PIXELS_PER_MEMIF * 2; 63const size_t GSC_W_ALIGNMENT = 16; 64const size_t GSC_H_ALIGNMENT = 16; 65const int AVAILABLE_GSC_UNITS[] = { 0, 3 }; 66const size_t NUM_GSC_UNITS = sizeof(AVAILABLE_GSC_UNITS) / 67 sizeof(AVAILABLE_GSC_UNITS[0]); 68 69struct exynos5_hwc_composer_device_1_t; 70 71struct exynos5_gsc_map_t { 72 enum { 73 GSC_NONE = 0, 74 GSC_M2M, 75 // TODO: GSC_LOCAL_PATH 76 } mode; 77 int idx; 78}; 79 80struct exynos5_hwc_post_data_t { 81 exynos5_hwc_composer_device_1_t *pdev; 82 int overlay_map[NUM_HW_WINDOWS]; 83 exynos5_gsc_map_t gsc_map[NUM_HW_WINDOWS]; 84 hwc_layer_1_t overlays[NUM_HW_WINDOWS]; 85 int num_overlays; 86 size_t fb_window; 87 int fence; 88 pthread_mutex_t completion_lock; 89 pthread_cond_t completion; 90}; 91 92const size_t NUM_GSC_DST_BUFS = 2; 93struct exynos5_gsc_data_t { 94 void *gsc; 95 exynos_gsc_img src_cfg; 96 exynos_gsc_img dst_cfg; 97 buffer_handle_t dst_buf[NUM_GSC_DST_BUFS]; 98 size_t current_buf; 99}; 100 101struct exynos5_hwc_composer_device_1_t { 102 hwc_composer_device_1_t base; 103 104 int fd; 105 int vsync_fd; 106 exynos5_hwc_post_data_t bufs; 107 108 const private_module_t *gralloc_module; 109 alloc_device_t *alloc_device; 110 const hwc_procs_t *procs; 111 pthread_t vsync_thread; 112 113 int hdmi_mixer0; 114 int hdmi_layer0; 115 int hdmi_layer1; 116 bool hdmi_hpd; 117 bool hdmi_enabled; 118 bool hdmi_blanked; 119 void *hdmi_gsc; 120 int hdmi_w; 121 int hdmi_h; 122 exynos_gsc_img hdmi_src; 123 exynos_gsc_img hdmi_dst; 124 125 exynos5_gsc_data_t gsc[NUM_GSC_UNITS]; 126 127 struct s3c_fb_win_config last_config[NUM_HW_WINDOWS]; 128 const void *last_handles[NUM_HW_WINDOWS]; 129 exynos5_gsc_map_t last_gsc_map[NUM_HW_WINDOWS]; 130}; 131 132static void dump_handle(private_handle_t *h) 133{ 134 ALOGV("\t\tformat = %d, width = %u, height = %u, stride = %u, vstride = %u", 135 h->format, h->width, h->height, h->stride, h->vstride); 136} 137 138static void dump_layer(hwc_layer_1_t const *l) 139{ 140 ALOGV("\ttype=%d, flags=%08x, handle=%p, tr=%02x, blend=%04x, " 141 "{%d,%d,%d,%d}, {%d,%d,%d,%d}", 142 l->compositionType, l->flags, l->handle, l->transform, 143 l->blending, 144 l->sourceCrop.left, 145 l->sourceCrop.top, 146 l->sourceCrop.right, 147 l->sourceCrop.bottom, 148 l->displayFrame.left, 149 l->displayFrame.top, 150 l->displayFrame.right, 151 l->displayFrame.bottom); 152 153 if(l->handle && !(l->flags & HWC_SKIP_LAYER)) 154 dump_handle(private_handle_t::dynamicCast(l->handle)); 155} 156 157static void dump_config(s3c_fb_win_config &c) 158{ 159 ALOGV("\tstate = %u", c.state); 160 if (c.state == c.S3C_FB_WIN_STATE_BUFFER) { 161 ALOGV("\t\tfd = %d, offset = %u, stride = %u, " 162 "x = %d, y = %d, w = %u, h = %u, " 163 "format = %u, blending = %u", 164 c.fd, c.offset, c.stride, 165 c.x, c.y, c.w, c.h, 166 c.format, c.blending); 167 } 168 else if (c.state == c.S3C_FB_WIN_STATE_COLOR) { 169 ALOGV("\t\tcolor = %u", c.color); 170 } 171} 172 173static void dump_gsc_img(exynos_gsc_img &c) 174{ 175 ALOGV("\tx = %u, y = %u, w = %u, h = %u, fw = %u, fh = %u", 176 c.x, c.y, c.w, c.h, c.fw, c.fh); 177 ALOGV("\taddr = {%u, %u, %u}, rot = %u, cacheable = %u, drmMode = %u", 178 c.yaddr, c.uaddr, c.vaddr, c.rot, c.cacheable, c.drmMode); 179} 180 181inline int WIDTH(const hwc_rect &rect) { return rect.right - rect.left; } 182inline int HEIGHT(const hwc_rect &rect) { return rect.bottom - rect.top; } 183template<typename T> inline T max(T a, T b) { return (a > b) ? a : b; } 184template<typename T> inline T min(T a, T b) { return (a < b) ? a : b; } 185 186static bool is_transformed(const hwc_layer_1_t &layer) 187{ 188 return layer.transform != 0; 189} 190 191static bool is_rotated(const hwc_layer_1_t &layer) 192{ 193 return (layer.transform & HAL_TRANSFORM_ROT_90) || 194 (layer.transform & HAL_TRANSFORM_ROT_180); 195} 196 197static bool is_scaled(const hwc_layer_1_t &layer) 198{ 199 return WIDTH(layer.displayFrame) != WIDTH(layer.sourceCrop) || 200 HEIGHT(layer.displayFrame) != HEIGHT(layer.sourceCrop); 201} 202 203static inline bool gsc_dst_cfg_changed(exynos_gsc_img &c1, exynos_gsc_img &c2) 204{ 205 return c1.x != c2.x || 206 c1.y != c2.y || 207 c1.w != c2.w || 208 c1.h != c2.h || 209 c1.format != c2.format || 210 c1.rot != c2.rot || 211 c1.cacheable != c2.cacheable || 212 c1.drmMode != c2.drmMode; 213} 214 215static inline bool gsc_src_cfg_changed(exynos_gsc_img &c1, exynos_gsc_img &c2) 216{ 217 return gsc_dst_cfg_changed(c1, c2) || 218 c1.fw != c2.fw || 219 c1.fh != c2.fh; 220} 221 222static enum s3c_fb_pixel_format exynos5_format_to_s3c_format(int format) 223{ 224 switch (format) { 225 case HAL_PIXEL_FORMAT_RGBA_8888: 226 return S3C_FB_PIXEL_FORMAT_RGBA_8888; 227 case HAL_PIXEL_FORMAT_RGBX_8888: 228 return S3C_FB_PIXEL_FORMAT_RGBX_8888; 229 case HAL_PIXEL_FORMAT_RGBA_5551: 230 return S3C_FB_PIXEL_FORMAT_RGBA_5551; 231 232 default: 233 return S3C_FB_PIXEL_FORMAT_MAX; 234 } 235} 236 237static bool exynos5_format_is_supported(int format) 238{ 239 return exynos5_format_to_s3c_format(format) < S3C_FB_PIXEL_FORMAT_MAX; 240} 241 242static bool exynos5_format_is_rgb(int format) 243{ 244 switch (format) { 245 case HAL_PIXEL_FORMAT_RGBA_8888: 246 case HAL_PIXEL_FORMAT_RGBX_8888: 247 case HAL_PIXEL_FORMAT_RGB_888: 248 case HAL_PIXEL_FORMAT_RGB_565: 249 case HAL_PIXEL_FORMAT_BGRA_8888: 250 case HAL_PIXEL_FORMAT_RGBA_5551: 251 case HAL_PIXEL_FORMAT_RGBA_4444: 252 return true; 253 254 default: 255 return false; 256 } 257} 258 259static bool exynos5_format_is_supported_by_gscaler(int format) 260{ 261 switch (format) { 262 case HAL_PIXEL_FORMAT_RGBX_8888: 263 case HAL_PIXEL_FORMAT_RGB_565: 264 case HAL_PIXEL_FORMAT_EXYNOS_YV12: 265 case HAL_PIXEL_FORMAT_YCbCr_420_SP: 266 case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED: 267 return true; 268 269 default: 270 return false; 271 } 272} 273 274static bool exynos5_format_is_ycrcb(int format) 275{ 276 return format == HAL_PIXEL_FORMAT_EXYNOS_YV12; 277} 278 279static bool exynos5_format_requires_gscaler(int format) 280{ 281 return exynos5_format_is_supported_by_gscaler(format) && 282 format != HAL_PIXEL_FORMAT_RGBX_8888; 283} 284 285static uint8_t exynos5_format_to_bpp(int format) 286{ 287 switch (format) { 288 case HAL_PIXEL_FORMAT_RGBA_8888: 289 case HAL_PIXEL_FORMAT_RGBX_8888: 290 return 32; 291 292 case HAL_PIXEL_FORMAT_RGBA_5551: 293 case HAL_PIXEL_FORMAT_RGBA_4444: 294 return 16; 295 296 default: 297 ALOGW("unrecognized pixel format %u", format); 298 return 0; 299 } 300} 301 302static bool exynos5_supports_gscaler(hwc_layer_1_t &layer, int format, 303 bool local_path) 304{ 305 private_handle_t *handle = private_handle_t::dynamicCast(layer.handle); 306 307 int max_w = is_rotated(layer) ? 2048 : 4800; 308 int max_h = is_rotated(layer) ? 2048 : 3344; 309 310 bool rot90or270 = !!(layer.transform & HAL_TRANSFORM_ROT_90); 311 // n.b.: HAL_TRANSFORM_ROT_270 = HAL_TRANSFORM_ROT_90 | 312 // HAL_TRANSFORM_ROT_180 313 314 int src_w = WIDTH(layer.sourceCrop), src_h = HEIGHT(layer.sourceCrop); 315 int dest_w, dest_h; 316 if (rot90or270) { 317 dest_w = HEIGHT(layer.displayFrame); 318 dest_h = WIDTH(layer.displayFrame); 319 } else { 320 dest_w = WIDTH(layer.displayFrame); 321 dest_h = HEIGHT(layer.displayFrame); 322 } 323 int max_downscale = local_path ? 4 : 16; 324 const int max_upscale = 8; 325 326 return exynos5_format_is_supported_by_gscaler(format) && 327 handle->stride <= max_w && 328 handle->stride % GSC_W_ALIGNMENT == 0 && 329 src_w <= dest_w * max_downscale && 330 dest_w <= src_w * max_upscale && 331 handle->vstride <= max_h && 332 handle->vstride % GSC_H_ALIGNMENT == 0 && 333 src_h <= dest_h * max_downscale && 334 dest_h <= src_h * max_upscale && 335 // per 46.2 336 (!rot90or270 || layer.sourceCrop.top % 2 == 0) && 337 (!rot90or270 || layer.sourceCrop.left % 2 == 0); 338 // per 46.3.1.6 339} 340 341static bool exynos5_requires_gscaler(hwc_layer_1_t &layer, int format) 342{ 343 return exynos5_format_requires_gscaler(format) || 344 is_scaled(layer) || is_transformed(layer); 345} 346 347int hdmi_get_config(struct exynos5_hwc_composer_device_1_t *dev) 348{ 349 struct v4l2_dv_preset preset; 350 struct v4l2_dv_enum_preset enum_preset; 351 int index = 0; 352 bool found = false; 353 int ret; 354 355 if (ioctl(dev->hdmi_layer0, VIDIOC_G_DV_PRESET, &preset) < 0) { 356 ALOGE("%s: g_dv_preset error, %d", __func__, errno); 357 return -1; 358 } 359 360 while (true) { 361 enum_preset.index = index++; 362 ret = ioctl(dev->hdmi_layer0, VIDIOC_ENUM_DV_PRESETS, &enum_preset); 363 364 if (ret < 0) { 365 if (errno == EINVAL) 366 break; 367 ALOGE("%s: enum_dv_presets error, %d", __func__, errno); 368 return -1; 369 } 370 371 ALOGV("%s: %d preset=%02d width=%d height=%d name=%s", 372 __func__, enum_preset.index, enum_preset.preset, 373 enum_preset.width, enum_preset.height, enum_preset.name); 374 375 if (preset.preset == enum_preset.preset) { 376 dev->hdmi_w = enum_preset.width; 377 dev->hdmi_h = enum_preset.height; 378 found = true; 379 } 380 } 381 382 return found ? 0 : -1; 383} 384 385static enum s3c_fb_blending exynos5_blending_to_s3c_blending(int32_t blending) 386{ 387 switch (blending) { 388 case HWC_BLENDING_NONE: 389 return S3C_FB_BLENDING_NONE; 390 case HWC_BLENDING_PREMULT: 391 return S3C_FB_BLENDING_PREMULT; 392 case HWC_BLENDING_COVERAGE: 393 return S3C_FB_BLENDING_COVERAGE; 394 395 default: 396 return S3C_FB_BLENDING_MAX; 397 } 398} 399 400static bool exynos5_blending_is_supported(int32_t blending) 401{ 402 return exynos5_blending_to_s3c_blending(blending) < S3C_FB_BLENDING_MAX; 403} 404 405static int hdmi_start_background(struct exynos5_hwc_composer_device_1_t *dev) 406{ 407 struct v4l2_requestbuffers reqbuf; 408 struct v4l2_subdev_format sd_fmt; 409 struct v4l2_subdev_crop sd_crop; 410 struct v4l2_format fmt; 411 struct v4l2_buffer buffer; 412 struct v4l2_plane planes[1]; 413 414 memset(&reqbuf, 0, sizeof(reqbuf)); 415 memset(&sd_fmt, 0, sizeof(sd_fmt)); 416 memset(&sd_crop, 0, sizeof(sd_crop)); 417 memset(&fmt, 0, sizeof(fmt)); 418 memset(&buffer, 0, sizeof(buffer)); 419 memset(planes, 0, sizeof(planes)); 420 421 sd_fmt.pad = MIXER_G1_SUBDEV_PAD_SINK; 422 sd_fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE; 423 sd_fmt.format.width = 1; 424 sd_fmt.format.height = 1; 425 sd_fmt.format.code = V4L2_MBUS_FMT_XRGB8888_4X8_LE; 426 if (exynos_subdev_s_fmt(dev->hdmi_mixer0, &sd_fmt) < 0) { 427 ALOGE("%s: s_fmt failed pad=%d", __func__, sd_fmt.pad); 428 return -1; 429 } 430 431 sd_crop.pad = MIXER_G1_SUBDEV_PAD_SINK; 432 sd_crop.which = V4L2_SUBDEV_FORMAT_ACTIVE; 433 sd_crop.rect.left = 0; 434 sd_crop.rect.top = 0; 435 sd_crop.rect.width = 1; 436 sd_crop.rect.height = 1; 437 if (exynos_subdev_s_crop(dev->hdmi_mixer0, &sd_crop) < 0) { 438 ALOGE("%s: set_crop failed pad=%d", __func__, sd_crop.pad); 439 return -1; 440 } 441 442 sd_fmt.pad = MIXER_G1_SUBDEV_PAD_SOURCE; 443 sd_fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE; 444 sd_fmt.format.width = dev->hdmi_w; 445 sd_fmt.format.height = dev->hdmi_h; 446 sd_fmt.format.code = V4L2_MBUS_FMT_XRGB8888_4X8_LE; 447 if (exynos_subdev_s_fmt(dev->hdmi_mixer0, &sd_fmt) < 0) { 448 ALOGE("%s: s_fmt failed pad=%d", __func__, sd_fmt.pad); 449 return -1; 450 } 451 452 sd_crop.pad = MIXER_G1_SUBDEV_PAD_SOURCE; 453 sd_crop.which = V4L2_SUBDEV_FORMAT_ACTIVE; 454 sd_crop.rect.left = 0; 455 sd_crop.rect.top = 0; 456 sd_crop.rect.width = 1; 457 sd_crop.rect.height = 1; 458 if (exynos_subdev_s_crop(dev->hdmi_mixer0, &sd_crop) < 0) { 459 ALOGE("%s: s_crop failed pad=%d", __func__, sd_crop.pad); 460 return -1; 461 } 462 463 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 464 fmt.fmt.pix_mp.width = 1; 465 fmt.fmt.pix_mp.height = 1; 466 fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_BGR32; 467 fmt.fmt.pix_mp.field = V4L2_FIELD_ANY; 468 fmt.fmt.pix_mp.num_planes = 1; 469 if (exynos_v4l2_s_fmt(dev->hdmi_layer1, &fmt) < 0) { 470 ALOGE("%s::videodev set format failed", __func__); 471 return -1; 472 } 473 474 reqbuf.count = 1; 475 reqbuf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 476 reqbuf.memory = V4L2_MEMORY_MMAP; 477 478 if (exynos_v4l2_reqbufs(dev->hdmi_layer1, &reqbuf) < 0) { 479 ALOGE("%s: exynos_v4l2_reqbufs failed %d", __func__, errno); 480 return -1; 481 } 482 483 if (reqbuf.count != 1) { 484 ALOGE("%s: didn't get buffer", __func__); 485 return -1; 486 } 487 488 memset(&buffer, 0, sizeof(buffer)); 489 buffer.type = reqbuf.type; 490 buffer.memory = V4L2_MEMORY_MMAP; 491 buffer.length = 1; 492 buffer.m.planes = planes; 493 if (exynos_v4l2_querybuf(dev->hdmi_layer1, &buffer) < 0) { 494 ALOGE("%s: exynos_v4l2_querybuf failed %d", __func__, errno); 495 return -1; 496 } 497 498 void *start = mmap(NULL, planes[0].length, PROT_READ | PROT_WRITE, 499 MAP_SHARED, dev->hdmi_layer1, planes[0].m.mem_offset); 500 if (start == MAP_FAILED) { 501 ALOGE("%s: mmap failed %d", __func__, errno); 502 return -1; 503 } 504 505 memset(start, 0, planes[0].length); 506 507 munmap(start, planes[0].length); 508 509 if (exynos_v4l2_qbuf(dev->hdmi_layer1, &buffer) < 0) { 510 ALOGE("%s: exynos_v4l2_qbuf failed %d", __func__, errno); 511 return -1; 512 } 513 514 if (exynos_v4l2_streamon(dev->hdmi_layer1, buffer.type) < 0) { 515 ALOGE("%s:stream on failed", __func__); 516 return -1; 517 } 518 519 if (exynos_v4l2_s_ctrl(dev->hdmi_layer1, V4L2_CID_TV_LAYER_PRIO, 0) < 0) { 520 ALOGE("%s: s_ctrl LAYER_PRIO failed", __func__); 521 return -1; 522 } 523 524 return 0; 525} 526 527static int hdmi_stop_background(struct exynos5_hwc_composer_device_1_t *dev) 528{ 529 struct v4l2_requestbuffers reqbuf; 530 531 if (exynos_v4l2_streamoff(dev->hdmi_layer1, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) < 0) { 532 ALOGE("%s:stream off failed", __func__); 533 return -1; 534 } 535 536 memset(&reqbuf, 0, sizeof(reqbuf)); 537 reqbuf.count = 0; 538 reqbuf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 539 reqbuf.memory = V4L2_MEMORY_MMAP; 540 if (exynos_v4l2_reqbufs(dev->hdmi_layer1, &reqbuf) < 0) { 541 ALOGE("%s: exynos_v4l2_reqbufs failed %d", __func__, errno); 542 return -1; 543 } 544 545 return 0; 546} 547 548static int hdmi_enable(struct exynos5_hwc_composer_device_1_t *dev) 549{ 550 if (dev->hdmi_enabled) 551 return 0; 552 553 if (dev->hdmi_blanked) 554 return 0; 555 556 dev->hdmi_gsc = exynos_gsc_create_exclusive(3, GSC_OUTPUT_MODE, GSC_OUT_TV); 557 if (!dev->hdmi_gsc) { 558 ALOGE("%s: exynos_gsc_create_exclusive failed", __func__); 559 return -ENODEV; 560 } 561 562 memset(&dev->hdmi_src, 0, sizeof(dev->hdmi_src)); 563 564 if (hdmi_start_background(dev) < 0) { 565 ALOGE("%s: hdmi_start_background failed", __func__); 566 return -1; 567 } 568 569 dev->hdmi_enabled = true; 570 return 0; 571} 572 573static void hdmi_disable(struct exynos5_hwc_composer_device_1_t *dev) 574{ 575 if (!dev->hdmi_enabled) 576 return; 577 exynos_gsc_destroy(dev->hdmi_gsc); 578 hdmi_stop_background(dev); 579 dev->hdmi_gsc = NULL; 580 dev->hdmi_enabled = false; 581} 582 583static int hdmi_configure(struct exynos5_hwc_composer_device_1_t *dev, 584 exynos_gsc_img &src_cfg, 585 exynos_gsc_img &dst_cfg) 586{ 587 if (!gsc_src_cfg_changed(src_cfg, dev->hdmi_src) 588 && !gsc_dst_cfg_changed(dst_cfg, dev->hdmi_dst)) 589 return 0; 590 591 ALOGV("HDMI source config:"); 592 dump_gsc_img(src_cfg); 593 ALOGV("HDMI dest config:"); 594 dump_gsc_img(dst_cfg); 595 596 exynos_gsc_stop_exclusive(dev->hdmi_gsc); 597 598 int ret = exynos_gsc_config_exclusive(dev->hdmi_gsc, &src_cfg, &dst_cfg); 599 if (ret < 0) { 600 ALOGE("%s: exynos_gsc_config_exclusive failed %d", __func__, ret); 601 return ret; 602 } 603 604 dev->hdmi_src = src_cfg; 605 dev->hdmi_dst = dst_cfg; 606 return ret; 607} 608 609static int hdmi_configure_handle(struct exynos5_hwc_composer_device_1_t *dev, private_handle_t *h) 610{ 611 exynos_gsc_img src_cfg, dst_cfg; 612 memset(&src_cfg, 0, sizeof(src_cfg)); 613 memset(&dst_cfg, 0, sizeof(dst_cfg)); 614 615 src_cfg.w = src_cfg.fw = h->width; 616 src_cfg.h = src_cfg.fh = h->height; 617 src_cfg.format = HAL_PIXEL_FORMAT_BGRA_8888; 618 619 dst_cfg.w = dst_cfg.fw = dev->hdmi_w; 620 dst_cfg.h = dst_cfg.fh = dev->hdmi_h; 621 dst_cfg.format = HAL_PIXEL_FORMAT_EXYNOS_YV12; 622 623 return hdmi_configure(dev, src_cfg, dst_cfg); 624} 625 626static int hdmi_configure_layer(struct exynos5_hwc_composer_device_1_t *dev, hwc_layer_1_t &layer) 627{ 628 exynos_gsc_img src_cfg, dst_cfg; 629 memset(&src_cfg, 0, sizeof(src_cfg)); 630 memset(&dst_cfg, 0, sizeof(dst_cfg)); 631 private_handle_t *src_handle = private_handle_t::dynamicCast(layer.handle); 632 633 src_cfg.x = layer.sourceCrop.left; 634 src_cfg.y = layer.sourceCrop.top; 635 src_cfg.w = WIDTH(layer.sourceCrop); 636 src_cfg.fw = src_handle->stride; 637 src_cfg.h = HEIGHT(layer.sourceCrop); 638 src_cfg.fh = src_handle->vstride; 639 src_cfg.format = src_handle->format; 640 641 if (dev->hdmi_w * src_cfg.h < dev->hdmi_h * src_cfg.w) { 642 dst_cfg.w = dev->hdmi_w; 643 dst_cfg.fw = dev->hdmi_w; 644 dst_cfg.fh = dev->hdmi_h; 645 dst_cfg.h = dev->hdmi_w * src_cfg.h / src_cfg.w; 646 dst_cfg.y = (dev->hdmi_h - dst_cfg.h) / 2; 647 } 648 else { 649 dst_cfg.w = dev->hdmi_h * src_cfg.w / src_cfg.h; 650 dst_cfg.fw = dev->hdmi_w; 651 dst_cfg.h = dev->hdmi_h; 652 dst_cfg.fh = dev->hdmi_h; 653 dst_cfg.x = (dev->hdmi_w - dst_cfg.w) / 2; 654 } 655 dst_cfg.format = HAL_PIXEL_FORMAT_EXYNOS_YV12; 656 dst_cfg.rot = layer.transform; 657 658 return hdmi_configure(dev, src_cfg, dst_cfg); 659} 660 661static int hdmi_output(struct exynos5_hwc_composer_device_1_t *dev, private_handle_t *h) 662{ 663 exynos_gsc_img src_info; 664 exynos_gsc_img dst_info; 665 666 memset(&src_info, 0, sizeof(src_info)); 667 memset(&dst_info, 0, sizeof(dst_info)); 668 669 src_info.yaddr = h->fd; 670 if (exynos5_format_is_ycrcb(h->format)) { 671 src_info.uaddr = h->fd2; 672 src_info.vaddr = h->fd1; 673 } else { 674 src_info.uaddr = h->fd1; 675 src_info.vaddr = h->fd2; 676 } 677 678 int ret = exynos_gsc_run_exclusive(dev->hdmi_gsc, &src_info, &dst_info); 679 if (ret < 0) { 680 ALOGE("%s: exynos_gsc_run_exclusive failed %d", __func__, ret); 681 return ret; 682 } 683 684 return 0; 685} 686 687bool exynos5_supports_overlay(hwc_layer_1_t &layer, size_t i) 688{ 689 if (layer.flags & HWC_SKIP_LAYER) { 690 ALOGV("\tlayer %u: skipping", i); 691 return false; 692 } 693 694 private_handle_t *handle = private_handle_t::dynamicCast(layer.handle); 695 696 if (!handle) { 697 ALOGV("\tlayer %u: handle is NULL", i); 698 return false; 699 } 700 if (!exynos5_format_is_rgb(handle->format) && 701 !exynos5_format_is_supported_by_gscaler(handle->format)) { 702 ALOGW("\tlayer %u: unexpected format %u", i, handle->format); 703 return false; 704 } 705 706 if (exynos5_requires_gscaler(layer, handle->format)) { 707 if (!exynos5_supports_gscaler(layer, handle->format, false)) { 708 ALOGV("\tlayer %u: gscaler required but not supported", i); 709 return false; 710 } 711 } else { 712 if (!exynos5_format_is_supported(handle->format)) { 713 ALOGV("\tlayer %u: pixel format %u not supported", i, handle->format); 714 return false; 715 } 716 } 717 if (!exynos5_blending_is_supported(layer.blending)) { 718 ALOGV("\tlayer %u: blending %d not supported", i, layer.blending); 719 return false; 720 } 721 722 return true; 723} 724 725inline bool intersect(const hwc_rect &r1, const hwc_rect &r2) 726{ 727 return !(r1.left > r2.right || 728 r1.right < r2.left || 729 r1.top > r2.bottom || 730 r1.bottom < r2.top); 731} 732 733inline hwc_rect intersection(const hwc_rect &r1, const hwc_rect &r2) 734{ 735 hwc_rect i; 736 i.top = max(r1.top, r2.top); 737 i.bottom = min(r1.bottom, r2.bottom); 738 i.left = max(r1.left, r2.left); 739 i.right = min(r1.right, r2.right); 740 return i; 741} 742 743static int exynos5_prepare(hwc_composer_device_1_t *dev, 744 size_t numDisplays, hwc_display_contents_1_t** displays) 745{ 746 if (!numDisplays || !displays) 747 return 0; 748 749 ALOGV("preparing %u layers", displays[0]->numHwLayers); 750 751 exynos5_hwc_composer_device_1_t *pdev = 752 (exynos5_hwc_composer_device_1_t *)dev; 753 memset(pdev->bufs.overlays, 0, sizeof(pdev->bufs.overlays)); 754 memset(pdev->bufs.gsc_map, 0, sizeof(pdev->bufs.gsc_map)); 755 756 bool force_fb = false; 757 if (pdev->hdmi_hpd) { 758 hdmi_enable(pdev); 759 force_fb = true; 760 for (size_t i = 0; i < displays[0]->numHwLayers; i++) { 761 hwc_layer_1_t &layer = displays[0]->hwLayers[i]; 762 if (layer.flags & HWC_SKIP_LAYER) 763 continue; 764 private_handle_t *handle = private_handle_t::dynamicCast(layer.handle); 765 if (handle->flags & GRALLOC_USAGE_EXTERNAL_DISP) { 766 force_fb = false; 767 break; 768 } 769 } 770 } else { 771 hdmi_disable(pdev); 772 } 773 774 for (size_t i = 0; i < NUM_HW_WINDOWS; i++) 775 pdev->bufs.overlay_map[i] = -1; 776 777 bool fb_needed = false; 778 size_t first_fb = 0, last_fb = 0; 779 780 // find unsupported overlays 781 for (size_t i = 0; i < displays[0]->numHwLayers; i++) { 782 hwc_layer_1_t &layer = displays[0]->hwLayers[i]; 783 784 if (layer.compositionType == HWC_BACKGROUND && !force_fb) { 785 ALOGV("\tlayer %u: background supported", i); 786 dump_layer(&displays[0]->hwLayers[i]); 787 continue; 788 } 789 790 if (exynos5_supports_overlay(displays[0]->hwLayers[i], i) && !force_fb) { 791 ALOGV("\tlayer %u: overlay supported", i); 792 layer.compositionType = HWC_OVERLAY; 793 dump_layer(&displays[0]->hwLayers[i]); 794 continue; 795 } 796 797 if (!fb_needed) { 798 first_fb = i; 799 fb_needed = true; 800 } 801 last_fb = i; 802 layer.compositionType = HWC_FRAMEBUFFER; 803 804 dump_layer(&displays[0]->hwLayers[i]); 805 } 806 807 // can't composite overlays sandwiched between framebuffers 808 if (fb_needed) 809 for (size_t i = first_fb; i < last_fb; i++) 810 displays[0]->hwLayers[i].compositionType = HWC_FRAMEBUFFER; 811 812 // Incrementally try to add our supported layers to hardware windows. 813 // If adding a layer would violate a hardware constraint, force it 814 // into the framebuffer and try again. (Revisiting the entire list is 815 // necessary because adding a layer to the framebuffer can cause other 816 // windows to retroactively violate constraints.) 817 // For simplicity ignore the way bandwidth is divided between memory 818 // interfaces; this will be enforced separately. 819 bool changed; 820 do { 821 android::Vector<hwc_rect> rects; 822 android::Vector<hwc_rect> overlaps; 823 size_t pixels_left, windows_left, gsc_left = NUM_GSC_UNITS; 824 825 if (fb_needed) { 826 hwc_rect_t fb_rect; 827 fb_rect.top = fb_rect.left = 0; 828 fb_rect.right = pdev->gralloc_module->xres - 1; 829 fb_rect.bottom = pdev->gralloc_module->yres - 1; 830 pixels_left = MAX_PIXELS - pdev->gralloc_module->xres * 831 pdev->gralloc_module->yres; 832 windows_left = NUM_HW_WINDOWS - 1; 833 rects.push_back(fb_rect); 834 } 835 else { 836 pixels_left = MAX_PIXELS; 837 windows_left = NUM_HW_WINDOWS; 838 } 839 if (pdev->hdmi_enabled) 840 gsc_left--; 841 842 changed = false; 843 844 for (size_t i = 0; i < displays[0]->numHwLayers; i++) { 845 hwc_layer_1_t &layer = displays[0]->hwLayers[i]; 846 if (layer.flags & HWC_SKIP_LAYER) 847 continue; 848 849 private_handle_t *handle = private_handle_t::dynamicCast( 850 layer.handle); 851 852 // we've already accounted for the framebuffer above 853 if (layer.compositionType == HWC_FRAMEBUFFER) 854 continue; 855 856 // only layer 0 can be HWC_BACKGROUND, so we can 857 // unconditionally allow it without extra checks 858 if (layer.compositionType == HWC_BACKGROUND) { 859 windows_left--; 860 continue; 861 } 862 863 size_t pixels_needed = WIDTH(layer.displayFrame) * 864 HEIGHT(layer.displayFrame); 865 bool can_compose = windows_left && pixels_needed <= pixels_left; 866 bool gsc_required = exynos5_requires_gscaler(layer, handle->format); 867 if (gsc_required) 868 can_compose = can_compose && gsc_left; 869 870 // hwc_rect_t right and bottom values are normally exclusive; 871 // the intersection logic is simpler if we make them inclusive 872 hwc_rect_t visible_rect = layer.displayFrame; 873 visible_rect.right--; visible_rect.bottom--; 874 875 // no more than 2 layers can overlap on a given pixel 876 for (size_t j = 0; can_compose && j < overlaps.size(); j++) { 877 if (intersect(visible_rect, overlaps.itemAt(j))) 878 can_compose = false; 879 } 880 881 if (!can_compose) { 882 layer.compositionType = HWC_FRAMEBUFFER; 883 if (!fb_needed) { 884 first_fb = last_fb = i; 885 fb_needed = true; 886 } 887 else { 888 first_fb = min(i, first_fb); 889 last_fb = max(i, last_fb); 890 } 891 changed = true; 892 break; 893 } 894 895 for (size_t j = 0; j < rects.size(); j++) { 896 const hwc_rect_t &other_rect = rects.itemAt(j); 897 if (intersect(visible_rect, other_rect)) 898 overlaps.push_back(intersection(visible_rect, other_rect)); 899 } 900 rects.push_back(visible_rect); 901 pixels_left -= pixels_needed; 902 windows_left--; 903 if (gsc_required) 904 gsc_left--; 905 } 906 907 if (changed) 908 for (size_t i = first_fb; i < last_fb; i++) 909 displays[0]->hwLayers[i].compositionType = HWC_FRAMEBUFFER; 910 } while(changed); 911 912 unsigned int nextWindow = 0; 913 int nextGsc = 0; 914 915 for (size_t i = 0; i < displays[0]->numHwLayers; i++) { 916 hwc_layer_1_t &layer = displays[0]->hwLayers[i]; 917 918 if (fb_needed && i == first_fb) { 919 ALOGV("assigning framebuffer to window %u\n", 920 nextWindow); 921 nextWindow++; 922 continue; 923 } 924 925 if (layer.compositionType != HWC_FRAMEBUFFER) { 926 ALOGV("assigning layer %u to window %u", i, nextWindow); 927 pdev->bufs.overlay_map[nextWindow] = i; 928 if (layer.compositionType == HWC_OVERLAY) { 929 private_handle_t *handle = 930 private_handle_t::dynamicCast(layer.handle); 931 if (exynos5_requires_gscaler(layer, handle->format)) { 932 ALOGV("\tusing gscaler %u", AVAILABLE_GSC_UNITS[nextGsc]); 933 pdev->bufs.gsc_map[i].mode = 934 exynos5_gsc_map_t::GSC_M2M; 935 pdev->bufs.gsc_map[i].idx = nextGsc++; 936 } 937 } 938 nextWindow++; 939 } 940 } 941 942 size_t memif_pixels[] = { 0, 0 }; 943 for (size_t i = 0; i < NUM_HW_WINDOWS; i++) { 944 int memif_idx = MEMIF_CONFIGURATION[i]; 945 if (fb_needed && i == first_fb) { 946 memif_pixels[memif_idx] += pdev->gralloc_module->xres * 947 pdev->gralloc_module->yres; 948 } else if (pdev->bufs.overlay_map[i] != -1) { 949 int layer_idx = pdev->bufs.overlay_map[i]; 950 hwc_layer_1_t &layer = displays[0]->hwLayers[layer_idx]; 951 memif_pixels[memif_idx] += WIDTH(layer.displayFrame) * 952 HEIGHT(layer.displayFrame); 953 } 954 } 955 956 // If there are too many pixels for either memory interface, retroactively 957 // put them into a framebuffer. One layer can be kept in window 0 if it's 958 // otherwise composable: the framebuffer will be in window 1 which is on a 959 // separate memory interface from window 0. 960 bool memif_pixels_ok = true; 961 for (size_t i = 0; i < 2; i++) { 962 if (memif_pixels[i] > MAX_PIXELS_PER_MEMIF) { 963 ALOGV("too many pixels for memory interface %u", i); 964 memif_pixels_ok = false; 965 } 966 } 967 if (!memif_pixels_ok) { 968 for (size_t i = 1; i < NUM_HW_WINDOWS; i++) { 969 int layer_idx = pdev->bufs.overlay_map[i]; 970 if (layer_idx == -1) 971 continue; 972 973 hwc_layer_1_t &layer = displays[0]->hwLayers[layer_idx]; 974 layer.transform = HWC_FRAMEBUFFER; 975 pdev->bufs.overlay_map[i] = -1; 976 pdev->bufs.gsc_map[i].mode = exynos5_gsc_map_t::GSC_NONE; 977 } 978 979 if (pdev->bufs.gsc_map[0].mode == exynos5_gsc_map_t::GSC_NONE) 980 nextGsc = 0; 981 else 982 nextGsc = 1; 983 984 if (fb_needed) 985 first_fb = min(first_fb, 1U); 986 else { 987 first_fb = 1; 988 fb_needed = true; 989 } 990 ALOGV("moving framebuffer to window %u", first_fb); 991 } 992 993 for (size_t i = nextGsc; i < NUM_GSC_UNITS; i++) { 994 for (size_t j = 0; j < NUM_GSC_DST_BUFS; j++) 995 if (pdev->gsc[i].dst_buf[j]) 996 pdev->alloc_device->free(pdev->alloc_device, 997 pdev->gsc[i].dst_buf[j]); 998 memset(&pdev->gsc[i], 0, sizeof(pdev->gsc[i])); 999 } 1000 1001 if (fb_needed) 1002 pdev->bufs.fb_window = first_fb; 1003 else 1004 pdev->bufs.fb_window = NO_FB_NEEDED; 1005 1006 return 0; 1007} 1008 1009static int exynos5_config_gsc_m2m(hwc_layer_1_t &layer, 1010 alloc_device_t* alloc_device, exynos5_gsc_data_t *gsc_data, 1011 int gsc_idx) 1012{ 1013 ALOGV("configuring gscaler %u for memory-to-memory", gsc_idx); 1014 1015 private_handle_t *src_handle = private_handle_t::dynamicCast(layer.handle); 1016 buffer_handle_t dst_buf; 1017 private_handle_t *dst_handle; 1018 int ret = 0; 1019 1020 exynos_gsc_img src_cfg, dst_cfg; 1021 memset(&src_cfg, 0, sizeof(src_cfg)); 1022 memset(&dst_cfg, 0, sizeof(dst_cfg)); 1023 1024 src_cfg.x = layer.sourceCrop.left; 1025 src_cfg.y = layer.sourceCrop.top; 1026 src_cfg.w = WIDTH(layer.sourceCrop); 1027 src_cfg.fw = src_handle->stride; 1028 src_cfg.h = HEIGHT(layer.sourceCrop); 1029 src_cfg.fh = src_handle->vstride; 1030 src_cfg.yaddr = src_handle->fd; 1031 if (exynos5_format_is_ycrcb(src_handle->format)) { 1032 src_cfg.uaddr = src_handle->fd2; 1033 src_cfg.vaddr = src_handle->fd1; 1034 } else { 1035 src_cfg.uaddr = src_handle->fd1; 1036 src_cfg.vaddr = src_handle->fd2; 1037 } 1038 src_cfg.format = src_handle->format; 1039 src_cfg.drmMode = !!(src_handle->flags & GRALLOC_USAGE_PROTECTED); 1040 1041 dst_cfg.x = 0; 1042 dst_cfg.y = 0; 1043 dst_cfg.w = WIDTH(layer.displayFrame); 1044 dst_cfg.h = HEIGHT(layer.displayFrame); 1045 dst_cfg.format = HAL_PIXEL_FORMAT_BGRA_8888; 1046 dst_cfg.rot = layer.transform; 1047 dst_cfg.drmMode = src_cfg.drmMode; 1048 1049 ALOGV("source configuration:"); 1050 dump_gsc_img(src_cfg); 1051 1052 if (gsc_src_cfg_changed(src_cfg, gsc_data->src_cfg) || 1053 gsc_dst_cfg_changed(dst_cfg, gsc_data->dst_cfg)) { 1054 int dst_stride; 1055 int usage = GRALLOC_USAGE_SW_READ_NEVER | 1056 GRALLOC_USAGE_SW_WRITE_NEVER | 1057 GRALLOC_USAGE_HW_COMPOSER; 1058 1059 if (src_handle->flags & GRALLOC_USAGE_PROTECTED) 1060 usage |= GRALLOC_USAGE_PROTECTED; 1061 1062 int w = ALIGN(WIDTH(layer.displayFrame), GSC_W_ALIGNMENT); 1063 int h = ALIGN(HEIGHT(layer.displayFrame), GSC_H_ALIGNMENT); 1064 1065 for (size_t i = 0; i < NUM_GSC_DST_BUFS; i++) { 1066 if (gsc_data->dst_buf[i]) { 1067 alloc_device->free(alloc_device, gsc_data->dst_buf[i]); 1068 gsc_data->dst_buf[i] = NULL; 1069 } 1070 1071 int ret = alloc_device->alloc(alloc_device, w, h, 1072 HAL_PIXEL_FORMAT_RGBX_8888, usage, &gsc_data->dst_buf[i], 1073 &dst_stride); 1074 if (ret < 0) { 1075 ALOGE("failed to allocate destination buffer: %s", 1076 strerror(-ret)); 1077 goto err_alloc; 1078 } 1079 } 1080 1081 gsc_data->current_buf = 0; 1082 } 1083 1084 dst_buf = gsc_data->dst_buf[gsc_data->current_buf]; 1085 dst_handle = private_handle_t::dynamicCast(dst_buf); 1086 1087 dst_cfg.fw = dst_handle->stride; 1088 dst_cfg.fh = dst_handle->vstride; 1089 dst_cfg.yaddr = dst_handle->fd; 1090 1091 ALOGV("destination configuration:"); 1092 dump_gsc_img(dst_cfg); 1093 1094 gsc_data->gsc = exynos_gsc_create_exclusive(AVAILABLE_GSC_UNITS[gsc_idx], 1095 GSC_M2M_MODE, GSC_DUMMY); 1096 if (!gsc_data->gsc) { 1097 ALOGE("failed to create gscaler handle"); 1098 ret = -1; 1099 goto err_alloc; 1100 } 1101 1102 ret = exynos_gsc_config_exclusive(gsc_data->gsc, &src_cfg, &dst_cfg); 1103 if (ret < 0) { 1104 ALOGE("failed to configure gscaler %u", gsc_idx); 1105 goto err_gsc_config; 1106 } 1107 1108 ret = exynos_gsc_run_exclusive(gsc_data->gsc, &src_cfg, &dst_cfg); 1109 if (ret < 0) { 1110 ALOGE("failed to run gscaler %u", gsc_idx); 1111 goto err_gsc_config; 1112 } 1113 1114 gsc_data->src_cfg = src_cfg; 1115 gsc_data->dst_cfg = dst_cfg; 1116 1117 return 0; 1118 1119err_gsc_config: 1120 exynos_gsc_destroy(gsc_data->gsc); 1121 gsc_data->gsc = NULL; 1122err_alloc: 1123 for (size_t i = 0; i < NUM_GSC_DST_BUFS; i++) { 1124 if (gsc_data->dst_buf[i]) { 1125 alloc_device->free(alloc_device, gsc_data->dst_buf[i]); 1126 gsc_data->dst_buf[i] = NULL; 1127 } 1128 } 1129 return ret; 1130} 1131 1132static void exynos5_config_handle(private_handle_t *handle, 1133 hwc_rect_t &sourceCrop, hwc_rect_t &displayFrame, 1134 int32_t blending, s3c_fb_win_config &cfg) 1135{ 1136 cfg.state = cfg.S3C_FB_WIN_STATE_BUFFER; 1137 cfg.fd = handle->fd; 1138 cfg.x = displayFrame.left; 1139 cfg.y = displayFrame.top; 1140 cfg.w = WIDTH(displayFrame); 1141 cfg.h = HEIGHT(displayFrame); 1142 cfg.format = exynos5_format_to_s3c_format(handle->format); 1143 uint8_t bpp = exynos5_format_to_bpp(handle->format); 1144 cfg.offset = (sourceCrop.top * handle->stride + sourceCrop.left) * bpp / 8; 1145 cfg.stride = handle->stride * bpp / 8; 1146 cfg.blending = exynos5_blending_to_s3c_blending(blending); 1147} 1148 1149static void exynos5_config_overlay(hwc_layer_1_t *layer, s3c_fb_win_config &cfg, 1150 const private_module_t *gralloc_module) 1151{ 1152 if (layer->compositionType == HWC_BACKGROUND) { 1153 hwc_color_t color = layer->backgroundColor; 1154 cfg.state = cfg.S3C_FB_WIN_STATE_COLOR; 1155 cfg.color = (color.r << 16) | (color.g << 8) | color.b; 1156 cfg.x = 0; 1157 cfg.y = 0; 1158 cfg.w = gralloc_module->xres; 1159 cfg.h = gralloc_module->yres; 1160 return; 1161 } 1162 1163 private_handle_t *handle = private_handle_t::dynamicCast(layer->handle); 1164 exynos5_config_handle(handle, layer->sourceCrop, layer->displayFrame, 1165 layer->blending, cfg); 1166} 1167 1168static void exynos5_post_callback(void *data, private_handle_t *fb) 1169{ 1170 hwc_layer_1_t *hdmi_layer = NULL; 1171 exynos5_hwc_post_data_t *pdata = (exynos5_hwc_post_data_t *)data; 1172 1173 struct s3c_fb_win_config_data win_data; 1174 struct s3c_fb_win_config *config = win_data.config; 1175 memset(config, 0, sizeof(win_data.config)); 1176 1177 for (size_t i = 0; i < NUM_HW_WINDOWS; i++) { 1178 if ( pdata->overlay_map[i] != -1) { 1179 hwc_layer_1_t &layer = pdata->overlays[i]; 1180 private_handle_t *handle = 1181 private_handle_t::dynamicCast(layer.handle); 1182 1183 if (layer.acquireFenceFd != -1) { 1184 int err = sync_wait(layer.acquireFenceFd, 100); 1185 if (err != 0) 1186 ALOGW("fence for layer %zu didn't signal in 100 ms: %s", 1187 i, strerror(errno)); 1188 close(layer.acquireFenceFd); 1189 } 1190 1191 if (pdata->gsc_map[i].mode == exynos5_gsc_map_t::GSC_M2M) { 1192 int gsc_idx = pdata->gsc_map[i].idx; 1193 exynos5_config_gsc_m2m(layer, pdata->pdev->alloc_device, 1194 &pdata->pdev->gsc[gsc_idx], gsc_idx); 1195 } 1196 } 1197 } 1198 1199 for (size_t i = 0; i < NUM_HW_WINDOWS; i++) { 1200 if (i == pdata->fb_window) { 1201 hwc_rect_t rect = { 0, 0, fb->width, fb->height }; 1202 int32_t blending = (i == 0) ? HWC_BLENDING_NONE : 1203 HWC_BLENDING_PREMULT; 1204 exynos5_config_handle(fb, rect, rect, blending, config[i]); 1205 } else if ( pdata->overlay_map[i] != -1) { 1206 hwc_layer_1_t &layer = pdata->overlays[i]; 1207 private_handle_t *handle = 1208 private_handle_t::dynamicCast(layer.handle); 1209 1210 if (pdata->gsc_map[i].mode == exynos5_gsc_map_t::GSC_M2M) { 1211 int gsc_idx = pdata->gsc_map[i].idx; 1212 exynos5_gsc_data_t &gsc = pdata->pdev->gsc[gsc_idx]; 1213 1214 if (!gsc.gsc) { 1215 ALOGE("failed to queue gscaler %u input for layer %u", 1216 gsc_idx, i); 1217 continue; 1218 } 1219 1220 int err = exynos_gsc_stop_exclusive(gsc.gsc); 1221 exynos_gsc_destroy(gsc.gsc); 1222 gsc.gsc = NULL; 1223 if (err < 0) { 1224 ALOGE("failed to dequeue gscaler output for layer %u", i); 1225 continue; 1226 } 1227 1228 buffer_handle_t dst_buf = gsc.dst_buf[gsc.current_buf]; 1229 gsc.current_buf = (gsc.current_buf + 1) % NUM_GSC_DST_BUFS; 1230 private_handle_t *dst_handle = 1231 private_handle_t::dynamicCast(dst_buf); 1232 hwc_rect_t sourceCrop = { 0, 0, 1233 WIDTH(layer.displayFrame), HEIGHT(layer.displayFrame) }; 1234 exynos5_config_handle(dst_handle, sourceCrop, 1235 layer.displayFrame, layer.blending, config[i]); 1236 1237 if (handle->flags & GRALLOC_USAGE_EXTERNAL_DISP) 1238 hdmi_layer = &layer; 1239 } 1240 else { 1241 exynos5_config_overlay(&layer, config[i], 1242 pdata->pdev->gralloc_module); 1243 } 1244 } 1245 if (i == 0 && config[i].blending != S3C_FB_BLENDING_NONE) { 1246 ALOGV("blending not supported on window 0; forcing BLENDING_NONE"); 1247 config[i].blending = S3C_FB_BLENDING_NONE; 1248 } 1249 1250 ALOGV("window %u configuration:", i); 1251 dump_config(config[i]); 1252 } 1253 1254 int ret = ioctl(pdata->pdev->fd, S3CFB_WIN_CONFIG, &win_data); 1255 if (ret < 0) 1256 ALOGE("ioctl S3CFB_WIN_CONFIG failed: %d", errno); 1257 else { 1258 memcpy(pdata->pdev->last_config, &win_data.config, 1259 sizeof(win_data.config)); 1260 memcpy(pdata->pdev->last_gsc_map, pdata->gsc_map, 1261 sizeof(pdata->gsc_map)); 1262 for (size_t i = 0; i < NUM_HW_WINDOWS; i++) { 1263 if (i == pdata->fb_window) { 1264 pdata->pdev->last_handles[i] = NULL; 1265 } else if (pdata->overlay_map[i] != -1) { 1266 hwc_layer_1_t &layer = pdata->overlays[i]; 1267 pdata->pdev->last_handles[i] = layer.handle; 1268 } 1269 } 1270 } 1271 1272 if (pdata->pdev->hdmi_enabled) { 1273 if (hdmi_layer) { 1274 private_handle_t *handle = 1275 private_handle_t::dynamicCast(hdmi_layer->handle); 1276 hdmi_configure_layer(pdata->pdev, *hdmi_layer); 1277 hdmi_output(pdata->pdev, handle); 1278 } else { 1279 hdmi_configure_handle(pdata->pdev, fb); 1280 hdmi_output(pdata->pdev, fb); 1281 } 1282 } 1283 1284 pthread_mutex_lock(&pdata->completion_lock); 1285 pdata->fence = win_data.fence; 1286 pthread_cond_signal(&pdata->completion); 1287 pthread_mutex_unlock(&pdata->completion_lock); 1288} 1289 1290static int exynos5_set(struct hwc_composer_device_1 *dev, 1291 size_t numDisplays, hwc_display_contents_1_t** displays) 1292{ 1293 exynos5_hwc_composer_device_1_t *pdev = 1294 (exynos5_hwc_composer_device_1_t *)dev; 1295 1296 if (!numDisplays || !displays || !displays[0] || !displays[0]->dpy || !displays[0]->sur) 1297 return 0; 1298 1299 hwc_callback_queue_t *queue = NULL; 1300 pthread_mutex_t *lock = NULL; 1301 exynos5_hwc_post_data_t *data = NULL; 1302 1303 for (size_t i = 0; i < NUM_HW_WINDOWS; i++) { 1304 if (pdev->bufs.overlay_map[i] != -1) { 1305 pdev->bufs.overlays[i] = 1306 displays[0]->hwLayers[pdev->bufs.overlay_map[i]]; 1307 } 1308 } 1309 1310 data = (exynos5_hwc_post_data_t *) 1311 malloc(sizeof(exynos5_hwc_post_data_t)); 1312 memcpy(data, &pdev->bufs, sizeof(pdev->bufs)); 1313 1314 data->fence = -1; 1315 pthread_mutex_init(&data->completion_lock, NULL); 1316 pthread_cond_init(&data->completion, NULL); 1317 1318 if (displays[0]->numHwLayers && pdev->bufs.fb_window == NO_FB_NEEDED) { 1319 exynos5_post_callback(data, NULL); 1320 } else { 1321 1322 struct hwc_callback_entry entry; 1323 entry.callback = exynos5_post_callback; 1324 entry.data = data; 1325 1326 queue = reinterpret_cast<hwc_callback_queue_t *>( 1327 pdev->gralloc_module->queue); 1328 lock = const_cast<pthread_mutex_t *>( 1329 &pdev->gralloc_module->queue_lock); 1330 1331 pthread_mutex_lock(lock); 1332 queue->push_front(entry); 1333 pthread_mutex_unlock(lock); 1334 1335 EGLBoolean success = eglSwapBuffers((EGLDisplay)displays[0]->dpy, 1336 (EGLSurface)displays[0]->sur); 1337 if (!success) { 1338 ALOGE("HWC_EGL_ERROR"); 1339 if (displays[0]) { 1340 pthread_mutex_lock(lock); 1341 queue->removeAt(0); 1342 pthread_mutex_unlock(lock); 1343 free(data); 1344 } 1345 return HWC_EGL_ERROR; 1346 } 1347 } 1348 1349 1350 pthread_mutex_lock(&data->completion_lock); 1351 while (data->fence == -1) 1352 pthread_cond_wait(&data->completion, &data->completion_lock); 1353 pthread_mutex_unlock(&data->completion_lock); 1354 1355 for (size_t i = 0; i < NUM_HW_WINDOWS; i++) { 1356 if (pdev->bufs.overlay_map[i] != -1) { 1357 int dup_fd = dup(data->fence); 1358 if (dup_fd < 0) 1359 ALOGW("release fence dup failed: %s", strerror(errno)); 1360 displays[0]->hwLayers[pdev->bufs.overlay_map[i]].releaseFenceFd = dup_fd; 1361 } 1362 } 1363 close(data->fence); 1364 free(data); 1365 return 0; 1366} 1367 1368static void exynos5_registerProcs(struct hwc_composer_device_1* dev, 1369 hwc_procs_t const* procs) 1370{ 1371 struct exynos5_hwc_composer_device_1_t* pdev = 1372 (struct exynos5_hwc_composer_device_1_t*)dev; 1373 pdev->procs = procs; 1374} 1375 1376static int exynos5_query(struct hwc_composer_device_1* dev, int what, int *value) 1377{ 1378 struct exynos5_hwc_composer_device_1_t *pdev = 1379 (struct exynos5_hwc_composer_device_1_t *)dev; 1380 1381 switch (what) { 1382 case HWC_BACKGROUND_LAYER_SUPPORTED: 1383 // we support the background layer 1384 value[0] = 1; 1385 break; 1386 case HWC_VSYNC_PERIOD: 1387 // vsync period in nanosecond 1388 value[0] = 1000000000.0 / pdev->gralloc_module->fps; 1389 break; 1390 default: 1391 // unsupported query 1392 return -EINVAL; 1393 } 1394 return 0; 1395} 1396 1397static int exynos5_eventControl(struct hwc_composer_device_1 *dev, int dpy, 1398 int event, int enabled) 1399{ 1400 struct exynos5_hwc_composer_device_1_t *pdev = 1401 (struct exynos5_hwc_composer_device_1_t *)dev; 1402 1403 switch (event) { 1404 case HWC_EVENT_VSYNC: 1405 __u32 val = !!enabled; 1406 int err = ioctl(pdev->fd, S3CFB_SET_VSYNC_INT, &val); 1407 if (err < 0) { 1408 ALOGE("vsync ioctl failed"); 1409 return -errno; 1410 } 1411 1412 return 0; 1413 } 1414 1415 return -EINVAL; 1416} 1417 1418static void handle_hdmi_uevent(struct exynos5_hwc_composer_device_1_t *pdev, 1419 const char *buff, int len) 1420{ 1421 const char *s = buff; 1422 s += strlen(s) + 1; 1423 1424 while (*s) { 1425 if (!strncmp(s, "SWITCH_STATE=", strlen("SWITCH_STATE="))) 1426 pdev->hdmi_hpd = atoi(s + strlen("SWITCH_STATE=")) == 1; 1427 1428 s += strlen(s) + 1; 1429 if (s - buff >= len) 1430 break; 1431 } 1432 1433 if (pdev->hdmi_hpd) { 1434 if (hdmi_get_config(pdev)) { 1435 ALOGE("Error reading HDMI configuration"); 1436 pdev->hdmi_hpd = false; 1437 return; 1438 } 1439 } 1440 1441 ALOGV("HDMI HPD changed to %s", pdev->hdmi_hpd ? "enabled" : "disabled"); 1442 if (pdev->hdmi_hpd) 1443 ALOGI("HDMI Resolution changed to %dx%d", pdev->hdmi_h, pdev->hdmi_w); 1444 1445 /* hwc_dev->procs is set right after the device is opened, but there is 1446 * still a race condition where a hotplug event might occur after the open 1447 * but before the procs are registered. */ 1448 if (pdev->procs) 1449 pdev->procs->invalidate(pdev->procs); 1450} 1451 1452static void handle_vsync_event(struct exynos5_hwc_composer_device_1_t *pdev) 1453{ 1454 if (!pdev->procs) 1455 return; 1456 1457 int err = lseek(pdev->vsync_fd, 0, SEEK_SET); 1458 if (err < 0) { 1459 ALOGE("error seeking to vsync timestamp: %s", strerror(errno)); 1460 return; 1461 } 1462 1463 char buf[4096]; 1464 err = read(pdev->vsync_fd, buf, sizeof(buf)); 1465 if (err < 0) { 1466 ALOGE("error reading vsync timestamp: %s", strerror(errno)); 1467 return; 1468 } 1469 buf[sizeof(buf) - 1] = '\0'; 1470 1471 errno = 0; 1472 uint64_t timestamp = strtoull(buf, NULL, 0); 1473 if (!errno) 1474 pdev->procs->vsync(pdev->procs, 0, timestamp); 1475} 1476 1477static void *hwc_vsync_thread(void *data) 1478{ 1479 struct exynos5_hwc_composer_device_1_t *pdev = 1480 (struct exynos5_hwc_composer_device_1_t *)data; 1481 char uevent_desc[4096]; 1482 memset(uevent_desc, 0, sizeof(uevent_desc)); 1483 1484 setpriority(PRIO_PROCESS, 0, HAL_PRIORITY_URGENT_DISPLAY); 1485 1486 uevent_init(); 1487 1488 char temp[4096]; 1489 int err = read(pdev->vsync_fd, temp, sizeof(temp)); 1490 if (err < 0) { 1491 ALOGE("error reading vsync timestamp: %s", strerror(errno)); 1492 return NULL; 1493 } 1494 1495 struct pollfd fds[2]; 1496 fds[0].fd = pdev->vsync_fd; 1497 fds[0].events = POLLPRI; 1498 fds[1].fd = uevent_get_fd(); 1499 fds[1].events = POLLIN; 1500 1501 while (true) { 1502 int err = poll(fds, 2, -1); 1503 1504 if (err > 0) { 1505 if (fds[0].revents & POLLPRI) { 1506 handle_vsync_event(pdev); 1507 } 1508 else if (fds[1].revents & POLLIN) { 1509 int len = uevent_next_event(uevent_desc, 1510 sizeof(uevent_desc) - 2); 1511 1512 bool hdmi = !strcmp(uevent_desc, 1513 "change@/devices/virtual/switch/hdmi"); 1514 if (hdmi) 1515 handle_hdmi_uevent(pdev, uevent_desc, len); 1516 } 1517 } 1518 else if (err == -1) { 1519 if (errno == EINTR) 1520 break; 1521 ALOGE("error in vsync thread: %s", strerror(errno)); 1522 } 1523 } 1524 1525 return NULL; 1526} 1527 1528static int exynos5_blank(struct hwc_composer_device_1 *dev, int dpy, int blank) 1529{ 1530 struct exynos5_hwc_composer_device_1_t *pdev = 1531 (struct exynos5_hwc_composer_device_1_t *)dev; 1532 1533 int fb_blank = blank ? FB_BLANK_POWERDOWN : FB_BLANK_UNBLANK; 1534 int err = ioctl(pdev->fd, FBIOBLANK, fb_blank); 1535 if (err < 0) { 1536 ALOGE("%sblank ioctl failed", blank ? "" : "un"); 1537 return -errno; 1538 } 1539 1540 if (pdev->hdmi_hpd) { 1541 if (blank && !pdev->hdmi_blanked) 1542 hdmi_disable(pdev); 1543 pdev->hdmi_blanked = !!blank; 1544 } 1545 1546 return 0; 1547} 1548 1549static void exynos5_dump(hwc_composer_device_1* dev, char *buff, int buff_len) 1550{ 1551 if (buff_len <= 0) 1552 return; 1553 1554 struct exynos5_hwc_composer_device_1_t *pdev = 1555 (struct exynos5_hwc_composer_device_1_t *)dev; 1556 1557 android::String8 result; 1558 1559 result.appendFormat(" hdmi_enabled=%u\n", pdev->hdmi_enabled); 1560 if (pdev->hdmi_enabled) 1561 result.appendFormat(" w=%u, h=%u\n", pdev->hdmi_w, pdev->hdmi_h); 1562 result.append( 1563 " type | handle | color | blend | format | position | size | gsc \n" 1564 "----------+----------|----------+-------+--------+---------------+---------------------\n"); 1565 // 8_______ | 8_______ | 8_______ | 5____ | 6_____ | [5____,5____] | [5____,5____] | 3__ \n" 1566 1567 for (size_t i = 0; i < NUM_HW_WINDOWS; i++) { 1568 struct s3c_fb_win_config &config = pdev->last_config[i]; 1569 if (config.state == config.S3C_FB_WIN_STATE_DISABLED) { 1570 result.appendFormat(" %8s | %8s | %8s | %5s | %6s | %13s | %13s", 1571 "DISABLED", "-", "-", "-", "-", "-", "-"); 1572 } 1573 else { 1574 if (config.state == config.S3C_FB_WIN_STATE_COLOR) 1575 result.appendFormat(" %8s | %8s | %8x | %5s | %6s", "COLOR", 1576 "-", config.color, "-", "-"); 1577 else { 1578 if (pdev->last_handles[i]) 1579 result.appendFormat(" %8s | %8x", "OVERLAY", intptr_t(pdev->last_handles[i])); 1580 else 1581 result.appendFormat(" %8s | %8s", "FB", "-"); 1582 1583 result.appendFormat(" | %8s | %5x | %6x", "-", config.blending, 1584 config.format); 1585 } 1586 1587 result.appendFormat(" | [%5d,%5d] | [%5u,%5u]", config.x, config.y, 1588 config.w, config.h); 1589 } 1590 if (pdev->last_gsc_map[i].mode == exynos5_gsc_map_t::GSC_NONE) 1591 result.appendFormat(" | %3s", "-"); 1592 else 1593 result.appendFormat(" | %3d", 1594 AVAILABLE_GSC_UNITS[pdev->last_gsc_map[i].idx]); 1595 result.append("\n"); 1596 } 1597 1598 strlcpy(buff, result.string(), buff_len); 1599} 1600 1601static int exynos5_close(hw_device_t* device); 1602 1603static int exynos5_open(const struct hw_module_t *module, const char *name, 1604 struct hw_device_t **device) 1605{ 1606 int ret; 1607 int sw_fd; 1608 1609 if (strcmp(name, HWC_HARDWARE_COMPOSER)) { 1610 return -EINVAL; 1611 } 1612 1613 struct exynos5_hwc_composer_device_1_t *dev; 1614 dev = (struct exynos5_hwc_composer_device_1_t *)malloc(sizeof(*dev)); 1615 memset(dev, 0, sizeof(*dev)); 1616 1617 if (hw_get_module(GRALLOC_HARDWARE_MODULE_ID, 1618 (const struct hw_module_t **)&dev->gralloc_module)) { 1619 ALOGE("failed to get gralloc hw module"); 1620 ret = -EINVAL; 1621 goto err_get_module; 1622 } 1623 1624 if (gralloc_open((const hw_module_t *)dev->gralloc_module, 1625 &dev->alloc_device)) { 1626 ALOGE("failed to open gralloc"); 1627 ret = -EINVAL; 1628 goto err_get_module; 1629 } 1630 1631 dev->fd = open("/dev/graphics/fb0", O_RDWR); 1632 if (dev->fd < 0) { 1633 ALOGE("failed to open framebuffer"); 1634 ret = dev->fd; 1635 goto err_open_fb; 1636 } 1637 1638 dev->hdmi_mixer0 = open("/dev/v4l-subdev7", O_RDWR); 1639 if (dev->hdmi_layer0 < 0) { 1640 ALOGE("failed to open hdmi mixer0 subdev"); 1641 ret = dev->hdmi_layer0; 1642 goto err_ioctl; 1643 } 1644 1645 dev->hdmi_layer0 = open("/dev/video16", O_RDWR); 1646 if (dev->hdmi_layer0 < 0) { 1647 ALOGE("failed to open hdmi layer0 device"); 1648 ret = dev->hdmi_layer0; 1649 goto err_mixer0; 1650 } 1651 1652 dev->hdmi_layer1 = open("/dev/video17", O_RDWR); 1653 if (dev->hdmi_layer1 < 0) { 1654 ALOGE("failed to open hdmi layer1 device"); 1655 ret = dev->hdmi_layer1; 1656 goto err_hdmi0; 1657 } 1658 1659 dev->vsync_fd = open("/sys/devices/platform/exynos5-fb.1/vsync", O_RDONLY); 1660 if (dev->vsync_fd < 0) { 1661 ALOGE("failed to open vsync attribute"); 1662 ret = dev->vsync_fd; 1663 goto err_hdmi1; 1664 } 1665 1666 sw_fd = open("/sys/class/switch/hdmi/state", O_RDONLY); 1667 if (sw_fd) { 1668 char val; 1669 if (read(sw_fd, &val, 1) == 1 && val == '1') { 1670 dev->hdmi_hpd = true; 1671 if (hdmi_get_config(dev)) { 1672 ALOGE("Error reading HDMI configuration"); 1673 dev->hdmi_hpd = false; 1674 } 1675 } 1676 } 1677 1678 dev->base.common.tag = HARDWARE_DEVICE_TAG; 1679 dev->base.common.version = HWC_DEVICE_API_VERSION_1_0; 1680 dev->base.common.module = const_cast<hw_module_t *>(module); 1681 dev->base.common.close = exynos5_close; 1682 1683 dev->base.prepare = exynos5_prepare; 1684 dev->base.set = exynos5_set; 1685 dev->base.eventControl = exynos5_eventControl; 1686 dev->base.blank = exynos5_blank; 1687 dev->base.query = exynos5_query; 1688 dev->base.registerProcs = exynos5_registerProcs; 1689 dev->base.dump = exynos5_dump; 1690 1691 dev->bufs.pdev = dev; 1692 1693 *device = &dev->base.common; 1694 1695 ret = pthread_create(&dev->vsync_thread, NULL, hwc_vsync_thread, dev); 1696 if (ret) { 1697 ALOGE("failed to start vsync thread: %s", strerror(ret)); 1698 ret = -ret; 1699 goto err_vsync; 1700 } 1701 1702 return 0; 1703 1704err_vsync: 1705 close(dev->vsync_fd); 1706err_mixer0: 1707 close(dev->hdmi_mixer0); 1708err_hdmi1: 1709 close(dev->hdmi_layer0); 1710err_hdmi0: 1711 close(dev->hdmi_layer1); 1712err_ioctl: 1713 close(dev->fd); 1714err_open_fb: 1715 gralloc_close(dev->alloc_device); 1716err_get_module: 1717 free(dev); 1718 return ret; 1719} 1720 1721static int exynos5_close(hw_device_t *device) 1722{ 1723 struct exynos5_hwc_composer_device_1_t *dev = 1724 (struct exynos5_hwc_composer_device_1_t *)device; 1725 pthread_kill(dev->vsync_thread, SIGTERM); 1726 pthread_join(dev->vsync_thread, NULL); 1727 for (size_t i = 0; i < NUM_GSC_UNITS; i++) { 1728 if (dev->gsc[i].gsc) 1729 exynos_gsc_destroy(dev->gsc[i].gsc); 1730 for (size_t j = 0; i < NUM_GSC_DST_BUFS; j++) 1731 if (dev->gsc[i].dst_buf[j]) 1732 dev->alloc_device->free(dev->alloc_device, dev->gsc[i].dst_buf[j]); 1733 } 1734 gralloc_close(dev->alloc_device); 1735 close(dev->vsync_fd); 1736 close(dev->hdmi_mixer0); 1737 close(dev->hdmi_layer0); 1738 close(dev->hdmi_layer1); 1739 close(dev->fd); 1740 return 0; 1741} 1742 1743static struct hw_module_methods_t exynos5_hwc_module_methods = { 1744 open: exynos5_open, 1745}; 1746 1747hwc_module_t HAL_MODULE_INFO_SYM = { 1748 common: { 1749 tag: HARDWARE_MODULE_TAG, 1750 module_api_version: HWC_MODULE_API_VERSION_0_1, 1751 hal_api_version: HARDWARE_HAL_API_VERSION, 1752 id: HWC_HARDWARE_MODULE_ID, 1753 name: "Samsung exynos5 hwcomposer module", 1754 author: "Google", 1755 methods: &exynos5_hwc_module_methods, 1756 } 1757}; 1758