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