diff --git a/drmhwctwo.cpp b/drmhwctwo.cpp
index e7fecb8..138f5fa 100644
--- a/drmhwctwo.cpp
+++ b/drmhwctwo.cpp
@@ -17,218 +17,815 @@
 #define ATRACE_TAG ATRACE_TAG_GRAPHICS
 #define LOG_TAG "hwc-drm-two"
 
+#include "drmdisplaycomposition.h"
+#include "drmhwcomposer.h"
 #include "drmhwctwo.h"
+#include "platform.h"
+#include "vsyncworker.h"
+
+#include <inttypes.h>
+#include <string>
 
 #include <cutils/log.h>
+#include <cutils/properties.h>
+#include <hardware/hardware.h>
 #include <hardware/hwcomposer2.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::Init() {
+  int ret = drm_.Init();
+  if (ret) {
+    ALOGE("Can't initialize drm object %d", ret);
+    return HWC2::Error::NoResources;
+  }
+
+  importer_.reset(Importer::CreateInstance(&drm_));
+  if (!importer_) {
+    ALOGE("Failed to create importer instance");
+    return HWC2::Error::NoResources;
+  }
+
+  ret = hw_get_module(GRALLOC_HARDWARE_MODULE_ID,
+                      (const hw_module_t **)&gralloc_);
+  if (ret) {
+    ALOGE("Failed to open gralloc module %d", ret);
+    return HWC2::Error::NoResources;
+  }
+
+  displays_.emplace(std::piecewise_construct,
+                    std::forward_as_tuple(HWC_DISPLAY_PRIMARY),
+                    std::forward_as_tuple(&drm_, importer_, gralloc_,
+                                          HWC_DISPLAY_PRIMARY,
+                                          HWC2::DisplayType::Physical));
+
+  DrmCrtc *crtc = drm_.GetCrtcForDisplay(static_cast<int>(HWC_DISPLAY_PRIMARY));
+  if (!crtc) {
+    ALOGE("Failed to get crtc for display %d",
+          static_cast<int>(HWC_DISPLAY_PRIMARY));
+    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(HWC_DISPLAY_PRIMARY).Init(&display_planes);
+  return HWC2::Error::None;
+}
+
 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, display);
+  return unsupported(__func__, width, height, format, display);
 }
 
 HWC2::Error DrmHwcTwo::DestroyVirtualDisplay(hwc2_display_t display) {
+  // TODO: Implement virtual display
   return unsupported(__func__, display);
 }
 
 void DrmHwcTwo::Dump(uint32_t *size, char *buffer) {
+  // TODO: Implement dump
   unsupported(__func__, size, buffer);
 }
 
 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) {
-  return unsupported(__func__, descriptor, data, function);
+                                        hwc2_callback_data_t data,
+                                        hwc2_function_pointer_t function) {
+  supported(__func__);
+  auto callback = static_cast<HWC2::Callback>(descriptor);
+  callbacks_.emplace(callback, HwcCallback(data, function));
+
+  switch (callback) {
+    case HWC2::Callback::Hotplug: {
+      auto hotplug = reinterpret_cast<HWC2_PFN_HOTPLUG>(function);
+      hotplug(data, HWC_DISPLAY_PRIMARY,
+              static_cast<int32_t>(HWC2::Connection::Connected));
+      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(DrmResources *drm,
+                                  std::shared_ptr<Importer> importer,
+                                  const gralloc_module_t *gralloc,
+                                  hwc2_display_t handle, HWC2::DisplayType type)
+    : drm_(drm),
+      importer_(importer),
+      gralloc_(gralloc),
+      handle_(handle),
+      type_(type) {
+  supported(__func__);
+}
+
+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(drm_, 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("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;
+  }
+
+  // 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;
+
+  // Grab the first mode, we'll choose this as the active mode
+  // TODO: Should choose the preferred mode here
+  hwc2_config_t default_config;
+  num_configs = 1;
+  err = GetDisplayConfigs(&num_configs, &default_config);
+  if (err != HWC2::Error::None)
+    return err;
+
+  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;
+  }
+
+  return SetActiveConfig(default_config);
+}
+
+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);
+  int ret = vsync_worker_.RegisterCallback(std::move(callback));
+  if (ret) {
+    ALOGE("Failed to register callback d=%" PRIu64 " ret=%d", handle_, ret);
+    return HWC2::Error::BadDisplay;
+  }
+  return HWC2::Error::None;
 }
 
 HWC2::Error DrmHwcTwo::HwcDisplay::AcceptDisplayChanges() {
-  return unsupported(__func__);
+  supported(__func__);
+  uint32_t num_changes = 0;
+  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) {
-  return unsupported(__func__, 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) {
-  return unsupported(__func__, layer);
+  supported(__func__);
+  layers_.erase(layer);
+  return HWC2::Error::None;
 }
 
 HWC2::Error DrmHwcTwo::HwcDisplay::GetActiveConfig(hwc2_config_t *config) {
-  return unsupported(__func__, 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) {
-  return unsupported(__func__, num_elements, layers, 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) {
-  return unsupported(__func__, width, height, format, dataspace);
+                                                          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) {
+                                                 int32_t *modes) {
+  supported(__func__);
+  // TODO: android_color_mode_t isn't defined yet!
   return unsupported(__func__, num_modes, modes);
 }
 
 HWC2::Error DrmHwcTwo::HwcDisplay::GetDisplayAttribute(hwc2_config_t config,
-                                                        int32_t attribute,
-                                                        int32_t *value) {
-  return unsupported(__func__, config, attribute, value);
+                                                       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) {
-  return unsupported(__func__, num_configs, 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;
+    }
+  }
+
+  auto num_modes = static_cast<uint32_t>(connector_->modes().size());
+  if (!configs) {
+    *num_configs = num_modes;
+    return HWC2::Error::None;
+  }
+
+  uint32_t idx = 0;
+  for (const DrmMode &mode : connector_->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) {
-  return unsupported(__func__, size, 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) {
-  return unsupported(__func__, display_requests, num_elements, layers,
-                     layer_requests);
+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) {
-  return unsupported(__func__, type);
+  supported(__func__);
+  *type = static_cast<int32_t>(type_);
+  return HWC2::Error::None;
 }
 
 HWC2::Error DrmHwcTwo::HwcDisplay::GetDozeSupport(int32_t *support) {
-  return unsupported(__func__, 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) {
-  return unsupported(__func__, num_elements, layers, fences);
+                                                    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::AddFenceToRetireFence(int fd) {
+  supported(__func__);
+  if (fd < 0)
+    return;
+
+  if (next_retire_fence_.get() >= 0) {
+    int old_fence = next_retire_fence_.get();
+    next_retire_fence_.Set(sync_merge("dc_retire", old_fence, fd));
+  } else {
+    next_retire_fence_.Set(dup(fd));
+  }
 }
 
 HWC2::Error DrmHwcTwo::HwcDisplay::PresentDisplay(int32_t *retire_fence) {
-  return unsupported(__func__, retire_fence);
+  supported(__func__);
+  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 = 0;
+  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 highest client layer
+        use_client_layer = true;
+        client_z_order = std::max(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_));
+
+  // 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(), gralloc_);
+    if (ret) {
+      ALOGE("Failed to import layer, ret=%d", ret);
+      return HWC2::Error::NoResources;
+    }
+    map.layers.emplace_back(std::move(layer));
+  }
+  if (map.layers.empty()) {
+    *retire_fence = -1;
+    return HWC2::Error::None;
+  }
+
+  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(compositor_.squash_state(), &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);
+  }
+
+  ret = compositor_.QueueComposition(std::move(composition));
+  if (ret) {
+    ALOGE("Failed to apply the frame composition ret=%d", ret);
+    return HWC2::Error::BadParameter;
+  }
+
+  // Now that the release fences have been generated by the compositor, make
+  // sure they're managed properly
+  for (std::pair<const uint32_t, DrmHwcTwo::HwcLayer *> &l : z_map) {
+    l.second->manage_release_fence();
+    AddFenceToRetireFence(l.second->release_fence());
+  }
+
+  // The retire fence returned here is for the last frame, so return it and
+  // promote the next retire fence
+  *retire_fence = retire_fence_.Release();
+  retire_fence_ = std::move(next_retire_fence_);
+
+  ++frame_no_;
+  return HWC2::Error::None;
 }
 
 HWC2::Error DrmHwcTwo::HwcDisplay::SetActiveConfig(hwc2_config_t config) {
-  return unsupported(__func__, 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_.QueueComposition(std::move(composition));
+  if (ret) {
+    ALOGE("Failed to queue dpms composition on %d", ret);
+    return HWC2::Error::BadConfig;
+  }
+  if (connector_->active_mode().id() == 0)
+    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) {
-  return unsupported(__func__, target, acquire_fence, dataspace, 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__);
+  // TODO: android_color_mode_t isn't defined yet!
   return unsupported(__func__, mode);
 }
 
 HWC2::Error DrmHwcTwo::HwcDisplay::SetColorTransform(const float *matrix,
-                                                      int32_t hint) {
+                                                     int32_t hint) {
+  supported(__func__);
+  // TODO: Force client composition if we get this
   return unsupported(__func__, matrix, hint);
 }
 
 HWC2::Error DrmHwcTwo::HwcDisplay::SetOutputBuffer(buffer_handle_t buffer,
-                                                    int32_t release_fence) {
+                                                   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) {
-  return unsupported(__func__, mode);
+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;
+    default:
+      ALOGI("Power mode %d is unsupported\n", mode);
+      return HWC2::Error::Unsupported;
+  };
+
+  std::unique_ptr<DrmDisplayComposition> composition =
+      compositor_.CreateComposition();
+  composition->Init(drm_, crtc_, importer_.get(), planner_.get(), frame_no_);
+  composition->SetDpmsMode(dpms_value);
+  int ret = compositor_.QueueComposition(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) {
-  return unsupported(__func__, enabled);
+  supported(__func__);
+  vsync_worker_.VSyncControl(enabled);
+  return HWC2::Error::None;
 }
 
 HWC2::Error DrmHwcTwo::HwcDisplay::ValidateDisplay(uint32_t *num_types,
-                                                    uint32_t *num_requests) {
-  return unsupported(__func__, num_types, num_requests);
+                                                   uint32_t *num_requests) {
+  supported(__func__);
+  *num_types = 0;
+  *num_requests = 0;
+  for (std::pair<const hwc2_layer_t, DrmHwcTwo::HwcLayer> &l : layers_) {
+    DrmHwcTwo::HwcLayer &layer = l.second;
+    switch (layer.sf_type()) {
+      case HWC2::Composition::SolidColor:
+      case HWC2::Composition::Cursor:
+      case HWC2::Composition::Sideband:
+        layer.set_validated_type(HWC2::Composition::Client);
+        ++*num_types;
+        break;
+      default:
+        layer.set_validated_type(layer.sf_type());
+        break;
+    }
+  }
+  return HWC2::Error::None;
 }
 
 HWC2::Error DrmHwcTwo::HwcLayer::SetCursorPosition(int32_t x, int32_t y) {
+  supported(__func__);
+  // TODO: Implement proper cursor support
   return unsupported(__func__, x, y);
 }
 
 HWC2::Error DrmHwcTwo::HwcLayer::SetLayerBlendMode(int32_t mode) {
-  return unsupported(__func__, 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) {
-  return unsupported(__func__, buffer, acquire_fence);
+                                                int32_t acquire_fence) {
+  supported(__func__);
+  UniqueFd uf(acquire_fence);
+
+  // The buffer and acquire_fence are handled elsewhere
+  if (sf_type_ == HWC2::Composition::Client ||
+      sf_type_ == HWC2::Composition::Sideband ||
+      sf_type_ == HWC2::Composition::SolidColor)
+    return HWC2::Error::None;
+
+  set_buffer(buffer);
+  set_acquire_fence(uf.get());
+  return HWC2::Error::None;
 }
 
 HWC2::Error DrmHwcTwo::HwcLayer::SetLayerColor(hwc_color_t color) {
+  // TODO: Punt to client composition here?
   return unsupported(__func__, color);
 }
 
 HWC2::Error DrmHwcTwo::HwcLayer::SetLayerCompositionType(int32_t type) {
-  return unsupported(__func__, type);
+  sf_type_ = static_cast<HWC2::Composition>(type);
+  return HWC2::Error::None;
 }
 
 HWC2::Error DrmHwcTwo::HwcLayer::SetLayerDataspace(int32_t dataspace) {
-  return unsupported(__func__, dataspace);
+  supported(__func__);
+  dataspace_ = static_cast<android_dataspace_t>(dataspace);
+  return HWC2::Error::None;
 }
 
 HWC2::Error DrmHwcTwo::HwcLayer::SetLayerDisplayFrame(hwc_rect_t frame) {
-  return unsupported(__func__, frame);
+  supported(__func__);
+  display_frame_ = frame;
+  return HWC2::Error::None;
 }
 
 HWC2::Error DrmHwcTwo::HwcLayer::SetLayerPlaneAlpha(float alpha) {
-  return unsupported(__func__, 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) {
-  return unsupported(__func__, crop);
+  supported(__func__);
+  source_crop_ = crop;
+  return HWC2::Error::None;
 }
 
 HWC2::Error DrmHwcTwo::HwcLayer::SetLayerSurfaceDamage(hwc_region_t damage) {
-  return unsupported(__func__, 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) {
-  return unsupported(__func__, transform);
+  supported(__func__);
+  transform_ = static_cast<HWC2::Transform>(transform);
+  return HWC2::Error::None;
 }
 
 HWC2::Error DrmHwcTwo::HwcLayer::SetLayerVisibleRegion(hwc_region_t visible) {
-  return unsupported(__func__, 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 z) {
-  return unsupported(__func__, z);
+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<uint8_t>(255.0f * alpha_ + 0.5f);
+  layer->SetSourceCrop(source_crop_);
+  layer->SetTransform(static_cast<int32_t>(transform_));
 }
 
 // static
@@ -239,18 +836,17 @@
 
 // static
 void DrmHwcTwo::HookDevGetCapabilities(hwc2_device_t * /*dev*/,
-                                        uint32_t *out_count,
-                                        int32_t * /*out_capabilities*/) {
-  unsupported(__func__);
+                                       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) {
-  DrmHwcTwo *hwc = toDrmHwcTwo(dev);
-  HWC2::FunctionDescriptor func = (HWC2::FunctionDescriptor)descriptor;
-
+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:
@@ -332,6 +928,11 @@
       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),
@@ -431,8 +1032,51 @@
       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;
 }
+}
+
+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},
+};
diff --git a/drmhwctwo.h b/drmhwctwo.h
index 8bc5ce9..038412d 100644
--- a/drmhwctwo.h
+++ b/drmhwctwo.h
@@ -14,6 +14,12 @@
  * limitations under the License.
  */
 
+#include "drmdisplaycompositor.h"
+#include "drmhwcomposer.h"
+#include "drmresources.h"
+#include "platform.h"
+#include "vsyncworker.h"
+
 #include <hardware/hwcomposer2.h>
 
 #include <map>
@@ -22,11 +28,67 @@
 
 class DrmHwcTwo : public hwc2_device_t {
  public:
+  static int HookDevOpen(const struct hw_module_t *module, const char *name,
+                         struct hw_device_t **dev);
+
   DrmHwcTwo();
 
+  HWC2::Error Init();
+
  private:
   class HwcLayer {
    public:
+    HWC2::Composition sf_type() const {
+      return sf_type_;
+    }
+    HWC2::Composition validated_type() const {
+      return validated_type_;
+    }
+    void accept_type_change() {
+      sf_type_ = validated_type_;
+    }
+    void set_validated_type(HWC2::Composition type) {
+      validated_type_ = type;
+    }
+    bool type_changed() const {
+      return sf_type_ != validated_type_;
+    }
+
+    uint32_t z_order() const {
+      return z_order_;
+    }
+
+    buffer_handle_t buffer() {
+      return buffer_;
+    }
+    void set_buffer(buffer_handle_t buffer) {
+      buffer_ = buffer;
+    }
+
+    int take_acquire_fence() {
+      return acquire_fence_.Release();
+    }
+    void set_acquire_fence(int acquire_fence) {
+      acquire_fence_.Set(dup(acquire_fence));
+    }
+
+    int release_fence() {
+      return release_fence_.get();
+    }
+    int take_release_fence() {
+      return release_fence_.Release();
+    }
+    void manage_release_fence() {
+      release_fence_.Set(release_fence_raw_);
+      release_fence_raw_ = -1;
+    }
+    OutputFd release_fence_output() {
+      return OutputFd(&release_fence_raw_);
+    }
+
+    void PopulateDrmLayer(DrmHwcLayer *layer);
+
+    // Layer hooks
     HWC2::Error SetCursorPosition(int32_t x, int32_t y);
     HWC2::Error SetLayerBlendMode(int32_t mode);
     HWC2::Error SetLayerBuffer(buffer_handle_t buffer, int32_t acquire_fence);
@@ -41,10 +103,45 @@
     HWC2::Error SetLayerTransform(int32_t transform);
     HWC2::Error SetLayerVisibleRegion(hwc_region_t visible);
     HWC2::Error SetLayerZOrder(uint32_t z);
+
+   private:
+    // sf_type_ stores the initial type given to us by surfaceflinger,
+    // validated_type_ stores the type after running ValidateDisplay
+    HWC2::Composition sf_type_ = HWC2::Composition::Invalid;
+    HWC2::Composition validated_type_ = HWC2::Composition::Invalid;
+
+    HWC2::BlendMode blending_ = HWC2::BlendMode::None;
+    buffer_handle_t buffer_;
+    UniqueFd acquire_fence_;
+    int release_fence_raw_ = -1;
+    UniqueFd release_fence_;
+    hwc_rect_t display_frame_;
+    float alpha_ = 1.0f;
+    hwc_frect_t source_crop_;
+    HWC2::Transform transform_ = HWC2::Transform::None;
+    uint32_t z_order_ = 0;
+    android_dataspace_t dataspace_ = HAL_DATASPACE_UNKNOWN;
+  };
+
+  struct HwcCallback {
+    HwcCallback(hwc2_callback_data_t d, hwc2_function_pointer_t f)
+        : data(d), func(f) {
+    }
+    hwc2_callback_data_t data;
+    hwc2_function_pointer_t func;
   };
 
   class HwcDisplay {
    public:
+    HwcDisplay(DrmResources *drm, std::shared_ptr<Importer> importer,
+               const gralloc_module_t *gralloc, hwc2_display_t handle,
+               HWC2::DisplayType type);
+    HwcDisplay(const HwcDisplay &) = delete;
+    HWC2::Error Init(std::vector<DrmPlane *> *planes);
+
+    HWC2::Error RegisterVsyncCallback(hwc2_callback_data_t data,
+                                      hwc2_function_pointer_t func);
+
     // HWC Hooks
     HWC2::Error AcceptDisplayChanges();
     HWC2::Error CreateLayer(hwc2_layer_t *layer);
@@ -66,6 +163,10 @@
                                    int32_t *layer_requests);
     HWC2::Error GetDisplayType(int32_t *type);
     HWC2::Error GetDozeSupport(int32_t *support);
+    HWC2::Error GetHdrCapabilities(uint32_t *num_types, int32_t *types,
+                                   float *max_luminance,
+                                   float *max_average_luminance,
+                                   float *min_luminance);
     HWC2::Error GetReleaseFences(uint32_t *num_elements, hwc2_layer_t *layers,
                                  int32_t *fences);
     HWC2::Error PresentDisplay(int32_t *retire_fence);
@@ -83,7 +184,29 @@
     }
 
    private:
+    void AddFenceToRetireFence(int fd);
+
+    DrmResources *drm_;
+    DrmDisplayCompositor compositor_;
+    std::shared_ptr<Importer> importer_;
+    std::unique_ptr<Planner> planner_;
+    const gralloc_module_t *gralloc_;
+
+    std::vector<DrmPlane *> primary_planes_;
+    std::vector<DrmPlane *> overlay_planes_;
+
+    VSyncWorker vsync_worker_;
+    DrmConnector *connector_ = NULL;
+    DrmCrtc *crtc_ = NULL;
+    hwc2_display_t handle_;
+    HWC2::DisplayType type_;
+    uint32_t layer_idx_ = 0;
     std::map<hwc2_layer_t, HwcLayer> layers_;
+    HwcLayer client_layer_;
+    UniqueFd retire_fence_;
+    UniqueFd next_retire_fence_;
+
+    uint32_t frame_no_ = 0;
   };
 
   static DrmHwcTwo *toDrmHwcTwo(hwc2_device_t *dev) {
@@ -136,6 +259,10 @@
   HWC2::Error RegisterCallback(int32_t descriptor, hwc2_callback_data_t data,
                                hwc2_function_pointer_t function);
 
+  DrmResources drm_;
+  std::shared_ptr<Importer> importer_;  // Shared with HwcDisplay
+  const gralloc_module_t *gralloc_;
   std::map<hwc2_display_t, HwcDisplay> displays_;
+  std::map<HWC2::Callback, HwcCallback> callbacks_;
 };
 }
