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 5* modification, are permitted provided that the following conditions are 6* met: 7* * Redistributions of source code must retain the above copyright 8* notice, this list of conditions and the following disclaimer. 9* * Redistributions in binary form must reproduce the above 10* copyright notice, this list of conditions and the following 11* disclaimer in the documentation and/or other materials provided 12* with the distribution. 13* * Neither the name of The Linux Foundation nor the names of its 14* contributors may be used to endorse or promote products derived 15* from this software without specific prior written permission. 16* 17* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED 18* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 19* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 20* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS 21* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 24* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 25* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 26* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 27* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28*/ 29 30#include <math.h> 31#include <errno.h> 32#include <gralloc_priv.h> 33#include <gr.h> 34#include <utils/constants.h> 35#include <utils/formats.h> 36#include <utils/rect.h> 37#include <utils/debug.h> 38#include <sys/types.h> 39#include <sys/stat.h> 40#include <sync/sync.h> 41#include <cutils/properties.h> 42#include <qd_utils.h> 43#include <map> 44#include <utility> 45#include <vector> 46#include <string> 47 48#include "blit_engine_c2d.h" 49#include "hwc_debugger.h" 50#include "hwc_display.h" 51#include "hwc_tonemapper.h" 52 53#ifdef QTI_BSP 54#include <hardware/display_defs.h> 55#endif 56 57#define __CLASS__ "HWCDisplay" 58 59namespace sdm { 60 61void HWCColorMode::Init() { 62 int ret = PopulateColorModes(); 63 if (ret != 0) { 64 DLOGW("Failed!!"); 65 } 66 return; 67} 68 69int HWCColorMode::SetColorMode(const std::string &color_mode) { 70 if (color_modes_.empty()) { 71 DLOGW("No Color Modes supported"); 72 return -1; 73 } 74 75 std::vector<std::string>::iterator it = std::find(color_modes_.begin(), color_modes_.end(), 76 color_mode); 77 if (it == color_modes_.end()) { 78 DLOGE("Invalid colorMode request: %s", color_mode.c_str()); 79 return -1; 80 } 81 82 DisplayError error = display_intf_->SetColorMode(color_mode); 83 if (error != kErrorNone) { 84 DLOGE("Failed to set color_mode = %s", color_mode.c_str()); 85 return -1; 86 } 87 current_color_mode_ = color_mode; 88 89 return 0; 90} 91 92const std::vector<std::string> &HWCColorMode::GetColorModes() { 93 return color_modes_; 94} 95 96int HWCColorMode::SetColorTransform(uint32_t matrix_count, const float *matrix) { 97 if (matrix_count > kColorTransformMatrixCount) { 98 DLOGE("Transform matrix count = %d, exceeds max = %d", matrix_count, 99 kColorTransformMatrixCount); 100 return -1; 101 } 102 103 double color_matrix[kColorTransformMatrixCount] = {0}; 104 CopyColorTransformMatrix(matrix, color_matrix); 105 DisplayError error = display_intf_->SetColorTransform(matrix_count, color_matrix); 106 if (error != kErrorNone) { 107 DLOGE("Failed!"); 108 return -1; 109 } 110 111 return 0; 112} 113 114int HWCColorMode::PopulateColorModes() { 115 uint32_t color_mode_count = 0; 116 DisplayError error = display_intf_->GetColorModeCount(&color_mode_count); 117 if (error != kErrorNone || (color_mode_count == 0)) { 118 return -1; 119 } 120 121 DLOGI("Color Mode count = %d", color_mode_count); 122 123 color_modes_.resize(color_mode_count); 124 125 // SDM returns modes which is string 126 error = display_intf_->GetColorModes(&color_mode_count, &color_modes_); 127 if (error != kErrorNone) { 128 DLOGE("GetColorModes Failed for count = %d", color_mode_count); 129 return -1; 130 } 131 132 return 0; 133} 134 135HWCDisplay::HWCDisplay(CoreInterface *core_intf, hwc_procs_t const **hwc_procs, DisplayType type, 136 int id, bool needs_blit, qService::QService *qservice, 137 DisplayClass display_class) 138 : core_intf_(core_intf), hwc_procs_(hwc_procs), type_(type), id_(id), needs_blit_(needs_blit), 139 qservice_(qservice), display_class_(display_class) { 140} 141 142int HWCDisplay::Init() { 143 DisplayError error = core_intf_->CreateDisplay(type_, this, &display_intf_); 144 if (error != kErrorNone) { 145 DLOGE("Display create failed. Error = %d display_type %d event_handler %p disp_intf %p", 146 error, type_, this, &display_intf_); 147 return -EINVAL; 148 } 149 150 HWCDebugHandler::Get()->GetProperty("sys.hwc_disable_hdr", &disable_hdr_handling_); 151 if (disable_hdr_handling_) { 152 DLOGI("HDR Handling disabled"); 153 } 154 155 int property_swap_interval = 1; 156 HWCDebugHandler::Get()->GetProperty("debug.egl.swapinterval", &property_swap_interval); 157 if (property_swap_interval == 0) { 158 swap_interval_zero_ = true; 159 } 160 161 int blit_enabled = 0; 162 HWCDebugHandler::Get()->GetProperty("persist.hwc.blit.comp", &blit_enabled); 163 if (needs_blit_ && blit_enabled) { 164 blit_engine_ = new BlitEngineC2d(); 165 if (!blit_engine_) { 166 DLOGI("Create Blit Engine C2D failed"); 167 } else { 168 if (blit_engine_->Init() < 0) { 169 DLOGI("Blit Engine Init failed, Blit Composition will not be used!!"); 170 delete blit_engine_; 171 blit_engine_ = NULL; 172 } 173 } 174 } 175 176 tone_mapper_ = new HWCToneMapper(); 177 178 display_intf_->GetRefreshRateRange(&min_refresh_rate_, &max_refresh_rate_); 179 current_refresh_rate_ = max_refresh_rate_; 180 181 s3d_format_hwc_to_sdm_.insert(std::pair<int, LayerBufferS3DFormat>(HAL_NO_3D, kS3dFormatNone)); 182 s3d_format_hwc_to_sdm_.insert(std::pair<int, LayerBufferS3DFormat>(HAL_3D_SIDE_BY_SIDE_L_R, 183 kS3dFormatLeftRight)); 184 s3d_format_hwc_to_sdm_.insert(std::pair<int, LayerBufferS3DFormat>(HAL_3D_SIDE_BY_SIDE_R_L, 185 kS3dFormatRightLeft)); 186 s3d_format_hwc_to_sdm_.insert(std::pair<int, LayerBufferS3DFormat>(HAL_3D_TOP_BOTTOM, 187 kS3dFormatTopBottom)); 188 189 disable_animation_ = Debug::IsExtAnimDisabled(); 190 191 return 0; 192} 193 194int HWCDisplay::Deinit() { 195 DisplayError error = core_intf_->DestroyDisplay(display_intf_); 196 if (error != kErrorNone) { 197 DLOGE("Display destroy failed. Error = %d", error); 198 return -EINVAL; 199 } 200 201 if (blit_engine_) { 202 blit_engine_->DeInit(); 203 delete blit_engine_; 204 blit_engine_ = NULL; 205 } 206 207 delete tone_mapper_; 208 tone_mapper_ = NULL; 209 210 return 0; 211} 212 213int HWCDisplay::EventControl(int event, int enable) { 214 DisplayError error = kErrorNone; 215 216 if (shutdown_pending_) { 217 return 0; 218 } 219 220 switch (event) { 221 case HWC_EVENT_VSYNC: 222 error = display_intf_->SetVSyncState(enable); 223 break; 224 default: 225 DLOGW("Unsupported event = %d", event); 226 } 227 228 if (error != kErrorNone) { 229 if (error == kErrorShutDown) { 230 shutdown_pending_ = true; 231 return 0; 232 } 233 DLOGE("Failed. event = %d, enable = %d, error = %d", event, enable, error); 234 return -EINVAL; 235 } 236 237 return 0; 238} 239 240int HWCDisplay::SetPowerMode(int mode) { 241 DLOGI("display = %d, mode = %d", id_, mode); 242 DisplayState state = kStateOff; 243 bool flush_on_error = flush_on_error_; 244 245 if (shutdown_pending_) { 246 return 0; 247 } 248 249 switch (mode) { 250 case HWC_POWER_MODE_OFF: 251 // During power off, all of the buffers are released. 252 // Do not flush until a buffer is successfully submitted again. 253 flush_on_error = false; 254 state = kStateOff; 255 tone_mapper_->Terminate(); 256 break; 257 258 case HWC_POWER_MODE_NORMAL: 259 state = kStateOn; 260 last_power_mode_ = HWC_POWER_MODE_NORMAL; 261 break; 262 263 case HWC_POWER_MODE_DOZE: 264 state = kStateDoze; 265 last_power_mode_ = HWC_POWER_MODE_DOZE; 266 break; 267 268 case HWC_POWER_MODE_DOZE_SUSPEND: 269 state = kStateDozeSuspend; 270 last_power_mode_ = HWC_POWER_MODE_DOZE_SUSPEND; 271 break; 272 273 default: 274 return -EINVAL; 275 } 276 277 DisplayError error = display_intf_->SetDisplayState(state); 278 if (error == kErrorNone) { 279 flush_on_error_ = flush_on_error; 280 } else { 281 if (error == kErrorShutDown) { 282 shutdown_pending_ = true; 283 return 0; 284 } 285 DLOGE("Set state failed. Error = %d", error); 286 return -EINVAL; 287 } 288 289 return 0; 290} 291 292int HWCDisplay::GetDisplayConfigs(uint32_t *configs, size_t *num_configs) { 293 if (*num_configs > 0) { 294 configs[0] = 0; 295 *num_configs = 1; 296 } 297 298 return 0; 299} 300 301int HWCDisplay::GetDisplayAttributes(uint32_t config, const uint32_t *display_attributes, 302 int32_t *values) { 303 DisplayConfigVariableInfo variable_config; 304 DisplayError error = display_intf_->GetFrameBufferConfig(&variable_config); 305 if (error != kErrorNone) { 306 DLOGV("Get variable config failed. Error = %d", error); 307 return -EINVAL; 308 } 309 310 for (int i = 0; display_attributes[i] != HWC_DISPLAY_NO_ATTRIBUTE; i++) { 311 switch (display_attributes[i]) { 312 case HWC_DISPLAY_VSYNC_PERIOD: 313 values[i] = INT32(variable_config.vsync_period_ns); 314 break; 315 case HWC_DISPLAY_WIDTH: 316 values[i] = INT32(variable_config.x_pixels); 317 break; 318 case HWC_DISPLAY_HEIGHT: 319 values[i] = INT32(variable_config.y_pixels); 320 break; 321 case HWC_DISPLAY_DPI_X: 322 values[i] = INT32(variable_config.x_dpi * 1000.0f); 323 break; 324 case HWC_DISPLAY_DPI_Y: 325 values[i] = INT32(variable_config.y_dpi * 1000.0f); 326 break; 327 default: 328 DLOGW("Spurious attribute type = %d", display_attributes[i]); 329 return -EINVAL; 330 } 331 } 332 333 return 0; 334} 335 336int HWCDisplay::GetActiveConfig() { 337 return 0; 338} 339 340int HWCDisplay::SetActiveConfig(int index) { 341 return -1; 342} 343 344DisplayError HWCDisplay::SetMixerResolution(uint32_t width, uint32_t height) { 345 return kErrorNotSupported; 346} 347 348void HWCDisplay::SetFrameDumpConfig(uint32_t count, uint32_t bit_mask_layer_type) { 349 dump_frame_count_ = count; 350 dump_frame_index_ = 0; 351 dump_input_layers_ = ((bit_mask_layer_type & (1 << INPUT_LAYER_DUMP)) != 0); 352 353 if (blit_engine_) { 354 blit_engine_->SetFrameDumpConfig(count); 355 } 356 357 if (tone_mapper_) { 358 tone_mapper_->SetFrameDumpConfig(count); 359 } 360 361 DLOGI("num_frame_dump %d, input_layer_dump_enable %d", dump_frame_count_, dump_input_layers_); 362} 363 364uint32_t HWCDisplay::GetLastPowerMode() { 365 return last_power_mode_; 366} 367 368DisplayError HWCDisplay::VSync(const DisplayEventVSync &vsync) { 369 const hwc_procs_t *hwc_procs = *hwc_procs_; 370 371 if (!hwc_procs) { 372 return kErrorParameters; 373 } 374 375 hwc_procs->vsync(hwc_procs, id_, vsync.timestamp); 376 377 return kErrorNone; 378} 379 380DisplayError HWCDisplay::Refresh() { 381 return kErrorNotSupported; 382} 383 384DisplayError HWCDisplay::CECMessage(char *message) { 385 if (qservice_) { 386 qservice_->onCECMessageReceived(message, 0); 387 } else { 388 DLOGW("Qservice instance not available."); 389 } 390 391 return kErrorNone; 392} 393 394int HWCDisplay::AllocateLayerStack(hwc_display_contents_1_t *content_list) { 395 if (!content_list || !content_list->numHwLayers) { 396 DLOGW("Invalid content list"); 397 return -EINVAL; 398 } 399 400 size_t num_hw_layers = content_list->numHwLayers; 401 uint32_t blit_target_count = 0; 402 403 if (blit_engine_) { 404 blit_target_count = kMaxBlitTargetLayers; 405 } 406 407 FreeLayerStack(); 408 409 for (size_t i = 0; i < num_hw_layers + blit_target_count; i++) { 410 Layer *layer = new Layer(); 411 layer_stack_.layers.push_back(layer); 412 } 413 414 return 0; 415} 416 417void HWCDisplay::FreeLayerStack() { 418 for (Layer *layer : layer_stack_.layers) { 419 delete layer; 420 } 421 layer_stack_ = {}; 422} 423 424int HWCDisplay::PrepareLayerParams(hwc_layer_1_t *hwc_layer, Layer* layer) { 425 const private_handle_t *pvt_handle = static_cast<const private_handle_t *>(hwc_layer->handle); 426 427 LayerBuffer &layer_buffer = layer->input_buffer; 428 429 if (pvt_handle) { 430 layer_buffer.planes[0].fd = pvt_handle->fd; 431 layer_buffer.format = GetSDMFormat(pvt_handle->format, pvt_handle->flags); 432 int aligned_width, aligned_height; 433 int unaligned_width, unaligned_height; 434 435 AdrenoMemInfo::getInstance().getAlignedWidthAndHeight(pvt_handle, aligned_width, 436 aligned_height); 437 AdrenoMemInfo::getInstance().getUnalignedWidthAndHeight(pvt_handle, unaligned_width, 438 unaligned_height); 439 440 layer_buffer.width = UINT32(aligned_width); 441 layer_buffer.height = UINT32(aligned_height); 442 layer_buffer.unaligned_width = UINT32(unaligned_width); 443 layer_buffer.unaligned_height = UINT32(unaligned_height); 444 445 if (SetMetaData(pvt_handle, layer) != kErrorNone) { 446 return -EINVAL; 447 } 448 449 if (pvt_handle->bufferType == BUFFER_TYPE_VIDEO) { 450 layer_stack_.flags.video_present = true; 451 layer_buffer.flags.video = true; 452 } 453 // TZ Protected Buffer - L1 454 if (pvt_handle->flags & private_handle_t::PRIV_FLAGS_SECURE_BUFFER) { 455 layer_stack_.flags.secure_present = true; 456 layer_buffer.flags.secure = true; 457 if (pvt_handle->flags & private_handle_t::PRIV_FLAGS_CAMERA_WRITE) { 458 layer_buffer.flags.secure_camera = true; 459 } 460 } 461 // Gralloc Usage Protected Buffer - L3 - which needs to be treated as Secure & avoid fallback 462 if (pvt_handle->flags & private_handle_t::PRIV_FLAGS_PROTECTED_BUFFER) { 463 layer_stack_.flags.secure_present = true; 464 } 465 if (pvt_handle->flags & private_handle_t::PRIV_FLAGS_SECURE_DISPLAY) { 466 layer_buffer.flags.secure_display = true; 467 } 468 469 // check if this is special solid_fill layer without input_buffer. 470 if (solid_fill_enable_ && pvt_handle->fd == -1) { 471 layer->flags.solid_fill = true; 472 layer->solid_fill_color = solid_fill_color_; 473 } 474 } else { 475 // for FBT layer 476 if (hwc_layer->compositionType == HWC_FRAMEBUFFER_TARGET) { 477 uint32_t x_pixels; 478 uint32_t y_pixels; 479 int aligned_width; 480 int aligned_height; 481 int usage = GRALLOC_USAGE_HW_FB; 482 int format = HAL_PIXEL_FORMAT_RGBA_8888; 483 int ubwc_enabled = 0; 484 int flags = 0; 485 HWCDebugHandler::Get()->GetProperty("debug.gralloc.enable_fb_ubwc", &ubwc_enabled); 486 bool linear = layer_stack_.output_buffer && !IsUBWCFormat(layer_stack_.output_buffer->format); 487 if ((ubwc_enabled == 1) && !linear) { 488 usage |= GRALLOC_USAGE_PRIVATE_ALLOC_UBWC; 489 flags |= private_handle_t::PRIV_FLAGS_UBWC_ALIGNED; 490 } 491 492 GetFrameBufferResolution(&x_pixels, &y_pixels); 493 494 AdrenoMemInfo::getInstance().getAlignedWidthAndHeight(INT(x_pixels), INT(y_pixels), format, 495 usage, aligned_width, aligned_height); 496 layer_buffer.width = UINT32(aligned_width); 497 layer_buffer.height = UINT32(aligned_height); 498 layer_buffer.unaligned_width = x_pixels; 499 layer_buffer.unaligned_height = y_pixels; 500 layer_buffer.format = GetSDMFormat(format, flags); 501 } 502 } 503 504 return 0; 505} 506 507void HWCDisplay::CommitLayerParams(hwc_layer_1_t *hwc_layer, Layer *layer) { 508 const private_handle_t *pvt_handle = static_cast<const private_handle_t *>(hwc_layer->handle); 509 LayerBuffer &layer_buffer = layer->input_buffer; 510 511 if (pvt_handle) { 512 layer_buffer.planes[0].fd = pvt_handle->fd; 513 layer_buffer.planes[0].offset = pvt_handle->offset; 514 layer_buffer.planes[0].stride = UINT32(pvt_handle->width); 515 layer_buffer.size = pvt_handle->size; 516 } 517 518 // if swapinterval property is set to 0 then close and reset the acquireFd 519 if (swap_interval_zero_ && hwc_layer->acquireFenceFd >= 0) { 520 close(hwc_layer->acquireFenceFd); 521 hwc_layer->acquireFenceFd = -1; 522 } 523 layer_buffer.acquire_fence_fd = hwc_layer->acquireFenceFd; 524} 525 526int HWCDisplay::PrePrepareLayerStack(hwc_display_contents_1_t *content_list) { 527 if (shutdown_pending_) { 528 return 0; 529 } 530 531 size_t num_hw_layers = content_list->numHwLayers; 532 533 use_blit_comp_ = false; 534 metadata_refresh_rate_ = 0; 535 display_rect_ = LayerRect(); 536 537 // Configure each layer 538 for (size_t i = 0; i < num_hw_layers; i++) { 539 hwc_layer_1_t &hwc_layer = content_list->hwLayers[i]; 540 541 const private_handle_t *pvt_handle = static_cast<const private_handle_t *>(hwc_layer.handle); 542 Layer *layer = layer_stack_.layers.at(i); 543 int ret = PrepareLayerParams(&content_list->hwLayers[i], layer); 544 545 if (ret != kErrorNone) { 546 return ret; 547 } 548 549 layer->flags.skip = ((hwc_layer.flags & HWC_SKIP_LAYER) > 0); 550 layer->flags.solid_fill = (hwc_layer.flags & kDimLayer) || solid_fill_enable_; 551 if (layer->flags.skip || layer->flags.solid_fill) { 552 layer->dirty_regions.clear(); 553 } 554 555 hwc_rect_t scaled_display_frame = hwc_layer.displayFrame; 556 ApplyScanAdjustment(&scaled_display_frame); 557 558 SetRect(scaled_display_frame, &layer->dst_rect); 559 if (pvt_handle) { 560 bool NonIntegralSourceCrop = IsNonIntegralSourceCrop(hwc_layer.sourceCropf); 561 bool secure = (pvt_handle->flags & private_handle_t::PRIV_FLAGS_SECURE_BUFFER) || 562 (pvt_handle->flags & private_handle_t::PRIV_FLAGS_PROTECTED_BUFFER) || 563 (pvt_handle->flags & private_handle_t::PRIV_FLAGS_SECURE_DISPLAY); 564 if (NonIntegralSourceCrop && (!secure && pvt_handle->bufferType != BUFFER_TYPE_VIDEO)) { 565 layer->flags.skip = true; 566 } 567 } 568 SetRect(hwc_layer.sourceCropf, &layer->src_rect); 569 570 uint32_t num_visible_rects = UINT32(hwc_layer.visibleRegionScreen.numRects); 571 uint32_t num_dirty_rects = UINT32(hwc_layer.surfaceDamage.numRects); 572 573 for (uint32_t j = 0; j < num_visible_rects; j++) { 574 LayerRect visible_rect = {}; 575 SetRect(hwc_layer.visibleRegionScreen.rects[j], &visible_rect); 576 layer->visible_regions.push_back(visible_rect); 577 } 578 579 for (uint32_t j = 0; j < num_dirty_rects; j++) { 580 LayerRect dirty_rect = {}; 581 SetRect(hwc_layer.surfaceDamage.rects[j], &dirty_rect); 582 layer->dirty_regions.push_back(dirty_rect); 583 } 584 585 if (blit_engine_) { 586 for (uint32_t j = 0; j < kMaxBlitTargetLayers; j++) { 587 LayerRect blit_rect = {}; 588 layer->blit_regions.push_back(blit_rect); 589 } 590 } 591 592 SetComposition(hwc_layer.compositionType, &layer->composition); 593 if (hwc_layer.compositionType != HWC_FRAMEBUFFER_TARGET) { 594 display_rect_ = Union(display_rect_, layer->dst_rect); 595 } 596 597 // For dim layers, SurfaceFlinger 598 // - converts planeAlpha to per pixel alpha, 599 // - sets appropriate RGB color, 600 // - sets planeAlpha to 0xff, 601 // - blending to Premultiplied. 602 // This can be achieved at hardware by 603 // - solid fill ARGB to appropriate value, 604 // - incoming planeAlpha, 605 // - blending to Coverage. 606 if (hwc_layer.flags & kDimLayer) { 607 layer->input_buffer.format = kFormatARGB8888; 608 layer->solid_fill_color = 0xff000000; 609#ifdef QTI_BSP 610 // Get ARGB color from HWC Dim Layer color 611 uint32_t a = UINT32(hwc_layer.color.a) << 24; 612 uint32_t r = UINT32(hwc_layer.color.r) << 16; 613 uint32_t g = UINT32(hwc_layer.color.g) << 8; 614 uint32_t b = UINT32(hwc_layer.color.b); 615 layer->solid_fill_color = a | r | g | b; 616#endif 617 SetBlending(HWC_BLENDING_COVERAGE, &layer->blending); 618 } else { 619 SetBlending(hwc_layer.blending, &layer->blending); 620 LayerTransform &layer_transform = layer->transform; 621 uint32_t &hwc_transform = hwc_layer.transform; 622 layer_transform.flip_horizontal = ((hwc_transform & HWC_TRANSFORM_FLIP_H) > 0); 623 layer_transform.flip_vertical = ((hwc_transform & HWC_TRANSFORM_FLIP_V) > 0); 624 layer_transform.rotation = ((hwc_transform & HWC_TRANSFORM_ROT_90) ? 90.0f : 0.0f); 625 } 626 627 // TODO(user): Remove below block. 628 // For solid fill, only dest rect need to be specified. 629 if (layer->flags.solid_fill) { 630 LayerBuffer &input_buffer = layer->input_buffer; 631 input_buffer.width = UINT32(layer->dst_rect.right - layer->dst_rect.left); 632 input_buffer.height = UINT32(layer->dst_rect.bottom - layer->dst_rect.top); 633 input_buffer.unaligned_width = input_buffer.width; 634 input_buffer.unaligned_height = input_buffer.height; 635 layer->src_rect.left = 0; 636 layer->src_rect.top = 0; 637 layer->src_rect.right = input_buffer.width; 638 layer->src_rect.bottom = input_buffer.height; 639 } 640 641 layer->plane_alpha = hwc_layer.planeAlpha; 642 layer->flags.cursor = ((hwc_layer.flags & HWC_IS_CURSOR_LAYER) > 0); 643 layer->flags.updating = true; 644 645 if (num_hw_layers <= kMaxLayerCount) { 646 layer->flags.updating = IsLayerUpdating(content_list, layer); 647 } 648#ifdef QTI_BSP 649 if (hwc_layer.flags & HWC_SCREENSHOT_ANIMATOR_LAYER) { 650 layer_stack_.flags.animating = true; 651 } 652#endif 653 if (layer->flags.skip) { 654 layer_stack_.flags.skip_present = true; 655 } 656 657 if (layer->flags.cursor) { 658 layer_stack_.flags.cursor_present = true; 659 } 660 661 PrepareDynamicRefreshRate(layer); 662 663 layer->input_buffer.buffer_id = reinterpret_cast<uint64_t>(hwc_layer.handle); 664 } 665 666 // Prepare the Blit Target 667 if (blit_engine_) { 668 // TODO(user): Fix this to enable BLIT 669#if 0 670 int ret = blit_engine_->Prepare(&layer_stack_); 671 if (ret) { 672 // Blit engine cannot handle this layer stack, hence set the layer stack 673 // count to num_hw_layers 674 layer_stack_.layer_count -= kMaxBlitTargetLayers; 675 } else { 676 use_blit_comp_ = true; 677 } 678#endif 679 } 680 681 // Configure layer stack 682 layer_stack_.flags.geometry_changed = ((content_list->flags & HWC_GEOMETRY_CHANGED) > 0); 683 684 return 0; 685} 686 687void HWCDisplay::SetLayerS3DMode(const LayerBufferS3DFormat &source, uint32_t *target) { 688#ifdef QTI_BSP 689 switch (source) { 690 case kS3dFormatNone: *target = HWC_S3DMODE_NONE; break; 691 case kS3dFormatLeftRight: *target = HWC_S3DMODE_LR; break; 692 case kS3dFormatRightLeft: *target = HWC_S3DMODE_RL; break; 693 case kS3dFormatTopBottom: *target = HWC_S3DMODE_TB; break; 694 case kS3dFormatFramePacking: *target = HWC_S3DMODE_FP; break; 695 default: *target = HWC_S3DMODE_MAX; break; 696 } 697#endif 698} 699 700int HWCDisplay::PrepareLayerStack(hwc_display_contents_1_t *content_list) { 701 if (shutdown_pending_) { 702 return 0; 703 } 704 705 size_t num_hw_layers = content_list->numHwLayers; 706 707 if (!skip_prepare_cnt) { 708 DisplayError error = display_intf_->Prepare(&layer_stack_); 709 if (error != kErrorNone) { 710 if (error == kErrorShutDown) { 711 shutdown_pending_ = true; 712 } else if ((error != kErrorPermission) && (error != kErrorNoAppLayers)) { 713 DLOGE("Prepare failed. Error = %d", error); 714 // To prevent surfaceflinger infinite wait, flush the previous frame during Commit() 715 // so that previous buffer and fences are released, and override the error. 716 flush_ = true; 717 } else { 718 DLOGV("Prepare failed for Display = %d Error = %d", type_, error); 719 } 720 return 0; 721 } 722 } else { 723 // Skip is not set 724 MarkLayersForGPUBypass(content_list); 725 skip_prepare_cnt = skip_prepare_cnt - 1; 726 DLOGI("SecureDisplay %s, Skip Prepare/Commit and Flush", secure_display_active_ ? "Starting" : 727 "Stopping"); 728 flush_ = true; 729 } 730 731 for (size_t i = 0; i < num_hw_layers; i++) { 732 hwc_layer_1_t &hwc_layer = content_list->hwLayers[i]; 733 Layer *layer = layer_stack_.layers.at(i); 734 LayerComposition composition = layer->composition; 735 private_handle_t* pvt_handle = static_cast<private_handle_t*> 736 (const_cast<native_handle_t*>(hwc_layer.handle)); 737 MetaData_t *meta_data = pvt_handle ? 738 reinterpret_cast<MetaData_t *>(pvt_handle->base_metadata) : NULL; 739 740 if ((composition == kCompositionSDE) || (composition == kCompositionHybrid) || 741 (composition == kCompositionBlit)) { 742 hwc_layer.hints |= HWC_HINT_CLEAR_FB; 743 } 744 SetComposition(composition, &hwc_layer.compositionType); 745 746 if (meta_data != NULL) { 747 if (composition == kCompositionGPUS3D) { 748 // Align HWC and client's dispaly ID in case of HDMI as primary 749 meta_data->s3dComp.displayId = 750 display_intf_->IsPrimaryDisplay() ? HWC_DISPLAY_PRIMARY: id_; 751 SetLayerS3DMode(layer->input_buffer.s3d_format, 752 &meta_data->s3dComp.s3dMode); 753 } 754 } 755 } 756 757 return 0; 758} 759 760int HWCDisplay::CommitLayerStack(hwc_display_contents_1_t *content_list) { 761 if (!content_list || !content_list->numHwLayers) { 762 DLOGW("Invalid content list"); 763 return -EINVAL; 764 } 765 766 if (shutdown_pending_) { 767 return 0; 768 } 769 770 int status = 0; 771 772 size_t num_hw_layers = content_list->numHwLayers; 773 774 DumpInputBuffers(content_list); 775 776 if (!flush_) { 777 for (size_t i = 0; i < num_hw_layers; i++) { 778 CommitLayerParams(&content_list->hwLayers[i], layer_stack_.layers.at(i)); 779 } 780 781 if (use_blit_comp_) { 782 status = blit_engine_->PreCommit(content_list, &layer_stack_); 783 if (status == 0) { 784 status = blit_engine_->Commit(content_list, &layer_stack_); 785 if (status != 0) { 786 DLOGE("Blit Comp Failed!"); 787 } 788 } 789 } 790 791 if (layer_stack_.flags.hdr_present) { 792 status = tone_mapper_->HandleToneMap(content_list, &layer_stack_); 793 if (status != 0) { 794 DLOGE("Error handling HDR in ToneMapper"); 795 } 796 } else { 797 tone_mapper_->Terminate(); 798 } 799 800 DisplayError error = kErrorUndefined; 801 if (status == 0) { 802 error = display_intf_->Commit(&layer_stack_); 803 status = 0; 804 } 805 806 if (error == kErrorNone) { 807 // A commit is successfully submitted, start flushing on failure now onwards. 808 flush_on_error_ = true; 809 } else { 810 if (error == kErrorShutDown) { 811 shutdown_pending_ = true; 812 return status; 813 } else if (error != kErrorPermission) { 814 DLOGE("Commit failed. Error = %d", error); 815 // To prevent surfaceflinger infinite wait, flush the previous frame during Commit() 816 // so that previous buffer and fences are released, and override the error. 817 flush_ = true; 818 } else { 819 DLOGI("Commit failed for Display = %d Error = %d", type_, error); 820 } 821 } 822 } 823 824 return status; 825} 826 827int HWCDisplay::PostCommitLayerStack(hwc_display_contents_1_t *content_list) { 828 size_t num_hw_layers = content_list->numHwLayers; 829 int status = 0; 830 831 // Do no call flush on errors, if a successful buffer is never submitted. 832 if (flush_ && flush_on_error_) { 833 display_intf_->Flush(); 834 } 835 836 837 if (tone_mapper_ && tone_mapper_->IsActive()) { 838 tone_mapper_->PostCommit(&layer_stack_); 839 } 840 841 // Set the release fence fd to the blit engine 842 if (use_blit_comp_ && blit_engine_->BlitActive()) { 843 blit_engine_->PostCommit(&layer_stack_); 844 } 845 846 for (size_t i = 0; i < num_hw_layers; i++) { 847 hwc_layer_1_t &hwc_layer = content_list->hwLayers[i]; 848 Layer *layer = layer_stack_.layers.at(i); 849 LayerBuffer &layer_buffer = layer->input_buffer; 850 851 if (!flush_) { 852 // If swapinterval property is set to 0 or for single buffer layers, do not update f/w 853 // release fences and discard fences from driver 854 if (swap_interval_zero_ || layer->flags.single_buffer) { 855 hwc_layer.releaseFenceFd = -1; 856 close(layer_buffer.release_fence_fd); 857 layer_buffer.release_fence_fd = -1; 858 } else if (layer->composition != kCompositionGPU) { 859 hwc_layer.releaseFenceFd = layer_buffer.release_fence_fd; 860 } 861 862 // During animation on external/virtual display, SDM will use the cached 863 // framebuffer layer throughout animation and do not allow framework to do eglswapbuffer on 864 // framebuffer target. So graphics doesn't close the release fence fd of framebuffer target, 865 // Hence close the release fencefd of framebuffer target here. 866 if (disable_animation_) { 867 if (layer->composition == kCompositionGPUTarget && animating_) { 868 close(hwc_layer.releaseFenceFd); 869 hwc_layer.releaseFenceFd = -1; 870 } 871 } 872 } 873 874 if (hwc_layer.acquireFenceFd >= 0) { 875 close(hwc_layer.acquireFenceFd); 876 hwc_layer.acquireFenceFd = -1; 877 } 878 } 879 880 if (!flush_) { 881 animating_ = layer_stack_.flags.animating; 882 // if swapinterval property is set to 0 then close and reset the list retire fence 883 if (swap_interval_zero_) { 884 close(layer_stack_.retire_fence_fd); 885 layer_stack_.retire_fence_fd = -1; 886 } 887 content_list->retireFenceFd = layer_stack_.retire_fence_fd; 888 889 if (dump_frame_count_) { 890 dump_frame_count_--; 891 dump_frame_index_++; 892 } 893 } 894 895 flush_ = false; 896 897 return status; 898} 899 900bool HWCDisplay::IsLayerUpdating(hwc_display_contents_1_t *content_list, const Layer *layer) { 901 // Layer should be considered updating if 902 // a) layer is in single buffer mode, or 903 // b) valid dirty_regions(android specific hint for updating status), or 904 // c) layer stack geometry has changed 905 return (layer->flags.single_buffer || IsSurfaceUpdated(layer->dirty_regions) || 906 (layer_stack_.flags.geometry_changed)); 907} 908 909bool HWCDisplay::IsNonIntegralSourceCrop(const hwc_frect_t &source) { 910 if ((source.left != roundf(source.left)) || 911 (source.top != roundf(source.top)) || 912 (source.right != roundf(source.right)) || 913 (source.bottom != roundf(source.bottom))) { 914 return true; 915 } else { 916 return false; 917 } 918} 919 920void HWCDisplay::SetRect(const hwc_rect_t &source, LayerRect *target) { 921 target->left = FLOAT(source.left); 922 target->top = FLOAT(source.top); 923 target->right = FLOAT(source.right); 924 target->bottom = FLOAT(source.bottom); 925} 926 927void HWCDisplay::SetRect(const hwc_frect_t &source, LayerRect *target) { 928 target->left = floorf(source.left); 929 target->top = floorf(source.top); 930 target->right = ceilf(source.right); 931 target->bottom = ceilf(source.bottom); 932} 933 934void HWCDisplay::SetComposition(const int32_t &source, LayerComposition *target) { 935 switch (source) { 936 case HWC_FRAMEBUFFER_TARGET: *target = kCompositionGPUTarget; break; 937 default: *target = kCompositionGPU; break; 938 } 939} 940 941void HWCDisplay::SetComposition(const LayerComposition &source, int32_t *target) { 942 switch (source) { 943 case kCompositionGPUTarget: *target = HWC_FRAMEBUFFER_TARGET; break; 944 case kCompositionGPU: *target = HWC_FRAMEBUFFER; break; 945 case kCompositionGPUS3D: *target = HWC_FRAMEBUFFER; break; 946 case kCompositionHWCursor: *target = HWC_CURSOR_OVERLAY; break; 947 default: *target = HWC_OVERLAY; break; 948 } 949} 950 951void HWCDisplay::SetBlending(const int32_t &source, LayerBlending *target) { 952 switch (source) { 953 case HWC_BLENDING_PREMULT: *target = kBlendingPremultiplied; break; 954 case HWC_BLENDING_COVERAGE: *target = kBlendingCoverage; break; 955 default: *target = kBlendingOpaque; break; 956 } 957} 958 959void HWCDisplay::SetIdleTimeoutMs(uint32_t timeout_ms) { 960 return; 961} 962 963DisplayError HWCDisplay::SetMaxMixerStages(uint32_t max_mixer_stages) { 964 DisplayError error = kErrorNone; 965 966 if (display_intf_) { 967 error = display_intf_->SetMaxMixerStages(max_mixer_stages); 968 } 969 970 return error; 971} 972 973LayerBufferFormat HWCDisplay::GetSDMFormat(const int32_t &source, const int flags) { 974 LayerBufferFormat format = kFormatInvalid; 975 if (flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED) { 976 switch (source) { 977 case HAL_PIXEL_FORMAT_RGBA_8888: format = kFormatRGBA8888Ubwc; break; 978 case HAL_PIXEL_FORMAT_RGBX_8888: format = kFormatRGBX8888Ubwc; break; 979 case HAL_PIXEL_FORMAT_BGR_565: format = kFormatBGR565Ubwc; break; 980 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS: 981 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC: 982 case HAL_PIXEL_FORMAT_NV12_ENCODEABLE: format = kFormatYCbCr420SPVenusUbwc; break; 983 case HAL_PIXEL_FORMAT_RGBA_1010102: format = kFormatRGBA1010102Ubwc; break; 984 case HAL_PIXEL_FORMAT_RGBX_1010102: format = kFormatRGBX1010102Ubwc; break; 985 case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC: format = kFormatYCbCr420TP10Ubwc; break; 986 case HAL_PIXEL_FORMAT_YCbCr_420_P010_UBWC: format = kFormatYCbCr420P010Ubwc; break; 987 default: 988 DLOGE("Unsupported format type for UBWC %d", source); 989 return kFormatInvalid; 990 } 991 return format; 992 } 993 994 switch (source) { 995 case HAL_PIXEL_FORMAT_RGBA_8888: format = kFormatRGBA8888; break; 996 case HAL_PIXEL_FORMAT_RGBA_5551: format = kFormatRGBA5551; break; 997 case HAL_PIXEL_FORMAT_RGBA_4444: format = kFormatRGBA4444; break; 998 case HAL_PIXEL_FORMAT_BGRA_8888: format = kFormatBGRA8888; break; 999 case HAL_PIXEL_FORMAT_RGBX_8888: format = kFormatRGBX8888; break; 1000 case HAL_PIXEL_FORMAT_BGRX_8888: format = kFormatBGRX8888; break; 1001 case HAL_PIXEL_FORMAT_RGB_888: format = kFormatRGB888; break; 1002 case HAL_PIXEL_FORMAT_RGB_565: format = kFormatRGB565; break; 1003 case HAL_PIXEL_FORMAT_BGR_565: format = kFormatBGR565; break; 1004 case HAL_PIXEL_FORMAT_NV12_ENCODEABLE: 1005 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS: format = kFormatYCbCr420SemiPlanarVenus; break; 1006 case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS: format = kFormatYCrCb420SemiPlanarVenus; break; 1007 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC: format = kFormatYCbCr420SPVenusUbwc; break; 1008 case HAL_PIXEL_FORMAT_YV12: format = kFormatYCrCb420PlanarStride16; break; 1009 case HAL_PIXEL_FORMAT_YCrCb_420_SP: format = kFormatYCrCb420SemiPlanar; break; 1010 case HAL_PIXEL_FORMAT_YCbCr_420_SP: format = kFormatYCbCr420SemiPlanar; break; 1011 case HAL_PIXEL_FORMAT_YCbCr_422_SP: format = kFormatYCbCr422H2V1SemiPlanar; break; 1012 case HAL_PIXEL_FORMAT_YCbCr_422_I: format = kFormatYCbCr422H2V1Packed; break; 1013 case HAL_PIXEL_FORMAT_CbYCrY_422_I: format = kFormatCbYCrY422H2V1Packed; break; 1014 case HAL_PIXEL_FORMAT_RGBA_1010102: format = kFormatRGBA1010102; break; 1015 case HAL_PIXEL_FORMAT_ARGB_2101010: format = kFormatARGB2101010; break; 1016 case HAL_PIXEL_FORMAT_RGBX_1010102: format = kFormatRGBX1010102; break; 1017 case HAL_PIXEL_FORMAT_XRGB_2101010: format = kFormatXRGB2101010; break; 1018 case HAL_PIXEL_FORMAT_BGRA_1010102: format = kFormatBGRA1010102; break; 1019 case HAL_PIXEL_FORMAT_ABGR_2101010: format = kFormatABGR2101010; break; 1020 case HAL_PIXEL_FORMAT_BGRX_1010102: format = kFormatBGRX1010102; break; 1021 case HAL_PIXEL_FORMAT_XBGR_2101010: format = kFormatXBGR2101010; break; 1022 case HAL_PIXEL_FORMAT_YCbCr_420_P010: format = kFormatYCbCr420P010; break; 1023 case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC: format = kFormatYCbCr420TP10Ubwc; break; 1024 case HAL_PIXEL_FORMAT_YCbCr_420_P010_UBWC: format = kFormatYCbCr420P010Ubwc; break; 1025 default: 1026 DLOGW("Unsupported format type = %d", source); 1027 return kFormatInvalid; 1028 } 1029 1030 return format; 1031} 1032 1033void HWCDisplay::DumpInputBuffers(hwc_display_contents_1_t *content_list) { 1034 size_t num_hw_layers = content_list->numHwLayers; 1035 char dir_path[PATH_MAX]; 1036 1037 if (!dump_frame_count_ || flush_ || !dump_input_layers_) { 1038 return; 1039 } 1040 1041 snprintf(dir_path, sizeof(dir_path), "/data/misc/display/frame_dump_%s", GetDisplayString()); 1042 1043 if (mkdir(dir_path, 0777) != 0 && errno != EEXIST) { 1044 DLOGW("Failed to create %s directory errno = %d, desc = %s", dir_path, errno, strerror(errno)); 1045 return; 1046 } 1047 1048 // if directory exists already, need to explicitly change the permission. 1049 if (errno == EEXIST && chmod(dir_path, 0777) != 0) { 1050 DLOGW("Failed to change permissions on %s directory", dir_path); 1051 return; 1052 } 1053 1054 for (uint32_t i = 0; i < num_hw_layers; i++) { 1055 hwc_layer_1_t &hwc_layer = content_list->hwLayers[i]; 1056 const private_handle_t *pvt_handle = static_cast<const private_handle_t *>(hwc_layer.handle); 1057 1058 if (hwc_layer.acquireFenceFd >= 0) { 1059 int error = sync_wait(hwc_layer.acquireFenceFd, 1000); 1060 if (error < 0) { 1061 DLOGW("sync_wait error errno = %d, desc = %s", errno, strerror(errno)); 1062 return; 1063 } 1064 } 1065 1066 if (pvt_handle && pvt_handle->base) { 1067 char dump_file_name[PATH_MAX]; 1068 size_t result = 0; 1069 1070 snprintf(dump_file_name, sizeof(dump_file_name), "%s/input_layer%d_%dx%d_%s_frame%d.raw", 1071 dir_path, i, pvt_handle->width, pvt_handle->height, 1072 qdutils::GetHALPixelFormatString(pvt_handle->format), dump_frame_index_); 1073 1074 FILE* fp = fopen(dump_file_name, "w+"); 1075 if (fp) { 1076 result = fwrite(reinterpret_cast<void *>(pvt_handle->base), pvt_handle->size, 1, fp); 1077 fclose(fp); 1078 } 1079 1080 DLOGI("Frame Dump %s: is %s", dump_file_name, result ? "Successful" : "Failed"); 1081 } 1082 } 1083} 1084 1085void HWCDisplay::DumpOutputBuffer(const BufferInfo& buffer_info, void *base, int fence) { 1086 char dir_path[PATH_MAX]; 1087 1088 snprintf(dir_path, sizeof(dir_path), "/data/misc/display/frame_dump_%s", GetDisplayString()); 1089 1090 if (mkdir(dir_path, 777) != 0 && errno != EEXIST) { 1091 DLOGW("Failed to create %s directory errno = %d, desc = %s", dir_path, errno, strerror(errno)); 1092 return; 1093 } 1094 1095 // if directory exists already, need to explicitly change the permission. 1096 if (errno == EEXIST && chmod(dir_path, 0777) != 0) { 1097 DLOGW("Failed to change permissions on %s directory", dir_path); 1098 return; 1099 } 1100 1101 if (base) { 1102 char dump_file_name[PATH_MAX]; 1103 size_t result = 0; 1104 1105 if (fence >= 0) { 1106 int error = sync_wait(fence, 1000); 1107 if (error < 0) { 1108 DLOGW("sync_wait error errno = %d, desc = %s", errno, strerror(errno)); 1109 return; 1110 } 1111 } 1112 1113 snprintf(dump_file_name, sizeof(dump_file_name), "%s/output_layer_%dx%d_%s_frame%d.raw", 1114 dir_path, buffer_info.alloc_buffer_info.aligned_width, 1115 buffer_info.alloc_buffer_info.aligned_height, 1116 GetFormatString(buffer_info.buffer_config.format), dump_frame_index_); 1117 1118 FILE* fp = fopen(dump_file_name, "w+"); 1119 if (fp) { 1120 result = fwrite(base, buffer_info.alloc_buffer_info.size, 1, fp); 1121 fclose(fp); 1122 } 1123 1124 DLOGI("Frame Dump of %s is %s", dump_file_name, result ? "Successful" : "Failed"); 1125 } 1126} 1127 1128const char *HWCDisplay::GetDisplayString() { 1129 switch (type_) { 1130 case kPrimary: 1131 return "primary"; 1132 case kHDMI: 1133 return "hdmi"; 1134 case kVirtual: 1135 return "virtual"; 1136 default: 1137 return "invalid"; 1138 } 1139} 1140 1141int HWCDisplay::SetFrameBufferResolution(uint32_t x_pixels, uint32_t y_pixels) { 1142 DisplayConfigVariableInfo fb_config; 1143 DisplayError error = display_intf_->GetFrameBufferConfig(&fb_config); 1144 if (error != kErrorNone) { 1145 DLOGV("Get frame buffer config failed. Error = %d", error); 1146 return -EINVAL; 1147 } 1148 1149 fb_config.x_pixels = x_pixels; 1150 fb_config.y_pixels = y_pixels; 1151 1152 error = display_intf_->SetFrameBufferConfig(fb_config); 1153 if (error != kErrorNone) { 1154 DLOGV("Set frame buffer config failed. Error = %d", error); 1155 return -EINVAL; 1156 } 1157 1158 DLOGI("New framebuffer resolution (%dx%d)", x_pixels, y_pixels); 1159 1160 return 0; 1161} 1162 1163void HWCDisplay::GetFrameBufferResolution(uint32_t *x_pixels, uint32_t *y_pixels) { 1164 DisplayConfigVariableInfo fb_config; 1165 display_intf_->GetFrameBufferConfig(&fb_config); 1166 1167 *x_pixels = fb_config.x_pixels; 1168 *y_pixels = fb_config.y_pixels; 1169} 1170 1171DisplayError HWCDisplay::GetMixerResolution(uint32_t *x_pixels, uint32_t *y_pixels) { 1172 return display_intf_->GetMixerResolution(x_pixels, y_pixels); 1173} 1174 1175 1176void HWCDisplay::GetPanelResolution(uint32_t *x_pixels, uint32_t *y_pixels) { 1177 DisplayConfigVariableInfo display_config; 1178 uint32_t active_index = 0; 1179 1180 display_intf_->GetActiveConfig(&active_index); 1181 display_intf_->GetConfig(active_index, &display_config); 1182 1183 *x_pixels = display_config.x_pixels; 1184 *y_pixels = display_config.y_pixels; 1185} 1186 1187int HWCDisplay::SetDisplayStatus(uint32_t display_status) { 1188 int status = 0; 1189 const hwc_procs_t *hwc_procs = *hwc_procs_; 1190 1191 switch (display_status) { 1192 case kDisplayStatusResume: 1193 display_paused_ = false; 1194 case kDisplayStatusOnline: 1195 status = SetPowerMode(HWC_POWER_MODE_NORMAL); 1196 break; 1197 case kDisplayStatusPause: 1198 display_paused_ = true; 1199 case kDisplayStatusOffline: 1200 status = SetPowerMode(HWC_POWER_MODE_OFF); 1201 break; 1202 default: 1203 DLOGW("Invalid display status %d", display_status); 1204 return -EINVAL; 1205 } 1206 1207 if (display_status == kDisplayStatusResume || 1208 display_status == kDisplayStatusPause) { 1209 hwc_procs->invalidate(hwc_procs); 1210 } 1211 1212 return status; 1213} 1214 1215int HWCDisplay::SetCursorPosition(int x, int y) { 1216 DisplayError error = kErrorNone; 1217 1218 if (shutdown_pending_) { 1219 return 0; 1220 } 1221 1222 error = display_intf_->SetCursorPosition(x, y); 1223 if (error != kErrorNone) { 1224 if (error == kErrorShutDown) { 1225 shutdown_pending_ = true; 1226 return 0; 1227 } 1228 DLOGE("Failed for x = %d y = %d, Error = %d", x, y, error); 1229 return -1; 1230 } 1231 1232 return 0; 1233} 1234 1235int HWCDisplay::OnMinHdcpEncryptionLevelChange(uint32_t min_enc_level) { 1236 DisplayError error = display_intf_->OnMinHdcpEncryptionLevelChange(min_enc_level); 1237 if (error != kErrorNone) { 1238 DLOGE("Failed. Error = %d", error); 1239 return -1; 1240 } 1241 1242 return 0; 1243} 1244 1245void HWCDisplay::MarkLayersForGPUBypass(hwc_display_contents_1_t *content_list) { 1246 for (size_t i = 0 ; i < (content_list->numHwLayers - 1); i++) { 1247 hwc_layer_1_t *layer = &content_list->hwLayers[i]; 1248 layer->compositionType = HWC_OVERLAY; 1249 } 1250} 1251 1252void HWCDisplay::ApplyScanAdjustment(hwc_rect_t *display_frame) { 1253} 1254 1255DisplayError HWCDisplay::SetCSC(const MetaData_t *meta_data, ColorMetaData *color_metadata) { 1256 if (meta_data->operation & COLOR_METADATA) { 1257#ifdef USE_COLOR_METADATA 1258 *color_metadata = meta_data->color; 1259#endif 1260 } else if (meta_data->operation & UPDATE_COLOR_SPACE) { 1261 ColorSpace_t csc = meta_data->colorSpace; 1262 color_metadata->range = Range_Limited; 1263 1264 if (csc == ITU_R_601_FR || csc == ITU_R_2020_FR) { 1265 color_metadata->range = Range_Full; 1266 } 1267 1268 switch (csc) { 1269 case ITU_R_601: 1270 case ITU_R_601_FR: 1271 // display driver uses 601 irrespective of 525 or 625 1272 color_metadata->colorPrimaries = ColorPrimaries_BT601_6_525; 1273 break; 1274 case ITU_R_709: 1275 color_metadata->colorPrimaries = ColorPrimaries_BT709_5; 1276 break; 1277 case ITU_R_2020: 1278 case ITU_R_2020_FR: 1279 color_metadata->colorPrimaries = ColorPrimaries_BT2020; 1280 break; 1281 default: 1282 DLOGE("Unsupported CSC: %d", csc); 1283 return kErrorNotSupported; 1284 } 1285 } 1286 1287 return kErrorNone; 1288} 1289 1290DisplayError HWCDisplay::SetIGC(IGC_t source, LayerIGC *target) { 1291 switch (source) { 1292 case IGC_NotSpecified: *target = kIGCNotSpecified; break; 1293 case IGC_sRGB: *target = kIGCsRGB; break; 1294 default: 1295 DLOGE("Unsupported IGC: %d", source); 1296 return kErrorNotSupported; 1297 } 1298 1299 return kErrorNone; 1300} 1301 1302DisplayError HWCDisplay::SetMetaData(const private_handle_t *pvt_handle, Layer *layer) { 1303 const MetaData_t *meta_data = reinterpret_cast<MetaData_t *>(pvt_handle->base_metadata); 1304 LayerBuffer &layer_buffer = layer->input_buffer; 1305 1306 if (!meta_data) { 1307 return kErrorNone; 1308 } 1309 1310 if (SetCSC(meta_data, &layer_buffer.color_metadata) != kErrorNone) { 1311 return kErrorNotSupported; 1312 } 1313 1314 bool hdr_layer = layer_buffer.color_metadata.colorPrimaries == ColorPrimaries_BT2020 && 1315 (layer_buffer.color_metadata.transfer == Transfer_SMPTE_ST2084 || 1316 layer_buffer.color_metadata.transfer == Transfer_HLG); 1317 if (hdr_layer && !disable_hdr_handling_) { 1318 // dont honor HDR when its handling is disabled 1319 layer_buffer.flags.hdr = true; 1320 layer_stack_.flags.hdr_present = true; 1321 } 1322 1323 if (meta_data->operation & SET_IGC) { 1324 if (SetIGC(meta_data->igc, &layer_buffer.igc) != kErrorNone) { 1325 return kErrorNotSupported; 1326 } 1327 } 1328 1329 if (meta_data->operation & UPDATE_REFRESH_RATE) { 1330 layer->frame_rate = RoundToStandardFPS(meta_data->refreshrate); 1331 } 1332 1333 if ((meta_data->operation & PP_PARAM_INTERLACED) && meta_data->interlaced) { 1334 layer_buffer.flags.interlace = true; 1335 } 1336 1337 if (meta_data->operation & LINEAR_FORMAT) { 1338 layer_buffer.format = GetSDMFormat(INT32(meta_data->linearFormat), 0); 1339 } 1340 1341 if (meta_data->operation & SET_SINGLE_BUFFER_MODE) { 1342 layer->flags.single_buffer = meta_data->isSingleBufferMode; 1343 // Graphics can set this operation on all types of layers including FB and set the actual value 1344 // to 0. To protect against SET operations of 0 value, we need to do a logical OR. 1345 layer_stack_.flags.single_buffered_layer_present |= meta_data->isSingleBufferMode; 1346 } 1347 1348 if (meta_data->operation & S3D_FORMAT) { 1349 std::map<int, LayerBufferS3DFormat>::iterator it = 1350 s3d_format_hwc_to_sdm_.find(INT32(meta_data->s3dFormat)); 1351 if (it != s3d_format_hwc_to_sdm_.end()) { 1352 layer->input_buffer.s3d_format = it->second; 1353 } else { 1354 DLOGW("Invalid S3D format %d", meta_data->s3dFormat); 1355 } 1356 } 1357 1358 return kErrorNone; 1359} 1360 1361int HWCDisplay::SetPanelBrightness(int level) { 1362 int ret = 0; 1363 if (display_intf_) 1364 ret = display_intf_->SetPanelBrightness(level); 1365 else 1366 ret = -EINVAL; 1367 1368 return ret; 1369} 1370 1371int HWCDisplay::GetPanelBrightness(int *level) { 1372 return display_intf_->GetPanelBrightness(level); 1373} 1374 1375int HWCDisplay::CachePanelBrightness(int level) { 1376 int ret = 0; 1377 if (display_intf_) 1378 ret = display_intf_->CachePanelBrightness(level); 1379 else 1380 ret = -EINVAL; 1381 1382 return ret; 1383} 1384 1385int HWCDisplay::ToggleScreenUpdates(bool enable) { 1386 const hwc_procs_t *hwc_procs = *hwc_procs_; 1387 display_paused_ = enable ? false : true; 1388 hwc_procs->invalidate(hwc_procs); 1389 return 0; 1390} 1391 1392int HWCDisplay::ColorSVCRequestRoute(const PPDisplayAPIPayload &in_payload, 1393 PPDisplayAPIPayload *out_payload, 1394 PPPendingParams *pending_action) { 1395 int ret = 0; 1396 1397 if (display_intf_) 1398 ret = display_intf_->ColorSVCRequestRoute(in_payload, out_payload, pending_action); 1399 else 1400 ret = -EINVAL; 1401 1402 return ret; 1403} 1404 1405int HWCDisplay::GetVisibleDisplayRect(hwc_rect_t* visible_rect) { 1406 if (!IsValid(display_rect_)) { 1407 return -EINVAL; 1408 } 1409 1410 visible_rect->left = INT(display_rect_.left); 1411 visible_rect->top = INT(display_rect_.top); 1412 visible_rect->right = INT(display_rect_.right); 1413 visible_rect->bottom = INT(display_rect_.bottom); 1414 DLOGI("Dpy = %d Visible Display Rect(%d %d %d %d)", visible_rect->left, visible_rect->top, 1415 visible_rect->right, visible_rect->bottom); 1416 1417 return 0; 1418} 1419 1420void HWCDisplay::SetSecureDisplay(bool secure_display_active, bool force_flush) { 1421 secure_display_active_ = secure_display_active; 1422 return; 1423} 1424 1425int HWCDisplay::SetActiveDisplayConfig(int config) { 1426 return display_intf_->SetActiveConfig(UINT32(config)) == kErrorNone ? 0 : -1; 1427} 1428 1429int HWCDisplay::GetActiveDisplayConfig(uint32_t *config) { 1430 return display_intf_->GetActiveConfig(config) == kErrorNone ? 0 : -1; 1431} 1432 1433int HWCDisplay::GetDisplayConfigCount(uint32_t *count) { 1434 return display_intf_->GetNumVariableInfoConfigs(count) == kErrorNone ? 0 : -1; 1435} 1436 1437int HWCDisplay::GetDisplayAttributesForConfig(int config, 1438 DisplayConfigVariableInfo *display_attributes) { 1439 return display_intf_->GetConfig(UINT32(config), display_attributes) == kErrorNone ? 0 : -1; 1440} 1441 1442int HWCDisplay::GetDisplayFixedConfig(DisplayConfigFixedInfo *fixed_info) { 1443 return display_intf_->GetConfig(fixed_info) == kErrorNone ? 0 : -1; 1444} 1445 1446// TODO(user): HWC needs to know updating for dyn_fps, cpu hint features, 1447// once the features are moved to SDM, the two functions below can be removed. 1448uint32_t HWCDisplay::GetUpdatingLayersCount(uint32_t app_layer_count) { 1449 uint32_t updating_count = 0; 1450 1451 for (uint i = 0; i < app_layer_count; i++) { 1452 Layer *layer = layer_stack_.layers.at(i); 1453 if (layer->flags.updating) { 1454 updating_count++; 1455 } 1456 } 1457 1458 return updating_count; 1459} 1460 1461bool HWCDisplay::SingleVideoLayerUpdating(uint32_t app_layer_count) { 1462 uint32_t updating_count = 0; 1463 1464 for (uint i = 0; i < app_layer_count; i++) { 1465 Layer *layer = layer_stack_.layers[i]; 1466 // TODO(user): disable DRC feature in S3D playbacl case.S3D video 1467 // need play in dedicate resolution and fps, if DRC switch the 1468 // mode to an non S3D supported mode, it would break S3D playback. 1469 // Need figure out a way to make S3D and DRC co-exist. 1470 if (layer->flags.updating && (layer->input_buffer.flags.video == true) && 1471 (layer->input_buffer.s3d_format == kS3dFormatNone)) { 1472 updating_count++; 1473 } 1474 } 1475 1476 return (updating_count == 1); 1477} 1478 1479uint32_t HWCDisplay::RoundToStandardFPS(float fps) { 1480 static const uint32_t standard_fps[4] = {30, 24, 48, 60}; 1481 uint32_t frame_rate = (uint32_t)(fps); 1482 1483 int count = INT(sizeof(standard_fps) / sizeof(standard_fps[0])); 1484 for (int i = 0; i < count; i++) { 1485 if ((standard_fps[i] - frame_rate) < 2) { 1486 // Most likely used for video, the fps can fluctuate 1487 // Ex: b/w 29 and 30 for 30 fps clip 1488 return standard_fps[i]; 1489 } 1490 } 1491 1492 return frame_rate; 1493} 1494 1495uint32_t HWCDisplay::SanitizeRefreshRate(uint32_t req_refresh_rate) { 1496 uint32_t refresh_rate = req_refresh_rate; 1497 1498 if (refresh_rate < min_refresh_rate_) { 1499 // Pick the next multiple of request which is within the range 1500 refresh_rate = (((min_refresh_rate_ / refresh_rate) + 1501 ((min_refresh_rate_ % refresh_rate) ? 1 : 0)) * refresh_rate); 1502 } 1503 1504 if (refresh_rate > max_refresh_rate_) { 1505 refresh_rate = max_refresh_rate_; 1506 } 1507 1508 return refresh_rate; 1509} 1510 1511DisplayClass HWCDisplay::GetDisplayClass() { 1512 return display_class_; 1513} 1514 1515void HWCDisplay::PrepareDynamicRefreshRate(Layer *layer) { 1516 if (layer->frame_rate > metadata_refresh_rate_) { 1517 metadata_refresh_rate_ = SanitizeRefreshRate(layer->frame_rate); 1518 } else { 1519 layer->frame_rate = current_refresh_rate_; 1520 } 1521} 1522 1523bool HWCDisplay::IsSurfaceUpdated(const std::vector<LayerRect> &dirty_regions) { 1524 // based on dirty_regions determine if its updating 1525 // dirty_rect count = 0 - whole layer - updating. 1526 // dirty_rect count = 1 or more valid rects - updating. 1527 // dirty_rect count = 1 with (0,0,0,0) - not updating. 1528 return (dirty_regions.empty() || IsValid(dirty_regions.at(0))); 1529} 1530 1531int HWCDisplay::GetDisplayPort(DisplayPort *port) { 1532 return display_intf_->GetDisplayPort(port) == kErrorNone ? 0 : -1; 1533} 1534 1535 1536} // namespace sdm 1537