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