diff --git a/DrmHwcTwo.h b/DrmHwcTwo.h
new file mode 100644
index 0000000..ca7a00b
--- /dev/null
+++ b/DrmHwcTwo.h
@@ -0,0 +1,431 @@
+/*
+ * 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.
+ */
+
+#ifndef ANDROID_DRM_HWC_TWO_H_
+#define ANDROID_DRM_HWC_TWO_H_
+
+#include <hardware/hwcomposer2.h>
+#include <math.h>
+
+#include <array>
+#include <map>
+
+#include "compositor/DrmDisplayCompositor.h"
+#include "drm/ResourceManager.h"
+#include "drm/VSyncWorker.h"
+#include "drmhwcomposer.h"
+#include "platform/platform.h"
+
+namespace android {
+
+class Backend;
+
+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();
+
+  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_);
+    }
+
+    hwc_rect_t display_frame() {
+      return display_frame_;
+    }
+
+    void PopulateDrmLayer(DrmHwcLayer *layer);
+
+    bool RequireScalingOrPhasing() {
+      float src_width = source_crop_.right - source_crop_.left;
+      float src_height = source_crop_.bottom - source_crop_.top;
+
+      float dest_width = display_frame_.right - display_frame_.left;
+      float dest_height = display_frame_.bottom - display_frame_.top;
+
+      bool scaling = src_width != dest_width || src_height != dest_height;
+      bool phasing = (source_crop_.left - floor(source_crop_.left) != 0) ||
+                     (source_crop_.top - floor(source_crop_.top) != 0);
+      return scaling || phasing;
+    }
+
+    // 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);
+    HWC2::Error SetLayerColor(hwc_color_t color);
+    HWC2::Error SetLayerCompositionType(int32_t type);
+    HWC2::Error SetLayerDataspace(int32_t dataspace);
+    HWC2::Error SetLayerDisplayFrame(hwc_rect_t frame);
+    HWC2::Error SetLayerPlaneAlpha(float alpha);
+    HWC2::Error SetLayerSidebandStream(const native_handle_t *stream);
+    HWC2::Error SetLayerSourceCrop(hwc_frect_t crop);
+    HWC2::Error SetLayerSurfaceDamage(hwc_region_t damage);
+    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_ = NULL;
+    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_;
+    int32_t cursor_x_;
+    int32_t cursor_y_;
+    hwc_color_t layer_color_;
+    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(ResourceManager *resource_manager, DrmDevice *drm,
+               std::shared_ptr<Importer> importer, 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);
+    void RegisterRefreshCallback(hwc2_callback_data_t data,
+                                 hwc2_function_pointer_t func);
+    HWC2::Error CreateComposition(bool test);
+    bool HardwareSupportsLayerType(HWC2::Composition comp_type);
+    uint32_t CalcPixOps(std::map<uint32_t, DrmHwcTwo::HwcLayer *> &z_map,
+                        size_t first_z, size_t size);
+    void MarkValidated(std::map<uint32_t, DrmHwcTwo::HwcLayer *> &z_map,
+                       size_t client_first_z, size_t client_size);
+
+    void ClearDisplay();
+
+    std::string Dump();
+
+    // HWC Hooks
+    HWC2::Error AcceptDisplayChanges();
+    HWC2::Error CreateLayer(hwc2_layer_t *layer);
+    HWC2::Error DestroyLayer(hwc2_layer_t layer);
+    HWC2::Error GetActiveConfig(hwc2_config_t *config);
+    HWC2::Error GetChangedCompositionTypes(uint32_t *num_elements,
+                                           hwc2_layer_t *layers,
+                                           int32_t *types);
+    HWC2::Error GetClientTargetSupport(uint32_t width, uint32_t height,
+                                       int32_t format, int32_t dataspace);
+    HWC2::Error GetColorModes(uint32_t *num_modes, int32_t *modes);
+    HWC2::Error GetDisplayAttribute(hwc2_config_t config, int32_t attribute,
+                                    int32_t *value);
+    HWC2::Error GetDisplayConfigs(uint32_t *num_configs,
+                                  hwc2_config_t *configs);
+    HWC2::Error GetDisplayName(uint32_t *size, char *name);
+    HWC2::Error GetDisplayRequests(int32_t *display_requests,
+                                   uint32_t *num_elements, hwc2_layer_t *layers,
+                                   int32_t *layer_requests);
+    HWC2::Error GetDisplayType(int32_t *type);
+#if PLATFORM_SDK_VERSION > 27
+    HWC2::Error GetRenderIntents(int32_t mode, uint32_t *outNumIntents,
+                                 int32_t *outIntents);
+    HWC2::Error SetColorModeWithIntent(int32_t mode, int32_t intent);
+#endif
+#if PLATFORM_SDK_VERSION > 28
+    HWC2::Error GetDisplayIdentificationData(uint8_t *outPort,
+                                             uint32_t *outDataSize,
+                                             uint8_t *outData);
+    HWC2::Error GetDisplayCapabilities(uint32_t *outNumCapabilities,
+                                       uint32_t *outCapabilities);
+    HWC2::Error GetDisplayBrightnessSupport(bool *supported);
+    HWC2::Error SetDisplayBrightness(float);
+#endif
+    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 *present_fence);
+    HWC2::Error SetActiveConfig(hwc2_config_t config);
+    HWC2::Error ChosePreferredConfig();
+    HWC2::Error SetClientTarget(buffer_handle_t target, int32_t acquire_fence,
+                                int32_t dataspace, hwc_region_t damage);
+    HWC2::Error SetColorMode(int32_t mode);
+    HWC2::Error SetColorTransform(const float *matrix, int32_t hint);
+    HWC2::Error SetOutputBuffer(buffer_handle_t buffer, int32_t release_fence);
+    HWC2::Error SetPowerMode(int32_t mode);
+    HWC2::Error SetVsyncEnabled(int32_t enabled);
+    HWC2::Error ValidateDisplay(uint32_t *num_types, uint32_t *num_requests);
+    HwcLayer *get_layer(hwc2_layer_t layer) {
+      auto it = layers_.find(layer);
+      if (it == layers_.end())
+        return nullptr;
+      return &it->second;
+    }
+
+    /* Statistics */
+    struct Stats {
+      Stats minus(Stats b) {
+        return {total_frames_ - b.total_frames_,
+                total_pixops_ - b.total_pixops_,
+                gpu_pixops_ - b.gpu_pixops_,
+                failed_kms_validate_ - b.failed_kms_validate_,
+                failed_kms_present_ - b.failed_kms_present_,
+                frames_flattened_ - b.frames_flattened_};
+      }
+
+      uint32_t total_frames_ = 0;
+      uint64_t total_pixops_ = 0;
+      uint64_t gpu_pixops_ = 0;
+      uint32_t failed_kms_validate_ = 0;
+      uint32_t failed_kms_present_ = 0;
+      uint32_t frames_flattened_ = 0;
+    };
+
+    const Backend *backend() const {
+      return backend_.get();
+    }
+    void set_backend(std::unique_ptr<Backend> backend) {
+      backend_ = std::move(backend);
+    }
+
+    const std::vector<DrmPlane *> &primary_planes() const {
+      return primary_planes_;
+    }
+
+    const std::vector<DrmPlane *> &overlay_planes() const {
+      return overlay_planes_;
+    }
+
+    std::map<hwc2_layer_t, HwcLayer> &layers() {
+      return layers_;
+    }
+
+    const DrmDisplayCompositor &compositor() const {
+      return compositor_;
+    }
+
+    const DrmDevice *drm() const {
+      return drm_;
+    }
+
+    const DrmConnector *connector() const {
+      return connector_;
+    }
+
+    const std::shared_ptr<Importer> &importer() const {
+      return importer_;
+    }
+
+    ResourceManager *resource_manager() const {
+      return resource_manager_;
+    }
+
+    android_color_transform_t &color_transform_hint() {
+      return color_transform_hint_;
+    }
+
+    Stats &total_stats() {
+      return total_stats_;
+    }
+
+   private:
+    void AddFenceToPresentFence(int fd);
+
+    constexpr static size_t MATRIX_SIZE = 16;
+
+    ResourceManager *resource_manager_;
+    DrmDevice *drm_;
+    DrmDisplayCompositor compositor_;
+    std::shared_ptr<Importer> importer_;
+    std::unique_ptr<Planner> planner_;
+
+    std::vector<DrmPlane *> primary_planes_;
+    std::vector<DrmPlane *> overlay_planes_;
+
+    std::unique_ptr<Backend> backend_;
+
+    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 present_fence_;
+    int32_t color_mode_;
+    std::array<float, MATRIX_SIZE> color_transform_matrix_;
+    android_color_transform_t color_transform_hint_;
+
+    uint32_t frame_no_ = 0;
+    Stats total_stats_;
+    Stats prev_stats_;
+    std::string DumpDelta(DrmHwcTwo::HwcDisplay::Stats delta);
+  };
+
+  class DrmHotplugHandler : public DrmEventHandler {
+   public:
+    DrmHotplugHandler(DrmHwcTwo *hwc2, DrmDevice *drm)
+        : hwc2_(hwc2), drm_(drm) {
+    }
+    void HandleEvent(uint64_t timestamp_us);
+
+   private:
+    DrmHwcTwo *hwc2_;
+    DrmDevice *drm_;
+  };
+
+ private:
+  static DrmHwcTwo *toDrmHwcTwo(hwc2_device_t *dev) {
+    return static_cast<DrmHwcTwo *>(dev);
+  }
+
+  template <typename PFN, typename T>
+  static hwc2_function_pointer_t ToHook(T function) {
+    static_assert(std::is_same<PFN, T>::value, "Incompatible fn pointer");
+    return reinterpret_cast<hwc2_function_pointer_t>(function);
+  }
+
+  template <typename T, typename HookType, HookType func, typename... Args>
+  static T DeviceHook(hwc2_device_t *dev, Args... args) {
+    DrmHwcTwo *hwc = toDrmHwcTwo(dev);
+    return static_cast<T>(((*hwc).*func)(std::forward<Args>(args)...));
+  }
+
+  static HwcDisplay *GetDisplay(DrmHwcTwo *hwc, hwc2_display_t display_handle) {
+    auto it = hwc->displays_.find(display_handle);
+    if (it == hwc->displays_.end())
+      return nullptr;
+
+    return &it->second;
+  }
+
+  template <typename HookType, HookType func, typename... Args>
+  static int32_t DisplayHook(hwc2_device_t *dev, hwc2_display_t display_handle,
+                             Args... args) {
+    HwcDisplay *display = GetDisplay(toDrmHwcTwo(dev), display_handle);
+    if (!display)
+      return static_cast<int32_t>(HWC2::Error::BadDisplay);
+
+    return static_cast<int32_t>((display->*func)(std::forward<Args>(args)...));
+  }
+
+  template <typename HookType, HookType func, typename... Args>
+  static int32_t LayerHook(hwc2_device_t *dev, hwc2_display_t display_handle,
+                           hwc2_layer_t layer_handle, Args... args) {
+    HwcDisplay *display = GetDisplay(toDrmHwcTwo(dev), display_handle);
+    if (!display)
+      return static_cast<int32_t>(HWC2::Error::BadDisplay);
+
+    HwcLayer *layer = display->get_layer(layer_handle);
+    if (!layer)
+      return static_cast<int32_t>(HWC2::Error::BadLayer);
+
+    return static_cast<int32_t>((layer->*func)(std::forward<Args>(args)...));
+  }
+
+  // hwc2_device_t hooks
+  static int HookDevClose(hw_device_t *dev);
+  static void HookDevGetCapabilities(hwc2_device_t *dev, uint32_t *out_count,
+                                     int32_t *out_capabilities);
+  static hwc2_function_pointer_t HookDevGetFunction(struct hwc2_device *device,
+                                                    int32_t descriptor);
+
+  // Device functions
+  HWC2::Error CreateVirtualDisplay(uint32_t width, uint32_t height,
+                                   int32_t *format, hwc2_display_t *display);
+  HWC2::Error DestroyVirtualDisplay(hwc2_display_t display);
+  void Dump(uint32_t *outSize, char *outBuffer);
+  uint32_t GetMaxVirtualDisplayCount();
+  HWC2::Error RegisterCallback(int32_t descriptor, hwc2_callback_data_t data,
+                               hwc2_function_pointer_t function);
+  HWC2::Error CreateDisplay(hwc2_display_t displ, HWC2::DisplayType type);
+  void HandleDisplayHotplug(hwc2_display_t displayid, int state);
+  void HandleInitialHotplugState(DrmDevice *drmDevice);
+
+  ResourceManager resource_manager_;
+  std::map<hwc2_display_t, HwcDisplay> displays_;
+  std::map<HWC2::Callback, HwcCallback> callbacks_;
+
+  std::string mDumpString;
+};
+}  // namespace android
+
+#endif
