1 /* 2 * Copyright (C) 2016 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 17 // Versions of hwcomposer we implement: 18 // JB: 0.3 19 // JB-MR1 to N : 1.1 20 // N-MR1 to ... : We report 1.1 but SurfaceFlinger has the option to use an 21 // adapter to treat our 1.1 hwcomposer as a 2.0. If SF stops using that adapter 22 // to support 1.1 implementations it can be copied into cuttlefish from 23 // frameworks/native/services/surfaceflinger/DisplayHardware/HWC2On1Adapter.* 24 25 #define LOG_TAG "hwc.cf_x86" 26 27 #include <guest/libs/platform_support/api_level_fixes.h> 28 29 #include <errno.h> 30 #include <fcntl.h> 31 #include <math.h> 32 #include <poll.h> 33 #include <pthread.h> 34 #include <stdio.h> 35 #include <stdlib.h> 36 37 #include <sys/ioctl.h> 38 #include <sys/mman.h> 39 #include <sys/resource.h> 40 #include <sys/time.h> 41 42 #include <string> 43 44 #define HWC_REMOVE_DEPRECATED_VERSIONS 1 45 46 #include <cutils/compiler.h> 47 #include <cutils/log.h> 48 #include <cutils/properties.h> 49 #include <hardware/gralloc.h> 50 #include <hardware/hardware.h> 51 #include <hardware/hwcomposer.h> 52 #include <hardware/hwcomposer_defs.h> 53 #include <utils/String8.h> 54 #include <utils/Vector.h> 55 56 #include "common/vsoc/lib/screen_region_view.h" 57 #include "guest/hals/gralloc/legacy/gralloc_vsoc_priv.h" 58 #include <sync/sync.h> 59 60 #include "base_composer.h" 61 #include "geometry_utils.h" 62 #include "hwcomposer_common.h" 63 #include "stats_keeper.h" 64 #include "vsoc_composer.h" 65 66 using vsoc::screen::ScreenRegionView; 67 68 #ifdef USE_OLD_HWCOMPOSER 69 typedef cvd::BaseComposer InnerComposerType; 70 #else 71 typedef cvd::VSoCComposer InnerComposerType; 72 #endif 73 74 #ifdef GATHER_STATS 75 typedef cvd::StatsKeepingComposer<InnerComposerType> ComposerType; 76 #else 77 typedef InnerComposerType ComposerType; 78 #endif 79 80 struct vsoc_hwc_composer_device_1_t { 81 vsoc_hwc_device base; 82 const hwc_procs_t* procs; 83 pthread_t vsync_thread; 84 int64_t vsync_base_timestamp; 85 int32_t vsync_period_ns; 86 ComposerType* composer; 87 }; 88 89 namespace { 90 91 std::string CompositionString(int type) { 92 switch (type) { 93 case HWC_FRAMEBUFFER: 94 return "Framebuffer"; 95 case HWC_OVERLAY: 96 return "Overlay"; 97 case HWC_BACKGROUND: 98 return "Background"; 99 case HWC_FRAMEBUFFER_TARGET: 100 return "FramebufferTarget"; 101 #if VSOC_PLATFORM_SDK_AFTER(K) 102 case HWC_SIDEBAND: 103 return "Sideband"; 104 case HWC_CURSOR_OVERLAY: 105 return "CursorOverlay"; 106 #endif 107 default: 108 return std::string("Unknown (") + std::to_string(type) + ")"; 109 } 110 } 111 112 void LogLayers(int num_layers, vsoc_hwc_layer* layers, int invalid) { 113 ALOGE("Layers:"); 114 for (int idx = 0; idx < num_layers; ++idx) { 115 std::string log_line; 116 if (idx == invalid) { 117 log_line = "Invalid layer: "; 118 } 119 log_line += 120 "Composition Type: " + CompositionString(layers[idx].compositionType); 121 ALOGE("%s", log_line.c_str()); 122 } 123 } 124 125 // Ensures that the layer does not include any inconsistencies 126 bool IsValidLayer(const vsoc_hwc_layer& layer) { 127 if (layer.flags & HWC_SKIP_LAYER) { 128 // A layer we are asked to skip validate should not be marked as skip 129 ALOGE("%s: Layer is marked as skip", __FUNCTION__); 130 return false; 131 } 132 // Check displayFrame 133 if (layer.displayFrame.left > layer.displayFrame.right || 134 layer.displayFrame.top > layer.displayFrame.bottom) { 135 ALOGE( 136 "%s: Malformed rectangle (displayFrame): [left = %d, right = %d, top = " 137 "%d, bottom = %d]", 138 __FUNCTION__, layer.displayFrame.left, layer.displayFrame.right, 139 layer.displayFrame.top, layer.displayFrame.bottom); 140 return false; 141 } 142 // Validate the handle 143 if (private_handle_t::validate(layer.handle) != 0) { 144 ALOGE("%s: Layer contains an invalid gralloc handle.", __FUNCTION__); 145 return false; 146 } 147 const private_handle_t* p_handle = 148 reinterpret_cast<const private_handle_t*>(layer.handle); 149 // Check sourceCrop 150 if (layer.sourceCrop.left > layer.sourceCrop.right || 151 layer.sourceCrop.top > layer.sourceCrop.bottom) { 152 ALOGE( 153 "%s: Malformed rectangle (sourceCrop): [left = %d, right = %d, top = " 154 "%d, bottom = %d]", 155 __FUNCTION__, layer.sourceCrop.left, layer.sourceCrop.right, 156 layer.sourceCrop.top, layer.sourceCrop.bottom); 157 return false; 158 } 159 if (layer.sourceCrop.left < 0 || layer.sourceCrop.top < 0 || 160 layer.sourceCrop.right > p_handle->x_res || 161 layer.sourceCrop.bottom > p_handle->y_res) { 162 ALOGE( 163 "%s: Invalid sourceCrop for buffer handle: sourceCrop = [left = %d, " 164 "right = %d, top = %d, bottom = %d], handle = [width = %d, height = " 165 "%d]", 166 __FUNCTION__, layer.sourceCrop.left, layer.sourceCrop.right, 167 layer.sourceCrop.top, layer.sourceCrop.bottom, p_handle->x_res, 168 p_handle->y_res); 169 return false; 170 } 171 return true; 172 } 173 174 bool IsValidComposition(int num_layers, vsoc_hwc_layer* layers, bool on_set) { 175 if (num_layers == 0) { 176 ALOGE("Composition requested with 0 layers"); 177 return false; 178 } 179 // Sometimes the hwcomposer receives a prepare and set calls with no other 180 // layer than the FRAMEBUFFER_TARGET with a null handler. We treat this case 181 // independently as a valid composition, but issue a warning about it. 182 if (num_layers == 1 && layers[0].compositionType == HWC_FRAMEBUFFER_TARGET && 183 layers[0].handle == NULL) { 184 ALOGW("Received request for empty composition, treating as valid noop"); 185 return true; 186 } 187 // The FRAMEBUFFER_TARGET layer needs to be sane only if 188 // there is at least one layer marked HWC_FRAMEBUFFER or if there is no layer 189 // marked HWC_OVERLAY (i.e some layers where composed with OpenGL, no layer 190 // marked overlay or framebuffer means that surfaceflinger decided to go for 191 // OpenGL without asking the hwcomposer first) 192 bool check_fb_target = true; 193 for (int idx = 0; idx < num_layers; ++idx) { 194 if (layers[idx].compositionType == HWC_FRAMEBUFFER) { 195 // There is at least one, so it needs to be checked. 196 // It may have been set to false before, so ensure it's set to true. 197 check_fb_target = true; 198 break; 199 } 200 if (layers[idx].compositionType == HWC_OVERLAY) { 201 // At least one overlay, we may not need to. 202 check_fb_target = false; 203 } 204 } 205 206 for (int idx = 0; idx < num_layers; ++idx) { 207 switch (layers[idx].compositionType) { 208 case HWC_FRAMEBUFFER_TARGET: 209 // In the call to prepare() the framebuffer target does not have a valid 210 // buffer_handle, so we don't validate it yet. 211 if (on_set && check_fb_target && !IsValidLayer(layers[idx])) { 212 ALOGE("%s: Invalid layer found", __FUNCTION__); 213 LogLayers(num_layers, layers, idx); 214 return false; 215 } 216 break; 217 case HWC_OVERLAY: 218 if (!(layers[idx].flags & HWC_SKIP_LAYER) && 219 !IsValidLayer(layers[idx])) { 220 ALOGE("%s: Invalid layer found", __FUNCTION__); 221 LogLayers(num_layers, layers, idx); 222 return false; 223 } 224 break; 225 } 226 } 227 return true; 228 } 229 230 } 231 232 #if VSOC_PLATFORM_SDK_BEFORE(J_MR1) 233 static int vsoc_hwc_prepare(vsoc_hwc_device* dev, hwc_layer_list_t* list) { 234 #else 235 static int vsoc_hwc_prepare(vsoc_hwc_device* dev, size_t numDisplays, 236 hwc_display_contents_1_t** displays) { 237 if (!numDisplays || !displays) return 0; 238 239 hwc_display_contents_1_t* list = displays[HWC_DISPLAY_PRIMARY]; 240 241 if (!list) return 0; 242 #endif 243 if (!IsValidComposition(list->numHwLayers, &list->hwLayers[0], false)) { 244 LOG_ALWAYS_FATAL("%s: Invalid composition requested", __FUNCTION__); 245 return -1; 246 } 247 reinterpret_cast<vsoc_hwc_composer_device_1_t*>(dev)->composer->PrepareLayers( 248 list->numHwLayers, &list->hwLayers[0]); 249 return 0; 250 } 251 252 #if VSOC_PLATFORM_SDK_BEFORE(J_MR1) 253 int vsoc_hwc_set(struct hwc_composer_device* dev, hwc_display_t dpy, 254 hwc_surface_t sur, hwc_layer_list_t* list) { 255 if (list->numHwLayers == 1 && 256 layers[0].compositionType == HWC_FRAMEBUFFER_TARGET) { 257 ALOGW("Received request for empty composition, treating as valid noop"); 258 return 0; 259 } 260 if (!IsValidComposition(list->numHwLayers, &list->hwLayers[0], true)) { 261 LOG_ALWAYS_FATAL("%s: Invalid composition requested", __FUNCTION__); 262 return -1; 263 } 264 return reinterpret_cast<vsoc_hwc_composer_device_1_t*>(dev) 265 ->composer->SetLayers(list->numHwLayers, &list->hwLayers[0]); 266 } 267 #else 268 static int vsoc_hwc_set(vsoc_hwc_device* dev, size_t numDisplays, 269 hwc_display_contents_1_t** displays) { 270 if (!numDisplays || !displays) return 0; 271 272 hwc_display_contents_1_t* contents = displays[HWC_DISPLAY_PRIMARY]; 273 if (!contents) return 0; 274 275 vsoc_hwc_layer* layers = &contents->hwLayers[0]; 276 if (contents->numHwLayers == 1 && 277 layers[0].compositionType == HWC_FRAMEBUFFER_TARGET) { 278 ALOGW("Received request for empty composition, treating as valid noop"); 279 return 0; 280 } 281 if (!IsValidComposition(contents->numHwLayers, layers, true)) { 282 LOG_ALWAYS_FATAL("%s: Invalid composition requested", __FUNCTION__); 283 return -1; 284 } 285 int retval = 286 reinterpret_cast<vsoc_hwc_composer_device_1_t*>(dev)->composer->SetLayers( 287 contents->numHwLayers, layers); 288 289 int closedFds = 0; 290 for (size_t index = 0; index < contents->numHwLayers; ++index) { 291 if (layers[index].acquireFenceFd != -1) { 292 close(layers[index].acquireFenceFd); 293 layers[index].acquireFenceFd = -1; 294 ++closedFds; 295 } 296 } 297 if (closedFds) { 298 ALOGI("Saw %zu layers, closed=%d", contents->numHwLayers, closedFds); 299 } 300 301 // TODO(ghartman): This should be set before returning. On the next set it 302 // should be signalled when we load the new frame. 303 contents->retireFenceFd = -1; 304 return retval; 305 } 306 #endif 307 308 static void vsoc_hwc_register_procs(vsoc_hwc_device* dev, 309 const hwc_procs_t* procs) { 310 struct vsoc_hwc_composer_device_1_t* pdev = 311 (struct vsoc_hwc_composer_device_1_t*)dev; 312 pdev->procs = procs; 313 } 314 315 static int vsoc_hwc_query(vsoc_hwc_device* dev, int what, int* value) { 316 struct vsoc_hwc_composer_device_1_t* pdev = 317 (struct vsoc_hwc_composer_device_1_t*)dev; 318 319 switch (what) { 320 case HWC_BACKGROUND_LAYER_SUPPORTED: 321 // we support the background layer 322 value[0] = 0; 323 break; 324 case HWC_VSYNC_PERIOD: 325 value[0] = pdev->vsync_period_ns; 326 break; 327 default: 328 // unsupported query 329 ALOGE("%s badness unsupported query what=%d", __FUNCTION__, what); 330 return -EINVAL; 331 } 332 return 0; 333 } 334 335 static int vsoc_hwc_event_control( 336 #if VSOC_PLATFORM_SDK_BEFORE(J_MR1) 337 vsoc_hwc_device* /*dev*/, int event, int /*enabled*/) { 338 #else 339 vsoc_hwc_device* /*dev*/, int /*dpy*/, int event, int /*enabled*/) { 340 #endif 341 342 if (event == HWC_EVENT_VSYNC) { 343 return 0; 344 } 345 return -EINVAL; 346 } 347 348 static void* hwc_vsync_thread(void* data) { 349 struct vsoc_hwc_composer_device_1_t* pdev = 350 (struct vsoc_hwc_composer_device_1_t*)data; 351 setpriority(PRIO_PROCESS, 0, HAL_PRIORITY_URGENT_DISPLAY); 352 353 int64_t base_timestamp = pdev->vsync_base_timestamp; 354 int64_t last_logged = base_timestamp / 1e9; 355 int sent = 0; 356 int last_sent = 0; 357 static const int log_interval = 60; 358 void (*vsync_proc)(const struct hwc_procs*, int, int64_t) = nullptr; 359 bool log_no_procs = true, log_no_vsync = true; 360 while (true) { 361 struct timespec rt; 362 if (clock_gettime(CLOCK_MONOTONIC, &rt) == -1) { 363 ALOGE("%s:%d error in vsync thread clock_gettime: %s", __FILE__, __LINE__, 364 strerror(errno)); 365 } 366 int64_t timestamp = int64_t(rt.tv_sec) * 1e9 + rt.tv_nsec; 367 // Given now's timestamp calculate the time of the next timestamp. 368 timestamp += pdev->vsync_period_ns - 369 (timestamp - base_timestamp) % pdev->vsync_period_ns; 370 371 rt.tv_sec = timestamp / 1e9; 372 rt.tv_nsec = timestamp % static_cast<int32_t>(1e9); 373 int err = clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &rt, NULL); 374 if (err == -1) { 375 ALOGE("error in vsync thread: %s", strerror(errno)); 376 if (errno == EINTR) { 377 continue; 378 } 379 } 380 381 // The vsync thread is started on device open, it may run before the 382 // registerProcs callback has a chance to be called, so we need to make sure 383 // procs is not NULL before dereferencing it. 384 if (pdev && pdev->procs) { 385 vsync_proc = pdev->procs->vsync; 386 } else if (log_no_procs) { 387 log_no_procs = false; 388 ALOGI("procs is not set yet, unable to deliver vsync event"); 389 } 390 if (vsync_proc) { 391 vsync_proc(const_cast<hwc_procs_t*>(pdev->procs), 0, timestamp); 392 ++sent; 393 } else if (log_no_vsync) { 394 log_no_vsync = false; 395 ALOGE("vsync callback is null (but procs was already set)"); 396 } 397 if (rt.tv_sec - last_logged > log_interval) { 398 ALOGI("Sent %d syncs in %ds", sent - last_sent, log_interval); 399 last_logged = rt.tv_sec; 400 last_sent = sent; 401 } 402 } 403 404 return NULL; 405 } 406 407 static int vsoc_hwc_blank(vsoc_hwc_device* /*dev*/, int disp, int /*blank*/) { 408 if (!IS_PRIMARY_DISPLAY(disp)) return -EINVAL; 409 return 0; 410 } 411 412 static void vsoc_hwc_dump(vsoc_hwc_device* dev, char* buff, int buff_len) { 413 reinterpret_cast<vsoc_hwc_composer_device_1_t*>(dev)->composer->Dump( 414 buff, buff_len); 415 } 416 417 static int vsoc_hwc_get_display_configs(vsoc_hwc_device* /*dev*/, int disp, 418 uint32_t* configs, size_t* numConfigs) { 419 if (*numConfigs == 0) return 0; 420 421 if (IS_PRIMARY_DISPLAY(disp)) { 422 configs[0] = 0; 423 *numConfigs = 1; 424 return 0; 425 } 426 427 return -EINVAL; 428 } 429 430 #if VSOC_PLATFORM_SDK_AFTER(J) 431 static int32_t vsoc_hwc_attribute(struct vsoc_hwc_composer_device_1_t* pdev, 432 const uint32_t attribute) { 433 auto screen_view = ScreenRegionView::GetInstance(); 434 switch (attribute) { 435 case HWC_DISPLAY_VSYNC_PERIOD: 436 return pdev->vsync_period_ns; 437 case HWC_DISPLAY_WIDTH: 438 return screen_view->x_res(); 439 case HWC_DISPLAY_HEIGHT: 440 return screen_view->y_res(); 441 case HWC_DISPLAY_DPI_X: 442 ALOGI("Reporting DPI_X of %d", screen_view->dpi()); 443 // The number of pixels per thousand inches 444 return screen_view->dpi() * 1000; 445 case HWC_DISPLAY_DPI_Y: 446 ALOGI("Reporting DPI_Y of %d", screen_view->dpi()); 447 // The number of pixels per thousand inches 448 return screen_view->dpi() * 1000; 449 default: 450 ALOGE("unknown display attribute %u", attribute); 451 return -EINVAL; 452 } 453 } 454 455 static int vsoc_hwc_get_display_attributes(vsoc_hwc_device* dev, int disp, 456 uint32_t config __unused, 457 const uint32_t* attributes, 458 int32_t* values) { 459 struct vsoc_hwc_composer_device_1_t* pdev = 460 (struct vsoc_hwc_composer_device_1_t*)dev; 461 462 if (!IS_PRIMARY_DISPLAY(disp)) { 463 ALOGE("unknown display type %u", disp); 464 return -EINVAL; 465 } 466 467 for (int i = 0; attributes[i] != HWC_DISPLAY_NO_ATTRIBUTE; i++) { 468 values[i] = vsoc_hwc_attribute(pdev, attributes[i]); 469 } 470 471 return 0; 472 } 473 #endif 474 475 static int vsoc_hwc_close(hw_device_t* device) { 476 struct vsoc_hwc_composer_device_1_t* dev = 477 (struct vsoc_hwc_composer_device_1_t*)device; 478 ALOGE("vsoc_hwc_close"); 479 pthread_kill(dev->vsync_thread, SIGTERM); 480 pthread_join(dev->vsync_thread, NULL); 481 delete dev->composer; 482 delete dev; 483 return 0; 484 } 485 486 static int vsoc_hwc_open(const struct hw_module_t* module, const char* name, 487 struct hw_device_t** device) { 488 ALOGI("%s", __FUNCTION__); 489 if (strcmp(name, HWC_HARDWARE_COMPOSER)) { 490 ALOGE("%s called with bad name %s", __FUNCTION__, name); 491 return -EINVAL; 492 } 493 494 vsoc_hwc_composer_device_1_t* dev = new vsoc_hwc_composer_device_1_t(); 495 if (!dev) { 496 ALOGE("%s failed to allocate dev", __FUNCTION__); 497 return -ENOMEM; 498 } 499 500 int refreshRate = ScreenRegionView::GetInstance()->refresh_rate_hz(); 501 dev->vsync_period_ns = 1000000000 / refreshRate; 502 struct timespec rt; 503 if (clock_gettime(CLOCK_MONOTONIC, &rt) == -1) { 504 ALOGE("%s:%d error in vsync thread clock_gettime: %s", __FILE__, __LINE__, 505 strerror(errno)); 506 } 507 dev->vsync_base_timestamp = int64_t(rt.tv_sec) * 1e9 + rt.tv_nsec; 508 509 dev->base.common.tag = HARDWARE_DEVICE_TAG; 510 dev->base.common.version = VSOC_HWC_DEVICE_API_VERSION; 511 dev->base.common.module = const_cast<hw_module_t*>(module); 512 dev->base.common.close = vsoc_hwc_close; 513 514 dev->base.prepare = vsoc_hwc_prepare; 515 dev->base.set = vsoc_hwc_set; 516 dev->base.query = vsoc_hwc_query; 517 dev->base.registerProcs = vsoc_hwc_register_procs; 518 dev->base.dump = vsoc_hwc_dump; 519 #if VSOC_PLATFORM_SDK_BEFORE(J_MR1) 520 static hwc_methods_t hwc_methods = {vsoc_hwc_event_control}; 521 dev->base.methods = &hwc_methods; 522 #else 523 dev->base.blank = vsoc_hwc_blank; 524 dev->base.eventControl = vsoc_hwc_event_control; 525 dev->base.getDisplayConfigs = vsoc_hwc_get_display_configs; 526 dev->base.getDisplayAttributes = vsoc_hwc_get_display_attributes; 527 #endif 528 dev->composer = 529 new ComposerType(dev->vsync_base_timestamp, dev->vsync_period_ns); 530 531 int ret = pthread_create(&dev->vsync_thread, NULL, hwc_vsync_thread, dev); 532 if (ret) { 533 ALOGE("failed to start vsync thread: %s", strerror(ret)); 534 ret = -ret; 535 delete dev; 536 } else { 537 *device = &dev->base.common; 538 } 539 540 return ret; 541 } 542 543 static struct hw_module_methods_t vsoc_hwc_module_methods = { 544 vsoc_hwc_open, 545 }; 546 547 hwc_module_t HAL_MODULE_INFO_SYM = {{HARDWARE_MODULE_TAG, 548 HWC_MODULE_API_VERSION_0_1, 549 HARDWARE_HAL_API_VERSION, 550 HWC_HARDWARE_MODULE_ID, 551 "VSOC hwcomposer module", 552 "Google", 553 &vsoc_hwc_module_methods, 554 NULL, 555 {0}}}; 556