Home | History | Annotate | Download | only in drm_hwcomposer
      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