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