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 48 namespace sdm { 49 50 static 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 59 HWCColorMode::HWCColorMode(DisplayInterface *display_intf) : display_intf_(display_intf) {} 60 61 HWC2::Error HWCColorMode::Init() { 62 PopulateColorModes(); 63 return SetColorMode(HAL_COLOR_MODE_NATIVE); 64 } 65 66 HWC2::Error HWCColorMode::DeInit() { 67 color_mode_transform_map_.clear(); 68 return HWC2::Error::None; 69 } 70 71 uint32_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 78 HWC2::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 89 HWC2::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 99 HWC2::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 115 HWC2::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 162 void 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 DLOGV_IF(kTagQDCM, "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 DLOGV_IF(kTagQDCM, "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 192 void 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 212 HWCDisplay::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 224 int 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 261 int 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 285 HWC2::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 293 HWCLayer *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 303 HWC2::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 324 void 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 layer->flags = {}; // Reset earlier flags 334 if (hwc_layer->GetClientRequestedCompositionType() == HWC2::Composition::Client) { 335 layer->flags.skip = true; 336 } else if (hwc_layer->GetClientRequestedCompositionType() == HWC2::Composition::SolidColor) { 337 layer->flags.solid_fill = true; 338 } 339 340 // set default composition as GPU for SDM 341 layer->composition = kCompositionGPU; 342 343 if (swap_interval_zero_) { 344 if (layer->input_buffer->acquire_fence_fd >= 0) { 345 close(layer->input_buffer->acquire_fence_fd); 346 layer->input_buffer->acquire_fence_fd = -1; 347 } 348 } 349 350 const private_handle_t *handle = 351 reinterpret_cast<const private_handle_t *>(layer->input_buffer->buffer_id); 352 if (handle) { 353 if (handle->bufferType == BUFFER_TYPE_VIDEO) { 354 layer_stack_.flags.video_present = true; 355 } 356 // TZ Protected Buffer - L1 357 if (handle->flags & private_handle_t::PRIV_FLAGS_SECURE_BUFFER) { 358 layer_stack_.flags.secure_present = true; 359 } 360 // Gralloc Usage Protected Buffer - L3 - which needs to be treated as Secure & avoid fallback 361 if (handle->flags & private_handle_t::PRIV_FLAGS_PROTECTED_BUFFER) { 362 layer_stack_.flags.secure_present = true; 363 } 364 } 365 366 if (layer->flags.skip) { 367 layer_stack_.flags.skip_present = true; 368 } 369 370 371 if (hwc_layer->GetClientRequestedCompositionType() == HWC2::Composition::Cursor) { 372 // Currently we support only one HWCursor & only at top most z-order 373 if ((*layer_set_.rbegin())->GetId() == hwc_layer->GetId()) { 374 layer->flags.cursor = true; 375 layer_stack_.flags.cursor_present = true; 376 } 377 } 378 379 // TODO(user): Move to a getter if this is needed at other places 380 hwc_rect_t scaled_display_frame = {INT(layer->dst_rect.left), INT(layer->dst_rect.top), 381 INT(layer->dst_rect.right), INT(layer->dst_rect.bottom)}; 382 ApplyScanAdjustment(&scaled_display_frame); 383 hwc_layer->SetLayerDisplayFrame(scaled_display_frame); 384 ApplyDeInterlaceAdjustment(layer); 385 // SDM requires these details even for solid fill 386 if (layer->flags.solid_fill) { 387 LayerBuffer *layer_buffer = layer->input_buffer; 388 uint32_t display_width = 0, display_height = 0; 389 GetMixerResolution(&display_width, &display_height); 390 layer_buffer->width = display_width; 391 layer_buffer->height = display_height; 392 layer_buffer->acquire_fence_fd = -1; 393 layer_buffer->release_fence_fd = -1; 394 layer->src_rect = layer->dst_rect; 395 } 396 397 if (layer->frame_rate > metadata_refresh_rate_) { 398 metadata_refresh_rate_ = SanitizeRefreshRate(layer->frame_rate); 399 } else { 400 layer->frame_rate = current_refresh_rate_; 401 } 402 display_rect_ = Union(display_rect_, layer->dst_rect); 403 geometry_changes_ |= hwc_layer->GetGeometryChanges(); 404 405 layer->flags.updating = true; 406 if (layer_set_.size() <= kMaxLayerCount) { 407 layer->flags.updating = IsLayerUpdating(layer); 408 } 409 410 layer_stack_.layers.push_back(layer); 411 } 412 // TODO(user): Set correctly when SDM supports geometry_changes as bitmask 413 layer_stack_.flags.geometry_changed = UINT32(geometry_changes_ > 0); 414 // Append client target to the layer stack 415 layer_stack_.layers.push_back(client_target_->GetSDMLayer()); 416 } 417 418 void HWCDisplay::BuildSolidFillStack() { 419 layer_stack_ = LayerStack(); 420 display_rect_ = LayerRect(); 421 422 layer_stack_.layers.push_back(solid_fill_layer_); 423 layer_stack_.flags.geometry_changed = 1U; 424 // Append client target to the layer stack 425 layer_stack_.layers.push_back(client_target_->GetSDMLayer()); 426 } 427 428 HWC2::Error HWCDisplay::SetLayerZOrder(hwc2_layer_t layer_id, uint32_t z) { 429 const auto map_layer = layer_map_.find(layer_id); 430 if (map_layer == layer_map_.end()) { 431 DLOGE("[%" PRIu64 "] updateLayerZ failed to find layer", id_); 432 return HWC2::Error::BadLayer; 433 } 434 435 const auto layer = map_layer->second; 436 const auto z_range = layer_set_.equal_range(layer); 437 bool layer_on_display = false; 438 for (auto current = z_range.first; current != z_range.second; ++current) { 439 if (*current == layer) { 440 if ((*current)->GetZ() == z) { 441 // Don't change anything if the Z hasn't changed 442 return HWC2::Error::None; 443 } 444 current = layer_set_.erase(current); 445 layer_on_display = true; 446 break; 447 } 448 } 449 450 if (!layer_on_display) { 451 DLOGE("[%" PRIu64 "] updateLayerZ failed to find layer on display", id_); 452 return HWC2::Error::BadLayer; 453 } 454 455 layer->SetLayerZOrder(z); 456 layer_set_.emplace(layer); 457 return HWC2::Error::None; 458 } 459 460 HWC2::Error HWCDisplay::SetVsyncEnabled(HWC2::Vsync enabled) { 461 DLOGV("Display ID: %d enabled: %s", id_, to_string(enabled).c_str()); 462 DisplayError error = kErrorNone; 463 464 if (shutdown_pending_) { 465 return HWC2::Error::None; 466 } 467 468 bool state; 469 if (enabled == HWC2::Vsync::Enable) 470 state = true; 471 else if (enabled == HWC2::Vsync::Disable) 472 state = false; 473 else 474 return HWC2::Error::BadParameter; 475 476 error = display_intf_->SetVSyncState(state); 477 478 if (error != kErrorNone) { 479 if (error == kErrorShutDown) { 480 shutdown_pending_ = true; 481 return HWC2::Error::None; 482 } 483 DLOGE("Failed. enabled = %s, error = %d", to_string(enabled).c_str(), error); 484 return HWC2::Error::BadDisplay; 485 } 486 487 return HWC2::Error::None; 488 } 489 490 HWC2::Error HWCDisplay::SetPowerMode(HWC2::PowerMode mode) { 491 DLOGV("display = %d, mode = %s", id_, to_string(mode).c_str()); 492 DisplayState state = kStateOff; 493 bool flush_on_error = flush_on_error_; 494 495 if (shutdown_pending_) { 496 return HWC2::Error::None; 497 } 498 499 switch (mode) { 500 case HWC2::PowerMode::Off: 501 // During power off, all of the buffers are released. 502 // Do not flush until a buffer is successfully submitted again. 503 flush_on_error = false; 504 state = kStateOff; 505 break; 506 case HWC2::PowerMode::On: 507 state = kStateOn; 508 last_power_mode_ = HWC2::PowerMode::On; 509 break; 510 case HWC2::PowerMode::Doze: 511 state = kStateDoze; 512 last_power_mode_ = HWC2::PowerMode::Doze; 513 break; 514 case HWC2::PowerMode::DozeSuspend: 515 state = kStateDozeSuspend; 516 last_power_mode_ = HWC2::PowerMode::DozeSuspend; 517 break; 518 default: 519 return HWC2::Error::BadParameter; 520 } 521 522 DisplayError error = display_intf_->SetDisplayState(state); 523 if (error == kErrorNone) { 524 flush_on_error_ = flush_on_error; 525 } else { 526 if (error == kErrorShutDown) { 527 shutdown_pending_ = true; 528 return HWC2::Error::None; 529 } 530 DLOGE("Set state failed. Error = %d", error); 531 return HWC2::Error::BadParameter; 532 } 533 534 return HWC2::Error::None; 535 } 536 537 HWC2::Error HWCDisplay::GetClientTargetSupport(uint32_t width, uint32_t height, int32_t format, 538 int32_t dataspace) { 539 DisplayConfigVariableInfo variable_config; 540 display_intf_->GetFrameBufferConfig(&variable_config); 541 // TODO(user): Support scaled configurations, other formats and other dataspaces 542 if (format != HAL_PIXEL_FORMAT_RGBA_8888 || dataspace != HAL_DATASPACE_UNKNOWN || 543 width != variable_config.x_pixels || height != variable_config.y_pixels) { 544 return HWC2::Error::Unsupported; 545 } else { 546 return HWC2::Error::None; 547 } 548 } 549 550 HWC2::Error HWCDisplay::GetColorModes(uint32_t *out_num_modes, android_color_mode_t *out_modes) { 551 if (out_modes) { 552 out_modes[0] = HAL_COLOR_MODE_NATIVE; 553 } 554 *out_num_modes = 1; 555 556 return HWC2::Error::None; 557 } 558 559 HWC2::Error HWCDisplay::GetDisplayConfigs(uint32_t *out_num_configs, hwc2_config_t *out_configs) { 560 // TODO(user): Actually handle multiple configs 561 if (out_configs == nullptr) { 562 *out_num_configs = 1; 563 } else { 564 *out_num_configs = 1; 565 out_configs[0] = 0; 566 } 567 568 return HWC2::Error::None; 569 } 570 571 HWC2::Error HWCDisplay::GetDisplayAttribute(hwc2_config_t config, HWC2::Attribute attribute, 572 int32_t *out_value) { 573 DisplayConfigVariableInfo variable_config; 574 DisplayError error = display_intf_->GetFrameBufferConfig(&variable_config); 575 if (error != kErrorNone) { 576 DLOGV("Get variable config failed. Error = %d", error); 577 return HWC2::Error::BadDisplay; 578 } 579 580 switch (attribute) { 581 case HWC2::Attribute::VsyncPeriod: 582 *out_value = INT32(variable_config.vsync_period_ns); 583 break; 584 case HWC2::Attribute::Width: 585 *out_value = INT32(variable_config.x_pixels); 586 break; 587 case HWC2::Attribute::Height: 588 *out_value = INT32(variable_config.y_pixels); 589 break; 590 case HWC2::Attribute::DpiX: 591 *out_value = INT32(variable_config.x_dpi * 1000.0f); 592 break; 593 case HWC2::Attribute::DpiY: 594 *out_value = INT32(variable_config.y_dpi * 1000.0f); 595 break; 596 default: 597 DLOGW("Spurious attribute type = %s", to_string(attribute).c_str()); 598 return HWC2::Error::BadConfig; 599 } 600 601 return HWC2::Error::None; 602 } 603 604 HWC2::Error HWCDisplay::GetDisplayName(uint32_t *out_size, char *out_name) { 605 // TODO(user): Get panel name and EDID name and populate it here 606 if (out_name == nullptr) { 607 *out_size = 32; 608 } else { 609 std::string name; 610 switch (id_) { 611 case HWC_DISPLAY_PRIMARY: 612 name = "Primary Display"; 613 break; 614 case HWC_DISPLAY_EXTERNAL: 615 name = "External Display"; 616 break; 617 case HWC_DISPLAY_VIRTUAL: 618 name = "Virtual Display"; 619 break; 620 default: 621 name = "Unknown"; 622 break; 623 } 624 std::strncpy(out_name, name.c_str(), name.size()); 625 *out_size = UINT32(name.size()); 626 } 627 return HWC2::Error::None; 628 } 629 630 HWC2::Error HWCDisplay::GetDisplayType(int32_t *out_type) { 631 if (out_type != nullptr) { 632 if (id_ == HWC_DISPLAY_VIRTUAL) { 633 *out_type = HWC2_DISPLAY_TYPE_VIRTUAL; 634 } else { 635 *out_type = HWC2_DISPLAY_TYPE_PHYSICAL; 636 } 637 return HWC2::Error::None; 638 } else { 639 return HWC2::Error::BadParameter; 640 } 641 } 642 643 // TODO(user): Store configurations and hook them up here 644 HWC2::Error HWCDisplay::GetActiveConfig(hwc2_config_t *out_config) { 645 if (out_config != nullptr) { 646 *out_config = 0; 647 return HWC2::Error::None; 648 } else { 649 return HWC2::Error::BadParameter; 650 } 651 } 652 653 HWC2::Error HWCDisplay::SetClientTarget(buffer_handle_t target, int32_t acquire_fence, 654 int32_t dataspace, hwc_region_t damage) { 655 // TODO(user): SurfaceFlinger gives us a null pointer here when doing full SDE composition 656 // The error is problematic for layer caching as it would overwrite our cached client target. 657 // Reported bug 28569722 to resolve this. 658 // For now, continue to use the last valid buffer reported to us for layer caching. 659 if (target == nullptr) { 660 return HWC2::Error::None; 661 } 662 663 if (acquire_fence == 0) { 664 DLOGE("acquire_fence is zero"); 665 return HWC2::Error::BadParameter; 666 } 667 668 client_target_->SetLayerBuffer(target, acquire_fence); 669 client_target_->SetLayerSurfaceDamage(damage); 670 // Ignoring dataspace for now 671 return HWC2::Error::None; 672 } 673 674 HWC2::Error HWCDisplay::SetActiveConfig(hwc2_config_t config) { 675 // We have only one config right now - do nothing 676 return HWC2::Error::None; 677 } 678 679 DisplayError HWCDisplay::SetMixerResolution(uint32_t width, uint32_t height) { 680 return kErrorNotSupported; 681 } 682 683 void HWCDisplay::SetFrameDumpConfig(uint32_t count, uint32_t bit_mask_layer_type) { 684 dump_frame_count_ = count; 685 dump_frame_index_ = 0; 686 dump_input_layers_ = ((bit_mask_layer_type & (1 << INPUT_LAYER_DUMP)) != 0); 687 688 if (blit_engine_) { 689 blit_engine_->SetFrameDumpConfig(count); 690 } 691 692 DLOGI("num_frame_dump %d, input_layer_dump_enable %d", dump_frame_count_, dump_input_layers_); 693 } 694 695 HWC2::PowerMode HWCDisplay::GetLastPowerMode() { 696 return last_power_mode_; 697 } 698 699 DisplayError HWCDisplay::VSync(const DisplayEventVSync &vsync) { 700 callbacks_->Vsync(id_, vsync.timestamp); 701 return kErrorNone; 702 } 703 704 DisplayError HWCDisplay::Refresh() { 705 return kErrorNotSupported; 706 } 707 708 DisplayError HWCDisplay::CECMessage(char *message) { 709 if (qservice_) { 710 qservice_->onCECMessageReceived(message, 0); 711 } else { 712 DLOGW("Qservice instance not available."); 713 } 714 715 return kErrorNone; 716 } 717 718 HWC2::Error HWCDisplay::PrepareLayerStack(uint32_t *out_num_types, uint32_t *out_num_requests) { 719 layer_changes_.clear(); 720 layer_requests_.clear(); 721 if (shutdown_pending_) { 722 return HWC2::Error::BadDisplay; 723 } 724 725 if (!skip_prepare_) { 726 DisplayError error = display_intf_->Prepare(&layer_stack_); 727 if (error != kErrorNone) { 728 if (error == kErrorShutDown) { 729 shutdown_pending_ = true; 730 } else if (error != kErrorPermission) { 731 DLOGE("Prepare failed. Error = %d", error); 732 // To prevent surfaceflinger infinite wait, flush the previous frame during Commit() 733 // so that previous buffer and fences are released, and override the error. 734 flush_ = true; 735 } 736 return HWC2::Error::BadDisplay; 737 } 738 } else { 739 // Skip is not set 740 MarkLayersForGPUBypass(); 741 skip_prepare_ = false; 742 DLOGI("SecureDisplay %s, Skip Prepare/Commit and Flush", 743 secure_display_active_ ? "Starting" : "Stopping"); 744 flush_ = true; 745 } 746 747 for (auto hwc_layer : layer_set_) { 748 Layer *layer = hwc_layer->GetSDMLayer(); 749 LayerComposition &composition = layer->composition; 750 751 if ((composition == kCompositionSDE) || (composition == kCompositionHybrid) || 752 (composition == kCompositionBlit)) { 753 layer_requests_[hwc_layer->GetId()] = HWC2::LayerRequest::ClearClientTarget; 754 } 755 756 HWC2::Composition requested_composition = hwc_layer->GetClientRequestedCompositionType(); 757 // Set SDM composition to HWC2 type in HWCLayer 758 hwc_layer->SetComposition(composition); 759 HWC2::Composition device_composition = hwc_layer->GetDeviceSelectedCompositionType(); 760 // Update the changes list only if the requested composition is different from SDM comp type 761 // TODO(user): Take Care of other comptypes(BLIT) 762 if (requested_composition != device_composition) { 763 layer_changes_[hwc_layer->GetId()] = device_composition; 764 } 765 } 766 *out_num_types = UINT32(layer_changes_.size()); 767 *out_num_requests = UINT32(layer_requests_.size()); 768 validated_ = true; 769 if (*out_num_types > 0) { 770 return HWC2::Error::HasChanges; 771 } else { 772 return HWC2::Error::None; 773 } 774 } 775 776 HWC2::Error HWCDisplay::AcceptDisplayChanges() { 777 if (layer_set_.empty()) { 778 return HWC2::Error::None; 779 } 780 781 if (!validated_) { 782 return HWC2::Error::NotValidated; 783 } 784 785 for (const auto& change : layer_changes_) { 786 auto hwc_layer = layer_map_[change.first]; 787 auto composition = change.second; 788 789 if (hwc_layer == nullptr) { 790 DLOGW("Null layer: %" PRIu64, change.first); 791 } else { 792 hwc_layer->UpdateClientCompositionType(composition); 793 } 794 } 795 return HWC2::Error::None; 796 } 797 798 HWC2::Error HWCDisplay::GetChangedCompositionTypes(uint32_t *out_num_elements, 799 hwc2_layer_t *out_layers, int32_t *out_types) { 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_num_elements = UINT32(layer_changes_.size()); 809 if (out_layers != nullptr && out_types != nullptr) { 810 int i = 0; 811 for (auto change : layer_changes_) { 812 out_layers[i] = change.first; 813 out_types[i] = INT32(change.second); 814 i++; 815 } 816 } 817 return HWC2::Error::None; 818 } 819 820 HWC2::Error HWCDisplay::GetReleaseFences(uint32_t *out_num_elements, hwc2_layer_t *out_layers, 821 int32_t *out_fences) { 822 if (out_layers != nullptr && out_fences != nullptr) { 823 int i = 0; 824 for (auto hwc_layer : layer_set_) { 825 out_layers[i] = hwc_layer->GetId(); 826 out_fences[i] = hwc_layer->PopReleaseFence(); 827 i++; 828 } 829 } 830 *out_num_elements = UINT32(layer_set_.size()); 831 return HWC2::Error::None; 832 } 833 834 HWC2::Error HWCDisplay::GetDisplayRequests(int32_t *out_display_requests, 835 uint32_t *out_num_elements, hwc2_layer_t *out_layers, 836 int32_t *out_layer_requests) { 837 // No display requests for now 838 // Use for sharing blit buffers and 839 // writing wfd buffer directly to output if there is full GPU composition 840 // and no color conversion needed 841 if (layer_set_.empty()) { 842 return HWC2::Error::None; 843 } 844 845 if (!validated_) { 846 DLOGW("Display is not validated"); 847 return HWC2::Error::NotValidated; 848 } 849 *out_display_requests = 0; 850 *out_num_elements = UINT32(layer_requests_.size()); 851 if (out_layers != nullptr && out_layer_requests != nullptr) { 852 int i = 0; 853 for (auto &request : layer_requests_) { 854 out_layers[i] = request.first; 855 out_layer_requests[i] = INT32(request.second); 856 i++; 857 } 858 } 859 return HWC2::Error::None; 860 } 861 862 HWC2::Error HWCDisplay::CommitLayerStack(void) { 863 if (shutdown_pending_ || layer_set_.empty()) { 864 return HWC2::Error::None; 865 } 866 867 if (!validated_) { 868 DLOGW("Display is not validated"); 869 return HWC2::Error::NotValidated; 870 } 871 872 DumpInputBuffers(); 873 874 if (!flush_) { 875 DisplayError error = kErrorUndefined; 876 error = display_intf_->Commit(&layer_stack_); 877 validated_ = false; 878 879 if (error == kErrorNone) { 880 // A commit is successfully submitted, start flushing on failure now onwards. 881 flush_on_error_ = true; 882 } else { 883 if (error == kErrorShutDown) { 884 shutdown_pending_ = true; 885 return HWC2::Error::Unsupported; 886 } else if (error != kErrorPermission) { 887 DLOGE("Commit failed. Error = %d", error); 888 // To prevent surfaceflinger infinite wait, flush the previous frame during Commit() 889 // so that previous buffer and fences are released, and override the error. 890 flush_ = true; 891 } 892 } 893 } 894 895 return HWC2::Error::None; 896 } 897 898 HWC2::Error HWCDisplay::PostCommitLayerStack(int32_t *out_retire_fence) { 899 auto status = HWC2::Error::None; 900 901 // Do no call flush on errors, if a successful buffer is never submitted. 902 if (flush_ && flush_on_error_) { 903 display_intf_->Flush(); 904 } 905 906 // TODO(user): No way to set the client target release fence on SF 907 int32_t &client_target_release_fence = 908 client_target_->GetSDMLayer()->input_buffer->release_fence_fd; 909 if (client_target_release_fence >= 0) { 910 close(client_target_release_fence); 911 client_target_release_fence = -1; 912 } 913 914 for (auto hwc_layer : layer_set_) { 915 hwc_layer->ResetGeometryChanges(); 916 Layer *layer = hwc_layer->GetSDMLayer(); 917 LayerBuffer *layer_buffer = layer->input_buffer; 918 919 if (!flush_) { 920 // If swapinterval property is set to 0 or for single buffer layers, do not update f/w 921 // release fences and discard fences from driver 922 if (swap_interval_zero_ || layer->flags.single_buffer) { 923 close(layer_buffer->release_fence_fd); 924 layer_buffer->release_fence_fd = -1; 925 } else if (layer->composition != kCompositionGPU) { 926 hwc_layer->PushReleaseFence(layer_buffer->release_fence_fd); 927 layer_buffer->release_fence_fd = -1; 928 } else { 929 hwc_layer->PushReleaseFence(-1); 930 } 931 } 932 933 if (layer_buffer->acquire_fence_fd >= 0) { 934 close(layer_buffer->acquire_fence_fd); 935 layer_buffer->acquire_fence_fd = -1; 936 } 937 } 938 939 *out_retire_fence = -1; 940 if (!flush_) { 941 // if swapinterval property is set to 0 then close and reset the list retire fence 942 if (swap_interval_zero_) { 943 close(layer_stack_.retire_fence_fd); 944 layer_stack_.retire_fence_fd = -1; 945 } 946 *out_retire_fence = layer_stack_.retire_fence_fd; 947 948 if (dump_frame_count_) { 949 dump_frame_count_--; 950 dump_frame_index_++; 951 } 952 } 953 954 geometry_changes_ = GeometryChanges::kNone; 955 flush_ = false; 956 957 return status; 958 } 959 960 void HWCDisplay::SetIdleTimeoutMs(uint32_t timeout_ms) { 961 return; 962 } 963 964 DisplayError HWCDisplay::SetMaxMixerStages(uint32_t max_mixer_stages) { 965 DisplayError error = kErrorNone; 966 967 if (display_intf_) { 968 error = display_intf_->SetMaxMixerStages(max_mixer_stages); 969 } 970 971 return error; 972 } 973 974 LayerBufferFormat HWCDisplay::GetSDMFormat(const int32_t &source, const int flags) { 975 LayerBufferFormat format = kFormatInvalid; 976 if (flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED) { 977 switch (source) { 978 case HAL_PIXEL_FORMAT_RGBA_8888: 979 format = kFormatRGBA8888Ubwc; 980 break; 981 case HAL_PIXEL_FORMAT_RGBX_8888: 982 format = kFormatRGBX8888Ubwc; 983 break; 984 case HAL_PIXEL_FORMAT_BGR_565: 985 format = kFormatBGR565Ubwc; 986 break; 987 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS: 988 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC: 989 case HAL_PIXEL_FORMAT_NV12_ENCODEABLE: 990 format = kFormatYCbCr420SPVenusUbwc; 991 break; 992 case HAL_PIXEL_FORMAT_RGBA_1010102: 993 format = kFormatRGBA1010102Ubwc; 994 break; 995 case HAL_PIXEL_FORMAT_RGBX_1010102: 996 format = kFormatRGBX1010102Ubwc; 997 break; 998 case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC: 999 format = kFormatYCbCr420TP10Ubwc; 1000 break; 1001 default: 1002 DLOGE("Unsupported format type for UBWC %d", source); 1003 return kFormatInvalid; 1004 } 1005 return format; 1006 } 1007 1008 switch (source) { 1009 case HAL_PIXEL_FORMAT_RGBA_8888: 1010 format = kFormatRGBA8888; 1011 break; 1012 case HAL_PIXEL_FORMAT_RGBA_5551: 1013 format = kFormatRGBA5551; 1014 break; 1015 case HAL_PIXEL_FORMAT_RGBA_4444: 1016 format = kFormatRGBA4444; 1017 break; 1018 case HAL_PIXEL_FORMAT_BGRA_8888: 1019 format = kFormatBGRA8888; 1020 break; 1021 case HAL_PIXEL_FORMAT_RGBX_8888: 1022 format = kFormatRGBX8888; 1023 break; 1024 case HAL_PIXEL_FORMAT_BGRX_8888: 1025 format = kFormatBGRX8888; 1026 break; 1027 case HAL_PIXEL_FORMAT_RGB_888: 1028 format = kFormatRGB888; 1029 break; 1030 case HAL_PIXEL_FORMAT_RGB_565: 1031 format = kFormatRGB565; 1032 break; 1033 case HAL_PIXEL_FORMAT_BGR_565: 1034 format = kFormatBGR565; 1035 break; 1036 case HAL_PIXEL_FORMAT_NV12_ENCODEABLE: 1037 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS: 1038 format = kFormatYCbCr420SemiPlanarVenus; 1039 break; 1040 case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS: 1041 format = kFormatYCrCb420SemiPlanarVenus; 1042 break; 1043 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC: 1044 format = kFormatYCbCr420SPVenusUbwc; 1045 break; 1046 case HAL_PIXEL_FORMAT_YV12: 1047 format = kFormatYCrCb420PlanarStride16; 1048 break; 1049 case HAL_PIXEL_FORMAT_YCrCb_420_SP: 1050 format = kFormatYCrCb420SemiPlanar; 1051 break; 1052 case HAL_PIXEL_FORMAT_YCbCr_420_SP: 1053 format = kFormatYCbCr420SemiPlanar; 1054 break; 1055 case HAL_PIXEL_FORMAT_YCbCr_422_SP: 1056 format = kFormatYCbCr422H2V1SemiPlanar; 1057 break; 1058 case HAL_PIXEL_FORMAT_YCbCr_422_I: 1059 format = kFormatYCbCr422H2V1Packed; 1060 break; 1061 case HAL_PIXEL_FORMAT_RGBA_1010102: 1062 format = kFormatRGBA1010102; 1063 break; 1064 case HAL_PIXEL_FORMAT_ARGB_2101010: 1065 format = kFormatARGB2101010; 1066 break; 1067 case HAL_PIXEL_FORMAT_RGBX_1010102: 1068 format = kFormatRGBX1010102; 1069 break; 1070 case HAL_PIXEL_FORMAT_XRGB_2101010: 1071 format = kFormatXRGB2101010; 1072 break; 1073 case HAL_PIXEL_FORMAT_BGRA_1010102: 1074 format = kFormatBGRA1010102; 1075 break; 1076 case HAL_PIXEL_FORMAT_ABGR_2101010: 1077 format = kFormatABGR2101010; 1078 break; 1079 case HAL_PIXEL_FORMAT_BGRX_1010102: 1080 format = kFormatBGRX1010102; 1081 break; 1082 case HAL_PIXEL_FORMAT_XBGR_2101010: 1083 format = kFormatXBGR2101010; 1084 break; 1085 case HAL_PIXEL_FORMAT_YCbCr_420_P010: 1086 format = kFormatYCbCr420P010; 1087 break; 1088 case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC: 1089 format = kFormatYCbCr420TP10Ubwc; 1090 break; 1091 default: 1092 DLOGW("Unsupported format type = %d", source); 1093 return kFormatInvalid; 1094 } 1095 1096 return format; 1097 } 1098 1099 void HWCDisplay::DumpInputBuffers() { 1100 char dir_path[PATH_MAX]; 1101 1102 if (!dump_frame_count_ || flush_ || !dump_input_layers_) { 1103 return; 1104 } 1105 1106 snprintf(dir_path, sizeof(dir_path), "/data/misc/display/frame_dump_%s", GetDisplayString()); 1107 1108 if (mkdir(dir_path, 0777) != 0 && errno != EEXIST) { 1109 DLOGW("Failed to create %s directory errno = %d, desc = %s", dir_path, errno, strerror(errno)); 1110 return; 1111 } 1112 1113 // if directory exists already, need to explicitly change the permission. 1114 if (errno == EEXIST && chmod(dir_path, 0777) != 0) { 1115 DLOGW("Failed to change permissions on %s directory", dir_path); 1116 return; 1117 } 1118 1119 for (uint32_t i = 0; i < layer_stack_.layers.size(); i++) { 1120 auto layer = layer_stack_.layers.at(i); 1121 const private_handle_t *pvt_handle = 1122 reinterpret_cast<const private_handle_t *>(layer->input_buffer->buffer_id); 1123 auto acquire_fence_fd = layer->input_buffer->acquire_fence_fd; 1124 1125 if (acquire_fence_fd >= 0) { 1126 int error = sync_wait(acquire_fence_fd, 1000); 1127 if (error < 0) { 1128 DLOGW("sync_wait error errno = %d, desc = %s", errno, strerror(errno)); 1129 return; 1130 } 1131 } 1132 1133 if (pvt_handle && pvt_handle->base) { 1134 char dump_file_name[PATH_MAX]; 1135 size_t result = 0; 1136 1137 snprintf(dump_file_name, sizeof(dump_file_name), "%s/input_layer%d_%dx%d_%s_frame%d.raw", 1138 dir_path, i, pvt_handle->width, pvt_handle->height, 1139 GetHALPixelFormatString(pvt_handle->format), dump_frame_index_); 1140 1141 FILE *fp = fopen(dump_file_name, "w+"); 1142 if (fp) { 1143 result = fwrite(reinterpret_cast<void *>(pvt_handle->base), pvt_handle->size, 1, fp); 1144 fclose(fp); 1145 } 1146 1147 DLOGI("Frame Dump %s: is %s", dump_file_name, result ? "Successful" : "Failed"); 1148 } 1149 } 1150 } 1151 1152 void HWCDisplay::DumpOutputBuffer(const BufferInfo &buffer_info, void *base, int fence) { 1153 char dir_path[PATH_MAX]; 1154 1155 snprintf(dir_path, sizeof(dir_path), "/data/misc/display/frame_dump_%s", GetDisplayString()); 1156 1157 if (mkdir(dir_path, 777) != 0 && errno != EEXIST) { 1158 DLOGW("Failed to create %s directory errno = %d, desc = %s", dir_path, errno, strerror(errno)); 1159 return; 1160 } 1161 1162 // if directory exists already, need to explicitly change the permission. 1163 if (errno == EEXIST && chmod(dir_path, 0777) != 0) { 1164 DLOGW("Failed to change permissions on %s directory", dir_path); 1165 return; 1166 } 1167 1168 if (base) { 1169 char dump_file_name[PATH_MAX]; 1170 size_t result = 0; 1171 1172 if (fence >= 0) { 1173 int error = sync_wait(fence, 1000); 1174 if (error < 0) { 1175 DLOGW("sync_wait error errno = %d, desc = %s", errno, strerror(errno)); 1176 return; 1177 } 1178 } 1179 1180 snprintf(dump_file_name, sizeof(dump_file_name), "%s/output_layer_%dx%d_%s_frame%d.raw", 1181 dir_path, buffer_info.buffer_config.width, buffer_info.buffer_config.height, 1182 GetFormatString(buffer_info.buffer_config.format), dump_frame_index_); 1183 1184 FILE *fp = fopen(dump_file_name, "w+"); 1185 if (fp) { 1186 result = fwrite(base, buffer_info.alloc_buffer_info.size, 1, fp); 1187 fclose(fp); 1188 } 1189 1190 DLOGI("Frame Dump of %s is %s", dump_file_name, result ? "Successful" : "Failed"); 1191 } 1192 } 1193 1194 const char *HWCDisplay::GetHALPixelFormatString(int format) { 1195 switch (format) { 1196 case HAL_PIXEL_FORMAT_RGBA_8888: 1197 return "RGBA_8888"; 1198 case HAL_PIXEL_FORMAT_RGBX_8888: 1199 return "RGBX_8888"; 1200 case HAL_PIXEL_FORMAT_RGB_888: 1201 return "RGB_888"; 1202 case HAL_PIXEL_FORMAT_RGB_565: 1203 return "RGB_565"; 1204 case HAL_PIXEL_FORMAT_BGR_565: 1205 return "BGR_565"; 1206 case HAL_PIXEL_FORMAT_BGRA_8888: 1207 return "BGRA_8888"; 1208 case HAL_PIXEL_FORMAT_RGBA_5551: 1209 return "RGBA_5551"; 1210 case HAL_PIXEL_FORMAT_RGBA_4444: 1211 return "RGBA_4444"; 1212 case HAL_PIXEL_FORMAT_YV12: 1213 return "YV12"; 1214 case HAL_PIXEL_FORMAT_YCbCr_422_SP: 1215 return "YCbCr_422_SP_NV16"; 1216 case HAL_PIXEL_FORMAT_YCrCb_420_SP: 1217 return "YCrCb_420_SP_NV21"; 1218 case HAL_PIXEL_FORMAT_YCbCr_422_I: 1219 return "YCbCr_422_I_YUY2"; 1220 case HAL_PIXEL_FORMAT_YCrCb_422_I: 1221 return "YCrCb_422_I_YVYU"; 1222 case HAL_PIXEL_FORMAT_NV12_ENCODEABLE: 1223 return "NV12_ENCODEABLE"; 1224 case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED: 1225 return "YCbCr_420_SP_TILED_TILE_4x2"; 1226 case HAL_PIXEL_FORMAT_YCbCr_420_SP: 1227 return "YCbCr_420_SP"; 1228 case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO: 1229 return "YCrCb_420_SP_ADRENO"; 1230 case HAL_PIXEL_FORMAT_YCrCb_422_SP: 1231 return "YCrCb_422_SP"; 1232 case HAL_PIXEL_FORMAT_R_8: 1233 return "R_8"; 1234 case HAL_PIXEL_FORMAT_RG_88: 1235 return "RG_88"; 1236 case HAL_PIXEL_FORMAT_INTERLACE: 1237 return "INTERLACE"; 1238 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS: 1239 return "YCbCr_420_SP_VENUS"; 1240 case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS: 1241 return "YCrCb_420_SP_VENUS"; 1242 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC: 1243 return "YCbCr_420_SP_VENUS_UBWC"; 1244 case HAL_PIXEL_FORMAT_RGBA_1010102: 1245 return "RGBA_1010102"; 1246 case HAL_PIXEL_FORMAT_ARGB_2101010: 1247 return "ARGB_2101010"; 1248 case HAL_PIXEL_FORMAT_RGBX_1010102: 1249 return "RGBX_1010102"; 1250 case HAL_PIXEL_FORMAT_XRGB_2101010: 1251 return "XRGB_2101010"; 1252 case HAL_PIXEL_FORMAT_BGRA_1010102: 1253 return "BGRA_1010102"; 1254 case HAL_PIXEL_FORMAT_ABGR_2101010: 1255 return "ABGR_2101010"; 1256 case HAL_PIXEL_FORMAT_BGRX_1010102: 1257 return "BGRX_1010102"; 1258 case HAL_PIXEL_FORMAT_XBGR_2101010: 1259 return "XBGR_2101010"; 1260 case HAL_PIXEL_FORMAT_YCbCr_420_P010: 1261 return "YCbCr_420_P010"; 1262 case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC: 1263 return "YCbCr_420_TP10_UBWC"; 1264 default: 1265 return "Unknown_format"; 1266 } 1267 } 1268 1269 const char *HWCDisplay::GetDisplayString() { 1270 switch (type_) { 1271 case kPrimary: 1272 return "primary"; 1273 case kHDMI: 1274 return "hdmi"; 1275 case kVirtual: 1276 return "virtual"; 1277 default: 1278 return "invalid"; 1279 } 1280 } 1281 1282 int HWCDisplay::SetFrameBufferResolution(uint32_t x_pixels, uint32_t y_pixels) { 1283 if (x_pixels <= 0 || y_pixels <= 0) { 1284 DLOGW("Unsupported config: x_pixels=%d, y_pixels=%d", x_pixels, y_pixels); 1285 return -EINVAL; 1286 } 1287 1288 DisplayConfigVariableInfo fb_config; 1289 DisplayError error = display_intf_->GetFrameBufferConfig(&fb_config); 1290 if (error != kErrorNone) { 1291 DLOGV("Get frame buffer config failed. Error = %d", error); 1292 return -EINVAL; 1293 } 1294 1295 fb_config.x_pixels = x_pixels; 1296 fb_config.y_pixels = y_pixels; 1297 1298 error = display_intf_->SetFrameBufferConfig(fb_config); 1299 if (error != kErrorNone) { 1300 DLOGV("Set frame buffer config failed. Error = %d", error); 1301 return -EINVAL; 1302 } 1303 1304 // Create rects to represent the new source and destination crops 1305 LayerRect crop = LayerRect(0, 0, FLOAT(x_pixels), FLOAT(y_pixels)); 1306 LayerRect dst = LayerRect(0, 0, FLOAT(fb_config.x_pixels), FLOAT(fb_config.y_pixels)); 1307 auto client_target_layer = client_target_->GetSDMLayer(); 1308 client_target_layer->src_rect = crop; 1309 client_target_layer->dst_rect = dst; 1310 1311 int aligned_width; 1312 int aligned_height; 1313 int usage = GRALLOC_USAGE_HW_FB; 1314 int format = HAL_PIXEL_FORMAT_RGBA_8888; 1315 int ubwc_enabled = 0; 1316 int flags = 0; 1317 HWCDebugHandler::Get()->GetProperty("debug.gralloc.enable_fb_ubwc", &ubwc_enabled); 1318 if (ubwc_enabled == 1) { 1319 usage |= GRALLOC_USAGE_PRIVATE_ALLOC_UBWC; 1320 flags |= private_handle_t::PRIV_FLAGS_UBWC_ALIGNED; 1321 } 1322 AdrenoMemInfo::getInstance().getAlignedWidthAndHeight(INT(x_pixels), INT(y_pixels), format, usage, 1323 aligned_width, aligned_height); 1324 1325 // TODO(user): How does the dirty region get set on the client target? File bug on Google 1326 client_target_layer->composition = kCompositionGPUTarget; 1327 client_target_layer->input_buffer->format = GetSDMFormat(format, flags); 1328 client_target_layer->input_buffer->width = UINT32(aligned_width); 1329 client_target_layer->input_buffer->height = UINT32(aligned_height); 1330 client_target_layer->plane_alpha = 255; 1331 1332 DLOGI("New framebuffer resolution (%dx%d)", fb_config.x_pixels, fb_config.y_pixels); 1333 1334 return 0; 1335 } 1336 1337 void HWCDisplay::GetFrameBufferResolution(uint32_t *x_pixels, uint32_t *y_pixels) { 1338 DisplayConfigVariableInfo fb_config; 1339 display_intf_->GetFrameBufferConfig(&fb_config); 1340 1341 *x_pixels = fb_config.x_pixels; 1342 *y_pixels = fb_config.y_pixels; 1343 } 1344 1345 DisplayError HWCDisplay::GetMixerResolution(uint32_t *x_pixels, uint32_t *y_pixels) { 1346 return display_intf_->GetMixerResolution(x_pixels, y_pixels); 1347 } 1348 1349 void HWCDisplay::GetPanelResolution(uint32_t *x_pixels, uint32_t *y_pixels) { 1350 DisplayConfigVariableInfo display_config; 1351 uint32_t active_index = 0; 1352 1353 display_intf_->GetActiveConfig(&active_index); 1354 display_intf_->GetConfig(active_index, &display_config); 1355 1356 *x_pixels = display_config.x_pixels; 1357 *y_pixels = display_config.y_pixels; 1358 } 1359 1360 int HWCDisplay::SetDisplayStatus(uint32_t display_status) { 1361 int status = 0; 1362 1363 switch (display_status) { 1364 case kDisplayStatusResume: 1365 display_paused_ = false; 1366 case kDisplayStatusOnline: 1367 status = INT32(SetPowerMode(HWC2::PowerMode::On)); 1368 break; 1369 case kDisplayStatusPause: 1370 display_paused_ = true; 1371 case kDisplayStatusOffline: 1372 status = INT32(SetPowerMode(HWC2::PowerMode::Off)); 1373 break; 1374 default: 1375 DLOGW("Invalid display status %d", display_status); 1376 return -EINVAL; 1377 } 1378 1379 if (display_status == kDisplayStatusResume || display_status == kDisplayStatusPause) { 1380 callbacks_->Refresh(HWC_DISPLAY_PRIMARY); 1381 } 1382 1383 return status; 1384 } 1385 1386 HWC2::Error HWCDisplay::SetCursorPosition(hwc2_layer_t layer, int x, int y) { 1387 if (shutdown_pending_) { 1388 return HWC2::Error::None; 1389 } 1390 1391 // TODO(user): Validate layer 1392 // TODO(user): Check if we're in a validate/present cycle 1393 1394 auto error = display_intf_->SetCursorPosition(x, y); 1395 if (error != kErrorNone) { 1396 if (error == kErrorShutDown) { 1397 shutdown_pending_ = true; 1398 return HWC2::Error::None; 1399 } 1400 1401 DLOGE("Failed for x = %d y = %d, Error = %d", x, y, error); 1402 return HWC2::Error::BadDisplay; 1403 } 1404 1405 return HWC2::Error::None; 1406 } 1407 1408 int HWCDisplay::OnMinHdcpEncryptionLevelChange(uint32_t min_enc_level) { 1409 DisplayError error = display_intf_->OnMinHdcpEncryptionLevelChange(min_enc_level); 1410 if (error != kErrorNone) { 1411 DLOGE("Failed. Error = %d", error); 1412 return -1; 1413 } 1414 1415 return 0; 1416 } 1417 1418 void HWCDisplay::MarkLayersForGPUBypass() { 1419 for (auto hwc_layer : layer_set_) { 1420 auto layer = hwc_layer->GetSDMLayer(); 1421 layer->composition = kCompositionSDE; 1422 } 1423 } 1424 1425 void HWCDisplay::MarkLayersForClientComposition() { 1426 // ClientComposition - GPU comp, to acheive this, set skip flag so that 1427 // SDM does not handle this layer and hwc_layer composition will be 1428 // set correctly at the end of Prepare. 1429 for (auto hwc_layer : layer_set_) { 1430 Layer *layer = hwc_layer->GetSDMLayer(); 1431 layer->flags.skip = true; 1432 } 1433 } 1434 1435 void HWCDisplay::ApplyScanAdjustment(hwc_rect_t *display_frame) { 1436 } 1437 1438 int HWCDisplay::SetPanelBrightness(int level) { 1439 int ret = 0; 1440 if (display_intf_) 1441 ret = display_intf_->SetPanelBrightness(level); 1442 else 1443 ret = -EINVAL; 1444 1445 return ret; 1446 } 1447 1448 int HWCDisplay::GetPanelBrightness(int *level) { 1449 return display_intf_->GetPanelBrightness(level); 1450 } 1451 1452 int HWCDisplay::ToggleScreenUpdates(bool enable) { 1453 display_paused_ = enable ? false : true; 1454 callbacks_->Refresh(HWC_DISPLAY_PRIMARY); 1455 return 0; 1456 } 1457 1458 int HWCDisplay::ColorSVCRequestRoute(const PPDisplayAPIPayload &in_payload, 1459 PPDisplayAPIPayload *out_payload, 1460 PPPendingParams *pending_action) { 1461 int ret = 0; 1462 1463 if (display_intf_) 1464 ret = display_intf_->ColorSVCRequestRoute(in_payload, out_payload, pending_action); 1465 else 1466 ret = -EINVAL; 1467 1468 return ret; 1469 } 1470 1471 void HWCDisplay::SolidFillPrepare() { 1472 if (solid_fill_enable_) { 1473 if (solid_fill_layer_ == NULL) { 1474 // Create a dummy layer here 1475 solid_fill_layer_ = new Layer(); 1476 solid_fill_layer_->input_buffer = new LayerBuffer(); 1477 } 1478 uint32_t primary_width = 0, primary_height = 0; 1479 GetMixerResolution(&primary_width, &primary_height); 1480 1481 LayerBuffer *layer_buffer = solid_fill_layer_->input_buffer; 1482 layer_buffer->width = primary_width; 1483 layer_buffer->height = primary_height; 1484 layer_buffer->acquire_fence_fd = -1; 1485 layer_buffer->release_fence_fd = -1; 1486 1487 LayerRect rect; 1488 rect.top = 0; rect.left = 0; 1489 rect.right = primary_width; 1490 rect.bottom = primary_height; 1491 1492 solid_fill_layer_->composition = kCompositionGPU; 1493 solid_fill_layer_->src_rect = rect; 1494 solid_fill_layer_->dst_rect = rect; 1495 1496 solid_fill_layer_->blending = kBlendingPremultiplied; 1497 solid_fill_layer_->solid_fill_color = solid_fill_color_; 1498 solid_fill_layer_->frame_rate = 60; 1499 solid_fill_layer_->visible_regions.push_back(solid_fill_layer_->dst_rect); 1500 solid_fill_layer_->flags.updating = 1; 1501 solid_fill_layer_->flags.solid_fill = true; 1502 } else { 1503 // delete the dummy layer 1504 if (solid_fill_layer_) { 1505 delete solid_fill_layer_->input_buffer; 1506 } 1507 delete solid_fill_layer_; 1508 solid_fill_layer_ = NULL; 1509 } 1510 1511 if (solid_fill_enable_ && solid_fill_layer_) { 1512 BuildSolidFillStack(); 1513 MarkLayersForGPUBypass(); 1514 } 1515 1516 return; 1517 } 1518 1519 void HWCDisplay::SolidFillCommit() { 1520 if (solid_fill_enable_ && solid_fill_layer_) { 1521 LayerBuffer *layer_buffer = solid_fill_layer_->input_buffer; 1522 if (layer_buffer->release_fence_fd > 0) { 1523 close(layer_buffer->release_fence_fd); 1524 layer_buffer->release_fence_fd = -1; 1525 } 1526 if (layer_stack_.retire_fence_fd > 0) { 1527 close(layer_stack_.retire_fence_fd); 1528 layer_stack_.retire_fence_fd = -1; 1529 } 1530 } 1531 } 1532 1533 int HWCDisplay::GetVisibleDisplayRect(hwc_rect_t *visible_rect) { 1534 if (!IsValid(display_rect_)) { 1535 return -EINVAL; 1536 } 1537 1538 visible_rect->left = INT(display_rect_.left); 1539 visible_rect->top = INT(display_rect_.top); 1540 visible_rect->right = INT(display_rect_.right); 1541 visible_rect->bottom = INT(display_rect_.bottom); 1542 DLOGI("Dpy = %d Visible Display Rect(%d %d %d %d)", visible_rect->left, visible_rect->top, 1543 visible_rect->right, visible_rect->bottom); 1544 1545 return 0; 1546 } 1547 1548 void HWCDisplay::SetSecureDisplay(bool secure_display_active) { 1549 secure_display_active_ = secure_display_active; 1550 return; 1551 } 1552 1553 int HWCDisplay::SetActiveDisplayConfig(int config) { 1554 return display_intf_->SetActiveConfig(UINT32(config)) == kErrorNone ? 0 : -1; 1555 } 1556 1557 int HWCDisplay::GetActiveDisplayConfig(uint32_t *config) { 1558 return display_intf_->GetActiveConfig(config) == kErrorNone ? 0 : -1; 1559 } 1560 1561 int HWCDisplay::GetDisplayConfigCount(uint32_t *count) { 1562 return display_intf_->GetNumVariableInfoConfigs(count) == kErrorNone ? 0 : -1; 1563 } 1564 1565 int HWCDisplay::GetDisplayAttributesForConfig(int config, 1566 DisplayConfigVariableInfo *display_attributes) { 1567 return display_intf_->GetConfig(UINT32(config), display_attributes) == kErrorNone ? 0 : -1; 1568 } 1569 1570 bool HWCDisplay::SingleLayerUpdating(void) { 1571 uint32_t updating_count = 0; 1572 1573 for (uint i = 0; i < layer_stack_.layers.size(); i++) { 1574 auto layer = layer_stack_.layers.at(i); 1575 if (layer->flags.updating) { 1576 updating_count++; 1577 } 1578 } 1579 1580 return (updating_count == 1); 1581 } 1582 1583 bool HWCDisplay::IsLayerUpdating(const Layer *layer) { 1584 // Layer should be considered updating if 1585 // a) layer is in single buffer mode, or 1586 // b) valid dirty_regions(android specific hint for updating status), or 1587 // c) layer stack geometry has changed (TODO(user): Remove when SDM accepts 1588 // geometry_changed as bit fields). 1589 return (layer->flags.single_buffer || IsSurfaceUpdated(layer->dirty_regions) || 1590 geometry_changes_); 1591 } 1592 1593 bool HWCDisplay::IsSurfaceUpdated(const std::vector<LayerRect> &dirty_regions) { 1594 // based on dirty_regions determine if its updating 1595 // dirty_rect count = 0 - whole layer - updating. 1596 // dirty_rect count = 1 or more valid rects - updating. 1597 // dirty_rect count = 1 with (0,0,0,0) - not updating. 1598 return (dirty_regions.empty() || IsValid(dirty_regions.at(0))); 1599 } 1600 1601 uint32_t HWCDisplay::SanitizeRefreshRate(uint32_t req_refresh_rate) { 1602 uint32_t refresh_rate = req_refresh_rate; 1603 1604 if (refresh_rate < min_refresh_rate_) { 1605 // Pick the next multiple of request which is within the range 1606 refresh_rate = 1607 (((min_refresh_rate_ / refresh_rate) + ((min_refresh_rate_ % refresh_rate) ? 1 : 0)) * 1608 refresh_rate); 1609 } 1610 1611 if (refresh_rate > max_refresh_rate_) { 1612 refresh_rate = max_refresh_rate_; 1613 } 1614 1615 return refresh_rate; 1616 } 1617 1618 DisplayClass HWCDisplay::GetDisplayClass() { 1619 return display_class_; 1620 } 1621 1622 void HWCDisplay::CloseAcquireFds() { 1623 for (auto hwc_layer : layer_set_) { 1624 auto layer = hwc_layer->GetSDMLayer(); 1625 if (layer->input_buffer->acquire_fence_fd >= 0) { 1626 close(layer->input_buffer->acquire_fence_fd); 1627 layer->input_buffer->acquire_fence_fd = -1; 1628 } 1629 } 1630 int32_t &client_target_acquire_fence = 1631 client_target_->GetSDMLayer()->input_buffer->acquire_fence_fd; 1632 if (client_target_acquire_fence >= 0) { 1633 close(client_target_acquire_fence); 1634 client_target_acquire_fence = -1; 1635 } 1636 } 1637 1638 std::string HWCDisplay::Dump() { 1639 std::ostringstream os; 1640 os << "-------------------------------" << std::endl; 1641 os << "HWC2 LayerDump display_id: " << id_ << std::endl; 1642 for (auto layer : layer_set_) { 1643 auto sdm_layer = layer->GetSDMLayer(); 1644 auto transform = sdm_layer->transform; 1645 os << "-------------------------------" << std::endl; 1646 os << "layer_id: " << layer->GetId() << std::endl; 1647 os << "\tz: " << layer->GetZ() << std::endl; 1648 os << "\tclient(SF) composition: " << 1649 to_string(layer->GetClientRequestedCompositionType()).c_str() << std::endl; 1650 os << "\tdevice(SDM) composition: " << 1651 to_string(layer->GetDeviceSelectedCompositionType()).c_str() << std::endl; 1652 os << "\tplane_alpha: " << std::to_string(sdm_layer->plane_alpha).c_str() << std::endl; 1653 os << "\tformat: " << GetFormatString(sdm_layer->input_buffer->format) << std::endl; 1654 os << "\ttransform: rot: " << transform.rotation << " flip_h: " << transform.flip_horizontal << 1655 " flip_v: "<< transform.flip_vertical << std::endl; 1656 os << "\tbuffer_id: " << std::hex << "0x" << sdm_layer->input_buffer->buffer_id << std::dec 1657 << std::endl; 1658 } 1659 return os.str(); 1660 } 1661 } // namespace sdm 1662