1 /* 2 * Copyright (c) 2014-2016, The Linux Foundation. All rights reserved. 3 * Not a Contribution. 4 * 5 * Copyright 2015 The Android Open Source Project 6 * 7 * Licensed under the Apache License, Version 2.0 (the "License"); 8 * you may not use this file except in compliance with the License. 9 * You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, software 14 * distributed under the License is distributed on an "AS IS" BASIS, 15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 * See the License for the specific language governing permissions and 17 * limitations under the License. 18 */ 19 20 #include <core/dump_interface.h> 21 #include <core/buffer_allocator.h> 22 #include <private/color_params.h> 23 #include <utils/constants.h> 24 #include <utils/String16.h> 25 #include <cutils/properties.h> 26 #include <hardware_legacy/uevent.h> 27 #include <sys/resource.h> 28 #include <sys/prctl.h> 29 #include <binder/Parcel.h> 30 #include <QService.h> 31 #include <gr.h> 32 #include <gralloc_priv.h> 33 #include <display_config.h> 34 #include <utils/debug.h> 35 #include <sync/sync.h> 36 #include <profiler.h> 37 #include <string> 38 #include <bitset> 39 40 #include "hwc_buffer_allocator.h" 41 #include "hwc_buffer_sync_handler.h" 42 #include "hwc_session.h" 43 #include "hwc_debugger.h" 44 #include "hwc_display_primary.h" 45 #include "hwc_display_virtual.h" 46 47 #define __CLASS__ "HWCSession" 48 49 #define HWC_UEVENT_SWITCH_HDMI "change@/devices/virtual/switch/hdmi" 50 #define HWC_UEVENT_GRAPHICS_FB0 "change@/devices/virtual/graphics/fb0" 51 52 static sdm::HWCSession::HWCModuleMethods g_hwc_module_methods; 53 54 hwc_module_t HAL_MODULE_INFO_SYM = { 55 .common = { 56 .tag = HARDWARE_MODULE_TAG, 57 .version_major = 3, 58 .version_minor = 0, 59 .id = HWC_HARDWARE_MODULE_ID, 60 .name = "QTI Hardware Composer Module", 61 .author = "CodeAurora Forum", 62 .methods = &g_hwc_module_methods, 63 .dso = 0, 64 .reserved = {0}, 65 } 66 }; 67 68 namespace sdm { 69 Locker HWCSession::locker_; 70 71 HWCSession::HWCSession(const hw_module_t *module) { 72 hwc2_device_t::common.tag = HARDWARE_DEVICE_TAG; 73 hwc2_device_t::common.version = HWC_DEVICE_API_VERSION_2_0; 74 hwc2_device_t::common.module = const_cast<hw_module_t *>(module); 75 hwc2_device_t::common.close = Close; 76 hwc2_device_t::getCapabilities = GetCapabilities; 77 hwc2_device_t::getFunction = GetFunction; 78 } 79 80 int HWCSession::Init() { 81 int status = -EINVAL; 82 const char *qservice_name = "display.qservice"; 83 84 // Start QService and connect to it. 85 qService::QService::init(); 86 android::sp<qService::IQService> iqservice = android::interface_cast<qService::IQService>( 87 android::defaultServiceManager()->getService(android::String16(qservice_name))); 88 89 if (iqservice.get()) { 90 iqservice->connect(android::sp<qClient::IQClient>(this)); 91 qservice_ = reinterpret_cast<qService::QService *>(iqservice.get()); 92 } else { 93 DLOGE("Failed to acquire %s", qservice_name); 94 return -EINVAL; 95 } 96 97 DisplayError error = CoreInterface::CreateCore(HWCDebugHandler::Get(), &buffer_allocator_, 98 &buffer_sync_handler_, &core_intf_); 99 if (error != kErrorNone) { 100 DLOGE("Display core initialization failed. Error = %d", error); 101 return -EINVAL; 102 } 103 104 // Read which display is first, and create it and store it in primary slot 105 // TODO(user): This will need to be redone for HWC2 - right now we validate only 106 // the primary physical path 107 HWDisplayInterfaceInfo hw_disp_info; 108 error = core_intf_->GetFirstDisplayInterfaceType(&hw_disp_info); 109 if (error == kErrorNone && hw_disp_info.type == kHDMI && hw_disp_info.is_connected) { 110 // HDMI is primary display. If already connected, then create it and store in 111 // primary display slot. If not connected, create a NULL display for now. 112 status = HWCDisplayExternal::Create(core_intf_, &callbacks_, qservice_, 113 &hwc_display_[HWC_DISPLAY_PRIMARY]); 114 } else { 115 // Create and power on primary display 116 status = HWCDisplayPrimary::Create(core_intf_, &buffer_allocator_, &callbacks_, qservice_, 117 &hwc_display_[HWC_DISPLAY_PRIMARY]); 118 } 119 120 if (status) { 121 CoreInterface::DestroyCore(); 122 return status; 123 } 124 125 color_mgr_ = HWCColorManager::CreateColorManager(); 126 if (!color_mgr_) { 127 DLOGW("Failed to load HWCColorManager."); 128 } 129 130 if (pthread_create(&uevent_thread_, NULL, &HWCUeventThread, this) < 0) { 131 DLOGE("Failed to start = %s, error = %s", uevent_thread_name_, strerror(errno)); 132 HWCDisplayPrimary::Destroy(hwc_display_[HWC_DISPLAY_PRIMARY]); 133 hwc_display_[HWC_DISPLAY_PRIMARY] = 0; 134 CoreInterface::DestroyCore(); 135 return -errno; 136 } 137 138 return 0; 139 } 140 141 int HWCSession::Deinit() { 142 HWCDisplayPrimary::Destroy(hwc_display_[HWC_DISPLAY_PRIMARY]); 143 hwc_display_[HWC_DISPLAY_PRIMARY] = 0; 144 if (color_mgr_) { 145 color_mgr_->DestroyColorManager(); 146 } 147 uevent_thread_exit_ = true; 148 pthread_join(uevent_thread_, NULL); 149 150 DisplayError error = CoreInterface::DestroyCore(); 151 if (error != kErrorNone) { 152 DLOGE("Display core de-initialization failed. Error = %d", error); 153 } 154 155 return 0; 156 } 157 158 int HWCSession::Open(const hw_module_t *module, const char *name, hw_device_t **device) { 159 SEQUENCE_WAIT_SCOPE_LOCK(locker_); 160 161 if (!module || !name || !device) { 162 DLOGE("Invalid parameters."); 163 return -EINVAL; 164 } 165 166 if (!strcmp(name, HWC_HARDWARE_COMPOSER)) { 167 HWCSession *hwc_session = new HWCSession(module); 168 if (!hwc_session) { 169 return -ENOMEM; 170 } 171 172 int status = hwc_session->Init(); 173 if (status != 0) { 174 delete hwc_session; 175 return status; 176 } 177 178 hwc2_device_t *composer_device = hwc_session; 179 *device = reinterpret_cast<hw_device_t *>(composer_device); 180 } 181 182 return 0; 183 } 184 185 int HWCSession::Close(hw_device_t *device) { 186 SEQUENCE_WAIT_SCOPE_LOCK(locker_); 187 188 if (!device) { 189 return -EINVAL; 190 } 191 192 hwc2_device_t *composer_device = reinterpret_cast<hwc2_device_t *>(device); 193 HWCSession *hwc_session = static_cast<HWCSession *>(composer_device); 194 195 hwc_session->Deinit(); 196 delete hwc_session; 197 198 return 0; 199 } 200 201 void HWCSession::GetCapabilities(struct hwc2_device *device, uint32_t *outCount, 202 int32_t *outCapabilities) { 203 if (outCapabilities != nullptr && *outCount >= 1) { 204 outCapabilities[0] = HWC2_CAPABILITY_SKIP_CLIENT_COLOR_TRANSFORM; 205 } 206 *outCount = 1; 207 } 208 209 template <typename PFN, typename T> 210 static hwc2_function_pointer_t AsFP(T function) { 211 static_assert(std::is_same<PFN, T>::value, "Incompatible function pointer"); 212 return reinterpret_cast<hwc2_function_pointer_t>(function); 213 } 214 215 // HWC2 functions returned in GetFunction 216 // Defined in the same order as in the HWC2 header 217 218 int32_t HWCSession::AcceptDisplayChanges(hwc2_device_t *device, 219 hwc2_display_t display) { 220 SCOPE_LOCK(locker_); 221 return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::AcceptDisplayChanges); 222 } 223 224 int32_t HWCSession::CreateLayer(hwc2_device_t *device, hwc2_display_t display, 225 hwc2_layer_t *out_layer_id) { 226 SCOPE_LOCK(locker_); 227 return CallDisplayFunction(device, display, &HWCDisplay::CreateLayer, out_layer_id); 228 } 229 230 int32_t HWCSession::CreateVirtualDisplay(hwc2_device_t *device, uint32_t width, uint32_t height, 231 int32_t *format, hwc2_display_t *out_display_id) { 232 // TODO(user): Handle concurrency with HDMI 233 SCOPE_LOCK(locker_); 234 if (!device) { 235 return HWC2_ERROR_BAD_DISPLAY; 236 } 237 238 HWCSession *hwc_session = static_cast<HWCSession *>(device); 239 auto status = hwc_session->CreateVirtualDisplayObject(width, height, format); 240 if (status == HWC2::Error::None) { 241 *out_display_id = HWC_DISPLAY_VIRTUAL; 242 DLOGI("Created virtual display id:% " PRIu64 " with res: %dx%d", 243 *out_display_id, width, height); 244 } else { 245 DLOGE("Failed to create virtual display: %s", to_string(status).c_str()); 246 } 247 return INT32(status); 248 } 249 250 int32_t HWCSession::DestroyLayer(hwc2_device_t *device, hwc2_display_t display, 251 hwc2_layer_t layer) { 252 SCOPE_LOCK(locker_); 253 return CallDisplayFunction(device, display, &HWCDisplay::DestroyLayer, layer); 254 } 255 256 int32_t HWCSession::DestroyVirtualDisplay(hwc2_device_t *device, hwc2_display_t display) { 257 SCOPE_LOCK(locker_); 258 if (!device) { 259 return HWC2_ERROR_BAD_DISPLAY; 260 } 261 262 DLOGI("Destroying virtual display id:%" PRIu64, display); 263 auto *hwc_session = static_cast<HWCSession *>(device); 264 265 if (hwc_session->hwc_display_[display]) { 266 HWCDisplayVirtual::Destroy(hwc_session->hwc_display_[display]); 267 hwc_session->hwc_display_[display] = nullptr; 268 return HWC2_ERROR_NONE; 269 } else { 270 return HWC2_ERROR_BAD_DISPLAY; 271 } 272 } 273 274 void HWCSession::Dump(hwc2_device_t *device, uint32_t *out_size, char *out_buffer) { 275 SEQUENCE_WAIT_SCOPE_LOCK(locker_); 276 277 if (!device) { 278 return; 279 } 280 auto *hwc_session = static_cast<HWCSession *>(device); 281 282 if (out_buffer == nullptr) { 283 *out_size = 8192; // TODO(user): Adjust required dump size 284 } else { 285 char sdm_dump[4096]; 286 DumpInterface::GetDump(sdm_dump, 4096); // TODO(user): Fix this workaround 287 std::string s(""); 288 for (int id = HWC_DISPLAY_PRIMARY; id <= HWC_DISPLAY_VIRTUAL; id++) { 289 if (hwc_session->hwc_display_[id]) { 290 s += hwc_session->hwc_display_[id]->Dump(); 291 } 292 } 293 s += sdm_dump; 294 s.copy(out_buffer, s.size(), 0); 295 *out_size = sizeof(out_buffer); 296 } 297 } 298 299 static int32_t GetActiveConfig(hwc2_device_t *device, hwc2_display_t display, 300 hwc2_config_t *out_config) { 301 return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::GetActiveConfig, out_config); 302 } 303 304 static int32_t GetChangedCompositionTypes(hwc2_device_t *device, hwc2_display_t display, 305 uint32_t *out_num_elements, hwc2_layer_t *out_layers, 306 int32_t *out_types) { 307 return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::GetChangedCompositionTypes, 308 out_num_elements, out_layers, out_types); 309 } 310 311 static int32_t GetClientTargetSupport(hwc2_device_t *device, hwc2_display_t display, uint32_t width, 312 uint32_t height, int32_t format, int32_t dataspace) { 313 return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::GetClientTargetSupport, 314 width, height, format, dataspace); 315 } 316 317 static int32_t GetColorModes(hwc2_device_t *device, hwc2_display_t display, uint32_t *out_num_modes, 318 int32_t /*android_color_mode_t*/ *int_out_modes) { 319 auto out_modes = reinterpret_cast<android_color_mode_t *>(int_out_modes); 320 return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::GetColorModes, out_num_modes, 321 out_modes); 322 } 323 324 static int32_t GetDisplayAttribute(hwc2_device_t *device, hwc2_display_t display, 325 hwc2_config_t config, int32_t int_attribute, 326 int32_t *out_value) { 327 auto attribute = static_cast<HWC2::Attribute>(int_attribute); 328 return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::GetDisplayAttribute, config, 329 attribute, out_value); 330 } 331 332 static int32_t GetDisplayConfigs(hwc2_device_t *device, hwc2_display_t display, 333 uint32_t *out_num_configs, hwc2_config_t *out_configs) { 334 return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::GetDisplayConfigs, 335 out_num_configs, out_configs); 336 } 337 338 static int32_t GetDisplayName(hwc2_device_t *device, hwc2_display_t display, uint32_t *out_size, 339 char *out_name) { 340 return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::GetDisplayName, out_size, 341 out_name); 342 } 343 344 static int32_t GetDisplayRequests(hwc2_device_t *device, hwc2_display_t display, 345 int32_t *out_display_requests, uint32_t *out_num_elements, 346 hwc2_layer_t *out_layers, int32_t *out_layer_requests) { 347 return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::GetDisplayRequests, 348 out_display_requests, out_num_elements, out_layers, 349 out_layer_requests); 350 } 351 352 static int32_t GetDisplayType(hwc2_device_t *device, hwc2_display_t display, int32_t *out_type) { 353 return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::GetDisplayType, out_type); 354 } 355 356 static int32_t GetDozeSupport(hwc2_device_t *device, hwc2_display_t display, int32_t *out_support) { 357 // TODO(user): Check if it is an HDMI as primary display and disable support for it 358 if (display == HWC_DISPLAY_PRIMARY) { 359 *out_support = 1; 360 } else { 361 *out_support = 0; 362 } 363 return HWC2_ERROR_NONE; 364 } 365 366 static int32_t GetHdrCapabilities(hwc2_device_t* device, hwc2_display_t display, 367 uint32_t* out_num_types, int32_t* out_types, 368 float* out_max_luminance, float* out_max_average_luminance, 369 float* out_min_luminance) { 370 *out_num_types = 0; 371 return HWC2_ERROR_NONE; 372 } 373 374 static uint32_t GetMaxVirtualDisplayCount(hwc2_device_t *device) { 375 return 1; 376 } 377 378 static int32_t GetReleaseFences(hwc2_device_t *device, hwc2_display_t display, 379 uint32_t *out_num_elements, hwc2_layer_t *out_layers, 380 int32_t *out_fences) { 381 return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::GetReleaseFences, 382 out_num_elements, out_layers, out_fences); 383 } 384 385 int32_t HWCSession::PresentDisplay(hwc2_device_t *device, hwc2_display_t display, 386 int32_t *out_retire_fence) { 387 HWCSession *hwc_session = static_cast<HWCSession *>(device); 388 DTRACE_SCOPED(); 389 SEQUENCE_EXIT_SCOPE_LOCK(locker_); 390 if (!device) { 391 return HWC2_ERROR_BAD_DISPLAY; 392 } 393 394 auto status = HWC2::Error::BadDisplay; 395 // TODO(user): Handle virtual display/HDMI concurrency 396 if (hwc_session->hwc_display_[display]) { 397 status = hwc_session->hwc_display_[display]->Present(out_retire_fence); 398 // This is only indicative of how many times SurfaceFlinger posts 399 // frames to the display. 400 CALC_FPS(); 401 } 402 403 return INT32(status); 404 } 405 406 int32_t HWCSession::RegisterCallback(hwc2_device_t *device, int32_t descriptor, 407 hwc2_callback_data_t callback_data, 408 hwc2_function_pointer_t pointer) { 409 HWCSession *hwc_session = static_cast<HWCSession *>(device); 410 if (!device) { 411 return HWC2_ERROR_BAD_DISPLAY; 412 } 413 auto desc = static_cast<HWC2::Callback>(descriptor); 414 auto error = hwc_session->callbacks_.Register(desc, callback_data, pointer); 415 DLOGD("Registering callback: %s", to_string(desc).c_str()); 416 if (descriptor == HWC2_CALLBACK_HOTPLUG) 417 hwc_session->callbacks_.Hotplug(HWC_DISPLAY_PRIMARY, HWC2::Connection::Connected); 418 return INT32(error); 419 } 420 421 static int32_t SetActiveConfig(hwc2_device_t *device, hwc2_display_t display, 422 hwc2_config_t config) { 423 return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::SetActiveConfig, config); 424 } 425 426 static int32_t SetClientTarget(hwc2_device_t *device, hwc2_display_t display, 427 buffer_handle_t target, int32_t acquire_fence, 428 int32_t dataspace, hwc_region_t damage) { 429 return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::SetClientTarget, target, 430 acquire_fence, dataspace, damage); 431 } 432 433 int32_t HWCSession::SetColorMode(hwc2_device_t *device, hwc2_display_t display, 434 int32_t /*android_color_mode_t*/ int_mode) { 435 auto mode = static_cast<android_color_mode_t>(int_mode); 436 SEQUENCE_WAIT_SCOPE_LOCK(locker_); 437 return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::SetColorMode, mode); 438 } 439 440 int32_t HWCSession::SetColorTransform(hwc2_device_t *device, hwc2_display_t display, 441 const float *matrix, 442 int32_t /*android_color_transform_t*/ hint) { 443 SEQUENCE_WAIT_SCOPE_LOCK(locker_); 444 android_color_transform_t transform_hint = static_cast<android_color_transform_t>(hint); 445 return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::SetColorTransform, matrix, 446 transform_hint); 447 } 448 449 static int32_t SetCursorPosition(hwc2_device_t *device, hwc2_display_t display, hwc2_layer_t layer, 450 int32_t x, int32_t y) { 451 return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::SetCursorPosition, layer, x, 452 y); 453 } 454 455 static int32_t SetLayerBlendMode(hwc2_device_t *device, hwc2_display_t display, hwc2_layer_t layer, 456 int32_t int_mode) { 457 auto mode = static_cast<HWC2::BlendMode>(int_mode); 458 return HWCSession::CallLayerFunction(device, display, layer, &HWCLayer::SetLayerBlendMode, mode); 459 } 460 461 static int32_t SetLayerBuffer(hwc2_device_t *device, hwc2_display_t display, hwc2_layer_t layer, 462 buffer_handle_t buffer, int32_t acquire_fence) { 463 return HWCSession::CallLayerFunction(device, display, layer, &HWCLayer::SetLayerBuffer, buffer, 464 acquire_fence); 465 } 466 467 static int32_t SetLayerColor(hwc2_device_t *device, hwc2_display_t display, hwc2_layer_t layer, 468 hwc_color_t color) { 469 return HWCSession::CallLayerFunction(device, display, layer, &HWCLayer::SetLayerColor, color); 470 } 471 472 static int32_t SetLayerCompositionType(hwc2_device_t *device, hwc2_display_t display, 473 hwc2_layer_t layer, int32_t int_type) { 474 auto type = static_cast<HWC2::Composition>(int_type); 475 return HWCSession::CallLayerFunction(device, display, layer, &HWCLayer::SetLayerCompositionType, 476 type); 477 } 478 479 static int32_t SetLayerDataspace(hwc2_device_t *device, hwc2_display_t display, hwc2_layer_t layer, 480 int32_t dataspace) { 481 return HWCSession::CallLayerFunction(device, display, layer, &HWCLayer::SetLayerDataspace, 482 dataspace); 483 } 484 485 static int32_t SetLayerDisplayFrame(hwc2_device_t *device, hwc2_display_t display, 486 hwc2_layer_t layer, hwc_rect_t frame) { 487 return HWCSession::CallLayerFunction(device, display, layer, &HWCLayer::SetLayerDisplayFrame, 488 frame); 489 } 490 491 static int32_t SetLayerPlaneAlpha(hwc2_device_t *device, hwc2_display_t display, hwc2_layer_t layer, 492 float alpha) { 493 return HWCSession::CallLayerFunction(device, display, layer, &HWCLayer::SetLayerPlaneAlpha, 494 alpha); 495 } 496 497 static int32_t SetLayerSourceCrop(hwc2_device_t *device, hwc2_display_t display, hwc2_layer_t layer, 498 hwc_frect_t crop) { 499 return HWCSession::CallLayerFunction(device, display, layer, &HWCLayer::SetLayerSourceCrop, crop); 500 } 501 502 static int32_t SetLayerSurfaceDamage(hwc2_device_t *device, hwc2_display_t display, 503 hwc2_layer_t layer, hwc_region_t damage) { 504 return HWCSession::CallLayerFunction(device, display, layer, &HWCLayer::SetLayerSurfaceDamage, 505 damage); 506 } 507 508 static int32_t SetLayerTransform(hwc2_device_t *device, hwc2_display_t display, hwc2_layer_t layer, 509 int32_t int_transform) { 510 auto transform = static_cast<HWC2::Transform>(int_transform); 511 return HWCSession::CallLayerFunction(device, display, layer, &HWCLayer::SetLayerTransform, 512 transform); 513 } 514 515 static int32_t SetLayerVisibleRegion(hwc2_device_t *device, hwc2_display_t display, 516 hwc2_layer_t layer, hwc_region_t visible) { 517 return HWCSession::CallLayerFunction(device, display, layer, &HWCLayer::SetLayerVisibleRegion, 518 visible); 519 } 520 521 int32_t HWCSession::SetLayerZOrder(hwc2_device_t *device, hwc2_display_t display, 522 hwc2_layer_t layer, uint32_t z) { 523 SCOPE_LOCK(locker_); 524 return CallDisplayFunction(device, display, &HWCDisplay::SetLayerZOrder, layer, z); 525 } 526 527 int32_t HWCSession::SetOutputBuffer(hwc2_device_t *device, hwc2_display_t display, 528 buffer_handle_t buffer, int32_t releaseFence) { 529 if (!device) { 530 return HWC2_ERROR_BAD_DISPLAY; 531 } 532 533 auto *hwc_session = static_cast<HWCSession *>(device); 534 if (display == HWC_DISPLAY_VIRTUAL && hwc_session->hwc_display_[display]) { 535 auto vds = reinterpret_cast<HWCDisplayVirtual *>(hwc_session->hwc_display_[display]); 536 auto status = vds->SetOutputBuffer(buffer, releaseFence); 537 return INT32(status); 538 } else { 539 return HWC2_ERROR_BAD_DISPLAY; 540 } 541 } 542 543 int32_t HWCSession::SetPowerMode(hwc2_device_t *device, hwc2_display_t display, int32_t int_mode) { 544 auto mode = static_cast<HWC2::PowerMode>(int_mode); 545 SEQUENCE_WAIT_SCOPE_LOCK(locker_); 546 return CallDisplayFunction(device, display, &HWCDisplay::SetPowerMode, mode); 547 } 548 549 static int32_t SetVsyncEnabled(hwc2_device_t *device, hwc2_display_t display, int32_t int_enabled) { 550 auto enabled = static_cast<HWC2::Vsync>(int_enabled); 551 return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::SetVsyncEnabled, enabled); 552 } 553 554 int32_t HWCSession::ValidateDisplay(hwc2_device_t *device, hwc2_display_t display, 555 uint32_t *out_num_types, uint32_t *out_num_requests) { 556 DTRACE_SCOPED(); 557 HWCSession *hwc_session = static_cast<HWCSession *>(device); 558 if (!device) { 559 return HWC2_ERROR_BAD_DISPLAY; 560 } 561 562 // TODO(user): Handle secure session, handle QDCM solid fill 563 // Handle external_pending_connect_ in CreateVirtualDisplay 564 auto status = HWC2::Error::BadDisplay; 565 if (hwc_session->hwc_display_[display]) { 566 SEQUENCE_ENTRY_SCOPE_LOCK(locker_); 567 if (display == HWC_DISPLAY_PRIMARY) { 568 // TODO(user): This can be moved to HWCDisplayPrimary 569 if (hwc_session->reset_panel_) { 570 DLOGW("panel is in bad state, resetting the panel"); 571 hwc_session->ResetPanel(); 572 } 573 574 if (hwc_session->need_invalidate_) { 575 hwc_session->callbacks_.Refresh(display); 576 } 577 } 578 579 status = hwc_session->hwc_display_[display]->Validate(out_num_types, out_num_requests); 580 } 581 // If validate fails, cancel the sequence lock so that other operations 582 // (such as Dump or SetPowerMode) may succeed without blocking on the condition 583 if (status == HWC2::Error::BadDisplay) { 584 SEQUENCE_CANCEL_SCOPE_LOCK(locker_); 585 } 586 return INT32(status); 587 } 588 589 hwc2_function_pointer_t HWCSession::GetFunction(struct hwc2_device *device, 590 int32_t int_descriptor) { 591 auto descriptor = static_cast<HWC2::FunctionDescriptor>(int_descriptor); 592 593 switch (descriptor) { 594 case HWC2::FunctionDescriptor::AcceptDisplayChanges: 595 return AsFP<HWC2_PFN_ACCEPT_DISPLAY_CHANGES>(HWCSession::AcceptDisplayChanges); 596 case HWC2::FunctionDescriptor::CreateLayer: 597 return AsFP<HWC2_PFN_CREATE_LAYER>(CreateLayer); 598 case HWC2::FunctionDescriptor::CreateVirtualDisplay: 599 return AsFP<HWC2_PFN_CREATE_VIRTUAL_DISPLAY>(HWCSession::CreateVirtualDisplay); 600 case HWC2::FunctionDescriptor::DestroyLayer: 601 return AsFP<HWC2_PFN_DESTROY_LAYER>(DestroyLayer); 602 case HWC2::FunctionDescriptor::DestroyVirtualDisplay: 603 return AsFP<HWC2_PFN_DESTROY_VIRTUAL_DISPLAY>(HWCSession::DestroyVirtualDisplay); 604 case HWC2::FunctionDescriptor::Dump: 605 return AsFP<HWC2_PFN_DUMP>(HWCSession::Dump); 606 case HWC2::FunctionDescriptor::GetActiveConfig: 607 return AsFP<HWC2_PFN_GET_ACTIVE_CONFIG>(GetActiveConfig); 608 case HWC2::FunctionDescriptor::GetChangedCompositionTypes: 609 return AsFP<HWC2_PFN_GET_CHANGED_COMPOSITION_TYPES>(GetChangedCompositionTypes); 610 case HWC2::FunctionDescriptor::GetClientTargetSupport: 611 return AsFP<HWC2_PFN_GET_CLIENT_TARGET_SUPPORT>(GetClientTargetSupport); 612 case HWC2::FunctionDescriptor::GetColorModes: 613 return AsFP<HWC2_PFN_GET_COLOR_MODES>(GetColorModes); 614 case HWC2::FunctionDescriptor::GetDisplayAttribute: 615 return AsFP<HWC2_PFN_GET_DISPLAY_ATTRIBUTE>(GetDisplayAttribute); 616 case HWC2::FunctionDescriptor::GetDisplayConfigs: 617 return AsFP<HWC2_PFN_GET_DISPLAY_CONFIGS>(GetDisplayConfigs); 618 case HWC2::FunctionDescriptor::GetDisplayName: 619 return AsFP<HWC2_PFN_GET_DISPLAY_NAME>(GetDisplayName); 620 case HWC2::FunctionDescriptor::GetDisplayRequests: 621 return AsFP<HWC2_PFN_GET_DISPLAY_REQUESTS>(GetDisplayRequests); 622 case HWC2::FunctionDescriptor::GetDisplayType: 623 return AsFP<HWC2_PFN_GET_DISPLAY_TYPE>(GetDisplayType); 624 case HWC2::FunctionDescriptor::GetHdrCapabilities: 625 return AsFP<HWC2_PFN_GET_HDR_CAPABILITIES>(GetHdrCapabilities); 626 case HWC2::FunctionDescriptor::GetDozeSupport: 627 return AsFP<HWC2_PFN_GET_DOZE_SUPPORT>(GetDozeSupport); 628 case HWC2::FunctionDescriptor::GetMaxVirtualDisplayCount: 629 return AsFP<HWC2_PFN_GET_MAX_VIRTUAL_DISPLAY_COUNT>(GetMaxVirtualDisplayCount); 630 case HWC2::FunctionDescriptor::GetReleaseFences: 631 return AsFP<HWC2_PFN_GET_RELEASE_FENCES>(GetReleaseFences); 632 case HWC2::FunctionDescriptor::PresentDisplay: 633 return AsFP<HWC2_PFN_PRESENT_DISPLAY>(PresentDisplay); 634 case HWC2::FunctionDescriptor::RegisterCallback: 635 return AsFP<HWC2_PFN_REGISTER_CALLBACK>(RegisterCallback); 636 case HWC2::FunctionDescriptor::SetActiveConfig: 637 return AsFP<HWC2_PFN_SET_ACTIVE_CONFIG>(SetActiveConfig); 638 case HWC2::FunctionDescriptor::SetClientTarget: 639 return AsFP<HWC2_PFN_SET_CLIENT_TARGET>(SetClientTarget); 640 case HWC2::FunctionDescriptor::SetColorMode: 641 return AsFP<HWC2_PFN_SET_COLOR_MODE>(SetColorMode); 642 case HWC2::FunctionDescriptor::SetColorTransform: 643 return AsFP<HWC2_PFN_SET_COLOR_TRANSFORM>(SetColorTransform); 644 case HWC2::FunctionDescriptor::SetCursorPosition: 645 return AsFP<HWC2_PFN_SET_CURSOR_POSITION>(SetCursorPosition); 646 case HWC2::FunctionDescriptor::SetLayerBlendMode: 647 return AsFP<HWC2_PFN_SET_LAYER_BLEND_MODE>(SetLayerBlendMode); 648 case HWC2::FunctionDescriptor::SetLayerBuffer: 649 return AsFP<HWC2_PFN_SET_LAYER_BUFFER>(SetLayerBuffer); 650 case HWC2::FunctionDescriptor::SetLayerColor: 651 return AsFP<HWC2_PFN_SET_LAYER_COLOR>(SetLayerColor); 652 case HWC2::FunctionDescriptor::SetLayerCompositionType: 653 return AsFP<HWC2_PFN_SET_LAYER_COMPOSITION_TYPE>(SetLayerCompositionType); 654 case HWC2::FunctionDescriptor::SetLayerDataspace: 655 return AsFP<HWC2_PFN_SET_LAYER_DATASPACE>(SetLayerDataspace); 656 case HWC2::FunctionDescriptor::SetLayerDisplayFrame: 657 return AsFP<HWC2_PFN_SET_LAYER_DISPLAY_FRAME>(SetLayerDisplayFrame); 658 case HWC2::FunctionDescriptor::SetLayerPlaneAlpha: 659 return AsFP<HWC2_PFN_SET_LAYER_PLANE_ALPHA>(SetLayerPlaneAlpha); 660 // Sideband stream is not supported 661 // case HWC2::FunctionDescriptor::SetLayerSidebandStream: 662 case HWC2::FunctionDescriptor::SetLayerSourceCrop: 663 return AsFP<HWC2_PFN_SET_LAYER_SOURCE_CROP>(SetLayerSourceCrop); 664 case HWC2::FunctionDescriptor::SetLayerSurfaceDamage: 665 return AsFP<HWC2_PFN_SET_LAYER_SURFACE_DAMAGE>(SetLayerSurfaceDamage); 666 case HWC2::FunctionDescriptor::SetLayerTransform: 667 return AsFP<HWC2_PFN_SET_LAYER_TRANSFORM>(SetLayerTransform); 668 case HWC2::FunctionDescriptor::SetLayerVisibleRegion: 669 return AsFP<HWC2_PFN_SET_LAYER_VISIBLE_REGION>(SetLayerVisibleRegion); 670 case HWC2::FunctionDescriptor::SetLayerZOrder: 671 return AsFP<HWC2_PFN_SET_LAYER_Z_ORDER>(SetLayerZOrder); 672 case HWC2::FunctionDescriptor::SetOutputBuffer: 673 return AsFP<HWC2_PFN_SET_OUTPUT_BUFFER>(SetOutputBuffer); 674 case HWC2::FunctionDescriptor::SetPowerMode: 675 return AsFP<HWC2_PFN_SET_POWER_MODE>(SetPowerMode); 676 case HWC2::FunctionDescriptor::SetVsyncEnabled: 677 return AsFP<HWC2_PFN_SET_VSYNC_ENABLED>(SetVsyncEnabled); 678 case HWC2::FunctionDescriptor::ValidateDisplay: 679 return AsFP<HWC2_PFN_VALIDATE_DISPLAY>(HWCSession::ValidateDisplay); 680 default: 681 DLOGD("Unknown/Unimplemented function descriptor: %d (%s)", int_descriptor, 682 to_string(descriptor).c_str()); 683 return nullptr; 684 } 685 return nullptr; 686 } 687 688 // TODO(user): handle locking 689 690 HWC2::Error HWCSession::CreateVirtualDisplayObject(uint32_t width, uint32_t height, 691 int32_t *format) { 692 if (hwc_display_[HWC_DISPLAY_VIRTUAL]) { 693 return HWC2::Error::NoResources; 694 } 695 auto status = HWCDisplayVirtual::Create(core_intf_, &callbacks_, width, height, format, 696 &hwc_display_[HWC_DISPLAY_VIRTUAL]); 697 // TODO(user): validate width and height support 698 if (status) 699 return HWC2::Error::Unsupported; 700 701 return HWC2::Error::None; 702 } 703 704 int32_t HWCSession::ConnectDisplay(int disp) { 705 DLOGI("Display = %d", disp); 706 707 int status = 0; 708 uint32_t primary_width = 0; 709 uint32_t primary_height = 0; 710 711 hwc_display_[HWC_DISPLAY_PRIMARY]->GetFrameBufferResolution(&primary_width, &primary_height); 712 713 if (disp == HWC_DISPLAY_EXTERNAL) { 714 status = HWCDisplayExternal::Create(core_intf_, &callbacks_, primary_width, primary_height, 715 qservice_, false, &hwc_display_[disp]); 716 } else { 717 DLOGE("Invalid display type"); 718 return -1; 719 } 720 721 if (!status) { 722 hwc_display_[disp]->SetSecureDisplay(secure_display_active_); 723 } 724 725 return status; 726 } 727 728 int HWCSession::DisconnectDisplay(int disp) { 729 DLOGI("Display = %d", disp); 730 731 if (disp == HWC_DISPLAY_EXTERNAL) { 732 HWCDisplayExternal::Destroy(hwc_display_[disp]); 733 } else if (disp == HWC_DISPLAY_VIRTUAL) { 734 HWCDisplayVirtual::Destroy(hwc_display_[disp]); 735 } else { 736 DLOGE("Invalid display type"); 737 return -1; 738 } 739 740 hwc_display_[disp] = NULL; 741 742 return 0; 743 } 744 745 // Qclient methods 746 android::status_t HWCSession::notifyCallback(uint32_t command, const android::Parcel *input_parcel, 747 android::Parcel *output_parcel) { 748 SEQUENCE_WAIT_SCOPE_LOCK(locker_); 749 750 android::status_t status = 0; 751 752 switch (command) { 753 case qService::IQService::DYNAMIC_DEBUG: 754 DynamicDebug(input_parcel); 755 break; 756 757 case qService::IQService::SCREEN_REFRESH: 758 callbacks_.Refresh(HWC_DISPLAY_PRIMARY); 759 break; 760 761 case qService::IQService::SET_IDLE_TIMEOUT: 762 if (hwc_display_[HWC_DISPLAY_PRIMARY]) { 763 uint32_t timeout = UINT32(input_parcel->readInt32()); 764 hwc_display_[HWC_DISPLAY_PRIMARY]->SetIdleTimeoutMs(timeout); 765 } 766 break; 767 768 case qService::IQService::SET_FRAME_DUMP_CONFIG: 769 SetFrameDumpConfig(input_parcel); 770 break; 771 772 case qService::IQService::SET_MAX_PIPES_PER_MIXER: 773 status = SetMaxMixerStages(input_parcel); 774 break; 775 776 case qService::IQService::SET_DISPLAY_MODE: 777 status = SetDisplayMode(input_parcel); 778 break; 779 780 case qService::IQService::SET_SECONDARY_DISPLAY_STATUS: 781 status = SetSecondaryDisplayStatus(input_parcel, output_parcel); 782 break; 783 784 case qService::IQService::CONFIGURE_DYN_REFRESH_RATE: 785 status = ConfigureRefreshRate(input_parcel); 786 break; 787 788 case qService::IQService::SET_VIEW_FRAME: 789 break; 790 791 case qService::IQService::TOGGLE_SCREEN_UPDATES: 792 status = ToggleScreenUpdates(input_parcel, output_parcel); 793 break; 794 795 case qService::IQService::QDCM_SVC_CMDS: 796 status = QdcmCMDHandler(input_parcel, output_parcel); 797 break; 798 799 case qService::IQService::MIN_HDCP_ENCRYPTION_LEVEL_CHANGED: 800 status = OnMinHdcpEncryptionLevelChange(input_parcel, output_parcel); 801 break; 802 803 case qService::IQService::CONTROL_PARTIAL_UPDATE: 804 status = ControlPartialUpdate(input_parcel, output_parcel); 805 break; 806 807 case qService::IQService::SET_ACTIVE_CONFIG: 808 status = HandleSetActiveDisplayConfig(input_parcel, output_parcel); 809 break; 810 811 case qService::IQService::GET_ACTIVE_CONFIG: 812 status = HandleGetActiveDisplayConfig(input_parcel, output_parcel); 813 break; 814 815 case qService::IQService::GET_CONFIG_COUNT: 816 status = HandleGetDisplayConfigCount(input_parcel, output_parcel); 817 break; 818 819 case qService::IQService::GET_DISPLAY_ATTRIBUTES_FOR_CONFIG: 820 status = HandleGetDisplayAttributesForConfig(input_parcel, output_parcel); 821 break; 822 823 case qService::IQService::GET_PANEL_BRIGHTNESS: 824 status = GetPanelBrightness(input_parcel, output_parcel); 825 break; 826 827 case qService::IQService::SET_PANEL_BRIGHTNESS: 828 status = SetPanelBrightness(input_parcel, output_parcel); 829 break; 830 831 case qService::IQService::GET_DISPLAY_VISIBLE_REGION: 832 status = GetVisibleDisplayRect(input_parcel, output_parcel); 833 break; 834 835 case qService::IQService::SET_CAMERA_STATUS: 836 status = SetDynamicBWForCamera(input_parcel, output_parcel); 837 break; 838 839 case qService::IQService::GET_BW_TRANSACTION_STATUS: 840 status = GetBWTransactionStatus(input_parcel, output_parcel); 841 break; 842 843 case qService::IQService::SET_LAYER_MIXER_RESOLUTION: 844 status = SetMixerResolution(input_parcel); 845 break; 846 847 case qService::IQService::SET_COLOR_MODE: 848 status = SetColorModeOverride(input_parcel); 849 break; 850 851 default: 852 DLOGW("QService command = %d is not supported", command); 853 return -EINVAL; 854 } 855 856 return status; 857 } 858 859 android::status_t HWCSession::ToggleScreenUpdates(const android::Parcel *input_parcel, 860 android::Parcel *output_parcel) { 861 int input = input_parcel->readInt32(); 862 int error = android::BAD_VALUE; 863 864 if (hwc_display_[HWC_DISPLAY_PRIMARY] && (input <= 1) && (input >= 0)) { 865 error = hwc_display_[HWC_DISPLAY_PRIMARY]->ToggleScreenUpdates(input == 1); 866 if (error != 0) { 867 DLOGE("Failed to toggle screen updates = %d. Error = %d", input, error); 868 } 869 } 870 output_parcel->writeInt32(error); 871 872 return error; 873 } 874 875 android::status_t HWCSession::SetPanelBrightness(const android::Parcel *input_parcel, 876 android::Parcel *output_parcel) { 877 int level = input_parcel->readInt32(); 878 int error = android::BAD_VALUE; 879 880 if (hwc_display_[HWC_DISPLAY_PRIMARY]) { 881 error = hwc_display_[HWC_DISPLAY_PRIMARY]->SetPanelBrightness(level); 882 if (error != 0) { 883 DLOGE("Failed to set the panel brightness = %d. Error = %d", level, error); 884 } 885 } 886 output_parcel->writeInt32(error); 887 888 return error; 889 } 890 891 android::status_t HWCSession::GetPanelBrightness(const android::Parcel *input_parcel, 892 android::Parcel *output_parcel) { 893 int error = android::BAD_VALUE; 894 int ret = error; 895 896 if (hwc_display_[HWC_DISPLAY_PRIMARY]) { 897 error = hwc_display_[HWC_DISPLAY_PRIMARY]->GetPanelBrightness(&ret); 898 if (error != 0) { 899 ret = error; 900 DLOGE("Failed to get the panel brightness. Error = %d", error); 901 } 902 } 903 output_parcel->writeInt32(ret); 904 905 return error; 906 } 907 908 android::status_t HWCSession::ControlPartialUpdate(const android::Parcel *input_parcel, 909 android::Parcel *out) { 910 DisplayError error = kErrorNone; 911 int ret = 0; 912 uint32_t disp_id = UINT32(input_parcel->readInt32()); 913 uint32_t enable = UINT32(input_parcel->readInt32()); 914 915 if (disp_id != HWC_DISPLAY_PRIMARY) { 916 DLOGW("CONTROL_PARTIAL_UPDATE is not applicable for display = %d", disp_id); 917 ret = -EINVAL; 918 out->writeInt32(ret); 919 return ret; 920 } 921 922 if (!hwc_display_[HWC_DISPLAY_PRIMARY]) { 923 DLOGE("primary display object is not instantiated"); 924 ret = -EINVAL; 925 out->writeInt32(ret); 926 return ret; 927 } 928 929 uint32_t pending = 0; 930 error = hwc_display_[HWC_DISPLAY_PRIMARY]->ControlPartialUpdate(enable, &pending); 931 932 if (error == kErrorNone) { 933 if (!pending) { 934 out->writeInt32(ret); 935 return ret; 936 } 937 } else if (error == kErrorNotSupported) { 938 out->writeInt32(ret); 939 return ret; 940 } else { 941 ret = -EINVAL; 942 out->writeInt32(ret); 943 return ret; 944 } 945 946 // Todo(user): Unlock it before sending events to client. It may cause deadlocks in future. 947 callbacks_.Refresh(HWC_DISPLAY_PRIMARY); 948 949 // Wait until partial update control is complete 950 ret = locker_.WaitFinite(kPartialUpdateControlTimeoutMs); 951 952 out->writeInt32(ret); 953 954 return ret; 955 } 956 957 android::status_t HWCSession::HandleSetActiveDisplayConfig(const android::Parcel *input_parcel, 958 android::Parcel *output_parcel) { 959 int config = input_parcel->readInt32(); 960 int dpy = input_parcel->readInt32(); 961 int error = android::BAD_VALUE; 962 963 if (dpy > HWC_DISPLAY_VIRTUAL) { 964 return android::BAD_VALUE; 965 } 966 967 if (hwc_display_[dpy]) { 968 error = hwc_display_[dpy]->SetActiveDisplayConfig(config); 969 if (error == 0) { 970 callbacks_.Refresh(0); 971 } 972 } 973 974 return error; 975 } 976 977 android::status_t HWCSession::HandleGetActiveDisplayConfig(const android::Parcel *input_parcel, 978 android::Parcel *output_parcel) { 979 int dpy = input_parcel->readInt32(); 980 int error = android::BAD_VALUE; 981 982 if (dpy > HWC_DISPLAY_VIRTUAL) { 983 return android::BAD_VALUE; 984 } 985 986 if (hwc_display_[dpy]) { 987 uint32_t config = 0; 988 error = hwc_display_[dpy]->GetActiveDisplayConfig(&config); 989 if (error == 0) { 990 output_parcel->writeInt32(INT(config)); 991 } 992 } 993 994 return error; 995 } 996 997 android::status_t HWCSession::HandleGetDisplayConfigCount(const android::Parcel *input_parcel, 998 android::Parcel *output_parcel) { 999 int dpy = input_parcel->readInt32(); 1000 int error = android::BAD_VALUE; 1001 1002 if (dpy > HWC_DISPLAY_VIRTUAL) { 1003 return android::BAD_VALUE; 1004 } 1005 1006 uint32_t count = 0; 1007 if (hwc_display_[dpy]) { 1008 error = hwc_display_[dpy]->GetDisplayConfigCount(&count); 1009 if (error == 0) { 1010 output_parcel->writeInt32(INT(count)); 1011 } 1012 } 1013 1014 return error; 1015 } 1016 1017 android::status_t HWCSession::HandleGetDisplayAttributesForConfig(const android::Parcel 1018 *input_parcel, 1019 android::Parcel *output_parcel) { 1020 int config = input_parcel->readInt32(); 1021 int dpy = input_parcel->readInt32(); 1022 int error = android::BAD_VALUE; 1023 DisplayConfigVariableInfo display_attributes; 1024 1025 if (dpy > HWC_DISPLAY_VIRTUAL) { 1026 return android::BAD_VALUE; 1027 } 1028 1029 if (hwc_display_[dpy]) { 1030 error = hwc_display_[dpy]->GetDisplayAttributesForConfig(config, &display_attributes); 1031 if (error == 0) { 1032 output_parcel->writeInt32(INT(display_attributes.vsync_period_ns)); 1033 output_parcel->writeInt32(INT(display_attributes.x_pixels)); 1034 output_parcel->writeInt32(INT(display_attributes.y_pixels)); 1035 output_parcel->writeFloat(display_attributes.x_dpi); 1036 output_parcel->writeFloat(display_attributes.y_dpi); 1037 output_parcel->writeInt32(0); // Panel type, unsupported. 1038 } 1039 } 1040 1041 return error; 1042 } 1043 1044 android::status_t HWCSession::SetSecondaryDisplayStatus(const android::Parcel *input_parcel, 1045 android::Parcel *output_parcel) { 1046 int ret = -EINVAL; 1047 1048 uint32_t display_id = UINT32(input_parcel->readInt32()); 1049 uint32_t display_status = UINT32(input_parcel->readInt32()); 1050 1051 DLOGI("Display = %d, Status = %d", display_id, display_status); 1052 1053 if (display_id >= HWC_NUM_DISPLAY_TYPES) { 1054 DLOGE("Invalid display_id"); 1055 } else if (display_id == HWC_DISPLAY_PRIMARY) { 1056 DLOGE("Not supported for this display"); 1057 } else if (!hwc_display_[display_id]) { 1058 DLOGW("Display is not connected"); 1059 } else { 1060 ret = hwc_display_[display_id]->SetDisplayStatus(display_status); 1061 } 1062 1063 output_parcel->writeInt32(ret); 1064 1065 return ret; 1066 } 1067 1068 android::status_t HWCSession::ConfigureRefreshRate(const android::Parcel *input_parcel) { 1069 uint32_t operation = UINT32(input_parcel->readInt32()); 1070 switch (operation) { 1071 case qdutils::DISABLE_METADATA_DYN_REFRESH_RATE: 1072 return hwc_display_[HWC_DISPLAY_PRIMARY]->Perform( 1073 HWCDisplayPrimary::SET_METADATA_DYN_REFRESH_RATE, false); 1074 case qdutils::ENABLE_METADATA_DYN_REFRESH_RATE: 1075 return hwc_display_[HWC_DISPLAY_PRIMARY]->Perform( 1076 HWCDisplayPrimary::SET_METADATA_DYN_REFRESH_RATE, true); 1077 case qdutils::SET_BINDER_DYN_REFRESH_RATE: { 1078 uint32_t refresh_rate = UINT32(input_parcel->readInt32()); 1079 return hwc_display_[HWC_DISPLAY_PRIMARY]->Perform( 1080 HWCDisplayPrimary::SET_BINDER_DYN_REFRESH_RATE, refresh_rate); 1081 } 1082 default: 1083 DLOGW("Invalid operation %d", operation); 1084 return -EINVAL; 1085 } 1086 1087 return 0; 1088 } 1089 1090 android::status_t HWCSession::SetDisplayMode(const android::Parcel *input_parcel) { 1091 uint32_t mode = UINT32(input_parcel->readInt32()); 1092 return hwc_display_[HWC_DISPLAY_PRIMARY]->Perform(HWCDisplayPrimary::SET_DISPLAY_MODE, mode); 1093 } 1094 1095 android::status_t HWCSession::SetMaxMixerStages(const android::Parcel *input_parcel) { 1096 DisplayError error = kErrorNone; 1097 std::bitset<32> bit_mask_display_type = UINT32(input_parcel->readInt32()); 1098 uint32_t max_mixer_stages = UINT32(input_parcel->readInt32()); 1099 1100 if (bit_mask_display_type[HWC_DISPLAY_PRIMARY]) { 1101 if (hwc_display_[HWC_DISPLAY_PRIMARY]) { 1102 error = hwc_display_[HWC_DISPLAY_PRIMARY]->SetMaxMixerStages(max_mixer_stages); 1103 if (error != kErrorNone) { 1104 return -EINVAL; 1105 } 1106 } 1107 } 1108 1109 if (bit_mask_display_type[HWC_DISPLAY_EXTERNAL]) { 1110 if (hwc_display_[HWC_DISPLAY_EXTERNAL]) { 1111 error = hwc_display_[HWC_DISPLAY_EXTERNAL]->SetMaxMixerStages(max_mixer_stages); 1112 if (error != kErrorNone) { 1113 return -EINVAL; 1114 } 1115 } 1116 } 1117 1118 if (bit_mask_display_type[HWC_DISPLAY_VIRTUAL]) { 1119 if (hwc_display_[HWC_DISPLAY_VIRTUAL]) { 1120 error = hwc_display_[HWC_DISPLAY_VIRTUAL]->SetMaxMixerStages(max_mixer_stages); 1121 if (error != kErrorNone) { 1122 return -EINVAL; 1123 } 1124 } 1125 } 1126 1127 return 0; 1128 } 1129 1130 android::status_t HWCSession::SetDynamicBWForCamera(const android::Parcel *input_parcel, 1131 android::Parcel *output_parcel) { 1132 DisplayError error = kErrorNone; 1133 uint32_t camera_status = UINT32(input_parcel->readInt32()); 1134 HWBwModes mode = camera_status > 0 ? kBwCamera : kBwDefault; 1135 1136 // trigger invalidate to apply new bw caps. 1137 callbacks_.Refresh(HWC_DISPLAY_PRIMARY); 1138 1139 error = core_intf_->SetMaxBandwidthMode(mode); 1140 if (error != kErrorNone) { 1141 return -EINVAL; 1142 } 1143 1144 new_bw_mode_ = true; 1145 need_invalidate_ = true; 1146 1147 return 0; 1148 } 1149 1150 android::status_t HWCSession::GetBWTransactionStatus(const android::Parcel *input_parcel, 1151 android::Parcel *output_parcel) { 1152 bool state = true; 1153 1154 if (hwc_display_[HWC_DISPLAY_PRIMARY]) { 1155 if (sync_wait(bw_mode_release_fd_, 0) < 0) { 1156 DLOGI("bw_transaction_release_fd is not yet signalled: err= %s", strerror(errno)); 1157 state = false; 1158 } 1159 output_parcel->writeInt32(state); 1160 } 1161 1162 return 0; 1163 } 1164 1165 void HWCSession::SetFrameDumpConfig(const android::Parcel *input_parcel) { 1166 uint32_t frame_dump_count = UINT32(input_parcel->readInt32()); 1167 std::bitset<32> bit_mask_display_type = UINT32(input_parcel->readInt32()); 1168 uint32_t bit_mask_layer_type = UINT32(input_parcel->readInt32()); 1169 1170 if (bit_mask_display_type[HWC_DISPLAY_PRIMARY]) { 1171 if (hwc_display_[HWC_DISPLAY_PRIMARY]) { 1172 hwc_display_[HWC_DISPLAY_PRIMARY]->SetFrameDumpConfig(frame_dump_count, bit_mask_layer_type); 1173 } 1174 } 1175 1176 if (bit_mask_display_type[HWC_DISPLAY_EXTERNAL]) { 1177 if (hwc_display_[HWC_DISPLAY_EXTERNAL]) { 1178 hwc_display_[HWC_DISPLAY_EXTERNAL]->SetFrameDumpConfig(frame_dump_count, bit_mask_layer_type); 1179 } 1180 } 1181 1182 if (bit_mask_display_type[HWC_DISPLAY_VIRTUAL]) { 1183 if (hwc_display_[HWC_DISPLAY_VIRTUAL]) { 1184 hwc_display_[HWC_DISPLAY_VIRTUAL]->SetFrameDumpConfig(frame_dump_count, bit_mask_layer_type); 1185 } 1186 } 1187 } 1188 1189 android::status_t HWCSession::SetMixerResolution(const android::Parcel *input_parcel) { 1190 DisplayError error = kErrorNone; 1191 uint32_t dpy = UINT32(input_parcel->readInt32()); 1192 1193 if (dpy != HWC_DISPLAY_PRIMARY) { 1194 DLOGI("Resoulution change not supported for this display %d", dpy); 1195 return -EINVAL; 1196 } 1197 1198 if (!hwc_display_[HWC_DISPLAY_PRIMARY]) { 1199 DLOGI("Primary display is not initialized"); 1200 return -EINVAL; 1201 } 1202 1203 uint32_t width = UINT32(input_parcel->readInt32()); 1204 uint32_t height = UINT32(input_parcel->readInt32()); 1205 1206 error = hwc_display_[HWC_DISPLAY_PRIMARY]->SetMixerResolution(width, height); 1207 if (error != kErrorNone) { 1208 return -EINVAL; 1209 } 1210 1211 return 0; 1212 } 1213 1214 android::status_t HWCSession::SetColorModeOverride(const android::Parcel *input_parcel) { 1215 auto display = static_cast<hwc2_display_t >(input_parcel->readInt32()); 1216 auto mode = static_cast<android_color_mode_t>(input_parcel->readInt32()); 1217 auto device = static_cast<hwc2_device_t *>(this); 1218 auto err = CallDisplayFunction(device, display, &HWCDisplay::SetColorMode, mode); 1219 if (err != HWC2_ERROR_NONE) 1220 return -EINVAL; 1221 return 0; 1222 } 1223 1224 void HWCSession::DynamicDebug(const android::Parcel *input_parcel) { 1225 int type = input_parcel->readInt32(); 1226 bool enable = (input_parcel->readInt32() > 0); 1227 DLOGI("type = %d enable = %d", type, enable); 1228 int verbose_level = input_parcel->readInt32(); 1229 1230 switch (type) { 1231 case qService::IQService::DEBUG_ALL: 1232 HWCDebugHandler::DebugAll(enable, verbose_level); 1233 break; 1234 1235 case qService::IQService::DEBUG_MDPCOMP: 1236 HWCDebugHandler::DebugStrategy(enable, verbose_level); 1237 HWCDebugHandler::DebugCompManager(enable, verbose_level); 1238 break; 1239 1240 case qService::IQService::DEBUG_PIPE_LIFECYCLE: 1241 HWCDebugHandler::DebugResources(enable, verbose_level); 1242 break; 1243 1244 case qService::IQService::DEBUG_DRIVER_CONFIG: 1245 HWCDebugHandler::DebugDriverConfig(enable, verbose_level); 1246 break; 1247 1248 case qService::IQService::DEBUG_ROTATOR: 1249 HWCDebugHandler::DebugResources(enable, verbose_level); 1250 HWCDebugHandler::DebugDriverConfig(enable, verbose_level); 1251 HWCDebugHandler::DebugRotator(enable, verbose_level); 1252 break; 1253 1254 case qService::IQService::DEBUG_QDCM: 1255 HWCDebugHandler::DebugQdcm(enable, verbose_level); 1256 break; 1257 1258 default: 1259 DLOGW("type = %d is not supported", type); 1260 } 1261 } 1262 1263 android::status_t HWCSession::QdcmCMDHandler(const android::Parcel *input_parcel, 1264 android::Parcel *output_parcel) { 1265 int ret = 0; 1266 int32_t *brightness_value = NULL; 1267 uint32_t display_id(0); 1268 PPPendingParams pending_action; 1269 PPDisplayAPIPayload resp_payload, req_payload; 1270 1271 if (!color_mgr_) { 1272 return -1; 1273 } 1274 1275 pending_action.action = kNoAction; 1276 pending_action.params = NULL; 1277 1278 // Read display_id, payload_size and payload from in_parcel. 1279 ret = HWCColorManager::CreatePayloadFromParcel(*input_parcel, &display_id, &req_payload); 1280 if (!ret) { 1281 if (HWC_DISPLAY_PRIMARY == display_id && hwc_display_[HWC_DISPLAY_PRIMARY]) 1282 ret = hwc_display_[HWC_DISPLAY_PRIMARY]->ColorSVCRequestRoute(req_payload, &resp_payload, 1283 &pending_action); 1284 1285 if (HWC_DISPLAY_EXTERNAL == display_id && hwc_display_[HWC_DISPLAY_EXTERNAL]) 1286 ret = hwc_display_[HWC_DISPLAY_EXTERNAL]->ColorSVCRequestRoute(req_payload, &resp_payload, 1287 &pending_action); 1288 } 1289 1290 if (ret) { 1291 output_parcel->writeInt32(ret); // first field in out parcel indicates return code. 1292 req_payload.DestroyPayload(); 1293 resp_payload.DestroyPayload(); 1294 return ret; 1295 } 1296 1297 switch (pending_action.action) { 1298 case kInvalidating: 1299 callbacks_.Refresh(HWC_DISPLAY_PRIMARY); 1300 break; 1301 case kEnterQDCMMode: 1302 ret = color_mgr_->EnableQDCMMode(true, hwc_display_[HWC_DISPLAY_PRIMARY]); 1303 break; 1304 case kExitQDCMMode: 1305 ret = color_mgr_->EnableQDCMMode(false, hwc_display_[HWC_DISPLAY_PRIMARY]); 1306 break; 1307 case kApplySolidFill: 1308 ret = 1309 color_mgr_->SetSolidFill(pending_action.params, true, hwc_display_[HWC_DISPLAY_PRIMARY]); 1310 callbacks_.Refresh(HWC_DISPLAY_PRIMARY); 1311 break; 1312 case kDisableSolidFill: 1313 ret = 1314 color_mgr_->SetSolidFill(pending_action.params, false, hwc_display_[HWC_DISPLAY_PRIMARY]); 1315 callbacks_.Refresh(HWC_DISPLAY_PRIMARY); 1316 break; 1317 case kSetPanelBrightness: 1318 brightness_value = reinterpret_cast<int32_t *>(resp_payload.payload); 1319 if (brightness_value == NULL) { 1320 DLOGE("Brightness value is Null"); 1321 return -EINVAL; 1322 } 1323 if (HWC_DISPLAY_PRIMARY == display_id) 1324 ret = hwc_display_[HWC_DISPLAY_PRIMARY]->SetPanelBrightness(*brightness_value); 1325 break; 1326 case kEnableFrameCapture: 1327 ret = color_mgr_->SetFrameCapture(pending_action.params, true, 1328 hwc_display_[HWC_DISPLAY_PRIMARY]); 1329 callbacks_.Refresh(HWC_DISPLAY_PRIMARY); 1330 break; 1331 case kDisableFrameCapture: 1332 ret = color_mgr_->SetFrameCapture(pending_action.params, false, 1333 hwc_display_[HWC_DISPLAY_PRIMARY]); 1334 break; 1335 case kNoAction: 1336 break; 1337 default: 1338 DLOGW("Invalid pending action = %d!", pending_action.action); 1339 break; 1340 } 1341 1342 // for display API getter case, marshall returned params into out_parcel. 1343 output_parcel->writeInt32(ret); 1344 HWCColorManager::MarshallStructIntoParcel(resp_payload, output_parcel); 1345 req_payload.DestroyPayload(); 1346 resp_payload.DestroyPayload(); 1347 1348 return (ret ? -EINVAL : 0); 1349 } 1350 1351 android::status_t HWCSession::OnMinHdcpEncryptionLevelChange(const android::Parcel *input_parcel, 1352 android::Parcel *output_parcel) { 1353 int ret = -EINVAL; 1354 uint32_t display_id = UINT32(input_parcel->readInt32()); 1355 uint32_t min_enc_level = UINT32(input_parcel->readInt32()); 1356 1357 DLOGI("Display %d", display_id); 1358 1359 if (display_id >= HWC_NUM_DISPLAY_TYPES) { 1360 DLOGE("Invalid display_id"); 1361 } else if (display_id != HWC_DISPLAY_EXTERNAL) { 1362 DLOGE("Not supported for display"); 1363 } else if (!hwc_display_[display_id]) { 1364 DLOGW("Display is not connected"); 1365 } else { 1366 ret = hwc_display_[display_id]->OnMinHdcpEncryptionLevelChange(min_enc_level); 1367 } 1368 1369 output_parcel->writeInt32(ret); 1370 1371 return ret; 1372 } 1373 1374 void *HWCSession::HWCUeventThread(void *context) { 1375 if (context) { 1376 return reinterpret_cast<HWCSession *>(context)->HWCUeventThreadHandler(); 1377 } 1378 1379 return NULL; 1380 } 1381 1382 void *HWCSession::HWCUeventThreadHandler() { 1383 static char uevent_data[PAGE_SIZE]; 1384 int length = 0; 1385 prctl(PR_SET_NAME, uevent_thread_name_, 0, 0, 0); 1386 setpriority(PRIO_PROCESS, 0, HAL_PRIORITY_URGENT_DISPLAY); 1387 if (!uevent_init()) { 1388 DLOGE("Failed to init uevent"); 1389 pthread_exit(0); 1390 return NULL; 1391 } 1392 1393 while (!uevent_thread_exit_) { 1394 // keep last 2 zeroes to ensure double 0 termination 1395 length = uevent_next_event(uevent_data, INT32(sizeof(uevent_data)) - 2); 1396 1397 if (strcasestr(HWC_UEVENT_SWITCH_HDMI, uevent_data)) { 1398 DLOGI("Uevent HDMI = %s", uevent_data); 1399 int connected = GetEventValue(uevent_data, length, "SWITCH_STATE="); 1400 if (connected >= 0) { 1401 DLOGI("HDMI = %s", connected ? "connected" : "disconnected"); 1402 if (HotPlugHandler(connected) == -1) { 1403 DLOGE("Failed handling Hotplug = %s", connected ? "connected" : "disconnected"); 1404 } 1405 } 1406 } else if (strcasestr(HWC_UEVENT_GRAPHICS_FB0, uevent_data)) { 1407 DLOGI("Uevent FB0 = %s", uevent_data); 1408 int panel_reset = GetEventValue(uevent_data, length, "PANEL_ALIVE="); 1409 if (panel_reset == 0) { 1410 callbacks_.Refresh(0); 1411 reset_panel_ = true; 1412 } 1413 } 1414 } 1415 pthread_exit(0); 1416 1417 return NULL; 1418 } 1419 1420 int HWCSession::GetEventValue(const char *uevent_data, int length, const char *event_info) { 1421 const char *iterator_str = uevent_data; 1422 while (((iterator_str - uevent_data) <= length) && (*iterator_str)) { 1423 const char *pstr = strstr(iterator_str, event_info); 1424 if (pstr != NULL) { 1425 return (atoi(iterator_str + strlen(event_info))); 1426 } 1427 iterator_str += strlen(iterator_str) + 1; 1428 } 1429 1430 return -1; 1431 } 1432 1433 void HWCSession::ResetPanel() { 1434 HWC2::Error status; 1435 1436 DLOGI("Powering off primary"); 1437 status = hwc_display_[HWC_DISPLAY_PRIMARY]->SetPowerMode(HWC2::PowerMode::Off); 1438 if (status != HWC2::Error::None) { 1439 DLOGE("power-off on primary failed with error = %d", status); 1440 } 1441 1442 DLOGI("Restoring power mode on primary"); 1443 HWC2::PowerMode mode = hwc_display_[HWC_DISPLAY_PRIMARY]->GetLastPowerMode(); 1444 status = hwc_display_[HWC_DISPLAY_PRIMARY]->SetPowerMode(mode); 1445 if (status != HWC2::Error::None) { 1446 DLOGE("Setting power mode = %d on primary failed with error = %d", mode, status); 1447 } 1448 1449 status = hwc_display_[HWC_DISPLAY_PRIMARY]->SetVsyncEnabled(HWC2::Vsync::Enable); 1450 if (status != HWC2::Error::None) { 1451 DLOGE("enabling vsync failed for primary with error = %d", status); 1452 } 1453 1454 reset_panel_ = false; 1455 } 1456 1457 int HWCSession::HotPlugHandler(bool connected) { 1458 int status = 0; 1459 bool notify_hotplug = false; 1460 bool hdmi_primary = false; 1461 1462 // To prevent sending events to client while a lock is held, acquire scope locks only within 1463 // below scope so that those get automatically unlocked after the scope ends. 1464 { 1465 SEQUENCE_WAIT_SCOPE_LOCK(locker_); 1466 1467 if (!hwc_display_[HWC_DISPLAY_PRIMARY]) { 1468 DLOGE("Primary display is not connected."); 1469 return -1; 1470 } 1471 1472 HWCDisplay *primary_display = hwc_display_[HWC_DISPLAY_PRIMARY]; 1473 HWCDisplay *external_display = NULL; 1474 1475 if (primary_display->GetDisplayClass() == DISPLAY_CLASS_EXTERNAL) { 1476 external_display = static_cast<HWCDisplayExternal *>(hwc_display_[HWC_DISPLAY_PRIMARY]); 1477 hdmi_primary = true; 1478 } 1479 1480 // If primary display connected is a NULL display, then replace it with the external display 1481 if (connected) { 1482 // If we are in HDMI as primary and the primary display just got plugged in 1483 if (hwc_display_[HWC_DISPLAY_EXTERNAL]) { 1484 DLOGE("HDMI is already connected"); 1485 return -1; 1486 } 1487 1488 // Connect external display if virtual display is not connected. 1489 // Else, defer external display connection and process it when virtual display 1490 // tears down; Do not notify SurfaceFlinger since connection is deferred now. 1491 if (!hwc_display_[HWC_DISPLAY_VIRTUAL]) { 1492 status = ConnectDisplay(HWC_DISPLAY_EXTERNAL); 1493 if (status) { 1494 return status; 1495 } 1496 notify_hotplug = true; 1497 } else { 1498 DLOGI("Virtual display is connected, pending connection"); 1499 external_pending_connect_ = true; 1500 } 1501 } else { 1502 // Do not return error if external display is not in connected status. 1503 // Due to virtual display concurrency, external display connection might be still pending 1504 // but hdmi got disconnected before pending connection could be processed. 1505 1506 if (hdmi_primary) { 1507 assert(external_display != NULL); 1508 uint32_t x_res, y_res; 1509 external_display->GetFrameBufferResolution(&x_res, &y_res); 1510 // Need to manually disable VSYNC as SF is not aware of connect/disconnect cases 1511 // for HDMI as primary 1512 external_display->SetVsyncEnabled(HWC2::Vsync::Disable); 1513 HWCDisplayExternal::Destroy(external_display); 1514 1515 // In HWC2, primary displays can be hotplugged out 1516 notify_hotplug = true; 1517 } else { 1518 if (hwc_display_[HWC_DISPLAY_EXTERNAL]) { 1519 status = DisconnectDisplay(HWC_DISPLAY_EXTERNAL); 1520 notify_hotplug = true; 1521 } 1522 external_pending_connect_ = false; 1523 } 1524 } 1525 } 1526 1527 if (connected && notify_hotplug) { 1528 // trigger screen refresh to ensure sufficient resources are available to process new 1529 // new display connection. 1530 callbacks_.Refresh(0); 1531 uint32_t vsync_period = UINT32(GetVsyncPeriod(HWC_DISPLAY_PRIMARY)); 1532 usleep(vsync_period * 2 / 1000); 1533 } 1534 // notify client 1535 // Handle HDMI as primary here 1536 if (notify_hotplug) { 1537 callbacks_.Hotplug(HWC_DISPLAY_EXTERNAL, 1538 connected ? HWC2::Connection::Connected : HWC2::Connection::Disconnected); 1539 } 1540 1541 qservice_->onHdmiHotplug(INT(connected)); 1542 1543 return 0; 1544 } 1545 1546 int HWCSession::GetVsyncPeriod(int disp) { 1547 SCOPE_LOCK(locker_); 1548 // default value 1549 int32_t vsync_period = 1000000000l / 60; 1550 auto attribute = HWC2::Attribute::VsyncPeriod; 1551 1552 if (hwc_display_[disp]) { 1553 hwc_display_[disp]->GetDisplayAttribute(0, attribute, &vsync_period); 1554 } 1555 1556 return vsync_period; 1557 } 1558 1559 android::status_t HWCSession::GetVisibleDisplayRect(const android::Parcel *input_parcel, 1560 android::Parcel *output_parcel) { 1561 int dpy = input_parcel->readInt32(); 1562 1563 if (dpy < HWC_DISPLAY_PRIMARY || dpy > HWC_DISPLAY_VIRTUAL) { 1564 return android::BAD_VALUE; 1565 } 1566 1567 if (!hwc_display_[dpy]) { 1568 return android::NO_INIT; 1569 } 1570 1571 hwc_rect_t visible_rect = {0, 0, 0, 0}; 1572 int error = hwc_display_[dpy]->GetVisibleDisplayRect(&visible_rect); 1573 if (error < 0) { 1574 return error; 1575 } 1576 1577 output_parcel->writeInt32(visible_rect.left); 1578 output_parcel->writeInt32(visible_rect.top); 1579 output_parcel->writeInt32(visible_rect.right); 1580 output_parcel->writeInt32(visible_rect.bottom); 1581 1582 return android::NO_ERROR; 1583 } 1584 1585 } // namespace sdm 1586