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