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