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