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