1 /* 2 * Copyright 2017 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 #define LOG_TAG "HWC2OnFbAdapter" 18 19 //#define LOG_NDEBUG 0 20 21 #include "hwc2onfbadapter/HWC2OnFbAdapter.h" 22 23 #include <algorithm> 24 #include <type_traits> 25 26 #include <inttypes.h> 27 #include <time.h> 28 #include <sys/prctl.h> 29 #include <unistd.h> // for close 30 31 #include <hardware/fb.h> 32 #include <log/log.h> 33 #include <sync/sync.h> 34 35 using namespace HWC2; 36 37 namespace android { 38 39 namespace { 40 41 void dumpHook(hwc2_device_t* device, uint32_t* outSize, char* outBuffer) { 42 auto& adapter = HWC2OnFbAdapter::cast(device); 43 if (outBuffer) { 44 *outSize = adapter.getDebugString().copy(outBuffer, *outSize); 45 } else { 46 adapter.updateDebugString(); 47 *outSize = adapter.getDebugString().size(); 48 } 49 } 50 51 int32_t registerCallbackHook(hwc2_device_t* device, int32_t descriptor, 52 hwc2_callback_data_t callbackData, hwc2_function_pointer_t pointer) { 53 auto& adapter = HWC2OnFbAdapter::cast(device); 54 switch (descriptor) { 55 case HWC2_CALLBACK_HOTPLUG: 56 if (pointer) { 57 reinterpret_cast<HWC2_PFN_HOTPLUG>(pointer)(callbackData, adapter.getDisplayId(), 58 HWC2_CONNECTION_CONNECTED); 59 } 60 break; 61 case HWC2_CALLBACK_REFRESH: 62 break; 63 case HWC2_CALLBACK_VSYNC: 64 adapter.setVsyncCallback(reinterpret_cast<HWC2_PFN_VSYNC>(pointer), callbackData); 65 break; 66 default: 67 return HWC2_ERROR_BAD_PARAMETER; 68 } 69 70 return HWC2_ERROR_NONE; 71 } 72 73 uint32_t getMaxVirtualDisplayCountHook(hwc2_device_t* /*device*/) { 74 return 0; 75 } 76 77 int32_t createVirtualDisplayHook(hwc2_device_t* /*device*/, uint32_t /*width*/, uint32_t /*height*/, 78 int32_t* /*format*/, hwc2_display_t* /*outDisplay*/) { 79 return HWC2_ERROR_NO_RESOURCES; 80 } 81 82 int32_t destroyVirtualDisplayHook(hwc2_device_t* /*device*/, hwc2_display_t /*display*/) { 83 return HWC2_ERROR_BAD_DISPLAY; 84 } 85 86 int32_t setOutputBufferHook(hwc2_device_t* /*device*/, hwc2_display_t /*display*/, 87 buffer_handle_t /*buffer*/, int32_t /*releaseFence*/) { 88 return HWC2_ERROR_BAD_DISPLAY; 89 } 90 91 int32_t getDisplayNameHook(hwc2_device_t* device, hwc2_display_t display, uint32_t* outSize, 92 char* outName) { 93 auto& adapter = HWC2OnFbAdapter::cast(device); 94 if (adapter.getDisplayId() != display) { 95 return HWC2_ERROR_BAD_DISPLAY; 96 } 97 98 const auto& info = adapter.getInfo(); 99 if (outName) { 100 *outSize = info.name.copy(outName, *outSize); 101 } else { 102 *outSize = info.name.size(); 103 } 104 105 return HWC2_ERROR_NONE; 106 } 107 108 int32_t getDisplayTypeHook(hwc2_device_t* device, hwc2_display_t display, int32_t* outType) { 109 auto& adapter = HWC2OnFbAdapter::cast(device); 110 if (adapter.getDisplayId() != display) { 111 return HWC2_ERROR_BAD_DISPLAY; 112 } 113 114 *outType = HWC2_DISPLAY_TYPE_PHYSICAL; 115 return HWC2_ERROR_NONE; 116 } 117 118 int32_t getDozeSupportHook(hwc2_device_t* device, hwc2_display_t display, int32_t* outSupport) { 119 auto& adapter = HWC2OnFbAdapter::cast(device); 120 if (adapter.getDisplayId() != display) { 121 return HWC2_ERROR_BAD_DISPLAY; 122 } 123 124 *outSupport = 0; 125 return HWC2_ERROR_NONE; 126 } 127 128 int32_t getHdrCapabilitiesHook(hwc2_device_t* device, hwc2_display_t display, uint32_t* outNumTypes, 129 int32_t* /*outTypes*/, float* /*outMaxLuminance*/, 130 float* /*outMaxAverageLuminance*/, float* /*outMinLuminance*/) { 131 auto& adapter = HWC2OnFbAdapter::cast(device); 132 if (adapter.getDisplayId() != display) { 133 return HWC2_ERROR_BAD_DISPLAY; 134 } 135 136 *outNumTypes = 0; 137 return HWC2_ERROR_NONE; 138 } 139 140 int32_t setPowerModeHook(hwc2_device_t* device, hwc2_display_t display, int32_t /*mode*/) { 141 auto& adapter = HWC2OnFbAdapter::cast(device); 142 if (adapter.getDisplayId() != display) { 143 return HWC2_ERROR_BAD_DISPLAY; 144 } 145 146 // pretend that it works 147 return HWC2_ERROR_NONE; 148 } 149 150 int32_t setVsyncEnabledHook(hwc2_device_t* device, hwc2_display_t display, int32_t enabled) { 151 auto& adapter = HWC2OnFbAdapter::cast(device); 152 if (adapter.getDisplayId() != display) { 153 return HWC2_ERROR_BAD_DISPLAY; 154 } 155 156 adapter.enableVsync(enabled == HWC2_VSYNC_ENABLE); 157 return HWC2_ERROR_NONE; 158 } 159 160 int32_t getColorModesHook(hwc2_device_t* device, hwc2_display_t display, uint32_t* outNumModes, 161 int32_t* outModes) { 162 auto& adapter = HWC2OnFbAdapter::cast(device); 163 if (adapter.getDisplayId() != display) { 164 return HWC2_ERROR_BAD_DISPLAY; 165 } 166 167 if (outModes) { 168 if (*outNumModes > 0) { 169 outModes[0] = HAL_COLOR_MODE_NATIVE; 170 *outNumModes = 1; 171 } 172 } else { 173 *outNumModes = 1; 174 } 175 176 return HWC2_ERROR_NONE; 177 } 178 179 int32_t setColorModeHook(hwc2_device_t* device, hwc2_display_t display, int32_t mode) { 180 auto& adapter = HWC2OnFbAdapter::cast(device); 181 if (adapter.getDisplayId() != display) { 182 return HWC2_ERROR_BAD_DISPLAY; 183 } 184 if (mode != HAL_COLOR_MODE_NATIVE) { 185 return HWC2_ERROR_BAD_PARAMETER; 186 } 187 188 return HWC2_ERROR_NONE; 189 } 190 191 int32_t setColorTransformHook(hwc2_device_t* device, hwc2_display_t display, 192 const float* /*matrix*/, int32_t /*hint*/) { 193 auto& adapter = HWC2OnFbAdapter::cast(device); 194 if (adapter.getDisplayId() != display) { 195 return HWC2_ERROR_BAD_DISPLAY; 196 } 197 198 // we always force client composition 199 adapter.setState(HWC2OnFbAdapter::State::MODIFIED); 200 return HWC2_ERROR_NONE; 201 } 202 203 int32_t getClientTargetSupportHook(hwc2_device_t* device, hwc2_display_t display, uint32_t width, 204 uint32_t height, int32_t format, int32_t dataspace) { 205 auto& adapter = HWC2OnFbAdapter::cast(device); 206 if (adapter.getDisplayId() != display) { 207 return HWC2_ERROR_BAD_DISPLAY; 208 } 209 if (dataspace != HAL_DATASPACE_UNKNOWN) { 210 return HWC2_ERROR_UNSUPPORTED; 211 } 212 213 const auto& info = adapter.getInfo(); 214 return (info.width == width && info.height == height && info.format == format) 215 ? HWC2_ERROR_NONE 216 : HWC2_ERROR_UNSUPPORTED; 217 } 218 219 int32_t setClientTargetHook(hwc2_device_t* device, hwc2_display_t display, buffer_handle_t target, 220 int32_t acquireFence, int32_t dataspace, hwc_region_t /*damage*/) { 221 if (acquireFence >= 0) { 222 sync_wait(acquireFence, -1); 223 close(acquireFence); 224 } 225 226 auto& adapter = HWC2OnFbAdapter::cast(device); 227 if (adapter.getDisplayId() != display) { 228 return HWC2_ERROR_BAD_DISPLAY; 229 } 230 if (dataspace != HAL_DATASPACE_UNKNOWN) { 231 return HWC2_ERROR_BAD_PARAMETER; 232 } 233 234 // no state change 235 adapter.setBuffer(target); 236 return HWC2_ERROR_NONE; 237 } 238 239 int32_t getDisplayConfigsHook(hwc2_device_t* device, hwc2_display_t display, 240 uint32_t* outNumConfigs, hwc2_config_t* outConfigs) { 241 auto& adapter = HWC2OnFbAdapter::cast(device); 242 if (adapter.getDisplayId() != display) { 243 return HWC2_ERROR_BAD_DISPLAY; 244 } 245 246 if (outConfigs) { 247 if (*outNumConfigs > 0) { 248 outConfigs[0] = adapter.getConfigId(); 249 *outNumConfigs = 1; 250 } 251 } else { 252 *outNumConfigs = 1; 253 } 254 255 return HWC2_ERROR_NONE; 256 } 257 258 int32_t getDisplayAttributeHook(hwc2_device_t* device, hwc2_display_t display, hwc2_config_t config, 259 int32_t attribute, int32_t* outValue) { 260 auto& adapter = HWC2OnFbAdapter::cast(device); 261 if (adapter.getDisplayId() != display) { 262 return HWC2_ERROR_BAD_DISPLAY; 263 } 264 if (adapter.getConfigId() != config) { 265 return HWC2_ERROR_BAD_CONFIG; 266 } 267 268 const auto& info = adapter.getInfo(); 269 switch (attribute) { 270 case HWC2_ATTRIBUTE_WIDTH: 271 *outValue = int32_t(info.width); 272 break; 273 case HWC2_ATTRIBUTE_HEIGHT: 274 *outValue = int32_t(info.height); 275 break; 276 case HWC2_ATTRIBUTE_VSYNC_PERIOD: 277 *outValue = int32_t(info.vsync_period_ns); 278 break; 279 case HWC2_ATTRIBUTE_DPI_X: 280 *outValue = int32_t(info.xdpi_scaled); 281 break; 282 case HWC2_ATTRIBUTE_DPI_Y: 283 *outValue = int32_t(info.ydpi_scaled); 284 break; 285 default: 286 return HWC2_ERROR_BAD_PARAMETER; 287 } 288 289 return HWC2_ERROR_NONE; 290 } 291 292 int32_t getActiveConfigHook(hwc2_device_t* device, hwc2_display_t display, 293 hwc2_config_t* outConfig) { 294 auto& adapter = HWC2OnFbAdapter::cast(device); 295 if (adapter.getDisplayId() != display) { 296 return HWC2_ERROR_BAD_DISPLAY; 297 } 298 299 *outConfig = adapter.getConfigId(); 300 return HWC2_ERROR_NONE; 301 } 302 303 int32_t setActiveConfigHook(hwc2_device_t* device, hwc2_display_t display, hwc2_config_t config) { 304 auto& adapter = HWC2OnFbAdapter::cast(device); 305 if (adapter.getDisplayId() != display) { 306 return HWC2_ERROR_BAD_DISPLAY; 307 } 308 if (adapter.getConfigId() != config) { 309 return HWC2_ERROR_BAD_CONFIG; 310 } 311 312 return HWC2_ERROR_NONE; 313 } 314 315 int32_t validateDisplayHook(hwc2_device_t* device, hwc2_display_t display, uint32_t* outNumTypes, 316 uint32_t* outNumRequests) { 317 auto& adapter = HWC2OnFbAdapter::cast(device); 318 if (adapter.getDisplayId() != display) { 319 return HWC2_ERROR_BAD_DISPLAY; 320 } 321 322 const auto& dirtyLayers = adapter.getDirtyLayers(); 323 *outNumTypes = dirtyLayers.size(); 324 *outNumRequests = 0; 325 326 if (*outNumTypes > 0) { 327 adapter.setState(HWC2OnFbAdapter::State::VALIDATED_WITH_CHANGES); 328 return HWC2_ERROR_HAS_CHANGES; 329 } else { 330 adapter.setState(HWC2OnFbAdapter::State::VALIDATED); 331 return HWC2_ERROR_NONE; 332 } 333 } 334 335 int32_t getChangedCompositionTypesHook(hwc2_device_t* device, hwc2_display_t display, 336 uint32_t* outNumElements, hwc2_layer_t* outLayers, 337 int32_t* outTypes) { 338 auto& adapter = HWC2OnFbAdapter::cast(device); 339 if (adapter.getDisplayId() != display) { 340 return HWC2_ERROR_BAD_DISPLAY; 341 } 342 if (adapter.getState() == HWC2OnFbAdapter::State::MODIFIED) { 343 return HWC2_ERROR_NOT_VALIDATED; 344 } 345 346 // request client composition for all layers 347 const auto& dirtyLayers = adapter.getDirtyLayers(); 348 if (outLayers && outTypes) { 349 *outNumElements = std::min(*outNumElements, uint32_t(dirtyLayers.size())); 350 auto iter = dirtyLayers.cbegin(); 351 for (uint32_t i = 0; i < *outNumElements; i++) { 352 outLayers[i] = *iter++; 353 outTypes[i] = HWC2_COMPOSITION_CLIENT; 354 } 355 } else { 356 *outNumElements = dirtyLayers.size(); 357 } 358 359 return HWC2_ERROR_NONE; 360 } 361 362 int32_t getDisplayRequestsHook(hwc2_device_t* device, hwc2_display_t display, 363 int32_t* outDisplayRequests, uint32_t* outNumElements, 364 hwc2_layer_t* /*outLayers*/, int32_t* /*outLayerRequests*/) { 365 auto& adapter = HWC2OnFbAdapter::cast(device); 366 if (adapter.getDisplayId() != display) { 367 return HWC2_ERROR_BAD_DISPLAY; 368 } 369 if (adapter.getState() == HWC2OnFbAdapter::State::MODIFIED) { 370 return HWC2_ERROR_NOT_VALIDATED; 371 } 372 373 *outDisplayRequests = 0; 374 *outNumElements = 0; 375 return HWC2_ERROR_NONE; 376 } 377 378 int32_t acceptDisplayChangesHook(hwc2_device_t* device, hwc2_display_t display) { 379 auto& adapter = HWC2OnFbAdapter::cast(device); 380 if (adapter.getDisplayId() != display) { 381 return HWC2_ERROR_BAD_DISPLAY; 382 } 383 if (adapter.getState() == HWC2OnFbAdapter::State::MODIFIED) { 384 return HWC2_ERROR_NOT_VALIDATED; 385 } 386 387 adapter.clearDirtyLayers(); 388 adapter.setState(HWC2OnFbAdapter::State::VALIDATED); 389 return HWC2_ERROR_NONE; 390 } 391 392 int32_t presentDisplayHook(hwc2_device_t* device, hwc2_display_t display, 393 int32_t* outPresentFence) { 394 auto& adapter = HWC2OnFbAdapter::cast(device); 395 if (adapter.getDisplayId() != display) { 396 return HWC2_ERROR_BAD_DISPLAY; 397 } 398 if (adapter.getState() != HWC2OnFbAdapter::State::VALIDATED) { 399 return HWC2_ERROR_NOT_VALIDATED; 400 } 401 402 adapter.postBuffer(); 403 *outPresentFence = -1; 404 405 return HWC2_ERROR_NONE; 406 } 407 408 int32_t getReleaseFencesHook(hwc2_device_t* device, hwc2_display_t display, 409 uint32_t* outNumElements, hwc2_layer_t* /*outLayers*/, 410 int32_t* /*outFences*/) { 411 auto& adapter = HWC2OnFbAdapter::cast(device); 412 if (adapter.getDisplayId() != display) { 413 return HWC2_ERROR_BAD_DISPLAY; 414 } 415 416 *outNumElements = 0; 417 return HWC2_ERROR_NONE; 418 } 419 420 int32_t createLayerHook(hwc2_device_t* device, hwc2_display_t display, hwc2_layer_t* outLayer) { 421 auto& adapter = HWC2OnFbAdapter::cast(device); 422 if (adapter.getDisplayId() != display) { 423 return HWC2_ERROR_BAD_DISPLAY; 424 } 425 426 *outLayer = adapter.addLayer(); 427 adapter.setState(HWC2OnFbAdapter::State::MODIFIED); 428 return HWC2_ERROR_NONE; 429 } 430 431 int32_t destroyLayerHook(hwc2_device_t* device, hwc2_display_t display, hwc2_layer_t layer) { 432 auto& adapter = HWC2OnFbAdapter::cast(device); 433 if (adapter.getDisplayId() != display) { 434 return HWC2_ERROR_BAD_DISPLAY; 435 } 436 437 if (adapter.removeLayer(layer)) { 438 adapter.setState(HWC2OnFbAdapter::State::MODIFIED); 439 return HWC2_ERROR_NONE; 440 } else { 441 return HWC2_ERROR_BAD_LAYER; 442 } 443 } 444 445 int32_t setCursorPositionHook(hwc2_device_t* device, hwc2_display_t display, hwc2_layer_t /*layer*/, 446 int32_t /*x*/, int32_t /*y*/) { 447 auto& adapter = HWC2OnFbAdapter::cast(device); 448 if (adapter.getDisplayId() != display) { 449 return HWC2_ERROR_BAD_DISPLAY; 450 } 451 452 // always an error 453 return HWC2_ERROR_BAD_LAYER; 454 } 455 456 int32_t setLayerBufferHook(hwc2_device_t* device, hwc2_display_t display, hwc2_layer_t layer, 457 buffer_handle_t /*buffer*/, int32_t acquireFence) { 458 if (acquireFence >= 0) { 459 sync_wait(acquireFence, -1); 460 close(acquireFence); 461 } 462 463 auto& adapter = HWC2OnFbAdapter::cast(device); 464 if (adapter.getDisplayId() != display) { 465 return HWC2_ERROR_BAD_DISPLAY; 466 } 467 if (!adapter.hasLayer(layer)) { 468 return HWC2_ERROR_BAD_LAYER; 469 } 470 471 // no state change 472 return HWC2_ERROR_NONE; 473 } 474 475 int32_t setLayerSurfaceDamageHook(hwc2_device_t* device, hwc2_display_t display, hwc2_layer_t layer, 476 hwc_region_t /*damage*/) { 477 auto& adapter = HWC2OnFbAdapter::cast(device); 478 if (adapter.getDisplayId() != display) { 479 return HWC2_ERROR_BAD_DISPLAY; 480 } 481 if (!adapter.hasLayer(layer)) { 482 return HWC2_ERROR_BAD_LAYER; 483 } 484 485 // no state change 486 return HWC2_ERROR_NONE; 487 } 488 489 int32_t setLayerCompositionTypeHook(hwc2_device_t* device, hwc2_display_t display, 490 hwc2_layer_t layer, int32_t type) { 491 auto& adapter = HWC2OnFbAdapter::cast(device); 492 if (adapter.getDisplayId() != display) { 493 return HWC2_ERROR_BAD_DISPLAY; 494 } 495 if (!adapter.markLayerDirty(layer, type != HWC2_COMPOSITION_CLIENT)) { 496 return HWC2_ERROR_BAD_LAYER; 497 } 498 499 adapter.setState(HWC2OnFbAdapter::State::MODIFIED); 500 return HWC2_ERROR_NONE; 501 } 502 503 template <typename... Args> 504 int32_t setLayerStateHook(hwc2_device_t* device, hwc2_display_t display, hwc2_layer_t layer, 505 Args... /*args*/) { 506 auto& adapter = HWC2OnFbAdapter::cast(device); 507 if (adapter.getDisplayId() != display) { 508 return HWC2_ERROR_BAD_DISPLAY; 509 } 510 if (!adapter.hasLayer(layer)) { 511 return HWC2_ERROR_BAD_LAYER; 512 } 513 514 adapter.setState(HWC2OnFbAdapter::State::MODIFIED); 515 return HWC2_ERROR_NONE; 516 } 517 518 template <typename PFN, typename T> 519 static hwc2_function_pointer_t asFP(T function) { 520 static_assert(std::is_same<PFN, T>::value, "Incompatible function pointer"); 521 return reinterpret_cast<hwc2_function_pointer_t>(function); 522 } 523 524 hwc2_function_pointer_t getFunctionHook(hwc2_device_t* /*device*/, int32_t descriptor) { 525 switch (descriptor) { 526 // global functions 527 case HWC2_FUNCTION_DUMP: 528 return asFP<HWC2_PFN_DUMP>(dumpHook); 529 case HWC2_FUNCTION_REGISTER_CALLBACK: 530 return asFP<HWC2_PFN_REGISTER_CALLBACK>(registerCallbackHook); 531 532 // virtual display functions 533 case HWC2_FUNCTION_GET_MAX_VIRTUAL_DISPLAY_COUNT: 534 return asFP<HWC2_PFN_GET_MAX_VIRTUAL_DISPLAY_COUNT>(getMaxVirtualDisplayCountHook); 535 case HWC2_FUNCTION_CREATE_VIRTUAL_DISPLAY: 536 return asFP<HWC2_PFN_CREATE_VIRTUAL_DISPLAY>(createVirtualDisplayHook); 537 case HWC2_FUNCTION_DESTROY_VIRTUAL_DISPLAY: 538 return asFP<HWC2_PFN_DESTROY_VIRTUAL_DISPLAY>(destroyVirtualDisplayHook); 539 case HWC2_FUNCTION_SET_OUTPUT_BUFFER: 540 return asFP<HWC2_PFN_SET_OUTPUT_BUFFER>(setOutputBufferHook); 541 542 // display functions 543 case HWC2_FUNCTION_GET_DISPLAY_NAME: 544 return asFP<HWC2_PFN_GET_DISPLAY_NAME>(getDisplayNameHook); 545 case HWC2_FUNCTION_GET_DISPLAY_TYPE: 546 return asFP<HWC2_PFN_GET_DISPLAY_TYPE>(getDisplayTypeHook); 547 case HWC2_FUNCTION_GET_DOZE_SUPPORT: 548 return asFP<HWC2_PFN_GET_DOZE_SUPPORT>(getDozeSupportHook); 549 case HWC2_FUNCTION_GET_HDR_CAPABILITIES: 550 return asFP<HWC2_PFN_GET_HDR_CAPABILITIES>(getHdrCapabilitiesHook); 551 case HWC2_FUNCTION_SET_POWER_MODE: 552 return asFP<HWC2_PFN_SET_POWER_MODE>(setPowerModeHook); 553 case HWC2_FUNCTION_SET_VSYNC_ENABLED: 554 return asFP<HWC2_PFN_SET_VSYNC_ENABLED>(setVsyncEnabledHook); 555 case HWC2_FUNCTION_GET_COLOR_MODES: 556 return asFP<HWC2_PFN_GET_COLOR_MODES>(getColorModesHook); 557 case HWC2_FUNCTION_SET_COLOR_MODE: 558 return asFP<HWC2_PFN_SET_COLOR_MODE>(setColorModeHook); 559 case HWC2_FUNCTION_SET_COLOR_TRANSFORM: 560 return asFP<HWC2_PFN_SET_COLOR_TRANSFORM>(setColorTransformHook); 561 case HWC2_FUNCTION_GET_CLIENT_TARGET_SUPPORT: 562 return asFP<HWC2_PFN_GET_CLIENT_TARGET_SUPPORT>(getClientTargetSupportHook); 563 case HWC2_FUNCTION_SET_CLIENT_TARGET: 564 return asFP<HWC2_PFN_SET_CLIENT_TARGET>(setClientTargetHook); 565 566 // config functions 567 case HWC2_FUNCTION_GET_DISPLAY_CONFIGS: 568 return asFP<HWC2_PFN_GET_DISPLAY_CONFIGS>(getDisplayConfigsHook); 569 case HWC2_FUNCTION_GET_DISPLAY_ATTRIBUTE: 570 return asFP<HWC2_PFN_GET_DISPLAY_ATTRIBUTE>(getDisplayAttributeHook); 571 case HWC2_FUNCTION_GET_ACTIVE_CONFIG: 572 return asFP<HWC2_PFN_GET_ACTIVE_CONFIG>(getActiveConfigHook); 573 case HWC2_FUNCTION_SET_ACTIVE_CONFIG: 574 return asFP<HWC2_PFN_SET_ACTIVE_CONFIG>(setActiveConfigHook); 575 576 // validate/present functions 577 case HWC2_FUNCTION_VALIDATE_DISPLAY: 578 return asFP<HWC2_PFN_VALIDATE_DISPLAY>(validateDisplayHook); 579 case HWC2_FUNCTION_GET_CHANGED_COMPOSITION_TYPES: 580 return asFP<HWC2_PFN_GET_CHANGED_COMPOSITION_TYPES>(getChangedCompositionTypesHook); 581 case HWC2_FUNCTION_GET_DISPLAY_REQUESTS: 582 return asFP<HWC2_PFN_GET_DISPLAY_REQUESTS>(getDisplayRequestsHook); 583 case HWC2_FUNCTION_ACCEPT_DISPLAY_CHANGES: 584 return asFP<HWC2_PFN_ACCEPT_DISPLAY_CHANGES>(acceptDisplayChangesHook); 585 case HWC2_FUNCTION_PRESENT_DISPLAY: 586 return asFP<HWC2_PFN_PRESENT_DISPLAY>(presentDisplayHook); 587 case HWC2_FUNCTION_GET_RELEASE_FENCES: 588 return asFP<HWC2_PFN_GET_RELEASE_FENCES>(getReleaseFencesHook); 589 590 // layer create/destroy 591 case HWC2_FUNCTION_CREATE_LAYER: 592 return asFP<HWC2_PFN_CREATE_LAYER>(createLayerHook); 593 case HWC2_FUNCTION_DESTROY_LAYER: 594 return asFP<HWC2_PFN_DESTROY_LAYER>(destroyLayerHook); 595 596 // layer functions; validateDisplay not required 597 case HWC2_FUNCTION_SET_CURSOR_POSITION: 598 return asFP<HWC2_PFN_SET_CURSOR_POSITION>(setCursorPositionHook); 599 case HWC2_FUNCTION_SET_LAYER_BUFFER: 600 return asFP<HWC2_PFN_SET_LAYER_BUFFER>(setLayerBufferHook); 601 case HWC2_FUNCTION_SET_LAYER_SURFACE_DAMAGE: 602 return asFP<HWC2_PFN_SET_LAYER_SURFACE_DAMAGE>(setLayerSurfaceDamageHook); 603 604 // layer state functions; validateDisplay required 605 case HWC2_FUNCTION_SET_LAYER_COMPOSITION_TYPE: 606 return asFP<HWC2_PFN_SET_LAYER_COMPOSITION_TYPE>(setLayerCompositionTypeHook); 607 case HWC2_FUNCTION_SET_LAYER_BLEND_MODE: 608 return asFP<HWC2_PFN_SET_LAYER_BLEND_MODE>(setLayerStateHook<int32_t>); 609 case HWC2_FUNCTION_SET_LAYER_COLOR: 610 return asFP<HWC2_PFN_SET_LAYER_COLOR>(setLayerStateHook<hwc_color_t>); 611 case HWC2_FUNCTION_SET_LAYER_DATASPACE: 612 return asFP<HWC2_PFN_SET_LAYER_DATASPACE>(setLayerStateHook<int32_t>); 613 case HWC2_FUNCTION_SET_LAYER_DISPLAY_FRAME: 614 return asFP<HWC2_PFN_SET_LAYER_DISPLAY_FRAME>(setLayerStateHook<hwc_rect_t>); 615 case HWC2_FUNCTION_SET_LAYER_PLANE_ALPHA: 616 return asFP<HWC2_PFN_SET_LAYER_PLANE_ALPHA>(setLayerStateHook<float>); 617 case HWC2_FUNCTION_SET_LAYER_SIDEBAND_STREAM: 618 return asFP<HWC2_PFN_SET_LAYER_SIDEBAND_STREAM>(setLayerStateHook<buffer_handle_t>); 619 case HWC2_FUNCTION_SET_LAYER_SOURCE_CROP: 620 return asFP<HWC2_PFN_SET_LAYER_SOURCE_CROP>(setLayerStateHook<hwc_frect_t>); 621 case HWC2_FUNCTION_SET_LAYER_TRANSFORM: 622 return asFP<HWC2_PFN_SET_LAYER_TRANSFORM>(setLayerStateHook<int32_t>); 623 case HWC2_FUNCTION_SET_LAYER_VISIBLE_REGION: 624 return asFP<HWC2_PFN_SET_LAYER_VISIBLE_REGION>(setLayerStateHook<hwc_region_t>); 625 case HWC2_FUNCTION_SET_LAYER_Z_ORDER: 626 return asFP<HWC2_PFN_SET_LAYER_Z_ORDER>(setLayerStateHook<uint32_t>); 627 628 default: 629 ALOGE("unknown function descriptor %d", descriptor); 630 return nullptr; 631 } 632 } 633 634 void getCapabilitiesHook(hwc2_device_t* device, uint32_t* outCount, 635 int32_t* outCapabilities) { 636 auto& adapter = HWC2OnFbAdapter::cast(device); 637 adapter.getCapabilities(outCount, outCapabilities); 638 } 639 640 int closeHook(hw_device_t* device) { 641 auto& adapter = HWC2OnFbAdapter::cast(device); 642 adapter.close(); 643 return 0; 644 } 645 646 } // anonymous namespace 647 648 HWC2OnFbAdapter::HWC2OnFbAdapter(framebuffer_device_t* fbDevice) 649 : hwc2_device_t(), mFbDevice(fbDevice) { 650 common.close = closeHook; 651 hwc2_device::getCapabilities = getCapabilitiesHook; 652 hwc2_device::getFunction = getFunctionHook; 653 654 mFbInfo.name = "fbdev"; 655 mFbInfo.width = mFbDevice->width; 656 mFbInfo.height = mFbDevice->height; 657 mFbInfo.format = mFbDevice->format; 658 mFbInfo.vsync_period_ns = int(1e9 / mFbDevice->fps); 659 mFbInfo.xdpi_scaled = int(mFbDevice->xdpi * 1000.0f); 660 mFbInfo.ydpi_scaled = int(mFbDevice->ydpi * 1000.0f); 661 662 // Present fences aren't supported, always indicate PresentFenceIsNotReliable 663 // for FB devices 664 mCapabilities.insert(Capability::PresentFenceIsNotReliable); 665 666 mVsyncThread.start(0, mFbInfo.vsync_period_ns); 667 } 668 669 HWC2OnFbAdapter& HWC2OnFbAdapter::cast(hw_device_t* device) { 670 return *reinterpret_cast<HWC2OnFbAdapter*>(device); 671 } 672 673 HWC2OnFbAdapter& HWC2OnFbAdapter::cast(hwc2_device_t* device) { 674 return *reinterpret_cast<HWC2OnFbAdapter*>(device); 675 } 676 677 hwc2_display_t HWC2OnFbAdapter::getDisplayId() { 678 return 0; 679 } 680 681 hwc2_config_t HWC2OnFbAdapter::getConfigId() { 682 return 0; 683 } 684 685 void HWC2OnFbAdapter::close() { 686 mVsyncThread.stop(); 687 framebuffer_close(mFbDevice); 688 } 689 690 const HWC2OnFbAdapter::Info& HWC2OnFbAdapter::getInfo() const { 691 return mFbInfo; 692 } 693 694 void HWC2OnFbAdapter::updateDebugString() { 695 if (mFbDevice->common.version >= 1 && mFbDevice->dump) { 696 char buffer[4096]; 697 mFbDevice->dump(mFbDevice, buffer, sizeof(buffer)); 698 buffer[sizeof(buffer) - 1] = '\0'; 699 700 mDebugString = buffer; 701 } 702 } 703 704 const std::string& HWC2OnFbAdapter::getDebugString() const { 705 return mDebugString; 706 } 707 708 void HWC2OnFbAdapter::setState(State state) { 709 mState = state; 710 } 711 712 HWC2OnFbAdapter::State HWC2OnFbAdapter::getState() const { 713 return mState; 714 } 715 716 hwc2_layer_t HWC2OnFbAdapter::addLayer() { 717 hwc2_layer_t id = ++mNextLayerId; 718 719 mLayers.insert(id); 720 mDirtyLayers.insert(id); 721 722 return id; 723 } 724 725 bool HWC2OnFbAdapter::removeLayer(hwc2_layer_t layer) { 726 mDirtyLayers.erase(layer); 727 return mLayers.erase(layer); 728 } 729 730 bool HWC2OnFbAdapter::hasLayer(hwc2_layer_t layer) const { 731 return mLayers.count(layer) > 0; 732 } 733 734 bool HWC2OnFbAdapter::markLayerDirty(hwc2_layer_t layer, bool dirty) { 735 if (mLayers.count(layer) == 0) { 736 return false; 737 } 738 739 if (dirty) { 740 mDirtyLayers.insert(layer); 741 } else { 742 mDirtyLayers.erase(layer); 743 } 744 745 return true; 746 } 747 748 const std::unordered_set<hwc2_layer_t>& HWC2OnFbAdapter::getDirtyLayers() const { 749 return mDirtyLayers; 750 } 751 752 void HWC2OnFbAdapter::clearDirtyLayers() { 753 mDirtyLayers.clear(); 754 } 755 756 /* 757 * For each frame, SurfaceFlinger 758 * 759 * - peforms GLES composition 760 * - calls eglSwapBuffers 761 * - calls setClientTarget, which maps to setBuffer below 762 * - calls presentDisplay, which maps to postBuffer below 763 * 764 * setBuffer should be a good place to call compositionComplete. 765 * 766 * As for post, it 767 * 768 * - schedules the buffer for presentation on the next vsync 769 * - locks the buffer and blocks all other users trying to lock it 770 * 771 * It does not give us a way to return a present fence, and we need to live 772 * with that. The implication is that, when we are double-buffered, 773 * SurfaceFlinger assumes the front buffer is available for rendering again 774 * immediately after the back buffer is posted. The locking semantics 775 * hopefully are strong enough that the rendering will be blocked. 776 */ 777 void HWC2OnFbAdapter::setBuffer(buffer_handle_t buffer) { 778 if (mFbDevice->compositionComplete) { 779 mFbDevice->compositionComplete(mFbDevice); 780 } 781 mBuffer = buffer; 782 } 783 784 bool HWC2OnFbAdapter::postBuffer() { 785 int error = 0; 786 if (mBuffer) { 787 error = mFbDevice->post(mFbDevice, mBuffer); 788 } 789 790 return error == 0; 791 } 792 793 void HWC2OnFbAdapter::setVsyncCallback(HWC2_PFN_VSYNC callback, hwc2_callback_data_t data) { 794 mVsyncThread.setCallback(callback, data); 795 } 796 797 void HWC2OnFbAdapter::enableVsync(bool enable) { 798 mVsyncThread.enableCallback(enable); 799 } 800 801 void HWC2OnFbAdapter::getCapabilities(uint32_t* outCount, 802 int32_t* outCapabilities) { 803 if (outCapabilities == nullptr) { 804 *outCount = mCapabilities.size(); 805 return; 806 } 807 808 auto capabilityIter = mCapabilities.cbegin(); 809 for (size_t written = 0; written < *outCount; ++written) { 810 if (capabilityIter == mCapabilities.cend()) { 811 return; 812 } 813 outCapabilities[written] = static_cast<int32_t>(*capabilityIter); 814 ++capabilityIter; 815 } 816 } 817 818 int64_t HWC2OnFbAdapter::VsyncThread::now() { 819 struct timespec ts; 820 clock_gettime(CLOCK_MONOTONIC, &ts); 821 822 return int64_t(ts.tv_sec) * 1'000'000'000 + ts.tv_nsec; 823 } 824 825 bool HWC2OnFbAdapter::VsyncThread::sleepUntil(int64_t t) { 826 struct timespec ts; 827 ts.tv_sec = t / 1'000'000'000; 828 ts.tv_nsec = t % 1'000'000'000; 829 830 while (true) { 831 int error = clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &ts, nullptr); 832 if (error) { 833 if (error == EINTR) { 834 continue; 835 } 836 return false; 837 } else { 838 return true; 839 } 840 } 841 } 842 843 void HWC2OnFbAdapter::VsyncThread::start(int64_t firstVsync, int64_t period) { 844 mNextVsync = firstVsync; 845 mPeriod = period; 846 mStarted = true; 847 mThread = std::thread(&VsyncThread::vsyncLoop, this); 848 } 849 850 void HWC2OnFbAdapter::VsyncThread::stop() { 851 { 852 std::lock_guard<std::mutex> lock(mMutex); 853 mStarted = false; 854 } 855 mCondition.notify_all(); 856 mThread.join(); 857 } 858 859 void HWC2OnFbAdapter::VsyncThread::setCallback(HWC2_PFN_VSYNC callback, hwc2_callback_data_t data) { 860 std::lock_guard<std::mutex> lock(mMutex); 861 mCallback = callback; 862 mCallbackData = data; 863 } 864 865 void HWC2OnFbAdapter::VsyncThread::enableCallback(bool enable) { 866 { 867 std::lock_guard<std::mutex> lock(mMutex); 868 mCallbackEnabled = enable; 869 } 870 mCondition.notify_all(); 871 } 872 873 void HWC2OnFbAdapter::VsyncThread::vsyncLoop() { 874 prctl(PR_SET_NAME, "VsyncThread", 0, 0, 0); 875 876 std::unique_lock<std::mutex> lock(mMutex); 877 if (!mStarted) { 878 return; 879 } 880 881 while (true) { 882 if (!mCallbackEnabled) { 883 mCondition.wait(lock, [this] { return mCallbackEnabled || !mStarted; }); 884 if (!mStarted) { 885 break; 886 } 887 } 888 889 lock.unlock(); 890 891 // adjust mNextVsync if necessary 892 int64_t t = now(); 893 if (mNextVsync < t) { 894 int64_t n = (t - mNextVsync + mPeriod - 1) / mPeriod; 895 mNextVsync += mPeriod * n; 896 } 897 bool fire = sleepUntil(mNextVsync); 898 899 lock.lock(); 900 901 if (fire) { 902 ALOGV("VsyncThread(%" PRId64 ")", mNextVsync); 903 if (mCallback) { 904 mCallback(mCallbackData, getDisplayId(), mNextVsync); 905 } 906 mNextVsync += mPeriod; 907 } 908 } 909 } 910 911 } // namespace android 912