1 /* 2 * Copyright (c) 2014 - 2017, The Linux Foundation. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without modification, are permitted 5 * provided that the following conditions are met: 6 * * Redistributions of source code must retain the above copyright notice, this list of 7 * conditions and the following disclaimer. 8 * * Redistributions in binary form must reproduce the above copyright notice, this list of 9 * conditions and the following disclaimer in the documentation and/or other materials provided 10 * with the distribution. 11 * * Neither the name of The Linux Foundation nor the names of its contributors may be used to 12 * endorse or promote products derived from this software without specific prior written 13 * permission. 14 * 15 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 16 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 17 * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 19 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 20 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 21 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 22 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23 */ 24 25 #include <stdio.h> 26 #include <utils/constants.h> 27 #include <utils/debug.h> 28 #include <utils/formats.h> 29 #include <utils/rect.h> 30 #include <string> 31 #include <vector> 32 #include <algorithm> 33 34 #include "display_base.h" 35 #include "hw_info_interface.h" 36 37 #define __CLASS__ "DisplayBase" 38 39 namespace sdm { 40 41 // TODO(user): Have a single structure handle carries all the interface pointers and variables. 42 DisplayBase::DisplayBase(DisplayType display_type, DisplayEventHandler *event_handler, 43 HWDeviceType hw_device_type, BufferSyncHandler *buffer_sync_handler, 44 BufferAllocator *buffer_allocator, CompManager *comp_manager, 45 HWInfoInterface *hw_info_intf) 46 : display_type_(display_type), event_handler_(event_handler), hw_device_type_(hw_device_type), 47 buffer_sync_handler_(buffer_sync_handler), buffer_allocator_(buffer_allocator), 48 comp_manager_(comp_manager), hw_info_intf_(hw_info_intf) { 49 } 50 51 DisplayError DisplayBase::Init() { 52 lock_guard<recursive_mutex> obj(recursive_mutex_); 53 DisplayError error = kErrorNone; 54 hw_panel_info_ = HWPanelInfo(); 55 hw_intf_->GetHWPanelInfo(&hw_panel_info_); 56 57 uint32_t active_index = 0; 58 hw_intf_->GetActiveConfig(&active_index); 59 hw_intf_->GetDisplayAttributes(active_index, &display_attributes_); 60 fb_config_ = display_attributes_; 61 62 error = Debug::GetMixerResolution(&mixer_attributes_.width, &mixer_attributes_.height); 63 if (error == kErrorNone) { 64 hw_intf_->SetMixerAttributes(mixer_attributes_); 65 } 66 67 error = hw_intf_->GetMixerAttributes(&mixer_attributes_); 68 if (error != kErrorNone) { 69 return error; 70 } 71 72 // Override x_pixels and y_pixels of frame buffer with mixer width and height 73 fb_config_.x_pixels = mixer_attributes_.width; 74 fb_config_.y_pixels = mixer_attributes_.height; 75 76 HWScaleLutInfo lut_info = {}; 77 error = comp_manager_->GetScaleLutConfig(&lut_info); 78 if (error == kErrorNone) { 79 error = hw_intf_->SetScaleLutConfig(&lut_info); 80 if (error != kErrorNone) { 81 goto CleanupOnError; 82 } 83 } 84 85 error = comp_manager_->RegisterDisplay(display_type_, display_attributes_, hw_panel_info_, 86 mixer_attributes_, fb_config_, &display_comp_ctx_); 87 if (error != kErrorNone) { 88 goto CleanupOnError; 89 } 90 91 if (hw_info_intf_) { 92 HWResourceInfo hw_resource_info = HWResourceInfo(); 93 hw_info_intf_->GetHWResourceInfo(&hw_resource_info); 94 auto max_mixer_stages = hw_resource_info.num_blending_stages; 95 int property_value = Debug::GetMaxPipesPerMixer(display_type_); 96 if (property_value >= 0) { 97 max_mixer_stages = std::min(UINT32(property_value), hw_resource_info.num_blending_stages); 98 } 99 DisplayBase::SetMaxMixerStages(max_mixer_stages); 100 } 101 102 color_mgr_ = ColorManagerProxy::CreateColorManagerProxy(display_type_, hw_intf_, 103 display_attributes_, hw_panel_info_); 104 if (!color_mgr_) { 105 DLOGW("Unable to create ColorManagerProxy for display = %d", display_type_); 106 } else if (InitializeColorModes() != kErrorNone) { 107 DLOGW("InitColorModes failed for display = %d", display_type_); 108 } 109 110 Debug::Get()->GetProperty("sdm.disable_hdr_lut_gen", &disable_hdr_lut_gen_); 111 112 return kErrorNone; 113 114 CleanupOnError: 115 if (display_comp_ctx_) { 116 comp_manager_->UnregisterDisplay(display_comp_ctx_); 117 } 118 119 return error; 120 } 121 122 DisplayError DisplayBase::Deinit() { 123 { // Scope for lock 124 lock_guard<recursive_mutex> obj(recursive_mutex_); 125 color_modes_.clear(); 126 color_mode_map_.clear(); 127 color_mode_attr_map_.clear(); 128 129 if (color_mgr_) { 130 delete color_mgr_; 131 color_mgr_ = NULL; 132 } 133 134 comp_manager_->UnregisterDisplay(display_comp_ctx_); 135 } 136 HWEventsInterface::Destroy(hw_events_intf_); 137 HWInterface::Destroy(hw_intf_); 138 139 return kErrorNone; 140 } 141 142 DisplayError DisplayBase::BuildLayerStackStats(LayerStack *layer_stack) { 143 std::vector<Layer *> &layers = layer_stack->layers; 144 HWLayersInfo &hw_layers_info = hw_layers_.info; 145 146 hw_layers_info.stack = layer_stack; 147 148 for (auto &layer : layers) { 149 if (layer->composition == kCompositionGPUTarget) { 150 hw_layers_info.gpu_target_index = hw_layers_info.app_layer_count; 151 break; 152 } 153 hw_layers_info.app_layer_count++; 154 } 155 156 DLOGV_IF(kTagNone, "LayerStack layer_count: %d, app_layer_count: %d, gpu_target_index: %d, " 157 "display type: %d", layers.size(), hw_layers_info.app_layer_count, 158 hw_layers_info.gpu_target_index, display_type_); 159 160 if (!hw_layers_info.app_layer_count) { 161 DLOGW("Layer count is zero"); 162 return kErrorNoAppLayers; 163 } 164 165 if (hw_layers_info.gpu_target_index) { 166 return ValidateGPUTargetParams(); 167 } 168 169 return kErrorNone; 170 } 171 172 DisplayError DisplayBase::ValidateGPUTargetParams() { 173 HWLayersInfo &hw_layers_info = hw_layers_.info; 174 Layer *gpu_target_layer = hw_layers_info.stack->layers.at(hw_layers_info.gpu_target_index); 175 176 if (!IsValid(gpu_target_layer->src_rect)) { 177 DLOGE("Invalid src rect for GPU target layer"); 178 return kErrorParameters; 179 } 180 181 if (!IsValid(gpu_target_layer->dst_rect)) { 182 DLOGE("Invalid dst rect for GPU target layer"); 183 return kErrorParameters; 184 } 185 186 float layer_mixer_width = FLOAT(mixer_attributes_.width); 187 float layer_mixer_height = FLOAT(mixer_attributes_.height); 188 float fb_width = FLOAT(fb_config_.x_pixels); 189 float fb_height = FLOAT(fb_config_.y_pixels); 190 LayerRect src_domain = (LayerRect){0.0f, 0.0f, fb_width, fb_height}; 191 LayerRect dst_domain = (LayerRect){0.0f, 0.0f, layer_mixer_width, layer_mixer_height}; 192 LayerRect out_rect = gpu_target_layer->dst_rect; 193 194 MapRect(src_domain, dst_domain, gpu_target_layer->dst_rect, &out_rect); 195 Normalize(1, 1, &out_rect); 196 197 auto gpu_target_layer_dst_xpixels = out_rect.right - out_rect.left; 198 auto gpu_target_layer_dst_ypixels = out_rect.bottom - out_rect.top; 199 200 if (gpu_target_layer_dst_xpixels > mixer_attributes_.width || 201 gpu_target_layer_dst_ypixels > mixer_attributes_.height) { 202 DLOGE("GPU target layer dst rect is not with in limits gpu wxh %fx%f, mixer wxh %dx%d", 203 gpu_target_layer_dst_xpixels, gpu_target_layer_dst_ypixels, 204 mixer_attributes_.width, mixer_attributes_.height); 205 return kErrorParameters; 206 } 207 208 return kErrorNone; 209 } 210 211 DisplayError DisplayBase::Prepare(LayerStack *layer_stack) { 212 lock_guard<recursive_mutex> obj(recursive_mutex_); 213 DisplayError error = kErrorNone; 214 needs_validate_ = true; 215 216 if (!active_) { 217 return kErrorPermission; 218 } 219 220 if (!layer_stack) { 221 return kErrorParameters; 222 } 223 224 error = BuildLayerStackStats(layer_stack); 225 if (error != kErrorNone) { 226 return error; 227 } 228 229 error = HandleHDR(layer_stack); 230 if (error != kErrorNone) { 231 DLOGW("HandleHDR failed"); 232 return error; 233 } 234 235 if (color_mgr_ && color_mgr_->NeedsPartialUpdateDisable()) { 236 DisablePartialUpdateOneFrame(); 237 } 238 239 if (partial_update_control_ == false || disable_pu_one_frame_) { 240 comp_manager_->ControlPartialUpdate(display_comp_ctx_, false /* enable */); 241 disable_pu_one_frame_ = false; 242 } 243 244 comp_manager_->PrePrepare(display_comp_ctx_, &hw_layers_); 245 while (true) { 246 error = comp_manager_->Prepare(display_comp_ctx_, &hw_layers_); 247 if (error != kErrorNone) { 248 break; 249 } 250 251 error = hw_intf_->Validate(&hw_layers_); 252 if (error == kErrorNone) { 253 // Strategy is successful now, wait for Commit(). 254 needs_validate_ = false; 255 break; 256 } 257 if (error == kErrorShutDown) { 258 comp_manager_->PostPrepare(display_comp_ctx_, &hw_layers_); 259 return error; 260 } 261 } 262 263 comp_manager_->PostPrepare(display_comp_ctx_, &hw_layers_); 264 265 return error; 266 } 267 268 DisplayError DisplayBase::Commit(LayerStack *layer_stack) { 269 lock_guard<recursive_mutex> obj(recursive_mutex_); 270 DisplayError error = kErrorNone; 271 272 if (!active_) { 273 needs_validate_ = true; 274 return kErrorPermission; 275 } 276 277 if (!layer_stack) { 278 return kErrorParameters; 279 } 280 281 if (needs_validate_) { 282 DLOGE("Commit: Corresponding Prepare() is not called for display = %d", display_type_); 283 return kErrorNotValidated; 284 } 285 286 // Layer stack attributes has changed, need to Reconfigure, currently in use for Hybrid Comp 287 if (layer_stack->flags.attributes_changed) { 288 error = comp_manager_->ReConfigure(display_comp_ctx_, &hw_layers_); 289 if (error != kErrorNone) { 290 return error; 291 } 292 293 error = hw_intf_->Validate(&hw_layers_); 294 if (error != kErrorNone) { 295 return error; 296 } 297 } 298 299 CommitLayerParams(layer_stack); 300 301 error = comp_manager_->Commit(display_comp_ctx_, &hw_layers_); 302 if (error != kErrorNone) { 303 return error; 304 } 305 306 // check if feature list cache is dirty and pending. 307 // If dirty, need program to hardware blocks. 308 if (color_mgr_) 309 error = color_mgr_->Commit(); 310 if (error != kErrorNone) { // won't affect this execution path. 311 DLOGW("ColorManager::Commit(...) isn't working"); 312 } 313 314 error = hw_intf_->Commit(&hw_layers_); 315 if (error != kErrorNone) { 316 return error; 317 } 318 319 PostCommitLayerParams(layer_stack); 320 321 if (partial_update_control_) { 322 comp_manager_->ControlPartialUpdate(display_comp_ctx_, true /* enable */); 323 } 324 325 error = comp_manager_->PostCommit(display_comp_ctx_, &hw_layers_); 326 if (error != kErrorNone) { 327 return error; 328 } 329 330 return kErrorNone; 331 } 332 333 DisplayError DisplayBase::Flush() { 334 lock_guard<recursive_mutex> obj(recursive_mutex_); 335 DisplayError error = kErrorNone; 336 337 if (!active_) { 338 return kErrorPermission; 339 } 340 hw_layers_.info.hw_layers.clear(); 341 error = hw_intf_->Flush(); 342 if (error == kErrorNone) { 343 comp_manager_->Purge(display_comp_ctx_); 344 needs_validate_ = true; 345 } else { 346 DLOGW("Unable to flush display = %d", display_type_); 347 } 348 349 return error; 350 } 351 352 DisplayError DisplayBase::GetDisplayState(DisplayState *state) { 353 lock_guard<recursive_mutex> obj(recursive_mutex_); 354 if (!state) { 355 return kErrorParameters; 356 } 357 358 *state = state_; 359 return kErrorNone; 360 } 361 362 DisplayError DisplayBase::GetNumVariableInfoConfigs(uint32_t *count) { 363 lock_guard<recursive_mutex> obj(recursive_mutex_); 364 return hw_intf_->GetNumDisplayAttributes(count); 365 } 366 367 DisplayError DisplayBase::GetConfig(uint32_t index, DisplayConfigVariableInfo *variable_info) { 368 lock_guard<recursive_mutex> obj(recursive_mutex_); 369 HWDisplayAttributes attrib; 370 if (hw_intf_->GetDisplayAttributes(index, &attrib) == kErrorNone) { 371 *variable_info = attrib; 372 return kErrorNone; 373 } 374 375 return kErrorNotSupported; 376 } 377 378 DisplayError DisplayBase::GetConfig(DisplayConfigFixedInfo *fixed_info) { 379 lock_guard<recursive_mutex> obj(recursive_mutex_); 380 fixed_info->is_cmdmode = (hw_panel_info_.mode == kModeCommand); 381 382 HWResourceInfo hw_resource_info = HWResourceInfo(); 383 hw_info_intf_->GetHWResourceInfo(&hw_resource_info); 384 // hdr can be supported by display when target and panel supports HDR. 385 fixed_info->hdr_supported = (hw_resource_info.has_hdr && hw_panel_info_.hdr_enabled); 386 // Populate luminance values only if hdr will be supported on that display 387 fixed_info->max_luminance = fixed_info->hdr_supported ? hw_panel_info_.peak_luminance: 0; 388 fixed_info->average_luminance = fixed_info->hdr_supported ? hw_panel_info_.average_luminance : 0; 389 fixed_info->min_luminance = fixed_info->hdr_supported ? hw_panel_info_.blackness_level: 0; 390 391 return kErrorNone; 392 } 393 394 DisplayError DisplayBase::GetActiveConfig(uint32_t *index) { 395 lock_guard<recursive_mutex> obj(recursive_mutex_); 396 return hw_intf_->GetActiveConfig(index); 397 } 398 399 DisplayError DisplayBase::GetVSyncState(bool *enabled) { 400 lock_guard<recursive_mutex> obj(recursive_mutex_); 401 if (!enabled) { 402 return kErrorParameters; 403 } 404 405 *enabled = vsync_enable_; 406 407 return kErrorNone; 408 } 409 410 DisplayError DisplayBase::SetDisplayState(DisplayState state) { 411 lock_guard<recursive_mutex> obj(recursive_mutex_); 412 DisplayError error = kErrorNone; 413 bool active = false; 414 415 DLOGI("Set state = %d, display %d", state, display_type_); 416 417 if (state == state_) { 418 DLOGI("Same state transition is requested."); 419 return kErrorNone; 420 } 421 422 switch (state) { 423 case kStateOff: 424 hw_layers_.info.hw_layers.clear(); 425 error = hw_intf_->Flush(); 426 if (error == kErrorNone) { 427 error = hw_intf_->PowerOff(); 428 } 429 break; 430 431 case kStateOn: 432 error = hw_intf_->PowerOn(); 433 if (error != kErrorNone) { 434 return error; 435 } 436 437 error = comp_manager_->ReconfigureDisplay(display_comp_ctx_, display_attributes_, 438 hw_panel_info_, mixer_attributes_, fb_config_); 439 if (error != kErrorNone) { 440 return error; 441 } 442 443 active = true; 444 break; 445 446 case kStateDoze: 447 case kStateDozeSuspend: 448 error = hw_intf_->DozeSuspend(); 449 active = true; 450 break; 451 452 case kStateStandby: 453 error = hw_intf_->Standby(); 454 break; 455 456 default: 457 DLOGE("Spurious state = %d transition requested.", state); 458 break; 459 } 460 461 if (error == kErrorNone) { 462 active_ = active; 463 state_ = state; 464 comp_manager_->SetDisplayState(display_comp_ctx_, state, display_type_); 465 } 466 467 return error; 468 } 469 470 DisplayError DisplayBase::SetActiveConfig(uint32_t index) { 471 lock_guard<recursive_mutex> obj(recursive_mutex_); 472 DisplayError error = kErrorNone; 473 uint32_t active_index = 0; 474 475 hw_intf_->GetActiveConfig(&active_index); 476 477 if (active_index == index) { 478 return kErrorNone; 479 } 480 481 error = hw_intf_->SetDisplayAttributes(index); 482 if (error != kErrorNone) { 483 return error; 484 } 485 486 return ReconfigureDisplay(); 487 } 488 489 DisplayError DisplayBase::SetMaxMixerStages(uint32_t max_mixer_stages) { 490 lock_guard<recursive_mutex> obj(recursive_mutex_); 491 DisplayError error = kErrorNone; 492 493 error = comp_manager_->SetMaxMixerStages(display_comp_ctx_, max_mixer_stages); 494 495 if (error == kErrorNone) { 496 max_mixer_stages_ = max_mixer_stages; 497 } 498 499 return error; 500 } 501 502 void DisplayBase::AppendDump(char *buffer, uint32_t length) { 503 lock_guard<recursive_mutex> obj(recursive_mutex_); 504 HWDisplayAttributes attrib; 505 uint32_t active_index = 0; 506 uint32_t num_modes = 0; 507 hw_intf_->GetNumDisplayAttributes(&num_modes); 508 hw_intf_->GetActiveConfig(&active_index); 509 hw_intf_->GetDisplayAttributes(active_index, &attrib); 510 511 DumpImpl::AppendString(buffer, length, "\n-----------------------"); 512 DumpImpl::AppendString(buffer, length, "\ndevice type: %u", display_type_); 513 DumpImpl::AppendString(buffer, length, "\nstate: %u, vsync on: %u, max. mixer stages: %u", 514 state_, INT(vsync_enable_), max_mixer_stages_); 515 DumpImpl::AppendString(buffer, length, "\nnum configs: %u, active config index: %u", 516 num_modes, active_index); 517 518 DisplayConfigVariableInfo &info = attrib; 519 520 uint32_t num_hw_layers = 0; 521 if (hw_layers_.info.stack) { 522 num_hw_layers = UINT32(hw_layers_.info.hw_layers.size()); 523 } 524 525 if (num_hw_layers == 0) { 526 DumpImpl::AppendString(buffer, length, "\nNo hardware layers programmed"); 527 return; 528 } 529 530 LayerBuffer *out_buffer = hw_layers_.info.stack->output_buffer; 531 if (out_buffer) { 532 DumpImpl::AppendString(buffer, length, "\nres:%u x %u format: %s", out_buffer->width, 533 out_buffer->height, GetFormatString(out_buffer->format)); 534 } else { 535 DumpImpl::AppendString(buffer, length, "\nres:%u x %u, dpi:%.2f x %.2f, fps:%u," 536 "vsync period: %u", info.x_pixels, info.y_pixels, info.x_dpi, 537 info.y_dpi, info.fps, info.vsync_period_ns); 538 } 539 540 DumpImpl::AppendString(buffer, length, "\n"); 541 542 HWLayersInfo &layer_info = hw_layers_.info; 543 544 for (uint32_t i = 0; i < layer_info.left_frame_roi.size(); i++) { 545 LayerRect &l_roi = layer_info.left_frame_roi.at(i); 546 LayerRect &r_roi = layer_info.right_frame_roi.at(i); 547 548 DumpImpl::AppendString(buffer, length, "\nROI%d(L T R B) : LEFT(%d %d %d %d)", i, 549 INT(l_roi.left), INT(l_roi.top), INT(l_roi.right), INT(l_roi.bottom)); 550 if (IsValid(r_roi)) { 551 DumpImpl::AppendString(buffer, length, ", RIGHT(%d %d %d %d)", INT(r_roi.left), 552 INT(r_roi.top), INT(r_roi.right), INT(r_roi.bottom)); 553 } 554 } 555 556 LayerRect &fb_roi = layer_info.partial_fb_roi; 557 if (IsValid(fb_roi)) { 558 DumpImpl::AppendString(buffer, length, "\nPartial FB ROI(L T R B) : (%d %d %d %d)", 559 INT(fb_roi.left), INT(fb_roi.top), INT(fb_roi.right), INT(fb_roi.bottom)); 560 } 561 562 const char *header = "\n| Idx | Comp Type | Split | WB | Pipe | W x H | Format | Src Rect (L T R B) | Dst Rect (L T R B) | Z | Flags | Deci(HxV) | CS | Rng |"; //NOLINT 563 const char *newline = "\n|-----|-------------|--------|----|--------|-------------|--------------------------|---------------------|---------------------|----|------------|-----------|----|-----|"; //NOLINT 564 const char *format = "\n| %3s | %11s " "| %6s " "| %2s | 0x%04x | %4d x %4d | %24s " "| %4d %4d %4d %4d " "| %4d %4d %4d %4d " "| %2s | %10s " "| %9s | %2s | %3s |"; //NOLINT 565 566 DumpImpl::AppendString(buffer, length, "\n"); 567 DumpImpl::AppendString(buffer, length, newline); 568 DumpImpl::AppendString(buffer, length, header); 569 DumpImpl::AppendString(buffer, length, newline); 570 571 for (uint32_t i = 0; i < num_hw_layers; i++) { 572 uint32_t layer_index = hw_layers_.info.index[i]; 573 // sdm-layer from client layer stack 574 Layer *sdm_layer = hw_layers_.info.stack->layers.at(layer_index); 575 // hw-layer from hw layers info 576 Layer &hw_layer = hw_layers_.info.hw_layers.at(i); 577 LayerBuffer *input_buffer = &hw_layer.input_buffer; 578 HWLayerConfig &layer_config = hw_layers_.config[i]; 579 HWRotatorSession &hw_rotator_session = layer_config.hw_rotator_session; 580 581 char idx[8] = { 0 }; 582 const char *comp_type = GetName(sdm_layer->composition); 583 const char *buffer_format = GetFormatString(input_buffer->format); 584 const char *rotate_split[2] = { "Rot-1", "Rot-2" }; 585 const char *comp_split[2] = { "Comp-1", "Comp-2" }; 586 587 snprintf(idx, sizeof(idx), "%d", layer_index); 588 589 for (uint32_t count = 0; count < hw_rotator_session.hw_block_count; count++) { 590 char writeback_id[8] = { 0 }; 591 HWRotateInfo &rotate = hw_rotator_session.hw_rotate_info[count]; 592 LayerRect &src_roi = rotate.src_roi; 593 LayerRect &dst_roi = rotate.dst_roi; 594 595 snprintf(writeback_id, sizeof(writeback_id), "%d", rotate.writeback_id); 596 597 DumpImpl::AppendString(buffer, length, format, idx, comp_type, rotate_split[count], 598 writeback_id, rotate.pipe_id, input_buffer->width, 599 input_buffer->height, buffer_format, INT(src_roi.left), 600 INT(src_roi.top), INT(src_roi.right), INT(src_roi.bottom), 601 INT(dst_roi.left), INT(dst_roi.top), INT(dst_roi.right), 602 INT(dst_roi.bottom), "-", "- ", "- ", "-", "-"); 603 604 // print the below only once per layer block, fill with spaces for rest. 605 idx[0] = 0; 606 comp_type = ""; 607 } 608 609 if (hw_rotator_session.hw_block_count > 0) { 610 input_buffer = &hw_rotator_session.output_buffer; 611 buffer_format = GetFormatString(input_buffer->format); 612 } 613 614 for (uint32_t count = 0; count < 2; count++) { 615 char decimation[16] = { 0 }; 616 char flags[16] = { 0 }; 617 char z_order[8] = { 0 }; 618 char color_primary[8] = { 0 }; 619 char range[8] = { 0 }; 620 621 HWPipeInfo &pipe = (count == 0) ? layer_config.left_pipe : layer_config.right_pipe; 622 623 if (!pipe.valid) { 624 continue; 625 } 626 627 LayerRect &src_roi = pipe.src_roi; 628 LayerRect &dst_roi = pipe.dst_roi; 629 630 snprintf(z_order, sizeof(z_order), "%d", pipe.z_order); 631 snprintf(flags, sizeof(flags), "0x%08x", hw_layer.flags.flags); 632 snprintf(decimation, sizeof(decimation), "%3d x %3d", pipe.horizontal_decimation, 633 pipe.vertical_decimation); 634 ColorMetaData &color_metadata = hw_layer.input_buffer.color_metadata; 635 snprintf(color_primary, sizeof(color_primary), "%d", color_metadata.colorPrimaries); 636 snprintf(range, sizeof(range), "%d", color_metadata.range); 637 638 DumpImpl::AppendString(buffer, length, format, idx, comp_type, comp_split[count], 639 "-", pipe.pipe_id, input_buffer->width, input_buffer->height, 640 buffer_format, INT(src_roi.left), INT(src_roi.top), 641 INT(src_roi.right), INT(src_roi.bottom), INT(dst_roi.left), 642 INT(dst_roi.top), INT(dst_roi.right), INT(dst_roi.bottom), 643 z_order, flags, decimation, color_primary, range); 644 645 // print the below only once per layer block, fill with spaces for rest. 646 idx[0] = 0; 647 comp_type = ""; 648 } 649 650 DumpImpl::AppendString(buffer, length, newline); 651 } 652 } 653 654 const char * DisplayBase::GetName(const LayerComposition &composition) { 655 switch (composition) { 656 case kCompositionGPU: return "GPU"; 657 case kCompositionSDE: return "SDE"; 658 case kCompositionHWCursor: return "CURSOR"; 659 case kCompositionHybrid: return "HYBRID"; 660 case kCompositionBlit: return "BLIT"; 661 case kCompositionGPUTarget: return "GPU_TARGET"; 662 case kCompositionBlitTarget: return "BLIT_TARGET"; 663 default: return "UNKNOWN"; 664 } 665 } 666 667 DisplayError DisplayBase::ColorSVCRequestRoute(const PPDisplayAPIPayload &in_payload, 668 PPDisplayAPIPayload *out_payload, 669 PPPendingParams *pending_action) { 670 lock_guard<recursive_mutex> obj(recursive_mutex_); 671 if (color_mgr_) 672 return color_mgr_->ColorSVCRequestRoute(in_payload, out_payload, pending_action); 673 else 674 return kErrorParameters; 675 } 676 677 DisplayError DisplayBase::GetColorModeCount(uint32_t *mode_count) { 678 lock_guard<recursive_mutex> obj(recursive_mutex_); 679 if (!mode_count) { 680 return kErrorParameters; 681 } 682 683 if (!color_mgr_) { 684 return kErrorNotSupported; 685 } 686 687 DLOGV_IF(kTagQDCM, "Number of modes from color manager = %d", num_color_modes_); 688 *mode_count = num_color_modes_; 689 690 return kErrorNone; 691 } 692 693 DisplayError DisplayBase::GetColorModes(uint32_t *mode_count, 694 std::vector<std::string> *color_modes) { 695 lock_guard<recursive_mutex> obj(recursive_mutex_); 696 if (!mode_count || !color_modes) { 697 return kErrorParameters; 698 } 699 700 if (!color_mgr_) { 701 return kErrorNotSupported; 702 } 703 704 for (uint32_t i = 0; i < num_color_modes_; i++) { 705 DLOGV_IF(kTagQDCM, "Color Mode[%d]: Name = %s mode_id = %d", i, color_modes_[i].name, 706 color_modes_[i].id); 707 color_modes->at(i) = color_modes_[i].name; 708 } 709 710 return kErrorNone; 711 } 712 713 DisplayError DisplayBase::GetColorModeAttr(const std::string &color_mode, AttrVal *attr) { 714 lock_guard<recursive_mutex> obj(recursive_mutex_); 715 if (!attr) { 716 return kErrorParameters; 717 } 718 719 if (!color_mgr_) { 720 return kErrorNotSupported; 721 } 722 723 auto it = color_mode_attr_map_.find(color_mode); 724 if (it == color_mode_attr_map_.end()) { 725 DLOGE("Failed: Mode %s without attribute", color_mode.c_str()); 726 return kErrorNotSupported; 727 } 728 *attr = it->second; 729 730 return kErrorNone; 731 } 732 733 DisplayError DisplayBase::SetColorMode(const std::string &color_mode) { 734 lock_guard<recursive_mutex> obj(recursive_mutex_); 735 if (!color_mgr_) { 736 return kErrorNotSupported; 737 } 738 739 DynamicRangeType dynamic_range_type; 740 if (IsSupportColorModeAttribute(color_mode)) { 741 auto it_mode = color_mode_attr_map_.find(color_mode); 742 std::string dynamic_range; 743 GetValueOfModeAttribute(it_mode->second, kDynamicRangeAttribute, &dynamic_range); 744 if (dynamic_range == kHdr) { 745 dynamic_range_type = kHdrType; 746 } else { 747 dynamic_range_type = kSdrType; 748 } 749 } else { 750 if (color_mode.find("hal_hdr") != std::string::npos) { 751 dynamic_range_type = kHdrType; 752 } else { 753 dynamic_range_type = kSdrType; 754 } 755 } 756 757 DisplayError error = kErrorNone; 758 if (disable_hdr_lut_gen_) { 759 error = SetColorModeInternal(color_mode); 760 if (error != kErrorNone) { 761 return error; 762 } 763 // Store the new SDR color mode request by client 764 if (dynamic_range_type == kSdrType) { 765 current_color_mode_ = color_mode; 766 } 767 return error; 768 } 769 770 if (hdr_playback_mode_) { 771 // HDR playback on, If incoming mode is SDR mode, 772 // cache the mode and apply it after HDR playback stop. 773 if (dynamic_range_type == kHdrType) { 774 error = SetColorModeInternal(color_mode); 775 if (error != kErrorNone) { 776 return error; 777 } 778 } else if (dynamic_range_type == kSdrType) { 779 current_color_mode_ = color_mode; 780 } 781 } else { 782 // HDR playback off, do not apply HDR mode 783 if (dynamic_range_type == kHdrType) { 784 DLOGE("Failed: Forbid setting HDR Mode : %s when HDR playback off", color_mode.c_str()); 785 return kErrorNotSupported; 786 } 787 error = SetColorModeInternal(color_mode); 788 if (error != kErrorNone) { 789 return error; 790 } 791 current_color_mode_ = color_mode; 792 } 793 794 return error; 795 } 796 797 DisplayError DisplayBase::SetColorModeInternal(const std::string &color_mode) { 798 DLOGV_IF(kTagQDCM, "Color Mode = %s", color_mode.c_str()); 799 800 ColorModeMap::iterator it = color_mode_map_.find(color_mode); 801 if (it == color_mode_map_.end()) { 802 DLOGE("Failed: Unknown Mode : %s", color_mode.c_str()); 803 return kErrorNotSupported; 804 } 805 806 SDEDisplayMode *sde_display_mode = it->second; 807 808 DLOGV_IF(kTagQDCM, "Color Mode Name = %s corresponding mode_id = %d", sde_display_mode->name, 809 sde_display_mode->id); 810 DisplayError error = kErrorNone; 811 error = color_mgr_->ColorMgrSetMode(sde_display_mode->id); 812 if (error != kErrorNone) { 813 DLOGE("Failed for mode id = %d", sde_display_mode->id); 814 return error; 815 } 816 817 return error; 818 } 819 820 DisplayError DisplayBase::GetValueOfModeAttribute(const AttrVal &attr,const std::string &type, 821 std::string *value) { 822 if (!value) { 823 return kErrorParameters; 824 } 825 for (auto &it : attr) { 826 if (it.first.find(type) != std::string::npos) { 827 *value = it.second; 828 } 829 } 830 831 return kErrorNone; 832 } 833 834 bool DisplayBase::IsSupportColorModeAttribute(const std::string &color_mode) { 835 auto it = color_mode_attr_map_.find(color_mode); 836 if (it == color_mode_attr_map_.end()) { 837 return false; 838 } 839 return true; 840 } 841 842 DisplayError DisplayBase::GetHdrColorMode(std::string *color_mode, bool *found_hdr) { 843 if (!found_hdr || !color_mode) { 844 return kErrorParameters; 845 } 846 auto it_mode = color_mode_attr_map_.find(current_color_mode_); 847 if (it_mode == color_mode_attr_map_.end()) { 848 DLOGE("Failed: Unknown Mode : %s", current_color_mode_.c_str()); 849 return kErrorNotSupported; 850 } 851 852 *found_hdr = false; 853 std::string cur_color_gamut, cur_pic_quality; 854 // get the attributes of current color mode 855 GetValueOfModeAttribute(it_mode->second, kColorGamutAttribute, &cur_color_gamut); 856 GetValueOfModeAttribute(it_mode->second, kPictureQualityAttribute, &cur_pic_quality); 857 858 // found the corresponding HDR mode id which 859 // has the same attributes with current SDR mode. 860 for (auto &it_hdr : color_mode_attr_map_) { 861 std::string dynamic_range, color_gamut, pic_quality; 862 GetValueOfModeAttribute(it_hdr.second, kDynamicRangeAttribute, &dynamic_range); 863 GetValueOfModeAttribute(it_hdr.second, kColorGamutAttribute, &color_gamut); 864 GetValueOfModeAttribute(it_hdr.second, kPictureQualityAttribute, &pic_quality); 865 if (dynamic_range == kHdr && cur_color_gamut == color_gamut && 866 cur_pic_quality == pic_quality) { 867 *color_mode = it_hdr.first; 868 *found_hdr = true; 869 DLOGV_IF(kTagQDCM, "corresponding hdr mode = %s", color_mode->c_str()); 870 return kErrorNone; 871 } 872 } 873 874 // The corresponding HDR mode was not be found, 875 // apply the first HDR mode that we encouter. 876 for (auto &it_hdr : color_mode_attr_map_) { 877 std::string dynamic_range; 878 GetValueOfModeAttribute(it_hdr.second, kDynamicRangeAttribute, &dynamic_range); 879 if (dynamic_range == kHdr) { 880 *color_mode = it_hdr.first; 881 *found_hdr = true; 882 DLOGV_IF(kTagQDCM, "First hdr mode = %s", color_mode->c_str()); 883 return kErrorNone; 884 } 885 } 886 887 return kErrorNone; 888 } 889 890 DisplayError DisplayBase::SetColorTransform(const uint32_t length, const double *color_transform) { 891 lock_guard<recursive_mutex> obj(recursive_mutex_); 892 if (!color_mgr_) { 893 return kErrorNotSupported; 894 } 895 896 if (!color_transform) { 897 return kErrorParameters; 898 } 899 900 return color_mgr_->ColorMgrSetColorTransform(length, color_transform); 901 } 902 903 DisplayError DisplayBase::GetDefaultColorMode(std::string *color_mode) { 904 lock_guard<recursive_mutex> obj(recursive_mutex_); 905 if (!color_mode) { 906 return kErrorParameters; 907 } 908 909 if (!color_mgr_) { 910 return kErrorNotSupported; 911 } 912 913 int32_t default_id = kInvalidModeId; 914 DisplayError error = color_mgr_->ColorMgrGetDefaultModeID(&default_id); 915 if (error != kErrorNone) { 916 DLOGE("Failed for get default color mode id"); 917 return error; 918 } 919 920 for (uint32_t i = 0; i < num_color_modes_; i++) { 921 if (color_modes_[i].id == default_id) { 922 *color_mode = color_modes_[i].name; 923 return kErrorNone; 924 } 925 } 926 927 return kErrorNotSupported; 928 } 929 930 DisplayError DisplayBase::ApplyDefaultDisplayMode() { 931 lock_guard<recursive_mutex> obj(recursive_mutex_); 932 if (color_mgr_) 933 return color_mgr_->ApplyDefaultDisplayMode(); 934 else 935 return kErrorParameters; 936 } 937 938 DisplayError DisplayBase::SetCursorPosition(int x, int y) { 939 lock_guard<recursive_mutex> obj(recursive_mutex_); 940 if (state_ != kStateOn) { 941 return kErrorNotSupported; 942 } 943 944 DisplayError error = comp_manager_->ValidateAndSetCursorPosition(display_comp_ctx_, &hw_layers_, 945 x, y); 946 if (error == kErrorNone) { 947 return hw_intf_->SetCursorPosition(&hw_layers_, x, y); 948 } 949 950 return kErrorNone; 951 } 952 953 DisplayError DisplayBase::GetRefreshRateRange(uint32_t *min_refresh_rate, 954 uint32_t *max_refresh_rate) { 955 lock_guard<recursive_mutex> obj(recursive_mutex_); 956 // The min and max refresh rates will be same when the HWPanelInfo does not contain valid rates. 957 // Usually for secondary displays, command mode panels 958 HWDisplayAttributes display_attributes; 959 uint32_t active_index = 0; 960 hw_intf_->GetActiveConfig(&active_index); 961 DisplayError error = hw_intf_->GetDisplayAttributes(active_index, &display_attributes); 962 if (error) { 963 return error; 964 } 965 966 *min_refresh_rate = display_attributes.fps; 967 *max_refresh_rate = display_attributes.fps; 968 969 return error; 970 } 971 972 DisplayError DisplayBase::SetVSyncState(bool enable) { 973 lock_guard<recursive_mutex> obj(recursive_mutex_); 974 DisplayError error = kErrorNone; 975 if (vsync_enable_ != enable) { 976 error = hw_intf_->SetVSyncState(enable); 977 if (error == kErrorNone) { 978 vsync_enable_ = enable; 979 } 980 } 981 return error; 982 } 983 984 DisplayError DisplayBase::ReconfigureDisplay() { 985 lock_guard<recursive_mutex> obj(recursive_mutex_); 986 DisplayError error = kErrorNone; 987 HWDisplayAttributes display_attributes; 988 HWMixerAttributes mixer_attributes; 989 HWPanelInfo hw_panel_info; 990 uint32_t active_index = 0; 991 992 error = hw_intf_->GetActiveConfig(&active_index); 993 if (error != kErrorNone) { 994 return error; 995 } 996 997 error = hw_intf_->GetDisplayAttributes(active_index, &display_attributes); 998 if (error != kErrorNone) { 999 return error; 1000 } 1001 1002 error = hw_intf_->GetMixerAttributes(&mixer_attributes); 1003 if (error != kErrorNone) { 1004 return error; 1005 } 1006 1007 error = hw_intf_->GetHWPanelInfo(&hw_panel_info); 1008 if (error != kErrorNone) { 1009 return error; 1010 } 1011 1012 if (display_attributes == display_attributes_ && mixer_attributes == mixer_attributes_ && 1013 hw_panel_info == hw_panel_info_) { 1014 return kErrorNone; 1015 } 1016 1017 error = comp_manager_->ReconfigureDisplay(display_comp_ctx_, display_attributes, hw_panel_info, 1018 mixer_attributes, fb_config_); 1019 if (error != kErrorNone) { 1020 return error; 1021 } 1022 1023 if (mixer_attributes != mixer_attributes_) { 1024 DisablePartialUpdateOneFrame(); 1025 } 1026 1027 display_attributes_ = display_attributes; 1028 mixer_attributes_ = mixer_attributes; 1029 hw_panel_info_ = hw_panel_info; 1030 1031 return kErrorNone; 1032 } 1033 1034 DisplayError DisplayBase::SetMixerResolution(uint32_t width, uint32_t height) { 1035 lock_guard<recursive_mutex> obj(recursive_mutex_); 1036 1037 DisplayError error = ReconfigureMixer(width, height); 1038 if (error != kErrorNone) { 1039 return error; 1040 } 1041 1042 req_mixer_width_ = width; 1043 req_mixer_height_ = height; 1044 1045 return kErrorNone; 1046 } 1047 1048 DisplayError DisplayBase::GetMixerResolution(uint32_t *width, uint32_t *height) { 1049 lock_guard<recursive_mutex> obj(recursive_mutex_); 1050 if (!width || !height) { 1051 return kErrorParameters; 1052 } 1053 1054 *width = mixer_attributes_.width; 1055 *height = mixer_attributes_.height; 1056 1057 return kErrorNone; 1058 } 1059 1060 DisplayError DisplayBase::ReconfigureMixer(uint32_t width, uint32_t height) { 1061 lock_guard<recursive_mutex> obj(recursive_mutex_); 1062 DisplayError error = kErrorNone; 1063 1064 if (!width || !height) { 1065 return kErrorParameters; 1066 } 1067 1068 HWMixerAttributes mixer_attributes; 1069 mixer_attributes.width = width; 1070 mixer_attributes.height = height; 1071 1072 error = hw_intf_->SetMixerAttributes(mixer_attributes); 1073 if (error != kErrorNone) { 1074 return error; 1075 } 1076 1077 return ReconfigureDisplay(); 1078 } 1079 1080 bool DisplayBase::NeedsDownScale(const LayerRect &src_rect, const LayerRect &dst_rect, 1081 bool needs_rotation) { 1082 float src_width = FLOAT(src_rect.right - src_rect.left); 1083 float src_height = FLOAT(src_rect.bottom - src_rect.top); 1084 float dst_width = FLOAT(dst_rect.right - dst_rect.left); 1085 float dst_height = FLOAT(dst_rect.bottom - dst_rect.top); 1086 1087 if (needs_rotation) { 1088 std::swap(src_width, src_height); 1089 } 1090 1091 if ((src_width > dst_width) || (src_height > dst_height)) { 1092 return true; 1093 } 1094 1095 return false; 1096 } 1097 1098 bool DisplayBase::NeedsMixerReconfiguration(LayerStack *layer_stack, uint32_t *new_mixer_width, 1099 uint32_t *new_mixer_height) { 1100 lock_guard<recursive_mutex> obj(recursive_mutex_); 1101 uint32_t layer_count = UINT32(layer_stack->layers.size()); 1102 1103 uint32_t fb_width = fb_config_.x_pixels; 1104 uint32_t fb_height = fb_config_.y_pixels; 1105 uint32_t fb_area = fb_width * fb_height; 1106 LayerRect fb_rect = (LayerRect) {0.0f, 0.0f, FLOAT(fb_width), FLOAT(fb_height)}; 1107 uint32_t mixer_width = mixer_attributes_.width; 1108 uint32_t mixer_height = mixer_attributes_.height; 1109 uint32_t display_width = display_attributes_.x_pixels; 1110 uint32_t display_height = display_attributes_.y_pixels; 1111 1112 RectOrientation fb_orientation = GetOrientation(fb_rect); 1113 uint32_t max_layer_area = 0; 1114 uint32_t max_area_layer_index = 0; 1115 std::vector<Layer *> layers = layer_stack->layers; 1116 uint32_t align_x = display_attributes_.is_device_split ? 4 : 2; 1117 uint32_t align_y = 2; 1118 1119 if (req_mixer_width_ && req_mixer_height_) { 1120 *new_mixer_width = req_mixer_width_; 1121 *new_mixer_height = req_mixer_height_; 1122 1123 return (req_mixer_width_ != mixer_width || req_mixer_height_ != mixer_height); 1124 } 1125 1126 for (uint32_t i = 0; i < layer_count; i++) { 1127 Layer *layer = layers.at(i); 1128 1129 uint32_t layer_width = UINT32(layer->src_rect.right - layer->src_rect.left); 1130 uint32_t layer_height = UINT32(layer->src_rect.bottom - layer->src_rect.top); 1131 uint32_t layer_area = layer_width * layer_height; 1132 1133 if (layer_area > max_layer_area) { 1134 max_layer_area = layer_area; 1135 max_area_layer_index = i; 1136 } 1137 } 1138 1139 // TODO(user): Mark layer which needs downscaling on GPU fallback as priority layer and use MDP 1140 // for composition to avoid quality mismatch between GPU and MDP switch(idle timeout usecase). 1141 if (max_layer_area >= fb_area) { 1142 Layer *layer = layers.at(max_area_layer_index); 1143 bool needs_rotation = (layer->transform.rotation == 90.0f); 1144 1145 uint32_t layer_width = UINT32(layer->src_rect.right - layer->src_rect.left); 1146 uint32_t layer_height = UINT32(layer->src_rect.bottom - layer->src_rect.top); 1147 LayerRect layer_dst_rect = {}; 1148 1149 RectOrientation layer_orientation = GetOrientation(layer->src_rect); 1150 if (layer_orientation != kOrientationUnknown && 1151 fb_orientation != kOrientationUnknown) { 1152 if (layer_orientation != fb_orientation) { 1153 std::swap(layer_width, layer_height); 1154 } 1155 } 1156 1157 // Align the width and height according to fb's aspect ratio 1158 *new_mixer_width = FloorToMultipleOf(UINT32((FLOAT(fb_width) / FLOAT(fb_height)) * 1159 layer_height), align_x); 1160 *new_mixer_height = FloorToMultipleOf(layer_height, align_y); 1161 1162 LayerRect dst_domain = {0.0f, 0.0f, FLOAT(*new_mixer_width), FLOAT(*new_mixer_height)}; 1163 1164 MapRect(fb_rect, dst_domain, layer->dst_rect, &layer_dst_rect); 1165 if (NeedsDownScale(layer->src_rect, layer_dst_rect, needs_rotation)) { 1166 *new_mixer_width = display_width; 1167 *new_mixer_height = display_height; 1168 } 1169 1170 return true; 1171 } 1172 1173 return false; 1174 } 1175 1176 DisplayError DisplayBase::SetFrameBufferConfig(const DisplayConfigVariableInfo &variable_info) { 1177 lock_guard<recursive_mutex> obj(recursive_mutex_); 1178 uint32_t width = variable_info.x_pixels; 1179 uint32_t height = variable_info.y_pixels; 1180 1181 if (width == 0 || height == 0) { 1182 DLOGE("Unsupported resolution: (%dx%d)", width, height); 1183 return kErrorParameters; 1184 } 1185 1186 // Create rects to represent the new source and destination crops 1187 LayerRect crop = LayerRect(0, 0, FLOAT(width), FLOAT(height)); 1188 LayerRect dst = LayerRect(0, 0, FLOAT(mixer_attributes_.width), FLOAT(mixer_attributes_.height)); 1189 // Set rotate90 to false since this is taken care of during regular composition. 1190 bool rotate90 = false; 1191 1192 DisplayError error = comp_manager_->ValidateScaling(crop, dst, rotate90); 1193 if (error != kErrorNone) { 1194 DLOGE("Unsupported resolution: (%dx%d)", width, height); 1195 return kErrorParameters; 1196 } 1197 1198 error = comp_manager_->ReconfigureDisplay(display_comp_ctx_, display_attributes_, hw_panel_info_, 1199 mixer_attributes_, variable_info); 1200 if (error != kErrorNone) { 1201 return error; 1202 } 1203 1204 fb_config_.x_pixels = width; 1205 fb_config_.y_pixels = height; 1206 1207 DLOGI("New framebuffer resolution (%dx%d)", fb_config_.x_pixels, fb_config_.y_pixels); 1208 1209 return kErrorNone; 1210 } 1211 1212 DisplayError DisplayBase::GetFrameBufferConfig(DisplayConfigVariableInfo *variable_info) { 1213 lock_guard<recursive_mutex> obj(recursive_mutex_); 1214 if (!variable_info) { 1215 return kErrorParameters; 1216 } 1217 1218 *variable_info = fb_config_; 1219 1220 return kErrorNone; 1221 } 1222 1223 DisplayError DisplayBase::SetDetailEnhancerData(const DisplayDetailEnhancerData &de_data) { 1224 lock_guard<recursive_mutex> obj(recursive_mutex_); 1225 DisplayError error = comp_manager_->SetDetailEnhancerData(display_comp_ctx_, de_data); 1226 if (error != kErrorNone) { 1227 return error; 1228 } 1229 1230 DisablePartialUpdateOneFrame(); 1231 1232 return kErrorNone; 1233 } 1234 1235 DisplayError DisplayBase::GetDisplayPort(DisplayPort *port) { 1236 lock_guard<recursive_mutex> obj(recursive_mutex_); 1237 1238 if (!port) { 1239 return kErrorParameters; 1240 } 1241 1242 *port = hw_panel_info_.port; 1243 1244 return kErrorNone; 1245 } 1246 1247 bool DisplayBase::IsPrimaryDisplay() { 1248 lock_guard<recursive_mutex> obj(recursive_mutex_); 1249 1250 return hw_panel_info_.is_primary_panel; 1251 } 1252 1253 DisplayError DisplayBase::SetCompositionState(LayerComposition composition_type, bool enable) { 1254 lock_guard<recursive_mutex> obj(recursive_mutex_); 1255 1256 return comp_manager_->SetCompositionState(display_comp_ctx_, composition_type, enable); 1257 } 1258 1259 void DisplayBase::CommitLayerParams(LayerStack *layer_stack) { 1260 // Copy the acquire fence from clients layers to HWLayers 1261 uint32_t hw_layers_count = UINT32(hw_layers_.info.hw_layers.size()); 1262 1263 for (uint32_t i = 0; i < hw_layers_count; i++) { 1264 Layer *sdm_layer = layer_stack->layers.at(hw_layers_.info.index[i]); 1265 Layer &hw_layer = hw_layers_.info.hw_layers.at(i); 1266 1267 hw_layer.input_buffer.planes[0].fd = sdm_layer->input_buffer.planes[0].fd; 1268 hw_layer.input_buffer.planes[0].offset = sdm_layer->input_buffer.planes[0].offset; 1269 hw_layer.input_buffer.planes[0].stride = sdm_layer->input_buffer.planes[0].stride; 1270 hw_layer.input_buffer.size = sdm_layer->input_buffer.size; 1271 hw_layer.input_buffer.acquire_fence_fd = sdm_layer->input_buffer.acquire_fence_fd; 1272 } 1273 1274 return; 1275 } 1276 1277 void DisplayBase::PostCommitLayerParams(LayerStack *layer_stack) { 1278 // Copy the release fence from HWLayers to clients layers 1279 uint32_t hw_layers_count = UINT32(hw_layers_.info.hw_layers.size()); 1280 1281 std::vector<uint32_t> fence_dup_flag; 1282 1283 for (uint32_t i = 0; i < hw_layers_count; i++) { 1284 uint32_t sdm_layer_index = hw_layers_.info.index[i]; 1285 Layer *sdm_layer = layer_stack->layers.at(sdm_layer_index); 1286 Layer &hw_layer = hw_layers_.info.hw_layers.at(i); 1287 1288 // Copy the release fence only once for a SDM Layer. 1289 // In S3D use case, two hw layers can share the same input buffer, So make sure to merge the 1290 // output fence fd and assign it to layer's input buffer release fence fd. 1291 if (std::find(fence_dup_flag.begin(), fence_dup_flag.end(), sdm_layer_index) == 1292 fence_dup_flag.end()) { 1293 sdm_layer->input_buffer.release_fence_fd = hw_layer.input_buffer.release_fence_fd; 1294 fence_dup_flag.push_back(sdm_layer_index); 1295 } else { 1296 int temp = -1; 1297 buffer_sync_handler_->SyncMerge(hw_layer.input_buffer.release_fence_fd, 1298 sdm_layer->input_buffer.release_fence_fd, &temp); 1299 1300 if (hw_layer.input_buffer.release_fence_fd >= 0) { 1301 Sys::close_(hw_layer.input_buffer.release_fence_fd); 1302 hw_layer.input_buffer.release_fence_fd = -1; 1303 } 1304 1305 if (sdm_layer->input_buffer.release_fence_fd >= 0) { 1306 Sys::close_(sdm_layer->input_buffer.release_fence_fd); 1307 sdm_layer->input_buffer.release_fence_fd = -1; 1308 } 1309 1310 sdm_layer->input_buffer.release_fence_fd = temp; 1311 } 1312 } 1313 1314 return; 1315 } 1316 1317 DisplayError DisplayBase::InitializeColorModes() { 1318 if (!color_mgr_) { 1319 return kErrorNotSupported; 1320 } 1321 1322 DisplayError error = color_mgr_->ColorMgrGetNumOfModes(&num_color_modes_); 1323 if (error != kErrorNone || !num_color_modes_) { 1324 DLOGV_IF(kTagQDCM, "GetNumModes failed = %d count = %d", error, num_color_modes_); 1325 return kErrorNotSupported; 1326 } 1327 DLOGI("Number of Color Modes = %d", num_color_modes_); 1328 1329 if (!color_modes_.size()) { 1330 color_modes_.resize(num_color_modes_); 1331 1332 DisplayError error = color_mgr_->ColorMgrGetModes(&num_color_modes_, color_modes_.data()); 1333 if (error != kErrorNone) { 1334 color_modes_.clear(); 1335 DLOGE("Failed"); 1336 return error; 1337 } 1338 int32_t default_id = kInvalidModeId; 1339 error = color_mgr_->ColorMgrGetDefaultModeID(&default_id); 1340 1341 AttrVal var; 1342 for (uint32_t i = 0; i < num_color_modes_; i++) { 1343 DLOGV_IF(kTagQDCM, "Color Mode[%d]: Name = %s mode_id = %d", i, color_modes_[i].name, 1344 color_modes_[i].id); 1345 // get the name of default color mode 1346 if (color_modes_[i].id == default_id) { 1347 current_color_mode_ = color_modes_[i].name; 1348 } 1349 auto it = color_mode_map_.find(color_modes_[i].name); 1350 if (it != color_mode_map_.end()) { 1351 if (it->second->id < color_modes_[i].id) { 1352 color_mode_map_.erase(it); 1353 color_mode_map_.insert(std::make_pair(color_modes_[i].name, &color_modes_[i])); 1354 } 1355 } else { 1356 color_mode_map_.insert(std::make_pair(color_modes_[i].name, &color_modes_[i])); 1357 } 1358 1359 var.clear(); 1360 error = color_mgr_->ColorMgrGetModeInfo(color_modes_[i].id, &var); 1361 if (error != kErrorNone) { 1362 DLOGE("Failed for get attributes of mode_id = %d", color_modes_[i].id); 1363 continue; 1364 } 1365 if (!var.empty()) { 1366 auto it = color_mode_attr_map_.find(color_modes_[i].name); 1367 if (it == color_mode_attr_map_.end()) { 1368 color_mode_attr_map_.insert(std::make_pair(color_modes_[i].name, var)); 1369 } 1370 } 1371 } 1372 } 1373 1374 return kErrorNone; 1375 } 1376 1377 DisplayError DisplayBase::HandleHDR(LayerStack *layer_stack) { 1378 DisplayError error = kErrorNone; 1379 1380 if (display_type_ != kPrimary) { 1381 // Handling is needed for only primary displays 1382 return kErrorNone; 1383 } 1384 1385 if (!layer_stack->flags.hdr_present) { 1386 // HDR playback off - set prev mode 1387 if (hdr_playback_mode_) { 1388 hdr_playback_mode_ = false; 1389 if (color_mgr_ && !disable_hdr_lut_gen_) { 1390 // Do not apply HDR Mode when hdr lut generation is disabled 1391 DLOGI("Setting color mode = %s", current_color_mode_.c_str()); 1392 // HDR playback off - set prev mode 1393 error = SetColorModeInternal(current_color_mode_); 1394 } 1395 comp_manager_->ControlDpps(true); // Enable Dpps 1396 } 1397 } else { 1398 // hdr is present 1399 if (!hdr_playback_mode_ && !layer_stack->flags.animating) { 1400 // hdr is starting 1401 hdr_playback_mode_ = true; 1402 if (color_mgr_ && !disable_hdr_lut_gen_) { 1403 std::string hdr_color_mode; 1404 if (IsSupportColorModeAttribute(current_color_mode_)) { 1405 bool found_hdr = false; 1406 error = GetHdrColorMode(&hdr_color_mode, &found_hdr); 1407 // try to set "hal-hdr" mode if did not found that 1408 // the dynamic range of mode is hdr 1409 if (!found_hdr) { 1410 hdr_color_mode = "hal_hdr"; 1411 } 1412 } else { 1413 hdr_color_mode = "hal_hdr"; 1414 } 1415 DLOGI("Setting color mode = %s", hdr_color_mode.c_str()); 1416 error = SetColorModeInternal(hdr_color_mode); 1417 } 1418 comp_manager_->ControlDpps(false); // Disable Dpps 1419 } 1420 } 1421 1422 return error; 1423 } 1424 1425 } // namespace sdm 1426