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