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 39namespace sdm { 40 41std::bitset<kDisplayMax> DisplayBase::needs_validate_ = 0; 42 43// TODO(user): Have a single structure handle carries all the interface pointers and variables. 44DisplayBase::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 52DisplayError 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 118CleanupOnError: 119 if (display_comp_ctx_) { 120 comp_manager_->UnregisterDisplay(display_comp_ctx_); 121 } 122 123 return error; 124} 125 126DisplayError 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 146DisplayError 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 176DisplayError 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 215DisplayError 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 272DisplayError 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 338DisplayError 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 357DisplayError 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 367DisplayError DisplayBase::GetNumVariableInfoConfigs(uint32_t *count) { 368 lock_guard<recursive_mutex> obj(recursive_mutex_); 369 return hw_intf_->GetNumDisplayAttributes(count); 370} 371 372DisplayError 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 383DisplayError 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 399DisplayError DisplayBase::GetActiveConfig(uint32_t *index) { 400 lock_guard<recursive_mutex> obj(recursive_mutex_); 401 return hw_intf_->GetActiveConfig(index); 402} 403 404DisplayError 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 415DisplayError 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 484DisplayError 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 503DisplayError 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 516void 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 561 DumpImpl::AppendString(buffer, length, "\nROI%d(L T R B) : LEFT(%d %d %d %d)", i, 562 INT(l_roi.left), INT(l_roi.top), INT(l_roi.right), INT(l_roi.bottom)); 563 if (i < layer_info.right_frame_roi.size()) { 564 LayerRect &r_roi = layer_info.right_frame_roi.at(i); 565 if (IsValid(r_roi)) { 566 DumpImpl::AppendString(buffer, length, ", RIGHT(%d %d %d %d)", INT(r_roi.left), 567 INT(r_roi.top), INT(r_roi.right), INT(r_roi.bottom)); 568 } 569 } 570 } 571 572 LayerRect &fb_roi = layer_info.partial_fb_roi; 573 if (IsValid(fb_roi)) { 574 DumpImpl::AppendString(buffer, length, "\nPartial FB ROI(L T R B) : (%d %d %d %d)", 575 INT(fb_roi.left), INT(fb_roi.top), INT(fb_roi.right), INT(fb_roi.bottom)); 576 } 577 578 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 579 const char *newline = "\n|-----|-------------|--------|----|--------|-------------|--------------------------|---------------------|---------------------|----|------------|-----------|----|-----|"; //NOLINT 580 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 581 582 DumpImpl::AppendString(buffer, length, "\n"); 583 DumpImpl::AppendString(buffer, length, newline); 584 DumpImpl::AppendString(buffer, length, header); 585 DumpImpl::AppendString(buffer, length, newline); 586 587 for (uint32_t i = 0; i < num_hw_layers; i++) { 588 uint32_t layer_index = hw_layers_.info.index[i]; 589 // sdm-layer from client layer stack 590 Layer *sdm_layer = hw_layers_.info.stack->layers.at(layer_index); 591 // hw-layer from hw layers info 592 Layer &hw_layer = hw_layers_.info.hw_layers.at(i); 593 LayerBuffer *input_buffer = &hw_layer.input_buffer; 594 HWLayerConfig &layer_config = hw_layers_.config[i]; 595 HWRotatorSession &hw_rotator_session = layer_config.hw_rotator_session; 596 597 char idx[8] = { 0 }; 598 const char *comp_type = GetName(sdm_layer->composition); 599 const char *buffer_format = GetFormatString(input_buffer->format); 600 const char *rotate_split[2] = { "Rot-1", "Rot-2" }; 601 const char *comp_split[2] = { "Comp-1", "Comp-2" }; 602 603 snprintf(idx, sizeof(idx), "%d", layer_index); 604 605 for (uint32_t count = 0; count < hw_rotator_session.hw_block_count; count++) { 606 char writeback_id[8] = { 0 }; 607 HWRotateInfo &rotate = hw_rotator_session.hw_rotate_info[count]; 608 LayerRect &src_roi = rotate.src_roi; 609 LayerRect &dst_roi = rotate.dst_roi; 610 611 snprintf(writeback_id, sizeof(writeback_id), "%d", rotate.writeback_id); 612 613 DumpImpl::AppendString(buffer, length, format, idx, comp_type, rotate_split[count], 614 writeback_id, rotate.pipe_id, input_buffer->width, 615 input_buffer->height, buffer_format, INT(src_roi.left), 616 INT(src_roi.top), INT(src_roi.right), INT(src_roi.bottom), 617 INT(dst_roi.left), INT(dst_roi.top), INT(dst_roi.right), 618 INT(dst_roi.bottom), "-", "- ", "- ", "-", "-"); 619 620 // print the below only once per layer block, fill with spaces for rest. 621 idx[0] = 0; 622 comp_type = ""; 623 } 624 625 if (hw_rotator_session.hw_block_count > 0) { 626 input_buffer = &hw_rotator_session.output_buffer; 627 buffer_format = GetFormatString(input_buffer->format); 628 } 629 630 for (uint32_t count = 0; count < 2; count++) { 631 char decimation[16] = { 0 }; 632 char flags[16] = { 0 }; 633 char z_order[8] = { 0 }; 634 char color_primary[8] = { 0 }; 635 char range[8] = { 0 }; 636 637 HWPipeInfo &pipe = (count == 0) ? layer_config.left_pipe : layer_config.right_pipe; 638 639 if (!pipe.valid) { 640 continue; 641 } 642 643 LayerRect &src_roi = pipe.src_roi; 644 LayerRect &dst_roi = pipe.dst_roi; 645 646 snprintf(z_order, sizeof(z_order), "%d", pipe.z_order); 647 snprintf(flags, sizeof(flags), "0x%08x", hw_layer.flags.flags); 648 snprintf(decimation, sizeof(decimation), "%3d x %3d", pipe.horizontal_decimation, 649 pipe.vertical_decimation); 650 ColorMetaData &color_metadata = hw_layer.input_buffer.color_metadata; 651 snprintf(color_primary, sizeof(color_primary), "%d", color_metadata.colorPrimaries); 652 snprintf(range, sizeof(range), "%d", color_metadata.range); 653 654 DumpImpl::AppendString(buffer, length, format, idx, comp_type, comp_split[count], 655 "-", pipe.pipe_id, input_buffer->width, input_buffer->height, 656 buffer_format, INT(src_roi.left), INT(src_roi.top), 657 INT(src_roi.right), INT(src_roi.bottom), INT(dst_roi.left), 658 INT(dst_roi.top), INT(dst_roi.right), INT(dst_roi.bottom), 659 z_order, flags, decimation, color_primary, range); 660 661 // print the below only once per layer block, fill with spaces for rest. 662 idx[0] = 0; 663 comp_type = ""; 664 } 665 666 DumpImpl::AppendString(buffer, length, newline); 667 } 668} 669 670const char * DisplayBase::GetName(const LayerComposition &composition) { 671 switch (composition) { 672 case kCompositionGPU: return "GPU"; 673 case kCompositionSDE: return "SDE"; 674 case kCompositionHWCursor: return "CURSOR"; 675 case kCompositionHybrid: return "HYBRID"; 676 case kCompositionBlit: return "BLIT"; 677 case kCompositionGPUTarget: return "GPU_TARGET"; 678 case kCompositionBlitTarget: return "BLIT_TARGET"; 679 default: return "UNKNOWN"; 680 } 681} 682 683DisplayError DisplayBase::ColorSVCRequestRoute(const PPDisplayAPIPayload &in_payload, 684 PPDisplayAPIPayload *out_payload, 685 PPPendingParams *pending_action) { 686 lock_guard<recursive_mutex> obj(recursive_mutex_); 687 if (color_mgr_) 688 return color_mgr_->ColorSVCRequestRoute(in_payload, out_payload, pending_action); 689 else 690 return kErrorParameters; 691} 692 693DisplayError DisplayBase::GetColorModeCount(uint32_t *mode_count) { 694 lock_guard<recursive_mutex> obj(recursive_mutex_); 695 if (!mode_count) { 696 return kErrorParameters; 697 } 698 699 if (!color_mgr_) { 700 return kErrorNotSupported; 701 } 702 703 DLOGV_IF(kTagQDCM, "Number of modes from color manager = %d", num_color_modes_); 704 *mode_count = num_color_modes_; 705 706 return kErrorNone; 707} 708 709DisplayError DisplayBase::GetColorModes(uint32_t *mode_count, 710 std::vector<std::string> *color_modes) { 711 lock_guard<recursive_mutex> obj(recursive_mutex_); 712 if (!mode_count || !color_modes) { 713 return kErrorParameters; 714 } 715 716 if (!color_mgr_) { 717 return kErrorNotSupported; 718 } 719 720 for (uint32_t i = 0; i < num_color_modes_; i++) { 721 DLOGV_IF(kTagQDCM, "Color Mode[%d]: Name = %s mode_id = %d", i, color_modes_[i].name, 722 color_modes_[i].id); 723 color_modes->at(i) = color_modes_[i].name; 724 } 725 726 return kErrorNone; 727} 728 729DisplayError DisplayBase::GetColorModeAttr(const std::string &color_mode, AttrVal *attr) { 730 lock_guard<recursive_mutex> obj(recursive_mutex_); 731 if (!attr) { 732 return kErrorParameters; 733 } 734 735 if (!color_mgr_) { 736 return kErrorNotSupported; 737 } 738 739 auto it = color_mode_attr_map_.find(color_mode); 740 if (it == color_mode_attr_map_.end()) { 741 DLOGI("Mode %s has no attribute", color_mode.c_str()); 742 return kErrorNotSupported; 743 } 744 *attr = it->second; 745 746 return kErrorNone; 747} 748 749DisplayError DisplayBase::SetColorMode(const std::string &color_mode) { 750 lock_guard<recursive_mutex> obj(recursive_mutex_); 751 if (!color_mgr_) { 752 return kErrorNotSupported; 753 } 754 755 DynamicRangeType dynamic_range_type; 756 if (IsSupportColorModeAttribute(color_mode)) { 757 auto it_mode = color_mode_attr_map_.find(color_mode); 758 std::string dynamic_range; 759 GetValueOfModeAttribute(it_mode->second, kDynamicRangeAttribute, &dynamic_range); 760 if (dynamic_range == kHdr) { 761 dynamic_range_type = kHdrType; 762 } else { 763 dynamic_range_type = kSdrType; 764 } 765 } else { 766 if (color_mode.find("hal_hdr") != std::string::npos) { 767 dynamic_range_type = kHdrType; 768 } else { 769 dynamic_range_type = kSdrType; 770 } 771 } 772 773 DisplayError error = kErrorNone; 774 if (disable_hdr_lut_gen_) { 775 error = SetColorModeInternal(color_mode); 776 if (error != kErrorNone) { 777 return error; 778 } 779 // Store the new SDR color mode request by client 780 if (dynamic_range_type == kSdrType) { 781 current_color_mode_ = color_mode; 782 } 783 return error; 784 } 785 786 if (hdr_playback_mode_) { 787 // HDR playback on, If incoming mode is SDR mode, 788 // cache the mode and apply it after HDR playback stop. 789 if (dynamic_range_type == kHdrType) { 790 error = SetColorModeInternal(color_mode); 791 if (error != kErrorNone) { 792 return error; 793 } 794 } else if (dynamic_range_type == kSdrType) { 795 current_color_mode_ = color_mode; 796 } 797 } else { 798 // HDR playback off, do not apply HDR mode 799 if (dynamic_range_type == kHdrType) { 800 DLOGE("Failed: Forbid setting HDR Mode : %s when HDR playback off", color_mode.c_str()); 801 return kErrorNotSupported; 802 } 803 error = SetColorModeInternal(color_mode); 804 if (error != kErrorNone) { 805 return error; 806 } 807 current_color_mode_ = color_mode; 808 } 809 810 return error; 811} 812 813DisplayError DisplayBase::SetColorModeById(int32_t color_mode_id) { 814 return color_mgr_->ColorMgrSetMode(color_mode_id); 815} 816 817DisplayError DisplayBase::SetColorModeInternal(const std::string &color_mode) { 818 DLOGV_IF(kTagQDCM, "Color Mode = %s", color_mode.c_str()); 819 820 ColorModeMap::iterator it = color_mode_map_.find(color_mode); 821 if (it == color_mode_map_.end()) { 822 DLOGE("Failed: Unknown Mode : %s", color_mode.c_str()); 823 return kErrorNotSupported; 824 } 825 826 SDEDisplayMode *sde_display_mode = it->second; 827 828 DLOGV_IF(kTagQDCM, "Color Mode Name = %s corresponding mode_id = %d", sde_display_mode->name, 829 sde_display_mode->id); 830 DisplayError error = kErrorNone; 831 error = color_mgr_->ColorMgrSetMode(sde_display_mode->id); 832 if (error != kErrorNone) { 833 DLOGE("Failed for mode id = %d", sde_display_mode->id); 834 return error; 835 } 836 837 return error; 838} 839 840DisplayError DisplayBase::GetValueOfModeAttribute(const AttrVal &attr, const std::string &type, 841 std::string *value) { 842 if (!value) { 843 return kErrorParameters; 844 } 845 for (auto &it : attr) { 846 if (it.first.find(type) != std::string::npos) { 847 *value = it.second; 848 } 849 } 850 851 return kErrorNone; 852} 853 854bool DisplayBase::IsSupportColorModeAttribute(const std::string &color_mode) { 855 auto it = color_mode_attr_map_.find(color_mode); 856 if (it == color_mode_attr_map_.end()) { 857 return false; 858 } 859 return true; 860} 861 862DisplayError DisplayBase::GetHdrColorMode(std::string *color_mode, bool *found_hdr) { 863 if (!found_hdr || !color_mode) { 864 return kErrorParameters; 865 } 866 auto it_mode = color_mode_attr_map_.find(current_color_mode_); 867 if (it_mode == color_mode_attr_map_.end()) { 868 DLOGE("Failed: Unknown Mode : %s", current_color_mode_.c_str()); 869 return kErrorNotSupported; 870 } 871 872 *found_hdr = false; 873 std::string cur_color_gamut, cur_pic_quality; 874 // get the attributes of current color mode 875 GetValueOfModeAttribute(it_mode->second, kColorGamutAttribute, &cur_color_gamut); 876 GetValueOfModeAttribute(it_mode->second, kPictureQualityAttribute, &cur_pic_quality); 877 878 // found the corresponding HDR mode id which 879 // has the same attributes with current SDR mode. 880 for (auto &it_hdr : color_mode_attr_map_) { 881 std::string dynamic_range, color_gamut, pic_quality; 882 GetValueOfModeAttribute(it_hdr.second, kDynamicRangeAttribute, &dynamic_range); 883 GetValueOfModeAttribute(it_hdr.second, kColorGamutAttribute, &color_gamut); 884 GetValueOfModeAttribute(it_hdr.second, kPictureQualityAttribute, &pic_quality); 885 if (dynamic_range == kHdr && cur_color_gamut == color_gamut && 886 cur_pic_quality == pic_quality) { 887 *color_mode = it_hdr.first; 888 *found_hdr = true; 889 DLOGV_IF(kTagQDCM, "corresponding hdr mode = %s", color_mode->c_str()); 890 return kErrorNone; 891 } 892 } 893 894 // The corresponding HDR mode was not be found, 895 // apply the first HDR mode that we encouter. 896 for (auto &it_hdr : color_mode_attr_map_) { 897 std::string dynamic_range; 898 GetValueOfModeAttribute(it_hdr.second, kDynamicRangeAttribute, &dynamic_range); 899 if (dynamic_range == kHdr) { 900 *color_mode = it_hdr.first; 901 *found_hdr = true; 902 DLOGV_IF(kTagQDCM, "First hdr mode = %s", color_mode->c_str()); 903 return kErrorNone; 904 } 905 } 906 907 return kErrorNone; 908} 909 910DisplayError DisplayBase::SetColorTransform(const uint32_t length, const double *color_transform) { 911 lock_guard<recursive_mutex> obj(recursive_mutex_); 912 if (!color_mgr_) { 913 return kErrorNotSupported; 914 } 915 916 if (!color_transform) { 917 return kErrorParameters; 918 } 919 920 return color_mgr_->ColorMgrSetColorTransform(length, color_transform); 921} 922 923DisplayError DisplayBase::GetDefaultColorMode(std::string *color_mode) { 924 lock_guard<recursive_mutex> obj(recursive_mutex_); 925 if (!color_mode) { 926 return kErrorParameters; 927 } 928 929 if (!color_mgr_) { 930 return kErrorNotSupported; 931 } 932 933 int32_t default_id = kInvalidModeId; 934 DisplayError error = color_mgr_->ColorMgrGetDefaultModeID(&default_id); 935 if (error != kErrorNone) { 936 DLOGE("Failed for get default color mode id"); 937 return error; 938 } 939 940 for (uint32_t i = 0; i < num_color_modes_; i++) { 941 if (color_modes_[i].id == default_id) { 942 *color_mode = color_modes_[i].name; 943 return kErrorNone; 944 } 945 } 946 947 return kErrorNotSupported; 948} 949 950DisplayError DisplayBase::ApplyDefaultDisplayMode() { 951 lock_guard<recursive_mutex> obj(recursive_mutex_); 952 if (color_mgr_) 953 return color_mgr_->ApplyDefaultDisplayMode(); 954 else 955 return kErrorParameters; 956} 957 958DisplayError DisplayBase::SetCursorPosition(int x, int y) { 959 lock_guard<recursive_mutex> obj(recursive_mutex_); 960 if (state_ != kStateOn) { 961 return kErrorNotSupported; 962 } 963 964 DisplayError error = comp_manager_->ValidateCursorPosition(display_comp_ctx_, &hw_layers_, x, y); 965 if (error == kErrorNone) { 966 return hw_intf_->SetCursorPosition(&hw_layers_, x, y); 967 } 968 969 return kErrorNone; 970} 971 972DisplayError DisplayBase::GetRefreshRateRange(uint32_t *min_refresh_rate, 973 uint32_t *max_refresh_rate) { 974 lock_guard<recursive_mutex> obj(recursive_mutex_); 975 // The min and max refresh rates will be same when the HWPanelInfo does not contain valid rates. 976 // Usually for secondary displays, command mode panels 977 HWDisplayAttributes display_attributes; 978 uint32_t active_index = 0; 979 hw_intf_->GetActiveConfig(&active_index); 980 DisplayError error = hw_intf_->GetDisplayAttributes(active_index, &display_attributes); 981 if (error) { 982 return error; 983 } 984 985 *min_refresh_rate = display_attributes.fps; 986 *max_refresh_rate = display_attributes.fps; 987 988 return error; 989} 990 991DisplayError DisplayBase::SetVSyncState(bool enable) { 992 lock_guard<recursive_mutex> obj(recursive_mutex_); 993 DisplayError error = kErrorNone; 994 if (vsync_enable_ != enable) { 995 error = hw_intf_->SetVSyncState(enable); 996 if (error == kErrorNone) { 997 vsync_enable_ = enable; 998 } 999 } 1000 return error; 1001} 1002 1003DisplayError DisplayBase::ReconfigureDisplay() { 1004 lock_guard<recursive_mutex> obj(recursive_mutex_); 1005 DisplayError error = kErrorNone; 1006 HWDisplayAttributes display_attributes; 1007 HWMixerAttributes mixer_attributes; 1008 HWPanelInfo hw_panel_info; 1009 uint32_t active_index = 0; 1010 1011 error = hw_intf_->GetActiveConfig(&active_index); 1012 if (error != kErrorNone) { 1013 return error; 1014 } 1015 1016 error = hw_intf_->GetDisplayAttributes(active_index, &display_attributes); 1017 if (error != kErrorNone) { 1018 return error; 1019 } 1020 1021 error = hw_intf_->GetMixerAttributes(&mixer_attributes); 1022 if (error != kErrorNone) { 1023 return error; 1024 } 1025 1026 error = hw_intf_->GetHWPanelInfo(&hw_panel_info); 1027 if (error != kErrorNone) { 1028 return error; 1029 } 1030 1031 if (display_attributes == display_attributes_ && mixer_attributes == mixer_attributes_ && 1032 hw_panel_info == hw_panel_info_) { 1033 return kErrorNone; 1034 } 1035 1036 error = comp_manager_->ReconfigureDisplay(display_comp_ctx_, display_attributes, hw_panel_info, 1037 mixer_attributes, fb_config_); 1038 if (error != kErrorNone) { 1039 return error; 1040 } 1041 1042 if (mixer_attributes != mixer_attributes_) { 1043 DisablePartialUpdateOneFrame(); 1044 } 1045 1046 display_attributes_ = display_attributes; 1047 mixer_attributes_ = mixer_attributes; 1048 hw_panel_info_ = hw_panel_info; 1049 1050 return kErrorNone; 1051} 1052 1053DisplayError DisplayBase::SetMixerResolution(uint32_t width, uint32_t height) { 1054 lock_guard<recursive_mutex> obj(recursive_mutex_); 1055 1056 DisplayError error = ReconfigureMixer(width, height); 1057 if (error != kErrorNone) { 1058 return error; 1059 } 1060 1061 req_mixer_width_ = width; 1062 req_mixer_height_ = height; 1063 1064 return kErrorNone; 1065} 1066 1067DisplayError DisplayBase::GetMixerResolution(uint32_t *width, uint32_t *height) { 1068 lock_guard<recursive_mutex> obj(recursive_mutex_); 1069 if (!width || !height) { 1070 return kErrorParameters; 1071 } 1072 1073 *width = mixer_attributes_.width; 1074 *height = mixer_attributes_.height; 1075 1076 return kErrorNone; 1077} 1078 1079DisplayError DisplayBase::ReconfigureMixer(uint32_t width, uint32_t height) { 1080 lock_guard<recursive_mutex> obj(recursive_mutex_); 1081 DisplayError error = kErrorNone; 1082 1083 if (!width || !height) { 1084 return kErrorParameters; 1085 } 1086 1087 HWMixerAttributes mixer_attributes; 1088 mixer_attributes.width = width; 1089 mixer_attributes.height = height; 1090 1091 error = hw_intf_->SetMixerAttributes(mixer_attributes); 1092 if (error != kErrorNone) { 1093 return error; 1094 } 1095 1096 return ReconfigureDisplay(); 1097} 1098 1099bool DisplayBase::NeedsDownScale(const LayerRect &src_rect, const LayerRect &dst_rect, 1100 bool needs_rotation) { 1101 float src_width = FLOAT(src_rect.right - src_rect.left); 1102 float src_height = FLOAT(src_rect.bottom - src_rect.top); 1103 float dst_width = FLOAT(dst_rect.right - dst_rect.left); 1104 float dst_height = FLOAT(dst_rect.bottom - dst_rect.top); 1105 1106 if (needs_rotation) { 1107 std::swap(src_width, src_height); 1108 } 1109 1110 if ((src_width > dst_width) || (src_height > dst_height)) { 1111 return true; 1112 } 1113 1114 return false; 1115} 1116 1117bool DisplayBase::NeedsMixerReconfiguration(LayerStack *layer_stack, uint32_t *new_mixer_width, 1118 uint32_t *new_mixer_height) { 1119 lock_guard<recursive_mutex> obj(recursive_mutex_); 1120 uint32_t layer_count = UINT32(layer_stack->layers.size()); 1121 1122 uint32_t fb_width = fb_config_.x_pixels; 1123 uint32_t fb_height = fb_config_.y_pixels; 1124 uint32_t fb_area = fb_width * fb_height; 1125 LayerRect fb_rect = (LayerRect) {0.0f, 0.0f, FLOAT(fb_width), FLOAT(fb_height)}; 1126 uint32_t mixer_width = mixer_attributes_.width; 1127 uint32_t mixer_height = mixer_attributes_.height; 1128 uint32_t display_width = display_attributes_.x_pixels; 1129 uint32_t display_height = display_attributes_.y_pixels; 1130 1131 RectOrientation fb_orientation = GetOrientation(fb_rect); 1132 uint32_t max_layer_area = 0; 1133 uint32_t max_area_layer_index = 0; 1134 std::vector<Layer *> layers = layer_stack->layers; 1135 uint32_t align_x = display_attributes_.is_device_split ? 4 : 2; 1136 uint32_t align_y = 2; 1137 1138 if (req_mixer_width_ && req_mixer_height_) { 1139 *new_mixer_width = req_mixer_width_; 1140 *new_mixer_height = req_mixer_height_; 1141 1142 return (req_mixer_width_ != mixer_width || req_mixer_height_ != mixer_height); 1143 } 1144 1145 for (uint32_t i = 0; i < layer_count; i++) { 1146 Layer *layer = layers.at(i); 1147 1148 uint32_t layer_width = UINT32(layer->src_rect.right - layer->src_rect.left); 1149 uint32_t layer_height = UINT32(layer->src_rect.bottom - layer->src_rect.top); 1150 uint32_t layer_area = layer_width * layer_height; 1151 1152 if (layer_area > max_layer_area) { 1153 max_layer_area = layer_area; 1154 max_area_layer_index = i; 1155 } 1156 } 1157 1158 // TODO(user): Mark layer which needs downscaling on GPU fallback as priority layer and use MDP 1159 // for composition to avoid quality mismatch between GPU and MDP switch(idle timeout usecase). 1160 if (max_layer_area >= fb_area) { 1161 Layer *layer = layers.at(max_area_layer_index); 1162 bool needs_rotation = (layer->transform.rotation == 90.0f); 1163 1164 uint32_t layer_width = UINT32(layer->src_rect.right - layer->src_rect.left); 1165 uint32_t layer_height = UINT32(layer->src_rect.bottom - layer->src_rect.top); 1166 LayerRect layer_dst_rect = {}; 1167 1168 RectOrientation layer_orientation = GetOrientation(layer->src_rect); 1169 if (layer_orientation != kOrientationUnknown && 1170 fb_orientation != kOrientationUnknown) { 1171 if (layer_orientation != fb_orientation) { 1172 std::swap(layer_width, layer_height); 1173 } 1174 } 1175 1176 // Align the width and height according to fb's aspect ratio 1177 *new_mixer_width = FloorToMultipleOf(UINT32((FLOAT(fb_width) / FLOAT(fb_height)) * 1178 layer_height), align_x); 1179 *new_mixer_height = FloorToMultipleOf(layer_height, align_y); 1180 1181 LayerRect dst_domain = {0.0f, 0.0f, FLOAT(*new_mixer_width), FLOAT(*new_mixer_height)}; 1182 1183 MapRect(fb_rect, dst_domain, layer->dst_rect, &layer_dst_rect); 1184 if (NeedsDownScale(layer->src_rect, layer_dst_rect, needs_rotation)) { 1185 *new_mixer_width = display_width; 1186 *new_mixer_height = display_height; 1187 } 1188 1189 return true; 1190 } 1191 1192 return false; 1193} 1194 1195DisplayError DisplayBase::SetFrameBufferConfig(const DisplayConfigVariableInfo &variable_info) { 1196 lock_guard<recursive_mutex> obj(recursive_mutex_); 1197 uint32_t width = variable_info.x_pixels; 1198 uint32_t height = variable_info.y_pixels; 1199 1200 if (width == 0 || height == 0) { 1201 DLOGE("Unsupported resolution: (%dx%d)", width, height); 1202 return kErrorParameters; 1203 } 1204 1205 // Create rects to represent the new source and destination crops 1206 LayerRect crop = LayerRect(0, 0, FLOAT(width), FLOAT(height)); 1207 LayerRect dst = LayerRect(0, 0, FLOAT(mixer_attributes_.width), FLOAT(mixer_attributes_.height)); 1208 // Set rotate90 to false since this is taken care of during regular composition. 1209 bool rotate90 = false; 1210 1211 DisplayError error = comp_manager_->ValidateScaling(crop, dst, rotate90); 1212 if (error != kErrorNone) { 1213 DLOGE("Unsupported resolution: (%dx%d)", width, height); 1214 return kErrorParameters; 1215 } 1216 1217 error = comp_manager_->ReconfigureDisplay(display_comp_ctx_, display_attributes_, hw_panel_info_, 1218 mixer_attributes_, variable_info); 1219 if (error != kErrorNone) { 1220 return error; 1221 } 1222 1223 fb_config_.x_pixels = width; 1224 fb_config_.y_pixels = height; 1225 1226 DLOGI("New framebuffer resolution (%dx%d)", fb_config_.x_pixels, fb_config_.y_pixels); 1227 1228 return kErrorNone; 1229} 1230 1231DisplayError DisplayBase::GetFrameBufferConfig(DisplayConfigVariableInfo *variable_info) { 1232 lock_guard<recursive_mutex> obj(recursive_mutex_); 1233 if (!variable_info) { 1234 return kErrorParameters; 1235 } 1236 1237 *variable_info = fb_config_; 1238 1239 return kErrorNone; 1240} 1241 1242DisplayError DisplayBase::SetDetailEnhancerData(const DisplayDetailEnhancerData &de_data) { 1243 lock_guard<recursive_mutex> obj(recursive_mutex_); 1244 DisplayError error = comp_manager_->SetDetailEnhancerData(display_comp_ctx_, de_data); 1245 if (error != kErrorNone) { 1246 return error; 1247 } 1248 1249 DisablePartialUpdateOneFrame(); 1250 1251 return kErrorNone; 1252} 1253 1254DisplayError DisplayBase::GetDisplayPort(DisplayPort *port) { 1255 lock_guard<recursive_mutex> obj(recursive_mutex_); 1256 1257 if (!port) { 1258 return kErrorParameters; 1259 } 1260 1261 *port = hw_panel_info_.port; 1262 1263 return kErrorNone; 1264} 1265 1266bool DisplayBase::IsPrimaryDisplay() { 1267 lock_guard<recursive_mutex> obj(recursive_mutex_); 1268 1269 return hw_panel_info_.is_primary_panel; 1270} 1271 1272DisplayError DisplayBase::SetCompositionState(LayerComposition composition_type, bool enable) { 1273 lock_guard<recursive_mutex> obj(recursive_mutex_); 1274 1275 return comp_manager_->SetCompositionState(display_comp_ctx_, composition_type, enable); 1276} 1277 1278void DisplayBase::CommitLayerParams(LayerStack *layer_stack) { 1279 // Copy the acquire fence from clients layers to HWLayers 1280 uint32_t hw_layers_count = UINT32(hw_layers_.info.hw_layers.size()); 1281 1282 for (uint32_t i = 0; i < hw_layers_count; i++) { 1283 Layer *sdm_layer = layer_stack->layers.at(hw_layers_.info.index[i]); 1284 Layer &hw_layer = hw_layers_.info.hw_layers.at(i); 1285 1286 hw_layer.input_buffer.planes[0].fd = sdm_layer->input_buffer.planes[0].fd; 1287 hw_layer.input_buffer.planes[0].offset = sdm_layer->input_buffer.planes[0].offset; 1288 hw_layer.input_buffer.planes[0].stride = sdm_layer->input_buffer.planes[0].stride; 1289 hw_layer.input_buffer.size = sdm_layer->input_buffer.size; 1290 hw_layer.input_buffer.acquire_fence_fd = sdm_layer->input_buffer.acquire_fence_fd; 1291 hw_layer.input_buffer.fb_id = sdm_layer->input_buffer.fb_id; 1292 } 1293 1294 return; 1295} 1296 1297void DisplayBase::PostCommitLayerParams(LayerStack *layer_stack) { 1298 // Copy the release fence from HWLayers to clients layers 1299 uint32_t hw_layers_count = UINT32(hw_layers_.info.hw_layers.size()); 1300 1301 std::vector<uint32_t> fence_dup_flag = {}; 1302 1303 for (uint32_t i = 0; i < hw_layers_count; i++) { 1304 uint32_t sdm_layer_index = hw_layers_.info.index[i]; 1305 Layer *sdm_layer = layer_stack->layers.at(sdm_layer_index); 1306 Layer &hw_layer = hw_layers_.info.hw_layers.at(i); 1307 1308 // Copy the release fence only once for a SDM Layer. 1309 // In S3D use case, two hw layers can share the same input buffer, So make sure to merge the 1310 // output fence fd and assign it to layer's input buffer release fence fd. 1311 if (std::find(fence_dup_flag.begin(), fence_dup_flag.end(), sdm_layer_index) == 1312 fence_dup_flag.end()) { 1313 sdm_layer->input_buffer.release_fence_fd = hw_layer.input_buffer.release_fence_fd; 1314 fence_dup_flag.push_back(sdm_layer_index); 1315 } else { 1316 int temp = -1; 1317 buffer_sync_handler_->SyncMerge(hw_layer.input_buffer.release_fence_fd, 1318 sdm_layer->input_buffer.release_fence_fd, &temp); 1319 1320 if (hw_layer.input_buffer.release_fence_fd >= 0) { 1321 Sys::close_(hw_layer.input_buffer.release_fence_fd); 1322 hw_layer.input_buffer.release_fence_fd = -1; 1323 } 1324 1325 if (sdm_layer->input_buffer.release_fence_fd >= 0) { 1326 Sys::close_(sdm_layer->input_buffer.release_fence_fd); 1327 sdm_layer->input_buffer.release_fence_fd = -1; 1328 } 1329 1330 sdm_layer->input_buffer.release_fence_fd = temp; 1331 } 1332 1333 // Reset the sync fence fds of HWLayer 1334 hw_layer.input_buffer.acquire_fence_fd = -1; 1335 hw_layer.input_buffer.release_fence_fd = -1; 1336 } 1337 1338 return; 1339} 1340 1341DisplayError DisplayBase::InitializeColorModes() { 1342 if (!color_mgr_) { 1343 return kErrorNotSupported; 1344 } 1345 1346 DisplayError error = color_mgr_->ColorMgrGetNumOfModes(&num_color_modes_); 1347 if (error != kErrorNone || !num_color_modes_) { 1348 DLOGV_IF(kTagQDCM, "GetNumModes failed = %d count = %d", error, num_color_modes_); 1349 return kErrorNotSupported; 1350 } 1351 DLOGI("Number of Color Modes = %d", num_color_modes_); 1352 1353 if (!color_modes_.size()) { 1354 color_modes_.resize(num_color_modes_); 1355 1356 DisplayError error = color_mgr_->ColorMgrGetModes(&num_color_modes_, color_modes_.data()); 1357 if (error != kErrorNone) { 1358 color_modes_.clear(); 1359 DLOGE("Failed"); 1360 return error; 1361 } 1362 int32_t default_id = kInvalidModeId; 1363 error = color_mgr_->ColorMgrGetDefaultModeID(&default_id); 1364 1365 AttrVal var; 1366 for (uint32_t i = 0; i < num_color_modes_; i++) { 1367 DLOGV_IF(kTagQDCM, "Color Mode[%d]: Name = %s mode_id = %d", i, color_modes_[i].name, 1368 color_modes_[i].id); 1369 // get the name of default color mode 1370 if (color_modes_[i].id == default_id) { 1371 current_color_mode_ = color_modes_[i].name; 1372 } 1373 auto it = color_mode_map_.find(color_modes_[i].name); 1374 if (it != color_mode_map_.end()) { 1375 if (it->second->id < color_modes_[i].id) { 1376 color_mode_map_.erase(it); 1377 color_mode_map_.insert(std::make_pair(color_modes_[i].name, &color_modes_[i])); 1378 } 1379 } else { 1380 color_mode_map_.insert(std::make_pair(color_modes_[i].name, &color_modes_[i])); 1381 } 1382 1383 var.clear(); 1384 error = color_mgr_->ColorMgrGetModeInfo(color_modes_[i].id, &var); 1385 if (error != kErrorNone) { 1386 DLOGE("Failed for get attributes of mode_id = %d", color_modes_[i].id); 1387 continue; 1388 } 1389 if (!var.empty()) { 1390 auto it = color_mode_attr_map_.find(color_modes_[i].name); 1391 if (it == color_mode_attr_map_.end()) { 1392 color_mode_attr_map_.insert(std::make_pair(color_modes_[i].name, var)); 1393 } 1394 } 1395 } 1396 } 1397 1398 return kErrorNone; 1399} 1400 1401DisplayError DisplayBase::HandleHDR(LayerStack *layer_stack) { 1402 DisplayError error = kErrorNone; 1403 1404 if (display_type_ != kPrimary) { 1405 // Handling is needed for only primary displays 1406 return kErrorNone; 1407 } 1408 1409 if (!layer_stack->flags.hdr_present) { 1410 // HDR playback off - set prev mode 1411 if (hdr_playback_mode_) { 1412 hdr_playback_mode_ = false; 1413 if (color_mgr_ && !disable_hdr_lut_gen_) { 1414 // Do not apply HDR Mode when hdr lut generation is disabled 1415 DLOGI("Setting color mode = %s", current_color_mode_.c_str()); 1416 // HDR playback off - set prev mode 1417 error = SetColorModeInternal(current_color_mode_); 1418 } 1419 comp_manager_->ControlDpps(true); // Enable Dpps 1420 } 1421 } else { 1422 // hdr is present 1423 if (!hdr_playback_mode_ && !layer_stack->flags.animating) { 1424 // hdr is starting 1425 hdr_playback_mode_ = true; 1426 if (color_mgr_ && !disable_hdr_lut_gen_) { 1427 std::string hdr_color_mode; 1428 if (IsSupportColorModeAttribute(current_color_mode_)) { 1429 bool found_hdr = false; 1430 error = GetHdrColorMode(&hdr_color_mode, &found_hdr); 1431 // try to set "hal-hdr" mode if did not found that 1432 // the dynamic range of mode is hdr 1433 if (!found_hdr) { 1434 hdr_color_mode = "hal_hdr"; 1435 } 1436 } else { 1437 hdr_color_mode = "hal_hdr"; 1438 } 1439 DLOGI("Setting color mode = %s", hdr_color_mode.c_str()); 1440 error = SetColorModeInternal(hdr_color_mode); 1441 } 1442 comp_manager_->ControlDpps(false); // Disable Dpps 1443 } 1444 } 1445 1446 return error; 1447} 1448 1449} // namespace sdm 1450