hwc_display.cpp revision c25b1e71c5c04691c5fa3936b9a37c94e69a2e03
1/* 2 * Copyright (c) 2014-2016, The Linux Foundation. All rights reserved. 3 * Not a Contribution. 4 * 5 * Copyright 2015 The Android Open Source Project 6 * 7 * Licensed under the Apache License, Version 2.0 (the "License"); 8 * you may not use this file except in compliance with the License. 9 * You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, software 14 * distributed under the License is distributed on an "AS IS" BASIS, 15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 * See the License for the specific language governing permissions and 17 * limitations under the License. 18 */ 19 20#include <cutils/properties.h> 21#include <errno.h> 22#include <gr.h> 23#include <gralloc_priv.h> 24#include <math.h> 25#include <sync/sync.h> 26#include <utils/constants.h> 27#include <utils/debug.h> 28#include <utils/formats.h> 29#include <utils/rect.h> 30 31#include <algorithm> 32#include <map> 33#include <sstream> 34#include <string> 35#include <utility> 36#include <vector> 37 38#include "hwc_display.h" 39#include "hwc_debugger.h" 40#include "blit_engine_c2d.h" 41 42#ifdef QTI_BSP 43#include <hardware/display_defs.h> 44#endif 45 46#define __CLASS__ "HWCDisplay" 47 48namespace sdm { 49 50static void ApplyDeInterlaceAdjustment(Layer *layer) { 51 // De-interlacing adjustment 52 if (layer->input_buffer->flags.interlace) { 53 float height = (layer->src_rect.bottom - layer->src_rect.top) / 2.0f; 54 layer->src_rect.top = ROUND_UP_ALIGN_DOWN(layer->src_rect.top / 2.0f, 2); 55 layer->src_rect.bottom = layer->src_rect.top + floorf(height); 56 } 57} 58 59HWCColorMode::HWCColorMode(DisplayInterface *display_intf) : display_intf_(display_intf) {} 60 61HWC2::Error HWCColorMode::Init() { 62 PopulateColorModes(); 63 return HWC2::Error::None; 64} 65 66HWC2::Error HWCColorMode::DeInit() { 67 color_mode_transform_map_.clear(); 68 return HWC2::Error::None; 69} 70 71uint32_t HWCColorMode::GetColorModeCount() { 72 uint32_t count = UINT32(color_mode_transform_map_.size()); 73 DLOGI("Supported color mode count = %d", count); 74 75 return std::max(1U, count); 76} 77 78HWC2::Error HWCColorMode::GetColorModes(uint32_t *out_num_modes, 79 android_color_mode_t *out_modes) { 80 auto it = color_mode_transform_map_.begin(); 81 for (auto i = 0; it != color_mode_transform_map_.end(); it++, i++) { 82 out_modes[i] = it->first; 83 DLOGI("Supports color mode[%d] = %d", i, it->first); 84 } 85 *out_num_modes = UINT32(color_mode_transform_map_.size()); 86 return HWC2::Error::None; 87} 88 89HWC2::Error HWCColorMode::SetColorMode(android_color_mode_t mode) { 90 // first mode in 2D matrix is the mode (identity) 91 auto status = HandleColorModeTransform(mode, current_color_transform_, color_matrix_); 92 if (status != HWC2::Error::None) { 93 DLOGE("failed for mode = %d", mode); 94 } 95 96 return status; 97} 98 99HWC2::Error HWCColorMode::SetColorTransform(const float *matrix, android_color_transform_t hint) { 100 if (!matrix) { 101 return HWC2::Error::BadParameter; 102 } 103 104 double color_matrix[kColorTransformMatrixCount] = {0}; 105 CopyColorTransformMatrix(matrix, color_matrix); 106 107 auto status = HandleColorModeTransform(current_color_mode_, hint, color_matrix); 108 if (status != HWC2::Error::None) { 109 DLOGE("failed for hint = %d", hint); 110 } 111 112 return status; 113} 114 115HWC2::Error HWCColorMode::HandleColorModeTransform(android_color_mode_t mode, 116 android_color_transform_t hint, 117 const double *matrix) { 118 android_color_transform_t transform_hint = hint; 119 std::string color_mode_transform; 120 bool use_matrix = false; 121 if (hint != HAL_COLOR_TRANSFORM_ARBITRARY_MATRIX) { 122 // if the mode + transfrom request from HWC matches one mode in SDM, set that 123 color_mode_transform = color_mode_transform_map_[mode][hint]; 124 if (color_mode_transform.empty()) { 125 transform_hint = HAL_COLOR_TRANSFORM_IDENTITY; 126 use_matrix = true; 127 } 128 } else { 129 use_matrix = true; 130 transform_hint = HAL_COLOR_TRANSFORM_IDENTITY; 131 } 132 133 // if the mode count is 1, then only native mode is supported, so just apply matrix w/o 134 // setting mode 135 if (color_mode_transform_map_.size() > 1U) { 136 color_mode_transform = color_mode_transform_map_[mode][transform_hint]; 137 DisplayError error = display_intf_->SetColorMode(color_mode_transform); 138 if (error != kErrorNone) { 139 DLOGE("Failed to set color_mode = %d transform_hint = %d", mode, hint); 140 // failure to force client composition 141 return HWC2::Error::Unsupported; 142 } 143 } 144 145 if (use_matrix) { 146 DisplayError error = display_intf_->SetColorTransform(kColorTransformMatrixCount, matrix); 147 if (error != kErrorNone) { 148 DLOGE("Failed to set Color Transform Matrix"); 149 // failure to force client composition 150 return HWC2::Error::Unsupported; 151 } 152 } 153 154 current_color_mode_ = mode; 155 current_color_transform_ = hint; 156 CopyColorTransformMatrix(matrix, color_matrix_); 157 DLOGI("Setting Color Mode = %d Transform Hint = %d Success", mode, hint); 158 159 return HWC2::Error::None; 160} 161 162void HWCColorMode::PopulateColorModes() { 163 uint32_t color_mode_count = 0; 164 // SDM returns modes which is string combination of mode + transform. 165 DisplayError error = display_intf_->GetColorModeCount(&color_mode_count); 166 if (error != kErrorNone || (color_mode_count == 0)) { 167 DLOGW("GetColorModeCount failed, use native color mode"); 168 PopulateTransform(HAL_COLOR_MODE_NATIVE, "native_identity"); 169 return; 170 } 171 172 DLOGI("Color Modes supported count = %d", color_mode_count); 173 174 std::vector<std::string> color_modes(color_mode_count); 175 error = display_intf_->GetColorModes(&color_mode_count, &color_modes); 176 177 for (uint32_t i = 0; i < color_mode_count; i++) { 178 std::string &mode_string = color_modes.at(i); 179 DLOGI("Color Mode[%d] = %s", i, mode_string.c_str()); 180 if (mode_string.find("hal_native") != std::string::npos) { 181 PopulateTransform(HAL_COLOR_MODE_NATIVE, mode_string); 182 } else if (mode_string.find("hal_srgb") != std::string::npos) { 183 PopulateTransform(HAL_COLOR_MODE_SRGB, mode_string); 184 } else if (mode_string.find("hal_adobe") != std::string::npos) { 185 PopulateTransform(HAL_COLOR_MODE_ADOBE_RGB, mode_string); 186 } else if (mode_string.find("hal_dci_p3") != std::string::npos) { 187 PopulateTransform(HAL_COLOR_MODE_DCI_P3, mode_string); 188 } 189 } 190} 191 192void HWCColorMode::PopulateTransform(const android_color_mode_t &mode, 193 const std::string &color_transform) { 194 // TODO(user): Check the substring from QDCM 195 if (color_transform.find("identity") != std::string::npos) { 196 color_mode_transform_map_[mode][HAL_COLOR_TRANSFORM_IDENTITY] = color_transform; 197 } else if (color_transform.find("arbitrary") != std::string::npos) { 198 // no color mode for arbitrary 199 } else if (color_transform.find("inverse") != std::string::npos) { 200 color_mode_transform_map_[mode][HAL_COLOR_TRANSFORM_VALUE_INVERSE] = color_transform; 201 } else if (color_transform.find("grayscale") != std::string::npos) { 202 color_mode_transform_map_[mode][HAL_COLOR_TRANSFORM_GRAYSCALE] = color_transform; 203 } else if (color_transform.find("correct_protonopia") != std::string::npos) { 204 color_mode_transform_map_[mode][HAL_COLOR_TRANSFORM_CORRECT_PROTANOPIA] = color_transform; 205 } else if (color_transform.find("correct_deuteranopia") != std::string::npos) { 206 color_mode_transform_map_[mode][HAL_COLOR_TRANSFORM_CORRECT_DEUTERANOPIA] = color_transform; 207 } else if (color_transform.find("correct_tritanopia") != std::string::npos) { 208 color_mode_transform_map_[mode][HAL_COLOR_TRANSFORM_CORRECT_TRITANOPIA] = color_transform; 209 } 210} 211 212HWCDisplay::HWCDisplay(CoreInterface *core_intf, HWCCallbacks *callbacks, DisplayType type, 213 hwc2_display_t id, bool needs_blit, qService::QService *qservice, 214 DisplayClass display_class) 215 : core_intf_(core_intf), 216 callbacks_(callbacks), 217 type_(type), 218 id_(id), 219 needs_blit_(needs_blit), 220 qservice_(qservice), 221 display_class_(display_class) { 222} 223 224int HWCDisplay::Init() { 225 DisplayError error = core_intf_->CreateDisplay(type_, this, &display_intf_); 226 if (error != kErrorNone) { 227 DLOGE("Display create failed. Error = %d display_type %d event_handler %p disp_intf %p", error, 228 type_, this, &display_intf_); 229 return -EINVAL; 230 } 231 232 int property_swap_interval = 1; 233 HWCDebugHandler::Get()->GetProperty("debug.egl.swapinterval", &property_swap_interval); 234 if (property_swap_interval == 0) { 235 swap_interval_zero_ = true; 236 } 237 238 239 client_target_ = new HWCLayer(id_); 240 int blit_enabled = 0; 241 HWCDebugHandler::Get()->GetProperty("persist.hwc.blit.comp", &blit_enabled); 242 if (needs_blit_ && blit_enabled) { 243 blit_engine_ = new BlitEngineC2d(); 244 if (!blit_engine_) { 245 DLOGI("Create Blit Engine C2D failed"); 246 } else { 247 if (blit_engine_->Init() < 0) { 248 DLOGI("Blit Engine Init failed, Blit Composition will not be used!!"); 249 delete blit_engine_; 250 blit_engine_ = NULL; 251 } 252 } 253 } 254 255 display_intf_->GetRefreshRateRange(&min_refresh_rate_, &max_refresh_rate_); 256 current_refresh_rate_ = max_refresh_rate_; 257 DLOGI("Display created with id: %d", id_); 258 return 0; 259} 260 261int HWCDisplay::Deinit() { 262 DisplayError error = core_intf_->DestroyDisplay(display_intf_); 263 if (error != kErrorNone) { 264 DLOGE("Display destroy failed. Error = %d", error); 265 return -EINVAL; 266 } 267 268 delete client_target_; 269 270 if (blit_engine_) { 271 blit_engine_->DeInit(); 272 delete blit_engine_; 273 blit_engine_ = NULL; 274 } 275 276 if (color_mode_) { 277 color_mode_->DeInit(); 278 delete color_mode_; 279 } 280 281 return 0; 282} 283 284// LayerStack operations 285HWC2::Error HWCDisplay::CreateLayer(hwc2_layer_t *out_layer_id) { 286 HWCLayer *layer = *layer_set_.emplace(new HWCLayer(id_)); 287 layer_map_.emplace(std::make_pair(layer->GetId(), layer)); 288 *out_layer_id = layer->GetId(); 289 geometry_changes_ |= GeometryChanges::kAdded; 290 return HWC2::Error::None; 291} 292 293HWCLayer *HWCDisplay::GetHWCLayer(hwc2_layer_t layer_id) { 294 const auto map_layer = layer_map_.find(layer_id); 295 if (map_layer == layer_map_.end()) { 296 DLOGE("[%" PRIu64 "] GetLayer(%" PRIu64 ") failed: no such layer", id_, layer_id); 297 return nullptr; 298 } else { 299 return map_layer->second; 300 } 301} 302 303HWC2::Error HWCDisplay::DestroyLayer(hwc2_layer_t layer_id) { 304 const auto map_layer = layer_map_.find(layer_id); 305 if (map_layer == layer_map_.end()) { 306 DLOGE("[%" PRIu64 "] destroyLayer(%" PRIu64 ") failed: no such layer", id_, layer_id); 307 return HWC2::Error::BadLayer; 308 } 309 const auto layer = map_layer->second; 310 layer_map_.erase(map_layer); 311 const auto z_range = layer_set_.equal_range(layer); 312 for (auto current = z_range.first; current != z_range.second; ++current) { 313 if (*current == layer) { 314 current = layer_set_.erase(current); 315 delete layer; 316 break; 317 } 318 } 319 320 geometry_changes_ |= GeometryChanges::kRemoved; 321 return HWC2::Error::None; 322} 323 324void HWCDisplay::BuildLayerStack() { 325 layer_stack_ = LayerStack(); 326 display_rect_ = LayerRect(); 327 metadata_refresh_rate_ = 0; 328 329 // Add one layer for fb target 330 // TODO(user): Add blit target layers 331 for (auto hwc_layer : layer_set_) { 332 Layer *layer = hwc_layer->GetSDMLayer(); 333 // set default composition as GPU for SDM 334 layer->composition = kCompositionGPU; 335 336 if (swap_interval_zero_) { 337 if (layer->input_buffer->acquire_fence_fd >= 0) { 338 close(layer->input_buffer->acquire_fence_fd); 339 layer->input_buffer->acquire_fence_fd = -1; 340 } 341 } 342 343 const private_handle_t *handle = 344 reinterpret_cast<const private_handle_t *>(layer->input_buffer->buffer_id); 345 if (handle) { 346 if (handle->bufferType == BUFFER_TYPE_VIDEO) { 347 layer_stack_.flags.video_present = true; 348 } 349 // TZ Protected Buffer - L1 350 if (handle->flags & private_handle_t::PRIV_FLAGS_SECURE_BUFFER) { 351 layer_stack_.flags.secure_present = true; 352 } 353 // Gralloc Usage Protected Buffer - L3 - which needs to be treated as Secure & avoid fallback 354 if (handle->flags & private_handle_t::PRIV_FLAGS_PROTECTED_BUFFER) { 355 layer_stack_.flags.secure_present = true; 356 } 357 } 358 359 if (layer->flags.skip) { 360 layer_stack_.flags.skip_present = true; 361 } 362 363 if (layer->flags.cursor) { 364 layer_stack_.flags.cursor_present = true; 365 } 366 // TODO(user): Move to a getter if this is needed at other places 367 hwc_rect_t scaled_display_frame = {INT(layer->dst_rect.left), INT(layer->dst_rect.top), 368 INT(layer->dst_rect.right), INT(layer->dst_rect.bottom)}; 369 ApplyScanAdjustment(&scaled_display_frame); 370 hwc_layer->SetLayerDisplayFrame(scaled_display_frame); 371 ApplyDeInterlaceAdjustment(layer); 372 // TODO(user): Verify if we still need to configure the solid fill layerbuffer, 373 // it should already have a valid dst_rect by this point 374 375 if (layer->frame_rate > metadata_refresh_rate_) { 376 metadata_refresh_rate_ = SanitizeRefreshRate(layer->frame_rate); 377 } else { 378 layer->frame_rate = current_refresh_rate_; 379 } 380 display_rect_ = Union(display_rect_, layer->dst_rect); 381 geometry_changes_ |= hwc_layer->GetGeometryChanges(); 382 layer->flags.updating = IsLayerUpdating(layer); 383 384 layer_stack_.layers.push_back(layer); 385 } 386 // TODO(user): Set correctly when SDM supports geometry_changes as bitmask 387 layer_stack_.flags.geometry_changed = UINT32(geometry_changes_ > 0); 388 // Append client target to the layer stack 389 layer_stack_.layers.push_back(client_target_->GetSDMLayer()); 390} 391 392void HWCDisplay::BuildSolidFillStack() { 393 layer_stack_ = LayerStack(); 394 display_rect_ = LayerRect(); 395 396 layer_stack_.layers.push_back(solid_fill_layer_); 397 layer_stack_.flags.geometry_changed = 1U; 398 // Append client target to the layer stack 399 layer_stack_.layers.push_back(client_target_->GetSDMLayer()); 400} 401 402HWC2::Error HWCDisplay::SetLayerZOrder(hwc2_layer_t layer_id, uint32_t z) { 403 const auto map_layer = layer_map_.find(layer_id); 404 if (map_layer == layer_map_.end()) { 405 DLOGE("[%" PRIu64 "] updateLayerZ failed to find layer", id_); 406 return HWC2::Error::BadLayer; 407 } 408 409 const auto layer = map_layer->second; 410 const auto z_range = layer_set_.equal_range(layer); 411 bool layer_on_display = false; 412 for (auto current = z_range.first; current != z_range.second; ++current) { 413 if (*current == layer) { 414 if ((*current)->GetZ() == z) { 415 // Don't change anything if the Z hasn't changed 416 return HWC2::Error::None; 417 } 418 current = layer_set_.erase(current); 419 layer_on_display = true; 420 break; 421 } 422 } 423 424 if (!layer_on_display) { 425 DLOGE("[%" PRIu64 "] updateLayerZ failed to find layer on display", id_); 426 return HWC2::Error::BadLayer; 427 } 428 429 layer->SetLayerZOrder(z); 430 layer_set_.emplace(layer); 431 return HWC2::Error::None; 432} 433 434HWC2::Error HWCDisplay::SetVsyncEnabled(HWC2::Vsync enabled) { 435 DLOGV("Display ID: %d enabled: %s", id_, to_string(enabled).c_str()); 436 DisplayError error = kErrorNone; 437 438 if (shutdown_pending_) { 439 return HWC2::Error::None; 440 } 441 442 bool state; 443 if (enabled == HWC2::Vsync::Enable) 444 state = true; 445 else if (enabled == HWC2::Vsync::Disable) 446 state = false; 447 else 448 return HWC2::Error::BadParameter; 449 450 error = display_intf_->SetVSyncState(state); 451 452 if (error != kErrorNone) { 453 if (error == kErrorShutDown) { 454 shutdown_pending_ = true; 455 return HWC2::Error::None; 456 } 457 DLOGE("Failed. enabled = %s, error = %d", to_string(enabled).c_str(), error); 458 return HWC2::Error::BadDisplay; 459 } 460 461 return HWC2::Error::None; 462} 463 464HWC2::Error HWCDisplay::SetPowerMode(HWC2::PowerMode mode) { 465 DLOGV("display = %d, mode = %s", id_, to_string(mode).c_str()); 466 DisplayState state = kStateOff; 467 bool flush_on_error = flush_on_error_; 468 469 if (shutdown_pending_) { 470 return HWC2::Error::None; 471 } 472 473 switch (mode) { 474 case HWC2::PowerMode::Off: 475 // During power off, all of the buffers are released. 476 // Do not flush until a buffer is successfully submitted again. 477 flush_on_error = false; 478 state = kStateOff; 479 break; 480 case HWC2::PowerMode::On: 481 state = kStateOn; 482 last_power_mode_ = HWC2::PowerMode::On; 483 break; 484 case HWC2::PowerMode::Doze: 485 state = kStateDoze; 486 last_power_mode_ = HWC2::PowerMode::Doze; 487 break; 488 case HWC2::PowerMode::DozeSuspend: 489 state = kStateDozeSuspend; 490 last_power_mode_ = HWC2::PowerMode::DozeSuspend; 491 break; 492 default: 493 return HWC2::Error::BadParameter; 494 } 495 496 DisplayError error = display_intf_->SetDisplayState(state); 497 if (error == kErrorNone) { 498 flush_on_error_ = flush_on_error; 499 } else { 500 if (error == kErrorShutDown) { 501 shutdown_pending_ = true; 502 return HWC2::Error::None; 503 } 504 DLOGE("Set state failed. Error = %d", error); 505 return HWC2::Error::BadParameter; 506 } 507 508 return HWC2::Error::None; 509} 510 511HWC2::Error HWCDisplay::GetClientTargetSupport(uint32_t width, uint32_t height, int32_t format, 512 int32_t dataspace) { 513 DisplayConfigVariableInfo variable_config; 514 display_intf_->GetFrameBufferConfig(&variable_config); 515 // TODO(user): Support scaled configurations, other formats and other dataspaces 516 if (format != HAL_PIXEL_FORMAT_RGBA_8888 || dataspace != HAL_DATASPACE_UNKNOWN || 517 width != variable_config.x_pixels || height != variable_config.y_pixels) { 518 return HWC2::Error::Unsupported; 519 } else { 520 return HWC2::Error::None; 521 } 522} 523 524HWC2::Error HWCDisplay::GetColorModes(uint32_t *out_num_modes, android_color_mode_t *out_modes) { 525 if (out_modes) { 526 out_modes[0] = HAL_COLOR_MODE_NATIVE; 527 } 528 *out_num_modes = 1; 529 530 return HWC2::Error::None; 531} 532 533HWC2::Error HWCDisplay::GetDisplayConfigs(uint32_t *out_num_configs, hwc2_config_t *out_configs) { 534 // TODO(user): Actually handle multiple configs 535 if (out_configs == nullptr) { 536 *out_num_configs = 1; 537 } else { 538 *out_num_configs = 1; 539 out_configs[0] = 0; 540 } 541 542 return HWC2::Error::None; 543} 544 545HWC2::Error HWCDisplay::GetDisplayAttribute(hwc2_config_t config, HWC2::Attribute attribute, 546 int32_t *out_value) { 547 DisplayConfigVariableInfo variable_config; 548 DisplayError error = display_intf_->GetFrameBufferConfig(&variable_config); 549 if (error != kErrorNone) { 550 DLOGV("Get variable config failed. Error = %d", error); 551 return HWC2::Error::BadDisplay; 552 } 553 554 switch (attribute) { 555 case HWC2::Attribute::VsyncPeriod: 556 *out_value = INT32(variable_config.vsync_period_ns); 557 break; 558 case HWC2::Attribute::Width: 559 *out_value = INT32(variable_config.x_pixels); 560 break; 561 case HWC2::Attribute::Height: 562 *out_value = INT32(variable_config.y_pixels); 563 break; 564 case HWC2::Attribute::DpiX: 565 *out_value = INT32(variable_config.x_dpi * 1000.0f); 566 break; 567 case HWC2::Attribute::DpiY: 568 *out_value = INT32(variable_config.y_dpi * 1000.0f); 569 break; 570 default: 571 DLOGW("Spurious attribute type = %s", to_string(attribute).c_str()); 572 return HWC2::Error::BadConfig; 573 } 574 575 return HWC2::Error::None; 576} 577 578HWC2::Error HWCDisplay::GetDisplayName(uint32_t *out_size, char *out_name) { 579 // TODO(user): Get panel name and EDID name and populate it here 580 if (out_name == nullptr) { 581 *out_size = 32; 582 } else { 583 std::string name; 584 switch (id_) { 585 case HWC_DISPLAY_PRIMARY: 586 name = "Primary Display"; 587 break; 588 case HWC_DISPLAY_EXTERNAL: 589 name = "External Display"; 590 break; 591 case HWC_DISPLAY_VIRTUAL: 592 name = "Virtual Display"; 593 break; 594 default: 595 name = "Unknown"; 596 break; 597 } 598 std::strncpy(out_name, name.c_str(), name.size()); 599 *out_size = UINT32(name.size()); 600 } 601 return HWC2::Error::None; 602} 603 604HWC2::Error HWCDisplay::GetDisplayType(int32_t *out_type) { 605 if (out_type != nullptr) { 606 if (id_ == HWC_DISPLAY_VIRTUAL) { 607 *out_type = HWC2_DISPLAY_TYPE_VIRTUAL; 608 } else { 609 *out_type = HWC2_DISPLAY_TYPE_PHYSICAL; 610 } 611 return HWC2::Error::None; 612 } else { 613 return HWC2::Error::BadParameter; 614 } 615} 616 617// TODO(user): Store configurations and hook them up here 618HWC2::Error HWCDisplay::GetActiveConfig(hwc2_config_t *out_config) { 619 if (out_config != nullptr) { 620 *out_config = 0; 621 return HWC2::Error::None; 622 } else { 623 return HWC2::Error::BadParameter; 624 } 625} 626 627HWC2::Error HWCDisplay::SetClientTarget(buffer_handle_t target, int32_t acquire_fence, 628 int32_t dataspace, hwc_region_t damage) { 629 // TODO(user): SurfaceFlinger gives us a null pointer here when doing full SDE composition 630 // The error is problematic for layer caching as it would overwrite our cached client target. 631 // Reported bug 28569722 to resolve this. 632 // For now, continue to use the last valid buffer reported to us for layer caching. 633 if (target == nullptr) { 634 return HWC2::Error::None; 635 } 636 637 if (acquire_fence == 0) { 638 DLOGE("acquire_fence is zero"); 639 return HWC2::Error::BadParameter; 640 } 641 642 client_target_->SetLayerBuffer(target, acquire_fence); 643 client_target_->SetLayerSurfaceDamage(damage); 644 // Ignoring dataspace for now 645 return HWC2::Error::None; 646} 647 648HWC2::Error HWCDisplay::SetActiveConfig(hwc2_config_t config) { 649 // We have only one config right now - do nothing 650 return HWC2::Error::None; 651} 652 653DisplayError HWCDisplay::SetMixerResolution(uint32_t width, uint32_t height) { 654 return kErrorNotSupported; 655} 656 657void HWCDisplay::SetFrameDumpConfig(uint32_t count, uint32_t bit_mask_layer_type) { 658 dump_frame_count_ = count; 659 dump_frame_index_ = 0; 660 dump_input_layers_ = ((bit_mask_layer_type & (1 << INPUT_LAYER_DUMP)) != 0); 661 662 if (blit_engine_) { 663 blit_engine_->SetFrameDumpConfig(count); 664 } 665 666 DLOGI("num_frame_dump %d, input_layer_dump_enable %d", dump_frame_count_, dump_input_layers_); 667} 668 669HWC2::PowerMode HWCDisplay::GetLastPowerMode() { 670 return last_power_mode_; 671} 672 673DisplayError HWCDisplay::VSync(const DisplayEventVSync &vsync) { 674 callbacks_->Vsync(id_, vsync.timestamp); 675 return kErrorNone; 676} 677 678DisplayError HWCDisplay::Refresh() { 679 return kErrorNotSupported; 680} 681 682DisplayError HWCDisplay::CECMessage(char *message) { 683 if (qservice_) { 684 qservice_->onCECMessageReceived(message, 0); 685 } else { 686 DLOGW("Qservice instance not available."); 687 } 688 689 return kErrorNone; 690} 691 692HWC2::Error HWCDisplay::PrepareLayerStack(uint32_t *out_num_types, uint32_t *out_num_requests) { 693 layer_changes_.clear(); 694 layer_requests_.clear(); 695 if (shutdown_pending_) { 696 return HWC2::Error::BadDisplay; 697 } 698 699 if (!skip_prepare_) { 700 DisplayError error = display_intf_->Prepare(&layer_stack_); 701 if (error != kErrorNone) { 702 if (error == kErrorShutDown) { 703 shutdown_pending_ = true; 704 } else if (error != kErrorPermission) { 705 DLOGE("Prepare failed. Error = %d", error); 706 // To prevent surfaceflinger infinite wait, flush the previous frame during Commit() 707 // so that previous buffer and fences are released, and override the error. 708 flush_ = true; 709 } 710 return HWC2::Error::BadDisplay; 711 } 712 } else { 713 // Skip is not set 714 MarkLayersForGPUBypass(); 715 skip_prepare_ = false; 716 DLOGI("SecureDisplay %s, Skip Prepare/Commit and Flush", 717 secure_display_active_ ? "Starting" : "Stopping"); 718 flush_ = true; 719 } 720 721 for (auto hwc_layer : layer_set_) { 722 Layer *layer = hwc_layer->GetSDMLayer(); 723 LayerComposition &composition = layer->composition; 724 725 if ((composition == kCompositionSDE) || (composition == kCompositionHybrid) || 726 (composition == kCompositionBlit)) { 727 layer_requests_[hwc_layer->GetId()] = HWC2::LayerRequest::ClearClientTarget; 728 } 729 730 HWC2::Composition requested_composition = hwc_layer->GetClientRequestedCompositionType(); 731 // Set SDM composition to HWC2 type in HWCLayer 732 hwc_layer->SetComposition(composition); 733 HWC2::Composition device_composition = hwc_layer->GetDeviceSelectedCompositionType(); 734 // Update the changes list only if the requested composition is different from SDM comp type 735 // TODO(user): Take Care of other comptypes(BLIT) 736 if (requested_composition != device_composition) { 737 layer_changes_[hwc_layer->GetId()] = device_composition; 738 } 739 } 740 *out_num_types = UINT32(layer_changes_.size()); 741 *out_num_requests = UINT32(layer_requests_.size()); 742 validated_ = true; 743 if (*out_num_types > 0) { 744 return HWC2::Error::HasChanges; 745 } else { 746 return HWC2::Error::None; 747 } 748} 749 750HWC2::Error HWCDisplay::AcceptDisplayChanges() { 751 if (!validated_ && !layer_set_.empty()) { 752 return HWC2::Error::NotValidated; 753 } 754 return HWC2::Error::None; 755} 756 757HWC2::Error HWCDisplay::GetChangedCompositionTypes(uint32_t *out_num_elements, 758 hwc2_layer_t *out_layers, int32_t *out_types) { 759 if (layer_set_.empty()) { 760 return HWC2::Error::None; 761 } 762 763 if (!validated_) { 764 DLOGW("Display is not validated"); 765 return HWC2::Error::NotValidated; 766 } 767 *out_num_elements = UINT32(layer_changes_.size()); 768 if (out_layers != nullptr && out_types != nullptr) { 769 int i = 0; 770 for (auto change : layer_changes_) { 771 out_layers[i] = change.first; 772 out_types[i] = INT32(change.second); 773 i++; 774 } 775 } 776 return HWC2::Error::None; 777} 778 779HWC2::Error HWCDisplay::GetReleaseFences(uint32_t *out_num_elements, hwc2_layer_t *out_layers, 780 int32_t *out_fences) { 781 if (out_layers != nullptr && out_fences != nullptr) { 782 int i = 0; 783 for (auto hwc_layer : layer_set_) { 784 out_layers[i] = hwc_layer->GetId(); 785 out_fences[i] = hwc_layer->PopReleaseFence(); 786 i++; 787 } 788 } 789 *out_num_elements = UINT32(layer_set_.size()); 790 return HWC2::Error::None; 791} 792 793HWC2::Error HWCDisplay::GetDisplayRequests(int32_t *out_display_requests, 794 uint32_t *out_num_elements, hwc2_layer_t *out_layers, 795 int32_t *out_layer_requests) { 796 // No display requests for now 797 // Use for sharing blit buffers and 798 // writing wfd buffer directly to output if there is full GPU composition 799 // and no color conversion needed 800 if (layer_set_.empty()) { 801 return HWC2::Error::None; 802 } 803 804 if (!validated_) { 805 DLOGW("Display is not validated"); 806 return HWC2::Error::NotValidated; 807 } 808 *out_display_requests = 0; 809 *out_num_elements = UINT32(layer_requests_.size()); 810 if (out_layers != nullptr && out_layer_requests != nullptr) { 811 int i = 0; 812 for (auto &request : layer_requests_) { 813 out_layers[i] = request.first; 814 out_layer_requests[i] = INT32(request.second); 815 i++; 816 } 817 } 818 return HWC2::Error::None; 819} 820 821HWC2::Error HWCDisplay::CommitLayerStack(void) { 822 if (shutdown_pending_ || layer_set_.empty()) { 823 return HWC2::Error::None; 824 } 825 826 if (!validated_) { 827 DLOGW("Display is not validated"); 828 return HWC2::Error::NotValidated; 829 } 830 831 DumpInputBuffers(); 832 833 if (!flush_) { 834 DisplayError error = kErrorUndefined; 835 error = display_intf_->Commit(&layer_stack_); 836 validated_ = false; 837 838 if (error == kErrorNone) { 839 // A commit is successfully submitted, start flushing on failure now onwards. 840 flush_on_error_ = true; 841 } else { 842 if (error == kErrorShutDown) { 843 shutdown_pending_ = true; 844 return HWC2::Error::Unsupported; 845 } else if (error != kErrorPermission) { 846 DLOGE("Commit failed. Error = %d", error); 847 // To prevent surfaceflinger infinite wait, flush the previous frame during Commit() 848 // so that previous buffer and fences are released, and override the error. 849 flush_ = true; 850 } 851 } 852 } 853 854 return HWC2::Error::None; 855} 856 857HWC2::Error HWCDisplay::PostCommitLayerStack(int32_t *out_retire_fence) { 858 auto status = HWC2::Error::None; 859 860 // Do no call flush on errors, if a successful buffer is never submitted. 861 if (flush_ && flush_on_error_) { 862 display_intf_->Flush(); 863 } 864 865 // TODO(user): No way to set the client target release fence on SF 866 int32_t &client_target_release_fence = 867 client_target_->GetSDMLayer()->input_buffer->release_fence_fd; 868 if (client_target_release_fence >= 0) { 869 close(client_target_release_fence); 870 client_target_release_fence = -1; 871 } 872 873 for (auto hwc_layer : layer_set_) { 874 hwc_layer->ResetGeometryChanges(); 875 Layer *layer = hwc_layer->GetSDMLayer(); 876 LayerBuffer *layer_buffer = layer->input_buffer; 877 878 if (!flush_) { 879 // If swapinterval property is set to 0 or for single buffer layers, do not update f/w 880 // release fences and discard fences from driver 881 if (swap_interval_zero_ || layer->flags.single_buffer) { 882 close(layer_buffer->release_fence_fd); 883 layer_buffer->release_fence_fd = -1; 884 } else if (layer->composition != kCompositionGPU) { 885 hwc_layer->PushReleaseFence(layer_buffer->release_fence_fd); 886 layer_buffer->release_fence_fd = -1; 887 } else { 888 hwc_layer->PushReleaseFence(-1); 889 } 890 } 891 892 if (layer_buffer->acquire_fence_fd >= 0) { 893 close(layer_buffer->acquire_fence_fd); 894 layer_buffer->acquire_fence_fd = -1; 895 } 896 } 897 898 *out_retire_fence = -1; 899 if (!flush_) { 900 // if swapinterval property is set to 0 then close and reset the list retire fence 901 if (swap_interval_zero_) { 902 close(layer_stack_.retire_fence_fd); 903 layer_stack_.retire_fence_fd = -1; 904 } 905 *out_retire_fence = layer_stack_.retire_fence_fd; 906 907 if (dump_frame_count_) { 908 dump_frame_count_--; 909 dump_frame_index_++; 910 } 911 } 912 913 geometry_changes_ = GeometryChanges::kNone; 914 flush_ = false; 915 916 return status; 917} 918 919void HWCDisplay::SetIdleTimeoutMs(uint32_t timeout_ms) { 920 return; 921} 922 923DisplayError HWCDisplay::SetMaxMixerStages(uint32_t max_mixer_stages) { 924 DisplayError error = kErrorNone; 925 926 if (display_intf_) { 927 error = display_intf_->SetMaxMixerStages(max_mixer_stages); 928 } 929 930 return error; 931} 932 933LayerBufferFormat HWCDisplay::GetSDMFormat(const int32_t &source, const int flags) { 934 LayerBufferFormat format = kFormatInvalid; 935 if (flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED) { 936 switch (source) { 937 case HAL_PIXEL_FORMAT_RGBA_8888: 938 format = kFormatRGBA8888Ubwc; 939 break; 940 case HAL_PIXEL_FORMAT_RGBX_8888: 941 format = kFormatRGBX8888Ubwc; 942 break; 943 case HAL_PIXEL_FORMAT_BGR_565: 944 format = kFormatBGR565Ubwc; 945 break; 946 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS: 947 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC: 948 case HAL_PIXEL_FORMAT_NV12_ENCODEABLE: 949 format = kFormatYCbCr420SPVenusUbwc; 950 break; 951 case HAL_PIXEL_FORMAT_RGBA_1010102: 952 format = kFormatRGBA1010102Ubwc; 953 break; 954 case HAL_PIXEL_FORMAT_RGBX_1010102: 955 format = kFormatRGBX1010102Ubwc; 956 break; 957 case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC: 958 format = kFormatYCbCr420TP10Ubwc; 959 break; 960 default: 961 DLOGE("Unsupported format type for UBWC %d", source); 962 return kFormatInvalid; 963 } 964 return format; 965 } 966 967 switch (source) { 968 case HAL_PIXEL_FORMAT_RGBA_8888: 969 format = kFormatRGBA8888; 970 break; 971 case HAL_PIXEL_FORMAT_RGBA_5551: 972 format = kFormatRGBA5551; 973 break; 974 case HAL_PIXEL_FORMAT_RGBA_4444: 975 format = kFormatRGBA4444; 976 break; 977 case HAL_PIXEL_FORMAT_BGRA_8888: 978 format = kFormatBGRA8888; 979 break; 980 case HAL_PIXEL_FORMAT_RGBX_8888: 981 format = kFormatRGBX8888; 982 break; 983 case HAL_PIXEL_FORMAT_BGRX_8888: 984 format = kFormatBGRX8888; 985 break; 986 case HAL_PIXEL_FORMAT_RGB_888: 987 format = kFormatRGB888; 988 break; 989 case HAL_PIXEL_FORMAT_RGB_565: 990 format = kFormatRGB565; 991 break; 992 case HAL_PIXEL_FORMAT_BGR_565: 993 format = kFormatBGR565; 994 break; 995 case HAL_PIXEL_FORMAT_NV12_ENCODEABLE: 996 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS: 997 format = kFormatYCbCr420SemiPlanarVenus; 998 break; 999 case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS: 1000 format = kFormatYCrCb420SemiPlanarVenus; 1001 break; 1002 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC: 1003 format = kFormatYCbCr420SPVenusUbwc; 1004 break; 1005 case HAL_PIXEL_FORMAT_YV12: 1006 format = kFormatYCrCb420PlanarStride16; 1007 break; 1008 case HAL_PIXEL_FORMAT_YCrCb_420_SP: 1009 format = kFormatYCrCb420SemiPlanar; 1010 break; 1011 case HAL_PIXEL_FORMAT_YCbCr_420_SP: 1012 format = kFormatYCbCr420SemiPlanar; 1013 break; 1014 case HAL_PIXEL_FORMAT_YCbCr_422_SP: 1015 format = kFormatYCbCr422H2V1SemiPlanar; 1016 break; 1017 case HAL_PIXEL_FORMAT_YCbCr_422_I: 1018 format = kFormatYCbCr422H2V1Packed; 1019 break; 1020 case HAL_PIXEL_FORMAT_RGBA_1010102: 1021 format = kFormatRGBA1010102; 1022 break; 1023 case HAL_PIXEL_FORMAT_ARGB_2101010: 1024 format = kFormatARGB2101010; 1025 break; 1026 case HAL_PIXEL_FORMAT_RGBX_1010102: 1027 format = kFormatRGBX1010102; 1028 break; 1029 case HAL_PIXEL_FORMAT_XRGB_2101010: 1030 format = kFormatXRGB2101010; 1031 break; 1032 case HAL_PIXEL_FORMAT_BGRA_1010102: 1033 format = kFormatBGRA1010102; 1034 break; 1035 case HAL_PIXEL_FORMAT_ABGR_2101010: 1036 format = kFormatABGR2101010; 1037 break; 1038 case HAL_PIXEL_FORMAT_BGRX_1010102: 1039 format = kFormatBGRX1010102; 1040 break; 1041 case HAL_PIXEL_FORMAT_XBGR_2101010: 1042 format = kFormatXBGR2101010; 1043 break; 1044 case HAL_PIXEL_FORMAT_YCbCr_420_P010: 1045 format = kFormatYCbCr420P010; 1046 break; 1047 case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC: 1048 format = kFormatYCbCr420TP10Ubwc; 1049 break; 1050 default: 1051 DLOGW("Unsupported format type = %d", source); 1052 return kFormatInvalid; 1053 } 1054 1055 return format; 1056} 1057 1058void HWCDisplay::DumpInputBuffers() { 1059 char dir_path[PATH_MAX]; 1060 1061 if (!dump_frame_count_ || flush_ || !dump_input_layers_) { 1062 return; 1063 } 1064 1065 snprintf(dir_path, sizeof(dir_path), "/data/misc/display/frame_dump_%s", GetDisplayString()); 1066 1067 if (mkdir(dir_path, 0777) != 0 && errno != EEXIST) { 1068 DLOGW("Failed to create %s directory errno = %d, desc = %s", dir_path, errno, strerror(errno)); 1069 return; 1070 } 1071 1072 // if directory exists already, need to explicitly change the permission. 1073 if (errno == EEXIST && chmod(dir_path, 0777) != 0) { 1074 DLOGW("Failed to change permissions on %s directory", dir_path); 1075 return; 1076 } 1077 1078 for (uint32_t i = 0; i < layer_stack_.layers.size(); i++) { 1079 auto layer = layer_stack_.layers.at(i); 1080 const private_handle_t *pvt_handle = 1081 reinterpret_cast<const private_handle_t *>(layer->input_buffer->buffer_id); 1082 auto acquire_fence_fd = layer->input_buffer->acquire_fence_fd; 1083 1084 if (acquire_fence_fd >= 0) { 1085 int error = sync_wait(acquire_fence_fd, 1000); 1086 if (error < 0) { 1087 DLOGW("sync_wait error errno = %d, desc = %s", errno, strerror(errno)); 1088 return; 1089 } 1090 } 1091 1092 if (pvt_handle && pvt_handle->base) { 1093 char dump_file_name[PATH_MAX]; 1094 size_t result = 0; 1095 1096 snprintf(dump_file_name, sizeof(dump_file_name), "%s/input_layer%d_%dx%d_%s_frame%d.raw", 1097 dir_path, i, pvt_handle->width, pvt_handle->height, 1098 GetHALPixelFormatString(pvt_handle->format), dump_frame_index_); 1099 1100 FILE *fp = fopen(dump_file_name, "w+"); 1101 if (fp) { 1102 result = fwrite(reinterpret_cast<void *>(pvt_handle->base), pvt_handle->size, 1, fp); 1103 fclose(fp); 1104 } 1105 1106 DLOGI("Frame Dump %s: is %s", dump_file_name, result ? "Successful" : "Failed"); 1107 } 1108 } 1109} 1110 1111void HWCDisplay::DumpOutputBuffer(const BufferInfo &buffer_info, void *base, int fence) { 1112 char dir_path[PATH_MAX]; 1113 1114 snprintf(dir_path, sizeof(dir_path), "/data/misc/display/frame_dump_%s", GetDisplayString()); 1115 1116 if (mkdir(dir_path, 777) != 0 && errno != EEXIST) { 1117 DLOGW("Failed to create %s directory errno = %d, desc = %s", dir_path, errno, strerror(errno)); 1118 return; 1119 } 1120 1121 // if directory exists already, need to explicitly change the permission. 1122 if (errno == EEXIST && chmod(dir_path, 0777) != 0) { 1123 DLOGW("Failed to change permissions on %s directory", dir_path); 1124 return; 1125 } 1126 1127 if (base) { 1128 char dump_file_name[PATH_MAX]; 1129 size_t result = 0; 1130 1131 if (fence >= 0) { 1132 int error = sync_wait(fence, 1000); 1133 if (error < 0) { 1134 DLOGW("sync_wait error errno = %d, desc = %s", errno, strerror(errno)); 1135 return; 1136 } 1137 } 1138 1139 snprintf(dump_file_name, sizeof(dump_file_name), "%s/output_layer_%dx%d_%s_frame%d.raw", 1140 dir_path, buffer_info.buffer_config.width, buffer_info.buffer_config.height, 1141 GetFormatString(buffer_info.buffer_config.format), dump_frame_index_); 1142 1143 FILE *fp = fopen(dump_file_name, "w+"); 1144 if (fp) { 1145 result = fwrite(base, buffer_info.alloc_buffer_info.size, 1, fp); 1146 fclose(fp); 1147 } 1148 1149 DLOGI("Frame Dump of %s is %s", dump_file_name, result ? "Successful" : "Failed"); 1150 } 1151} 1152 1153const char *HWCDisplay::GetHALPixelFormatString(int format) { 1154 switch (format) { 1155 case HAL_PIXEL_FORMAT_RGBA_8888: 1156 return "RGBA_8888"; 1157 case HAL_PIXEL_FORMAT_RGBX_8888: 1158 return "RGBX_8888"; 1159 case HAL_PIXEL_FORMAT_RGB_888: 1160 return "RGB_888"; 1161 case HAL_PIXEL_FORMAT_RGB_565: 1162 return "RGB_565"; 1163 case HAL_PIXEL_FORMAT_BGR_565: 1164 return "BGR_565"; 1165 case HAL_PIXEL_FORMAT_BGRA_8888: 1166 return "BGRA_8888"; 1167 case HAL_PIXEL_FORMAT_RGBA_5551: 1168 return "RGBA_5551"; 1169 case HAL_PIXEL_FORMAT_RGBA_4444: 1170 return "RGBA_4444"; 1171 case HAL_PIXEL_FORMAT_YV12: 1172 return "YV12"; 1173 case HAL_PIXEL_FORMAT_YCbCr_422_SP: 1174 return "YCbCr_422_SP_NV16"; 1175 case HAL_PIXEL_FORMAT_YCrCb_420_SP: 1176 return "YCrCb_420_SP_NV21"; 1177 case HAL_PIXEL_FORMAT_YCbCr_422_I: 1178 return "YCbCr_422_I_YUY2"; 1179 case HAL_PIXEL_FORMAT_YCrCb_422_I: 1180 return "YCrCb_422_I_YVYU"; 1181 case HAL_PIXEL_FORMAT_NV12_ENCODEABLE: 1182 return "NV12_ENCODEABLE"; 1183 case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED: 1184 return "YCbCr_420_SP_TILED_TILE_4x2"; 1185 case HAL_PIXEL_FORMAT_YCbCr_420_SP: 1186 return "YCbCr_420_SP"; 1187 case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO: 1188 return "YCrCb_420_SP_ADRENO"; 1189 case HAL_PIXEL_FORMAT_YCrCb_422_SP: 1190 return "YCrCb_422_SP"; 1191 case HAL_PIXEL_FORMAT_R_8: 1192 return "R_8"; 1193 case HAL_PIXEL_FORMAT_RG_88: 1194 return "RG_88"; 1195 case HAL_PIXEL_FORMAT_INTERLACE: 1196 return "INTERLACE"; 1197 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS: 1198 return "YCbCr_420_SP_VENUS"; 1199 case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS: 1200 return "YCrCb_420_SP_VENUS"; 1201 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC: 1202 return "YCbCr_420_SP_VENUS_UBWC"; 1203 case HAL_PIXEL_FORMAT_RGBA_1010102: 1204 return "RGBA_1010102"; 1205 case HAL_PIXEL_FORMAT_ARGB_2101010: 1206 return "ARGB_2101010"; 1207 case HAL_PIXEL_FORMAT_RGBX_1010102: 1208 return "RGBX_1010102"; 1209 case HAL_PIXEL_FORMAT_XRGB_2101010: 1210 return "XRGB_2101010"; 1211 case HAL_PIXEL_FORMAT_BGRA_1010102: 1212 return "BGRA_1010102"; 1213 case HAL_PIXEL_FORMAT_ABGR_2101010: 1214 return "ABGR_2101010"; 1215 case HAL_PIXEL_FORMAT_BGRX_1010102: 1216 return "BGRX_1010102"; 1217 case HAL_PIXEL_FORMAT_XBGR_2101010: 1218 return "XBGR_2101010"; 1219 case HAL_PIXEL_FORMAT_YCbCr_420_P010: 1220 return "YCbCr_420_P010"; 1221 case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC: 1222 return "YCbCr_420_TP10_UBWC"; 1223 default: 1224 return "Unknown_format"; 1225 } 1226} 1227 1228const char *HWCDisplay::GetDisplayString() { 1229 switch (type_) { 1230 case kPrimary: 1231 return "primary"; 1232 case kHDMI: 1233 return "hdmi"; 1234 case kVirtual: 1235 return "virtual"; 1236 default: 1237 return "invalid"; 1238 } 1239} 1240 1241int HWCDisplay::SetFrameBufferResolution(uint32_t x_pixels, uint32_t y_pixels) { 1242 if (x_pixels <= 0 || y_pixels <= 0) { 1243 DLOGW("Unsupported config: x_pixels=%d, y_pixels=%d", x_pixels, y_pixels); 1244 return -EINVAL; 1245 } 1246 1247 DisplayConfigVariableInfo fb_config; 1248 DisplayError error = display_intf_->GetFrameBufferConfig(&fb_config); 1249 if (error != kErrorNone) { 1250 DLOGV("Get frame buffer config failed. Error = %d", error); 1251 return -EINVAL; 1252 } 1253 1254 fb_config.x_pixels = x_pixels; 1255 fb_config.y_pixels = y_pixels; 1256 1257 error = display_intf_->SetFrameBufferConfig(fb_config); 1258 if (error != kErrorNone) { 1259 DLOGV("Set frame buffer config failed. Error = %d", error); 1260 return -EINVAL; 1261 } 1262 1263 // Create rects to represent the new source and destination crops 1264 LayerRect crop = LayerRect(0, 0, FLOAT(x_pixels), FLOAT(y_pixels)); 1265 LayerRect dst = LayerRect(0, 0, FLOAT(fb_config.x_pixels), FLOAT(fb_config.y_pixels)); 1266 auto client_target_layer = client_target_->GetSDMLayer(); 1267 client_target_layer->src_rect = crop; 1268 client_target_layer->dst_rect = dst; 1269 1270 int aligned_width; 1271 int aligned_height; 1272 int usage = GRALLOC_USAGE_HW_FB; 1273 int format = HAL_PIXEL_FORMAT_RGBA_8888; 1274 int ubwc_enabled = 0; 1275 int flags = 0; 1276 HWCDebugHandler::Get()->GetProperty("debug.gralloc.enable_fb_ubwc", &ubwc_enabled); 1277 if (ubwc_enabled == 1) { 1278 usage |= GRALLOC_USAGE_PRIVATE_ALLOC_UBWC; 1279 flags |= private_handle_t::PRIV_FLAGS_UBWC_ALIGNED; 1280 } 1281 AdrenoMemInfo::getInstance().getAlignedWidthAndHeight(INT(x_pixels), INT(y_pixels), format, usage, 1282 aligned_width, aligned_height); 1283 1284 // TODO(user): How does the dirty region get set on the client target? File bug on Google 1285 client_target_layer->composition = kCompositionGPUTarget; 1286 client_target_layer->input_buffer->format = GetSDMFormat(format, flags); 1287 client_target_layer->input_buffer->width = UINT32(aligned_width); 1288 client_target_layer->input_buffer->height = UINT32(aligned_height); 1289 client_target_layer->plane_alpha = 255; 1290 1291 DLOGI("New framebuffer resolution (%dx%d)", fb_config.x_pixels, fb_config.y_pixels); 1292 1293 return 0; 1294} 1295 1296void HWCDisplay::GetFrameBufferResolution(uint32_t *x_pixels, uint32_t *y_pixels) { 1297 DisplayConfigVariableInfo fb_config; 1298 display_intf_->GetFrameBufferConfig(&fb_config); 1299 1300 *x_pixels = fb_config.x_pixels; 1301 *y_pixels = fb_config.y_pixels; 1302} 1303 1304DisplayError HWCDisplay::GetMixerResolution(uint32_t *x_pixels, uint32_t *y_pixels) { 1305 return display_intf_->GetMixerResolution(x_pixels, y_pixels); 1306} 1307 1308void HWCDisplay::GetPanelResolution(uint32_t *x_pixels, uint32_t *y_pixels) { 1309 DisplayConfigVariableInfo display_config; 1310 uint32_t active_index = 0; 1311 1312 display_intf_->GetActiveConfig(&active_index); 1313 display_intf_->GetConfig(active_index, &display_config); 1314 1315 *x_pixels = display_config.x_pixels; 1316 *y_pixels = display_config.y_pixels; 1317} 1318 1319int HWCDisplay::SetDisplayStatus(uint32_t display_status) { 1320 int status = 0; 1321 1322 switch (display_status) { 1323 case kDisplayStatusResume: 1324 display_paused_ = false; 1325 case kDisplayStatusOnline: 1326 status = INT32(SetPowerMode(HWC2::PowerMode::On)); 1327 break; 1328 case kDisplayStatusPause: 1329 display_paused_ = true; 1330 case kDisplayStatusOffline: 1331 status = INT32(SetPowerMode(HWC2::PowerMode::Off)); 1332 break; 1333 default: 1334 DLOGW("Invalid display status %d", display_status); 1335 return -EINVAL; 1336 } 1337 1338 if (display_status == kDisplayStatusResume || display_status == kDisplayStatusPause) { 1339 callbacks_->Refresh(HWC_DISPLAY_PRIMARY); 1340 } 1341 1342 return status; 1343} 1344 1345HWC2::Error HWCDisplay::SetCursorPosition(hwc2_layer_t layer, int x, int y) { 1346 if (shutdown_pending_) { 1347 return HWC2::Error::None; 1348 } 1349 1350 // TODO(user): Validate layer 1351 // TODO(user): Check if we're in a validate/present cycle 1352 1353 auto error = display_intf_->SetCursorPosition(x, y); 1354 if (error != kErrorNone) { 1355 if (error == kErrorShutDown) { 1356 shutdown_pending_ = true; 1357 return HWC2::Error::None; 1358 } 1359 1360 DLOGE("Failed for x = %d y = %d, Error = %d", x, y, error); 1361 return HWC2::Error::BadDisplay; 1362 } 1363 1364 return HWC2::Error::None; 1365} 1366 1367int HWCDisplay::OnMinHdcpEncryptionLevelChange(uint32_t min_enc_level) { 1368 DisplayError error = display_intf_->OnMinHdcpEncryptionLevelChange(min_enc_level); 1369 if (error != kErrorNone) { 1370 DLOGE("Failed. Error = %d", error); 1371 return -1; 1372 } 1373 1374 return 0; 1375} 1376 1377void HWCDisplay::MarkLayersForGPUBypass() { 1378 for (auto hwc_layer : layer_set_) { 1379 auto layer = hwc_layer->GetSDMLayer(); 1380 layer->composition = kCompositionSDE; 1381 } 1382} 1383 1384void HWCDisplay::MarkLayersForClientComposition() { 1385 // ClientComposition - GPU comp, to acheive this, set skip flag so that 1386 // SDM does not handle this layer and hwc_layer composition will be 1387 // set correctly at the end of Prepare. 1388 for (auto hwc_layer : layer_set_) { 1389 Layer *layer = hwc_layer->GetSDMLayer(); 1390 layer->flags.skip = true; 1391 } 1392} 1393 1394void HWCDisplay::ApplyScanAdjustment(hwc_rect_t *display_frame) { 1395} 1396 1397int HWCDisplay::SetPanelBrightness(int level) { 1398 int ret = 0; 1399 if (display_intf_) 1400 ret = display_intf_->SetPanelBrightness(level); 1401 else 1402 ret = -EINVAL; 1403 1404 return ret; 1405} 1406 1407int HWCDisplay::GetPanelBrightness(int *level) { 1408 return display_intf_->GetPanelBrightness(level); 1409} 1410 1411int HWCDisplay::ToggleScreenUpdates(bool enable) { 1412 display_paused_ = enable ? false : true; 1413 callbacks_->Refresh(HWC_DISPLAY_PRIMARY); 1414 return 0; 1415} 1416 1417int HWCDisplay::ColorSVCRequestRoute(const PPDisplayAPIPayload &in_payload, 1418 PPDisplayAPIPayload *out_payload, 1419 PPPendingParams *pending_action) { 1420 int ret = 0; 1421 1422 if (display_intf_) 1423 ret = display_intf_->ColorSVCRequestRoute(in_payload, out_payload, pending_action); 1424 else 1425 ret = -EINVAL; 1426 1427 return ret; 1428} 1429 1430void HWCDisplay::SolidFillPrepare() { 1431 if (solid_fill_enable_) { 1432 if (solid_fill_layer_ == NULL) { 1433 // Create a dummy layer here 1434 solid_fill_layer_ = new Layer(); 1435 solid_fill_layer_->input_buffer = new LayerBuffer(); 1436 } 1437 uint32_t primary_width = 0, primary_height = 0; 1438 GetMixerResolution(&primary_width, &primary_height); 1439 1440 LayerBuffer *layer_buffer = solid_fill_layer_->input_buffer; 1441 layer_buffer->width = primary_width; 1442 layer_buffer->height = primary_height; 1443 layer_buffer->acquire_fence_fd = -1; 1444 layer_buffer->release_fence_fd = -1; 1445 1446 LayerRect rect; 1447 rect.top = 0; rect.left = 0; 1448 rect.right = primary_width; 1449 rect.bottom = primary_height; 1450 1451 solid_fill_layer_->composition = kCompositionGPU; 1452 solid_fill_layer_->src_rect = rect; 1453 solid_fill_layer_->dst_rect = rect; 1454 1455 solid_fill_layer_->blending = kBlendingPremultiplied; 1456 solid_fill_layer_->solid_fill_color = solid_fill_color_; 1457 solid_fill_layer_->frame_rate = 60; 1458 solid_fill_layer_->visible_regions.push_back(solid_fill_layer_->dst_rect); 1459 solid_fill_layer_->flags.updating = 1; 1460 solid_fill_layer_->flags.solid_fill = true; 1461 } else { 1462 // delete the dummy layer 1463 if (solid_fill_layer_) { 1464 delete solid_fill_layer_->input_buffer; 1465 } 1466 delete solid_fill_layer_; 1467 solid_fill_layer_ = NULL; 1468 } 1469 1470 if (solid_fill_enable_ && solid_fill_layer_) { 1471 BuildSolidFillStack(); 1472 MarkLayersForGPUBypass(); 1473 } 1474 1475 return; 1476} 1477 1478void HWCDisplay::SolidFillCommit() { 1479 if (solid_fill_enable_ && solid_fill_layer_) { 1480 LayerBuffer *layer_buffer = solid_fill_layer_->input_buffer; 1481 if (layer_buffer->release_fence_fd > 0) { 1482 close(layer_buffer->release_fence_fd); 1483 layer_buffer->release_fence_fd = -1; 1484 } 1485 if (layer_stack_.retire_fence_fd > 0) { 1486 close(layer_stack_.retire_fence_fd); 1487 layer_stack_.retire_fence_fd = -1; 1488 } 1489 } 1490} 1491 1492int HWCDisplay::GetVisibleDisplayRect(hwc_rect_t *visible_rect) { 1493 if (!IsValid(display_rect_)) { 1494 return -EINVAL; 1495 } 1496 1497 visible_rect->left = INT(display_rect_.left); 1498 visible_rect->top = INT(display_rect_.top); 1499 visible_rect->right = INT(display_rect_.right); 1500 visible_rect->bottom = INT(display_rect_.bottom); 1501 DLOGI("Dpy = %d Visible Display Rect(%d %d %d %d)", visible_rect->left, visible_rect->top, 1502 visible_rect->right, visible_rect->bottom); 1503 1504 return 0; 1505} 1506 1507void HWCDisplay::SetSecureDisplay(bool secure_display_active) { 1508 secure_display_active_ = secure_display_active; 1509 return; 1510} 1511 1512int HWCDisplay::SetActiveDisplayConfig(int config) { 1513 return display_intf_->SetActiveConfig(UINT32(config)) == kErrorNone ? 0 : -1; 1514} 1515 1516int HWCDisplay::GetActiveDisplayConfig(uint32_t *config) { 1517 return display_intf_->GetActiveConfig(config) == kErrorNone ? 0 : -1; 1518} 1519 1520int HWCDisplay::GetDisplayConfigCount(uint32_t *count) { 1521 return display_intf_->GetNumVariableInfoConfigs(count) == kErrorNone ? 0 : -1; 1522} 1523 1524int HWCDisplay::GetDisplayAttributesForConfig(int config, 1525 DisplayConfigVariableInfo *display_attributes) { 1526 return display_intf_->GetConfig(UINT32(config), display_attributes) == kErrorNone ? 0 : -1; 1527} 1528 1529bool HWCDisplay::SingleLayerUpdating(void) { 1530 uint32_t updating_count = 0; 1531 1532 for (uint i = 0; i < layer_stack_.layers.size(); i++) { 1533 auto layer = layer_stack_.layers.at(i); 1534 if (layer->flags.updating) { 1535 updating_count++; 1536 } 1537 } 1538 1539 return (updating_count == 1); 1540} 1541 1542bool HWCDisplay::IsLayerUpdating(const Layer *layer) { 1543 // Layer should be considered updating if 1544 // a) layer is in single buffer mode, or 1545 // b) valid dirty_regions(android specific hint for updating status), or 1546 // c) layer stack geometry has changed (TODO(user): Remove when SDM accepts 1547 // geometry_changed as bit fields). 1548 return (layer->flags.single_buffer || IsSurfaceUpdated(layer->dirty_regions) || 1549 geometry_changes_); 1550} 1551 1552bool HWCDisplay::IsSurfaceUpdated(const std::vector<LayerRect> &dirty_regions) { 1553 // based on dirty_regions determine if its updating 1554 // dirty_rect count = 0 - whole layer - updating. 1555 // dirty_rect count = 1 or more valid rects - updating. 1556 // dirty_rect count = 1 with (0,0,0,0) - not updating. 1557 return (dirty_regions.empty() || IsValid(dirty_regions.at(0))); 1558} 1559 1560uint32_t HWCDisplay::SanitizeRefreshRate(uint32_t req_refresh_rate) { 1561 uint32_t refresh_rate = req_refresh_rate; 1562 1563 if (refresh_rate < min_refresh_rate_) { 1564 // Pick the next multiple of request which is within the range 1565 refresh_rate = 1566 (((min_refresh_rate_ / refresh_rate) + ((min_refresh_rate_ % refresh_rate) ? 1 : 0)) * 1567 refresh_rate); 1568 } 1569 1570 if (refresh_rate > max_refresh_rate_) { 1571 refresh_rate = max_refresh_rate_; 1572 } 1573 1574 return refresh_rate; 1575} 1576 1577DisplayClass HWCDisplay::GetDisplayClass() { 1578 return display_class_; 1579} 1580 1581void HWCDisplay::CloseAcquireFds() { 1582 for (auto hwc_layer : layer_set_) { 1583 auto layer = hwc_layer->GetSDMLayer(); 1584 if (layer->input_buffer->acquire_fence_fd >= 0) { 1585 close(layer->input_buffer->acquire_fence_fd); 1586 layer->input_buffer->acquire_fence_fd = -1; 1587 } 1588 } 1589 int32_t &client_target_acquire_fence = 1590 client_target_->GetSDMLayer()->input_buffer->acquire_fence_fd; 1591 if (client_target_acquire_fence >= 0) { 1592 close(client_target_acquire_fence); 1593 client_target_acquire_fence = -1; 1594 } 1595} 1596 1597std::string HWCDisplay::Dump() { 1598 std::ostringstream os; 1599 os << "-------------------------------" << std::endl; 1600 os << "HWC2 LayerDump display_id: " << id_ << std::endl; 1601 for (auto layer : layer_set_) { 1602 auto sdm_layer = layer->GetSDMLayer(); 1603 auto transform = sdm_layer->transform; 1604 os << "-------------------------------" << std::endl; 1605 os << "layer_id: " << layer->GetId() << std::endl; 1606 os << "\tz: " << layer->GetZ() << std::endl; 1607 os << "\tclient(SF) composition: " << 1608 to_string(layer->GetClientRequestedCompositionType()).c_str() << std::endl; 1609 os << "\tdevice(SDM) composition: " << 1610 to_string(layer->GetDeviceSelectedCompositionType()).c_str() << std::endl; 1611 os << "\tplane_alpha: " << std::to_string(sdm_layer->plane_alpha).c_str() << std::endl; 1612 os << "\tformat: " << GetFormatString(sdm_layer->input_buffer->format) << std::endl; 1613 os << "\ttransform: rot: " << transform.rotation << " flip_h: " << transform.flip_horizontal << 1614 " flip_v: "<< transform.flip_vertical << std::endl; 1615 os << "\tbuffer_id: " << std::hex << "0x" << sdm_layer->input_buffer->buffer_id << std::dec 1616 << std::endl; 1617 } 1618 return os.str(); 1619} 1620} // namespace sdm 1621