1 /* 2 * Copyright (c) 2014 - 2016, 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 CompManager *comp_manager, RotatorInterface *rotator_intf, 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), comp_manager_(comp_manager), 48 rotator_intf_(rotator_intf), 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 = hw_intf_->GetMixerAttributes(&mixer_attributes_); 63 if (error != kErrorNone) { 64 return error; 65 } 66 67 // Override x_pixels and y_pixels of frame buffer with mixer width and height 68 fb_config_.x_pixels = mixer_attributes_.width; 69 fb_config_.y_pixels = mixer_attributes_.height; 70 71 HWScaleLutInfo lut_info = {}; 72 error = comp_manager_->GetScaleLutConfig(&lut_info); 73 if (error == kErrorNone) { 74 error = hw_intf_->SetScaleLutConfig(&lut_info); 75 } 76 77 if (error != kErrorNone) { 78 goto CleanupOnError; 79 } 80 81 error = comp_manager_->RegisterDisplay(display_type_, display_attributes_, hw_panel_info_, 82 mixer_attributes_, fb_config_, &display_comp_ctx_); 83 if (error != kErrorNone) { 84 goto CleanupOnError; 85 } 86 87 if (rotator_intf_) { 88 error = rotator_intf_->RegisterDisplay(display_type_, &display_rotator_ctx_); 89 if (error != kErrorNone) { 90 goto CleanupOnError; 91 } 92 } 93 94 if (hw_info_intf_) { 95 HWResourceInfo hw_resource_info = HWResourceInfo(); 96 hw_info_intf_->GetHWResourceInfo(&hw_resource_info); 97 auto max_mixer_stages = hw_resource_info.num_blending_stages; 98 int property_value = Debug::GetMaxPipesPerMixer(display_type_); 99 if (property_value >= 0) { 100 max_mixer_stages = std::min(UINT32(property_value), hw_resource_info.num_blending_stages); 101 } 102 DisplayBase::SetMaxMixerStages(max_mixer_stages); 103 } 104 105 color_mgr_ = ColorManagerProxy::CreateColorManagerProxy(display_type_, hw_intf_, 106 display_attributes_, hw_panel_info_); 107 if (!color_mgr_) { 108 DLOGW("Unable to create ColorManagerProxy for display = %d", display_type_); 109 } 110 111 return kErrorNone; 112 113 CleanupOnError: 114 if (display_comp_ctx_) { 115 comp_manager_->UnregisterDisplay(display_comp_ctx_); 116 } 117 118 return error; 119 } 120 121 DisplayError DisplayBase::Deinit() { 122 lock_guard<recursive_mutex> obj(recursive_mutex_); 123 if (rotator_intf_) { 124 rotator_intf_->UnregisterDisplay(display_rotator_ctx_); 125 } 126 127 if (color_mgr_) { 128 delete color_mgr_; 129 color_mgr_ = NULL; 130 } 131 132 comp_manager_->UnregisterDisplay(display_comp_ctx_); 133 HWEventsInterface::Destroy(hw_events_intf_); 134 HWInterface::Destroy(hw_intf_); 135 136 return kErrorNone; 137 } 138 139 DisplayError DisplayBase::BuildLayerStackStats(LayerStack *layer_stack) { 140 std::vector<Layer *> &layers = layer_stack->layers; 141 HWLayersInfo &hw_layers_info = hw_layers_.info; 142 143 hw_layers_info.stack = layer_stack; 144 145 for (auto &layer : layers) { 146 if (layer->composition == kCompositionGPUTarget) { 147 hw_layers_info.gpu_target_index = hw_layers_info.app_layer_count; 148 break; 149 } 150 hw_layers_info.app_layer_count++; 151 } 152 153 DLOGV_IF(kTagNone, "LayerStack layer_count: %d, app_layer_count: %d, gpu_target_index: %d, " 154 "display type: %d", layers.size(), hw_layers_info.app_layer_count, 155 hw_layers_info.gpu_target_index, display_type_); 156 157 if (!hw_layers_info.app_layer_count) { 158 DLOGE("Layer count is zero"); 159 return kErrorParameters; 160 } 161 162 if (hw_layers_info.gpu_target_index) { 163 return ValidateGPUTargetParams(); 164 } 165 166 return kErrorNone; 167 } 168 169 DisplayError DisplayBase::ValidateGPUTargetParams() { 170 HWLayersInfo &hw_layers_info = hw_layers_.info; 171 Layer *gpu_target_layer = hw_layers_info.stack->layers.at(hw_layers_info.gpu_target_index); 172 173 if (!IsValid(gpu_target_layer->src_rect)) { 174 DLOGE("Invalid src rect for GPU target layer"); 175 return kErrorParameters; 176 } 177 178 if (!IsValid(gpu_target_layer->dst_rect)) { 179 DLOGE("Invalid dst rect for GPU target layer"); 180 return kErrorParameters; 181 } 182 183 float layer_mixer_width = FLOAT(mixer_attributes_.width); 184 float layer_mixer_height = FLOAT(mixer_attributes_.height); 185 float fb_width = FLOAT(fb_config_.x_pixels); 186 float fb_height = FLOAT(fb_config_.y_pixels); 187 LayerRect src_domain = (LayerRect){0.0f, 0.0f, fb_width, fb_height}; 188 LayerRect dst_domain = (LayerRect){0.0f, 0.0f, layer_mixer_width, layer_mixer_height}; 189 LayerRect out_rect = gpu_target_layer->dst_rect; 190 191 MapRect(src_domain, dst_domain, gpu_target_layer->dst_rect, &out_rect); 192 193 auto gpu_target_layer_dst_xpixels = out_rect.right - out_rect.left; 194 auto gpu_target_layer_dst_ypixels = out_rect.bottom - out_rect.top; 195 196 if (gpu_target_layer_dst_xpixels > mixer_attributes_.width || 197 gpu_target_layer_dst_ypixels > mixer_attributes_.height) { 198 DLOGE("GPU target layer dst rect is not with in limits gpu wxh %fx%f, mixer wxh %dx%d", 199 gpu_target_layer_dst_xpixels, gpu_target_layer_dst_ypixels, 200 mixer_attributes_.width, mixer_attributes_.height); 201 return kErrorParameters; 202 } 203 204 return kErrorNone; 205 } 206 207 DisplayError DisplayBase::Prepare(LayerStack *layer_stack) { 208 lock_guard<recursive_mutex> obj(recursive_mutex_); 209 DisplayError error = kErrorNone; 210 211 if (!active_) { 212 return kErrorPermission; 213 } 214 215 if (!layer_stack) { 216 return kErrorParameters; 217 } 218 219 error = BuildLayerStackStats(layer_stack); 220 if (error != kErrorNone) { 221 return error; 222 } 223 224 if (color_mgr_ && color_mgr_->NeedsPartialUpdateDisable()) { 225 DisablePartialUpdateOneFrame(); 226 } 227 228 if (partial_update_control_ == false || disable_pu_one_frame_) { 229 comp_manager_->ControlPartialUpdate(display_comp_ctx_, false /* enable */); 230 disable_pu_one_frame_ = false; 231 } 232 233 comp_manager_->PrePrepare(display_comp_ctx_, &hw_layers_); 234 while (true) { 235 error = comp_manager_->Prepare(display_comp_ctx_, &hw_layers_); 236 if (error != kErrorNone) { 237 break; 238 } 239 240 if (IsRotationRequired(&hw_layers_)) { 241 if (!rotator_intf_) { 242 continue; 243 } 244 error = rotator_intf_->Prepare(display_rotator_ctx_, &hw_layers_); 245 } else { 246 // Release all the previous rotator sessions. 247 if (rotator_intf_) { 248 error = rotator_intf_->Purge(display_rotator_ctx_); 249 } 250 } 251 252 if (error == kErrorNone) { 253 error = hw_intf_->Validate(&hw_layers_); 254 if (error == kErrorNone) { 255 // Strategy is successful now, wait for Commit(). 256 pending_commit_ = true; 257 break; 258 } 259 if (error == kErrorShutDown) { 260 comp_manager_->PostPrepare(display_comp_ctx_, &hw_layers_); 261 return error; 262 } 263 } 264 } 265 266 comp_manager_->PostPrepare(display_comp_ctx_, &hw_layers_); 267 268 return error; 269 } 270 271 DisplayError DisplayBase::Commit(LayerStack *layer_stack) { 272 lock_guard<recursive_mutex> obj(recursive_mutex_); 273 DisplayError error = kErrorNone; 274 275 if (!active_) { 276 pending_commit_ = false; 277 return kErrorPermission; 278 } 279 280 if (!layer_stack) { 281 return kErrorParameters; 282 } 283 284 if (!pending_commit_) { 285 DLOGE("Commit: Corresponding Prepare() is not called for display = %d", display_type_); 286 return kErrorUndefined; 287 } 288 289 pending_commit_ = false; 290 291 // Layer stack attributes has changed, need to Reconfigure, currently in use for Hybrid Comp 292 if (layer_stack->flags.attributes_changed) { 293 error = comp_manager_->ReConfigure(display_comp_ctx_, &hw_layers_); 294 if (error != kErrorNone) { 295 return error; 296 } 297 298 error = hw_intf_->Validate(&hw_layers_); 299 if (error != kErrorNone) { 300 return error; 301 } 302 } 303 304 if (rotator_intf_ && IsRotationRequired(&hw_layers_)) { 305 error = rotator_intf_->Commit(display_rotator_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 if (rotator_intf_ && IsRotationRequired(&hw_layers_)) { 325 error = rotator_intf_->PostCommit(display_rotator_ctx_, &hw_layers_); 326 if (error != kErrorNone) { 327 return error; 328 } 329 } 330 331 if (partial_update_control_) { 332 comp_manager_->ControlPartialUpdate(display_comp_ctx_, true /* enable */); 333 } 334 335 error = comp_manager_->PostCommit(display_comp_ctx_, &hw_layers_); 336 if (error != kErrorNone) { 337 return error; 338 } 339 340 return kErrorNone; 341 } 342 343 DisplayError DisplayBase::Flush() { 344 lock_guard<recursive_mutex> obj(recursive_mutex_); 345 DisplayError error = kErrorNone; 346 347 if (!active_) { 348 return kErrorPermission; 349 } 350 351 hw_layers_.info.count = 0; 352 error = hw_intf_->Flush(); 353 if (error == kErrorNone) { 354 // Release all the rotator sessions. 355 if (rotator_intf_) { 356 error = rotator_intf_->Purge(display_rotator_ctx_); 357 if (error != kErrorNone) { 358 DLOGE("Rotator purge failed for display %d", display_type_); 359 return error; 360 } 361 } 362 363 comp_manager_->Purge(display_comp_ctx_); 364 365 pending_commit_ = false; 366 } else { 367 DLOGW("Unable to flush display = %d", display_type_); 368 } 369 370 return error; 371 } 372 373 DisplayError DisplayBase::GetDisplayState(DisplayState *state) { 374 lock_guard<recursive_mutex> obj(recursive_mutex_); 375 if (!state) { 376 return kErrorParameters; 377 } 378 379 *state = state_; 380 return kErrorNone; 381 } 382 383 DisplayError DisplayBase::GetNumVariableInfoConfigs(uint32_t *count) { 384 lock_guard<recursive_mutex> obj(recursive_mutex_); 385 return hw_intf_->GetNumDisplayAttributes(count); 386 } 387 388 DisplayError DisplayBase::GetConfig(uint32_t index, DisplayConfigVariableInfo *variable_info) { 389 lock_guard<recursive_mutex> obj(recursive_mutex_); 390 HWDisplayAttributes attrib; 391 if (hw_intf_->GetDisplayAttributes(index, &attrib) == kErrorNone) { 392 *variable_info = attrib; 393 return kErrorNone; 394 } 395 396 return kErrorNotSupported; 397 } 398 399 DisplayError DisplayBase::GetActiveConfig(uint32_t *index) { 400 lock_guard<recursive_mutex> obj(recursive_mutex_); 401 return hw_intf_->GetActiveConfig(index); 402 } 403 404 DisplayError DisplayBase::GetVSyncState(bool *enabled) { 405 lock_guard<recursive_mutex> obj(recursive_mutex_); 406 if (!enabled) { 407 return kErrorParameters; 408 } 409 410 *enabled = vsync_enable_; 411 412 return kErrorNone; 413 } 414 415 DisplayError DisplayBase::SetDisplayState(DisplayState state) { 416 lock_guard<recursive_mutex> obj(recursive_mutex_); 417 DisplayError error = kErrorNone; 418 bool active = false; 419 420 DLOGI("Set state = %d, display %d", state, display_type_); 421 422 if (state == state_) { 423 DLOGI("Same state transition is requested."); 424 return kErrorNone; 425 } 426 427 switch (state) { 428 case kStateOff: 429 hw_layers_.info.count = 0; 430 error = hw_intf_->Flush(); 431 if (error == kErrorNone) { 432 // Release all the rotator sessions. 433 if (rotator_intf_) { 434 error = rotator_intf_->Purge(display_rotator_ctx_); 435 if (error != kErrorNone) { 436 DLOGE("Rotator purge failed for display %d", display_type_); 437 return error; 438 } 439 } 440 441 comp_manager_->Purge(display_comp_ctx_); 442 443 error = hw_intf_->PowerOff(); 444 } 445 break; 446 447 case kStateOn: 448 error = hw_intf_->PowerOn(); 449 active = true; 450 break; 451 452 case kStateDoze: 453 error = hw_intf_->Doze(); 454 active = true; 455 break; 456 457 case kStateDozeSuspend: 458 error = hw_intf_->DozeSuspend(); 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 } 474 475 return error; 476 } 477 478 DisplayError DisplayBase::SetActiveConfig(uint32_t index) { 479 lock_guard<recursive_mutex> obj(recursive_mutex_); 480 DisplayError error = kErrorNone; 481 uint32_t active_index = 0; 482 483 hw_intf_->GetActiveConfig(&active_index); 484 485 if (active_index == index) { 486 return kErrorNone; 487 } 488 489 error = hw_intf_->SetDisplayAttributes(index); 490 if (error != kErrorNone) { 491 return error; 492 } 493 494 return ReconfigureDisplay(); 495 } 496 497 DisplayError DisplayBase::SetMaxMixerStages(uint32_t max_mixer_stages) { 498 lock_guard<recursive_mutex> obj(recursive_mutex_); 499 DisplayError error = kErrorNone; 500 501 error = comp_manager_->SetMaxMixerStages(display_comp_ctx_, max_mixer_stages); 502 503 if (error == kErrorNone) { 504 max_mixer_stages_ = max_mixer_stages; 505 } 506 507 return error; 508 } 509 510 void DisplayBase::AppendDump(char *buffer, uint32_t length) { 511 lock_guard<recursive_mutex> obj(recursive_mutex_); 512 HWDisplayAttributes attrib; 513 uint32_t active_index = 0; 514 uint32_t num_modes = 0; 515 hw_intf_->GetNumDisplayAttributes(&num_modes); 516 hw_intf_->GetActiveConfig(&active_index); 517 hw_intf_->GetDisplayAttributes(active_index, &attrib); 518 519 DumpImpl::AppendString(buffer, length, "\n-----------------------"); 520 DumpImpl::AppendString(buffer, length, "\ndevice type: %u", display_type_); 521 DumpImpl::AppendString(buffer, length, "\nstate: %u, vsync on: %u, max. mixer stages: %u", 522 state_, INT(vsync_enable_), max_mixer_stages_); 523 DumpImpl::AppendString(buffer, length, "\nnum configs: %u, active config index: %u", 524 num_modes, active_index); 525 526 DisplayConfigVariableInfo &info = attrib; 527 528 uint32_t num_hw_layers = 0; 529 if (hw_layers_.info.stack) { 530 num_hw_layers = hw_layers_.info.count; 531 } 532 533 if (num_hw_layers == 0) { 534 DumpImpl::AppendString(buffer, length, "\nNo hardware layers programmed"); 535 return; 536 } 537 538 LayerBuffer *out_buffer = hw_layers_.info.stack->output_buffer; 539 if (out_buffer) { 540 DumpImpl::AppendString(buffer, length, "\nres:%u x %u format: %s", out_buffer->width, 541 out_buffer->height, GetFormatString(out_buffer->format)); 542 } else { 543 DumpImpl::AppendString(buffer, length, "\nres:%u x %u, dpi:%.2f x %.2f, fps:%u," 544 "vsync period: %u", info.x_pixels, info.y_pixels, info.x_dpi, 545 info.y_dpi, info.fps, info.vsync_period_ns); 546 } 547 548 DumpImpl::AppendString(buffer, length, "\n"); 549 550 HWLayersInfo &layer_info = hw_layers_.info; 551 LayerRect &l_roi = layer_info.left_partial_update; 552 LayerRect &r_roi = layer_info.right_partial_update; 553 DumpImpl::AppendString(buffer, length, "\nROI(L T R B) : LEFT(%d %d %d %d)", INT(l_roi.left), 554 INT(l_roi.top), INT(l_roi.right), INT(l_roi.bottom)); 555 556 if (IsValid(r_roi)) { 557 DumpImpl::AppendString(buffer, length, ", RIGHT(%d %d %d %d)", INT(r_roi.left), 558 INT(r_roi.top), INT(r_roi.right), INT(r_roi.bottom)); 559 } 560 561 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 |"; //NOLINT 562 const char *newline = "\n|-----|-------------|--------|----|-------|-------------|--------------------------|---------------------|---------------------|----|------------|-----------|----|"; //NOLINT 563 const char *format = "\n| %3s | %11s " "| %6s " "| %2s | 0x%03x | %4d x %4d | %24s " "| %4d %4d %4d %4d " "| %4d %4d %4d %4d " "| %2s | %10s " "| %9s | %2s |"; //NOLINT 564 565 DumpImpl::AppendString(buffer, length, "\n"); 566 DumpImpl::AppendString(buffer, length, newline); 567 DumpImpl::AppendString(buffer, length, header); 568 DumpImpl::AppendString(buffer, length, newline); 569 570 for (uint32_t i = 0; i < num_hw_layers; i++) { 571 uint32_t layer_index = hw_layers_.info.index[i]; 572 Layer *layer = hw_layers_.info.stack->layers.at(layer_index); 573 LayerBuffer *input_buffer = layer->input_buffer; 574 HWLayerConfig &layer_config = hw_layers_.config[i]; 575 HWRotatorSession &hw_rotator_session = layer_config.hw_rotator_session; 576 577 char idx[8] = { 0 }; 578 const char *comp_type = GetName(layer->composition); 579 const char *buffer_format = GetFormatString(input_buffer->format); 580 const char *rotate_split[2] = { "Rot-1", "Rot-2" }; 581 const char *comp_split[2] = { "Comp-1", "Comp-2" }; 582 583 snprintf(idx, sizeof(idx), "%d", layer_index); 584 585 for (uint32_t count = 0; count < hw_rotator_session.hw_block_count; count++) { 586 char writeback_id[8] = { 0 }; 587 HWRotateInfo &rotate = hw_rotator_session.hw_rotate_info[count]; 588 LayerRect &src_roi = rotate.src_roi; 589 LayerRect &dst_roi = rotate.dst_roi; 590 591 snprintf(writeback_id, sizeof(writeback_id), "%d", rotate.writeback_id); 592 593 DumpImpl::AppendString(buffer, length, format, idx, comp_type, rotate_split[count], 594 writeback_id, rotate.pipe_id, input_buffer->width, 595 input_buffer->height, buffer_format, INT(src_roi.left), 596 INT(src_roi.top), INT(src_roi.right), INT(src_roi.bottom), 597 INT(dst_roi.left), INT(dst_roi.top), INT(dst_roi.right), 598 INT(dst_roi.bottom), "-", "- ", "- ", "-"); 599 600 // print the below only once per layer block, fill with spaces for rest. 601 idx[0] = 0; 602 comp_type = ""; 603 } 604 605 if (hw_rotator_session.hw_block_count > 0) { 606 input_buffer = &hw_rotator_session.output_buffer; 607 buffer_format = GetFormatString(input_buffer->format); 608 } 609 610 for (uint32_t count = 0; count < 2; count++) { 611 char decimation[16] = { 0 }; 612 char flags[16] = { 0 }; 613 char z_order[8] = { 0 }; 614 char csc[8] = { 0 }; 615 616 HWPipeInfo &pipe = (count == 0) ? layer_config.left_pipe : layer_config.right_pipe; 617 618 if (!pipe.valid) { 619 continue; 620 } 621 622 LayerRect &src_roi = pipe.src_roi; 623 LayerRect &dst_roi = pipe.dst_roi; 624 625 snprintf(z_order, sizeof(z_order), "%d", pipe.z_order); 626 snprintf(flags, sizeof(flags), "0x%08x", layer->flags.flags); 627 snprintf(decimation, sizeof(decimation), "%3d x %3d", pipe.horizontal_decimation, 628 pipe.vertical_decimation); 629 snprintf(csc, sizeof(csc), "%d", layer->input_buffer->csc); 630 631 DumpImpl::AppendString(buffer, length, format, idx, comp_type, comp_split[count], 632 "-", pipe.pipe_id, input_buffer->width, input_buffer->height, 633 buffer_format, INT(src_roi.left), INT(src_roi.top), 634 INT(src_roi.right), INT(src_roi.bottom), INT(dst_roi.left), 635 INT(dst_roi.top), INT(dst_roi.right), INT(dst_roi.bottom), 636 z_order, flags, decimation, csc); 637 638 // print the below only once per layer block, fill with spaces for rest. 639 idx[0] = 0; 640 comp_type = ""; 641 } 642 643 DumpImpl::AppendString(buffer, length, newline); 644 } 645 } 646 647 bool DisplayBase::IsRotationRequired(HWLayers *hw_layers) { 648 lock_guard<recursive_mutex> obj(recursive_mutex_); 649 HWLayersInfo &layer_info = hw_layers->info; 650 651 for (uint32_t i = 0; i < layer_info.count; i++) { 652 HWRotatorSession *hw_rotator_session = &hw_layers->config[i].hw_rotator_session; 653 654 if (hw_rotator_session->hw_block_count) { 655 return true; 656 } 657 } 658 659 return false; 660 } 661 662 const char * DisplayBase::GetName(const LayerComposition &composition) { 663 switch (composition) { 664 case kCompositionGPU: return "GPU"; 665 case kCompositionSDE: return "SDE"; 666 case kCompositionHWCursor: return "CURSOR"; 667 case kCompositionHybrid: return "HYBRID"; 668 case kCompositionBlit: return "BLIT"; 669 case kCompositionGPUTarget: return "GPU_TARGET"; 670 case kCompositionBlitTarget: return "BLIT_TARGET"; 671 default: return "UNKNOWN"; 672 } 673 } 674 675 DisplayError DisplayBase::ColorSVCRequestRoute(const PPDisplayAPIPayload &in_payload, 676 PPDisplayAPIPayload *out_payload, 677 PPPendingParams *pending_action) { 678 lock_guard<recursive_mutex> obj(recursive_mutex_); 679 if (color_mgr_) 680 return color_mgr_->ColorSVCRequestRoute(in_payload, out_payload, pending_action); 681 else 682 return kErrorParameters; 683 } 684 685 DisplayError DisplayBase::GetColorModeCount(uint32_t *mode_count) { 686 lock_guard<recursive_mutex> obj(recursive_mutex_); 687 if (!mode_count) { 688 return kErrorParameters; 689 } 690 691 if (!color_mgr_) { 692 return kErrorNotSupported; 693 } 694 695 DisplayError error = color_mgr_->ColorMgrGetNumOfModes(&num_color_modes_); 696 if (error != kErrorNone || !num_color_modes_) { 697 return kErrorNotSupported; 698 } 699 700 DLOGV_IF(kTagQDCM, "Number of modes from color manager = %d", num_color_modes_); 701 *mode_count = num_color_modes_; 702 703 return kErrorNone; 704 } 705 706 DisplayError DisplayBase::GetColorModes(uint32_t *mode_count, 707 std::vector<std::string> *color_modes) { 708 lock_guard<recursive_mutex> obj(recursive_mutex_); 709 if (!mode_count || !color_modes) { 710 return kErrorParameters; 711 } 712 713 if (!color_mgr_) { 714 return kErrorNotSupported; 715 } 716 717 if (!color_modes_.size()) { 718 color_modes_.resize(num_color_modes_); 719 720 DisplayError error = color_mgr_->ColorMgrGetModes(&num_color_modes_, color_modes_.data()); 721 if (error != kErrorNone) { 722 DLOGE("Failed"); 723 return error; 724 } 725 726 for (uint32_t i = 0; i < num_color_modes_; i++) { 727 DLOGV_IF(kTagQDCM, "Color Mode[%d]: Name = %s mode_id = %d", i, color_modes_[i].name, 728 color_modes_[i].id); 729 auto it = color_mode_map_.find(color_modes_[i].name); 730 if (it != color_mode_map_.end()) { 731 if (it->second->id < color_modes_[i].id) { 732 color_mode_map_.erase(it); 733 color_mode_map_.insert(std::make_pair(color_modes_[i].name, &color_modes_[i])); 734 } 735 } else { 736 color_mode_map_.insert(std::make_pair(color_modes_[i].name, &color_modes_[i])); 737 } 738 } 739 } 740 741 for (uint32_t i = 0; i < num_color_modes_; i++) { 742 DLOGV_IF(kTagQDCM, "Color Mode[%d]: Name = %s mode_id = %d", i, color_modes_[i].name, 743 color_modes_[i].id); 744 color_modes->at(i) = color_modes_[i].name; 745 } 746 747 return kErrorNone; 748 } 749 750 DisplayError DisplayBase::SetColorMode(const std::string &color_mode) { 751 lock_guard<recursive_mutex> obj(recursive_mutex_); 752 if (!color_mgr_) { 753 return kErrorNotSupported; 754 } 755 756 DLOGV_IF(kTagQDCM, "Color Mode = %s", color_mode.c_str()); 757 758 ColorModeMap::iterator it = color_mode_map_.find(color_mode); 759 if (it == color_mode_map_.end()) { 760 DLOGE("Failed: Unknown Mode : %s", color_mode.c_str()); 761 return kErrorNotSupported; 762 } 763 764 SDEDisplayMode *sde_display_mode = it->second; 765 766 DLOGD("Color Mode Name = %s corresponding mode_id = %d", sde_display_mode->name, 767 sde_display_mode->id); 768 DisplayError error = kErrorNone; 769 error = color_mgr_->ColorMgrSetMode(sde_display_mode->id); 770 if (error != kErrorNone) { 771 DLOGE("Failed for mode id = %d", sde_display_mode->id); 772 return error; 773 } 774 775 return error; 776 } 777 778 DisplayError DisplayBase::SetColorTransform(const uint32_t length, const double *color_transform) { 779 lock_guard<recursive_mutex> obj(recursive_mutex_); 780 if (!color_mgr_) { 781 return kErrorNotSupported; 782 } 783 784 if (!color_transform) { 785 return kErrorParameters; 786 } 787 788 return color_mgr_->ColorMgrSetColorTransform(length, color_transform); 789 } 790 791 DisplayError DisplayBase::ApplyDefaultDisplayMode() { 792 lock_guard<recursive_mutex> obj(recursive_mutex_); 793 if (color_mgr_) 794 return color_mgr_->ApplyDefaultDisplayMode(); 795 else 796 return kErrorParameters; 797 } 798 799 DisplayError DisplayBase::SetCursorPosition(int x, int y) { 800 lock_guard<recursive_mutex> obj(recursive_mutex_); 801 if (state_ != kStateOn) { 802 return kErrorNotSupported; 803 } 804 805 DisplayError error = comp_manager_->ValidateCursorPosition(display_comp_ctx_, &hw_layers_, x, y); 806 if (error == kErrorNone) { 807 return hw_intf_->SetCursorPosition(&hw_layers_, x, y); 808 } 809 810 return kErrorNone; 811 } 812 813 DisplayError DisplayBase::GetRefreshRateRange(uint32_t *min_refresh_rate, 814 uint32_t *max_refresh_rate) { 815 lock_guard<recursive_mutex> obj(recursive_mutex_); 816 // The min and max refresh rates will be same when the HWPanelInfo does not contain valid rates. 817 // Usually for secondary displays, command mode panels 818 HWDisplayAttributes display_attributes; 819 uint32_t active_index = 0; 820 hw_intf_->GetActiveConfig(&active_index); 821 DisplayError error = hw_intf_->GetDisplayAttributes(active_index, &display_attributes); 822 if (error) { 823 return error; 824 } 825 826 *min_refresh_rate = display_attributes.fps; 827 *max_refresh_rate = display_attributes.fps; 828 829 return error; 830 } 831 832 DisplayError DisplayBase::SetVSyncState(bool enable) { 833 lock_guard<recursive_mutex> obj(recursive_mutex_); 834 DisplayError error = kErrorNone; 835 if (vsync_enable_ != enable) { 836 error = hw_intf_->SetVSyncState(enable); 837 if (error == kErrorNone) { 838 vsync_enable_ = enable; 839 } 840 } 841 return error; 842 } 843 844 DisplayError DisplayBase::ReconfigureDisplay() { 845 lock_guard<recursive_mutex> obj(recursive_mutex_); 846 DisplayError error = kErrorNone; 847 HWDisplayAttributes display_attributes; 848 HWMixerAttributes mixer_attributes; 849 HWPanelInfo hw_panel_info; 850 uint32_t active_index = 0; 851 852 error = hw_intf_->GetActiveConfig(&active_index); 853 if (error != kErrorNone) { 854 return error; 855 } 856 857 error = hw_intf_->GetDisplayAttributes(active_index, &display_attributes); 858 if (error != kErrorNone) { 859 return error; 860 } 861 862 error = hw_intf_->GetMixerAttributes(&mixer_attributes); 863 if (error != kErrorNone) { 864 return error; 865 } 866 867 error = hw_intf_->GetHWPanelInfo(&hw_panel_info); 868 if (error != kErrorNone) { 869 return error; 870 } 871 872 if (display_attributes == display_attributes_ && mixer_attributes == mixer_attributes_ && 873 hw_panel_info == hw_panel_info_) { 874 return kErrorNone; 875 } 876 877 error = comp_manager_->ReconfigureDisplay(display_comp_ctx_, display_attributes, hw_panel_info, 878 mixer_attributes, fb_config_); 879 if (error != kErrorNone) { 880 return error; 881 } 882 883 if (mixer_attributes != mixer_attributes_) { 884 DisablePartialUpdateOneFrame(); 885 } 886 887 display_attributes_ = display_attributes; 888 mixer_attributes_ = mixer_attributes; 889 hw_panel_info_ = hw_panel_info; 890 891 return kErrorNone; 892 } 893 894 DisplayError DisplayBase::SetMixerResolution(uint32_t width, uint32_t height) { 895 lock_guard<recursive_mutex> obj(recursive_mutex_); 896 return ReconfigureMixer(width, height); 897 } 898 899 DisplayError DisplayBase::GetMixerResolution(uint32_t *width, uint32_t *height) { 900 lock_guard<recursive_mutex> obj(recursive_mutex_); 901 if (!width || !height) { 902 return kErrorParameters; 903 } 904 905 *width = mixer_attributes_.width; 906 *height = mixer_attributes_.height; 907 908 return kErrorNone; 909 } 910 911 DisplayError DisplayBase::ReconfigureMixer(uint32_t width, uint32_t height) { 912 lock_guard<recursive_mutex> obj(recursive_mutex_); 913 DisplayError error = kErrorNone; 914 915 HWMixerAttributes mixer_attributes; 916 mixer_attributes.width = width; 917 mixer_attributes.height = height; 918 919 error = hw_intf_->SetMixerAttributes(mixer_attributes); 920 if (error != kErrorNone) { 921 return error; 922 } 923 924 return ReconfigureDisplay(); 925 } 926 927 bool DisplayBase::NeedsMixerReconfiguration(LayerStack *layer_stack, uint32_t *new_mixer_width, 928 uint32_t *new_mixer_height) { 929 lock_guard<recursive_mutex> obj(recursive_mutex_); 930 uint32_t layer_count = UINT32(layer_stack->layers.size()); 931 932 uint32_t fb_width = fb_config_.x_pixels; 933 uint32_t fb_height = fb_config_.y_pixels; 934 uint32_t fb_area = fb_width * fb_height; 935 LayerRect fb_rect = (LayerRect) {0.0f, 0.0f, FLOAT(fb_width), FLOAT(fb_height)}; 936 uint32_t mixer_width = mixer_attributes_.width; 937 uint32_t mixer_height = mixer_attributes_.height; 938 939 RectOrientation fb_orientation = GetOrientation(fb_rect); 940 uint32_t max_layer_area = 0; 941 uint32_t max_area_layer_index = 0; 942 std::vector<Layer *> layers = layer_stack->layers; 943 944 for (uint32_t i = 0; i < layer_count; i++) { 945 Layer *layer = layers.at(i); 946 LayerBuffer *layer_buffer = layer->input_buffer; 947 948 if (!layer_buffer->flags.video) { 949 continue; 950 } 951 952 uint32_t layer_width = UINT32(layer->src_rect.right - layer->src_rect.left); 953 uint32_t layer_height = UINT32(layer->src_rect.bottom - layer->src_rect.top); 954 uint32_t layer_area = layer_width * layer_height; 955 956 if (layer_area > max_layer_area) { 957 max_layer_area = layer_area; 958 max_area_layer_index = i; 959 } 960 } 961 962 if (max_layer_area > fb_area) { 963 Layer *layer = layers.at(max_area_layer_index); 964 965 uint32_t layer_width = UINT32(layer->src_rect.right - layer->src_rect.left); 966 uint32_t layer_height = UINT32(layer->src_rect.bottom - layer->src_rect.top); 967 LayerRect layer_rect = (LayerRect){0.0f, 0.0f, FLOAT(layer_width), FLOAT(layer_height)}; 968 969 RectOrientation layer_orientation = GetOrientation(layer_rect); 970 if (layer_orientation != kOrientationUnknown && 971 fb_orientation != kOrientationUnknown) { 972 if (layer_orientation != fb_orientation) { 973 std::swap(layer_width, layer_height); 974 } 975 } 976 977 // Align the width and height according to fb's aspect ratio 978 layer_width = UINT32((FLOAT(fb_width) / FLOAT(fb_height)) * layer_height); 979 980 *new_mixer_width = layer_width; 981 *new_mixer_height = layer_height; 982 983 return true; 984 } else { 985 if (fb_width != mixer_width || fb_height != mixer_height) { 986 *new_mixer_width = fb_width; 987 *new_mixer_height = fb_height; 988 989 return true; 990 } 991 } 992 993 return false; 994 } 995 996 DisplayError DisplayBase::SetFrameBufferConfig(const DisplayConfigVariableInfo &variable_info) { 997 lock_guard<recursive_mutex> obj(recursive_mutex_); 998 uint32_t width = variable_info.x_pixels; 999 uint32_t height = variable_info.y_pixels; 1000 1001 if (width == 0 || height == 0) { 1002 DLOGE("Unsupported resolution: (%dx%d)", width, height); 1003 return kErrorParameters; 1004 } 1005 1006 // Create rects to represent the new source and destination crops 1007 LayerRect crop = LayerRect(0, 0, FLOAT(width), FLOAT(height)); 1008 LayerRect dst = LayerRect(0, 0, FLOAT(mixer_attributes_.width), FLOAT(mixer_attributes_.height)); 1009 // Set rotate90 to false since this is taken care of during regular composition. 1010 bool rotate90 = false; 1011 1012 DisplayError error = comp_manager_->ValidateScaling(crop, dst, rotate90); 1013 if (error != kErrorNone) { 1014 DLOGE("Unsupported resolution: (%dx%d)", width, height); 1015 return kErrorParameters; 1016 } 1017 1018 error = comp_manager_->ReconfigureDisplay(display_comp_ctx_, display_attributes_, hw_panel_info_, 1019 mixer_attributes_, variable_info); 1020 if (error != kErrorNone) { 1021 return error; 1022 } 1023 1024 fb_config_.x_pixels = width; 1025 fb_config_.y_pixels = height; 1026 1027 DLOGI("New framebuffer resolution (%dx%d)", fb_config_.x_pixels, fb_config_.y_pixels); 1028 1029 return kErrorNone; 1030 } 1031 1032 DisplayError DisplayBase::GetFrameBufferConfig(DisplayConfigVariableInfo *variable_info) { 1033 lock_guard<recursive_mutex> obj(recursive_mutex_); 1034 if (!variable_info) { 1035 return kErrorParameters; 1036 } 1037 1038 *variable_info = fb_config_; 1039 1040 return kErrorNone; 1041 } 1042 1043 DisplayError DisplayBase::SetDetailEnhancerData(const DisplayDetailEnhancerData &de_data) { 1044 lock_guard<recursive_mutex> obj(recursive_mutex_); 1045 DisplayError error = comp_manager_->SetDetailEnhancerData(display_comp_ctx_, de_data); 1046 if (error != kErrorNone) { 1047 return error; 1048 } 1049 1050 DisablePartialUpdateOneFrame(); 1051 1052 return kErrorNone; 1053 } 1054 1055 DisplayError DisplayBase::GetDisplayPort(DisplayPort *port) { 1056 lock_guard<recursive_mutex> obj(recursive_mutex_); 1057 1058 if (!port) { 1059 return kErrorParameters; 1060 } 1061 1062 *port = hw_panel_info_.port; 1063 1064 return kErrorNone; 1065 } 1066 1067 bool DisplayBase::IsPrimaryDisplay() { 1068 lock_guard<recursive_mutex> obj(recursive_mutex_); 1069 1070 return hw_panel_info_.is_primary_panel; 1071 } 1072 1073 } // namespace sdm 1074