diff --git a/DrmHwcTwo.cpp b/DrmHwcTwo.cpp
new file mode 100644
index 0000000..15fa324
--- /dev/null
+++ b/DrmHwcTwo.cpp
@@ -0,0 +1,1448 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define ATRACE_TAG ATRACE_TAG_GRAPHICS
+#define LOG_TAG "hwc-drm-two"
+
+#include "DrmHwcTwo.h"
+
+#include <cutils/properties.h>
+#include <hardware/hardware.h>
+#include <hardware/hwcomposer2.h>
+#include <inttypes.h>
+#include <log/log.h>
+
+#include <string>
+
+#include "backend/BackendManager.h"
+#include "compositor/DrmDisplayComposition.h"
+
+namespace android {
+
+class DrmVsyncCallback : public VsyncCallback {
+ public:
+  DrmVsyncCallback(hwc2_callback_data_t data, hwc2_function_pointer_t hook)
+      : data_(data), hook_(hook) {
+  }
+
+  void Callback(int display, int64_t timestamp) {
+    auto hook = reinterpret_cast<HWC2_PFN_VSYNC>(hook_);
+    hook(data_, display, timestamp);
+  }
+
+ private:
+  hwc2_callback_data_t data_;
+  hwc2_function_pointer_t hook_;
+};
+
+DrmHwcTwo::DrmHwcTwo() {
+  common.tag = HARDWARE_DEVICE_TAG;
+  common.version = HWC_DEVICE_API_VERSION_2_0;
+  common.close = HookDevClose;
+  getCapabilities = HookDevGetCapabilities;
+  getFunction = HookDevGetFunction;
+}
+
+HWC2::Error DrmHwcTwo::CreateDisplay(hwc2_display_t displ,
+                                     HWC2::DisplayType type) {
+  DrmDevice *drm = resource_manager_.GetDrmDevice(displ);
+  std::shared_ptr<Importer> importer = resource_manager_.GetImporter(displ);
+  if (!drm || !importer) {
+    ALOGE("Failed to get a valid drmresource and importer");
+    return HWC2::Error::NoResources;
+  }
+  displays_.emplace(std::piecewise_construct, std::forward_as_tuple(displ),
+                    std::forward_as_tuple(&resource_manager_, drm, importer,
+                                          displ, type));
+
+  DrmCrtc *crtc = drm->GetCrtcForDisplay(static_cast<int>(displ));
+  if (!crtc) {
+    ALOGE("Failed to get crtc for display %d", static_cast<int>(displ));
+    return HWC2::Error::BadDisplay;
+  }
+  std::vector<DrmPlane *> display_planes;
+  for (auto &plane : drm->planes()) {
+    if (plane->GetCrtcSupported(*crtc))
+      display_planes.push_back(plane.get());
+  }
+  displays_.at(displ).Init(&display_planes);
+  return HWC2::Error::None;
+}
+
+HWC2::Error DrmHwcTwo::Init() {
+  int rv = resource_manager_.Init();
+  if (rv) {
+    ALOGE("Can't initialize the resource manager %d", rv);
+    return HWC2::Error::NoResources;
+  }
+
+  HWC2::Error ret = HWC2::Error::None;
+  for (int i = 0; i < resource_manager_.getDisplayCount(); i++) {
+    ret = CreateDisplay(i, HWC2::DisplayType::Physical);
+    if (ret != HWC2::Error::None) {
+      ALOGE("Failed to create display %d with error %d", i, ret);
+      return ret;
+    }
+  }
+
+  auto &drmDevices = resource_manager_.getDrmDevices();
+  for (auto &device : drmDevices) {
+    device->RegisterHotplugHandler(new DrmHotplugHandler(this, device.get()));
+  }
+  return ret;
+}
+
+template <typename... Args>
+static inline HWC2::Error unsupported(char const *func, Args... /*args*/) {
+  ALOGV("Unsupported function: %s", func);
+  return HWC2::Error::Unsupported;
+}
+
+static inline void supported(char const *func) {
+  ALOGV("Supported function: %s", func);
+}
+
+HWC2::Error DrmHwcTwo::CreateVirtualDisplay(uint32_t width, uint32_t height,
+                                            int32_t *format,
+                                            hwc2_display_t *display) {
+  // TODO: Implement virtual display
+  return unsupported(__func__, width, height, format, display);
+}
+
+HWC2::Error DrmHwcTwo::DestroyVirtualDisplay(hwc2_display_t display) {
+  // TODO: Implement virtual display
+  return unsupported(__func__, display);
+}
+
+std::string DrmHwcTwo::HwcDisplay::DumpDelta(
+    DrmHwcTwo::HwcDisplay::Stats delta) {
+  if (delta.total_pixops_ == 0)
+    return "No stats yet";
+  double Ratio = 1.0 - double(delta.gpu_pixops_) / double(delta.total_pixops_);
+
+  return (std::stringstream()
+          << " Total frames count: " << delta.total_frames_ << "\n"
+          << " Failed to test commit frames: " << delta.failed_kms_validate_
+          << "\n"
+          << " Failed to commit frames: " << delta.failed_kms_present_ << "\n"
+          << ((delta.failed_kms_present_ > 0)
+                  ? " !!! Internal failure, FIX it please\n"
+                  : "")
+          << " Flattened frames: " << delta.frames_flattened_ << "\n"
+          << " Pixel operations (free units)"
+          << " : [TOTAL: " << delta.total_pixops_
+          << " / GPU: " << delta.gpu_pixops_ << "]\n"
+          << " Composition efficiency: " << Ratio)
+      .str();
+}
+
+std::string DrmHwcTwo::HwcDisplay::Dump() {
+  auto out = (std::stringstream()
+              << "- Display on: " << connector_->name() << "\n"
+              << "  Flattening state: " << compositor_.GetFlatteningState()
+              << "\n"
+              << "Statistics since system boot:\n"
+              << DumpDelta(total_stats_) << "\n\n"
+              << "Statistics since last dumpsys request:\n"
+              << DumpDelta(total_stats_.minus(prev_stats_)) << "\n\n")
+                 .str();
+
+  memcpy(&prev_stats_, &total_stats_, sizeof(Stats));
+  return out;
+}
+
+void DrmHwcTwo::Dump(uint32_t *outSize, char *outBuffer) {
+  supported(__func__);
+
+  if (outBuffer != nullptr) {
+    auto copiedBytes = mDumpString.copy(outBuffer, *outSize);
+    *outSize = static_cast<uint32_t>(copiedBytes);
+    return;
+  }
+
+  std::stringstream output;
+
+  output << "-- drm_hwcomposer --\n\n";
+
+  for (std::pair<const hwc2_display_t, DrmHwcTwo::HwcDisplay> &dp : displays_)
+    output << dp.second.Dump();
+
+  mDumpString = output.str();
+  *outSize = static_cast<uint32_t>(mDumpString.size());
+}
+
+uint32_t DrmHwcTwo::GetMaxVirtualDisplayCount() {
+  // TODO: Implement virtual display
+  unsupported(__func__);
+  return 0;
+}
+
+HWC2::Error DrmHwcTwo::RegisterCallback(int32_t descriptor,
+                                        hwc2_callback_data_t data,
+                                        hwc2_function_pointer_t function) {
+  supported(__func__);
+  auto callback = static_cast<HWC2::Callback>(descriptor);
+
+  if (!function) {
+    callbacks_.erase(callback);
+    return HWC2::Error::None;
+  }
+
+  callbacks_.emplace(callback, HwcCallback(data, function));
+
+  switch (callback) {
+    case HWC2::Callback::Hotplug: {
+      auto &drmDevices = resource_manager_.getDrmDevices();
+      for (auto &device : drmDevices)
+        HandleInitialHotplugState(device.get());
+      break;
+    }
+    case HWC2::Callback::Refresh: {
+      for (std::pair<const hwc2_display_t, DrmHwcTwo::HwcDisplay> &d :
+           displays_)
+        d.second.RegisterRefreshCallback(data, function);
+      break;
+    }
+    case HWC2::Callback::Vsync: {
+      for (std::pair<const hwc2_display_t, DrmHwcTwo::HwcDisplay> &d :
+           displays_)
+        d.second.RegisterVsyncCallback(data, function);
+      break;
+    }
+    default:
+      break;
+  }
+  return HWC2::Error::None;
+}
+
+DrmHwcTwo::HwcDisplay::HwcDisplay(ResourceManager *resource_manager,
+                                  DrmDevice *drm,
+                                  std::shared_ptr<Importer> importer,
+                                  hwc2_display_t handle, HWC2::DisplayType type)
+    : resource_manager_(resource_manager),
+      drm_(drm),
+      importer_(importer),
+      handle_(handle),
+      type_(type),
+      color_transform_hint_(HAL_COLOR_TRANSFORM_IDENTITY) {
+  supported(__func__);
+
+  // clang-format off
+  color_transform_matrix_ = {1.0, 0.0, 0.0, 0.0,
+                             0.0, 1.0, 0.0, 0.0,
+                             0.0, 0.0, 1.0, 0.0,
+                             0.0, 0.0, 0.0, 1.0};
+  // clang-format on
+}
+
+void DrmHwcTwo::HwcDisplay::ClearDisplay() {
+  compositor_.ClearDisplay();
+}
+
+HWC2::Error DrmHwcTwo::HwcDisplay::Init(std::vector<DrmPlane *> *planes) {
+  supported(__func__);
+  planner_ = Planner::CreateInstance(drm_);
+  if (!planner_) {
+    ALOGE("Failed to create planner instance for composition");
+    return HWC2::Error::NoResources;
+  }
+
+  int display = static_cast<int>(handle_);
+  int ret = compositor_.Init(resource_manager_, display);
+  if (ret) {
+    ALOGE("Failed display compositor init for display %d (%d)", display, ret);
+    return HWC2::Error::NoResources;
+  }
+
+  // Split up the given display planes into primary and overlay to properly
+  // interface with the composition
+  char use_overlay_planes_prop[PROPERTY_VALUE_MAX];
+  property_get("vendor.hwc.drm.use_overlay_planes", use_overlay_planes_prop,
+               "1");
+  bool use_overlay_planes = atoi(use_overlay_planes_prop);
+  for (auto &plane : *planes) {
+    if (plane->type() == DRM_PLANE_TYPE_PRIMARY)
+      primary_planes_.push_back(plane);
+    else if (use_overlay_planes && (plane)->type() == DRM_PLANE_TYPE_OVERLAY)
+      overlay_planes_.push_back(plane);
+  }
+
+  crtc_ = drm_->GetCrtcForDisplay(display);
+  if (!crtc_) {
+    ALOGE("Failed to get crtc for display %d", display);
+    return HWC2::Error::BadDisplay;
+  }
+
+  connector_ = drm_->GetConnectorForDisplay(display);
+  if (!connector_) {
+    ALOGE("Failed to get connector for display %d", display);
+    return HWC2::Error::BadDisplay;
+  }
+
+  ret = vsync_worker_.Init(drm_, display);
+  if (ret) {
+    ALOGE("Failed to create event worker for d=%d %d\n", display, ret);
+    return HWC2::Error::BadDisplay;
+  }
+
+  ret = BackendManager::GetInstance().SetBackendForDisplay(this);
+  if (ret) {
+    ALOGE("Failed to set backend for d=%d %d\n", display, ret);
+    return HWC2::Error::BadDisplay;
+  }
+
+  return ChosePreferredConfig();
+}
+
+HWC2::Error DrmHwcTwo::HwcDisplay::ChosePreferredConfig() {
+  // Fetch the number of modes from the display
+  uint32_t num_configs;
+  HWC2::Error err = GetDisplayConfigs(&num_configs, NULL);
+  if (err != HWC2::Error::None || !num_configs)
+    return err;
+
+  return SetActiveConfig(connector_->get_preferred_mode_id());
+}
+
+HWC2::Error DrmHwcTwo::HwcDisplay::RegisterVsyncCallback(
+    hwc2_callback_data_t data, hwc2_function_pointer_t func) {
+  supported(__func__);
+  auto callback = std::make_shared<DrmVsyncCallback>(data, func);
+  vsync_worker_.RegisterCallback(std::move(callback));
+  return HWC2::Error::None;
+}
+
+void DrmHwcTwo::HwcDisplay::RegisterRefreshCallback(
+    hwc2_callback_data_t data, hwc2_function_pointer_t func) {
+  supported(__func__);
+  auto hook = reinterpret_cast<HWC2_PFN_REFRESH>(func);
+  compositor_.SetRefreshCallback([data, hook](int display) {
+    hook(data, static_cast<hwc2_display_t>(display));
+  });
+}
+
+HWC2::Error DrmHwcTwo::HwcDisplay::AcceptDisplayChanges() {
+  supported(__func__);
+  for (std::pair<const hwc2_layer_t, DrmHwcTwo::HwcLayer> &l : layers_)
+    l.second.accept_type_change();
+  return HWC2::Error::None;
+}
+
+HWC2::Error DrmHwcTwo::HwcDisplay::CreateLayer(hwc2_layer_t *layer) {
+  supported(__func__);
+  layers_.emplace(static_cast<hwc2_layer_t>(layer_idx_), HwcLayer());
+  *layer = static_cast<hwc2_layer_t>(layer_idx_);
+  ++layer_idx_;
+  return HWC2::Error::None;
+}
+
+HWC2::Error DrmHwcTwo::HwcDisplay::DestroyLayer(hwc2_layer_t layer) {
+  supported(__func__);
+  if (!get_layer(layer))
+    return HWC2::Error::BadLayer;
+
+  layers_.erase(layer);
+  return HWC2::Error::None;
+}
+
+HWC2::Error DrmHwcTwo::HwcDisplay::GetActiveConfig(hwc2_config_t *config) {
+  supported(__func__);
+  DrmMode const &mode = connector_->active_mode();
+  if (mode.id() == 0)
+    return HWC2::Error::BadConfig;
+
+  *config = mode.id();
+  return HWC2::Error::None;
+}
+
+HWC2::Error DrmHwcTwo::HwcDisplay::GetChangedCompositionTypes(
+    uint32_t *num_elements, hwc2_layer_t *layers, int32_t *types) {
+  supported(__func__);
+  uint32_t num_changes = 0;
+  for (std::pair<const hwc2_layer_t, DrmHwcTwo::HwcLayer> &l : layers_) {
+    if (l.second.type_changed()) {
+      if (layers && num_changes < *num_elements)
+        layers[num_changes] = l.first;
+      if (types && num_changes < *num_elements)
+        types[num_changes] = static_cast<int32_t>(l.second.validated_type());
+      ++num_changes;
+    }
+  }
+  if (!layers && !types)
+    *num_elements = num_changes;
+  return HWC2::Error::None;
+}
+
+HWC2::Error DrmHwcTwo::HwcDisplay::GetClientTargetSupport(uint32_t width,
+                                                          uint32_t height,
+                                                          int32_t /*format*/,
+                                                          int32_t dataspace) {
+  supported(__func__);
+  std::pair<uint32_t, uint32_t> min = drm_->min_resolution();
+  std::pair<uint32_t, uint32_t> max = drm_->max_resolution();
+
+  if (width < min.first || height < min.second)
+    return HWC2::Error::Unsupported;
+
+  if (width > max.first || height > max.second)
+    return HWC2::Error::Unsupported;
+
+  if (dataspace != HAL_DATASPACE_UNKNOWN &&
+      dataspace != HAL_DATASPACE_STANDARD_UNSPECIFIED)
+    return HWC2::Error::Unsupported;
+
+  // TODO: Validate format can be handled by either GL or planes
+  return HWC2::Error::None;
+}
+
+HWC2::Error DrmHwcTwo::HwcDisplay::GetColorModes(uint32_t *num_modes,
+                                                 int32_t *modes) {
+  supported(__func__);
+  if (!modes)
+    *num_modes = 1;
+
+  if (modes)
+    *modes = HAL_COLOR_MODE_NATIVE;
+
+  return HWC2::Error::None;
+}
+
+HWC2::Error DrmHwcTwo::HwcDisplay::GetDisplayAttribute(hwc2_config_t config,
+                                                       int32_t attribute_in,
+                                                       int32_t *value) {
+  supported(__func__);
+  auto mode = std::find_if(connector_->modes().begin(),
+                           connector_->modes().end(),
+                           [config](DrmMode const &m) {
+                             return m.id() == config;
+                           });
+  if (mode == connector_->modes().end()) {
+    ALOGE("Could not find active mode for %d", config);
+    return HWC2::Error::BadConfig;
+  }
+
+  static const int32_t kUmPerInch = 25400;
+  uint32_t mm_width = connector_->mm_width();
+  uint32_t mm_height = connector_->mm_height();
+  auto attribute = static_cast<HWC2::Attribute>(attribute_in);
+  switch (attribute) {
+    case HWC2::Attribute::Width:
+      *value = mode->h_display();
+      break;
+    case HWC2::Attribute::Height:
+      *value = mode->v_display();
+      break;
+    case HWC2::Attribute::VsyncPeriod:
+      // in nanoseconds
+      *value = 1000 * 1000 * 1000 / mode->v_refresh();
+      break;
+    case HWC2::Attribute::DpiX:
+      // Dots per 1000 inches
+      *value = mm_width ? (mode->h_display() * kUmPerInch) / mm_width : -1;
+      break;
+    case HWC2::Attribute::DpiY:
+      // Dots per 1000 inches
+      *value = mm_height ? (mode->v_display() * kUmPerInch) / mm_height : -1;
+      break;
+    default:
+      *value = -1;
+      return HWC2::Error::BadConfig;
+  }
+  return HWC2::Error::None;
+}
+
+HWC2::Error DrmHwcTwo::HwcDisplay::GetDisplayConfigs(uint32_t *num_configs,
+                                                     hwc2_config_t *configs) {
+  supported(__func__);
+  // Since this callback is normally invoked twice (once to get the count, and
+  // once to populate configs), we don't really want to read the edid
+  // redundantly. Instead, only update the modes on the first invocation. While
+  // it's possible this will result in stale modes, it'll all come out in the
+  // wash when we try to set the active config later.
+  if (!configs) {
+    int ret = connector_->UpdateModes();
+    if (ret) {
+      ALOGE("Failed to update display modes %d", ret);
+      return HWC2::Error::BadDisplay;
+    }
+  }
+
+  // Since the upper layers only look at vactive/hactive/refresh, height and
+  // width, it doesn't differentiate interlaced from progressive and other
+  // similar modes. Depending on the order of modes we return to SF, it could
+  // end up choosing a suboptimal configuration and dropping the preferred
+  // mode. To workaround this, don't offer interlaced modes to SF if there is
+  // at least one non-interlaced alternative and only offer a single WxH@R
+  // mode with at least the prefered mode from in DrmConnector::UpdateModes()
+
+  // TODO: Remove the following block of code until AOSP handles all modes
+  std::vector<DrmMode> sel_modes;
+
+  // Add the preferred mode first to be sure it's not dropped
+  auto mode = std::find_if(connector_->modes().begin(),
+                           connector_->modes().end(), [&](DrmMode const &m) {
+                             return m.id() ==
+                                    connector_->get_preferred_mode_id();
+                           });
+  if (mode != connector_->modes().end())
+    sel_modes.push_back(*mode);
+
+  // Add the active mode if different from preferred mode
+  if (connector_->active_mode().id() != connector_->get_preferred_mode_id())
+    sel_modes.push_back(connector_->active_mode());
+
+  // Cycle over the modes and filter out "similar" modes, keeping only the
+  // first ones in the order given by DRM (from CEA ids and timings order)
+  for (const DrmMode &mode : connector_->modes()) {
+    // TODO: Remove this when 3D Attributes are in AOSP
+    if (mode.flags() & DRM_MODE_FLAG_3D_MASK)
+      continue;
+
+    // TODO: Remove this when the Interlaced attribute is in AOSP
+    if (mode.flags() & DRM_MODE_FLAG_INTERLACE) {
+      auto m = std::find_if(connector_->modes().begin(),
+                            connector_->modes().end(),
+                            [&mode](DrmMode const &m) {
+                              return !(m.flags() & DRM_MODE_FLAG_INTERLACE) &&
+                                     m.h_display() == mode.h_display() &&
+                                     m.v_display() == mode.v_display();
+                            });
+      if (m == connector_->modes().end())
+        sel_modes.push_back(mode);
+
+      continue;
+    }
+
+    // Search for a similar WxH@R mode in the filtered list and drop it if
+    // another mode with the same WxH@R has already been selected
+    // TODO: Remove this when AOSP handles duplicates modes
+    auto m = std::find_if(sel_modes.begin(), sel_modes.end(),
+                          [&mode](DrmMode const &m) {
+                            return m.h_display() == mode.h_display() &&
+                                   m.v_display() == mode.v_display() &&
+                                   m.v_refresh() == mode.v_refresh();
+                          });
+    if (m == sel_modes.end())
+      sel_modes.push_back(mode);
+  }
+
+  auto num_modes = static_cast<uint32_t>(sel_modes.size());
+  if (!configs) {
+    *num_configs = num_modes;
+    return HWC2::Error::None;
+  }
+
+  uint32_t idx = 0;
+  for (const DrmMode &mode : sel_modes) {
+    if (idx >= *num_configs)
+      break;
+    configs[idx++] = mode.id();
+  }
+  *num_configs = idx;
+  return HWC2::Error::None;
+}
+
+HWC2::Error DrmHwcTwo::HwcDisplay::GetDisplayName(uint32_t *size, char *name) {
+  supported(__func__);
+  std::ostringstream stream;
+  stream << "display-" << connector_->id();
+  std::string string = stream.str();
+  size_t length = string.length();
+  if (!name) {
+    *size = length;
+    return HWC2::Error::None;
+  }
+
+  *size = std::min<uint32_t>(static_cast<uint32_t>(length - 1), *size);
+  strncpy(name, string.c_str(), *size);
+  return HWC2::Error::None;
+}
+
+HWC2::Error DrmHwcTwo::HwcDisplay::GetDisplayRequests(int32_t *display_requests,
+                                                      uint32_t *num_elements,
+                                                      hwc2_layer_t *layers,
+                                                      int32_t *layer_requests) {
+  supported(__func__);
+  // TODO: I think virtual display should request
+  //      HWC2_DISPLAY_REQUEST_WRITE_CLIENT_TARGET_TO_OUTPUT here
+  unsupported(__func__, display_requests, num_elements, layers, layer_requests);
+  *num_elements = 0;
+  return HWC2::Error::None;
+}
+
+HWC2::Error DrmHwcTwo::HwcDisplay::GetDisplayType(int32_t *type) {
+  supported(__func__);
+  *type = static_cast<int32_t>(type_);
+  return HWC2::Error::None;
+}
+
+HWC2::Error DrmHwcTwo::HwcDisplay::GetDozeSupport(int32_t *support) {
+  supported(__func__);
+  *support = 0;
+  return HWC2::Error::None;
+}
+
+HWC2::Error DrmHwcTwo::HwcDisplay::GetHdrCapabilities(
+    uint32_t *num_types, int32_t * /*types*/, float * /*max_luminance*/,
+    float * /*max_average_luminance*/, float * /*min_luminance*/) {
+  supported(__func__);
+  *num_types = 0;
+  return HWC2::Error::None;
+}
+
+HWC2::Error DrmHwcTwo::HwcDisplay::GetReleaseFences(uint32_t *num_elements,
+                                                    hwc2_layer_t *layers,
+                                                    int32_t *fences) {
+  supported(__func__);
+  uint32_t num_layers = 0;
+
+  for (std::pair<const hwc2_layer_t, DrmHwcTwo::HwcLayer> &l : layers_) {
+    ++num_layers;
+    if (layers == NULL || fences == NULL) {
+      continue;
+    } else if (num_layers > *num_elements) {
+      ALOGW("Overflow num_elements %d/%d", num_layers, *num_elements);
+      return HWC2::Error::None;
+    }
+
+    layers[num_layers - 1] = l.first;
+    fences[num_layers - 1] = l.second.take_release_fence();
+  }
+  *num_elements = num_layers;
+  return HWC2::Error::None;
+}
+
+void DrmHwcTwo::HwcDisplay::AddFenceToPresentFence(int fd) {
+  if (fd < 0)
+    return;
+
+  if (present_fence_.get() >= 0) {
+    int old_fence = present_fence_.get();
+    present_fence_.Set(sync_merge("dc_present", old_fence, fd));
+    close(fd);
+  } else {
+    present_fence_.Set(fd);
+  }
+}
+
+bool DrmHwcTwo::HwcDisplay::HardwareSupportsLayerType(
+    HWC2::Composition comp_type) {
+  return comp_type == HWC2::Composition::Device ||
+         comp_type == HWC2::Composition::Cursor;
+}
+
+HWC2::Error DrmHwcTwo::HwcDisplay::CreateComposition(bool test) {
+  std::vector<DrmCompositionDisplayLayersMap> layers_map;
+  layers_map.emplace_back();
+  DrmCompositionDisplayLayersMap &map = layers_map.back();
+
+  map.display = static_cast<int>(handle_);
+  map.geometry_changed = true;  // TODO: Fix this
+
+  // order the layers by z-order
+  bool use_client_layer = false;
+  uint32_t client_z_order = UINT32_MAX;
+  std::map<uint32_t, DrmHwcTwo::HwcLayer *> z_map;
+  for (std::pair<const hwc2_layer_t, DrmHwcTwo::HwcLayer> &l : layers_) {
+    switch (l.second.validated_type()) {
+      case HWC2::Composition::Device:
+        z_map.emplace(std::make_pair(l.second.z_order(), &l.second));
+        break;
+      case HWC2::Composition::Client:
+        // Place it at the z_order of the lowest client layer
+        use_client_layer = true;
+        client_z_order = std::min(client_z_order, l.second.z_order());
+        break;
+      default:
+        continue;
+    }
+  }
+  if (use_client_layer)
+    z_map.emplace(std::make_pair(client_z_order, &client_layer_));
+
+  if (z_map.empty())
+    return HWC2::Error::BadLayer;
+
+  // now that they're ordered by z, add them to the composition
+  for (std::pair<const uint32_t, DrmHwcTwo::HwcLayer *> &l : z_map) {
+    DrmHwcLayer layer;
+    l.second->PopulateDrmLayer(&layer);
+    int ret = layer.ImportBuffer(importer_.get());
+    if (ret) {
+      ALOGE("Failed to import layer, ret=%d", ret);
+      return HWC2::Error::NoResources;
+    }
+    map.layers.emplace_back(std::move(layer));
+  }
+
+  std::unique_ptr<DrmDisplayComposition> composition = compositor_
+                                                           .CreateComposition();
+  composition->Init(drm_, crtc_, importer_.get(), planner_.get(), frame_no_);
+
+  // TODO: Don't always assume geometry changed
+  int ret = composition->SetLayers(map.layers.data(), map.layers.size(), true);
+  if (ret) {
+    ALOGE("Failed to set layers in the composition ret=%d", ret);
+    return HWC2::Error::BadLayer;
+  }
+
+  std::vector<DrmPlane *> primary_planes(primary_planes_);
+  std::vector<DrmPlane *> overlay_planes(overlay_planes_);
+  ret = composition->Plan(&primary_planes, &overlay_planes);
+  if (ret) {
+    ALOGE("Failed to plan the composition ret=%d", ret);
+    return HWC2::Error::BadConfig;
+  }
+
+  // Disable the planes we're not using
+  for (auto i = primary_planes.begin(); i != primary_planes.end();) {
+    composition->AddPlaneDisable(*i);
+    i = primary_planes.erase(i);
+  }
+  for (auto i = overlay_planes.begin(); i != overlay_planes.end();) {
+    composition->AddPlaneDisable(*i);
+    i = overlay_planes.erase(i);
+  }
+
+  if (test) {
+    ret = compositor_.TestComposition(composition.get());
+  } else {
+    ret = compositor_.ApplyComposition(std::move(composition));
+    AddFenceToPresentFence(compositor_.TakeOutFence());
+  }
+  if (ret) {
+    if (!test)
+      ALOGE("Failed to apply the frame composition ret=%d", ret);
+    return HWC2::Error::BadParameter;
+  }
+  return HWC2::Error::None;
+}
+
+HWC2::Error DrmHwcTwo::HwcDisplay::PresentDisplay(int32_t *present_fence) {
+  supported(__func__);
+  HWC2::Error ret;
+
+  ++total_stats_.total_frames_;
+
+  ret = CreateComposition(false);
+  if (ret != HWC2::Error::None)
+    ++total_stats_.failed_kms_present_;
+
+  if (ret == HWC2::Error::BadLayer) {
+    // Can we really have no client or device layers?
+    *present_fence = -1;
+    return HWC2::Error::None;
+  }
+  if (ret != HWC2::Error::None)
+    return ret;
+
+  *present_fence = present_fence_.Release();
+
+  ++frame_no_;
+  return HWC2::Error::None;
+}
+
+HWC2::Error DrmHwcTwo::HwcDisplay::SetActiveConfig(hwc2_config_t config) {
+  supported(__func__);
+  auto mode = std::find_if(connector_->modes().begin(),
+                           connector_->modes().end(),
+                           [config](DrmMode const &m) {
+                             return m.id() == config;
+                           });
+  if (mode == connector_->modes().end()) {
+    ALOGE("Could not find active mode for %d", config);
+    return HWC2::Error::BadConfig;
+  }
+
+  std::unique_ptr<DrmDisplayComposition> composition = compositor_
+                                                           .CreateComposition();
+  composition->Init(drm_, crtc_, importer_.get(), planner_.get(), frame_no_);
+  int ret = composition->SetDisplayMode(*mode);
+  ret = compositor_.ApplyComposition(std::move(composition));
+  if (ret) {
+    ALOGE("Failed to queue dpms composition on %d", ret);
+    return HWC2::Error::BadConfig;
+  }
+
+  connector_->set_active_mode(*mode);
+
+  // Setup the client layer's dimensions
+  hwc_rect_t display_frame = {.left = 0,
+                              .top = 0,
+                              .right = static_cast<int>(mode->h_display()),
+                              .bottom = static_cast<int>(mode->v_display())};
+  client_layer_.SetLayerDisplayFrame(display_frame);
+  hwc_frect_t source_crop = {.left = 0.0f,
+                             .top = 0.0f,
+                             .right = mode->h_display() + 0.0f,
+                             .bottom = mode->v_display() + 0.0f};
+  client_layer_.SetLayerSourceCrop(source_crop);
+
+  return HWC2::Error::None;
+}
+
+HWC2::Error DrmHwcTwo::HwcDisplay::SetClientTarget(buffer_handle_t target,
+                                                   int32_t acquire_fence,
+                                                   int32_t dataspace,
+                                                   hwc_region_t /*damage*/) {
+  supported(__func__);
+  UniqueFd uf(acquire_fence);
+
+  client_layer_.set_buffer(target);
+  client_layer_.set_acquire_fence(uf.get());
+  client_layer_.SetLayerDataspace(dataspace);
+  return HWC2::Error::None;
+}
+
+HWC2::Error DrmHwcTwo::HwcDisplay::SetColorMode(int32_t mode) {
+  supported(__func__);
+
+  if (mode != HAL_COLOR_MODE_NATIVE)
+    return HWC2::Error::BadParameter;
+
+  color_mode_ = mode;
+  return HWC2::Error::None;
+}
+
+HWC2::Error DrmHwcTwo::HwcDisplay::SetColorTransform(const float *matrix,
+                                                     int32_t hint) {
+  supported(__func__);
+  if (hint < HAL_COLOR_TRANSFORM_IDENTITY ||
+      hint > HAL_COLOR_TRANSFORM_CORRECT_TRITANOPIA)
+    return HWC2::Error::BadParameter;
+
+  if (!matrix && hint == HAL_COLOR_TRANSFORM_ARBITRARY_MATRIX)
+    return HWC2::Error::BadParameter;
+
+  color_transform_hint_ = static_cast<android_color_transform_t>(hint);
+  if (color_transform_hint_ == HAL_COLOR_TRANSFORM_ARBITRARY_MATRIX)
+    std::copy(matrix, matrix + MATRIX_SIZE, color_transform_matrix_.begin());
+
+  return HWC2::Error::None;
+}
+
+HWC2::Error DrmHwcTwo::HwcDisplay::SetOutputBuffer(buffer_handle_t buffer,
+                                                   int32_t release_fence) {
+  supported(__func__);
+  // TODO: Need virtual display support
+  return unsupported(__func__, buffer, release_fence);
+}
+
+HWC2::Error DrmHwcTwo::HwcDisplay::SetPowerMode(int32_t mode_in) {
+  supported(__func__);
+  uint64_t dpms_value = 0;
+  auto mode = static_cast<HWC2::PowerMode>(mode_in);
+  switch (mode) {
+    case HWC2::PowerMode::Off:
+      dpms_value = DRM_MODE_DPMS_OFF;
+      break;
+    case HWC2::PowerMode::On:
+      dpms_value = DRM_MODE_DPMS_ON;
+      break;
+    case HWC2::PowerMode::Doze:
+    case HWC2::PowerMode::DozeSuspend:
+      return HWC2::Error::Unsupported;
+    default:
+      ALOGI("Power mode %d is unsupported\n", mode);
+      return HWC2::Error::BadParameter;
+  };
+
+  std::unique_ptr<DrmDisplayComposition> composition = compositor_
+                                                           .CreateComposition();
+  composition->Init(drm_, crtc_, importer_.get(), planner_.get(), frame_no_);
+  composition->SetDpmsMode(dpms_value);
+  int ret = compositor_.ApplyComposition(std::move(composition));
+  if (ret) {
+    ALOGE("Failed to apply the dpms composition ret=%d", ret);
+    return HWC2::Error::BadParameter;
+  }
+  return HWC2::Error::None;
+}
+
+HWC2::Error DrmHwcTwo::HwcDisplay::SetVsyncEnabled(int32_t enabled) {
+  supported(__func__);
+  vsync_worker_.VSyncControl(HWC2_VSYNC_ENABLE == enabled);
+  return HWC2::Error::None;
+}
+
+uint32_t DrmHwcTwo::HwcDisplay::CalcPixOps(
+    std::map<uint32_t, DrmHwcTwo::HwcLayer *> &z_map, size_t first_z,
+    size_t size) {
+  uint32_t pixops = 0;
+  for (std::pair<const uint32_t, DrmHwcTwo::HwcLayer *> &l : z_map) {
+    if (l.first >= first_z && l.first < first_z + size) {
+      hwc_rect_t df = l.second->display_frame();
+      pixops += (df.right - df.left) * (df.bottom - df.top);
+    }
+  }
+  return pixops;
+}
+
+void DrmHwcTwo::HwcDisplay::MarkValidated(
+    std::map<uint32_t, DrmHwcTwo::HwcLayer *> &z_map, size_t client_first_z,
+    size_t client_size) {
+  for (std::pair<const uint32_t, DrmHwcTwo::HwcLayer *> &l : z_map) {
+    if (l.first >= client_first_z && l.first < client_first_z + client_size)
+      l.second->set_validated_type(HWC2::Composition::Client);
+    else
+      l.second->set_validated_type(HWC2::Composition::Device);
+  }
+}
+
+HWC2::Error DrmHwcTwo::HwcDisplay::ValidateDisplay(uint32_t *num_types,
+                                                   uint32_t *num_requests) {
+  supported(__func__);
+
+  return backend_->ValidateDisplay(this, num_types, num_requests);
+}
+
+#if PLATFORM_SDK_VERSION > 28
+HWC2::Error DrmHwcTwo::HwcDisplay::GetDisplayIdentificationData(
+    uint8_t *outPort, uint32_t *outDataSize, uint8_t *outData) {
+  supported(__func__);
+
+  drmModePropertyBlobPtr blob;
+  int ret;
+  uint64_t blob_id;
+
+  std::tie(ret, blob_id) = connector_->edid_property().value();
+  if (ret) {
+    ALOGE("Failed to get edid property value.");
+    return HWC2::Error::Unsupported;
+  }
+
+  blob = drmModeGetPropertyBlob(drm_->fd(), blob_id);
+
+  if (outData) {
+    *outDataSize = std::min(*outDataSize, blob->length);
+    memcpy(outData, blob->data, *outDataSize);
+  } else {
+    *outDataSize = blob->length;
+  }
+  *outPort = connector_->id();
+
+  return HWC2::Error::None;
+}
+
+HWC2::Error DrmHwcTwo::HwcDisplay::GetDisplayCapabilities(
+    uint32_t *outNumCapabilities, uint32_t *outCapabilities) {
+  unsupported(__func__, outCapabilities);
+
+  if (outNumCapabilities == NULL) {
+    return HWC2::Error::BadParameter;
+  }
+
+  *outNumCapabilities = 0;
+
+  return HWC2::Error::None;
+}
+
+HWC2::Error DrmHwcTwo::HwcDisplay::GetDisplayBrightnessSupport(
+    bool *supported) {
+  *supported = false;
+  return HWC2::Error::None;
+}
+
+HWC2::Error DrmHwcTwo::HwcDisplay::SetDisplayBrightness(
+    float /* brightness */) {
+  return HWC2::Error::Unsupported;
+}
+
+#endif /* PLATFORM_SDK_VERSION > 28 */
+
+#if PLATFORM_SDK_VERSION > 27
+
+HWC2::Error DrmHwcTwo::HwcDisplay::GetRenderIntents(
+    int32_t mode, uint32_t *outNumIntents,
+    int32_t * /*android_render_intent_v1_1_t*/ outIntents) {
+  if (mode != HAL_COLOR_MODE_NATIVE) {
+    return HWC2::Error::BadParameter;
+  }
+
+  if (outIntents == nullptr) {
+    *outNumIntents = 1;
+    return HWC2::Error::None;
+  }
+  *outNumIntents = 1;
+  outIntents[0] = HAL_RENDER_INTENT_COLORIMETRIC;
+  return HWC2::Error::None;
+}
+
+HWC2::Error DrmHwcTwo::HwcDisplay::SetColorModeWithIntent(int32_t mode,
+                                                          int32_t intent) {
+  if (mode != HAL_COLOR_MODE_NATIVE)
+    return HWC2::Error::BadParameter;
+  if (intent != HAL_RENDER_INTENT_COLORIMETRIC)
+    return HWC2::Error::BadParameter;
+  color_mode_ = mode;
+  return HWC2::Error::None;
+}
+
+#endif /* PLATFORM_SDK_VERSION > 27 */
+
+HWC2::Error DrmHwcTwo::HwcLayer::SetCursorPosition(int32_t x, int32_t y) {
+  supported(__func__);
+  cursor_x_ = x;
+  cursor_y_ = y;
+  return HWC2::Error::None;
+}
+
+HWC2::Error DrmHwcTwo::HwcLayer::SetLayerBlendMode(int32_t mode) {
+  supported(__func__);
+  blending_ = static_cast<HWC2::BlendMode>(mode);
+  return HWC2::Error::None;
+}
+
+HWC2::Error DrmHwcTwo::HwcLayer::SetLayerBuffer(buffer_handle_t buffer,
+                                                int32_t acquire_fence) {
+  supported(__func__);
+  UniqueFd uf(acquire_fence);
+
+  set_buffer(buffer);
+  set_acquire_fence(uf.get());
+  return HWC2::Error::None;
+}
+
+HWC2::Error DrmHwcTwo::HwcLayer::SetLayerColor(hwc_color_t color) {
+  // TODO: Put to client composition here?
+  supported(__func__);
+  layer_color_ = color;
+  return HWC2::Error::None;
+}
+
+HWC2::Error DrmHwcTwo::HwcLayer::SetLayerCompositionType(int32_t type) {
+  sf_type_ = static_cast<HWC2::Composition>(type);
+  return HWC2::Error::None;
+}
+
+HWC2::Error DrmHwcTwo::HwcLayer::SetLayerDataspace(int32_t dataspace) {
+  supported(__func__);
+  dataspace_ = static_cast<android_dataspace_t>(dataspace);
+  return HWC2::Error::None;
+}
+
+HWC2::Error DrmHwcTwo::HwcLayer::SetLayerDisplayFrame(hwc_rect_t frame) {
+  supported(__func__);
+  display_frame_ = frame;
+  return HWC2::Error::None;
+}
+
+HWC2::Error DrmHwcTwo::HwcLayer::SetLayerPlaneAlpha(float alpha) {
+  supported(__func__);
+  alpha_ = alpha;
+  return HWC2::Error::None;
+}
+
+HWC2::Error DrmHwcTwo::HwcLayer::SetLayerSidebandStream(
+    const native_handle_t *stream) {
+  supported(__func__);
+  // TODO: We don't support sideband
+  return unsupported(__func__, stream);
+}
+
+HWC2::Error DrmHwcTwo::HwcLayer::SetLayerSourceCrop(hwc_frect_t crop) {
+  supported(__func__);
+  source_crop_ = crop;
+  return HWC2::Error::None;
+}
+
+HWC2::Error DrmHwcTwo::HwcLayer::SetLayerSurfaceDamage(hwc_region_t damage) {
+  supported(__func__);
+  // TODO: We don't use surface damage, marking as unsupported
+  unsupported(__func__, damage);
+  return HWC2::Error::None;
+}
+
+HWC2::Error DrmHwcTwo::HwcLayer::SetLayerTransform(int32_t transform) {
+  supported(__func__);
+  transform_ = static_cast<HWC2::Transform>(transform);
+  return HWC2::Error::None;
+}
+
+HWC2::Error DrmHwcTwo::HwcLayer::SetLayerVisibleRegion(hwc_region_t visible) {
+  supported(__func__);
+  // TODO: We don't use this information, marking as unsupported
+  unsupported(__func__, visible);
+  return HWC2::Error::None;
+}
+
+HWC2::Error DrmHwcTwo::HwcLayer::SetLayerZOrder(uint32_t order) {
+  supported(__func__);
+  z_order_ = order;
+  return HWC2::Error::None;
+}
+
+void DrmHwcTwo::HwcLayer::PopulateDrmLayer(DrmHwcLayer *layer) {
+  supported(__func__);
+  switch (blending_) {
+    case HWC2::BlendMode::None:
+      layer->blending = DrmHwcBlending::kNone;
+      break;
+    case HWC2::BlendMode::Premultiplied:
+      layer->blending = DrmHwcBlending::kPreMult;
+      break;
+    case HWC2::BlendMode::Coverage:
+      layer->blending = DrmHwcBlending::kCoverage;
+      break;
+    default:
+      ALOGE("Unknown blending mode b=%d", blending_);
+      layer->blending = DrmHwcBlending::kNone;
+      break;
+  }
+
+  OutputFd release_fence = release_fence_output();
+
+  layer->sf_handle = buffer_;
+  layer->acquire_fence = acquire_fence_.Release();
+  layer->release_fence = std::move(release_fence);
+  layer->SetDisplayFrame(display_frame_);
+  layer->alpha = static_cast<uint16_t>(65535.0f * alpha_ + 0.5f);
+  layer->SetSourceCrop(source_crop_);
+  layer->SetTransform(static_cast<int32_t>(transform_));
+}
+
+void DrmHwcTwo::HandleDisplayHotplug(hwc2_display_t displayid, int state) {
+  auto cb = callbacks_.find(HWC2::Callback::Hotplug);
+  if (cb == callbacks_.end())
+    return;
+
+  auto hotplug = reinterpret_cast<HWC2_PFN_HOTPLUG>(cb->second.func);
+  hotplug(cb->second.data, displayid,
+          (state == DRM_MODE_CONNECTED ? HWC2_CONNECTION_CONNECTED
+                                       : HWC2_CONNECTION_DISCONNECTED));
+}
+
+void DrmHwcTwo::HandleInitialHotplugState(DrmDevice *drmDevice) {
+  for (auto &conn : drmDevice->connectors()) {
+    if (conn->state() != DRM_MODE_CONNECTED)
+      continue;
+    HandleDisplayHotplug(conn->display(), conn->state());
+  }
+}
+
+void DrmHwcTwo::DrmHotplugHandler::HandleEvent(uint64_t timestamp_us) {
+  for (auto &conn : drm_->connectors()) {
+    drmModeConnection old_state = conn->state();
+    drmModeConnection cur_state = conn->UpdateModes()
+                                      ? DRM_MODE_UNKNOWNCONNECTION
+                                      : conn->state();
+
+    if (cur_state == old_state)
+      continue;
+
+    ALOGI("%s event @%" PRIu64 " for connector %u on display %d",
+          cur_state == DRM_MODE_CONNECTED ? "Plug" : "Unplug", timestamp_us,
+          conn->id(), conn->display());
+
+    int display_id = conn->display();
+    if (cur_state == DRM_MODE_CONNECTED) {
+      auto &display = hwc2_->displays_.at(display_id);
+      display.ChosePreferredConfig();
+    } else {
+      auto &display = hwc2_->displays_.at(display_id);
+      display.ClearDisplay();
+    }
+
+    hwc2_->HandleDisplayHotplug(display_id, cur_state);
+  }
+}
+
+// static
+int DrmHwcTwo::HookDevClose(hw_device_t * /*dev*/) {
+  unsupported(__func__);
+  return 0;
+}
+
+// static
+void DrmHwcTwo::HookDevGetCapabilities(hwc2_device_t * /*dev*/,
+                                       uint32_t *out_count,
+                                       int32_t * /*out_capabilities*/) {
+  supported(__func__);
+  *out_count = 0;
+}
+
+// static
+hwc2_function_pointer_t DrmHwcTwo::HookDevGetFunction(
+    struct hwc2_device * /*dev*/, int32_t descriptor) {
+  supported(__func__);
+  auto func = static_cast<HWC2::FunctionDescriptor>(descriptor);
+  switch (func) {
+    // Device functions
+    case HWC2::FunctionDescriptor::CreateVirtualDisplay:
+      return ToHook<HWC2_PFN_CREATE_VIRTUAL_DISPLAY>(
+          DeviceHook<int32_t, decltype(&DrmHwcTwo::CreateVirtualDisplay),
+                     &DrmHwcTwo::CreateVirtualDisplay, uint32_t, uint32_t,
+                     int32_t *, hwc2_display_t *>);
+    case HWC2::FunctionDescriptor::DestroyVirtualDisplay:
+      return ToHook<HWC2_PFN_DESTROY_VIRTUAL_DISPLAY>(
+          DeviceHook<int32_t, decltype(&DrmHwcTwo::DestroyVirtualDisplay),
+                     &DrmHwcTwo::DestroyVirtualDisplay, hwc2_display_t>);
+    case HWC2::FunctionDescriptor::Dump:
+      return ToHook<HWC2_PFN_DUMP>(
+          DeviceHook<void, decltype(&DrmHwcTwo::Dump), &DrmHwcTwo::Dump,
+                     uint32_t *, char *>);
+    case HWC2::FunctionDescriptor::GetMaxVirtualDisplayCount:
+      return ToHook<HWC2_PFN_GET_MAX_VIRTUAL_DISPLAY_COUNT>(
+          DeviceHook<uint32_t, decltype(&DrmHwcTwo::GetMaxVirtualDisplayCount),
+                     &DrmHwcTwo::GetMaxVirtualDisplayCount>);
+    case HWC2::FunctionDescriptor::RegisterCallback:
+      return ToHook<HWC2_PFN_REGISTER_CALLBACK>(
+          DeviceHook<int32_t, decltype(&DrmHwcTwo::RegisterCallback),
+                     &DrmHwcTwo::RegisterCallback, int32_t,
+                     hwc2_callback_data_t, hwc2_function_pointer_t>);
+
+    // Display functions
+    case HWC2::FunctionDescriptor::AcceptDisplayChanges:
+      return ToHook<HWC2_PFN_ACCEPT_DISPLAY_CHANGES>(
+          DisplayHook<decltype(&HwcDisplay::AcceptDisplayChanges),
+                      &HwcDisplay::AcceptDisplayChanges>);
+    case HWC2::FunctionDescriptor::CreateLayer:
+      return ToHook<HWC2_PFN_CREATE_LAYER>(
+          DisplayHook<decltype(&HwcDisplay::CreateLayer),
+                      &HwcDisplay::CreateLayer, hwc2_layer_t *>);
+    case HWC2::FunctionDescriptor::DestroyLayer:
+      return ToHook<HWC2_PFN_DESTROY_LAYER>(
+          DisplayHook<decltype(&HwcDisplay::DestroyLayer),
+                      &HwcDisplay::DestroyLayer, hwc2_layer_t>);
+    case HWC2::FunctionDescriptor::GetActiveConfig:
+      return ToHook<HWC2_PFN_GET_ACTIVE_CONFIG>(
+          DisplayHook<decltype(&HwcDisplay::GetActiveConfig),
+                      &HwcDisplay::GetActiveConfig, hwc2_config_t *>);
+    case HWC2::FunctionDescriptor::GetChangedCompositionTypes:
+      return ToHook<HWC2_PFN_GET_CHANGED_COMPOSITION_TYPES>(
+          DisplayHook<decltype(&HwcDisplay::GetChangedCompositionTypes),
+                      &HwcDisplay::GetChangedCompositionTypes, uint32_t *,
+                      hwc2_layer_t *, int32_t *>);
+    case HWC2::FunctionDescriptor::GetClientTargetSupport:
+      return ToHook<HWC2_PFN_GET_CLIENT_TARGET_SUPPORT>(
+          DisplayHook<decltype(&HwcDisplay::GetClientTargetSupport),
+                      &HwcDisplay::GetClientTargetSupport, uint32_t, uint32_t,
+                      int32_t, int32_t>);
+    case HWC2::FunctionDescriptor::GetColorModes:
+      return ToHook<HWC2_PFN_GET_COLOR_MODES>(
+          DisplayHook<decltype(&HwcDisplay::GetColorModes),
+                      &HwcDisplay::GetColorModes, uint32_t *, int32_t *>);
+    case HWC2::FunctionDescriptor::GetDisplayAttribute:
+      return ToHook<HWC2_PFN_GET_DISPLAY_ATTRIBUTE>(
+          DisplayHook<decltype(&HwcDisplay::GetDisplayAttribute),
+                      &HwcDisplay::GetDisplayAttribute, hwc2_config_t, int32_t,
+                      int32_t *>);
+    case HWC2::FunctionDescriptor::GetDisplayConfigs:
+      return ToHook<HWC2_PFN_GET_DISPLAY_CONFIGS>(
+          DisplayHook<decltype(&HwcDisplay::GetDisplayConfigs),
+                      &HwcDisplay::GetDisplayConfigs, uint32_t *,
+                      hwc2_config_t *>);
+    case HWC2::FunctionDescriptor::GetDisplayName:
+      return ToHook<HWC2_PFN_GET_DISPLAY_NAME>(
+          DisplayHook<decltype(&HwcDisplay::GetDisplayName),
+                      &HwcDisplay::GetDisplayName, uint32_t *, char *>);
+    case HWC2::FunctionDescriptor::GetDisplayRequests:
+      return ToHook<HWC2_PFN_GET_DISPLAY_REQUESTS>(
+          DisplayHook<decltype(&HwcDisplay::GetDisplayRequests),
+                      &HwcDisplay::GetDisplayRequests, int32_t *, uint32_t *,
+                      hwc2_layer_t *, int32_t *>);
+    case HWC2::FunctionDescriptor::GetDisplayType:
+      return ToHook<HWC2_PFN_GET_DISPLAY_TYPE>(
+          DisplayHook<decltype(&HwcDisplay::GetDisplayType),
+                      &HwcDisplay::GetDisplayType, int32_t *>);
+    case HWC2::FunctionDescriptor::GetDozeSupport:
+      return ToHook<HWC2_PFN_GET_DOZE_SUPPORT>(
+          DisplayHook<decltype(&HwcDisplay::GetDozeSupport),
+                      &HwcDisplay::GetDozeSupport, int32_t *>);
+    case HWC2::FunctionDescriptor::GetHdrCapabilities:
+      return ToHook<HWC2_PFN_GET_HDR_CAPABILITIES>(
+          DisplayHook<decltype(&HwcDisplay::GetHdrCapabilities),
+                      &HwcDisplay::GetHdrCapabilities, uint32_t *, int32_t *,
+                      float *, float *, float *>);
+    case HWC2::FunctionDescriptor::GetReleaseFences:
+      return ToHook<HWC2_PFN_GET_RELEASE_FENCES>(
+          DisplayHook<decltype(&HwcDisplay::GetReleaseFences),
+                      &HwcDisplay::GetReleaseFences, uint32_t *, hwc2_layer_t *,
+                      int32_t *>);
+    case HWC2::FunctionDescriptor::PresentDisplay:
+      return ToHook<HWC2_PFN_PRESENT_DISPLAY>(
+          DisplayHook<decltype(&HwcDisplay::PresentDisplay),
+                      &HwcDisplay::PresentDisplay, int32_t *>);
+    case HWC2::FunctionDescriptor::SetActiveConfig:
+      return ToHook<HWC2_PFN_SET_ACTIVE_CONFIG>(
+          DisplayHook<decltype(&HwcDisplay::SetActiveConfig),
+                      &HwcDisplay::SetActiveConfig, hwc2_config_t>);
+    case HWC2::FunctionDescriptor::SetClientTarget:
+      return ToHook<HWC2_PFN_SET_CLIENT_TARGET>(
+          DisplayHook<decltype(&HwcDisplay::SetClientTarget),
+                      &HwcDisplay::SetClientTarget, buffer_handle_t, int32_t,
+                      int32_t, hwc_region_t>);
+    case HWC2::FunctionDescriptor::SetColorMode:
+      return ToHook<HWC2_PFN_SET_COLOR_MODE>(
+          DisplayHook<decltype(&HwcDisplay::SetColorMode),
+                      &HwcDisplay::SetColorMode, int32_t>);
+    case HWC2::FunctionDescriptor::SetColorTransform:
+      return ToHook<HWC2_PFN_SET_COLOR_TRANSFORM>(
+          DisplayHook<decltype(&HwcDisplay::SetColorTransform),
+                      &HwcDisplay::SetColorTransform, const float *, int32_t>);
+    case HWC2::FunctionDescriptor::SetOutputBuffer:
+      return ToHook<HWC2_PFN_SET_OUTPUT_BUFFER>(
+          DisplayHook<decltype(&HwcDisplay::SetOutputBuffer),
+                      &HwcDisplay::SetOutputBuffer, buffer_handle_t, int32_t>);
+    case HWC2::FunctionDescriptor::SetPowerMode:
+      return ToHook<HWC2_PFN_SET_POWER_MODE>(
+          DisplayHook<decltype(&HwcDisplay::SetPowerMode),
+                      &HwcDisplay::SetPowerMode, int32_t>);
+    case HWC2::FunctionDescriptor::SetVsyncEnabled:
+      return ToHook<HWC2_PFN_SET_VSYNC_ENABLED>(
+          DisplayHook<decltype(&HwcDisplay::SetVsyncEnabled),
+                      &HwcDisplay::SetVsyncEnabled, int32_t>);
+    case HWC2::FunctionDescriptor::ValidateDisplay:
+      return ToHook<HWC2_PFN_VALIDATE_DISPLAY>(
+          DisplayHook<decltype(&HwcDisplay::ValidateDisplay),
+                      &HwcDisplay::ValidateDisplay, uint32_t *, uint32_t *>);
+#if PLATFORM_SDK_VERSION > 27
+    case HWC2::FunctionDescriptor::GetRenderIntents:
+      return ToHook<HWC2_PFN_GET_RENDER_INTENTS>(
+          DisplayHook<decltype(&HwcDisplay::GetRenderIntents),
+                      &HwcDisplay::GetRenderIntents, int32_t, uint32_t *,
+                      int32_t *>);
+    case HWC2::FunctionDescriptor::SetColorModeWithRenderIntent:
+      return ToHook<HWC2_PFN_SET_COLOR_MODE_WITH_RENDER_INTENT>(
+          DisplayHook<decltype(&HwcDisplay::SetColorModeWithIntent),
+                      &HwcDisplay::SetColorModeWithIntent, int32_t, int32_t>);
+#endif
+#if PLATFORM_SDK_VERSION > 28
+    case HWC2::FunctionDescriptor::GetDisplayIdentificationData:
+      return ToHook<HWC2_PFN_GET_DISPLAY_IDENTIFICATION_DATA>(
+          DisplayHook<decltype(&HwcDisplay::GetDisplayIdentificationData),
+                      &HwcDisplay::GetDisplayIdentificationData, uint8_t *,
+                      uint32_t *, uint8_t *>);
+    case HWC2::FunctionDescriptor::GetDisplayCapabilities:
+      return ToHook<HWC2_PFN_GET_DISPLAY_CAPABILITIES>(
+          DisplayHook<decltype(&HwcDisplay::GetDisplayCapabilities),
+                      &HwcDisplay::GetDisplayCapabilities, uint32_t *,
+                      uint32_t *>);
+    case HWC2::FunctionDescriptor::GetDisplayBrightnessSupport:
+      return ToHook<HWC2_PFN_GET_DISPLAY_BRIGHTNESS_SUPPORT>(
+          DisplayHook<decltype(&HwcDisplay::GetDisplayBrightnessSupport),
+                      &HwcDisplay::GetDisplayBrightnessSupport, bool *>);
+    case HWC2::FunctionDescriptor::SetDisplayBrightness:
+      return ToHook<HWC2_PFN_SET_DISPLAY_BRIGHTNESS>(
+          DisplayHook<decltype(&HwcDisplay::SetDisplayBrightness),
+                      &HwcDisplay::SetDisplayBrightness, float>);
+#endif /* PLATFORM_SDK_VERSION > 28 */
+    // Layer functions
+    case HWC2::FunctionDescriptor::SetCursorPosition:
+      return ToHook<HWC2_PFN_SET_CURSOR_POSITION>(
+          LayerHook<decltype(&HwcLayer::SetCursorPosition),
+                    &HwcLayer::SetCursorPosition, int32_t, int32_t>);
+    case HWC2::FunctionDescriptor::SetLayerBlendMode:
+      return ToHook<HWC2_PFN_SET_LAYER_BLEND_MODE>(
+          LayerHook<decltype(&HwcLayer::SetLayerBlendMode),
+                    &HwcLayer::SetLayerBlendMode, int32_t>);
+    case HWC2::FunctionDescriptor::SetLayerBuffer:
+      return ToHook<HWC2_PFN_SET_LAYER_BUFFER>(
+          LayerHook<decltype(&HwcLayer::SetLayerBuffer),
+                    &HwcLayer::SetLayerBuffer, buffer_handle_t, int32_t>);
+    case HWC2::FunctionDescriptor::SetLayerColor:
+      return ToHook<HWC2_PFN_SET_LAYER_COLOR>(
+          LayerHook<decltype(&HwcLayer::SetLayerColor),
+                    &HwcLayer::SetLayerColor, hwc_color_t>);
+    case HWC2::FunctionDescriptor::SetLayerCompositionType:
+      return ToHook<HWC2_PFN_SET_LAYER_COMPOSITION_TYPE>(
+          LayerHook<decltype(&HwcLayer::SetLayerCompositionType),
+                    &HwcLayer::SetLayerCompositionType, int32_t>);
+    case HWC2::FunctionDescriptor::SetLayerDataspace:
+      return ToHook<HWC2_PFN_SET_LAYER_DATASPACE>(
+          LayerHook<decltype(&HwcLayer::SetLayerDataspace),
+                    &HwcLayer::SetLayerDataspace, int32_t>);
+    case HWC2::FunctionDescriptor::SetLayerDisplayFrame:
+      return ToHook<HWC2_PFN_SET_LAYER_DISPLAY_FRAME>(
+          LayerHook<decltype(&HwcLayer::SetLayerDisplayFrame),
+                    &HwcLayer::SetLayerDisplayFrame, hwc_rect_t>);
+    case HWC2::FunctionDescriptor::SetLayerPlaneAlpha:
+      return ToHook<HWC2_PFN_SET_LAYER_PLANE_ALPHA>(
+          LayerHook<decltype(&HwcLayer::SetLayerPlaneAlpha),
+                    &HwcLayer::SetLayerPlaneAlpha, float>);
+    case HWC2::FunctionDescriptor::SetLayerSidebandStream:
+      return ToHook<HWC2_PFN_SET_LAYER_SIDEBAND_STREAM>(
+          LayerHook<decltype(&HwcLayer::SetLayerSidebandStream),
+                    &HwcLayer::SetLayerSidebandStream,
+                    const native_handle_t *>);
+    case HWC2::FunctionDescriptor::SetLayerSourceCrop:
+      return ToHook<HWC2_PFN_SET_LAYER_SOURCE_CROP>(
+          LayerHook<decltype(&HwcLayer::SetLayerSourceCrop),
+                    &HwcLayer::SetLayerSourceCrop, hwc_frect_t>);
+    case HWC2::FunctionDescriptor::SetLayerSurfaceDamage:
+      return ToHook<HWC2_PFN_SET_LAYER_SURFACE_DAMAGE>(
+          LayerHook<decltype(&HwcLayer::SetLayerSurfaceDamage),
+                    &HwcLayer::SetLayerSurfaceDamage, hwc_region_t>);
+    case HWC2::FunctionDescriptor::SetLayerTransform:
+      return ToHook<HWC2_PFN_SET_LAYER_TRANSFORM>(
+          LayerHook<decltype(&HwcLayer::SetLayerTransform),
+                    &HwcLayer::SetLayerTransform, int32_t>);
+    case HWC2::FunctionDescriptor::SetLayerVisibleRegion:
+      return ToHook<HWC2_PFN_SET_LAYER_VISIBLE_REGION>(
+          LayerHook<decltype(&HwcLayer::SetLayerVisibleRegion),
+                    &HwcLayer::SetLayerVisibleRegion, hwc_region_t>);
+    case HWC2::FunctionDescriptor::SetLayerZOrder:
+      return ToHook<HWC2_PFN_SET_LAYER_Z_ORDER>(
+          LayerHook<decltype(&HwcLayer::SetLayerZOrder),
+                    &HwcLayer::SetLayerZOrder, uint32_t>);
+    case HWC2::FunctionDescriptor::Invalid:
+    default:
+      return NULL;
+  }
+}
+
+// static
+int DrmHwcTwo::HookDevOpen(const struct hw_module_t *module, const char *name,
+                           struct hw_device_t **dev) {
+  supported(__func__);
+  if (strcmp(name, HWC_HARDWARE_COMPOSER)) {
+    ALOGE("Invalid module name- %s", name);
+    return -EINVAL;
+  }
+
+  std::unique_ptr<DrmHwcTwo> ctx(new DrmHwcTwo());
+  if (!ctx) {
+    ALOGE("Failed to allocate DrmHwcTwo");
+    return -ENOMEM;
+  }
+
+  HWC2::Error err = ctx->Init();
+  if (err != HWC2::Error::None) {
+    ALOGE("Failed to initialize DrmHwcTwo err=%d\n", err);
+    return -EINVAL;
+  }
+
+  ctx->common.module = const_cast<hw_module_t *>(module);
+  *dev = &ctx->common;
+  ctx.release();
+  return 0;
+}
+}  // namespace android
+
+static struct hw_module_methods_t hwc2_module_methods = {
+    .open = android::DrmHwcTwo::HookDevOpen,
+};
+
+hw_module_t HAL_MODULE_INFO_SYM = {
+    .tag = HARDWARE_MODULE_TAG,
+    .module_api_version = HARDWARE_MODULE_API_VERSION(2, 0),
+    .id = HWC_HARDWARE_MODULE_ID,
+    .name = "DrmHwcTwo module",
+    .author = "The Android Open Source Project",
+    .methods = &hwc2_module_methods,
+    .dso = NULL,
+    .reserved = {0},
+};
