1 /* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #define ATRACE_TAG ATRACE_TAG_GRAPHICS 18 #define LOG_TAG "hwc-drm-two" 19 20 #include "drmdisplaycomposition.h" 21 #include "drmhwcomposer.h" 22 #include "drmhwctwo.h" 23 #include "platform.h" 24 #include "vsyncworker.h" 25 26 #include <inttypes.h> 27 #include <string> 28 29 #include <cutils/log.h> 30 #include <cutils/properties.h> 31 #include <hardware/hardware.h> 32 #include <hardware/hwcomposer2.h> 33 34 namespace android { 35 36 class DrmVsyncCallback : public VsyncCallback { 37 public: 38 DrmVsyncCallback(hwc2_callback_data_t data, hwc2_function_pointer_t hook) 39 : data_(data), hook_(hook) { 40 } 41 42 void Callback(int display, int64_t timestamp) { 43 auto hook = reinterpret_cast<HWC2_PFN_VSYNC>(hook_); 44 hook(data_, display, timestamp); 45 } 46 47 private: 48 hwc2_callback_data_t data_; 49 hwc2_function_pointer_t hook_; 50 }; 51 52 DrmHwcTwo::DrmHwcTwo() { 53 common.tag = HARDWARE_DEVICE_TAG; 54 common.version = HWC_DEVICE_API_VERSION_2_0; 55 common.close = HookDevClose; 56 getCapabilities = HookDevGetCapabilities; 57 getFunction = HookDevGetFunction; 58 } 59 60 HWC2::Error DrmHwcTwo::Init() { 61 int ret = drm_.Init(); 62 if (ret) { 63 ALOGE("Can't initialize drm object %d", ret); 64 return HWC2::Error::NoResources; 65 } 66 67 importer_.reset(Importer::CreateInstance(&drm_)); 68 if (!importer_) { 69 ALOGE("Failed to create importer instance"); 70 return HWC2::Error::NoResources; 71 } 72 73 ret = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, 74 (const hw_module_t **)&gralloc_); 75 if (ret) { 76 ALOGE("Failed to open gralloc module %d", ret); 77 return HWC2::Error::NoResources; 78 } 79 80 displays_.emplace(std::piecewise_construct, 81 std::forward_as_tuple(HWC_DISPLAY_PRIMARY), 82 std::forward_as_tuple(&drm_, importer_, gralloc_, 83 HWC_DISPLAY_PRIMARY, 84 HWC2::DisplayType::Physical)); 85 86 DrmCrtc *crtc = drm_.GetCrtcForDisplay(static_cast<int>(HWC_DISPLAY_PRIMARY)); 87 if (!crtc) { 88 ALOGE("Failed to get crtc for display %d", 89 static_cast<int>(HWC_DISPLAY_PRIMARY)); 90 return HWC2::Error::BadDisplay; 91 } 92 93 std::vector<DrmPlane *> display_planes; 94 for (auto &plane : drm_.planes()) { 95 if (plane->GetCrtcSupported(*crtc)) 96 display_planes.push_back(plane.get()); 97 } 98 displays_.at(HWC_DISPLAY_PRIMARY).Init(&display_planes); 99 return HWC2::Error::None; 100 } 101 102 template <typename... Args> 103 static inline HWC2::Error unsupported(char const *func, Args... /*args*/) { 104 ALOGV("Unsupported function: %s", func); 105 return HWC2::Error::Unsupported; 106 } 107 108 static inline void supported(char const *func) { 109 ALOGV("Supported function: %s", func); 110 } 111 112 HWC2::Error DrmHwcTwo::CreateVirtualDisplay(uint32_t width, uint32_t height, 113 int32_t *format, 114 hwc2_display_t *display) { 115 // TODO: Implement virtual display 116 return unsupported(__func__, width, height, format, display); 117 } 118 119 HWC2::Error DrmHwcTwo::DestroyVirtualDisplay(hwc2_display_t display) { 120 // TODO: Implement virtual display 121 return unsupported(__func__, display); 122 } 123 124 void DrmHwcTwo::Dump(uint32_t *size, char *buffer) { 125 // TODO: Implement dump 126 unsupported(__func__, size, buffer); 127 } 128 129 uint32_t DrmHwcTwo::GetMaxVirtualDisplayCount() { 130 // TODO: Implement virtual display 131 unsupported(__func__); 132 return 0; 133 } 134 135 HWC2::Error DrmHwcTwo::RegisterCallback(int32_t descriptor, 136 hwc2_callback_data_t data, 137 hwc2_function_pointer_t function) { 138 supported(__func__); 139 auto callback = static_cast<HWC2::Callback>(descriptor); 140 callbacks_.emplace(callback, HwcCallback(data, function)); 141 142 switch (callback) { 143 case HWC2::Callback::Hotplug: { 144 auto hotplug = reinterpret_cast<HWC2_PFN_HOTPLUG>(function); 145 hotplug(data, HWC_DISPLAY_PRIMARY, 146 static_cast<int32_t>(HWC2::Connection::Connected)); 147 break; 148 } 149 case HWC2::Callback::Vsync: { 150 for (std::pair<const hwc2_display_t, DrmHwcTwo::HwcDisplay> &d : 151 displays_) 152 d.second.RegisterVsyncCallback(data, function); 153 break; 154 } 155 default: 156 break; 157 } 158 return HWC2::Error::None; 159 } 160 161 DrmHwcTwo::HwcDisplay::HwcDisplay(DrmResources *drm, 162 std::shared_ptr<Importer> importer, 163 const gralloc_module_t *gralloc, 164 hwc2_display_t handle, HWC2::DisplayType type) 165 : drm_(drm), 166 importer_(importer), 167 gralloc_(gralloc), 168 handle_(handle), 169 type_(type) { 170 supported(__func__); 171 } 172 173 HWC2::Error DrmHwcTwo::HwcDisplay::Init(std::vector<DrmPlane *> *planes) { 174 supported(__func__); 175 planner_ = Planner::CreateInstance(drm_); 176 if (!planner_) { 177 ALOGE("Failed to create planner instance for composition"); 178 return HWC2::Error::NoResources; 179 } 180 181 int display = static_cast<int>(handle_); 182 int ret = compositor_.Init(drm_, display); 183 if (ret) { 184 ALOGE("Failed display compositor init for display %d (%d)", display, ret); 185 return HWC2::Error::NoResources; 186 } 187 188 // Split up the given display planes into primary and overlay to properly 189 // interface with the composition 190 char use_overlay_planes_prop[PROPERTY_VALUE_MAX]; 191 property_get("hwc.drm.use_overlay_planes", use_overlay_planes_prop, "1"); 192 bool use_overlay_planes = atoi(use_overlay_planes_prop); 193 for (auto &plane : *planes) { 194 if (plane->type() == DRM_PLANE_TYPE_PRIMARY) 195 primary_planes_.push_back(plane); 196 else if (use_overlay_planes && (plane)->type() == DRM_PLANE_TYPE_OVERLAY) 197 overlay_planes_.push_back(plane); 198 } 199 200 crtc_ = drm_->GetCrtcForDisplay(display); 201 if (!crtc_) { 202 ALOGE("Failed to get crtc for display %d", display); 203 return HWC2::Error::BadDisplay; 204 } 205 206 connector_ = drm_->GetConnectorForDisplay(display); 207 if (!connector_) { 208 ALOGE("Failed to get connector for display %d", display); 209 return HWC2::Error::BadDisplay; 210 } 211 212 // Fetch the number of modes from the display 213 uint32_t num_configs; 214 HWC2::Error err = GetDisplayConfigs(&num_configs, NULL); 215 if (err != HWC2::Error::None || !num_configs) 216 return err; 217 218 // Grab the first mode, we'll choose this as the active mode 219 // TODO: Should choose the preferred mode here 220 hwc2_config_t default_config; 221 num_configs = 1; 222 err = GetDisplayConfigs(&num_configs, &default_config); 223 if (err != HWC2::Error::None) 224 return err; 225 226 ret = vsync_worker_.Init(drm_, display); 227 if (ret) { 228 ALOGE("Failed to create event worker for d=%d %d\n", display, ret); 229 return HWC2::Error::BadDisplay; 230 } 231 232 return SetActiveConfig(default_config); 233 } 234 235 HWC2::Error DrmHwcTwo::HwcDisplay::RegisterVsyncCallback( 236 hwc2_callback_data_t data, hwc2_function_pointer_t func) { 237 supported(__func__); 238 auto callback = std::make_shared<DrmVsyncCallback>(data, func); 239 vsync_worker_.RegisterCallback(std::move(callback)); 240 return HWC2::Error::None; 241 } 242 243 HWC2::Error DrmHwcTwo::HwcDisplay::AcceptDisplayChanges() { 244 supported(__func__); 245 uint32_t num_changes = 0; 246 for (std::pair<const hwc2_layer_t, DrmHwcTwo::HwcLayer> &l : layers_) 247 l.second.accept_type_change(); 248 return HWC2::Error::None; 249 } 250 251 HWC2::Error DrmHwcTwo::HwcDisplay::CreateLayer(hwc2_layer_t *layer) { 252 supported(__func__); 253 layers_.emplace(static_cast<hwc2_layer_t>(layer_idx_), HwcLayer()); 254 *layer = static_cast<hwc2_layer_t>(layer_idx_); 255 ++layer_idx_; 256 return HWC2::Error::None; 257 } 258 259 HWC2::Error DrmHwcTwo::HwcDisplay::DestroyLayer(hwc2_layer_t layer) { 260 supported(__func__); 261 layers_.erase(layer); 262 return HWC2::Error::None; 263 } 264 265 HWC2::Error DrmHwcTwo::HwcDisplay::GetActiveConfig(hwc2_config_t *config) { 266 supported(__func__); 267 DrmMode const &mode = connector_->active_mode(); 268 if (mode.id() == 0) 269 return HWC2::Error::BadConfig; 270 271 *config = mode.id(); 272 return HWC2::Error::None; 273 } 274 275 HWC2::Error DrmHwcTwo::HwcDisplay::GetChangedCompositionTypes( 276 uint32_t *num_elements, hwc2_layer_t *layers, int32_t *types) { 277 supported(__func__); 278 uint32_t num_changes = 0; 279 for (std::pair<const hwc2_layer_t, DrmHwcTwo::HwcLayer> &l : layers_) { 280 if (l.second.type_changed()) { 281 if (layers && num_changes < *num_elements) 282 layers[num_changes] = l.first; 283 if (types && num_changes < *num_elements) 284 types[num_changes] = static_cast<int32_t>(l.second.validated_type()); 285 ++num_changes; 286 } 287 } 288 if (!layers && !types) 289 *num_elements = num_changes; 290 return HWC2::Error::None; 291 } 292 293 HWC2::Error DrmHwcTwo::HwcDisplay::GetClientTargetSupport(uint32_t width, 294 uint32_t height, 295 int32_t /*format*/, 296 int32_t dataspace) { 297 supported(__func__); 298 std::pair<uint32_t, uint32_t> min = drm_->min_resolution(); 299 std::pair<uint32_t, uint32_t> max = drm_->max_resolution(); 300 301 if (width < min.first || height < min.second) 302 return HWC2::Error::Unsupported; 303 304 if (width > max.first || height > max.second) 305 return HWC2::Error::Unsupported; 306 307 if (dataspace != HAL_DATASPACE_UNKNOWN && 308 dataspace != HAL_DATASPACE_STANDARD_UNSPECIFIED) 309 return HWC2::Error::Unsupported; 310 311 // TODO: Validate format can be handled by either GL or planes 312 return HWC2::Error::None; 313 } 314 315 HWC2::Error DrmHwcTwo::HwcDisplay::GetColorModes(uint32_t *num_modes, 316 int32_t *modes) { 317 supported(__func__); 318 if (!modes) 319 *num_modes = 1; 320 321 if (modes) 322 *modes = HAL_COLOR_MODE_NATIVE; 323 324 return HWC2::Error::None; 325 } 326 327 HWC2::Error DrmHwcTwo::HwcDisplay::GetDisplayAttribute(hwc2_config_t config, 328 int32_t attribute_in, 329 int32_t *value) { 330 supported(__func__); 331 auto mode = 332 std::find_if(connector_->modes().begin(), connector_->modes().end(), 333 [config](DrmMode const &m) { return m.id() == config; }); 334 if (mode == connector_->modes().end()) { 335 ALOGE("Could not find active mode for %d", config); 336 return HWC2::Error::BadConfig; 337 } 338 339 static const int32_t kUmPerInch = 25400; 340 uint32_t mm_width = connector_->mm_width(); 341 uint32_t mm_height = connector_->mm_height(); 342 auto attribute = static_cast<HWC2::Attribute>(attribute_in); 343 switch (attribute) { 344 case HWC2::Attribute::Width: 345 *value = mode->h_display(); 346 break; 347 case HWC2::Attribute::Height: 348 *value = mode->v_display(); 349 break; 350 case HWC2::Attribute::VsyncPeriod: 351 // in nanoseconds 352 *value = 1000 * 1000 * 1000 / mode->v_refresh(); 353 break; 354 case HWC2::Attribute::DpiX: 355 // Dots per 1000 inches 356 *value = mm_width ? (mode->h_display() * kUmPerInch) / mm_width : -1; 357 break; 358 case HWC2::Attribute::DpiY: 359 // Dots per 1000 inches 360 *value = mm_height ? (mode->v_display() * kUmPerInch) / mm_height : -1; 361 break; 362 default: 363 *value = -1; 364 return HWC2::Error::BadConfig; 365 } 366 return HWC2::Error::None; 367 } 368 369 HWC2::Error DrmHwcTwo::HwcDisplay::GetDisplayConfigs(uint32_t *num_configs, 370 hwc2_config_t *configs) { 371 supported(__func__); 372 // Since this callback is normally invoked twice (once to get the count, and 373 // once to populate configs), we don't really want to read the edid 374 // redundantly. Instead, only update the modes on the first invocation. While 375 // it's possible this will result in stale modes, it'll all come out in the 376 // wash when we try to set the active config later. 377 if (!configs) { 378 int ret = connector_->UpdateModes(); 379 if (ret) { 380 ALOGE("Failed to update display modes %d", ret); 381 return HWC2::Error::BadDisplay; 382 } 383 } 384 385 auto num_modes = static_cast<uint32_t>(connector_->modes().size()); 386 if (!configs) { 387 *num_configs = num_modes; 388 return HWC2::Error::None; 389 } 390 391 uint32_t idx = 0; 392 for (const DrmMode &mode : connector_->modes()) { 393 if (idx >= *num_configs) 394 break; 395 configs[idx++] = mode.id(); 396 } 397 *num_configs = idx; 398 return HWC2::Error::None; 399 } 400 401 HWC2::Error DrmHwcTwo::HwcDisplay::GetDisplayName(uint32_t *size, char *name) { 402 supported(__func__); 403 std::ostringstream stream; 404 stream << "display-" << connector_->id(); 405 std::string string = stream.str(); 406 size_t length = string.length(); 407 if (!name) { 408 *size = length; 409 return HWC2::Error::None; 410 } 411 412 *size = std::min<uint32_t>(static_cast<uint32_t>(length - 1), *size); 413 strncpy(name, string.c_str(), *size); 414 return HWC2::Error::None; 415 } 416 417 HWC2::Error DrmHwcTwo::HwcDisplay::GetDisplayRequests(int32_t *display_requests, 418 uint32_t *num_elements, 419 hwc2_layer_t *layers, 420 int32_t *layer_requests) { 421 supported(__func__); 422 // TODO: I think virtual display should request 423 // HWC2_DISPLAY_REQUEST_WRITE_CLIENT_TARGET_TO_OUTPUT here 424 unsupported(__func__, display_requests, num_elements, layers, layer_requests); 425 *num_elements = 0; 426 return HWC2::Error::None; 427 } 428 429 HWC2::Error DrmHwcTwo::HwcDisplay::GetDisplayType(int32_t *type) { 430 supported(__func__); 431 *type = static_cast<int32_t>(type_); 432 return HWC2::Error::None; 433 } 434 435 HWC2::Error DrmHwcTwo::HwcDisplay::GetDozeSupport(int32_t *support) { 436 supported(__func__); 437 *support = 0; 438 return HWC2::Error::None; 439 } 440 441 HWC2::Error DrmHwcTwo::HwcDisplay::GetHdrCapabilities( 442 uint32_t *num_types, int32_t */*types*/, float */*max_luminance*/, 443 float */*max_average_luminance*/, float */*min_luminance*/) { 444 supported(__func__); 445 *num_types = 0; 446 return HWC2::Error::None; 447 } 448 449 HWC2::Error DrmHwcTwo::HwcDisplay::GetReleaseFences(uint32_t *num_elements, 450 hwc2_layer_t *layers, 451 int32_t *fences) { 452 supported(__func__); 453 uint32_t num_layers = 0; 454 455 for (std::pair<const hwc2_layer_t, DrmHwcTwo::HwcLayer> &l : layers_) { 456 ++num_layers; 457 if (layers == NULL || fences == NULL) { 458 continue; 459 } else if (num_layers > *num_elements) { 460 ALOGW("Overflow num_elements %d/%d", num_layers, *num_elements); 461 return HWC2::Error::None; 462 } 463 464 layers[num_layers - 1] = l.first; 465 fences[num_layers - 1] = l.second.take_release_fence(); 466 } 467 *num_elements = num_layers; 468 return HWC2::Error::None; 469 } 470 471 void DrmHwcTwo::HwcDisplay::AddFenceToRetireFence(int fd) { 472 supported(__func__); 473 if (fd < 0) 474 return; 475 476 if (next_retire_fence_.get() >= 0) { 477 int old_fence = next_retire_fence_.get(); 478 next_retire_fence_.Set(sync_merge("dc_retire", old_fence, fd)); 479 } else { 480 next_retire_fence_.Set(dup(fd)); 481 } 482 } 483 484 HWC2::Error DrmHwcTwo::HwcDisplay::PresentDisplay(int32_t *retire_fence) { 485 supported(__func__); 486 std::vector<DrmCompositionDisplayLayersMap> layers_map; 487 layers_map.emplace_back(); 488 DrmCompositionDisplayLayersMap &map = layers_map.back(); 489 490 map.display = static_cast<int>(handle_); 491 map.geometry_changed = true; // TODO: Fix this 492 493 // order the layers by z-order 494 bool use_client_layer = false; 495 uint32_t client_z_order = 0; 496 std::map<uint32_t, DrmHwcTwo::HwcLayer *> z_map; 497 for (std::pair<const hwc2_layer_t, DrmHwcTwo::HwcLayer> &l : layers_) { 498 switch (l.second.validated_type()) { 499 case HWC2::Composition::Device: 500 z_map.emplace(std::make_pair(l.second.z_order(), &l.second)); 501 break; 502 case HWC2::Composition::Client: 503 // Place it at the z_order of the highest client layer 504 use_client_layer = true; 505 client_z_order = std::max(client_z_order, l.second.z_order()); 506 break; 507 default: 508 continue; 509 } 510 } 511 if (use_client_layer) 512 z_map.emplace(std::make_pair(client_z_order, &client_layer_)); 513 514 // now that they're ordered by z, add them to the composition 515 for (std::pair<const uint32_t, DrmHwcTwo::HwcLayer *> &l : z_map) { 516 DrmHwcLayer layer; 517 l.second->PopulateDrmLayer(&layer); 518 int ret = layer.ImportBuffer(importer_.get(), gralloc_); 519 if (ret) { 520 ALOGE("Failed to import layer, ret=%d", ret); 521 return HWC2::Error::NoResources; 522 } 523 map.layers.emplace_back(std::move(layer)); 524 } 525 if (map.layers.empty()) { 526 *retire_fence = -1; 527 return HWC2::Error::None; 528 } 529 530 std::unique_ptr<DrmDisplayComposition> composition = 531 compositor_.CreateComposition(); 532 composition->Init(drm_, crtc_, importer_.get(), planner_.get(), frame_no_); 533 534 // TODO: Don't always assume geometry changed 535 int ret = composition->SetLayers(map.layers.data(), map.layers.size(), true); 536 if (ret) { 537 ALOGE("Failed to set layers in the composition ret=%d", ret); 538 return HWC2::Error::BadLayer; 539 } 540 541 std::vector<DrmPlane *> primary_planes(primary_planes_); 542 std::vector<DrmPlane *> overlay_planes(overlay_planes_); 543 ret = composition->Plan(compositor_.squash_state(), &primary_planes, 544 &overlay_planes); 545 if (ret) { 546 ALOGE("Failed to plan the composition ret=%d", ret); 547 return HWC2::Error::BadConfig; 548 } 549 550 // Disable the planes we're not using 551 for (auto i = primary_planes.begin(); i != primary_planes.end();) { 552 composition->AddPlaneDisable(*i); 553 i = primary_planes.erase(i); 554 } 555 for (auto i = overlay_planes.begin(); i != overlay_planes.end();) { 556 composition->AddPlaneDisable(*i); 557 i = overlay_planes.erase(i); 558 } 559 560 ret = compositor_.QueueComposition(std::move(composition)); 561 if (ret) { 562 ALOGE("Failed to apply the frame composition ret=%d", ret); 563 return HWC2::Error::BadParameter; 564 } 565 566 // Now that the release fences have been generated by the compositor, make 567 // sure they're managed properly 568 for (std::pair<const uint32_t, DrmHwcTwo::HwcLayer *> &l : z_map) { 569 l.second->manage_release_fence(); 570 AddFenceToRetireFence(l.second->release_fence()); 571 } 572 573 // The retire fence returned here is for the last frame, so return it and 574 // promote the next retire fence 575 *retire_fence = retire_fence_.Release(); 576 retire_fence_ = std::move(next_retire_fence_); 577 578 ++frame_no_; 579 return HWC2::Error::None; 580 } 581 582 HWC2::Error DrmHwcTwo::HwcDisplay::SetActiveConfig(hwc2_config_t config) { 583 supported(__func__); 584 auto mode = 585 std::find_if(connector_->modes().begin(), connector_->modes().end(), 586 [config](DrmMode const &m) { return m.id() == config; }); 587 if (mode == connector_->modes().end()) { 588 ALOGE("Could not find active mode for %d", config); 589 return HWC2::Error::BadConfig; 590 } 591 592 std::unique_ptr<DrmDisplayComposition> composition = 593 compositor_.CreateComposition(); 594 composition->Init(drm_, crtc_, importer_.get(), planner_.get(), frame_no_); 595 int ret = composition->SetDisplayMode(*mode); 596 ret = compositor_.QueueComposition(std::move(composition)); 597 if (ret) { 598 ALOGE("Failed to queue dpms composition on %d", ret); 599 return HWC2::Error::BadConfig; 600 } 601 if (connector_->active_mode().id() == 0) 602 connector_->set_active_mode(*mode); 603 604 // Setup the client layer's dimensions 605 hwc_rect_t display_frame = {.left = 0, 606 .top = 0, 607 .right = static_cast<int>(mode->h_display()), 608 .bottom = static_cast<int>(mode->v_display())}; 609 client_layer_.SetLayerDisplayFrame(display_frame); 610 hwc_frect_t source_crop = {.left = 0.0f, 611 .top = 0.0f, 612 .right = mode->h_display() + 0.0f, 613 .bottom = mode->v_display() + 0.0f}; 614 client_layer_.SetLayerSourceCrop(source_crop); 615 616 return HWC2::Error::None; 617 } 618 619 HWC2::Error DrmHwcTwo::HwcDisplay::SetClientTarget(buffer_handle_t target, 620 int32_t acquire_fence, 621 int32_t dataspace, 622 hwc_region_t damage) { 623 supported(__func__); 624 UniqueFd uf(acquire_fence); 625 626 client_layer_.set_buffer(target); 627 client_layer_.set_acquire_fence(uf.get()); 628 client_layer_.SetLayerDataspace(dataspace); 629 return HWC2::Error::None; 630 } 631 632 HWC2::Error DrmHwcTwo::HwcDisplay::SetColorMode(int32_t mode) { 633 supported(__func__); 634 635 if (mode != HAL_COLOR_MODE_NATIVE) 636 return HWC2::Error::Unsupported; 637 638 color_mode_ = mode; 639 return HWC2::Error::None; 640 } 641 642 HWC2::Error DrmHwcTwo::HwcDisplay::SetColorTransform(const float *matrix, 643 int32_t hint) { 644 supported(__func__); 645 // TODO: Force client composition if we get this 646 return unsupported(__func__, matrix, hint); 647 } 648 649 HWC2::Error DrmHwcTwo::HwcDisplay::SetOutputBuffer(buffer_handle_t buffer, 650 int32_t release_fence) { 651 supported(__func__); 652 // TODO: Need virtual display support 653 return unsupported(__func__, buffer, release_fence); 654 } 655 656 HWC2::Error DrmHwcTwo::HwcDisplay::SetPowerMode(int32_t mode_in) { 657 supported(__func__); 658 uint64_t dpms_value = 0; 659 auto mode = static_cast<HWC2::PowerMode>(mode_in); 660 switch (mode) { 661 case HWC2::PowerMode::Off: 662 dpms_value = DRM_MODE_DPMS_OFF; 663 break; 664 case HWC2::PowerMode::On: 665 dpms_value = DRM_MODE_DPMS_ON; 666 break; 667 default: 668 ALOGI("Power mode %d is unsupported\n", mode); 669 return HWC2::Error::Unsupported; 670 }; 671 672 std::unique_ptr<DrmDisplayComposition> composition = 673 compositor_.CreateComposition(); 674 composition->Init(drm_, crtc_, importer_.get(), planner_.get(), frame_no_); 675 composition->SetDpmsMode(dpms_value); 676 int ret = compositor_.QueueComposition(std::move(composition)); 677 if (ret) { 678 ALOGE("Failed to apply the dpms composition ret=%d", ret); 679 return HWC2::Error::BadParameter; 680 } 681 return HWC2::Error::None; 682 } 683 684 HWC2::Error DrmHwcTwo::HwcDisplay::SetVsyncEnabled(int32_t enabled) { 685 supported(__func__); 686 vsync_worker_.VSyncControl(enabled); 687 return HWC2::Error::None; 688 } 689 690 HWC2::Error DrmHwcTwo::HwcDisplay::ValidateDisplay(uint32_t *num_types, 691 uint32_t *num_requests) { 692 supported(__func__); 693 *num_types = 0; 694 *num_requests = 0; 695 for (std::pair<const hwc2_layer_t, DrmHwcTwo::HwcLayer> &l : layers_) { 696 DrmHwcTwo::HwcLayer &layer = l.second; 697 switch (layer.sf_type()) { 698 case HWC2::Composition::SolidColor: 699 case HWC2::Composition::Cursor: 700 case HWC2::Composition::Sideband: 701 layer.set_validated_type(HWC2::Composition::Client); 702 ++*num_types; 703 break; 704 default: 705 layer.set_validated_type(layer.sf_type()); 706 break; 707 } 708 } 709 return HWC2::Error::None; 710 } 711 712 HWC2::Error DrmHwcTwo::HwcLayer::SetCursorPosition(int32_t x, int32_t y) { 713 supported(__func__); 714 cursor_x_ = x; 715 cursor_y_ = y; 716 return HWC2::Error::None; 717 } 718 719 HWC2::Error DrmHwcTwo::HwcLayer::SetLayerBlendMode(int32_t mode) { 720 supported(__func__); 721 blending_ = static_cast<HWC2::BlendMode>(mode); 722 return HWC2::Error::None; 723 } 724 725 HWC2::Error DrmHwcTwo::HwcLayer::SetLayerBuffer(buffer_handle_t buffer, 726 int32_t acquire_fence) { 727 supported(__func__); 728 UniqueFd uf(acquire_fence); 729 730 // The buffer and acquire_fence are handled elsewhere 731 if (sf_type_ == HWC2::Composition::Client || 732 sf_type_ == HWC2::Composition::Sideband || 733 sf_type_ == HWC2::Composition::SolidColor) 734 return HWC2::Error::None; 735 736 set_buffer(buffer); 737 set_acquire_fence(uf.get()); 738 return HWC2::Error::None; 739 } 740 741 HWC2::Error DrmHwcTwo::HwcLayer::SetLayerColor(hwc_color_t color) { 742 // TODO: Punt to client composition here? 743 return unsupported(__func__, color); 744 } 745 746 HWC2::Error DrmHwcTwo::HwcLayer::SetLayerCompositionType(int32_t type) { 747 sf_type_ = static_cast<HWC2::Composition>(type); 748 return HWC2::Error::None; 749 } 750 751 HWC2::Error DrmHwcTwo::HwcLayer::SetLayerDataspace(int32_t dataspace) { 752 supported(__func__); 753 dataspace_ = static_cast<android_dataspace_t>(dataspace); 754 return HWC2::Error::None; 755 } 756 757 HWC2::Error DrmHwcTwo::HwcLayer::SetLayerDisplayFrame(hwc_rect_t frame) { 758 supported(__func__); 759 display_frame_ = frame; 760 return HWC2::Error::None; 761 } 762 763 HWC2::Error DrmHwcTwo::HwcLayer::SetLayerPlaneAlpha(float alpha) { 764 supported(__func__); 765 alpha_ = alpha; 766 return HWC2::Error::None; 767 } 768 769 HWC2::Error DrmHwcTwo::HwcLayer::SetLayerSidebandStream( 770 const native_handle_t *stream) { 771 supported(__func__); 772 // TODO: We don't support sideband 773 return unsupported(__func__, stream); 774 } 775 776 HWC2::Error DrmHwcTwo::HwcLayer::SetLayerSourceCrop(hwc_frect_t crop) { 777 supported(__func__); 778 source_crop_ = crop; 779 return HWC2::Error::None; 780 } 781 782 HWC2::Error DrmHwcTwo::HwcLayer::SetLayerSurfaceDamage(hwc_region_t damage) { 783 supported(__func__); 784 // TODO: We don't use surface damage, marking as unsupported 785 unsupported(__func__, damage); 786 return HWC2::Error::None; 787 } 788 789 HWC2::Error DrmHwcTwo::HwcLayer::SetLayerTransform(int32_t transform) { 790 supported(__func__); 791 transform_ = static_cast<HWC2::Transform>(transform); 792 return HWC2::Error::None; 793 } 794 795 HWC2::Error DrmHwcTwo::HwcLayer::SetLayerVisibleRegion(hwc_region_t visible) { 796 supported(__func__); 797 // TODO: We don't use this information, marking as unsupported 798 unsupported(__func__, visible); 799 return HWC2::Error::None; 800 } 801 802 HWC2::Error DrmHwcTwo::HwcLayer::SetLayerZOrder(uint32_t order) { 803 supported(__func__); 804 z_order_ = order; 805 return HWC2::Error::None; 806 } 807 808 void DrmHwcTwo::HwcLayer::PopulateDrmLayer(DrmHwcLayer *layer) { 809 supported(__func__); 810 switch (blending_) { 811 case HWC2::BlendMode::None: 812 layer->blending = DrmHwcBlending::kNone; 813 break; 814 case HWC2::BlendMode::Premultiplied: 815 layer->blending = DrmHwcBlending::kPreMult; 816 break; 817 case HWC2::BlendMode::Coverage: 818 layer->blending = DrmHwcBlending::kCoverage; 819 break; 820 default: 821 ALOGE("Unknown blending mode b=%d", blending_); 822 layer->blending = DrmHwcBlending::kNone; 823 break; 824 } 825 826 OutputFd release_fence = release_fence_output(); 827 828 layer->sf_handle = buffer_; 829 layer->acquire_fence = acquire_fence_.Release(); 830 layer->release_fence = std::move(release_fence); 831 layer->SetDisplayFrame(display_frame_); 832 layer->alpha = static_cast<uint8_t>(255.0f * alpha_ + 0.5f); 833 layer->SetSourceCrop(source_crop_); 834 layer->SetTransform(static_cast<int32_t>(transform_)); 835 } 836 837 // static 838 int DrmHwcTwo::HookDevClose(hw_device_t * /*dev*/) { 839 unsupported(__func__); 840 return 0; 841 } 842 843 // static 844 void DrmHwcTwo::HookDevGetCapabilities(hwc2_device_t * /*dev*/, 845 uint32_t *out_count, 846 int32_t * /*out_capabilities*/) { 847 supported(__func__); 848 *out_count = 0; 849 } 850 851 // static 852 hwc2_function_pointer_t DrmHwcTwo::HookDevGetFunction( 853 struct hwc2_device * /*dev*/, int32_t descriptor) { 854 supported(__func__); 855 auto func = static_cast<HWC2::FunctionDescriptor>(descriptor); 856 switch (func) { 857 // Device functions 858 case HWC2::FunctionDescriptor::CreateVirtualDisplay: 859 return ToHook<HWC2_PFN_CREATE_VIRTUAL_DISPLAY>( 860 DeviceHook<int32_t, decltype(&DrmHwcTwo::CreateVirtualDisplay), 861 &DrmHwcTwo::CreateVirtualDisplay, uint32_t, uint32_t, 862 int32_t*, hwc2_display_t *>); 863 case HWC2::FunctionDescriptor::DestroyVirtualDisplay: 864 return ToHook<HWC2_PFN_DESTROY_VIRTUAL_DISPLAY>( 865 DeviceHook<int32_t, decltype(&DrmHwcTwo::DestroyVirtualDisplay), 866 &DrmHwcTwo::DestroyVirtualDisplay, hwc2_display_t>); 867 case HWC2::FunctionDescriptor::Dump: 868 return ToHook<HWC2_PFN_DUMP>( 869 DeviceHook<void, decltype(&DrmHwcTwo::Dump), &DrmHwcTwo::Dump, 870 uint32_t *, char *>); 871 case HWC2::FunctionDescriptor::GetMaxVirtualDisplayCount: 872 return ToHook<HWC2_PFN_GET_MAX_VIRTUAL_DISPLAY_COUNT>( 873 DeviceHook<uint32_t, decltype(&DrmHwcTwo::GetMaxVirtualDisplayCount), 874 &DrmHwcTwo::GetMaxVirtualDisplayCount>); 875 case HWC2::FunctionDescriptor::RegisterCallback: 876 return ToHook<HWC2_PFN_REGISTER_CALLBACK>( 877 DeviceHook<int32_t, decltype(&DrmHwcTwo::RegisterCallback), 878 &DrmHwcTwo::RegisterCallback, int32_t, 879 hwc2_callback_data_t, hwc2_function_pointer_t>); 880 881 // Display functions 882 case HWC2::FunctionDescriptor::AcceptDisplayChanges: 883 return ToHook<HWC2_PFN_ACCEPT_DISPLAY_CHANGES>( 884 DisplayHook<decltype(&HwcDisplay::AcceptDisplayChanges), 885 &HwcDisplay::AcceptDisplayChanges>); 886 case HWC2::FunctionDescriptor::CreateLayer: 887 return ToHook<HWC2_PFN_CREATE_LAYER>( 888 DisplayHook<decltype(&HwcDisplay::CreateLayer), 889 &HwcDisplay::CreateLayer, hwc2_layer_t *>); 890 case HWC2::FunctionDescriptor::DestroyLayer: 891 return ToHook<HWC2_PFN_DESTROY_LAYER>( 892 DisplayHook<decltype(&HwcDisplay::DestroyLayer), 893 &HwcDisplay::DestroyLayer, hwc2_layer_t>); 894 case HWC2::FunctionDescriptor::GetActiveConfig: 895 return ToHook<HWC2_PFN_GET_ACTIVE_CONFIG>( 896 DisplayHook<decltype(&HwcDisplay::GetActiveConfig), 897 &HwcDisplay::GetActiveConfig, hwc2_config_t *>); 898 case HWC2::FunctionDescriptor::GetChangedCompositionTypes: 899 return ToHook<HWC2_PFN_GET_CHANGED_COMPOSITION_TYPES>( 900 DisplayHook<decltype(&HwcDisplay::GetChangedCompositionTypes), 901 &HwcDisplay::GetChangedCompositionTypes, uint32_t *, 902 hwc2_layer_t *, int32_t *>); 903 case HWC2::FunctionDescriptor::GetClientTargetSupport: 904 return ToHook<HWC2_PFN_GET_CLIENT_TARGET_SUPPORT>( 905 DisplayHook<decltype(&HwcDisplay::GetClientTargetSupport), 906 &HwcDisplay::GetClientTargetSupport, uint32_t, uint32_t, 907 int32_t, int32_t>); 908 case HWC2::FunctionDescriptor::GetColorModes: 909 return ToHook<HWC2_PFN_GET_COLOR_MODES>( 910 DisplayHook<decltype(&HwcDisplay::GetColorModes), 911 &HwcDisplay::GetColorModes, uint32_t *, int32_t *>); 912 case HWC2::FunctionDescriptor::GetDisplayAttribute: 913 return ToHook<HWC2_PFN_GET_DISPLAY_ATTRIBUTE>(DisplayHook< 914 decltype(&HwcDisplay::GetDisplayAttribute), 915 &HwcDisplay::GetDisplayAttribute, hwc2_config_t, int32_t, int32_t *>); 916 case HWC2::FunctionDescriptor::GetDisplayConfigs: 917 return ToHook<HWC2_PFN_GET_DISPLAY_CONFIGS>(DisplayHook< 918 decltype(&HwcDisplay::GetDisplayConfigs), 919 &HwcDisplay::GetDisplayConfigs, uint32_t *, hwc2_config_t *>); 920 case HWC2::FunctionDescriptor::GetDisplayName: 921 return ToHook<HWC2_PFN_GET_DISPLAY_NAME>( 922 DisplayHook<decltype(&HwcDisplay::GetDisplayName), 923 &HwcDisplay::GetDisplayName, uint32_t *, char *>); 924 case HWC2::FunctionDescriptor::GetDisplayRequests: 925 return ToHook<HWC2_PFN_GET_DISPLAY_REQUESTS>( 926 DisplayHook<decltype(&HwcDisplay::GetDisplayRequests), 927 &HwcDisplay::GetDisplayRequests, int32_t *, uint32_t *, 928 hwc2_layer_t *, int32_t *>); 929 case HWC2::FunctionDescriptor::GetDisplayType: 930 return ToHook<HWC2_PFN_GET_DISPLAY_TYPE>( 931 DisplayHook<decltype(&HwcDisplay::GetDisplayType), 932 &HwcDisplay::GetDisplayType, int32_t *>); 933 case HWC2::FunctionDescriptor::GetDozeSupport: 934 return ToHook<HWC2_PFN_GET_DOZE_SUPPORT>( 935 DisplayHook<decltype(&HwcDisplay::GetDozeSupport), 936 &HwcDisplay::GetDozeSupport, int32_t *>); 937 case HWC2::FunctionDescriptor::GetHdrCapabilities: 938 return ToHook<HWC2_PFN_GET_HDR_CAPABILITIES>( 939 DisplayHook<decltype(&HwcDisplay::GetHdrCapabilities), 940 &HwcDisplay::GetHdrCapabilities, uint32_t *, int32_t *, 941 float *, float *, float *>); 942 case HWC2::FunctionDescriptor::GetReleaseFences: 943 return ToHook<HWC2_PFN_GET_RELEASE_FENCES>( 944 DisplayHook<decltype(&HwcDisplay::GetReleaseFences), 945 &HwcDisplay::GetReleaseFences, uint32_t *, hwc2_layer_t *, 946 int32_t *>); 947 case HWC2::FunctionDescriptor::PresentDisplay: 948 return ToHook<HWC2_PFN_PRESENT_DISPLAY>( 949 DisplayHook<decltype(&HwcDisplay::PresentDisplay), 950 &HwcDisplay::PresentDisplay, int32_t *>); 951 case HWC2::FunctionDescriptor::SetActiveConfig: 952 return ToHook<HWC2_PFN_SET_ACTIVE_CONFIG>( 953 DisplayHook<decltype(&HwcDisplay::SetActiveConfig), 954 &HwcDisplay::SetActiveConfig, hwc2_config_t>); 955 case HWC2::FunctionDescriptor::SetClientTarget: 956 return ToHook<HWC2_PFN_SET_CLIENT_TARGET>(DisplayHook< 957 decltype(&HwcDisplay::SetClientTarget), &HwcDisplay::SetClientTarget, 958 buffer_handle_t, int32_t, int32_t, hwc_region_t>); 959 case HWC2::FunctionDescriptor::SetColorMode: 960 return ToHook<HWC2_PFN_SET_COLOR_MODE>( 961 DisplayHook<decltype(&HwcDisplay::SetColorMode), 962 &HwcDisplay::SetColorMode, int32_t>); 963 case HWC2::FunctionDescriptor::SetColorTransform: 964 return ToHook<HWC2_PFN_SET_COLOR_TRANSFORM>( 965 DisplayHook<decltype(&HwcDisplay::SetColorTransform), 966 &HwcDisplay::SetColorTransform, const float *, int32_t>); 967 case HWC2::FunctionDescriptor::SetOutputBuffer: 968 return ToHook<HWC2_PFN_SET_OUTPUT_BUFFER>( 969 DisplayHook<decltype(&HwcDisplay::SetOutputBuffer), 970 &HwcDisplay::SetOutputBuffer, buffer_handle_t, int32_t>); 971 case HWC2::FunctionDescriptor::SetPowerMode: 972 return ToHook<HWC2_PFN_SET_POWER_MODE>( 973 DisplayHook<decltype(&HwcDisplay::SetPowerMode), 974 &HwcDisplay::SetPowerMode, int32_t>); 975 case HWC2::FunctionDescriptor::SetVsyncEnabled: 976 return ToHook<HWC2_PFN_SET_VSYNC_ENABLED>( 977 DisplayHook<decltype(&HwcDisplay::SetVsyncEnabled), 978 &HwcDisplay::SetVsyncEnabled, int32_t>); 979 case HWC2::FunctionDescriptor::ValidateDisplay: 980 return ToHook<HWC2_PFN_VALIDATE_DISPLAY>( 981 DisplayHook<decltype(&HwcDisplay::ValidateDisplay), 982 &HwcDisplay::ValidateDisplay, uint32_t *, uint32_t *>); 983 984 // Layer functions 985 case HWC2::FunctionDescriptor::SetCursorPosition: 986 return ToHook<HWC2_PFN_SET_CURSOR_POSITION>( 987 LayerHook<decltype(&HwcLayer::SetCursorPosition), 988 &HwcLayer::SetCursorPosition, int32_t, int32_t>); 989 case HWC2::FunctionDescriptor::SetLayerBlendMode: 990 return ToHook<HWC2_PFN_SET_LAYER_BLEND_MODE>( 991 LayerHook<decltype(&HwcLayer::SetLayerBlendMode), 992 &HwcLayer::SetLayerBlendMode, int32_t>); 993 case HWC2::FunctionDescriptor::SetLayerBuffer: 994 return ToHook<HWC2_PFN_SET_LAYER_BUFFER>( 995 LayerHook<decltype(&HwcLayer::SetLayerBuffer), 996 &HwcLayer::SetLayerBuffer, buffer_handle_t, int32_t>); 997 case HWC2::FunctionDescriptor::SetLayerColor: 998 return ToHook<HWC2_PFN_SET_LAYER_COLOR>( 999 LayerHook<decltype(&HwcLayer::SetLayerColor), 1000 &HwcLayer::SetLayerColor, hwc_color_t>); 1001 case HWC2::FunctionDescriptor::SetLayerCompositionType: 1002 return ToHook<HWC2_PFN_SET_LAYER_COMPOSITION_TYPE>( 1003 LayerHook<decltype(&HwcLayer::SetLayerCompositionType), 1004 &HwcLayer::SetLayerCompositionType, int32_t>); 1005 case HWC2::FunctionDescriptor::SetLayerDataspace: 1006 return ToHook<HWC2_PFN_SET_LAYER_DATASPACE>( 1007 LayerHook<decltype(&HwcLayer::SetLayerDataspace), 1008 &HwcLayer::SetLayerDataspace, int32_t>); 1009 case HWC2::FunctionDescriptor::SetLayerDisplayFrame: 1010 return ToHook<HWC2_PFN_SET_LAYER_DISPLAY_FRAME>( 1011 LayerHook<decltype(&HwcLayer::SetLayerDisplayFrame), 1012 &HwcLayer::SetLayerDisplayFrame, hwc_rect_t>); 1013 case HWC2::FunctionDescriptor::SetLayerPlaneAlpha: 1014 return ToHook<HWC2_PFN_SET_LAYER_PLANE_ALPHA>( 1015 LayerHook<decltype(&HwcLayer::SetLayerPlaneAlpha), 1016 &HwcLayer::SetLayerPlaneAlpha, float>); 1017 case HWC2::FunctionDescriptor::SetLayerSidebandStream: 1018 return ToHook<HWC2_PFN_SET_LAYER_SIDEBAND_STREAM>(LayerHook< 1019 decltype(&HwcLayer::SetLayerSidebandStream), 1020 &HwcLayer::SetLayerSidebandStream, const native_handle_t *>); 1021 case HWC2::FunctionDescriptor::SetLayerSourceCrop: 1022 return ToHook<HWC2_PFN_SET_LAYER_SOURCE_CROP>( 1023 LayerHook<decltype(&HwcLayer::SetLayerSourceCrop), 1024 &HwcLayer::SetLayerSourceCrop, hwc_frect_t>); 1025 case HWC2::FunctionDescriptor::SetLayerSurfaceDamage: 1026 return ToHook<HWC2_PFN_SET_LAYER_SURFACE_DAMAGE>( 1027 LayerHook<decltype(&HwcLayer::SetLayerSurfaceDamage), 1028 &HwcLayer::SetLayerSurfaceDamage, hwc_region_t>); 1029 case HWC2::FunctionDescriptor::SetLayerTransform: 1030 return ToHook<HWC2_PFN_SET_LAYER_TRANSFORM>( 1031 LayerHook<decltype(&HwcLayer::SetLayerTransform), 1032 &HwcLayer::SetLayerTransform, int32_t>); 1033 case HWC2::FunctionDescriptor::SetLayerVisibleRegion: 1034 return ToHook<HWC2_PFN_SET_LAYER_VISIBLE_REGION>( 1035 LayerHook<decltype(&HwcLayer::SetLayerVisibleRegion), 1036 &HwcLayer::SetLayerVisibleRegion, hwc_region_t>); 1037 case HWC2::FunctionDescriptor::SetLayerZOrder: 1038 return ToHook<HWC2_PFN_SET_LAYER_Z_ORDER>( 1039 LayerHook<decltype(&HwcLayer::SetLayerZOrder), 1040 &HwcLayer::SetLayerZOrder, uint32_t>); 1041 case HWC2::FunctionDescriptor::Invalid: 1042 default: 1043 return NULL; 1044 } 1045 } 1046 1047 // static 1048 int DrmHwcTwo::HookDevOpen(const struct hw_module_t *module, const char *name, 1049 struct hw_device_t **dev) { 1050 supported(__func__); 1051 if (strcmp(name, HWC_HARDWARE_COMPOSER)) { 1052 ALOGE("Invalid module name- %s", name); 1053 return -EINVAL; 1054 } 1055 1056 std::unique_ptr<DrmHwcTwo> ctx(new DrmHwcTwo()); 1057 if (!ctx) { 1058 ALOGE("Failed to allocate DrmHwcTwo"); 1059 return -ENOMEM; 1060 } 1061 1062 HWC2::Error err = ctx->Init(); 1063 if (err != HWC2::Error::None) { 1064 ALOGE("Failed to initialize DrmHwcTwo err=%d\n", err); 1065 return -EINVAL; 1066 } 1067 1068 ctx->common.module = const_cast<hw_module_t *>(module); 1069 *dev = &ctx->common; 1070 ctx.release(); 1071 return 0; 1072 } 1073 } 1074 1075 static struct hw_module_methods_t hwc2_module_methods = { 1076 .open = android::DrmHwcTwo::HookDevOpen, 1077 }; 1078 1079 hw_module_t HAL_MODULE_INFO_SYM = { 1080 .tag = HARDWARE_MODULE_TAG, 1081 .module_api_version = HARDWARE_MODULE_API_VERSION(2, 0), 1082 .id = HWC_HARDWARE_MODULE_ID, 1083 .name = "DrmHwcTwo module", 1084 .author = "The Android Open Source Project", 1085 .methods = &hwc2_module_methods, 1086 .dso = NULL, 1087 .reserved = {0}, 1088 }; 1089