diff --git a/.ci/Makefile b/.ci/Makefile
index c85dd88..ebe534f 100644
--- a/.ci/Makefile
+++ b/.ci/Makefile
@@ -37,6 +37,8 @@
     drm/DrmProperty.cpp:COARSE                          \
     drm/UEventListener.cpp:COARSE                       \
     drm/VSyncWorker.cpp:COARSE                          \
+    hwc2_device/HwcDisplay.cpp:COARSE                   \
+    hwc2_device/HwcDisplay.h:COARSE                     \
     tests/worker_test.cpp:COARSE                        \
     utils/Worker.h:COARSE                               \
     utils/UniqueFd.h:FINE                               \
diff --git a/Android.bp b/Android.bp
index 0a05376..d72e13a 100644
--- a/Android.bp
+++ b/Android.bp
@@ -110,6 +110,7 @@
         "backend/BackendManager.cpp",
         "backend/BackendRCarDu.cpp",
 
+        "hwc2_device/HwcDisplay.cpp",
         "hwc2_device/HwcLayer.cpp",
         "hwc2_device/hwc2_device.cpp",
     ],
diff --git a/DrmHwcTwo.cpp b/DrmHwcTwo.cpp
index 76fecf9..5bbb48a 100644
--- a/DrmHwcTwo.cpp
+++ b/DrmHwcTwo.cpp
@@ -14,27 +14,12 @@
  * limitations under the License.
  */
 
-#define ATRACE_TAG ATRACE_TAG_GRAPHICS
 #define LOG_TAG "hwc-drm-two"
 
 #include "DrmHwcTwo.h"
 
-#include <fcntl.h>
-#include <hardware/hardware.h>
-#include <hardware/hwcomposer2.h>
-#include <sync/sync.h>
-#include <unistd.h>
-
-#include <cinttypes>
-#include <iostream>
-#include <sstream>
-#include <string>
-
-#include "backend/BackendManager.h"
-#include "bufferinfo/BufferInfoGetter.h"
-#include "compositor/DrmDisplayComposition.h"
+#include "backend/Backend.h"
 #include "utils/log.h"
-#include "utils/properties.h"
 
 namespace android {
 
@@ -100,60 +85,6 @@
   return HWC2::Error::Unsupported;
 }
 
-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_);
-
-  std::stringstream ss;
-  ss << " 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;
-
-  return ss.str();
-}
-
-std::string DrmHwcTwo::HwcDisplay::Dump() {
-  std::string flattening_state_str;
-  switch (flattenning_state_) {
-    case ClientFlattenningState::Disabled:
-      flattening_state_str = "Disabled";
-      break;
-    case ClientFlattenningState::NotRequired:
-      flattening_state_str = "Not needed";
-      break;
-    case ClientFlattenningState::Flattened:
-      flattening_state_str = "Active";
-      break;
-    case ClientFlattenningState::ClientRefreshRequested:
-      flattening_state_str = "Refresh requested";
-      break;
-    default:
-      flattening_state_str = std::to_string(flattenning_state_) +
-                             " VSync remains";
-  }
-
-  std::stringstream ss;
-  ss << "- Display on: " << connector_->name() << "\n"
-     << "  Flattening state: " << flattening_state_str << "\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";
-
-  memcpy(&prev_stats_, &total_stats_, sizeof(Stats));
-  return ss.str();
-}
-
 void DrmHwcTwo::Dump(uint32_t *outSize, char *outBuffer) {
   if (outBuffer != nullptr) {
     auto copied_bytes = mDumpString.copy(outBuffer, *outSize);
@@ -165,7 +96,7 @@
 
   output << "-- drm_hwcomposer --\n\n";
 
-  for (std::pair<const hwc2_display_t, DrmHwcTwo::HwcDisplay> &dp : displays_)
+  for (std::pair<const hwc2_display_t, HwcDisplay> &dp : displays_)
     output << dp.second.Dump();
 
   mDumpString = output.str();
@@ -211,880 +142,6 @@
   return HWC2::Error::None;
 }
 
-DrmHwcTwo::HwcDisplay::HwcDisplay(ResourceManager *resource_manager,
-                                  DrmDevice *drm, hwc2_display_t handle,
-                                  HWC2::DisplayType type, DrmHwcTwo *hwc2)
-    : hwc2_(hwc2),
-      resource_manager_(resource_manager),
-      drm_(drm),
-      handle_(handle),
-      type_(type),
-      color_transform_hint_(HAL_COLOR_TRANSFORM_IDENTITY) {
-  // 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() {
-  AtomicCommitArgs a_args = {.clear_active_composition = true};
-  compositor_.ExecuteAtomicCommit(a_args);
-}
-
-HWC2::Error DrmHwcTwo::HwcDisplay::Init(std::vector<DrmPlane *> *planes) {
-  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 = strtol(use_overlay_planes_prop, nullptr, 10);
-  for (auto &plane : *planes) {
-    if (plane->GetType() == DRM_PLANE_TYPE_PRIMARY)
-      primary_planes_.push_back(plane);
-    else if (use_overlay_planes && (plane)->GetType() == 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, [this](int64_t timestamp) {
-    const std::lock_guard<std::mutex> lock(hwc2_->callback_lock_);
-    /* vsync callback */
-#if PLATFORM_SDK_VERSION > 29
-    if (hwc2_->vsync_2_4_callback_.first != nullptr &&
-        hwc2_->vsync_2_4_callback_.second != nullptr) {
-      hwc2_vsync_period_t period_ns{};
-      GetDisplayVsyncPeriod(&period_ns);
-      hwc2_->vsync_2_4_callback_.first(hwc2_->vsync_2_4_callback_.second,
-                                       handle_, timestamp, period_ns);
-    } else
-#endif
-        if (hwc2_->vsync_callback_.first != nullptr &&
-            hwc2_->vsync_callback_.second != nullptr) {
-      hwc2_->vsync_callback_.first(hwc2_->vsync_callback_.second, handle_,
-                                   timestamp);
-    }
-  });
-  if (ret) {
-    ALOGE("Failed to create event worker for d=%d %d\n", display, ret);
-    return HWC2::Error::BadDisplay;
-  }
-
-  ret = flattening_vsync_worker_.Init(drm_, display, [this](int64_t /*timestamp*/) {
-    const std::lock_guard<std::mutex> lock(hwc2_->callback_lock_);
-    /* Frontend flattening */
-    if (flattenning_state_ > ClientFlattenningState::ClientRefreshRequested &&
-        --flattenning_state_ ==
-            ClientFlattenningState::ClientRefreshRequested &&
-        hwc2_->refresh_callback_.first != nullptr &&
-        hwc2_->refresh_callback_.second != nullptr) {
-      hwc2_->refresh_callback_.first(hwc2_->refresh_callback_.second, handle_);
-      flattening_vsync_worker_.VSyncControl(false);
-    }
-  });
-  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;
-  }
-
-  client_layer_.SetLayerBlendMode(HWC2_BLEND_MODE_PREMULTIPLIED);
-
-  return ChosePreferredConfig();
-}
-
-HWC2::Error DrmHwcTwo::HwcDisplay::ChosePreferredConfig() {
-  // Fetch the number of modes from the display
-  uint32_t num_configs = 0;
-  HWC2::Error err = GetDisplayConfigs(&num_configs, nullptr);
-  if (err != HWC2::Error::None || !num_configs)
-    return HWC2::Error::BadDisplay;
-
-  return SetActiveConfig(preferred_config_id_);
-}
-
-HWC2::Error DrmHwcTwo::HwcDisplay::AcceptDisplayChanges() {
-  for (std::pair<const hwc2_layer_t, HwcLayer> &l : layers_)
-    l.second.AcceptTypeChange();
-  return HWC2::Error::None;
-}
-
-HWC2::Error DrmHwcTwo::HwcDisplay::CreateLayer(hwc2_layer_t *layer) {
-  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) {
-  if (!get_layer(layer))
-    return HWC2::Error::BadLayer;
-
-  layers_.erase(layer);
-  return HWC2::Error::None;
-}
-
-HWC2::Error DrmHwcTwo::HwcDisplay::GetActiveConfig(
-    hwc2_config_t *config) const {
-  if (hwc_configs_.count(active_config_id_) == 0)
-    return HWC2::Error::BadConfig;
-
-  *config = active_config_id_;
-  return HWC2::Error::None;
-}
-
-HWC2::Error DrmHwcTwo::HwcDisplay::GetChangedCompositionTypes(
-    uint32_t *num_elements, hwc2_layer_t *layers, int32_t *types) {
-  uint32_t num_changes = 0;
-  for (std::pair<const hwc2_layer_t, HwcLayer> &l : layers_) {
-    if (l.second.IsTypeChanged()) {
-      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.GetValidatedType());
-      ++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) {
-  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)
-    return HWC2::Error::Unsupported;
-
-  // TODO(nobody): 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) {
-  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) {
-  int conf = static_cast<int>(config);
-
-  if (hwc_configs_.count(conf) == 0) {
-    ALOGE("Could not find active mode for %d", conf);
-    return HWC2::Error::BadConfig;
-  }
-
-  auto &hwc_config = hwc_configs_[conf];
-
-  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 = static_cast<int>(hwc_config.mode.h_display());
-      break;
-    case HWC2::Attribute::Height:
-      *value = static_cast<int>(hwc_config.mode.v_display());
-      break;
-    case HWC2::Attribute::VsyncPeriod:
-      // in nanoseconds
-      *value = static_cast<int>(1E9 / hwc_config.mode.v_refresh());
-      break;
-    case HWC2::Attribute::DpiX:
-      // Dots per 1000 inches
-      *value = mm_width ? static_cast<int>(hwc_config.mode.h_display() *
-                                           kUmPerInch / mm_width)
-                        : -1;
-      break;
-    case HWC2::Attribute::DpiY:
-      // Dots per 1000 inches
-      *value = mm_height ? static_cast<int>(hwc_config.mode.v_display() *
-                                            kUmPerInch / mm_height)
-                         : -1;
-      break;
-#if PLATFORM_SDK_VERSION > 29
-    case HWC2::Attribute::ConfigGroup:
-      /* Dispite ConfigGroup is a part of HWC2.4 API, framework
-       * able to request it even if service @2.1 is used */
-      *value = hwc_config.group_id;
-      break;
-#endif
-    default:
-      *value = -1;
-      return HWC2::Error::BadConfig;
-  }
-  return HWC2::Error::None;
-}
-
-// NOLINTNEXTLINE (readability-function-cognitive-complexity): Fixme
-HWC2::Error DrmHwcTwo::HwcDisplay::GetDisplayConfigs(uint32_t *num_configs,
-                                                     hwc2_config_t *configs) {
-  // 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;
-    }
-
-    hwc_configs_.clear();
-    preferred_config_id_ = 0;
-    int preferred_config_group_id_ = 0;
-
-    if (connector_->modes().empty()) {
-      ALOGE("No modes reported by KMS");
-      return HWC2::Error::BadDisplay;
-    }
-
-    int last_config_id = 1;
-    int last_group_id = 1;
-
-    /* Group modes */
-    for (const auto &mode : connector_->modes()) {
-      /* Find group for the new mode or create new group */
-      int group_found = 0;
-      for (auto &hwc_config : hwc_configs_) {
-        if (mode.h_display() == hwc_config.second.mode.h_display() &&
-            mode.v_display() == hwc_config.second.mode.v_display()) {
-          group_found = hwc_config.second.group_id;
-        }
-      }
-      if (group_found == 0) {
-        group_found = last_group_id++;
-      }
-
-      bool disabled = false;
-      if (mode.flags() & DRM_MODE_FLAG_3D_MASK) {
-        ALOGI("Disabling display mode %s (Modes with 3D flag aren't supported)",
-              mode.name().c_str());
-        disabled = true;
-      }
-
-      /* Add config */
-      hwc_configs_[last_config_id] = {
-          .id = last_config_id,
-          .group_id = group_found,
-          .mode = mode,
-          .disabled = disabled,
-      };
-
-      /* Chwck if the mode is preferred */
-      if ((mode.type() & DRM_MODE_TYPE_PREFERRED) != 0 &&
-          preferred_config_id_ == 0) {
-        preferred_config_id_ = last_config_id;
-        preferred_config_group_id_ = group_found;
-      }
-
-      last_config_id++;
-    }
-
-    /* We must have preferred mode. Set first mode as preferred
-     * in case KMS haven't reported anything. */
-    if (preferred_config_id_ == 0) {
-      preferred_config_id_ = 1;
-      preferred_config_group_id_ = 1;
-    }
-
-    for (int group = 1; group < last_group_id; group++) {
-      bool has_interlaced = false;
-      bool has_progressive = false;
-      for (auto &hwc_config : hwc_configs_) {
-        if (hwc_config.second.group_id != group || hwc_config.second.disabled) {
-          continue;
-        }
-
-        if (hwc_config.second.IsInterlaced()) {
-          has_interlaced = true;
-        } else {
-          has_progressive = true;
-        }
-      }
-
-      bool has_both = has_interlaced && has_progressive;
-      if (!has_both) {
-        continue;
-      }
-
-      bool group_contains_preferred_interlaced = false;
-      if (group == preferred_config_group_id_ &&
-          hwc_configs_[preferred_config_id_].IsInterlaced()) {
-        group_contains_preferred_interlaced = true;
-      }
-
-      for (auto &hwc_config : hwc_configs_) {
-        if (hwc_config.second.group_id != group || hwc_config.second.disabled) {
-          continue;
-        }
-
-        bool disable = group_contains_preferred_interlaced
-                           ? !hwc_config.second.IsInterlaced()
-                           : hwc_config.second.IsInterlaced();
-
-        if (disable) {
-          ALOGI(
-              "Group %i: Disabling display mode %s (This group should consist "
-              "of %s modes)",
-              group, hwc_config.second.mode.name().c_str(),
-              group_contains_preferred_interlaced ? "interlaced"
-                                                  : "progressive");
-
-          hwc_config.second.disabled = true;
-        }
-      }
-    }
-
-    /* Group should not contain 2 modes with FPS delta less than ~1HZ
-     * otherwise android.graphics.cts.SetFrameRateTest CTS will fail
-     */
-    for (int m1 = 1; m1 < last_config_id; m1++) {
-      for (int m2 = 1; m2 < last_config_id; m2++) {
-        if (m1 != m2 &&
-            hwc_configs_[m1].group_id == hwc_configs_[m2].group_id &&
-            !hwc_configs_[m1].disabled && !hwc_configs_[m2].disabled &&
-            fabsf(hwc_configs_[m1].mode.v_refresh() -
-                  hwc_configs_[m2].mode.v_refresh()) < 1.0) {
-          ALOGI(
-              "Group %i: Disabling display mode %s (Refresh rate value is "
-              "too close to existing mode %s)",
-              hwc_configs_[m2].group_id, hwc_configs_[m2].mode.name().c_str(),
-              hwc_configs_[m1].mode.name().c_str());
-
-          hwc_configs_[m2].disabled = true;
-        }
-      }
-    }
-  }
-
-  uint32_t idx = 0;
-  for (auto &hwc_config : hwc_configs_) {
-    if (hwc_config.second.disabled) {
-      continue;
-    }
-
-    if (configs != nullptr) {
-      if (idx >= *num_configs) {
-        break;
-      }
-      configs[idx] = hwc_config.second.id;
-    }
-
-    idx++;
-  }
-  *num_configs = idx;
-  return HWC2::Error::None;
-}
-
-HWC2::Error DrmHwcTwo::HwcDisplay::GetDisplayName(uint32_t *size, char *name) {
-  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*/) {
-  // TODO(nobody): I think virtual display should request
-  //      HWC2_DISPLAY_REQUEST_WRITE_CLIENT_TARGET_TO_OUTPUT here
-  *num_elements = 0;
-  return HWC2::Error::None;
-}
-
-HWC2::Error DrmHwcTwo::HwcDisplay::GetDisplayType(int32_t *type) {
-  *type = static_cast<int32_t>(type_);
-  return HWC2::Error::None;
-}
-
-HWC2::Error DrmHwcTwo::HwcDisplay::GetDozeSupport(int32_t *support) {
-  *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*/) {
-  *num_types = 0;
-  return HWC2::Error::None;
-}
-
-/* Find API details at:
- * https://cs.android.com/android/platform/superproject/+/android-11.0.0_r3:hardware/libhardware/include/hardware/hwcomposer2.h;l=1767
- */
-HWC2::Error DrmHwcTwo::HwcDisplay::GetReleaseFences(uint32_t *num_elements,
-                                                    hwc2_layer_t *layers,
-                                                    int32_t *fences) {
-  uint32_t num_layers = 0;
-
-  for (std::pair<const hwc2_layer_t, HwcLayer> &l : layers_) {
-    ++num_layers;
-    if (layers == nullptr || fences == nullptr)
-      continue;
-
-    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.GetReleaseFence().Release();
-  }
-  *num_elements = num_layers;
-  return HWC2::Error::None;
-}
-
-HWC2::Error DrmHwcTwo::HwcDisplay::CreateComposition(AtomicCommitArgs &a_args) {
-  // order the layers by z-order
-  bool use_client_layer = false;
-  uint32_t client_z_order = UINT32_MAX;
-  std::map<uint32_t, HwcLayer *> z_map;
-  for (std::pair<const hwc2_layer_t, HwcLayer> &l : layers_) {
-    switch (l.second.GetValidatedType()) {
-      case HWC2::Composition::Device:
-        z_map.emplace(std::make_pair(l.second.GetZOrder(), &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.GetZOrder());
-        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;
-
-  std::vector<DrmHwcLayer> composition_layers;
-
-  // now that they're ordered by z, add them to the composition
-  for (std::pair<const uint32_t, HwcLayer *> &l : z_map) {
-    DrmHwcLayer layer;
-    l.second->PopulateDrmLayer(&layer);
-    int ret = layer.ImportBuffer(drm_);
-    if (ret) {
-      ALOGE("Failed to import layer, ret=%d", ret);
-      return HWC2::Error::NoResources;
-    }
-    composition_layers.emplace_back(std::move(layer));
-  }
-
-  auto composition = std::make_shared<DrmDisplayComposition>(crtc_);
-
-  // TODO(nobody): Don't always assume geometry changed
-  int ret = composition->SetLayers(composition_layers.data(),
-                                   composition_layers.size());
-  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) {
-    ALOGV("Failed to plan the composition ret=%d", ret);
-    return HWC2::Error::BadConfig;
-  }
-
-  a_args.composition = composition;
-  if (staged_mode) {
-    a_args.display_mode = *staged_mode;
-  }
-  ret = compositor_.ExecuteAtomicCommit(a_args);
-
-  if (ret) {
-    if (!a_args.test_only)
-      ALOGE("Failed to apply the frame composition ret=%d", ret);
-    return HWC2::Error::BadParameter;
-  }
-
-  if (!a_args.test_only) {
-    staged_mode.reset();
-  }
-
-  return HWC2::Error::None;
-}
-
-/* Find API details at:
- * https://cs.android.com/android/platform/superproject/+/android-11.0.0_r3:hardware/libhardware/include/hardware/hwcomposer2.h;l=1805
- */
-HWC2::Error DrmHwcTwo::HwcDisplay::PresentDisplay(int32_t *present_fence) {
-  HWC2::Error ret;
-
-  ++total_stats_.total_frames_;
-
-  AtomicCommitArgs a_args{};
-  ret = CreateComposition(a_args);
-
-  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 = a_args.out_fence.Release();
-
-  ++frame_no_;
-  return HWC2::Error::None;
-}
-
-HWC2::Error DrmHwcTwo::HwcDisplay::SetActiveConfig(hwc2_config_t config) {
-  int conf = static_cast<int>(config);
-
-  if (hwc_configs_.count(conf) == 0) {
-    ALOGE("Could not find active mode for %d", conf);
-    return HWC2::Error::BadConfig;
-  }
-
-  auto &mode = hwc_configs_[conf].mode;
-
-  staged_mode = mode;
-
-  active_config_id_ = conf;
-
-  // 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);
-
-  return HWC2::Error::None;
-}
-
-/* Find API details at:
- * https://cs.android.com/android/platform/superproject/+/android-11.0.0_r3:hardware/libhardware/include/hardware/hwcomposer2.h;l=1861
- */
-HWC2::Error DrmHwcTwo::HwcDisplay::SetClientTarget(buffer_handle_t target,
-                                                   int32_t acquire_fence,
-                                                   int32_t dataspace,
-                                                   hwc_region_t /*damage*/) {
-  client_layer_.SetLayerBuffer(target, acquire_fence);
-  client_layer_.SetLayerDataspace(dataspace);
-
-  /*
-   * target can be nullptr, this does mean the Composer Service is calling
-   * cleanDisplayResources() on after receiving HOTPLUG event. See more at:
-   * https://cs.android.com/android/platform/superproject/+/master:hardware/interfaces/graphics/composer/2.1/utils/hal/include/composer-hal/2.1/ComposerClient.h;l=350;drc=944b68180b008456ed2eb4d4d329e33b19bd5166
-   */
-  if (target == nullptr) {
-    return HWC2::Error::None;
-  }
-
-  /* TODO: Do not update source_crop every call.
-   * It makes sense to do it once after every hotplug event. */
-  HwcDrmBo bo{};
-  BufferInfoGetter::GetInstance()->ConvertBoInfo(target, &bo);
-
-  hwc_frect_t source_crop = {.left = 0.0F,
-                             .top = 0.0F,
-                             .right = static_cast<float>(bo.width),
-                             .bottom = static_cast<float>(bo.height)};
-  client_layer_.SetLayerSourceCrop(source_crop);
-
-  return HWC2::Error::None;
-}
-
-HWC2::Error DrmHwcTwo::HwcDisplay::SetColorMode(int32_t mode) {
-  if (mode < HAL_COLOR_MODE_NATIVE || mode > HAL_COLOR_MODE_BT2100_HLG)
-    return HWC2::Error::BadParameter;
-
-  if (mode != HAL_COLOR_MODE_NATIVE)
-    return HWC2::Error::Unsupported;
-
-  color_mode_ = mode;
-  return HWC2::Error::None;
-}
-
-HWC2::Error DrmHwcTwo::HwcDisplay::SetColorTransform(const float *matrix,
-                                                     int32_t hint) {
-  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*/) {
-  // TODO(nobody): Need virtual display support
-  return HWC2::Error::Unsupported;
-}
-
-HWC2::Error DrmHwcTwo::HwcDisplay::SetPowerMode(int32_t mode_in) {
-  auto mode = static_cast<HWC2::PowerMode>(mode_in);
-  AtomicCommitArgs a_args{};
-
-  switch (mode) {
-    case HWC2::PowerMode::Off:
-      a_args.active = false;
-      break;
-    case HWC2::PowerMode::On:
-      /*
-       * Setting the display to active before we have a composition
-       * can break some drivers, so skip setting a_args.active to
-       * true, as the next composition frame will implicitly activate
-       * the display
-       */
-      return HWC2::Error::None;
-      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;
-  };
-
-  int err = compositor_.ExecuteAtomicCommit(a_args);
-  if (err) {
-    ALOGE("Failed to apply the dpms composition err=%d", err);
-    return HWC2::Error::BadParameter;
-  }
-  return HWC2::Error::None;
-}
-
-HWC2::Error DrmHwcTwo::HwcDisplay::SetVsyncEnabled(int32_t enabled) {
-  vsync_worker_.VSyncControl(HWC2_VSYNC_ENABLE == enabled);
-  return HWC2::Error::None;
-}
-
-HWC2::Error DrmHwcTwo::HwcDisplay::ValidateDisplay(uint32_t *num_types,
-                                                   uint32_t *num_requests) {
-  return backend_->ValidateDisplay(this, num_types, num_requests);
-}
-
-std::vector<HwcLayer *> DrmHwcTwo::HwcDisplay::GetOrderLayersByZPos() {
-  std::vector<HwcLayer *> ordered_layers;
-  ordered_layers.reserve(layers_.size());
-
-  for (auto &[handle, layer] : layers_) {
-    ordered_layers.emplace_back(&layer);
-  }
-
-  std::sort(std::begin(ordered_layers), std::end(ordered_layers),
-            [](const HwcLayer *lhs, const HwcLayer *rhs) {
-              return lhs->GetZOrder() < rhs->GetZOrder();
-            });
-
-  return ordered_layers;
-}
-
-#if PLATFORM_SDK_VERSION > 29
-HWC2::Error DrmHwcTwo::HwcDisplay::GetDisplayConnectionType(uint32_t *outType) {
-  if (connector_->internal())
-    *outType = static_cast<uint32_t>(HWC2::DisplayConnectionType::Internal);
-  else if (connector_->external())
-    *outType = static_cast<uint32_t>(HWC2::DisplayConnectionType::External);
-  else
-    return HWC2::Error::BadConfig;
-
-  return HWC2::Error::None;
-}
-
-HWC2::Error DrmHwcTwo::HwcDisplay::GetDisplayVsyncPeriod(
-    hwc2_vsync_period_t *outVsyncPeriod /* ns */) {
-  return GetDisplayAttribute(active_config_id_, HWC2_ATTRIBUTE_VSYNC_PERIOD,
-                             (int32_t *)(outVsyncPeriod));
-}
-
-HWC2::Error DrmHwcTwo::HwcDisplay::SetActiveConfigWithConstraints(
-    hwc2_config_t /*config*/,
-    hwc_vsync_period_change_constraints_t *vsyncPeriodChangeConstraints,
-    hwc_vsync_period_change_timeline_t *outTimeline) {
-  if (vsyncPeriodChangeConstraints == nullptr || outTimeline == nullptr) {
-    return HWC2::Error::BadParameter;
-  }
-
-  return HWC2::Error::BadConfig;
-}
-
-HWC2::Error DrmHwcTwo::HwcDisplay::SetAutoLowLatencyMode(bool /*on*/) {
-  return HWC2::Error::Unsupported;
-}
-
-HWC2::Error DrmHwcTwo::HwcDisplay::GetSupportedContentTypes(
-    uint32_t *outNumSupportedContentTypes,
-    const uint32_t *outSupportedContentTypes) {
-  if (outSupportedContentTypes == nullptr)
-    *outNumSupportedContentTypes = 0;
-
-  return HWC2::Error::None;
-}
-
-HWC2::Error DrmHwcTwo::HwcDisplay::SetContentType(int32_t contentType) {
-  if (contentType != HWC2_CONTENT_TYPE_NONE)
-    return HWC2::Error::Unsupported;
-
-  /* TODO: Map to the DRM Connector property:
-   * https://elixir.bootlin.com/linux/v5.4-rc5/source/drivers/gpu/drm/drm_connector.c#L809
-   */
-
-  return HWC2::Error::None;
-}
-#endif
-
-#if PLATFORM_SDK_VERSION > 28
-HWC2::Error DrmHwcTwo::HwcDisplay::GetDisplayIdentificationData(
-    uint8_t *outPort, uint32_t *outDataSize, uint8_t *outData) {
-  auto blob = connector_->GetEdidBlob();
-
-  if (!blob) {
-    ALOGE("Failed to get edid property value.");
-    return HWC2::Error::Unsupported;
-  }
-
-  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*/) {
-  if (outNumCapabilities == nullptr) {
-    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 (intent < HAL_RENDER_INTENT_COLORIMETRIC ||
-      intent > HAL_RENDER_INTENT_TONE_MAP_ENHANCE)
-    return HWC2::Error::BadParameter;
-
-  if (mode < HAL_COLOR_MODE_NATIVE || mode > HAL_COLOR_MODE_BT2100_HLG)
-    return HWC2::Error::BadParameter;
-
-  if (mode != HAL_COLOR_MODE_NATIVE)
-    return HWC2::Error::Unsupported;
-
-  if (intent != HAL_RENDER_INTENT_COLORIMETRIC)
-    return HWC2::Error::Unsupported;
-
-  color_mode_ = mode;
-  return HWC2::Error::None;
-}
-
-#endif /* PLATFORM_SDK_VERSION > 27 */
-
-const Backend *DrmHwcTwo::HwcDisplay::backend() const {
-  return backend_.get();
-}
-
-void DrmHwcTwo::HwcDisplay::set_backend(std::unique_ptr<Backend> backend) {
-  backend_ = std::move(backend);
-}
-
 void DrmHwcTwo::HandleDisplayHotplug(hwc2_display_t displayid, int state) {
   const std::lock_guard<std::mutex> lock(callback_lock_);
 
diff --git a/DrmHwcTwo.h b/DrmHwcTwo.h
index de70199..d096160 100644
--- a/DrmHwcTwo.h
+++ b/DrmHwcTwo.h
@@ -19,21 +19,11 @@
 
 #include <hardware/hwcomposer2.h>
 
-#include <array>
-#include <cmath>
-#include <map>
-#include <optional>
-
-#include "compositor/DrmDisplayCompositor.h"
 #include "drm/ResourceManager.h"
-#include "drm/VSyncWorker.h"
-#include "drmhwcomposer.h"
-#include "hwc2_device/HwcLayer.h"
+#include "hwc2_device/HwcDisplay.h"
 
 namespace android {
 
-class Backend;
-
 class DrmHwcTwo {
  public:
   DrmHwcTwo();
@@ -49,236 +39,6 @@
 
   std::mutex callback_lock_;
 
-  class HwcDisplay {
-   public:
-    HwcDisplay(ResourceManager *resource_manager, DrmDevice *drm,
-               hwc2_display_t handle, HWC2::DisplayType type, DrmHwcTwo *hwc2);
-    HwcDisplay(const HwcDisplay &) = delete;
-    HWC2::Error Init(std::vector<DrmPlane *> *planes);
-
-    HWC2::Error CreateComposition(AtomicCommitArgs &a_args);
-    std::vector<HwcLayer *> GetOrderLayersByZPos();
-
-    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) const;
-    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
-#if PLATFORM_SDK_VERSION > 29
-    HWC2::Error GetDisplayConnectionType(uint32_t *outType);
-    HWC2::Error GetDisplayVsyncPeriod(hwc2_vsync_period_t *outVsyncPeriod);
-
-    HWC2::Error SetActiveConfigWithConstraints(
-        hwc2_config_t config,
-        hwc_vsync_period_change_constraints_t *vsyncPeriodChangeConstraints,
-        hwc_vsync_period_change_timeline_t *outTimeline);
-    HWC2::Error SetAutoLowLatencyMode(bool on);
-    HWC2::Error GetSupportedContentTypes(
-        uint32_t *outNumSupportedContentTypes,
-        const uint32_t *outSupportedContentTypes);
-
-    HWC2::Error SetContentType(int32_t contentType);
-#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) const {
-        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;
-    };
-
-    struct HwcDisplayConfig {
-      int id{};
-      int group_id{};
-      DrmMode mode;
-      bool disabled{};
-
-      bool IsInterlaced() const {
-        return (mode.flags() & DRM_MODE_FLAG_INTERLACE) != 0;
-      }
-    };
-
-    std::map<int /*config_id*/, struct HwcDisplayConfig> hwc_configs_;
-
-    int active_config_id_ = 0;
-    int preferred_config_id_ = 0;
-
-    const Backend *backend() const;
-    void set_backend(std::unique_ptr<Backend> 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_;
-    }
-
-    ResourceManager *resource_manager() const {
-      return resource_manager_;
-    }
-
-    android_color_transform_t &color_transform_hint() {
-      return color_transform_hint_;
-    }
-
-    Stats &total_stats() {
-      return total_stats_;
-    }
-
-    /* returns true if composition should be sent to client */
-    bool ProcessClientFlatteningState(bool skip) {
-      int flattenning_state = flattenning_state_;
-      if (flattenning_state == ClientFlattenningState::Disabled) {
-        return false;
-      }
-
-      if (skip) {
-        flattenning_state_ = ClientFlattenningState::NotRequired;
-        return false;
-      }
-
-      if (flattenning_state == ClientFlattenningState::ClientRefreshRequested) {
-        flattenning_state_ = ClientFlattenningState::Flattened;
-        return true;
-      }
-
-      flattening_vsync_worker_.VSyncControl(true);
-      flattenning_state_ = ClientFlattenningState::VsyncCountdownMax;
-      return false;
-    }
-
-   private:
-    enum ClientFlattenningState : int32_t {
-      Disabled = -3,
-      NotRequired = -2,
-      Flattened = -1,
-      ClientRefreshRequested = 0,
-      VsyncCountdownMax = 60, /* 1 sec @ 60FPS */
-    };
-
-    std::atomic_int flattenning_state_{ClientFlattenningState::NotRequired};
-    VSyncWorker flattening_vsync_worker_;
-
-    constexpr static size_t MATRIX_SIZE = 16;
-
-    DrmHwcTwo *hwc2_;
-
-    std::optional<DrmMode> staged_mode;
-
-    ResourceManager *resource_manager_;
-    DrmDevice *drm_;
-    DrmDisplayCompositor compositor_;
-
-    std::vector<DrmPlane *> primary_planes_;
-    std::vector<DrmPlane *> overlay_planes_;
-
-    std::unique_ptr<Backend> backend_;
-
-    VSyncWorker vsync_worker_;
-    DrmConnector *connector_ = nullptr;
-    DrmCrtc *crtc_ = nullptr;
-    hwc2_display_t handle_;
-    HWC2::DisplayType type_;
-    uint32_t layer_idx_ = 0;
-    std::map<hwc2_layer_t, HwcLayer> layers_;
-    HwcLayer client_layer_;
-    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);
-  };
-
   static HwcDisplay *GetDisplay(DrmHwcTwo *hwc, hwc2_display_t display_handle) {
     auto it = hwc->displays_.find(display_handle);
     if (it == hwc->displays_.end())
diff --git a/backend/Backend.cpp b/backend/Backend.cpp
index 7f87b05..98862ba 100644
--- a/backend/Backend.cpp
+++ b/backend/Backend.cpp
@@ -23,8 +23,7 @@
 
 namespace android {
 
-HWC2::Error Backend::ValidateDisplay(DrmHwcTwo::HwcDisplay *display,
-                                     uint32_t *num_types,
+HWC2::Error Backend::ValidateDisplay(HwcDisplay *display, uint32_t *num_types,
                                      uint32_t *num_requests) {
   *num_types = 0;
   *num_requests = 0;
@@ -67,7 +66,7 @@
 }
 
 std::tuple<int, size_t> Backend::GetClientLayers(
-    DrmHwcTwo::HwcDisplay *display, const std::vector<HwcLayer *> &layers) {
+    HwcDisplay *display, const std::vector<HwcLayer *> &layers) {
   int client_start = -1;
   size_t client_size = 0;
 
@@ -82,7 +81,7 @@
   return GetExtraClientRange(display, layers, client_start, client_size);
 }
 
-bool Backend::IsClientLayer(DrmHwcTwo::HwcDisplay *display, HwcLayer *layer) {
+bool Backend::IsClientLayer(HwcDisplay *display, HwcLayer *layer) {
   return !HardwareSupportsLayerType(layer->GetSfType()) ||
          !BufferInfoGetter::GetInstance()->IsHandleUsable(layer->GetBuffer()) ||
          display->color_transform_hint() != HAL_COLOR_TRANSFORM_IDENTITY ||
@@ -118,7 +117,7 @@
 }
 
 std::tuple<int, int> Backend::GetExtraClientRange(
-    DrmHwcTwo::HwcDisplay *display, const std::vector<HwcLayer *> &layers,
+    HwcDisplay *display, const std::vector<HwcLayer *> &layers,
     int client_start, size_t client_size) {
   size_t avail_planes = display->primary_planes().size() +
                         display->overlay_planes().size();
diff --git a/backend/Backend.h b/backend/Backend.h
index 0273570..1a4833e 100644
--- a/backend/Backend.h
+++ b/backend/Backend.h
@@ -24,12 +24,11 @@
 class Backend {
  public:
   virtual ~Backend() = default;
-  virtual HWC2::Error ValidateDisplay(DrmHwcTwo::HwcDisplay *display,
-                                      uint32_t *num_types,
+  virtual HWC2::Error ValidateDisplay(HwcDisplay *display, uint32_t *num_types,
                                       uint32_t *num_requests);
   virtual std::tuple<int, size_t> GetClientLayers(
-      DrmHwcTwo::HwcDisplay *display, const std::vector<HwcLayer *> &layers);
-  virtual bool IsClientLayer(DrmHwcTwo::HwcDisplay *display, HwcLayer *layer);
+      HwcDisplay *display, const std::vector<HwcLayer *> &layers);
+  virtual bool IsClientLayer(HwcDisplay *display, HwcLayer *layer);
 
  protected:
   static bool HardwareSupportsLayerType(HWC2::Composition comp_type);
@@ -38,7 +37,7 @@
   static void MarkValidated(std::vector<HwcLayer *> &layers,
                             size_t client_first_z, size_t client_size);
   static std::tuple<int, int> GetExtraClientRange(
-      DrmHwcTwo::HwcDisplay *display, const std::vector<HwcLayer *> &layers,
+      HwcDisplay *display, const std::vector<HwcLayer *> &layers,
       int client_start, size_t client_size);
 };
 }  // namespace android
diff --git a/backend/BackendClient.cpp b/backend/BackendClient.cpp
index 73a3b3d..606dca2 100644
--- a/backend/BackendClient.cpp
+++ b/backend/BackendClient.cpp
@@ -20,10 +20,10 @@
 
 namespace android {
 
-HWC2::Error BackendClient::ValidateDisplay(DrmHwcTwo::HwcDisplay *display,
+HWC2::Error BackendClient::ValidateDisplay(HwcDisplay *display,
                                            uint32_t *num_types,
                                            uint32_t * /*num_requests*/) {
-  for (auto & [ layer_handle, layer ] : display->layers()) {
+  for (auto &[layer_handle, layer] : display->layers()) {
     layer.SetValidatedType(HWC2::Composition::Client);
     ++*num_types;
   }
diff --git a/backend/BackendClient.h b/backend/BackendClient.h
index 13543f1..95abb0f 100644
--- a/backend/BackendClient.h
+++ b/backend/BackendClient.h
@@ -23,8 +23,7 @@
 
 class BackendClient : public Backend {
  public:
-  HWC2::Error ValidateDisplay(DrmHwcTwo::HwcDisplay *display,
-                              uint32_t *num_types,
+  HWC2::Error ValidateDisplay(HwcDisplay *display, uint32_t *num_types,
                               uint32_t *num_requests) override;
 };
 }  // namespace android
diff --git a/backend/BackendManager.cpp b/backend/BackendManager.cpp
index 0577e2f..aadef36 100644
--- a/backend/BackendManager.cpp
+++ b/backend/BackendManager.cpp
@@ -41,7 +41,7 @@
   return 0;
 }
 
-int BackendManager::SetBackendForDisplay(DrmHwcTwo::HwcDisplay *display) {
+int BackendManager::SetBackendForDisplay(HwcDisplay *display) {
   std::string driver_name(display->drm()->GetName());
   char backend_override[PROPERTY_VALUE_MAX];
   property_get("vendor.hwc.backend_override", backend_override,
diff --git a/backend/BackendManager.h b/backend/BackendManager.h
index 274484c..751cb78 100644
--- a/backend/BackendManager.h
+++ b/backend/BackendManager.h
@@ -41,10 +41,10 @@
   static BackendManager &GetInstance();
   int RegisterBackend(const std::string &name,
                       BackendConstructorT backend_constructor);
-  int SetBackendForDisplay(DrmHwcTwo::HwcDisplay *display);
+  int SetBackendForDisplay(HwcDisplay *display);
   std::unique_ptr<Backend> GetBackendByName(std::string &name);
-  HWC2::Error ValidateDisplay(DrmHwcTwo::HwcDisplay *display,
-                              uint32_t *num_types, uint32_t *num_requests);
+  HWC2::Error ValidateDisplay(HwcDisplay *display, uint32_t *num_types,
+                              uint32_t *num_requests);
 
  private:
   BackendManager() = default;
diff --git a/backend/BackendRCarDu.cpp b/backend/BackendRCarDu.cpp
index b319d89..0750ee4 100644
--- a/backend/BackendRCarDu.cpp
+++ b/backend/BackendRCarDu.cpp
@@ -22,8 +22,7 @@
 
 namespace android {
 
-bool BackendRCarDu::IsClientLayer(DrmHwcTwo::HwcDisplay *display,
-                                  HwcLayer *layer) {
+bool BackendRCarDu::IsClientLayer(HwcDisplay *display, HwcLayer *layer) {
   hwc_drm_bo_t bo;
 
   int ret = BufferInfoGetter::GetInstance()->ConvertBoInfo(layer->GetBuffer(),
diff --git a/backend/BackendRCarDu.h b/backend/BackendRCarDu.h
index 862bef2..1259c9f 100644
--- a/backend/BackendRCarDu.h
+++ b/backend/BackendRCarDu.h
@@ -23,7 +23,7 @@
 
 class BackendRCarDu : public Backend {
  public:
-  bool IsClientLayer(DrmHwcTwo::HwcDisplay *display, HwcLayer *layer) override;
+  bool IsClientLayer(HwcDisplay *display, HwcLayer *layer) override;
 };
 }  // namespace android
 
diff --git a/hwc2_device/HwcDisplay.cpp b/hwc2_device/HwcDisplay.cpp
new file mode 100644
index 0000000..e0a5823
--- /dev/null
+++ b/hwc2_device/HwcDisplay.cpp
@@ -0,0 +1,958 @@
+/*
+ * Copyright (C) 2022 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 LOG_TAG "hwc-display"
+#define ATRACE_TAG ATRACE_TAG_GRAPHICS
+
+#include "HwcDisplay.h"
+
+#include "DrmHwcTwo.h"
+#include "backend/BackendManager.h"
+#include "bufferinfo/BufferInfoGetter.h"
+#include "utils/log.h"
+#include "utils/properties.h"
+
+namespace android {
+
+std::string HwcDisplay::DumpDelta(HwcDisplay::Stats delta) {
+  if (delta.total_pixops_ == 0)
+    return "No stats yet";
+  double ratio = 1.0 - double(delta.gpu_pixops_) / double(delta.total_pixops_);
+
+  std::stringstream ss;
+  ss << " 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;
+
+  return ss.str();
+}
+
+std::string HwcDisplay::Dump() {
+  std::string flattening_state_str;
+  switch (flattenning_state_) {
+    case ClientFlattenningState::Disabled:
+      flattening_state_str = "Disabled";
+      break;
+    case ClientFlattenningState::NotRequired:
+      flattening_state_str = "Not needed";
+      break;
+    case ClientFlattenningState::Flattened:
+      flattening_state_str = "Active";
+      break;
+    case ClientFlattenningState::ClientRefreshRequested:
+      flattening_state_str = "Refresh requested";
+      break;
+    default:
+      flattening_state_str = std::to_string(flattenning_state_) +
+                             " VSync remains";
+  }
+
+  std::stringstream ss;
+  ss << "- Display on: " << connector_->name() << "\n"
+     << "  Flattening state: " << flattening_state_str << "\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";
+
+  memcpy(&prev_stats_, &total_stats_, sizeof(Stats));
+  return ss.str();
+}
+
+HwcDisplay::HwcDisplay(ResourceManager *resource_manager, DrmDevice *drm,
+                       hwc2_display_t handle, HWC2::DisplayType type,
+                       DrmHwcTwo *hwc2)
+    : hwc2_(hwc2),
+      resource_manager_(resource_manager),
+      drm_(drm),
+      handle_(handle),
+      type_(type),
+      color_transform_hint_(HAL_COLOR_TRANSFORM_IDENTITY) {
+  // 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 HwcDisplay::ClearDisplay() {
+  AtomicCommitArgs a_args = {.clear_active_composition = true};
+  compositor_.ExecuteAtomicCommit(a_args);
+}
+
+HWC2::Error HwcDisplay::Init(std::vector<DrmPlane *> *planes) {
+  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 = strtol(use_overlay_planes_prop, nullptr, 10);
+  for (auto &plane : *planes) {
+    if (plane->GetType() == DRM_PLANE_TYPE_PRIMARY)
+      primary_planes_.push_back(plane);
+    else if (use_overlay_planes && (plane)->GetType() == 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, [this](int64_t timestamp) {
+    const std::lock_guard<std::mutex> lock(hwc2_->callback_lock_);
+    /* vsync callback */
+#if PLATFORM_SDK_VERSION > 29
+    if (hwc2_->vsync_2_4_callback_.first != nullptr &&
+        hwc2_->vsync_2_4_callback_.second != nullptr) {
+      hwc2_vsync_period_t period_ns{};
+      GetDisplayVsyncPeriod(&period_ns);
+      hwc2_->vsync_2_4_callback_.first(hwc2_->vsync_2_4_callback_.second,
+                                       handle_, timestamp, period_ns);
+    } else
+#endif
+        if (hwc2_->vsync_callback_.first != nullptr &&
+            hwc2_->vsync_callback_.second != nullptr) {
+      hwc2_->vsync_callback_.first(hwc2_->vsync_callback_.second, handle_,
+                                   timestamp);
+    }
+  });
+  if (ret) {
+    ALOGE("Failed to create event worker for d=%d %d\n", display, ret);
+    return HWC2::Error::BadDisplay;
+  }
+
+  ret = flattening_vsync_worker_
+            .Init(drm_, display, [this](int64_t /*timestamp*/) {
+              const std::lock_guard<std::mutex> lock(hwc2_->callback_lock_);
+              /* Frontend flattening */
+              if (flattenning_state_ >
+                      ClientFlattenningState::ClientRefreshRequested &&
+                  --flattenning_state_ ==
+                      ClientFlattenningState::ClientRefreshRequested &&
+                  hwc2_->refresh_callback_.first != nullptr &&
+                  hwc2_->refresh_callback_.second != nullptr) {
+                hwc2_->refresh_callback_.first(hwc2_->refresh_callback_.second,
+                                               handle_);
+                flattening_vsync_worker_.VSyncControl(false);
+              }
+            });
+  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;
+  }
+
+  client_layer_.SetLayerBlendMode(HWC2_BLEND_MODE_PREMULTIPLIED);
+
+  return ChosePreferredConfig();
+}
+
+HWC2::Error HwcDisplay::ChosePreferredConfig() {
+  // Fetch the number of modes from the display
+  uint32_t num_configs = 0;
+  HWC2::Error err = GetDisplayConfigs(&num_configs, nullptr);
+  if (err != HWC2::Error::None || !num_configs)
+    return HWC2::Error::BadDisplay;
+
+  return SetActiveConfig(preferred_config_id_);
+}
+
+HWC2::Error HwcDisplay::AcceptDisplayChanges() {
+  for (std::pair<const hwc2_layer_t, HwcLayer> &l : layers_)
+    l.second.AcceptTypeChange();
+  return HWC2::Error::None;
+}
+
+HWC2::Error HwcDisplay::CreateLayer(hwc2_layer_t *layer) {
+  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 HwcDisplay::DestroyLayer(hwc2_layer_t layer) {
+  if (!get_layer(layer))
+    return HWC2::Error::BadLayer;
+
+  layers_.erase(layer);
+  return HWC2::Error::None;
+}
+
+HWC2::Error HwcDisplay::GetActiveConfig(hwc2_config_t *config) const {
+  if (hwc_configs_.count(active_config_id_) == 0)
+    return HWC2::Error::BadConfig;
+
+  *config = active_config_id_;
+  return HWC2::Error::None;
+}
+
+HWC2::Error HwcDisplay::GetChangedCompositionTypes(uint32_t *num_elements,
+                                                   hwc2_layer_t *layers,
+                                                   int32_t *types) {
+  uint32_t num_changes = 0;
+  for (std::pair<const hwc2_layer_t, HwcLayer> &l : layers_) {
+    if (l.second.IsTypeChanged()) {
+      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.GetValidatedType());
+      ++num_changes;
+    }
+  }
+  if (!layers && !types)
+    *num_elements = num_changes;
+  return HWC2::Error::None;
+}
+
+HWC2::Error HwcDisplay::GetClientTargetSupport(uint32_t width, uint32_t height,
+                                               int32_t /*format*/,
+                                               int32_t dataspace) {
+  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)
+    return HWC2::Error::Unsupported;
+
+  // TODO(nobody): Validate format can be handled by either GL or planes
+  return HWC2::Error::None;
+}
+
+HWC2::Error HwcDisplay::GetColorModes(uint32_t *num_modes, int32_t *modes) {
+  if (!modes)
+    *num_modes = 1;
+
+  if (modes)
+    *modes = HAL_COLOR_MODE_NATIVE;
+
+  return HWC2::Error::None;
+}
+
+HWC2::Error HwcDisplay::GetDisplayAttribute(hwc2_config_t config,
+                                            int32_t attribute_in,
+                                            int32_t *value) {
+  int conf = static_cast<int>(config);
+
+  if (hwc_configs_.count(conf) == 0) {
+    ALOGE("Could not find active mode for %d", conf);
+    return HWC2::Error::BadConfig;
+  }
+
+  auto &hwc_config = hwc_configs_[conf];
+
+  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 = static_cast<int>(hwc_config.mode.h_display());
+      break;
+    case HWC2::Attribute::Height:
+      *value = static_cast<int>(hwc_config.mode.v_display());
+      break;
+    case HWC2::Attribute::VsyncPeriod:
+      // in nanoseconds
+      *value = static_cast<int>(1E9 / hwc_config.mode.v_refresh());
+      break;
+    case HWC2::Attribute::DpiX:
+      // Dots per 1000 inches
+      *value = mm_width ? static_cast<int>(hwc_config.mode.h_display() *
+                                           kUmPerInch / mm_width)
+                        : -1;
+      break;
+    case HWC2::Attribute::DpiY:
+      // Dots per 1000 inches
+      *value = mm_height ? static_cast<int>(hwc_config.mode.v_display() *
+                                            kUmPerInch / mm_height)
+                         : -1;
+      break;
+#if PLATFORM_SDK_VERSION > 29
+    case HWC2::Attribute::ConfigGroup:
+      /* Dispite ConfigGroup is a part of HWC2.4 API, framework
+       * able to request it even if service @2.1 is used */
+      *value = hwc_config.group_id;
+      break;
+#endif
+    default:
+      *value = -1;
+      return HWC2::Error::BadConfig;
+  }
+  return HWC2::Error::None;
+}
+
+// NOLINTNEXTLINE (readability-function-cognitive-complexity): Fixme
+HWC2::Error HwcDisplay::GetDisplayConfigs(uint32_t *num_configs,
+                                          hwc2_config_t *configs) {
+  // 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;
+    }
+
+    hwc_configs_.clear();
+    preferred_config_id_ = 0;
+    int preferred_config_group_id_ = 0;
+
+    if (connector_->modes().empty()) {
+      ALOGE("No modes reported by KMS");
+      return HWC2::Error::BadDisplay;
+    }
+
+    int last_config_id = 1;
+    int last_group_id = 1;
+
+    /* Group modes */
+    for (const auto &mode : connector_->modes()) {
+      /* Find group for the new mode or create new group */
+      int group_found = 0;
+      for (auto &hwc_config : hwc_configs_) {
+        if (mode.h_display() == hwc_config.second.mode.h_display() &&
+            mode.v_display() == hwc_config.second.mode.v_display()) {
+          group_found = hwc_config.second.group_id;
+        }
+      }
+      if (group_found == 0) {
+        group_found = last_group_id++;
+      }
+
+      bool disabled = false;
+      if (mode.flags() & DRM_MODE_FLAG_3D_MASK) {
+        ALOGI("Disabling display mode %s (Modes with 3D flag aren't supported)",
+              mode.name().c_str());
+        disabled = true;
+      }
+
+      /* Add config */
+      hwc_configs_[last_config_id] = {
+          .id = last_config_id,
+          .group_id = group_found,
+          .mode = mode,
+          .disabled = disabled,
+      };
+
+      /* Chwck if the mode is preferred */
+      if ((mode.type() & DRM_MODE_TYPE_PREFERRED) != 0 &&
+          preferred_config_id_ == 0) {
+        preferred_config_id_ = last_config_id;
+        preferred_config_group_id_ = group_found;
+      }
+
+      last_config_id++;
+    }
+
+    /* We must have preferred mode. Set first mode as preferred
+     * in case KMS haven't reported anything. */
+    if (preferred_config_id_ == 0) {
+      preferred_config_id_ = 1;
+      preferred_config_group_id_ = 1;
+    }
+
+    for (int group = 1; group < last_group_id; group++) {
+      bool has_interlaced = false;
+      bool has_progressive = false;
+      for (auto &hwc_config : hwc_configs_) {
+        if (hwc_config.second.group_id != group || hwc_config.second.disabled) {
+          continue;
+        }
+
+        if (hwc_config.second.IsInterlaced()) {
+          has_interlaced = true;
+        } else {
+          has_progressive = true;
+        }
+      }
+
+      bool has_both = has_interlaced && has_progressive;
+      if (!has_both) {
+        continue;
+      }
+
+      bool group_contains_preferred_interlaced = false;
+      if (group == preferred_config_group_id_ &&
+          hwc_configs_[preferred_config_id_].IsInterlaced()) {
+        group_contains_preferred_interlaced = true;
+      }
+
+      for (auto &hwc_config : hwc_configs_) {
+        if (hwc_config.second.group_id != group || hwc_config.second.disabled) {
+          continue;
+        }
+
+        bool disable = group_contains_preferred_interlaced
+                           ? !hwc_config.second.IsInterlaced()
+                           : hwc_config.second.IsInterlaced();
+
+        if (disable) {
+          ALOGI(
+              "Group %i: Disabling display mode %s (This group should consist "
+              "of %s modes)",
+              group, hwc_config.second.mode.name().c_str(),
+              group_contains_preferred_interlaced ? "interlaced"
+                                                  : "progressive");
+
+          hwc_config.second.disabled = true;
+        }
+      }
+    }
+
+    /* Group should not contain 2 modes with FPS delta less than ~1HZ
+     * otherwise android.graphics.cts.SetFrameRateTest CTS will fail
+     */
+    for (int m1 = 1; m1 < last_config_id; m1++) {
+      for (int m2 = 1; m2 < last_config_id; m2++) {
+        if (m1 != m2 &&
+            hwc_configs_[m1].group_id == hwc_configs_[m2].group_id &&
+            !hwc_configs_[m1].disabled && !hwc_configs_[m2].disabled &&
+            fabsf(hwc_configs_[m1].mode.v_refresh() -
+                  hwc_configs_[m2].mode.v_refresh()) < 1.0) {
+          ALOGI(
+              "Group %i: Disabling display mode %s (Refresh rate value is "
+              "too close to existing mode %s)",
+              hwc_configs_[m2].group_id, hwc_configs_[m2].mode.name().c_str(),
+              hwc_configs_[m1].mode.name().c_str());
+
+          hwc_configs_[m2].disabled = true;
+        }
+      }
+    }
+  }
+
+  uint32_t idx = 0;
+  for (auto &hwc_config : hwc_configs_) {
+    if (hwc_config.second.disabled) {
+      continue;
+    }
+
+    if (configs != nullptr) {
+      if (idx >= *num_configs) {
+        break;
+      }
+      configs[idx] = hwc_config.second.id;
+    }
+
+    idx++;
+  }
+  *num_configs = idx;
+  return HWC2::Error::None;
+}
+
+HWC2::Error HwcDisplay::GetDisplayName(uint32_t *size, char *name) {
+  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 HwcDisplay::GetDisplayRequests(int32_t * /*display_requests*/,
+                                           uint32_t *num_elements,
+                                           hwc2_layer_t * /*layers*/,
+                                           int32_t * /*layer_requests*/) {
+  // TODO(nobody): I think virtual display should request
+  //      HWC2_DISPLAY_REQUEST_WRITE_CLIENT_TARGET_TO_OUTPUT here
+  *num_elements = 0;
+  return HWC2::Error::None;
+}
+
+HWC2::Error HwcDisplay::GetDisplayType(int32_t *type) {
+  *type = static_cast<int32_t>(type_);
+  return HWC2::Error::None;
+}
+
+HWC2::Error HwcDisplay::GetDozeSupport(int32_t *support) {
+  *support = 0;
+  return HWC2::Error::None;
+}
+
+HWC2::Error HwcDisplay::GetHdrCapabilities(uint32_t *num_types,
+                                           int32_t * /*types*/,
+                                           float * /*max_luminance*/,
+                                           float * /*max_average_luminance*/,
+                                           float * /*min_luminance*/) {
+  *num_types = 0;
+  return HWC2::Error::None;
+}
+
+/* Find API details at:
+ * https://cs.android.com/android/platform/superproject/+/android-11.0.0_r3:hardware/libhardware/include/hardware/hwcomposer2.h;l=1767
+ */
+HWC2::Error HwcDisplay::GetReleaseFences(uint32_t *num_elements,
+                                         hwc2_layer_t *layers,
+                                         int32_t *fences) {
+  uint32_t num_layers = 0;
+
+  for (std::pair<const hwc2_layer_t, HwcLayer> &l : layers_) {
+    ++num_layers;
+    if (layers == nullptr || fences == nullptr)
+      continue;
+
+    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.GetReleaseFence().Release();
+  }
+  *num_elements = num_layers;
+  return HWC2::Error::None;
+}
+
+HWC2::Error HwcDisplay::CreateComposition(AtomicCommitArgs &a_args) {
+  // order the layers by z-order
+  bool use_client_layer = false;
+  uint32_t client_z_order = UINT32_MAX;
+  std::map<uint32_t, HwcLayer *> z_map;
+  for (std::pair<const hwc2_layer_t, HwcLayer> &l : layers_) {
+    switch (l.second.GetValidatedType()) {
+      case HWC2::Composition::Device:
+        z_map.emplace(std::make_pair(l.second.GetZOrder(), &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.GetZOrder());
+        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;
+
+  std::vector<DrmHwcLayer> composition_layers;
+
+  // now that they're ordered by z, add them to the composition
+  for (std::pair<const uint32_t, HwcLayer *> &l : z_map) {
+    DrmHwcLayer layer;
+    l.second->PopulateDrmLayer(&layer);
+    int ret = layer.ImportBuffer(drm_);
+    if (ret) {
+      ALOGE("Failed to import layer, ret=%d", ret);
+      return HWC2::Error::NoResources;
+    }
+    composition_layers.emplace_back(std::move(layer));
+  }
+
+  auto composition = std::make_shared<DrmDisplayComposition>(crtc_);
+
+  // TODO(nobody): Don't always assume geometry changed
+  int ret = composition->SetLayers(composition_layers.data(),
+                                   composition_layers.size());
+  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) {
+    ALOGV("Failed to plan the composition ret=%d", ret);
+    return HWC2::Error::BadConfig;
+  }
+
+  a_args.composition = composition;
+  if (staged_mode) {
+    a_args.display_mode = *staged_mode;
+  }
+  ret = compositor_.ExecuteAtomicCommit(a_args);
+
+  if (ret) {
+    if (!a_args.test_only)
+      ALOGE("Failed to apply the frame composition ret=%d", ret);
+    return HWC2::Error::BadParameter;
+  }
+
+  if (!a_args.test_only) {
+    staged_mode.reset();
+  }
+
+  return HWC2::Error::None;
+}
+
+/* Find API details at:
+ * https://cs.android.com/android/platform/superproject/+/android-11.0.0_r3:hardware/libhardware/include/hardware/hwcomposer2.h;l=1805
+ */
+HWC2::Error HwcDisplay::PresentDisplay(int32_t *present_fence) {
+  HWC2::Error ret;
+
+  ++total_stats_.total_frames_;
+
+  AtomicCommitArgs a_args{};
+  ret = CreateComposition(a_args);
+
+  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 = a_args.out_fence.Release();
+
+  ++frame_no_;
+  return HWC2::Error::None;
+}
+
+HWC2::Error HwcDisplay::SetActiveConfig(hwc2_config_t config) {
+  int conf = static_cast<int>(config);
+
+  if (hwc_configs_.count(conf) == 0) {
+    ALOGE("Could not find active mode for %d", conf);
+    return HWC2::Error::BadConfig;
+  }
+
+  auto &mode = hwc_configs_[conf].mode;
+
+  staged_mode = mode;
+
+  active_config_id_ = conf;
+
+  // 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);
+
+  return HWC2::Error::None;
+}
+
+/* Find API details at:
+ * https://cs.android.com/android/platform/superproject/+/android-11.0.0_r3:hardware/libhardware/include/hardware/hwcomposer2.h;l=1861
+ */
+HWC2::Error HwcDisplay::SetClientTarget(buffer_handle_t target,
+                                        int32_t acquire_fence,
+                                        int32_t dataspace,
+                                        hwc_region_t /*damage*/) {
+  client_layer_.SetLayerBuffer(target, acquire_fence);
+  client_layer_.SetLayerDataspace(dataspace);
+
+  /*
+   * target can be nullptr, this does mean the Composer Service is calling
+   * cleanDisplayResources() on after receiving HOTPLUG event. See more at:
+   * https://cs.android.com/android/platform/superproject/+/master:hardware/interfaces/graphics/composer/2.1/utils/hal/include/composer-hal/2.1/ComposerClient.h;l=350;drc=944b68180b008456ed2eb4d4d329e33b19bd5166
+   */
+  if (target == nullptr) {
+    return HWC2::Error::None;
+  }
+
+  /* TODO: Do not update source_crop every call.
+   * It makes sense to do it once after every hotplug event. */
+  HwcDrmBo bo{};
+  BufferInfoGetter::GetInstance()->ConvertBoInfo(target, &bo);
+
+  hwc_frect_t source_crop = {.left = 0.0F,
+                             .top = 0.0F,
+                             .right = static_cast<float>(bo.width),
+                             .bottom = static_cast<float>(bo.height)};
+  client_layer_.SetLayerSourceCrop(source_crop);
+
+  return HWC2::Error::None;
+}
+
+HWC2::Error HwcDisplay::SetColorMode(int32_t mode) {
+  if (mode < HAL_COLOR_MODE_NATIVE || mode > HAL_COLOR_MODE_BT2100_HLG)
+    return HWC2::Error::BadParameter;
+
+  if (mode != HAL_COLOR_MODE_NATIVE)
+    return HWC2::Error::Unsupported;
+
+  color_mode_ = mode;
+  return HWC2::Error::None;
+}
+
+HWC2::Error HwcDisplay::SetColorTransform(const float *matrix, int32_t hint) {
+  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 HwcDisplay::SetOutputBuffer(buffer_handle_t /*buffer*/,
+                                        int32_t /*release_fence*/) {
+  // TODO(nobody): Need virtual display support
+  return HWC2::Error::Unsupported;
+}
+
+HWC2::Error HwcDisplay::SetPowerMode(int32_t mode_in) {
+  auto mode = static_cast<HWC2::PowerMode>(mode_in);
+  AtomicCommitArgs a_args{};
+
+  switch (mode) {
+    case HWC2::PowerMode::Off:
+      a_args.active = false;
+      break;
+    case HWC2::PowerMode::On:
+      /*
+       * Setting the display to active before we have a composition
+       * can break some drivers, so skip setting a_args.active to
+       * true, as the next composition frame will implicitly activate
+       * the display
+       */
+      return HWC2::Error::None;
+      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;
+  };
+
+  int err = compositor_.ExecuteAtomicCommit(a_args);
+  if (err) {
+    ALOGE("Failed to apply the dpms composition err=%d", err);
+    return HWC2::Error::BadParameter;
+  }
+  return HWC2::Error::None;
+}
+
+HWC2::Error HwcDisplay::SetVsyncEnabled(int32_t enabled) {
+  vsync_worker_.VSyncControl(HWC2_VSYNC_ENABLE == enabled);
+  return HWC2::Error::None;
+}
+
+HWC2::Error HwcDisplay::ValidateDisplay(uint32_t *num_types,
+                                        uint32_t *num_requests) {
+  return backend_->ValidateDisplay(this, num_types, num_requests);
+}
+
+std::vector<HwcLayer *> HwcDisplay::GetOrderLayersByZPos() {
+  std::vector<HwcLayer *> ordered_layers;
+  ordered_layers.reserve(layers_.size());
+
+  for (auto &[handle, layer] : layers_) {
+    ordered_layers.emplace_back(&layer);
+  }
+
+  std::sort(std::begin(ordered_layers), std::end(ordered_layers),
+            [](const HwcLayer *lhs, const HwcLayer *rhs) {
+              return lhs->GetZOrder() < rhs->GetZOrder();
+            });
+
+  return ordered_layers;
+}
+
+#if PLATFORM_SDK_VERSION > 29
+HWC2::Error HwcDisplay::GetDisplayConnectionType(uint32_t *outType) {
+  if (connector_->internal())
+    *outType = static_cast<uint32_t>(HWC2::DisplayConnectionType::Internal);
+  else if (connector_->external())
+    *outType = static_cast<uint32_t>(HWC2::DisplayConnectionType::External);
+  else
+    return HWC2::Error::BadConfig;
+
+  return HWC2::Error::None;
+}
+
+HWC2::Error HwcDisplay::GetDisplayVsyncPeriod(
+    hwc2_vsync_period_t *outVsyncPeriod /* ns */) {
+  return GetDisplayAttribute(active_config_id_, HWC2_ATTRIBUTE_VSYNC_PERIOD,
+                             (int32_t *)(outVsyncPeriod));
+}
+
+HWC2::Error HwcDisplay::SetActiveConfigWithConstraints(
+    hwc2_config_t /*config*/,
+    hwc_vsync_period_change_constraints_t *vsyncPeriodChangeConstraints,
+    hwc_vsync_period_change_timeline_t *outTimeline) {
+  if (vsyncPeriodChangeConstraints == nullptr || outTimeline == nullptr) {
+    return HWC2::Error::BadParameter;
+  }
+
+  return HWC2::Error::BadConfig;
+}
+
+HWC2::Error HwcDisplay::SetAutoLowLatencyMode(bool /*on*/) {
+  return HWC2::Error::Unsupported;
+}
+
+HWC2::Error HwcDisplay::GetSupportedContentTypes(
+    uint32_t *outNumSupportedContentTypes,
+    const uint32_t *outSupportedContentTypes) {
+  if (outSupportedContentTypes == nullptr)
+    *outNumSupportedContentTypes = 0;
+
+  return HWC2::Error::None;
+}
+
+HWC2::Error HwcDisplay::SetContentType(int32_t contentType) {
+  if (contentType != HWC2_CONTENT_TYPE_NONE)
+    return HWC2::Error::Unsupported;
+
+  /* TODO: Map to the DRM Connector property:
+   * https://elixir.bootlin.com/linux/v5.4-rc5/source/drivers/gpu/drm/drm_connector.c#L809
+   */
+
+  return HWC2::Error::None;
+}
+#endif
+
+#if PLATFORM_SDK_VERSION > 28
+HWC2::Error HwcDisplay::GetDisplayIdentificationData(uint8_t *outPort,
+                                                     uint32_t *outDataSize,
+                                                     uint8_t *outData) {
+  auto blob = connector_->GetEdidBlob();
+
+  if (!blob) {
+    ALOGE("Failed to get edid property value.");
+    return HWC2::Error::Unsupported;
+  }
+
+  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 HwcDisplay::GetDisplayCapabilities(uint32_t *outNumCapabilities,
+                                               uint32_t * /*outCapabilities*/) {
+  if (outNumCapabilities == nullptr) {
+    return HWC2::Error::BadParameter;
+  }
+
+  *outNumCapabilities = 0;
+
+  return HWC2::Error::None;
+}
+
+HWC2::Error HwcDisplay::GetDisplayBrightnessSupport(bool *supported) {
+  *supported = false;
+  return HWC2::Error::None;
+}
+
+HWC2::Error HwcDisplay::SetDisplayBrightness(float /* brightness */) {
+  return HWC2::Error::Unsupported;
+}
+
+#endif /* PLATFORM_SDK_VERSION > 28 */
+
+#if PLATFORM_SDK_VERSION > 27
+
+HWC2::Error 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 HwcDisplay::SetColorModeWithIntent(int32_t mode, int32_t intent) {
+  if (intent < HAL_RENDER_INTENT_COLORIMETRIC ||
+      intent > HAL_RENDER_INTENT_TONE_MAP_ENHANCE)
+    return HWC2::Error::BadParameter;
+
+  if (mode < HAL_COLOR_MODE_NATIVE || mode > HAL_COLOR_MODE_BT2100_HLG)
+    return HWC2::Error::BadParameter;
+
+  if (mode != HAL_COLOR_MODE_NATIVE)
+    return HWC2::Error::Unsupported;
+
+  if (intent != HAL_RENDER_INTENT_COLORIMETRIC)
+    return HWC2::Error::Unsupported;
+
+  color_mode_ = mode;
+  return HWC2::Error::None;
+}
+
+#endif /* PLATFORM_SDK_VERSION > 27 */
+
+const Backend *HwcDisplay::backend() const {
+  return backend_.get();
+}
+
+void HwcDisplay::set_backend(std::unique_ptr<Backend> backend) {
+  backend_ = std::move(backend);
+}
+
+}  // namespace android
diff --git a/hwc2_device/HwcDisplay.h b/hwc2_device/HwcDisplay.h
new file mode 100644
index 0000000..f69ff18
--- /dev/null
+++ b/hwc2_device/HwcDisplay.h
@@ -0,0 +1,265 @@
+/*
+ * Copyright (C) 2022 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_HWC2_DEVICE_HWC_DISPLAY_H
+#define ANDROID_HWC2_DEVICE_HWC_DISPLAY_H
+
+#include <hardware/hwcomposer2.h>
+
+#include <optional>
+
+#include "compositor/DrmDisplayCompositor.h"
+#include "drm/ResourceManager.h"
+#include "drm/VSyncWorker.h"
+#include "drmhwcomposer.h"
+#include "hwc2_device/HwcLayer.h"
+
+namespace android {
+
+class Backend;
+class DrmHwcTwo;
+
+class HwcDisplay {
+ public:
+  HwcDisplay(ResourceManager *resource_manager, DrmDevice *drm,
+             hwc2_display_t handle, HWC2::DisplayType type, DrmHwcTwo *hwc2);
+  HwcDisplay(const HwcDisplay &) = delete;
+  HWC2::Error Init(std::vector<DrmPlane *> *planes);
+
+  HWC2::Error CreateComposition(AtomicCommitArgs &a_args);
+  std::vector<HwcLayer *> GetOrderLayersByZPos();
+
+  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) const;
+  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
+#if PLATFORM_SDK_VERSION > 29
+  HWC2::Error GetDisplayConnectionType(uint32_t *outType);
+  HWC2::Error GetDisplayVsyncPeriod(hwc2_vsync_period_t *outVsyncPeriod);
+
+  HWC2::Error SetActiveConfigWithConstraints(
+      hwc2_config_t config,
+      hwc_vsync_period_change_constraints_t *vsyncPeriodChangeConstraints,
+      hwc_vsync_period_change_timeline_t *outTimeline);
+  HWC2::Error SetAutoLowLatencyMode(bool on);
+  HWC2::Error GetSupportedContentTypes(
+      uint32_t *outNumSupportedContentTypes,
+      const uint32_t *outSupportedContentTypes);
+
+  HWC2::Error SetContentType(int32_t contentType);
+#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) const {
+      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;
+  };
+
+  struct HwcDisplayConfig {
+    int id{};
+    int group_id{};
+    DrmMode mode;
+    bool disabled{};
+
+    bool IsInterlaced() const {
+      return (mode.flags() & DRM_MODE_FLAG_INTERLACE) != 0;
+    }
+  };
+
+  std::map<int /*config_id*/, struct HwcDisplayConfig> hwc_configs_;
+
+  int active_config_id_ = 0;
+  int preferred_config_id_ = 0;
+
+  const Backend *backend() const;
+  void set_backend(std::unique_ptr<Backend> 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_;
+  }
+
+  ResourceManager *resource_manager() const {
+    return resource_manager_;
+  }
+
+  android_color_transform_t &color_transform_hint() {
+    return color_transform_hint_;
+  }
+
+  Stats &total_stats() {
+    return total_stats_;
+  }
+
+  /* returns true if composition should be sent to client */
+  bool ProcessClientFlatteningState(bool skip) {
+    int flattenning_state = flattenning_state_;
+    if (flattenning_state == ClientFlattenningState::Disabled) {
+      return false;
+    }
+
+    if (skip) {
+      flattenning_state_ = ClientFlattenningState::NotRequired;
+      return false;
+    }
+
+    if (flattenning_state == ClientFlattenningState::ClientRefreshRequested) {
+      flattenning_state_ = ClientFlattenningState::Flattened;
+      return true;
+    }
+
+    flattening_vsync_worker_.VSyncControl(true);
+    flattenning_state_ = ClientFlattenningState::VsyncCountdownMax;
+    return false;
+  }
+
+ private:
+  enum ClientFlattenningState : int32_t {
+    Disabled = -3,
+    NotRequired = -2,
+    Flattened = -1,
+    ClientRefreshRequested = 0,
+    VsyncCountdownMax = 60, /* 1 sec @ 60FPS */
+  };
+
+  std::atomic_int flattenning_state_{ClientFlattenningState::NotRequired};
+  VSyncWorker flattening_vsync_worker_;
+
+  constexpr static size_t MATRIX_SIZE = 16;
+
+  DrmHwcTwo *hwc2_;
+
+  std::optional<DrmMode> staged_mode;
+
+  ResourceManager *resource_manager_;
+  DrmDevice *drm_;
+  DrmDisplayCompositor compositor_;
+
+  std::vector<DrmPlane *> primary_planes_;
+  std::vector<DrmPlane *> overlay_planes_;
+
+  std::unique_ptr<Backend> backend_;
+
+  VSyncWorker vsync_worker_;
+  DrmConnector *connector_ = nullptr;
+  DrmCrtc *crtc_ = nullptr;
+  hwc2_display_t handle_;
+  HWC2::DisplayType type_;
+  uint32_t layer_idx_ = 0;
+  std::map<hwc2_layer_t, HwcLayer> layers_;
+  HwcLayer client_layer_;
+  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(HwcDisplay::Stats delta);
+};
+
+}  // namespace android
+
+#endif
diff --git a/hwc2_device/hwc2_device.cpp b/hwc2_device/hwc2_device.cpp
index 72074ad..22e4589 100644
--- a/hwc2_device/hwc2_device.cpp
+++ b/hwc2_device/hwc2_device.cpp
@@ -47,8 +47,7 @@
 template <typename HookType, HookType func, typename... Args>
 static int32_t DisplayHook(hwc2_device_t *dev, hwc2_display_t display_handle,
                            Args... args) {
-  DrmHwcTwo::HwcDisplay *display = DrmHwcTwo::GetDisplay(ToDrmHwcTwo(dev),
-                                                         display_handle);
+  HwcDisplay *display = DrmHwcTwo::GetDisplay(ToDrmHwcTwo(dev), display_handle);
   if (!display)
     return static_cast<int32_t>(HWC2::Error::BadDisplay);
 
@@ -58,8 +57,7 @@
 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) {
-  DrmHwcTwo::HwcDisplay *display = DrmHwcTwo::GetDisplay(ToDrmHwcTwo(dev),
-                                                         display_handle);
+  HwcDisplay *display = DrmHwcTwo::GetDisplay(ToDrmHwcTwo(dev), display_handle);
   if (!display)
     return static_cast<int32_t>(HWC2::Error::BadDisplay);
 
@@ -113,181 +111,168 @@
     // Display functions
     case HWC2::FunctionDescriptor::AcceptDisplayChanges:
       return ToHook<HWC2_PFN_ACCEPT_DISPLAY_CHANGES>(
-          DisplayHook<decltype(&DrmHwcTwo::HwcDisplay::AcceptDisplayChanges),
-                      &DrmHwcTwo::HwcDisplay::AcceptDisplayChanges>);
+          DisplayHook<decltype(&HwcDisplay::AcceptDisplayChanges),
+                      &HwcDisplay::AcceptDisplayChanges>);
     case HWC2::FunctionDescriptor::CreateLayer:
       return ToHook<HWC2_PFN_CREATE_LAYER>(
-          DisplayHook<decltype(&DrmHwcTwo::HwcDisplay::CreateLayer),
-                      &DrmHwcTwo::HwcDisplay::CreateLayer, hwc2_layer_t *>);
+          DisplayHook<decltype(&HwcDisplay::CreateLayer),
+                      &HwcDisplay::CreateLayer, hwc2_layer_t *>);
     case HWC2::FunctionDescriptor::DestroyLayer:
       return ToHook<HWC2_PFN_DESTROY_LAYER>(
-          DisplayHook<decltype(&DrmHwcTwo::HwcDisplay::DestroyLayer),
-                      &DrmHwcTwo::HwcDisplay::DestroyLayer, hwc2_layer_t>);
+          DisplayHook<decltype(&HwcDisplay::DestroyLayer),
+                      &HwcDisplay::DestroyLayer, hwc2_layer_t>);
     case HWC2::FunctionDescriptor::GetActiveConfig:
       return ToHook<HWC2_PFN_GET_ACTIVE_CONFIG>(
-          DisplayHook<decltype(&DrmHwcTwo::HwcDisplay::GetActiveConfig),
-                      &DrmHwcTwo::HwcDisplay::GetActiveConfig,
-                      hwc2_config_t *>);
+          DisplayHook<decltype(&HwcDisplay::GetActiveConfig),
+                      &HwcDisplay::GetActiveConfig, hwc2_config_t *>);
     case HWC2::FunctionDescriptor::GetChangedCompositionTypes:
       return ToHook<HWC2_PFN_GET_CHANGED_COMPOSITION_TYPES>(
-          DisplayHook<
-              decltype(&DrmHwcTwo::HwcDisplay::GetChangedCompositionTypes),
-              &DrmHwcTwo::HwcDisplay::GetChangedCompositionTypes, uint32_t *,
-              hwc2_layer_t *, int32_t *>);
+          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(&DrmHwcTwo::HwcDisplay::GetClientTargetSupport),
-                      &DrmHwcTwo::HwcDisplay::GetClientTargetSupport, uint32_t,
-                      uint32_t, int32_t, int32_t>);
+          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(&DrmHwcTwo::HwcDisplay::GetColorModes),
-                      &DrmHwcTwo::HwcDisplay::GetColorModes, uint32_t *,
-                      int32_t *>);
+          DisplayHook<decltype(&HwcDisplay::GetColorModes),
+                      &HwcDisplay::GetColorModes, uint32_t *, int32_t *>);
     case HWC2::FunctionDescriptor::GetDisplayAttribute:
       return ToHook<HWC2_PFN_GET_DISPLAY_ATTRIBUTE>(
-          DisplayHook<decltype(&DrmHwcTwo::HwcDisplay::GetDisplayAttribute),
-                      &DrmHwcTwo::HwcDisplay::GetDisplayAttribute,
-                      hwc2_config_t, int32_t, int32_t *>);
+          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(&DrmHwcTwo::HwcDisplay::GetDisplayConfigs),
-                      &DrmHwcTwo::HwcDisplay::GetDisplayConfigs, uint32_t *,
+          DisplayHook<decltype(&HwcDisplay::GetDisplayConfigs),
+                      &HwcDisplay::GetDisplayConfigs, uint32_t *,
                       hwc2_config_t *>);
     case HWC2::FunctionDescriptor::GetDisplayName:
       return ToHook<HWC2_PFN_GET_DISPLAY_NAME>(
-          DisplayHook<decltype(&DrmHwcTwo::HwcDisplay::GetDisplayName),
-                      &DrmHwcTwo::HwcDisplay::GetDisplayName, uint32_t *,
-                      char *>);
+          DisplayHook<decltype(&HwcDisplay::GetDisplayName),
+                      &HwcDisplay::GetDisplayName, uint32_t *, char *>);
     case HWC2::FunctionDescriptor::GetDisplayRequests:
       return ToHook<HWC2_PFN_GET_DISPLAY_REQUESTS>(
-          DisplayHook<decltype(&DrmHwcTwo::HwcDisplay::GetDisplayRequests),
-                      &DrmHwcTwo::HwcDisplay::GetDisplayRequests, int32_t *,
-                      uint32_t *, hwc2_layer_t *, int32_t *>);
+          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(&DrmHwcTwo::HwcDisplay::GetDisplayType),
-                      &DrmHwcTwo::HwcDisplay::GetDisplayType, int32_t *>);
+          DisplayHook<decltype(&HwcDisplay::GetDisplayType),
+                      &HwcDisplay::GetDisplayType, int32_t *>);
     case HWC2::FunctionDescriptor::GetDozeSupport:
       return ToHook<HWC2_PFN_GET_DOZE_SUPPORT>(
-          DisplayHook<decltype(&DrmHwcTwo::HwcDisplay::GetDozeSupport),
-                      &DrmHwcTwo::HwcDisplay::GetDozeSupport, int32_t *>);
+          DisplayHook<decltype(&HwcDisplay::GetDozeSupport),
+                      &HwcDisplay::GetDozeSupport, int32_t *>);
     case HWC2::FunctionDescriptor::GetHdrCapabilities:
       return ToHook<HWC2_PFN_GET_HDR_CAPABILITIES>(
-          DisplayHook<decltype(&DrmHwcTwo::HwcDisplay::GetHdrCapabilities),
-                      &DrmHwcTwo::HwcDisplay::GetHdrCapabilities, uint32_t *,
-                      int32_t *, float *, float *, float *>);
+          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(&DrmHwcTwo::HwcDisplay::GetReleaseFences),
-                      &DrmHwcTwo::HwcDisplay::GetReleaseFences, uint32_t *,
-                      hwc2_layer_t *, int32_t *>);
+          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(&DrmHwcTwo::HwcDisplay::PresentDisplay),
-                      &DrmHwcTwo::HwcDisplay::PresentDisplay, int32_t *>);
+          DisplayHook<decltype(&HwcDisplay::PresentDisplay),
+                      &HwcDisplay::PresentDisplay, int32_t *>);
     case HWC2::FunctionDescriptor::SetActiveConfig:
       return ToHook<HWC2_PFN_SET_ACTIVE_CONFIG>(
-          DisplayHook<decltype(&DrmHwcTwo::HwcDisplay::SetActiveConfig),
-                      &DrmHwcTwo::HwcDisplay::SetActiveConfig, hwc2_config_t>);
+          DisplayHook<decltype(&HwcDisplay::SetActiveConfig),
+                      &HwcDisplay::SetActiveConfig, hwc2_config_t>);
     case HWC2::FunctionDescriptor::SetClientTarget:
       return ToHook<HWC2_PFN_SET_CLIENT_TARGET>(
-          DisplayHook<decltype(&DrmHwcTwo::HwcDisplay::SetClientTarget),
-                      &DrmHwcTwo::HwcDisplay::SetClientTarget, buffer_handle_t,
-                      int32_t, int32_t, hwc_region_t>);
+          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(&DrmHwcTwo::HwcDisplay::SetColorMode),
-                      &DrmHwcTwo::HwcDisplay::SetColorMode, int32_t>);
+          DisplayHook<decltype(&HwcDisplay::SetColorMode),
+                      &HwcDisplay::SetColorMode, int32_t>);
     case HWC2::FunctionDescriptor::SetColorTransform:
       return ToHook<HWC2_PFN_SET_COLOR_TRANSFORM>(
-          DisplayHook<decltype(&DrmHwcTwo::HwcDisplay::SetColorTransform),
-                      &DrmHwcTwo::HwcDisplay::SetColorTransform, const float *,
-                      int32_t>);
+          DisplayHook<decltype(&HwcDisplay::SetColorTransform),
+                      &HwcDisplay::SetColorTransform, const float *, int32_t>);
     case HWC2::FunctionDescriptor::SetOutputBuffer:
       return ToHook<HWC2_PFN_SET_OUTPUT_BUFFER>(
-          DisplayHook<decltype(&DrmHwcTwo::HwcDisplay::SetOutputBuffer),
-                      &DrmHwcTwo::HwcDisplay::SetOutputBuffer, buffer_handle_t,
-                      int32_t>);
+          DisplayHook<decltype(&HwcDisplay::SetOutputBuffer),
+                      &HwcDisplay::SetOutputBuffer, buffer_handle_t, int32_t>);
     case HWC2::FunctionDescriptor::SetPowerMode:
       return ToHook<HWC2_PFN_SET_POWER_MODE>(
-          DisplayHook<decltype(&DrmHwcTwo::HwcDisplay::SetPowerMode),
-                      &DrmHwcTwo::HwcDisplay::SetPowerMode, int32_t>);
+          DisplayHook<decltype(&HwcDisplay::SetPowerMode),
+                      &HwcDisplay::SetPowerMode, int32_t>);
     case HWC2::FunctionDescriptor::SetVsyncEnabled:
       return ToHook<HWC2_PFN_SET_VSYNC_ENABLED>(
-          DisplayHook<decltype(&DrmHwcTwo::HwcDisplay::SetVsyncEnabled),
-                      &DrmHwcTwo::HwcDisplay::SetVsyncEnabled, int32_t>);
+          DisplayHook<decltype(&HwcDisplay::SetVsyncEnabled),
+                      &HwcDisplay::SetVsyncEnabled, int32_t>);
     case HWC2::FunctionDescriptor::ValidateDisplay:
       return ToHook<HWC2_PFN_VALIDATE_DISPLAY>(
-          DisplayHook<decltype(&DrmHwcTwo::HwcDisplay::ValidateDisplay),
-                      &DrmHwcTwo::HwcDisplay::ValidateDisplay, uint32_t *,
-                      uint32_t *>);
+          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(&DrmHwcTwo::HwcDisplay::GetRenderIntents),
-                      &DrmHwcTwo::HwcDisplay::GetRenderIntents, int32_t,
-                      uint32_t *, int32_t *>);
+          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(&DrmHwcTwo::HwcDisplay::SetColorModeWithIntent),
-                      &DrmHwcTwo::HwcDisplay::SetColorModeWithIntent, int32_t,
-                      int32_t>);
+          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(&DrmHwcTwo::HwcDisplay::GetDisplayIdentificationData),
-              &DrmHwcTwo::HwcDisplay::GetDisplayIdentificationData, uint8_t *,
-              uint32_t *, uint8_t *>);
+          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(&DrmHwcTwo::HwcDisplay::GetDisplayCapabilities),
-                      &DrmHwcTwo::HwcDisplay::GetDisplayCapabilities,
-                      uint32_t *, uint32_t *>);
+          DisplayHook<decltype(&HwcDisplay::GetDisplayCapabilities),
+                      &HwcDisplay::GetDisplayCapabilities, uint32_t *,
+                      uint32_t *>);
     case HWC2::FunctionDescriptor::GetDisplayBrightnessSupport:
       return ToHook<HWC2_PFN_GET_DISPLAY_BRIGHTNESS_SUPPORT>(
-          DisplayHook<
-              decltype(&DrmHwcTwo::HwcDisplay::GetDisplayBrightnessSupport),
-              &DrmHwcTwo::HwcDisplay::GetDisplayBrightnessSupport, bool *>);
+          DisplayHook<decltype(&HwcDisplay::GetDisplayBrightnessSupport),
+                      &HwcDisplay::GetDisplayBrightnessSupport, bool *>);
     case HWC2::FunctionDescriptor::SetDisplayBrightness:
       return ToHook<HWC2_PFN_SET_DISPLAY_BRIGHTNESS>(
-          DisplayHook<decltype(&DrmHwcTwo::HwcDisplay::SetDisplayBrightness),
-                      &DrmHwcTwo::HwcDisplay::SetDisplayBrightness, float>);
+          DisplayHook<decltype(&HwcDisplay::SetDisplayBrightness),
+                      &HwcDisplay::SetDisplayBrightness, float>);
 #endif /* PLATFORM_SDK_VERSION > 28 */
 #if PLATFORM_SDK_VERSION > 29
     case HWC2::FunctionDescriptor::GetDisplayConnectionType:
       return ToHook<HWC2_PFN_GET_DISPLAY_CONNECTION_TYPE>(
-          DisplayHook<
-              decltype(&DrmHwcTwo::HwcDisplay::GetDisplayConnectionType),
-              &DrmHwcTwo::HwcDisplay::GetDisplayConnectionType, uint32_t *>);
+          DisplayHook<decltype(&HwcDisplay::GetDisplayConnectionType),
+                      &HwcDisplay::GetDisplayConnectionType, uint32_t *>);
     case HWC2::FunctionDescriptor::GetDisplayVsyncPeriod:
       return ToHook<HWC2_PFN_GET_DISPLAY_VSYNC_PERIOD>(
-          DisplayHook<decltype(&DrmHwcTwo::HwcDisplay::GetDisplayVsyncPeriod),
-                      &DrmHwcTwo::HwcDisplay::GetDisplayVsyncPeriod,
+          DisplayHook<decltype(&HwcDisplay::GetDisplayVsyncPeriod),
+                      &HwcDisplay::GetDisplayVsyncPeriod,
                       hwc2_vsync_period_t *>);
     case HWC2::FunctionDescriptor::SetActiveConfigWithConstraints:
       return ToHook<HWC2_PFN_SET_ACTIVE_CONFIG_WITH_CONSTRAINTS>(
-          DisplayHook<
-              decltype(&DrmHwcTwo::HwcDisplay::SetActiveConfigWithConstraints),
-              &DrmHwcTwo::HwcDisplay::SetActiveConfigWithConstraints,
-              hwc2_config_t, hwc_vsync_period_change_constraints_t *,
-              hwc_vsync_period_change_timeline_t *>);
+          DisplayHook<decltype(&HwcDisplay::SetActiveConfigWithConstraints),
+                      &HwcDisplay::SetActiveConfigWithConstraints,
+                      hwc2_config_t, hwc_vsync_period_change_constraints_t *,
+                      hwc_vsync_period_change_timeline_t *>);
     case HWC2::FunctionDescriptor::SetAutoLowLatencyMode:
       return ToHook<HWC2_PFN_SET_AUTO_LOW_LATENCY_MODE>(
-          DisplayHook<decltype(&DrmHwcTwo::HwcDisplay::SetAutoLowLatencyMode),
-                      &DrmHwcTwo::HwcDisplay::SetAutoLowLatencyMode, bool>);
+          DisplayHook<decltype(&HwcDisplay::SetAutoLowLatencyMode),
+                      &HwcDisplay::SetAutoLowLatencyMode, bool>);
     case HWC2::FunctionDescriptor::GetSupportedContentTypes:
       return ToHook<HWC2_PFN_GET_SUPPORTED_CONTENT_TYPES>(
-          DisplayHook<
-              decltype(&DrmHwcTwo::HwcDisplay::GetSupportedContentTypes),
-              &DrmHwcTwo::HwcDisplay::GetSupportedContentTypes, uint32_t *,
-              uint32_t *>);
+          DisplayHook<decltype(&HwcDisplay::GetSupportedContentTypes),
+                      &HwcDisplay::GetSupportedContentTypes, uint32_t *,
+                      uint32_t *>);
     case HWC2::FunctionDescriptor::SetContentType:
       return ToHook<HWC2_PFN_SET_CONTENT_TYPE>(
-          DisplayHook<decltype(&DrmHwcTwo::HwcDisplay::SetContentType),
-                      &DrmHwcTwo::HwcDisplay::SetContentType, int32_t>);
+          DisplayHook<decltype(&HwcDisplay::SetContentType),
+                      &HwcDisplay::SetContentType, int32_t>);
 #endif
     // Layer functions
     case HWC2::FunctionDescriptor::SetCursorPosition:
