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