Empty merge of sc-v2-dev-plus-aosp-without-vendor@8084891

Bug: 214455710
Merged-In: I95601c680ca1af0dc9d3b3f102f79f77af081b75
Change-Id: I96baa183ce57edeab2e627dbe9bfe061db37eb77
diff --git a/.ci/.common.sh b/.ci/.common.sh
deleted file mode 100644
index 48cc594..0000000
--- a/.ci/.common.sh
+++ /dev/null
@@ -1,42 +0,0 @@
-INCLUDE_DIRS="-I. -I../libdrm/include/drm -Iinclude -I/usr/include/libdrm -I./.ci/android_headers -I./tests/test_include"
-
-CLANG="clang++-12"
-CLANG_TIDY="clang-tidy-12"
-
-CXXARGS="-fPIC -Wall -Werror -DPLATFORM_SDK_VERSION=30 -D__ANDROID_API__=30 -Wsign-promo -Wimplicit-fallthrough"
-CXXARGS+=" -D_LIBCPP_ENABLE_THREAD_SAFETY_ANNOTATIONS -Wno-gnu-include-next -Wsign-compare"
-CXXARGS+=" -fvisibility-inlines-hidden -std=gnu++17 -DHWC2_USE_CPP11 -DHWC2_INCLUDE_STRINGIFICATION -fno-rtti"
-
-BUILD_FILES=(
-backend/BackendClient.cpp
-backend/Backend.cpp
-backend/BackendManager.cpp
-backend/BackendRCarDu.cpp
-bufferinfo/BufferInfoGetter.cpp
-#bufferinfo/BufferInfoMapperMetadata.cpp
-bufferinfo/legacy/BufferInfoImagination.cpp
-bufferinfo/legacy/BufferInfoLibdrm.cpp
-bufferinfo/legacy/BufferInfoMaliHisi.cpp
-bufferinfo/legacy/BufferInfoMaliMediatek.cpp
-bufferinfo/legacy/BufferInfoMaliMeson.cpp
-bufferinfo/legacy/BufferInfoMinigbm.cpp
-compositor/DrmDisplayComposition.cpp
-compositor/DrmDisplayCompositor.cpp
-compositor/Planner.cpp
-drm/DrmConnector.cpp
-drm/DrmCrtc.cpp
-drm/DrmDevice.cpp
-drm/DrmEncoder.cpp
-drm/DrmFbImporter.cpp
-drm/DrmMode.cpp
-drm/DrmPlane.cpp
-drm/DrmProperty.cpp
-DrmHwcTwo.cpp
-drm/ResourceManager.cpp
-drm/UEventListener.cpp
-drm/VSyncWorker.cpp
-tests/worker_test.cpp
-utils/autolock.cpp
-#utils/hwcutils.cpp
-utils/Worker.cpp
-)
diff --git a/.ci/.gitlab-ci-checkcommit.sh b/.ci/.gitlab-ci-checkcommit.sh
index 817afa7..c9c2e49 100755
--- a/.ci/.gitlab-ci-checkcommit.sh
+++ b/.ci/.gitlab-ci-checkcommit.sh
@@ -50,7 +50,7 @@
 		exit 1
 	fi
 
-	git show "$h" -- | clang-format-diff-11 -p 1 -style=file > /tmp/format-fixup.patch
+	git show "$h" -- | clang-format-diff-13 -p 1 -style=file > /tmp/format-fixup.patch
 	if [ -s  /tmp/format-fixup.patch ]; then
 		cat /tmp/format-fixup.patch >&2
 		exit 1
diff --git a/.ci/.gitlab-ci-clang-build.sh b/.ci/.gitlab-ci-clang-build.sh
deleted file mode 100755
index 1070365..0000000
--- a/.ci/.gitlab-ci-clang-build.sh
+++ /dev/null
@@ -1,11 +0,0 @@
-#!/bin/bash
-
-. ./.ci/.common.sh
-
-set -xe
-
-for source in "${BUILD_FILES[@]}"
-do
-    filename=$(basename -- "$source")
-    $CLANG $source $INCLUDE_DIRS $CXXARGS -c -o /tmp/"${filename%.*}.o"
-done
diff --git a/.ci/.gitlab-ci-clang-tidy-coarse.sh b/.ci/.gitlab-ci-clang-tidy-coarse.sh
deleted file mode 100755
index a3afeb9..0000000
--- a/.ci/.gitlab-ci-clang-tidy-coarse.sh
+++ /dev/null
@@ -1,42 +0,0 @@
-#!/bin/bash
-
-. ./.ci/.common.sh
-
-TIDY_COARSE_CHECKS="-*,android-*,bugprone-*,cert-*,clang-analyzer-*,"
-TIDY_COARSE_CHECKS+="cppcoreguidelines-*,"
-TIDY_COARSE_CHECKS+="-cppcoreguidelines-pro-bounds-array-to-pointer-decay,"
-TIDY_COARSE_CHECKS+="-cppcoreguidelines-pro-bounds-constant-array-index,"
-TIDY_COARSE_CHECKS+="-cppcoreguidelines-pro-bounds-pointer-arithmetic,"
-TIDY_COARSE_CHECKS+="-cppcoreguidelines-pro-type-cstyle-cast,"
-TIDY_COARSE_CHECKS+="-cppcoreguidelines-pro-type-union-access,"
-TIDY_COARSE_CHECKS+="-cppcoreguidelines-pro-type-vararg,"
-TIDY_COARSE_CHECKS+="-cppcoreguidelines-avoid-magic-numbers,"
-TIDY_COARSE_CHECKS+="-cppcoreguidelines-macro-usage,"
-TIDY_COARSE_CHECKS+="-cppcoreguidelines-avoid-c-arrays,"
-TIDY_COARSE_CHECKS+="google-*,"
-TIDY_COARSE_CHECKS+="-google-readability-braces-around-statements,"
-TIDY_COARSE_CHECKS+="-google-readability-casting,"
-TIDY_COARSE_CHECKS+="misc-*,"
-TIDY_COARSE_CHECKS+="-misc-non-private-member-variables-in-classes",
-TIDY_COARSE_CHECKS+="modernize-*,"
-TIDY_COARSE_CHECKS+="-modernize-avoid-c-arrays,"
-TIDY_COARSE_CHECKS+="-modernize-use-trailing-return-type,"
-TIDY_COARSE_CHECKS+="performance-*,"
-TIDY_COARSE_CHECKS+="portability-*,"
-TIDY_COARSE_CHECKS+="readability-*,"
-TIDY_COARSE_CHECKS+="-readability-braces-around-statements,"
-TIDY_COARSE_CHECKS+="-readability-function-cognitive-complexity,"
-TIDY_COARSE_CHECKS+="-readability-convert-member-functions-to-static,"
-TIDY_COARSE_CHECKS+="-readability-implicit-bool-conversion,"
-TIDY_COARSE_CHECKS+="-readability-identifier-naming,"
-TIDY_COARSE_CHECKS+="-readability-magic-numbers,"
-TIDY_COARSE_CHECKS+="-readability-use-anyofallof"
-
-TIDY_FILES=( "${BUILD_FILES[@]}" )
-
-set -xe
-
-for source in "${TIDY_FILES[@]}"
-do
-    $CLANG_TIDY $source --checks=$TIDY_COARSE_CHECKS -- -x c++ $INCLUDE_DIRS $CXXARGS
-done
diff --git a/.ci/.gitlab-ci-clang-tidy-fine.sh b/.ci/.gitlab-ci-clang-tidy-fine.sh
deleted file mode 100755
index 0e3e35b..0000000
--- a/.ci/.gitlab-ci-clang-tidy-fine.sh
+++ /dev/null
@@ -1,18 +0,0 @@
-#!/bin/bash
-
-. ./.ci/.common.sh
-
-TIDY_FILES=(
-drm/DrmFbImporter.h
-drm/DrmUnique.h
-utils/UniqueFd.h
-utils/log.h
-utils/properties.h
-)
-
-set -xe
-
-for source in "${TIDY_FILES[@]}"
-do
-    $CLANG_TIDY $source -- -x c++ $INCLUDE_DIRS $CXXARGS
-done
diff --git a/.ci/Makefile b/.ci/Makefile
new file mode 100644
index 0000000..7f43a8a
--- /dev/null
+++ b/.ci/Makefile
@@ -0,0 +1,168 @@
+
+INCLUDE_DIRS := . ../libdrm/include/drm include ./.ci/android_headers ./tests/test_include
+SYSTEM_INCLUDE_DIRS := /usr/include/libdrm
+
+CLANG := clang++-13
+CLANG_TIDY := clang-tidy-13
+OUT_DIR := /tmp/drm_hwcomposer/build
+SRC_DIR := .
+
+CXXFLAGS := -fPIC -Wall -Wextra -Werror -DPLATFORM_SDK_VERSION=31 -D__ANDROID_API__=31
+CXXFLAGS += -D_LIBCPP_ENABLE_THREAD_SAFETY_ANNOTATIONS
+CXXFLAGS += -fvisibility-inlines-hidden -std=gnu++17 -DHWC2_USE_CPP11 -DHWC2_INCLUDE_STRINGIFICATION -fno-rtti
+
+SKIP_FILES := \
+    bufferinfo/BufferInfoMapperMetadata.cpp
+
+TIDY_FILES_OVERRIDE := \
+    bufferinfo/legacy/BufferInfoImagination.cpp:COARSE  \
+    bufferinfo/legacy/BufferInfoLibdrm.cpp:COARSE       \
+    bufferinfo/legacy/BufferInfoMaliHisi.cpp:COARSE     \
+    bufferinfo/legacy/BufferInfoMaliMediatek.cpp:COARSE \
+    bufferinfo/legacy/BufferInfoMaliMeson.cpp:COARSE    \
+    bufferinfo/legacy/BufferInfoMinigbm.cpp:COARSE      \
+    compositor/DrmDisplayComposition.cpp:COARSE         \
+    compositor/DrmDisplayComposition.h:COARSE           \
+    compositor/DrmDisplayCompositor.cpp:COARSE          \
+    drm/DrmFbImporter.h:FINE                            \
+    drm/DrmMode.h:COARSE                                \
+    drm/DrmDevice.h:COARSE                              \
+    drm/DrmProperty.h:COARSE                            \
+    drm/DrmConnector.h:COARSE                           \
+    drm/DrmCrtc.h:COARSE                                \
+    drm/DrmUnique.h:FINE                                \
+    drm/DrmEncoder.h:COARSE                             \
+    drm/DrmConnector.cpp:COARSE                         \
+    drm/DrmDevice.cpp:COARSE                            \
+    drm/DrmProperty.cpp:COARSE                          \
+    drm/UEventListener.cpp:COARSE                       \
+    drm/VSyncWorker.cpp:COARSE                          \
+    hwc2_device/DrmHwcTwo.cpp:COARSE                    \
+    hwc2_device/DrmHwcTwo.h:COARSE                      \
+    hwc2_device/HwcDisplay.cpp:COARSE                   \
+    hwc2_device/HwcDisplay.h:COARSE                     \
+    tests/worker_test.cpp:COARSE                        \
+    utils/Worker.h:COARSE                               \
+    utils/UniqueFd.h:FINE                               \
+    utils/log.h:FINE                                    \
+    utils/properties.h:FINE                             \
+
+TIDY_CHECKS_FINE := *                                   \
+    -llvmlibc* -fuchsia-* -altera-*                     \
+    -llvm-header-guard                                  \
+    -cppcoreguidelines-pro-type-vararg                  \
+    -hicpp-vararg                                       \
+    -hicpp-signed-bitwise                               \
+
+TIDY_CHECKS_NORMAL :=                                   \
+    $(TIDY_CHECKS_FINE)                                 \
+    -hicpp*                                             \
+    -bugprone-easily-swappable-parameters               \
+    -cppcoreguidelines-special-member-functions \
+    -cppcoreguidelines-avoid-c-arrays \
+    -cppcoreguidelines-pro-bounds-array-to-pointer-decay \
+    -cppcoreguidelines-pro-bounds-constant-array-index \
+    -cppcoreguidelines-avoid-magic-numbers \
+    -google-readability-braces-around-statements \
+    -google-readability-casting \
+    -misc-non-private-member-variables-in-classes \
+    -modernize-avoid-c-arrays \
+    -modernize-use-nodiscard \
+    -modernize-use-trailing-return-type \
+    -readability-braces-around-statements \
+
+TIDY_CHECKS_COARSE := \
+    $(TIDY_CHECKS_NORMAL) \
+    -cppcoreguidelines-non-private-member-variables-in-classes \
+    -cppcoreguidelines-pro-bounds-pointer-arithmetic \
+    -cppcoreguidelines-pro-type-cstyle-cast \
+    -cppcoreguidelines-pro-type-reinterpret-cast \
+    -cppcoreguidelines-pro-type-static-cast-downcast \
+    -cppcoreguidelines-pro-type-union-access \
+    -cppcoreguidelines-macro-usage \
+    -readability-convert-member-functions-to-static \
+    -readability-implicit-bool-conversion \
+    -readability-identifier-naming \
+    -readability-magic-numbers \
+
+.PHONY: all build tidy clean
+
+all: build tidy
+
+clean:
+	rm -rf $(OUT_DIR)/
+
+# Build
+
+BUILD_FILES_AUTO := $(shell find -L $(SRC_DIR) -not -path '*/\.*' -not -path '*/tests/*' -path '*.cpp')
+SKIP_FILES_path := $(foreach file,$(SKIP_FILES),$(SRC_DIR)/$(file))
+
+BUILD_FILES := $(subst ./,,$(filter-out $(SKIP_FILES_path),$(BUILD_FILES_AUTO)))
+
+_OBJ := $(BUILD_FILES:.cpp=.o)
+OBJ  := $(patsubst %,$(OUT_DIR)/%,$(_OBJ))
+
+DEPS := $(patsubst %.cpp,$(OUT_DIR)/%.d,$(BUILD_FILES))
+
+build: $(OBJ)
+
+CXXARGS := $(foreach dir,$(INCLUDE_DIRS),-I$(SRC_DIR)/$(dir)) $(foreach dir,$(SYSTEM_INCLUDE_DIRS),-I$(dir)) $(CXXFLAGS)
+
+$(OUT_DIR)/%.o: $(SRC_DIR)/%.cpp
+	mkdir -p $(dir $@)
+	$(CLANG) $< $(CXXARGS) -c -o $@
+
+$(OUT_DIR)/%.d: $(SRC_DIR)/%.cpp
+	mkdir -p $(dir $@)
+	$(CLANG) $(CXXARGS) $< -MM -MT $(OUT_DIR)/$(patsubst %.cpp,%.o,$<) -o $@
+
+# TIDY
+TIDY_FILES_AUTO := $(shell find -L $(SRC_DIR) -not -path '*/\.*' -not -path '*/tests/*' \( -path '*.cpp' -o -path '*.h' \))
+
+TIDY_FILES_AUTO_filtered := $(filter-out $(SKIP_FILES_path),$(TIDY_FILES_AUTO))
+
+TIDY_FILES_OVERRIDE_path := $(foreach pair,$(TIDY_FILES_OVERRIDE),$(SRC_DIR)/$(pair))
+
+TIDY_FILES_OVERRIDE_name_only := $(foreach pair,$(TIDY_FILES_OVERRIDE_path),$(word 1, $(subst :, ,$(pair))))
+
+TIDY_FILES := $(sort $(TIDY_FILES_AUTO_filtered) $(TIDY_FILES_OVERRIDE_name_only))
+
+space := $(subst ,, )
+comma := ,
+
+TIDY_ARGS_NONE := --checks="-*,llvm-include-order"
+TIDY_ARGS_     := --checks="-*,llvm-include-order"
+TIDY_ARGS_FINE := --checks="$(subst $(space),$(comma),$(strip $(TIDY_CHECKS_FINE)))"
+TIDY_ARGS_NORMAL := --checks="$(subst $(space),$(comma),$(strip $(TIDY_CHECKS_NORMAL)))"
+TIDY_ARGS_COARSE := --checks="$(subst $(space),$(comma),$(strip $(TIDY_CHECKS_COARSE)))"
+
+define process-tidy
+
+_TARG := $(OUT_DIR)/$1.tidy.ts
+_DEP := $(SRC_DIR)/$1
+
+TIDY_DEPS += $(_TARG)
+
+TIDY_LEVEL_1 := $$(strip $$(foreach pair,$$(TIDY_FILES_OVERRIDE_path),$$(if $$(filter $$(word 1, $$(subst :, ,$$(pair))),$1),$$(word 2, $$(subst :, ,$$(pair))),)))
+
+TIDY_LEVEL_2 := $$(if $$(TIDY_LEVEL_1),$$(TIDY_LEVEL_1),NORMAL)
+
+TIDY_ARGS := $$(TIDY_ARGS_$$(TIDY_LEVEL_2))
+
+$$(_TARG): _DEP := $$(_DEP)
+$$(_TARG): _TARG := $$(_TARG)
+$$(_TARG): TIDY_ARGS := $$(TIDY_ARGS)
+$$(_TARG): $$(_DEP)
+	mkdir -p $$(dir $$(_TARG))
+	$$(CLANG_TIDY) $$(_DEP) $$(TIDY_ARGS) -- -x c++ $$(CXXARGS)
+	touch $$(_TARG)
+
+endef
+
+$(foreach file,$(TIDY_FILES),$(eval $(call process-tidy,$(file))))
+
+tidy: $(TIDY_DEPS)
+
+ifneq ($(MAKECMDGOALS), clean)
+-include $(DEPS)
+endif
diff --git a/.clang-tidy b/.clang-tidy
index 221c030..3731a29 100644
--- a/.clang-tidy
+++ b/.clang-tidy
@@ -1,15 +1,3 @@
-# fuchsia: Conflicts with other checks
-# llvm-header-guard: Does not match drm_hwc header gusrd style 
-# Allow using ALOGE 
-
-Checks: >
-    *,
-    -fuchsia*,
-    -llvm*,
-    -concurrency-mt-unsafe,
-    -cppcoreguidelines-pro-type-vararg, -hicpp-vararg,
-    -hicpp-signed-bitwise,
-
 # Turn all the warnings from the checks above into errors.
 WarningsAsErrors: "*"
 
@@ -50,8 +38,10 @@
     value:           '^[A-Z]+(_[A-Z]+)*_$'
   - key:             readability-identifier-naming.MemberCase
     value:           lower_case
-  - key:             readability-identifier-naming.MemberSuffix
+  - key:             readability-identifier-naming.PrivateMemberSuffix
     value:           _
+  - key:             readability-identifier-naming.PublicMemberSuffix
+    value:           ''
   - key:             readability-identifier-naming.NamespaceCase
     value:           lower_case
   - key:             readability-identifier-naming.ParameterCase
@@ -64,3 +54,7 @@
     value:           lower_case
   - key:             readability-identifier-naming.IgnoreMainLikeFunctions
     value:           1
+  - key:             cppcoreguidelines-macro-usage.AllowedRegexp
+    value:           "LOG_TAG|ATRACE_TAG"
+  - key:             readability-magic-numbers.IgnoredFloatingPointValues
+    value:           '1000.0'
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 41d38ba..89ac1b8 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -1,11 +1,11 @@
-image: ubuntu:21.04
+image: ubuntu:21.10
 
 variables:
   DEBIAN_FRONTEND: noninteractive
 
 before_script:
   - apt-get --quiet update --yes >/dev/null
-  - apt-get --quiet install --yes clang-12 clang-tidy-12 clang-format-12 git libdrm-dev blueprint-tools libgtest-dev >/dev/null
+  - apt-get --quiet install --yes clang-13 clang-tidy-13 clang-format-13 git libdrm-dev blueprint-tools libgtest-dev make >/dev/null
 
 stages:
   - build
@@ -13,7 +13,8 @@
 
 build:
   stage: build
-  script: "./.ci/.gitlab-ci-clang-build.sh"
+  script:
+    - make -f .ci/Makefile
   artifacts:
     when: on_failure
     untracked: true
@@ -24,17 +25,3 @@
   artifacts:
     when: on_failure
     untracked: true
-
-tidy-coarse:
-  stage: style
-  script: "./.ci/.gitlab-ci-clang-tidy-coarse.sh"
-  artifacts:
-    when: on_failure
-    untracked: true
-
-tidy-fine:
-  stage: style
-  script: "./.ci/.gitlab-ci-clang-tidy-fine.sh"
-  artifacts:
-    when: on_failure
-    untracked: true
diff --git a/Android.bp b/Android.bp
index ae2f690..1c3030c 100644
--- a/Android.bp
+++ b/Android.bp
@@ -98,8 +98,6 @@
 filegroup {
     name: "drm_hwcomposer_common",
     srcs: [
-        "DrmHwcTwo.cpp",
-
         "bufferinfo/BufferInfoGetter.cpp",
         "bufferinfo/BufferInfoMapperMetadata.cpp",
 
@@ -119,13 +117,18 @@
         "drm/UEventListener.cpp",
         "drm/VSyncWorker.cpp",
 
-        "utils/autolock.cpp",
         "utils/hwcutils.cpp",
 
         "backend/Backend.cpp",
         "backend/BackendClient.cpp",
         "backend/BackendManager.cpp",
         "backend/BackendRCarDu.cpp",
+
+        "hwc2_device/DrmHwcTwo.cpp",
+        "hwc2_device/HwcDisplay.cpp",
+        "hwc2_device/HwcDisplayConfigs.cpp",
+        "hwc2_device/HwcLayer.cpp",
+        "hwc2_device/hwc2_device.cpp",
     ],
 }
 
diff --git a/DrmHwcTwo.cpp b/DrmHwcTwo.cpp
deleted file mode 100644
index 9bf1327..0000000
--- a/DrmHwcTwo.cpp
+++ /dev/null
@@ -1,1679 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define ATRACE_TAG ATRACE_TAG_GRAPHICS
-#define LOG_TAG "hwc-drm-two"
-
-#include "DrmHwcTwo.h"
-
-#include <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 "utils/log.h"
-#include "utils/properties.h"
-
-namespace android {
-
-DrmHwcTwo::DrmHwcTwo() : hwc2_device() {
-  common.tag = HARDWARE_DEVICE_TAG;
-  common.version = HWC_DEVICE_API_VERSION_2_0;
-  common.close = HookDevClose;
-  getCapabilities = HookDevGetCapabilities;
-  getFunction = HookDevGetFunction;
-}
-
-HWC2::Error DrmHwcTwo::CreateDisplay(hwc2_display_t displ,
-                                     HWC2::DisplayType type) {
-  DrmDevice *drm = resource_manager_.GetDrmDevice(static_cast<int>(displ));
-  if (!drm) {
-    ALOGE("Failed to get a valid drmresource");
-    return HWC2::Error::NoResources;
-  }
-  displays_.emplace(std::piecewise_construct, std::forward_as_tuple(displ),
-                    std::forward_as_tuple(&resource_manager_, drm, displ, type,
-                                          this));
-
-  DrmCrtc *crtc = drm->GetCrtcForDisplay(static_cast<int>(displ));
-  if (!crtc) {
-    ALOGE("Failed to get crtc for display %d", static_cast<int>(displ));
-    return HWC2::Error::BadDisplay;
-  }
-  auto display_planes = std::vector<DrmPlane *>();
-  for (const auto &plane : drm->planes()) {
-    if (plane->GetCrtcSupported(*crtc))
-      display_planes.push_back(plane.get());
-  }
-  displays_.at(displ).Init(&display_planes);
-  return HWC2::Error::None;
-}
-
-HWC2::Error DrmHwcTwo::Init() {
-  int rv = resource_manager_.Init();
-  if (rv) {
-    ALOGE("Can't initialize the resource manager %d", rv);
-    return HWC2::Error::NoResources;
-  }
-
-  HWC2::Error ret = HWC2::Error::None;
-  for (int i = 0; i < resource_manager_.getDisplayCount(); i++) {
-    ret = CreateDisplay(i, HWC2::DisplayType::Physical);
-    if (ret != HWC2::Error::None) {
-      ALOGE("Failed to create display %d with error %d", i, ret);
-      return ret;
-    }
-  }
-
-  resource_manager_.GetUEventListener()->RegisterHotplugHandler(
-      [this] { HandleHotplugUEvent(); });
-
-  return ret;
-}
-
-template <typename... Args>
-static inline HWC2::Error unsupported(char const *func, Args... /*args*/) {
-  ALOGV("Unsupported function: %s", func);
-  return HWC2::Error::Unsupported;
-}
-
-static inline void supported(char const *func) {
-  ALOGV("Supported function: %s", func);
-}
-
-HWC2::Error DrmHwcTwo::CreateVirtualDisplay(uint32_t width, uint32_t height,
-                                            int32_t *format,
-                                            hwc2_display_t *display) {
-  // TODO(nobody): Implement virtual display
-  return unsupported(__func__, width, height, format, display);
-}
-
-HWC2::Error DrmHwcTwo::DestroyVirtualDisplay(hwc2_display_t display) {
-  // TODO(nobody): Implement virtual display
-  return unsupported(__func__, display);
-}
-
-std::string DrmHwcTwo::HwcDisplay::DumpDelta(
-    DrmHwcTwo::HwcDisplay::Stats delta) {
-  if (delta.total_pixops_ == 0)
-    return "No stats yet";
-  double ratio = 1.0 - double(delta.gpu_pixops_) / double(delta.total_pixops_);
-
-  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) {
-  supported(__func__);
-
-  if (outBuffer != nullptr) {
-    auto copied_bytes = mDumpString.copy(outBuffer, *outSize);
-    *outSize = static_cast<uint32_t>(copied_bytes);
-    return;
-  }
-
-  std::stringstream output;
-
-  output << "-- drm_hwcomposer --\n\n";
-
-  for (std::pair<const hwc2_display_t, DrmHwcTwo::HwcDisplay> &dp : displays_)
-    output << dp.second.Dump();
-
-  mDumpString = output.str();
-  *outSize = static_cast<uint32_t>(mDumpString.size());
-}
-
-uint32_t DrmHwcTwo::GetMaxVirtualDisplayCount() {
-  // TODO(nobody): Implement virtual display
-  unsupported(__func__);
-  return 0;
-}
-
-HWC2::Error DrmHwcTwo::RegisterCallback(int32_t descriptor,
-                                        hwc2_callback_data_t data,
-                                        hwc2_function_pointer_t function) {
-  supported(__func__);
-
-  std::unique_lock<std::mutex> lock(callback_lock_);
-
-  switch (static_cast<HWC2::Callback>(descriptor)) {
-    case HWC2::Callback::Hotplug: {
-      hotplug_callback_ = std::make_pair(HWC2_PFN_HOTPLUG(function), data);
-      lock.unlock();
-      const auto &drm_devices = resource_manager_.getDrmDevices();
-      for (const auto &device : drm_devices)
-        HandleInitialHotplugState(device.get());
-      break;
-    }
-    case HWC2::Callback::Refresh: {
-      refresh_callback_ = std::make_pair(HWC2_PFN_REFRESH(function), data);
-      break;
-    }
-    case HWC2::Callback::Vsync: {
-      vsync_callback_ = std::make_pair(HWC2_PFN_VSYNC(function), data);
-      break;
-    }
-#if PLATFORM_SDK_VERSION > 29
-    case HWC2::Callback::Vsync_2_4: {
-      vsync_2_4_callback_ = std::make_pair(HWC2_PFN_VSYNC_2_4(function), data);
-      break;
-    }
-#endif
-    default:
-      break;
-  }
-  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) {
-  supported(__func__);
-
-  // clang-format off
-  color_transform_matrix_ = {1.0, 0.0, 0.0, 0.0,
-                             0.0, 1.0, 0.0, 0.0,
-                             0.0, 0.0, 1.0, 0.0,
-                             0.0, 0.0, 0.0, 1.0};
-  // clang-format on
-}
-
-void DrmHwcTwo::HwcDisplay::ClearDisplay() {
-  AtomicCommitArgs a_args = {.clear_active_composition = true};
-  compositor_.ExecuteAtomicCommit(a_args);
-}
-
-HWC2::Error DrmHwcTwo::HwcDisplay::Init(std::vector<DrmPlane *> *planes) {
-  supported(__func__);
-  planner_ = Planner::CreateInstance(drm_);
-  if (!planner_) {
-    ALOGE("Failed to create planner instance for composition");
-    return HWC2::Error::NoResources;
-  }
-
-  int display = static_cast<int>(handle_);
-  int ret = compositor_.Init(resource_manager_, display);
-  if (ret) {
-    ALOGE("Failed display compositor init for display %d (%d)", display, ret);
-    return HWC2::Error::NoResources;
-  }
-
-  // Split up the given display planes into primary and overlay to properly
-  // interface with the composition
-  char use_overlay_planes_prop[PROPERTY_VALUE_MAX];
-  property_get("vendor.hwc.drm.use_overlay_planes", use_overlay_planes_prop,
-               "1");
-  bool use_overlay_planes = strtol(use_overlay_planes_prop, nullptr, 10);
-  for (auto &plane : *planes) {
-    if (plane->type() == DRM_PLANE_TYPE_PRIMARY)
-      primary_planes_.push_back(plane);
-    else if (use_overlay_planes && (plane)->type() == DRM_PLANE_TYPE_OVERLAY)
-      overlay_planes_.push_back(plane);
-  }
-
-  crtc_ = drm_->GetCrtcForDisplay(display);
-  if (!crtc_) {
-    ALOGE("Failed to get crtc for display %d", display);
-    return HWC2::Error::BadDisplay;
-  }
-
-  connector_ = drm_->GetConnectorForDisplay(display);
-  if (!connector_) {
-    ALOGE("Failed to get connector for display %d", display);
-    return HWC2::Error::BadDisplay;
-  }
-
-  ret = vsync_worker_.Init(drm_, display, [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() {
-  supported(__func__);
-  for (std::pair<const hwc2_layer_t, DrmHwcTwo::HwcLayer> &l : layers_)
-    l.second.accept_type_change();
-  return HWC2::Error::None;
-}
-
-HWC2::Error DrmHwcTwo::HwcDisplay::CreateLayer(hwc2_layer_t *layer) {
-  supported(__func__);
-  layers_.emplace(static_cast<hwc2_layer_t>(layer_idx_), HwcLayer());
-  *layer = static_cast<hwc2_layer_t>(layer_idx_);
-  ++layer_idx_;
-  return HWC2::Error::None;
-}
-
-HWC2::Error DrmHwcTwo::HwcDisplay::DestroyLayer(hwc2_layer_t layer) {
-  supported(__func__);
-  if (!get_layer(layer))
-    return HWC2::Error::BadLayer;
-
-  layers_.erase(layer);
-  return HWC2::Error::None;
-}
-
-HWC2::Error DrmHwcTwo::HwcDisplay::GetActiveConfig(
-    hwc2_config_t *config) const {
-  supported(__func__);
-  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) {
-  supported(__func__);
-  uint32_t num_changes = 0;
-  for (std::pair<const hwc2_layer_t, DrmHwcTwo::HwcLayer> &l : layers_) {
-    if (l.second.type_changed()) {
-      if (layers && num_changes < *num_elements)
-        layers[num_changes] = l.first;
-      if (types && num_changes < *num_elements)
-        types[num_changes] = static_cast<int32_t>(l.second.validated_type());
-      ++num_changes;
-    }
-  }
-  if (!layers && !types)
-    *num_elements = num_changes;
-  return HWC2::Error::None;
-}
-
-HWC2::Error DrmHwcTwo::HwcDisplay::GetClientTargetSupport(uint32_t width,
-                                                          uint32_t height,
-                                                          int32_t /*format*/,
-                                                          int32_t dataspace) {
-  supported(__func__);
-  std::pair<uint32_t, uint32_t> min = drm_->min_resolution();
-  std::pair<uint32_t, uint32_t> max = drm_->max_resolution();
-
-  if (width < min.first || height < min.second)
-    return HWC2::Error::Unsupported;
-
-  if (width > max.first || height > max.second)
-    return HWC2::Error::Unsupported;
-
-  if (dataspace != HAL_DATASPACE_UNKNOWN)
-    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) {
-  supported(__func__);
-  if (!modes)
-    *num_modes = 1;
-
-  if (modes)
-    *modes = HAL_COLOR_MODE_NATIVE;
-
-  return HWC2::Error::None;
-}
-
-HWC2::Error DrmHwcTwo::HwcDisplay::GetDisplayAttribute(hwc2_config_t config,
-                                                       int32_t attribute_in,
-                                                       int32_t *value) {
-  supported(__func__);
-  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;
-}
-
-HWC2::Error DrmHwcTwo::HwcDisplay::GetDisplayConfigs(uint32_t *num_configs,
-                                                     hwc2_config_t *configs) {
-  supported(__func__);
-  // Since this callback is normally invoked twice (once to get the count, and
-  // once to populate configs), we don't really want to read the edid
-  // redundantly. Instead, only update the modes on the first invocation. While
-  // it's possible this will result in stale modes, it'll all come out in the
-  // wash when we try to set the active config later.
-  if (!configs) {
-    int ret = connector_->UpdateModes();
-    if (ret) {
-      ALOGE("Failed to update display modes %d", ret);
-      return HWC2::Error::BadDisplay;
-    }
-
-    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) {
-  supported(__func__);
-  std::ostringstream stream;
-  stream << "display-" << connector_->id();
-  std::string string = stream.str();
-  size_t length = string.length();
-  if (!name) {
-    *size = length;
-    return HWC2::Error::None;
-  }
-
-  *size = std::min<uint32_t>(static_cast<uint32_t>(length - 1), *size);
-  strncpy(name, string.c_str(), *size);
-  return HWC2::Error::None;
-}
-
-HWC2::Error DrmHwcTwo::HwcDisplay::GetDisplayRequests(int32_t *display_requests,
-                                                      uint32_t *num_elements,
-                                                      hwc2_layer_t *layers,
-                                                      int32_t *layer_requests) {
-  supported(__func__);
-  // TODO(nobody): I think virtual display should request
-  //      HWC2_DISPLAY_REQUEST_WRITE_CLIENT_TARGET_TO_OUTPUT here
-  unsupported(__func__, display_requests, num_elements, layers, layer_requests);
-  *num_elements = 0;
-  return HWC2::Error::None;
-}
-
-HWC2::Error DrmHwcTwo::HwcDisplay::GetDisplayType(int32_t *type) {
-  supported(__func__);
-  *type = static_cast<int32_t>(type_);
-  return HWC2::Error::None;
-}
-
-HWC2::Error DrmHwcTwo::HwcDisplay::GetDozeSupport(int32_t *support) {
-  supported(__func__);
-  *support = 0;
-  return HWC2::Error::None;
-}
-
-HWC2::Error DrmHwcTwo::HwcDisplay::GetHdrCapabilities(
-    uint32_t *num_types, int32_t * /*types*/, float * /*max_luminance*/,
-    float * /*max_average_luminance*/, float * /*min_luminance*/) {
-  supported(__func__);
-  *num_types = 0;
-  return HWC2::Error::None;
-}
-
-/* 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) {
-  supported(__func__);
-  uint32_t num_layers = 0;
-
-  for (std::pair<const hwc2_layer_t, DrmHwcTwo::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.release_fence_.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, DrmHwcTwo::HwcLayer *> z_map;
-  for (std::pair<const hwc2_layer_t, DrmHwcTwo::HwcLayer> &l : layers_) {
-    switch (l.second.validated_type()) {
-      case HWC2::Composition::Device:
-        z_map.emplace(std::make_pair(l.second.z_order(), &l.second));
-        break;
-      case HWC2::Composition::Client:
-        // Place it at the z_order of the lowest client layer
-        use_client_layer = true;
-        client_z_order = std::min(client_z_order, l.second.z_order());
-        break;
-      default:
-        continue;
-    }
-  }
-  if (use_client_layer)
-    z_map.emplace(std::make_pair(client_z_order, &client_layer_));
-
-  if (z_map.empty())
-    return HWC2::Error::BadLayer;
-
-  std::vector<DrmHwcLayer> composition_layers;
-
-  // now that they're ordered by z, add them to the composition
-  for (std::pair<const uint32_t, DrmHwcTwo::HwcLayer *> &l : z_map) {
-    DrmHwcLayer layer;
-    l.second->PopulateDrmLayer(&layer);
-    int ret = layer.ImportBuffer(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_,
-                                                             planner_.get());
-
-  // 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;
-  }
-
-  // Disable the planes we're not using
-  for (auto i = primary_planes.begin(); i != primary_planes.end();) {
-    composition->AddPlaneDisable(*i);
-    i = primary_planes.erase(i);
-  }
-  for (auto i = overlay_planes.begin(); i != overlay_planes.end();) {
-    composition->AddPlaneDisable(*i);
-    i = overlay_planes.erase(i);
-  }
-
-  a_args.composition = composition;
-  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;
-  }
-  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) {
-  supported(__func__);
-  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) {
-  supported(__func__);
-
-  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;
-
-  AtomicCommitArgs a_args = {
-      .display_mode = mode,
-      .clear_active_composition = true,
-  };
-
-  int err = compositor_.ExecuteAtomicCommit(a_args);
-  if (err != 0) {
-    ALOGE("Failed to queue mode changing commit %d", err);
-    return HWC2::Error::BadConfig;
-  }
-
-  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*/) {
-  supported(__func__);
-
-  client_layer_.set_buffer(target);
-  client_layer_.acquire_fence_ = UniqueFd(acquire_fence);
-  client_layer_.SetLayerDataspace(dataspace);
-
-  /* TODO: Do not update source_crop every call.
-   * It makes sense to do it once after every hotplug event. */
-  hwc_drm_bo 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) {
-  supported(__func__);
-
-  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) {
-  supported(__func__);
-  if (hint < HAL_COLOR_TRANSFORM_IDENTITY ||
-      hint > HAL_COLOR_TRANSFORM_CORRECT_TRITANOPIA)
-    return HWC2::Error::BadParameter;
-
-  if (!matrix && hint == HAL_COLOR_TRANSFORM_ARBITRARY_MATRIX)
-    return HWC2::Error::BadParameter;
-
-  color_transform_hint_ = static_cast<android_color_transform_t>(hint);
-  if (color_transform_hint_ == HAL_COLOR_TRANSFORM_ARBITRARY_MATRIX)
-    std::copy(matrix, matrix + MATRIX_SIZE, color_transform_matrix_.begin());
-
-  return HWC2::Error::None;
-}
-
-HWC2::Error DrmHwcTwo::HwcDisplay::SetOutputBuffer(buffer_handle_t buffer,
-                                                   int32_t release_fence) {
-  supported(__func__);
-  // TODO(nobody): Need virtual display support
-  return unsupported(__func__, buffer, release_fence);
-}
-
-HWC2::Error DrmHwcTwo::HwcDisplay::SetPowerMode(int32_t mode_in) {
-  supported(__func__);
-  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:
-      a_args.active = true;
-      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) {
-  supported(__func__);
-  vsync_worker_.VSyncControl(HWC2_VSYNC_ENABLE == enabled);
-  return HWC2::Error::None;
-}
-
-HWC2::Error DrmHwcTwo::HwcDisplay::ValidateDisplay(uint32_t *num_types,
-                                                   uint32_t *num_requests) {
-  supported(__func__);
-
-  return backend_->ValidateDisplay(this, num_types, num_requests);
-}
-
-std::vector<DrmHwcTwo::HwcLayer *>
-DrmHwcTwo::HwcDisplay::GetOrderLayersByZPos() {
-  std::vector<DrmHwcTwo::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 DrmHwcTwo::HwcLayer *lhs, const DrmHwcTwo::HwcLayer *rhs) {
-              return lhs->z_order() < rhs->z_order();
-            });
-
-  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 */) {
-  supported(__func__);
-  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) {
-  supported(__func__);
-
-  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) {
-  supported(__func__);
-
-  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) {
-  supported(__func__);
-
-  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) {
-  unsupported(__func__, 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 */
-
-HWC2::Error DrmHwcTwo::HwcLayer::SetCursorPosition(int32_t /*x*/,
-                                                   int32_t /*y*/) {
-  supported(__func__);
-  return HWC2::Error::None;
-}
-
-HWC2::Error DrmHwcTwo::HwcLayer::SetLayerBlendMode(int32_t mode) {
-  supported(__func__);
-  switch (static_cast<HWC2::BlendMode>(mode)) {
-    case HWC2::BlendMode::None:
-      blending_ = DrmHwcBlending::kNone;
-      break;
-    case HWC2::BlendMode::Premultiplied:
-      blending_ = DrmHwcBlending::kPreMult;
-      break;
-    case HWC2::BlendMode::Coverage:
-      blending_ = DrmHwcBlending::kCoverage;
-      break;
-    default:
-      ALOGE("Unknown blending mode b=%d", blending_);
-      blending_ = DrmHwcBlending::kNone;
-      break;
-  }
-  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=2314
- */
-HWC2::Error DrmHwcTwo::HwcLayer::SetLayerBuffer(buffer_handle_t buffer,
-                                                int32_t acquire_fence) {
-  supported(__func__);
-
-  set_buffer(buffer);
-  acquire_fence_ = UniqueFd(acquire_fence);
-  return HWC2::Error::None;
-}
-
-HWC2::Error DrmHwcTwo::HwcLayer::SetLayerColor(hwc_color_t /*color*/) {
-  // TODO(nobody): Put to client composition here?
-  supported(__func__);
-  return HWC2::Error::None;
-}
-
-HWC2::Error DrmHwcTwo::HwcLayer::SetLayerCompositionType(int32_t type) {
-  sf_type_ = static_cast<HWC2::Composition>(type);
-  return HWC2::Error::None;
-}
-
-HWC2::Error DrmHwcTwo::HwcLayer::SetLayerDataspace(int32_t dataspace) {
-  supported(__func__);
-  switch (dataspace & HAL_DATASPACE_STANDARD_MASK) {
-    case HAL_DATASPACE_STANDARD_BT709:
-      color_space_ = DrmHwcColorSpace::kItuRec709;
-      break;
-    case HAL_DATASPACE_STANDARD_BT601_625:
-    case HAL_DATASPACE_STANDARD_BT601_625_UNADJUSTED:
-    case HAL_DATASPACE_STANDARD_BT601_525:
-    case HAL_DATASPACE_STANDARD_BT601_525_UNADJUSTED:
-      color_space_ = DrmHwcColorSpace::kItuRec601;
-      break;
-    case HAL_DATASPACE_STANDARD_BT2020:
-    case HAL_DATASPACE_STANDARD_BT2020_CONSTANT_LUMINANCE:
-      color_space_ = DrmHwcColorSpace::kItuRec2020;
-      break;
-    default:
-      color_space_ = DrmHwcColorSpace::kUndefined;
-  }
-
-  switch (dataspace & HAL_DATASPACE_RANGE_MASK) {
-    case HAL_DATASPACE_RANGE_FULL:
-      sample_range_ = DrmHwcSampleRange::kFullRange;
-      break;
-    case HAL_DATASPACE_RANGE_LIMITED:
-      sample_range_ = DrmHwcSampleRange::kLimitedRange;
-      break;
-    default:
-      sample_range_ = DrmHwcSampleRange::kUndefined;
-  }
-  return HWC2::Error::None;
-}
-
-HWC2::Error DrmHwcTwo::HwcLayer::SetLayerDisplayFrame(hwc_rect_t frame) {
-  supported(__func__);
-  display_frame_ = frame;
-  return HWC2::Error::None;
-}
-
-HWC2::Error DrmHwcTwo::HwcLayer::SetLayerPlaneAlpha(float alpha) {
-  supported(__func__);
-  alpha_ = alpha;
-  return HWC2::Error::None;
-}
-
-HWC2::Error DrmHwcTwo::HwcLayer::SetLayerSidebandStream(
-    const native_handle_t *stream) {
-  supported(__func__);
-  // TODO(nobody): We don't support sideband
-  return unsupported(__func__, stream);
-}
-
-HWC2::Error DrmHwcTwo::HwcLayer::SetLayerSourceCrop(hwc_frect_t crop) {
-  supported(__func__);
-  source_crop_ = crop;
-  return HWC2::Error::None;
-}
-
-HWC2::Error DrmHwcTwo::HwcLayer::SetLayerSurfaceDamage(hwc_region_t damage) {
-  supported(__func__);
-  // TODO(nobody): We don't use surface damage, marking as unsupported
-  unsupported(__func__, damage);
-  return HWC2::Error::None;
-}
-
-HWC2::Error DrmHwcTwo::HwcLayer::SetLayerTransform(int32_t transform) {
-  supported(__func__);
-
-  uint32_t l_transform = 0;
-
-  // 270* and 180* cannot be combined with flips. More specifically, they
-  // already contain both horizontal and vertical flips, so those fields are
-  // redundant in this case. 90* rotation can be combined with either horizontal
-  // flip or vertical flip, so treat it differently
-  if (transform == HWC_TRANSFORM_ROT_270) {
-    l_transform = DrmHwcTransform::kRotate270;
-  } else if (transform == HWC_TRANSFORM_ROT_180) {
-    l_transform = DrmHwcTransform::kRotate180;
-  } else {
-    if (transform & HWC_TRANSFORM_FLIP_H)
-      l_transform |= DrmHwcTransform::kFlipH;
-    if (transform & HWC_TRANSFORM_FLIP_V)
-      l_transform |= DrmHwcTransform::kFlipV;
-    if (transform & HWC_TRANSFORM_ROT_90)
-      l_transform |= DrmHwcTransform::kRotate90;
-  }
-
-  transform_ = static_cast<DrmHwcTransform>(l_transform);
-  return HWC2::Error::None;
-}
-
-HWC2::Error DrmHwcTwo::HwcLayer::SetLayerVisibleRegion(hwc_region_t visible) {
-  supported(__func__);
-  // TODO(nobody): We don't use this information, marking as unsupported
-  unsupported(__func__, visible);
-  return HWC2::Error::None;
-}
-
-HWC2::Error DrmHwcTwo::HwcLayer::SetLayerZOrder(uint32_t order) {
-  supported(__func__);
-  z_order_ = order;
-  return HWC2::Error::None;
-}
-
-void DrmHwcTwo::HwcLayer::PopulateDrmLayer(DrmHwcLayer *layer) {
-  supported(__func__);
-  layer->sf_handle = buffer_;
-  // TODO(rsglobal): Avoid extra fd duplication
-  layer->acquire_fence = UniqueFd(fcntl(acquire_fence_.Get(), F_DUPFD_CLOEXEC));
-  layer->display_frame = display_frame_;
-  layer->alpha = lround(65535.0F * alpha_);
-  layer->blending = blending_;
-  layer->source_crop = source_crop_;
-  layer->transform = transform_;
-  layer->color_space = color_space_;
-  layer->sample_range = sample_range_;
-}
-
-void DrmHwcTwo::HandleDisplayHotplug(hwc2_display_t displayid, int state) {
-  const std::lock_guard<std::mutex> lock(callback_lock_);
-
-  if (hotplug_callback_.first != nullptr &&
-      hotplug_callback_.second != nullptr) {
-    hotplug_callback_.first(hotplug_callback_.second, displayid,
-                            state == DRM_MODE_CONNECTED
-                                ? HWC2_CONNECTION_CONNECTED
-                                : HWC2_CONNECTION_DISCONNECTED);
-  }
-}
-
-void DrmHwcTwo::HandleInitialHotplugState(DrmDevice *drmDevice) {
-  for (const auto &conn : drmDevice->connectors()) {
-    if (conn->state() != DRM_MODE_CONNECTED)
-      continue;
-    HandleDisplayHotplug(conn->display(), conn->state());
-  }
-}
-
-void DrmHwcTwo::HandleHotplugUEvent() {
-  for (const auto &drm : resource_manager_.getDrmDevices()) {
-    for (const auto &conn : drm->connectors()) {
-      drmModeConnection old_state = conn->state();
-      drmModeConnection cur_state = conn->UpdateModes()
-                                        ? DRM_MODE_UNKNOWNCONNECTION
-                                        : conn->state();
-
-      if (cur_state == old_state)
-        continue;
-
-      ALOGI("%s event for connector %u on display %d",
-            cur_state == DRM_MODE_CONNECTED ? "Plug" : "Unplug", conn->id(),
-            conn->display());
-
-      int display_id = conn->display();
-      if (cur_state == DRM_MODE_CONNECTED) {
-        auto &display = displays_.at(display_id);
-        display.ChosePreferredConfig();
-      } else {
-        auto &display = displays_.at(display_id);
-        display.ClearDisplay();
-      }
-
-      HandleDisplayHotplug(display_id, cur_state);
-    }
-  }
-}
-
-// static
-int DrmHwcTwo::HookDevClose(hw_device_t * /*dev*/) {
-  unsupported(__func__);
-  return 0;
-}
-
-// static
-void DrmHwcTwo::HookDevGetCapabilities(hwc2_device_t * /*dev*/,
-                                       uint32_t *out_count,
-                                       int32_t * /*out_capabilities*/) {
-  supported(__func__);
-  *out_count = 0;
-}
-
-// static
-hwc2_function_pointer_t DrmHwcTwo::HookDevGetFunction(
-    struct hwc2_device * /*dev*/, int32_t descriptor) {
-  supported(__func__);
-  auto func = static_cast<HWC2::FunctionDescriptor>(descriptor);
-  switch (func) {
-    // Device functions
-    case HWC2::FunctionDescriptor::CreateVirtualDisplay:
-      return ToHook<HWC2_PFN_CREATE_VIRTUAL_DISPLAY>(
-          DeviceHook<int32_t, decltype(&DrmHwcTwo::CreateVirtualDisplay),
-                     &DrmHwcTwo::CreateVirtualDisplay, uint32_t, uint32_t,
-                     int32_t *, hwc2_display_t *>);
-    case HWC2::FunctionDescriptor::DestroyVirtualDisplay:
-      return ToHook<HWC2_PFN_DESTROY_VIRTUAL_DISPLAY>(
-          DeviceHook<int32_t, decltype(&DrmHwcTwo::DestroyVirtualDisplay),
-                     &DrmHwcTwo::DestroyVirtualDisplay, hwc2_display_t>);
-    case HWC2::FunctionDescriptor::Dump:
-      return ToHook<HWC2_PFN_DUMP>(
-          DeviceHook<void, decltype(&DrmHwcTwo::Dump), &DrmHwcTwo::Dump,
-                     uint32_t *, char *>);
-    case HWC2::FunctionDescriptor::GetMaxVirtualDisplayCount:
-      return ToHook<HWC2_PFN_GET_MAX_VIRTUAL_DISPLAY_COUNT>(
-          DeviceHook<uint32_t, decltype(&DrmHwcTwo::GetMaxVirtualDisplayCount),
-                     &DrmHwcTwo::GetMaxVirtualDisplayCount>);
-    case HWC2::FunctionDescriptor::RegisterCallback:
-      return ToHook<HWC2_PFN_REGISTER_CALLBACK>(
-          DeviceHook<int32_t, decltype(&DrmHwcTwo::RegisterCallback),
-                     &DrmHwcTwo::RegisterCallback, int32_t,
-                     hwc2_callback_data_t, hwc2_function_pointer_t>);
-
-    // Display functions
-    case HWC2::FunctionDescriptor::AcceptDisplayChanges:
-      return ToHook<HWC2_PFN_ACCEPT_DISPLAY_CHANGES>(
-          DisplayHook<decltype(&HwcDisplay::AcceptDisplayChanges),
-                      &HwcDisplay::AcceptDisplayChanges>);
-    case HWC2::FunctionDescriptor::CreateLayer:
-      return ToHook<HWC2_PFN_CREATE_LAYER>(
-          DisplayHook<decltype(&HwcDisplay::CreateLayer),
-                      &HwcDisplay::CreateLayer, hwc2_layer_t *>);
-    case HWC2::FunctionDescriptor::DestroyLayer:
-      return ToHook<HWC2_PFN_DESTROY_LAYER>(
-          DisplayHook<decltype(&HwcDisplay::DestroyLayer),
-                      &HwcDisplay::DestroyLayer, hwc2_layer_t>);
-    case HWC2::FunctionDescriptor::GetActiveConfig:
-      return ToHook<HWC2_PFN_GET_ACTIVE_CONFIG>(
-          DisplayHook<decltype(&HwcDisplay::GetActiveConfig),
-                      &HwcDisplay::GetActiveConfig, hwc2_config_t *>);
-    case HWC2::FunctionDescriptor::GetChangedCompositionTypes:
-      return ToHook<HWC2_PFN_GET_CHANGED_COMPOSITION_TYPES>(
-          DisplayHook<decltype(&HwcDisplay::GetChangedCompositionTypes),
-                      &HwcDisplay::GetChangedCompositionTypes, uint32_t *,
-                      hwc2_layer_t *, int32_t *>);
-    case HWC2::FunctionDescriptor::GetClientTargetSupport:
-      return ToHook<HWC2_PFN_GET_CLIENT_TARGET_SUPPORT>(
-          DisplayHook<decltype(&HwcDisplay::GetClientTargetSupport),
-                      &HwcDisplay::GetClientTargetSupport, uint32_t, uint32_t,
-                      int32_t, int32_t>);
-    case HWC2::FunctionDescriptor::GetColorModes:
-      return ToHook<HWC2_PFN_GET_COLOR_MODES>(
-          DisplayHook<decltype(&HwcDisplay::GetColorModes),
-                      &HwcDisplay::GetColorModes, uint32_t *, int32_t *>);
-    case HWC2::FunctionDescriptor::GetDisplayAttribute:
-      return ToHook<HWC2_PFN_GET_DISPLAY_ATTRIBUTE>(
-          DisplayHook<decltype(&HwcDisplay::GetDisplayAttribute),
-                      &HwcDisplay::GetDisplayAttribute, hwc2_config_t, int32_t,
-                      int32_t *>);
-    case HWC2::FunctionDescriptor::GetDisplayConfigs:
-      return ToHook<HWC2_PFN_GET_DISPLAY_CONFIGS>(
-          DisplayHook<decltype(&HwcDisplay::GetDisplayConfigs),
-                      &HwcDisplay::GetDisplayConfigs, uint32_t *,
-                      hwc2_config_t *>);
-    case HWC2::FunctionDescriptor::GetDisplayName:
-      return ToHook<HWC2_PFN_GET_DISPLAY_NAME>(
-          DisplayHook<decltype(&HwcDisplay::GetDisplayName),
-                      &HwcDisplay::GetDisplayName, uint32_t *, char *>);
-    case HWC2::FunctionDescriptor::GetDisplayRequests:
-      return ToHook<HWC2_PFN_GET_DISPLAY_REQUESTS>(
-          DisplayHook<decltype(&HwcDisplay::GetDisplayRequests),
-                      &HwcDisplay::GetDisplayRequests, int32_t *, uint32_t *,
-                      hwc2_layer_t *, int32_t *>);
-    case HWC2::FunctionDescriptor::GetDisplayType:
-      return ToHook<HWC2_PFN_GET_DISPLAY_TYPE>(
-          DisplayHook<decltype(&HwcDisplay::GetDisplayType),
-                      &HwcDisplay::GetDisplayType, int32_t *>);
-    case HWC2::FunctionDescriptor::GetDozeSupport:
-      return ToHook<HWC2_PFN_GET_DOZE_SUPPORT>(
-          DisplayHook<decltype(&HwcDisplay::GetDozeSupport),
-                      &HwcDisplay::GetDozeSupport, int32_t *>);
-    case HWC2::FunctionDescriptor::GetHdrCapabilities:
-      return ToHook<HWC2_PFN_GET_HDR_CAPABILITIES>(
-          DisplayHook<decltype(&HwcDisplay::GetHdrCapabilities),
-                      &HwcDisplay::GetHdrCapabilities, uint32_t *, int32_t *,
-                      float *, float *, float *>);
-    case HWC2::FunctionDescriptor::GetReleaseFences:
-      return ToHook<HWC2_PFN_GET_RELEASE_FENCES>(
-          DisplayHook<decltype(&HwcDisplay::GetReleaseFences),
-                      &HwcDisplay::GetReleaseFences, uint32_t *, hwc2_layer_t *,
-                      int32_t *>);
-    case HWC2::FunctionDescriptor::PresentDisplay:
-      return ToHook<HWC2_PFN_PRESENT_DISPLAY>(
-          DisplayHook<decltype(&HwcDisplay::PresentDisplay),
-                      &HwcDisplay::PresentDisplay, int32_t *>);
-    case HWC2::FunctionDescriptor::SetActiveConfig:
-      return ToHook<HWC2_PFN_SET_ACTIVE_CONFIG>(
-          DisplayHook<decltype(&HwcDisplay::SetActiveConfig),
-                      &HwcDisplay::SetActiveConfig, hwc2_config_t>);
-    case HWC2::FunctionDescriptor::SetClientTarget:
-      return ToHook<HWC2_PFN_SET_CLIENT_TARGET>(
-          DisplayHook<decltype(&HwcDisplay::SetClientTarget),
-                      &HwcDisplay::SetClientTarget, buffer_handle_t, int32_t,
-                      int32_t, hwc_region_t>);
-    case HWC2::FunctionDescriptor::SetColorMode:
-      return ToHook<HWC2_PFN_SET_COLOR_MODE>(
-          DisplayHook<decltype(&HwcDisplay::SetColorMode),
-                      &HwcDisplay::SetColorMode, int32_t>);
-    case HWC2::FunctionDescriptor::SetColorTransform:
-      return ToHook<HWC2_PFN_SET_COLOR_TRANSFORM>(
-          DisplayHook<decltype(&HwcDisplay::SetColorTransform),
-                      &HwcDisplay::SetColorTransform, const float *, int32_t>);
-    case HWC2::FunctionDescriptor::SetOutputBuffer:
-      return ToHook<HWC2_PFN_SET_OUTPUT_BUFFER>(
-          DisplayHook<decltype(&HwcDisplay::SetOutputBuffer),
-                      &HwcDisplay::SetOutputBuffer, buffer_handle_t, int32_t>);
-    case HWC2::FunctionDescriptor::SetPowerMode:
-      return ToHook<HWC2_PFN_SET_POWER_MODE>(
-          DisplayHook<decltype(&HwcDisplay::SetPowerMode),
-                      &HwcDisplay::SetPowerMode, int32_t>);
-    case HWC2::FunctionDescriptor::SetVsyncEnabled:
-      return ToHook<HWC2_PFN_SET_VSYNC_ENABLED>(
-          DisplayHook<decltype(&HwcDisplay::SetVsyncEnabled),
-                      &HwcDisplay::SetVsyncEnabled, int32_t>);
-    case HWC2::FunctionDescriptor::ValidateDisplay:
-      return ToHook<HWC2_PFN_VALIDATE_DISPLAY>(
-          DisplayHook<decltype(&HwcDisplay::ValidateDisplay),
-                      &HwcDisplay::ValidateDisplay, uint32_t *, uint32_t *>);
-#if PLATFORM_SDK_VERSION > 27
-    case HWC2::FunctionDescriptor::GetRenderIntents:
-      return ToHook<HWC2_PFN_GET_RENDER_INTENTS>(
-          DisplayHook<decltype(&HwcDisplay::GetRenderIntents),
-                      &HwcDisplay::GetRenderIntents, int32_t, uint32_t *,
-                      int32_t *>);
-    case HWC2::FunctionDescriptor::SetColorModeWithRenderIntent:
-      return ToHook<HWC2_PFN_SET_COLOR_MODE_WITH_RENDER_INTENT>(
-          DisplayHook<decltype(&HwcDisplay::SetColorModeWithIntent),
-                      &HwcDisplay::SetColorModeWithIntent, int32_t, int32_t>);
-#endif
-#if PLATFORM_SDK_VERSION > 28
-    case HWC2::FunctionDescriptor::GetDisplayIdentificationData:
-      return ToHook<HWC2_PFN_GET_DISPLAY_IDENTIFICATION_DATA>(
-          DisplayHook<decltype(&HwcDisplay::GetDisplayIdentificationData),
-                      &HwcDisplay::GetDisplayIdentificationData, uint8_t *,
-                      uint32_t *, uint8_t *>);
-    case HWC2::FunctionDescriptor::GetDisplayCapabilities:
-      return ToHook<HWC2_PFN_GET_DISPLAY_CAPABILITIES>(
-          DisplayHook<decltype(&HwcDisplay::GetDisplayCapabilities),
-                      &HwcDisplay::GetDisplayCapabilities, uint32_t *,
-                      uint32_t *>);
-    case HWC2::FunctionDescriptor::GetDisplayBrightnessSupport:
-      return ToHook<HWC2_PFN_GET_DISPLAY_BRIGHTNESS_SUPPORT>(
-          DisplayHook<decltype(&HwcDisplay::GetDisplayBrightnessSupport),
-                      &HwcDisplay::GetDisplayBrightnessSupport, bool *>);
-    case HWC2::FunctionDescriptor::SetDisplayBrightness:
-      return ToHook<HWC2_PFN_SET_DISPLAY_BRIGHTNESS>(
-          DisplayHook<decltype(&HwcDisplay::SetDisplayBrightness),
-                      &HwcDisplay::SetDisplayBrightness, float>);
-#endif /* PLATFORM_SDK_VERSION > 28 */
-#if PLATFORM_SDK_VERSION > 29
-    case HWC2::FunctionDescriptor::GetDisplayConnectionType:
-      return ToHook<HWC2_PFN_GET_DISPLAY_CONNECTION_TYPE>(
-          DisplayHook<decltype(&HwcDisplay::GetDisplayConnectionType),
-                      &HwcDisplay::GetDisplayConnectionType, uint32_t *>);
-    case HWC2::FunctionDescriptor::GetDisplayVsyncPeriod:
-      return ToHook<HWC2_PFN_GET_DISPLAY_VSYNC_PERIOD>(
-          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(&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(&HwcDisplay::SetAutoLowLatencyMode),
-                      &HwcDisplay::SetAutoLowLatencyMode, bool>);
-    case HWC2::FunctionDescriptor::GetSupportedContentTypes:
-      return ToHook<HWC2_PFN_GET_SUPPORTED_CONTENT_TYPES>(
-          DisplayHook<decltype(&HwcDisplay::GetSupportedContentTypes),
-                      &HwcDisplay::GetSupportedContentTypes, uint32_t *,
-                      uint32_t *>);
-    case HWC2::FunctionDescriptor::SetContentType:
-      return ToHook<HWC2_PFN_SET_CONTENT_TYPE>(
-          DisplayHook<decltype(&HwcDisplay::SetContentType),
-                      &HwcDisplay::SetContentType, int32_t>);
-#endif
-    // Layer functions
-    case HWC2::FunctionDescriptor::SetCursorPosition:
-      return ToHook<HWC2_PFN_SET_CURSOR_POSITION>(
-          LayerHook<decltype(&HwcLayer::SetCursorPosition),
-                    &HwcLayer::SetCursorPosition, int32_t, int32_t>);
-    case HWC2::FunctionDescriptor::SetLayerBlendMode:
-      return ToHook<HWC2_PFN_SET_LAYER_BLEND_MODE>(
-          LayerHook<decltype(&HwcLayer::SetLayerBlendMode),
-                    &HwcLayer::SetLayerBlendMode, int32_t>);
-    case HWC2::FunctionDescriptor::SetLayerBuffer:
-      return ToHook<HWC2_PFN_SET_LAYER_BUFFER>(
-          LayerHook<decltype(&HwcLayer::SetLayerBuffer),
-                    &HwcLayer::SetLayerBuffer, buffer_handle_t, int32_t>);
-    case HWC2::FunctionDescriptor::SetLayerColor:
-      return ToHook<HWC2_PFN_SET_LAYER_COLOR>(
-          LayerHook<decltype(&HwcLayer::SetLayerColor),
-                    &HwcLayer::SetLayerColor, hwc_color_t>);
-    case HWC2::FunctionDescriptor::SetLayerCompositionType:
-      return ToHook<HWC2_PFN_SET_LAYER_COMPOSITION_TYPE>(
-          LayerHook<decltype(&HwcLayer::SetLayerCompositionType),
-                    &HwcLayer::SetLayerCompositionType, int32_t>);
-    case HWC2::FunctionDescriptor::SetLayerDataspace:
-      return ToHook<HWC2_PFN_SET_LAYER_DATASPACE>(
-          LayerHook<decltype(&HwcLayer::SetLayerDataspace),
-                    &HwcLayer::SetLayerDataspace, int32_t>);
-    case HWC2::FunctionDescriptor::SetLayerDisplayFrame:
-      return ToHook<HWC2_PFN_SET_LAYER_DISPLAY_FRAME>(
-          LayerHook<decltype(&HwcLayer::SetLayerDisplayFrame),
-                    &HwcLayer::SetLayerDisplayFrame, hwc_rect_t>);
-    case HWC2::FunctionDescriptor::SetLayerPlaneAlpha:
-      return ToHook<HWC2_PFN_SET_LAYER_PLANE_ALPHA>(
-          LayerHook<decltype(&HwcLayer::SetLayerPlaneAlpha),
-                    &HwcLayer::SetLayerPlaneAlpha, float>);
-    case HWC2::FunctionDescriptor::SetLayerSidebandStream:
-      return ToHook<HWC2_PFN_SET_LAYER_SIDEBAND_STREAM>(
-          LayerHook<decltype(&HwcLayer::SetLayerSidebandStream),
-                    &HwcLayer::SetLayerSidebandStream,
-                    const native_handle_t *>);
-    case HWC2::FunctionDescriptor::SetLayerSourceCrop:
-      return ToHook<HWC2_PFN_SET_LAYER_SOURCE_CROP>(
-          LayerHook<decltype(&HwcLayer::SetLayerSourceCrop),
-                    &HwcLayer::SetLayerSourceCrop, hwc_frect_t>);
-    case HWC2::FunctionDescriptor::SetLayerSurfaceDamage:
-      return ToHook<HWC2_PFN_SET_LAYER_SURFACE_DAMAGE>(
-          LayerHook<decltype(&HwcLayer::SetLayerSurfaceDamage),
-                    &HwcLayer::SetLayerSurfaceDamage, hwc_region_t>);
-    case HWC2::FunctionDescriptor::SetLayerTransform:
-      return ToHook<HWC2_PFN_SET_LAYER_TRANSFORM>(
-          LayerHook<decltype(&HwcLayer::SetLayerTransform),
-                    &HwcLayer::SetLayerTransform, int32_t>);
-    case HWC2::FunctionDescriptor::SetLayerVisibleRegion:
-      return ToHook<HWC2_PFN_SET_LAYER_VISIBLE_REGION>(
-          LayerHook<decltype(&HwcLayer::SetLayerVisibleRegion),
-                    &HwcLayer::SetLayerVisibleRegion, hwc_region_t>);
-    case HWC2::FunctionDescriptor::SetLayerZOrder:
-      return ToHook<HWC2_PFN_SET_LAYER_Z_ORDER>(
-          LayerHook<decltype(&HwcLayer::SetLayerZOrder),
-                    &HwcLayer::SetLayerZOrder, uint32_t>);
-    case HWC2::FunctionDescriptor::Invalid:
-    default:
-      return nullptr;
-  }
-}
-
-// static
-int DrmHwcTwo::HookDevOpen(const struct hw_module_t *module, const char *name,
-                           struct hw_device_t **dev) {
-  supported(__func__);
-  if (strcmp(name, HWC_HARDWARE_COMPOSER) != 0) {
-    ALOGE("Invalid module name- %s", name);
-    return -EINVAL;
-  }
-
-  std::unique_ptr<DrmHwcTwo> ctx(new DrmHwcTwo());
-  if (!ctx) {
-    ALOGE("Failed to allocate DrmHwcTwo");
-    return -ENOMEM;
-  }
-
-  HWC2::Error err = ctx->Init();
-  if (err != HWC2::Error::None) {
-    ALOGE("Failed to initialize DrmHwcTwo err=%d\n", err);
-    return -EINVAL;
-  }
-
-  ctx->common.module = (hw_module_t *)module;
-  *dev = &ctx->common;
-  ctx.release();  // NOLINT(bugprone-unused-return-value)
-  return 0;
-}
-}  // namespace android
-
-// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)
-static struct hw_module_methods_t hwc2_module_methods = {
-    .open = android::DrmHwcTwo::HookDevOpen,
-};
-
-// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)
-hw_module_t HAL_MODULE_INFO_SYM = {
-    .tag = HARDWARE_MODULE_TAG,
-    .module_api_version = HARDWARE_MODULE_API_VERSION(2, 0),
-    .id = HWC_HARDWARE_MODULE_ID,
-    .name = "DrmHwcTwo module",
-    .author = "The Android Open Source Project",
-    .methods = &hwc2_module_methods,
-    .dso = nullptr,
-    .reserved = {0},
-};
diff --git a/DrmHwcTwo.h b/DrmHwcTwo.h
deleted file mode 100644
index 7fd4fbd..0000000
--- a/DrmHwcTwo.h
+++ /dev/null
@@ -1,455 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_DRM_HWC_TWO_H_
-#define ANDROID_DRM_HWC_TWO_H_
-
-#include <hardware/hwcomposer2.h>
-#include <math.h>
-
-#include <array>
-#include <map>
-
-#include "compositor/DrmDisplayCompositor.h"
-#include "compositor/Planner.h"
-#include "drm/ResourceManager.h"
-#include "drm/VSyncWorker.h"
-#include "drmhwcomposer.h"
-
-namespace android {
-
-class Backend;
-
-class DrmHwcTwo : public hwc2_device_t {
- public:
-  static int HookDevOpen(const struct hw_module_t *module, const char *name,
-                         struct hw_device_t **dev);
-
-  DrmHwcTwo();
-
-  HWC2::Error Init();
-
-  std::pair<HWC2_PFN_HOTPLUG, hwc2_callback_data_t> hotplug_callback_{};
-  std::pair<HWC2_PFN_VSYNC, hwc2_callback_data_t> vsync_callback_{};
-#if PLATFORM_SDK_VERSION > 29
-  std::pair<HWC2_PFN_VSYNC_2_4, hwc2_callback_data_t> vsync_2_4_callback_{};
-#endif
-  std::pair<HWC2_PFN_REFRESH, hwc2_callback_data_t> refresh_callback_{};
-
-  std::mutex callback_lock_;
-
-  class HwcLayer {
-   public:
-    HWC2::Composition sf_type() const {
-      return sf_type_;
-    }
-    HWC2::Composition validated_type() const {
-      return validated_type_;
-    }
-    void accept_type_change() {
-      sf_type_ = validated_type_;
-    }
-    void set_validated_type(HWC2::Composition type) {
-      validated_type_ = type;
-    }
-    bool type_changed() const {
-      return sf_type_ != validated_type_;
-    }
-
-    uint32_t z_order() const {
-      return z_order_;
-    }
-
-    buffer_handle_t buffer() {
-      return buffer_;
-    }
-    void set_buffer(buffer_handle_t buffer) {
-      buffer_ = buffer;
-    }
-
-    hwc_rect_t display_frame() {
-      return display_frame_;
-    }
-
-    void PopulateDrmLayer(DrmHwcLayer *layer);
-
-    bool RequireScalingOrPhasing() {
-      float src_width = source_crop_.right - source_crop_.left;
-      float src_height = source_crop_.bottom - source_crop_.top;
-
-      float dest_width = display_frame_.right - display_frame_.left;
-      float dest_height = display_frame_.bottom - display_frame_.top;
-
-      bool scaling = src_width != dest_width || src_height != dest_height;
-      bool phasing = (source_crop_.left - floor(source_crop_.left) != 0) ||
-                     (source_crop_.top - floor(source_crop_.top) != 0);
-      return scaling || phasing;
-    }
-
-    // Layer hooks
-    HWC2::Error SetCursorPosition(int32_t /*x*/, int32_t /*y*/);
-    HWC2::Error SetLayerBlendMode(int32_t mode);
-    HWC2::Error SetLayerBuffer(buffer_handle_t buffer, int32_t acquire_fence);
-    HWC2::Error SetLayerColor(hwc_color_t /*color*/);
-    HWC2::Error SetLayerCompositionType(int32_t type);
-    HWC2::Error SetLayerDataspace(int32_t dataspace);
-    HWC2::Error SetLayerDisplayFrame(hwc_rect_t frame);
-    HWC2::Error SetLayerPlaneAlpha(float alpha);
-    HWC2::Error SetLayerSidebandStream(const native_handle_t *stream);
-    HWC2::Error SetLayerSourceCrop(hwc_frect_t crop);
-    HWC2::Error SetLayerSurfaceDamage(hwc_region_t damage);
-    HWC2::Error SetLayerTransform(int32_t transform);
-    HWC2::Error SetLayerVisibleRegion(hwc_region_t visible);
-    HWC2::Error SetLayerZOrder(uint32_t order);
-
-    UniqueFd acquire_fence_;
-
-    /*
-     * Release fence is not used.
-     * There is no release fence support available in the DRM/KMS. In case no
-     * release fence provided application will use this buffer for writing when
-     * the next frame present fence is signaled.
-     */
-    UniqueFd release_fence_;
-
-   private:
-    // sf_type_ stores the initial type given to us by surfaceflinger,
-    // validated_type_ stores the type after running ValidateDisplay
-    HWC2::Composition sf_type_ = HWC2::Composition::Invalid;
-    HWC2::Composition validated_type_ = HWC2::Composition::Invalid;
-
-    buffer_handle_t buffer_ = NULL;
-    hwc_rect_t display_frame_;
-    float alpha_ = 1.0f;
-    hwc_frect_t source_crop_;
-    DrmHwcTransform transform_ = DrmHwcTransform::kIdentity;
-    uint32_t z_order_ = 0;
-    DrmHwcBlending blending_ = DrmHwcBlending::kNone;
-    DrmHwcColorSpace color_space_ = DrmHwcColorSpace::kUndefined;
-    DrmHwcSampleRange sample_range_ = DrmHwcSampleRange::kUndefined;
-  };
-
-  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<DrmHwcTwo::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) {
-        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() {
-        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 {
-      return backend_.get();
-    }
-    void set_backend(std::unique_ptr<Backend> backend) {
-      backend_ = std::move(backend);
-    }
-
-    const std::vector<DrmPlane *> &primary_planes() const {
-      return primary_planes_;
-    }
-
-    const std::vector<DrmPlane *> &overlay_planes() const {
-      return overlay_planes_;
-    }
-
-    std::map<hwc2_layer_t, HwcLayer> &layers() {
-      return layers_;
-    }
-
-    const DrmDisplayCompositor &compositor() const {
-      return compositor_;
-    }
-
-    const DrmDevice *drm() const {
-      return drm_;
-    }
-
-    const DrmConnector *connector() const {
-      return connector_;
-    }
-
-    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_;
-
-    ResourceManager *resource_manager_;
-    DrmDevice *drm_;
-    DrmDisplayCompositor compositor_;
-    std::unique_ptr<Planner> planner_;
-
-    std::vector<DrmPlane *> primary_planes_;
-    std::vector<DrmPlane *> overlay_planes_;
-
-    std::unique_ptr<Backend> backend_;
-
-    VSyncWorker vsync_worker_;
-    DrmConnector *connector_ = NULL;
-    DrmCrtc *crtc_ = NULL;
-    hwc2_display_t handle_;
-    HWC2::DisplayType type_;
-    uint32_t layer_idx_ = 0;
-    std::map<hwc2_layer_t, HwcLayer> layers_;
-    HwcLayer client_layer_;
-    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);
-  };
-
- private:
-  static DrmHwcTwo *toDrmHwcTwo(hwc2_device_t *dev) {
-    return static_cast<DrmHwcTwo *>(dev);
-  }
-
-  template <typename PFN, typename T>
-  static hwc2_function_pointer_t ToHook(T function) {
-    static_assert(std::is_same<PFN, T>::value, "Incompatible fn pointer");
-    return reinterpret_cast<hwc2_function_pointer_t>(function);
-  }
-
-  template <typename T, typename HookType, HookType func, typename... Args>
-  static T DeviceHook(hwc2_device_t *dev, Args... args) {
-    DrmHwcTwo *hwc = toDrmHwcTwo(dev);
-    return static_cast<T>(((*hwc).*func)(std::forward<Args>(args)...));
-  }
-
-  static HwcDisplay *GetDisplay(DrmHwcTwo *hwc, hwc2_display_t display_handle) {
-    auto it = hwc->displays_.find(display_handle);
-    if (it == hwc->displays_.end())
-      return nullptr;
-
-    return &it->second;
-  }
-
-  template <typename HookType, HookType func, typename... Args>
-  static int32_t DisplayHook(hwc2_device_t *dev, hwc2_display_t display_handle,
-                             Args... args) {
-    HwcDisplay *display = GetDisplay(toDrmHwcTwo(dev), display_handle);
-    if (!display)
-      return static_cast<int32_t>(HWC2::Error::BadDisplay);
-
-    return static_cast<int32_t>((display->*func)(std::forward<Args>(args)...));
-  }
-
-  template <typename HookType, HookType func, typename... Args>
-  static int32_t LayerHook(hwc2_device_t *dev, hwc2_display_t display_handle,
-                           hwc2_layer_t layer_handle, Args... args) {
-    HwcDisplay *display = GetDisplay(toDrmHwcTwo(dev), display_handle);
-    if (!display)
-      return static_cast<int32_t>(HWC2::Error::BadDisplay);
-
-    HwcLayer *layer = display->get_layer(layer_handle);
-    if (!layer)
-      return static_cast<int32_t>(HWC2::Error::BadLayer);
-
-    return static_cast<int32_t>((layer->*func)(std::forward<Args>(args)...));
-  }
-
-  // hwc2_device_t hooks
-  static int HookDevClose(hw_device_t *dev);
-  static void HookDevGetCapabilities(hwc2_device_t *dev, uint32_t *out_count,
-                                     int32_t *out_capabilities);
-  static hwc2_function_pointer_t HookDevGetFunction(struct hwc2_device *device,
-                                                    int32_t descriptor);
-
-  // Device functions
-  HWC2::Error CreateVirtualDisplay(uint32_t width, uint32_t height,
-                                   int32_t *format, hwc2_display_t *display);
-  HWC2::Error DestroyVirtualDisplay(hwc2_display_t display);
-  void Dump(uint32_t *outSize, char *outBuffer);
-  uint32_t GetMaxVirtualDisplayCount();
-  HWC2::Error RegisterCallback(int32_t descriptor, hwc2_callback_data_t data,
-                               hwc2_function_pointer_t function);
-  HWC2::Error CreateDisplay(hwc2_display_t displ, HWC2::DisplayType type);
-  void HandleDisplayHotplug(hwc2_display_t displayid, int state);
-  void HandleInitialHotplugState(DrmDevice *drmDevice);
-
-  void HandleHotplugUEvent();
-
-  ResourceManager resource_manager_;
-  std::map<hwc2_display_t, HwcDisplay> displays_;
-
-  std::string mDumpString;
-};
-}  // namespace android
-
-#endif
diff --git a/OWNERS b/OWNERS
index 75e29ae..dd8e743 100644
--- a/OWNERS
+++ b/OWNERS
@@ -1,5 +1,5 @@
 adelva@google.com
+dimitrysh@google.com
 john.stultz@linaro.org
 marcheu@google.com
 seanpaul@google.com
-zachr@google.com
diff --git a/README.md b/README.md
index c142266..05ddc79 100644
--- a/README.md
+++ b/README.md
@@ -16,7 +16,7 @@
   you with formatting of your patches:
 
     ```
-    git diff | clang-format-diff-12 -p 1 -style=file
+    git diff | clang-format-diff-13 -p 1 -style=file
     ```
 
 * Hardware specific changes should be tested on relevant platforms before
diff --git a/backend/Backend.cpp b/backend/Backend.cpp
index ce606dd..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;
@@ -63,12 +62,11 @@
                                                    client_size);
   display->total_stats().total_pixops_ += CalcPixOps(layers, 0, layers.size());
 
-  return *num_types ? HWC2::Error::HasChanges : HWC2::Error::None;
+  return *num_types != 0 ? HWC2::Error::HasChanges : HWC2::Error::None;
 }
 
 std::tuple<int, size_t> Backend::GetClientLayers(
-    DrmHwcTwo::HwcDisplay *display,
-    const std::vector<DrmHwcTwo::HwcLayer *> &layers) {
+    HwcDisplay *display, const std::vector<HwcLayer *> &layers) {
   int client_start = -1;
   size_t client_size = 0;
 
@@ -83,10 +81,9 @@
   return GetExtraClientRange(display, layers, client_start, client_size);
 }
 
-bool Backend::IsClientLayer(DrmHwcTwo::HwcDisplay *display,
-                            DrmHwcTwo::HwcLayer *layer) {
-  return !HardwareSupportsLayerType(layer->sf_type()) ||
-         !BufferInfoGetter::GetInstance()->IsHandleUsable(layer->buffer()) ||
+bool Backend::IsClientLayer(HwcDisplay *display, HwcLayer *layer) {
+  return !HardwareSupportsLayerType(layer->GetSfType()) ||
+         !BufferInfoGetter::GetInstance()->IsHandleUsable(layer->GetBuffer()) ||
          display->color_transform_hint() != HAL_COLOR_TRANSFORM_IDENTITY ||
          (layer->RequireScalingOrPhasing() &&
           display->resource_manager()->ForcedScalingWithGpu());
@@ -97,32 +94,31 @@
          comp_type == HWC2::Composition::Cursor;
 }
 
-uint32_t Backend::CalcPixOps(const std::vector<DrmHwcTwo::HwcLayer *> &layers,
+uint32_t Backend::CalcPixOps(const std::vector<HwcLayer *> &layers,
                              size_t first_z, size_t size) {
   uint32_t pixops = 0;
   for (size_t z_order = 0; z_order < layers.size(); ++z_order) {
     if (z_order >= first_z && z_order < first_z + size) {
-      hwc_rect_t df = layers[z_order]->display_frame();
+      hwc_rect_t df = layers[z_order]->GetDisplayFrame();
       pixops += (df.right - df.left) * (df.bottom - df.top);
     }
   }
   return pixops;
 }
 
-void Backend::MarkValidated(std::vector<DrmHwcTwo::HwcLayer *> &layers,
+void Backend::MarkValidated(std::vector<HwcLayer *> &layers,
                             size_t client_first_z, size_t client_size) {
   for (size_t z_order = 0; z_order < layers.size(); ++z_order) {
     if (z_order >= client_first_z && z_order < client_first_z + client_size)
-      layers[z_order]->set_validated_type(HWC2::Composition::Client);
+      layers[z_order]->SetValidatedType(HWC2::Composition::Client);
     else
-      layers[z_order]->set_validated_type(HWC2::Composition::Device);
+      layers[z_order]->SetValidatedType(HWC2::Composition::Device);
   }
 }
 
 std::tuple<int, int> Backend::GetExtraClientRange(
-    DrmHwcTwo::HwcDisplay *display,
-    const std::vector<DrmHwcTwo::HwcLayer *> &layers, int client_start,
-    size_t client_size) {
+    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 fc9a733..82b8fca 100644
--- a/backend/Backend.h
+++ b/backend/Backend.h
@@ -17,32 +17,28 @@
 #ifndef ANDROID_BACKEND_H
 #define ANDROID_BACKEND_H
 
-#include "DrmHwcTwo.h"
+#include "hwc2_device/DrmHwcTwo.h"
 
 namespace android {
 
 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<DrmHwcTwo::HwcLayer *> &layers);
-  virtual bool IsClientLayer(DrmHwcTwo::HwcDisplay *display,
-                             DrmHwcTwo::HwcLayer *layer);
+      HwcDisplay *display, const std::vector<HwcLayer *> &layers);
+  virtual bool IsClientLayer(HwcDisplay *display, HwcLayer *layer);
 
  protected:
-  bool HardwareSupportsLayerType(HWC2::Composition comp_type);
-  uint32_t CalcPixOps(const std::vector<DrmHwcTwo::HwcLayer *> &layers,
-                      size_t first_z, size_t size);
-  void MarkValidated(std::vector<DrmHwcTwo::HwcLayer *> &layers,
-                     size_t client_first_z, size_t client_size);
-  std::tuple<int, int> GetExtraClientRange(
-      DrmHwcTwo::HwcDisplay *display,
-      const std::vector<DrmHwcTwo::HwcLayer *> &layers, int client_start,
-      size_t client_size);
+  static bool HardwareSupportsLayerType(HWC2::Composition comp_type);
+  static uint32_t CalcPixOps(const std::vector<HwcLayer *> &layers,
+                             size_t first_z, size_t size);
+  static void MarkValidated(std::vector<HwcLayer *> &layers,
+                            size_t client_first_z, size_t client_size);
+  static std::tuple<int, int> GetExtraClientRange(
+      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 49963b8..606dca2 100644
--- a/backend/BackendClient.cpp
+++ b/backend/BackendClient.cpp
@@ -20,11 +20,11 @@
 
 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()) {
-    layer.set_validated_type(HWC2::Composition::Client);
+  for (auto &[layer_handle, layer] : display->layers()) {
+    layer.SetValidatedType(HWC2::Composition::Client);
     ++*num_types;
   }
   return HWC2::Error::HasChanges;
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 7b89761..aadef36 100644
--- a/backend/BackendManager.cpp
+++ b/backend/BackendManager.cpp
@@ -36,12 +36,12 @@
 }
 
 int BackendManager::RegisterBackend(const std::string &name,
-                                    backend_constructor_t backend_constructor) {
+                                    BackendConstructorT backend_constructor) {
   available_backends_[name] = std::move(backend_constructor);
   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,
@@ -49,7 +49,7 @@
   std::string backend_name(backend_override);
 
   display->set_backend(GetBackendByName(backend_name));
-  if (!display->backend()) {
+  if (display->backend() == nullptr) {
     ALOGE("Failed to set backend '%s' for '%s' and driver '%s'",
           backend_name.c_str(), display->connector()->name().c_str(),
           driver_name.c_str());
diff --git a/backend/BackendManager.h b/backend/BackendManager.h
index 9b314db..751cb78 100644
--- a/backend/BackendManager.h
+++ b/backend/BackendManager.h
@@ -24,6 +24,7 @@
 
 #include "Backend.h"
 
+// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
 #define REGISTER_BACKEND(name_str_, backend_)                               \
   static int                                                                \
       backend = BackendManager::GetInstance()                               \
@@ -36,21 +37,21 @@
 
 class BackendManager {
  public:
-  using backend_constructor_t = std::function<std::unique_ptr<Backend>()>;
+  using BackendConstructorT = std::function<std::unique_ptr<Backend>()>;
   static BackendManager &GetInstance();
   int RegisterBackend(const std::string &name,
-                      backend_constructor_t backend_constructor);
-  int SetBackendForDisplay(DrmHwcTwo::HwcDisplay *display);
+                      BackendConstructorT backend_constructor);
+  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;
 
   static const std::vector<std::string> kClientDevices;
 
-  std::map<std::string, backend_constructor_t> available_backends_;
+  std::map<std::string, BackendConstructorT> available_backends_;
 };
 }  // namespace android
 
diff --git a/backend/BackendRCarDu.cpp b/backend/BackendRCarDu.cpp
index b012797..0750ee4 100644
--- a/backend/BackendRCarDu.cpp
+++ b/backend/BackendRCarDu.cpp
@@ -22,13 +22,12 @@
 
 namespace android {
 
-bool BackendRCarDu::IsClientLayer(DrmHwcTwo::HwcDisplay *display,
-                                  DrmHwcTwo::HwcLayer *layer) {
+bool BackendRCarDu::IsClientLayer(HwcDisplay *display, HwcLayer *layer) {
   hwc_drm_bo_t bo;
 
-  int ret = BufferInfoGetter::GetInstance()->ConvertBoInfo(layer->buffer(),
+  int ret = BufferInfoGetter::GetInstance()->ConvertBoInfo(layer->GetBuffer(),
                                                            &bo);
-  if (ret)
+  if (ret != 0)
     return true;
 
   if (bo.format == DRM_FORMAT_ABGR8888)
diff --git a/backend/BackendRCarDu.h b/backend/BackendRCarDu.h
index 8a1011a..1259c9f 100644
--- a/backend/BackendRCarDu.h
+++ b/backend/BackendRCarDu.h
@@ -23,8 +23,7 @@
 
 class BackendRCarDu : public Backend {
  public:
-  bool IsClientLayer(DrmHwcTwo::HwcDisplay *display,
-                     DrmHwcTwo::HwcLayer *layer) override;
+  bool IsClientLayer(HwcDisplay *display, HwcLayer *layer) override;
 };
 }  // namespace android
 
diff --git a/bufferinfo/BufferInfoGetter.cpp b/bufferinfo/BufferInfoGetter.cpp
index c284365..0cfd7e5 100644
--- a/bufferinfo/BufferInfoGetter.cpp
+++ b/bufferinfo/BufferInfoGetter.cpp
@@ -62,9 +62,11 @@
 }
 
 int LegacyBufferInfoGetter::Init() {
-  int ret = hw_get_module(GRALLOC_HARDWARE_MODULE_ID,
-                          (const hw_module_t **)&gralloc_);
-  if (ret) {
+  int ret = hw_get_module(
+      GRALLOC_HARDWARE_MODULE_ID,
+      // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
+      reinterpret_cast<const hw_module_t **>(&gralloc_));
+  if (ret != 0) {
     ALOGE("Failed to open gralloc module");
     return ret;
   }
diff --git a/bufferinfo/BufferInfoGetter.h b/bufferinfo/BufferInfoGetter.h
index 7b088df..59184a4 100644
--- a/bufferinfo/BufferInfoGetter.h
+++ b/bufferinfo/BufferInfoGetter.h
@@ -31,8 +31,7 @@
 
 class BufferInfoGetter {
  public:
-  virtual ~BufferInfoGetter() {
-  }
+  virtual ~BufferInfoGetter() = default;
 
   virtual int ConvertBoInfo(buffer_handle_t handle, hwc_drm_bo_t *bo) = 0;
 
@@ -53,17 +52,18 @@
     return 0;
   }
 
-  int ConvertBoInfo(buffer_handle_t handle, hwc_drm_bo_t *bo) override = 0;
-
   static std::unique_ptr<LegacyBufferInfoGetter> CreateInstance();
 
   static uint32_t ConvertHalFormatToDrm(uint32_t hal_format);
+
+  // NOLINTNEXTLINE:(readability-identifier-naming)
   const gralloc_module_t *gralloc_;
 };
 
 #ifdef DISABLE_LEGACY_GETTERS
 #define LEGACY_BUFFER_INFO_GETTER(getter_)
 #else
+// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
 #define LEGACY_BUFFER_INFO_GETTER(getter_)                             \
   std::unique_ptr<LegacyBufferInfoGetter>                              \
   LegacyBufferInfoGetter::CreateInstance() {                           \
diff --git a/bufferinfo/BufferInfoMapperMetadata.cpp b/bufferinfo/BufferInfoMapperMetadata.cpp
index a8e95e7..2f08a76 100644
--- a/bufferinfo/BufferInfoMapperMetadata.cpp
+++ b/bufferinfo/BufferInfoMapperMetadata.cpp
@@ -54,7 +54,7 @@
     return android::BAD_VALUE;
   }
 
-  for (int i = 0; i < HWC_DRM_BO_MAX_PLANES; i++) {
+  for (int i = 0; i < kHwcDrmBoMaxPlanes; i++) {
     /* If no size, we're out of usable planes */
     if (bo->sizes[i] <= 0) {
       if (i == 0) {
@@ -89,12 +89,12 @@
 int BufferInfoMapperMetadata::ConvertBoInfo(buffer_handle_t handle,
                                             hwc_drm_bo_t *bo) {
   GraphicBufferMapper &mapper = GraphicBufferMapper::getInstance();
-  if (!handle)
+  if (handle == nullptr)
     return -EINVAL;
 
   uint64_t usage = 0;
   int err = mapper.getUsage(handle, &usage);
-  if (err) {
+  if (err != 0) {
     ALOGE("Failed to get usage err=%d", err);
     return err;
   }
@@ -102,27 +102,27 @@
 
   ui::PixelFormat hal_format;
   err = mapper.getPixelFormatRequested(handle, &hal_format);
-  if (err) {
+  if (err != 0) {
     ALOGE("Failed to get HAL Pixel Format err=%d", err);
     return err;
   }
   bo->hal_format = static_cast<uint32_t>(hal_format);
 
   err = mapper.getPixelFormatFourCC(handle, &bo->format);
-  if (err) {
+  if (err != 0) {
     ALOGE("Failed to get FourCC format err=%d", err);
     return err;
   }
 
   err = mapper.getPixelFormatModifier(handle, &bo->modifiers[0]);
-  if (err) {
+  if (err != 0) {
     ALOGE("Failed to get DRM Modifier err=%d", err);
     return err;
   }
 
   uint64_t width = 0;
   err = mapper.getWidth(handle, &width);
-  if (err) {
+  if (err != 0) {
     ALOGE("Failed to get Width err=%d", err);
     return err;
   }
@@ -130,7 +130,7 @@
 
   uint64_t height = 0;
   err = mapper.getHeight(handle, &height);
-  if (err) {
+  if (err != 0) {
     ALOGE("Failed to get Height err=%d", err);
     return err;
   }
@@ -138,7 +138,7 @@
 
   std::vector<ui::PlaneLayout> layouts;
   err = mapper.getPlaneLayouts(handle, &layouts);
-  if (err) {
+  if (err != 0) {
     ALOGE("Failed to get Plane Layouts err=%d", err);
     return err;
   }
diff --git a/bufferinfo/legacy/BufferInfoLibdrm.cpp b/bufferinfo/legacy/BufferInfoLibdrm.cpp
index 47481b2..4f942fe 100644
--- a/bufferinfo/legacy/BufferInfoLibdrm.cpp
+++ b/bufferinfo/legacy/BufferInfoLibdrm.cpp
@@ -78,6 +78,7 @@
 }
 
 static bool is_yuv(uint32_t native) {
+  // NOLINTNEXTLINE(readability-use-anyofallof)
   for (auto droid_yuv_format : kDroidYuvFormats)
     if (droid_yuv_format.native == native)
       return true;
diff --git a/build_deploy.sh b/build_deploy.sh
new file mode 100755
index 0000000..ba9732b
--- /dev/null
+++ b/build_deploy.sh
@@ -0,0 +1,26 @@
+#!/bin/bash -e
+
+# To see logs after deploy run: $ HWCLOG=1 TESTDEV=<DEV> ./build_deploy.sh
+
+[ -z "$TESTDEV" ] && echo "Run $ TESTDEV=<Your lunch target> ./build_deploy.sh" && false
+
+cd ../..
+. build/envsetup.sh
+lunch $TESTDEV
+cd -
+
+mm
+
+adb root && adb remount && adb sync vendor
+
+adb shell stop
+adb shell stop vendor.hwcomposer-2-1 || true
+adb shell stop vendor.hwcomposer-2-2 || true
+adb shell stop vendor.hwcomposer-2-3 || true
+adb shell stop vendor.hwcomposer-2-4 || true
+
+[ $HWCLOG -eq "1" ] && adb logcat -c
+
+adb shell start
+
+[ $HWCLOG -eq "1" ] && adb logcat | grep -i hwc
diff --git a/compositor/DrmDisplayComposition.cpp b/compositor/DrmDisplayComposition.cpp
index cd95267..e571b26 100644
--- a/compositor/DrmDisplayComposition.cpp
+++ b/compositor/DrmDisplayComposition.cpp
@@ -32,9 +32,9 @@
 
 namespace android {
 
-DrmDisplayComposition::DrmDisplayComposition(DrmCrtc *crtc, Planner *planner)
-    : crtc_(crtc),  // Can be NULL if we haven't modeset yet
-      planner_(planner) {
+DrmDisplayComposition::DrmDisplayComposition(DrmCrtc *crtc)
+    : crtc_(crtc)  // Can be NULL if we haven't modeset yet
+{
 }
 
 int DrmDisplayComposition::SetLayers(DrmHwcLayer *layers, size_t num_layers) {
@@ -45,11 +45,6 @@
   return 0;
 }
 
-int DrmDisplayComposition::AddPlaneDisable(DrmPlane *plane) {
-  composition_planes_.emplace_back(DrmCompositionPlane::Type::kDisable, plane);
-  return 0;
-}
-
 int DrmDisplayComposition::AddPlaneComposition(DrmCompositionPlane plane) {
   composition_planes_.emplace_back(std::move(plane));
   return 0;
@@ -63,10 +58,10 @@
     to_composite.emplace(std::make_pair(i, &layers_[i]));
 
   int ret = 0;
-  std::tie(ret,
-           composition_planes_) = planner_->ProvisionPlanes(to_composite, crtc_,
-                                                            primary_planes,
-                                                            overlay_planes);
+  std::tie(ret, composition_planes_) = Planner::ProvisionPlanes(to_composite,
+                                                                crtc_,
+                                                                primary_planes,
+                                                                overlay_planes);
   if (ret) {
     ALOGV("Planner failed provisioning planes ret=%d", ret);
     return ret;
@@ -78,11 +73,8 @@
     if (!i.plane())
       continue;
 
-    // make sure that source layers are ordered based on zorder
-    std::sort(i.source_layers().begin(), i.source_layers().end());
-
     std::vector<DrmPlane *> *container = nullptr;
-    if (i.plane()->type() == DRM_PLANE_TYPE_PRIMARY)
+    if (i.plane()->GetType() == DRM_PLANE_TYPE_PRIMARY)
       container = primary_planes;
     else
       container = overlay_planes;
diff --git a/compositor/DrmDisplayComposition.h b/compositor/DrmDisplayComposition.h
index f1958d7..dcfd96e 100644
--- a/compositor/DrmDisplayComposition.h
+++ b/compositor/DrmDisplayComposition.h
@@ -30,58 +30,39 @@
 namespace android {
 
 class Importer;
-class Planner;
+
+constexpr size_t kUndefinedSourceLayer = UINT16_MAX;
 
 class DrmCompositionPlane {
  public:
-  enum class Type : int32_t {
-    kDisable,
-    kLayer,
-  };
-
   DrmCompositionPlane() = default;
   DrmCompositionPlane(DrmCompositionPlane &&rhs) = default;
   DrmCompositionPlane &operator=(DrmCompositionPlane &&other) = default;
-  DrmCompositionPlane(Type type, DrmPlane *plane) : type_(type), plane_(plane) {
-  }
-  DrmCompositionPlane(Type type, DrmPlane *plane, size_t source_layer)
-      : type_(type), plane_(plane), source_layers_(1, source_layer) {
-  }
-
-  Type type() const {
-    return type_;
+  DrmCompositionPlane(DrmPlane *plane, size_t source_layer)
+      : plane_(plane), source_layer_(source_layer) {
   }
 
   DrmPlane *plane() const {
     return plane_;
   }
-  void set_plane(DrmPlane *plane) {
-    plane_ = plane;
-  }
 
-  std::vector<size_t> &source_layers() {
-    return source_layers_;
-  }
-
-  const std::vector<size_t> &source_layers() const {
-    return source_layers_;
+  size_t source_layer() const {
+    return source_layer_;
   }
 
  private:
-  Type type_ = Type::kDisable;
-  DrmPlane *plane_ = NULL;
-  std::vector<size_t> source_layers_;
+  DrmPlane *plane_ = nullptr;
+  size_t source_layer_ = kUndefinedSourceLayer;
 };
 
 class DrmDisplayComposition {
  public:
   DrmDisplayComposition(const DrmDisplayComposition &) = delete;
-  DrmDisplayComposition(DrmCrtc *crtc, Planner *planner);
+  explicit DrmDisplayComposition(DrmCrtc *crtc);
   ~DrmDisplayComposition() = default;
 
   int SetLayers(DrmHwcLayer *layers, size_t num_layers);
   int AddPlaneComposition(DrmCompositionPlane plane);
-  int AddPlaneDisable(DrmPlane *plane);
 
   int Plan(std::vector<DrmPlane *> *primary_planes,
            std::vector<DrmPlane *> *overlay_planes);
@@ -98,13 +79,8 @@
     return crtc_;
   }
 
-  Planner *planner() const {
-    return planner_;
-  }
-
  private:
-  DrmCrtc *crtc_ = NULL;
-  Planner *planner_ = NULL;
+  DrmCrtc *crtc_ = nullptr;
 
   std::vector<DrmHwcLayer> layers_;
   std::vector<DrmCompositionPlane> composition_planes_;
diff --git a/compositor/DrmDisplayCompositor.cpp b/compositor/DrmDisplayCompositor.cpp
index 447d75e..c2e51ee 100644
--- a/compositor/DrmDisplayCompositor.cpp
+++ b/compositor/DrmDisplayCompositor.cpp
@@ -35,7 +35,6 @@
 #include "drm/DrmDevice.h"
 #include "drm/DrmPlane.h"
 #include "drm/DrmUnique.h"
-#include "utils/autolock.h"
 #include "utils/log.h"
 
 namespace android {
@@ -49,28 +48,16 @@
     ALOGE("Could not find drmdevice for display");
     return -EINVAL;
   }
-  planner_ = Planner::CreateInstance(drm);
 
   initialized_ = true;
   return 0;
 }
 
-std::unique_ptr<DrmDisplayComposition>
-DrmDisplayCompositor::CreateInitializedComposition() const {
-  DrmDevice *drm = resource_manager_->GetDrmDevice(display_);
-  DrmCrtc *crtc = drm->GetCrtcForDisplay(display_);
-  if (!crtc) {
-    ALOGE("Failed to find crtc for display = %d", display_);
-    return std::unique_ptr<DrmDisplayComposition>();
-  }
-
-  return std::make_unique<DrmDisplayComposition>(crtc, planner_.get());
-}
-
+// NOLINTNEXTLINE (readability-function-cognitive-complexity): Fixme
 auto DrmDisplayCompositor::CommitFrame(AtomicCommitArgs &args) -> int {
   ATRACE_CALL();
 
-  if (args.active && *args.active == active_kms_data.active_state) {
+  if (args.active && *args.active == active_frame_state_.crtc_active_state) {
     /* Don't set the same state twice */
     args.active.reset();
   }
@@ -80,7 +67,7 @@
     return 0;
   }
 
-  if (!active_kms_data.active_state) {
+  if (!active_frame_state_.crtc_active_state) {
     /* Force activate display */
     args.active = true;
   }
@@ -90,6 +77,8 @@
     return -EINVAL;
   }
 
+  auto new_frame_state = NewFrameState();
+
   DrmDevice *drm = resource_manager_->GetDrmDevice(display_);
 
   DrmConnector *connector = drm->GetConnectorForDisplay(display_);
@@ -115,9 +104,8 @@
     return -EINVAL;
   }
 
-  DrmModeUserPropertyBlobUnique mode_blob;
-
   if (args.active) {
+    new_frame_state.crtc_active_state = *args.active;
     if (!crtc->active_property().AtomicSet(*pset, *args.active) ||
         !connector->crtc_id_property().AtomicSet(*pset, crtc->id())) {
       return -EINVAL;
@@ -125,58 +113,61 @@
   }
 
   if (args.display_mode) {
-    mode_blob = args.display_mode.value().CreateModeBlob(
+    new_frame_state.mode_blob = args.display_mode.value().CreateModeBlob(
         *resource_manager_->GetDrmDevice(display_));
 
-    if (!mode_blob) {
+    if (!new_frame_state.mode_blob) {
       ALOGE("Failed to create mode_blob");
       return -EINVAL;
     }
 
-    if (!crtc->mode_property().AtomicSet(*pset, *mode_blob)) {
+    if (!crtc->mode_property().AtomicSet(*pset, *new_frame_state.mode_blob)) {
       return -EINVAL;
     }
   }
 
+  auto unused_planes = new_frame_state.used_planes;
+
   if (args.composition) {
+    new_frame_state.used_framebuffers.clear();
+    new_frame_state.used_planes.clear();
+
     std::vector<DrmHwcLayer> &layers = args.composition->layers();
     std::vector<DrmCompositionPlane> &comp_planes = args.composition
                                                         ->composition_planes();
 
     for (DrmCompositionPlane &comp_plane : comp_planes) {
       DrmPlane *plane = comp_plane.plane();
-      std::vector<size_t> &source_layers = comp_plane.source_layers();
+      size_t source_layer = comp_plane.source_layer();
 
-      if (comp_plane.type() != DrmCompositionPlane::Type::kDisable) {
-        if (source_layers.size() > 1) {
-          ALOGE("Can't handle more than one source layer sz=%zu type=%d",
-                source_layers.size(), comp_plane.type());
-          continue;
-        }
+      if (source_layer >= layers.size()) {
+        ALOGE("Source layer index %zu out of bounds %zu", source_layer,
+              layers.size());
+        return -EINVAL;
+      }
+      DrmHwcLayer &layer = layers[source_layer];
 
-        if (source_layers.empty() || source_layers.front() >= layers.size()) {
-          ALOGE("Source layer index %zu out of bounds %zu type=%d",
-                source_layers.front(), layers.size(), comp_plane.type());
-          return -EINVAL;
-        }
-        DrmHwcLayer &layer = layers[source_layers.front()];
+      new_frame_state.used_framebuffers.emplace_back(layer.fb_id_handle);
+      new_frame_state.used_planes.emplace_back(plane);
 
-        if (plane->AtomicSetState(*pset, layer, source_layers.front(),
-                                  crtc->id()) != 0) {
-          return -EINVAL;
-        }
-      } else {
-        if (plane->AtomicDisablePlane(*pset) != 0) {
-          return -EINVAL;
-        }
+      /* Remove from 'unused' list, since plane is re-used */
+      auto &v = unused_planes;
+      v.erase(std::remove(v.begin(), v.end(), plane), v.end());
+
+      if (plane->AtomicSetState(*pset, layer, source_layer, crtc->id()) != 0) {
+        return -EINVAL;
       }
     }
   }
 
-  if (args.clear_active_composition && active_kms_data.composition) {
-    auto &comp_planes = active_kms_data.composition->composition_planes();
-    for (auto &comp_plane : comp_planes) {
-      if (comp_plane.plane()->AtomicDisablePlane(*pset) != 0) {
+  if (args.clear_active_composition) {
+    new_frame_state.used_framebuffers.clear();
+    new_frame_state.used_planes.clear();
+  }
+
+  if (args.clear_active_composition || args.composition) {
+    for (auto *plane : unused_planes) {
+      if (plane->AtomicDisablePlane(*pset) != 0) {
         return -EINVAL;
       }
     }
@@ -195,21 +186,12 @@
 
   if (!args.test_only) {
     if (args.display_mode) {
+      /* TODO(nobody): we still need this for synthetic vsync, remove after
+       * vsync reworked */
       connector->set_active_mode(*args.display_mode);
-      active_kms_data.mode_blob = std::move(mode_blob);
     }
 
-    if (args.clear_active_composition) {
-      active_kms_data.composition.reset();
-    }
-
-    if (args.composition) {
-      active_kms_data.composition = args.composition;
-    }
-
-    if (args.active) {
-      active_kms_data.active_state = *args.active;
-    }
+    active_frame_state_ = std::move(new_frame_state);
 
     if (crtc->out_fence_ptr_property()) {
       args.out_fence = UniqueFd((int)out_fence);
@@ -238,4 +220,20 @@
   return err;
 }  // namespace android
 
+auto DrmDisplayCompositor::ActivateDisplayUsingDPMS() -> int {
+  auto *drm = resource_manager_->GetDrmDevice(display_);
+  auto *connector = drm->GetConnectorForDisplay(display_);
+  if (connector == nullptr) {
+    ALOGE("Could not locate connector for display %d", display_);
+    return -ENODEV;
+  }
+
+  if (connector->dpms_property()) {
+    drmModeConnectorSetProperty(drm->fd(), connector->id(),
+                                connector->dpms_property().id(),
+                                DRM_MODE_DPMS_ON);
+  }
+  return 0;
+}
+
 }  // namespace android
diff --git a/compositor/DrmDisplayCompositor.h b/compositor/DrmDisplayCompositor.h
index 55fe77d..9679520 100644
--- a/compositor/DrmDisplayCompositor.h
+++ b/compositor/DrmDisplayCompositor.h
@@ -23,11 +23,11 @@
 
 #include <functional>
 #include <memory>
+#include <optional>
 #include <sstream>
 #include <tuple>
 
 #include "DrmDisplayComposition.h"
-#include "Planner.h"
 #include "drm/ResourceManager.h"
 #include "drm/VSyncWorker.h"
 #include "drmhwcomposer.h"
@@ -58,23 +58,37 @@
   ~DrmDisplayCompositor() = default;
   auto Init(ResourceManager *resource_manager, int display) -> int;
 
-  std::unique_ptr<DrmDisplayComposition> CreateInitializedComposition() const;
-
   auto ExecuteAtomicCommit(AtomicCommitArgs &args) -> int;
 
- private:
   DrmDisplayCompositor(const DrmDisplayCompositor &) = delete;
 
+  auto ActivateDisplayUsingDPMS() -> int;
+
+ private:
   auto CommitFrame(AtomicCommitArgs &args) -> int;
 
-  struct {
-    std::shared_ptr<DrmDisplayComposition> composition;
+  struct KmsState {
+    /* Required to cleanup unused planes */
+    std::vector<DrmPlane *> used_planes;
+    /* We have to hold a reference to framebuffer while displaying it ,
+     * otherwise picture will blink */
+    std::vector<std::shared_ptr<DrmFbIdHandle>> used_framebuffers;
+
     DrmModeUserPropertyBlobUnique mode_blob;
-    bool active_state{};
-  } active_kms_data;
+
+    /* To avoid setting the inactive state twice, which will fail the commit */
+    bool crtc_active_state{};
+  } active_frame_state_;
+
+  auto NewFrameState() -> KmsState {
+    return (KmsState){
+        .used_planes = active_frame_state_.used_planes,
+        .used_framebuffers = active_frame_state_.used_framebuffers,
+        .crtc_active_state = active_frame_state_.crtc_active_state,
+    };
+  }
 
   ResourceManager *resource_manager_ = nullptr;
-  std::unique_ptr<Planner> planner_;
   bool initialized_{};
   int display_ = -1;
 };
diff --git a/compositor/Planner.cpp b/compositor/Planner.cpp
index 9db03c3..f43e314 100644
--- a/compositor/Planner.cpp
+++ b/compositor/Planner.cpp
@@ -25,12 +25,6 @@
 
 namespace android {
 
-std::unique_ptr<Planner> Planner::CreateInstance(DrmDevice * /*device*/) {
-  std::unique_ptr<Planner> planner(new Planner);
-  planner->AddStage<PlanStageGreedy>();
-  return planner;
-}
-
 std::vector<DrmPlane *> Planner::GetUsablePlanes(
     DrmCrtc *crtc, std::vector<DrmPlane *> *primary_planes,
     std::vector<DrmPlane *> *overlay_planes) {
@@ -57,54 +51,26 @@
   }
 
   // Go through the provisioning stages and provision planes
-  for (auto &i : stages_) {
-    int ret = i->ProvisionPlanes(&composition, layers, &planes);
-    if (ret) {
-      ALOGV("Failed provision stage with ret %d", ret);
-      return std::make_tuple(ret, std::vector<DrmCompositionPlane>());
-    }
+  int ret = ProvisionPlanesInternal(&composition, layers, &planes);
+  if (ret != 0) {
+    ALOGV("Failed provision stage with ret %d", ret);
+    return std::make_tuple(ret, std::vector<DrmCompositionPlane>());
   }
 
   return std::make_tuple(0, std::move(composition));
 }
 
-int PlanStageProtected::ProvisionPlanes(
+int Planner::ProvisionPlanesInternal(
     std::vector<DrmCompositionPlane> *composition,
-    std::map<size_t, DrmHwcLayer *> &layers,
-    std::vector<DrmPlane *> *planes) {
-  int ret = 0;
-  for (auto i = layers.begin(); i != layers.end();) {
-    if (!i->second->protected_usage()) {
-      ++i;
-      continue;
-    }
-
-    ret = Emplace(composition, planes, DrmCompositionPlane::Type::kLayer,
-                  std::make_pair(i->first, i->second));
-    if (ret) {
-      ALOGE("Failed to dedicate protected layer! Dropping it.");
-      return ret;
-    }
-
-    i = layers.erase(i);
-  }
-
-  return 0;
-}
-
-int PlanStageGreedy::ProvisionPlanes(
-    std::vector<DrmCompositionPlane> *composition,
-    std::map<size_t, DrmHwcLayer *> &layers,
-    std::vector<DrmPlane *> *planes) {
+    std::map<size_t, DrmHwcLayer *> &layers, std::vector<DrmPlane *> *planes) {
   // Fill up the remaining planes
   for (auto i = layers.begin(); i != layers.end(); i = layers.erase(i)) {
-    int ret = Emplace(composition, planes, DrmCompositionPlane::Type::kLayer,
-                      std::make_pair(i->first, i->second));
+    int ret = Emplace(composition, planes, std::make_pair(i->first, i->second));
     // We don't have any planes left
     if (ret == -ENOENT)
       break;
 
-    if (ret) {
+    if (ret != 0) {
       ALOGV("Failed to emplace layer %zu, dropping it", i->first);
       return ret;
     }
diff --git a/compositor/Planner.h b/compositor/Planner.h
index 3390acb..7802d0c 100644
--- a/compositor/Planner.h
+++ b/compositor/Planner.h
@@ -32,56 +32,46 @@
 class DrmDevice;
 
 class Planner {
+ private:
+  // Removes and returns the next available plane from planes
+  static DrmPlane *PopPlane(std::vector<DrmPlane *> *planes) {
+    if (planes->empty())
+      return nullptr;
+    DrmPlane *plane = planes->front();
+    planes->erase(planes->begin());
+    return plane;
+  }
+
+  // Inserts the given layer:plane in the composition at the back
+  static int Emplace(std::vector<DrmCompositionPlane> *composition,
+                     std::vector<DrmPlane *> *planes,
+                     std::pair<size_t, DrmHwcLayer *> layer) {
+    DrmPlane *plane = PopPlane(planes);
+    std::vector<DrmPlane *> unused_planes;
+    int ret = -ENOENT;
+    while (plane != nullptr) {
+      ret = plane->IsValidForLayer(layer.second) ? 0 : -EINVAL;
+      if (ret == 0)
+        break;
+      if (!plane->GetZPosProperty().is_immutable())
+        unused_planes.push_back(plane);
+      plane = PopPlane(planes);
+    }
+
+    if (ret == 0) {
+      composition->emplace_back(plane, layer.first);
+      planes->insert(planes->begin(), unused_planes.begin(),
+                     unused_planes.end());
+    }
+
+    return ret;
+  }
+
+  static int ProvisionPlanesInternal(
+      std::vector<DrmCompositionPlane> *composition,
+      std::map<size_t, DrmHwcLayer *> &layers, std::vector<DrmPlane *> *planes);
+
  public:
-  class PlanStage {
-   public:
-    virtual ~PlanStage() {
-    }
-
-    virtual int ProvisionPlanes(std::vector<DrmCompositionPlane> *composition,
-                                std::map<size_t, DrmHwcLayer *> &layers,
-                                std::vector<DrmPlane *> *planes) = 0;
-
-   protected:
-    // Removes and returns the next available plane from planes
-    static DrmPlane *PopPlane(std::vector<DrmPlane *> *planes) {
-      if (planes->empty())
-        return NULL;
-      DrmPlane *plane = planes->front();
-      planes->erase(planes->begin());
-      return plane;
-    }
-
-    // Inserts the given layer:plane in the composition at the back
-    static int Emplace(std::vector<DrmCompositionPlane> *composition,
-                       std::vector<DrmPlane *> *planes,
-                       DrmCompositionPlane::Type type,
-                       std::pair<size_t, DrmHwcLayer *> layer) {
-      DrmPlane *plane = PopPlane(planes);
-      std::vector<DrmPlane *> unused_planes;
-      int ret = -ENOENT;
-      while (plane) {
-        ret = plane->IsValidForLayer(layer.second) ? 0 : -EINVAL;
-        if (!ret)
-          break;
-        if (!plane->zpos_property().is_immutable())
-          unused_planes.push_back(plane);
-        plane = PopPlane(planes);
-      }
-
-      if (!ret) {
-        composition->emplace_back(type, plane, layer.first);
-        planes->insert(planes->begin(), unused_planes.begin(),
-                       unused_planes.end());
-      }
-
-      return ret;
-    }
-  };
-
-  // Creates a planner instance with platform-specific planning stages
-  static std::unique_ptr<Planner> CreateInstance(DrmDevice *drm);
-
   // Takes a stack of layers and provisions hardware planes for them. If the
   // entire stack can't fit in hardware, FIXME
   //
@@ -91,42 +81,15 @@
   //
   // Returns: A tuple with the status of the operation (0 for success) and
   //          a vector of the resulting plan (ie: layer->plane mapping).
-  std::tuple<int, std::vector<DrmCompositionPlane>> ProvisionPlanes(
+  static std::tuple<int, std::vector<DrmCompositionPlane>> ProvisionPlanes(
       std::map<size_t, DrmHwcLayer *> &layers, DrmCrtc *crtc,
       std::vector<DrmPlane *> *primary_planes,
       std::vector<DrmPlane *> *overlay_planes);
 
-  template <typename T, typename... A>
-  void AddStage(A &&...args) {
-    stages_.emplace_back(
-        std::unique_ptr<PlanStage>(new T(std::forward(args)...)));
-  }
-
  private:
-  std::vector<DrmPlane *> GetUsablePlanes(
+  static std::vector<DrmPlane *> GetUsablePlanes(
       DrmCrtc *crtc, std::vector<DrmPlane *> *primary_planes,
       std::vector<DrmPlane *> *overlay_planes);
-
-  std::vector<std::unique_ptr<PlanStage>> stages_;
-};
-
-// This plan stage extracts all protected layers and places them on dedicated
-// planes.
-class PlanStageProtected : public Planner::PlanStage {
- public:
-  int ProvisionPlanes(std::vector<DrmCompositionPlane> *composition,
-                      std::map<size_t, DrmHwcLayer *> &layers,
-                      std::vector<DrmPlane *> *planes);
-};
-
-// This plan stage places as many layers on dedicated planes as possible (first
-// come first serve), and then sticks the rest in a precomposition plane (if
-// needed).
-class PlanStageGreedy : public Planner::PlanStage {
- public:
-  int ProvisionPlanes(std::vector<DrmCompositionPlane> *composition,
-                      std::map<size_t, DrmHwcLayer *> &layers,
-                      std::vector<DrmPlane *> *planes);
 };
 }  // namespace android
 #endif
diff --git a/drm/DrmConnector.cpp b/drm/DrmConnector.cpp
index 5b3c697..7cbec95 100644
--- a/drm/DrmConnector.cpp
+++ b/drm/DrmConnector.cpp
@@ -28,9 +28,17 @@
 #include "DrmDevice.h"
 #include "utils/log.h"
 
+#ifndef DRM_MODE_CONNECTOR_SPI
+#define DRM_MODE_CONNECTOR_SPI 19
+#endif
+
+#ifndef DRM_MODE_CONNECTOR_USB
+#define DRM_MODE_CONNECTOR_USB 20
+#endif
+
 namespace android {
 
-constexpr size_t kTypesCount = 17;
+constexpr size_t kTypesCount = 21;
 
 DrmConnector::DrmConnector(DrmDevice *drm, drmModeConnectorPtr c,
                            DrmEncoder *current_encoder,
@@ -94,12 +102,12 @@
   uint64_t blob_id = 0;
   int ret = UpdateEdidProperty();
   if (ret != 0) {
-    return DrmModePropertyBlobUnique();
+    return {};
   }
 
   std::tie(ret, blob_id) = edid_property().value();
   if (ret != 0) {
-    return DrmModePropertyBlobUnique();
+    return {};
   }
 
   return MakeDrmModePropertyBlobUnique(drm_->fd(), blob_id);
@@ -120,14 +128,15 @@
 bool DrmConnector::internal() const {
   return type_ == DRM_MODE_CONNECTOR_LVDS || type_ == DRM_MODE_CONNECTOR_eDP ||
          type_ == DRM_MODE_CONNECTOR_DSI ||
-         type_ == DRM_MODE_CONNECTOR_VIRTUAL || type_ == DRM_MODE_CONNECTOR_DPI;
+         type_ == DRM_MODE_CONNECTOR_VIRTUAL ||
+         type_ == DRM_MODE_CONNECTOR_DPI || type_ == DRM_MODE_CONNECTOR_SPI;
 }
 
 bool DrmConnector::external() const {
   return type_ == DRM_MODE_CONNECTOR_HDMIA ||
          type_ == DRM_MODE_CONNECTOR_DisplayPort ||
          type_ == DRM_MODE_CONNECTOR_DVID || type_ == DRM_MODE_CONNECTOR_DVII ||
-         type_ == DRM_MODE_CONNECTOR_VGA;
+         type_ == DRM_MODE_CONNECTOR_VGA || type_ == DRM_MODE_CONNECTOR_USB;
 }
 
 bool DrmConnector::writeback() const {
@@ -144,9 +153,10 @@
 
 std::string DrmConnector::name() const {
   constexpr std::array<const char *, kTypesCount> kNames =
-      {"None",   "VGA",  "DVI-I",     "DVI-D",   "DVI-A", "Composite",
-       "SVIDEO", "LVDS", "Component", "DIN",     "DP",    "HDMI-A",
-       "HDMI-B", "TV",   "eDP",       "Virtual", "DSI"};
+      {"None",      "VGA",  "DVI-I",     "DVI-D",   "DVI-A", "Composite",
+       "SVIDEO",    "LVDS", "Component", "DIN",     "DP",    "HDMI-A",
+       "HDMI-B",    "TV",   "eDP",       "Virtual", "DSI",   "DPI",
+       "Writeback", "SPI",  "USB"};
 
   if (type_ < kTypesCount) {
     std::ostringstream name_buf;
@@ -165,6 +175,8 @@
     return -ENODEV;
   }
 
+  state_ = c->connection;
+
   modes_.clear();
   for (int i = 0; i < c->count_modes; ++i) {
     bool exists = false;
diff --git a/drm/DrmConnector.h b/drm/DrmConnector.h
index f2305aa..2bcb543 100644
--- a/drm/DrmConnector.h
+++ b/drm/DrmConnector.h
@@ -17,9 +17,9 @@
 #ifndef ANDROID_DRM_CONNECTOR_H_
 #define ANDROID_DRM_CONNECTOR_H_
 
-#include <stdint.h>
 #include <xf86drmMode.h>
 
+#include <cstdint>
 #include <string>
 #include <vector>
 
diff --git a/drm/DrmCrtc.cpp b/drm/DrmCrtc.cpp
index 4da08fe..08a1922 100644
--- a/drm/DrmCrtc.cpp
+++ b/drm/DrmCrtc.cpp
@@ -33,19 +33,19 @@
 
 int DrmCrtc::Init() {
   int ret = drm_->GetCrtcProperty(*this, "ACTIVE", &active_property_);
-  if (ret) {
+  if (ret != 0) {
     ALOGE("Failed to get ACTIVE property");
     return ret;
   }
 
   ret = drm_->GetCrtcProperty(*this, "MODE_ID", &mode_property_);
-  if (ret) {
+  if (ret != 0) {
     ALOGE("Failed to get MODE_ID property");
     return ret;
   }
 
   ret = drm_->GetCrtcProperty(*this, "OUT_FENCE_PTR", &out_fence_ptr_property_);
-  if (ret) {
+  if (ret != 0) {
     ALOGE("Failed to get OUT_FENCE_PTR property");
     return ret;
   }
diff --git a/drm/DrmCrtc.h b/drm/DrmCrtc.h
index 7972bef..85e067a 100644
--- a/drm/DrmCrtc.h
+++ b/drm/DrmCrtc.h
@@ -17,9 +17,10 @@
 #ifndef ANDROID_DRM_CRTC_H_
 #define ANDROID_DRM_CRTC_H_
 
-#include <stdint.h>
 #include <xf86drmMode.h>
 
+#include <cstdint>
+
 #include "DrmMode.h"
 #include "DrmProperty.h"
 
diff --git a/drm/DrmDevice.cpp b/drm/DrmDevice.cpp
index 0f5f581..8245b78 100644
--- a/drm/DrmDevice.cpp
+++ b/drm/DrmDevice.cpp
@@ -30,6 +30,7 @@
 #include <sstream>
 #include <string>
 
+#include "drm/DrmPlane.h"
 #include "utils/log.h"
 #include "utils/properties.h"
 
@@ -116,10 +117,12 @@
   mDrmFbImporter = std::make_unique<DrmFbImporter>(self);
 }
 
+// NOLINTNEXTLINE (readability-function-cognitive-complexity): Fixme
 std::tuple<int, int> DrmDevice::Init(const char *path, int num_displays) {
   /* TODO: Use drmOpenControl here instead */
   fd_ = UniqueFd(open(path, O_RDWR | O_CLOEXEC));
   if (fd() < 0) {
+    // NOLINTNEXTLINE(concurrency-mt-unsafe): Fixme
     ALOGE("Failed to open dri %s: %s", path, strerror(errno));
     return std::make_tuple(-ENODEV, 0);
   }
@@ -328,9 +331,6 @@
       ALOGE("Failed CreateDisplayPipe %d with %d", conn->id(), ret);
       return std::make_tuple(ret, 0);
     }
-    if (!AttachWriteback(conn.get())) {
-      ALOGI("Display %d has writeback attach to it", conn->display());
-    }
   }
   return std::make_tuple(ret, displays_.size());
 }
@@ -347,39 +347,6 @@
   return nullptr;
 }
 
-DrmConnector *DrmDevice::GetWritebackConnectorForDisplay(int display) const {
-  for (const auto &conn : writeback_connectors_) {
-    if (conn->display() == display)
-      return conn.get();
-  }
-  return nullptr;
-}
-
-// TODO(nobody): what happens when hotplugging
-DrmConnector *DrmDevice::AvailableWritebackConnector(int display) const {
-  DrmConnector *writeback_conn = GetWritebackConnectorForDisplay(display);
-  DrmConnector *display_conn = GetConnectorForDisplay(display);
-  // If we have a writeback already attached to the same CRTC just use that,
-  // if possible.
-  if (display_conn && writeback_conn &&
-      writeback_conn->encoder()->CanClone(display_conn->encoder()))
-    return writeback_conn;
-
-  // Use another CRTC if available and doesn't have any connector
-  for (const auto &crtc : crtcs_) {
-    if (crtc->display() == display)
-      continue;
-    display_conn = GetConnectorForDisplay(crtc->display());
-    // If we have a display connected don't use it for writeback
-    if (display_conn && display_conn->state() == DRM_MODE_CONNECTED)
-      continue;
-    writeback_conn = GetWritebackConnectorForDisplay(crtc->display());
-    if (writeback_conn)
-      return writeback_conn;
-  }
-  return nullptr;
-}
-
 DrmCrtc *DrmDevice::GetCrtcForDisplay(int display) const {
   for (const auto &crtc : crtcs_) {
     if (crtc->display() == display)
@@ -388,14 +355,6 @@
   return nullptr;
 }
 
-DrmPlane *DrmDevice::GetPlane(uint32_t id) const {
-  for (const auto &plane : planes_) {
-    if (plane->id() == id)
-      return plane.get();
-  }
-  return nullptr;
-}
-
 const std::vector<std::unique_ptr<DrmCrtc>> &DrmDevice::crtcs() const {
   return crtcs_;
 }
@@ -462,34 +421,6 @@
   return -ENODEV;
 }
 
-// Attach writeback connector to the CRTC linked to the display_conn
-int DrmDevice::AttachWriteback(DrmConnector *display_conn) {
-  DrmCrtc *display_crtc = display_conn->encoder()->crtc();
-  if (GetWritebackConnectorForDisplay(display_crtc->display()) != nullptr) {
-    ALOGE("Display already has writeback attach to it");
-    return -EINVAL;
-  }
-  for (auto &writeback_conn : writeback_connectors_) {
-    if (writeback_conn->display() >= 0)
-      continue;
-    for (DrmEncoder *writeback_enc : writeback_conn->possible_encoders()) {
-      for (DrmCrtc *possible_crtc : writeback_enc->possible_crtcs()) {
-        if (possible_crtc != display_crtc)
-          continue;
-        // Use just encoders which had not been bound already
-        if (writeback_enc->can_bind(display_crtc->display())) {
-          writeback_enc->set_crtc(display_crtc);
-          writeback_conn->set_encoder(writeback_enc);
-          writeback_conn->set_display(display_crtc->display());
-          writeback_conn->UpdateModes();
-          return 0;
-        }
-      }
-    }
-  }
-  return -EINVAL;
-}
-
 auto DrmDevice::RegisterUserPropertyBlob(void *data, size_t length) const
     -> DrmModeUserPropertyBlobUnique {
   struct drm_mode_create_blob create_blob {};
@@ -499,7 +430,7 @@
   int ret = drmIoctl(fd(), DRM_IOCTL_MODE_CREATEPROPBLOB, &create_blob);
   if (ret) {
     ALOGE("Failed to create mode property blob %d", ret);
-    return DrmModeUserPropertyBlobUnique();
+    return {};
   }
 
   return DrmModeUserPropertyBlobUnique(
diff --git a/drm/DrmDevice.h b/drm/DrmDevice.h
index c08c766..9983d61 100644
--- a/drm/DrmDevice.h
+++ b/drm/DrmDevice.h
@@ -17,8 +17,7 @@
 #ifndef ANDROID_DRM_H_
 #define ANDROID_DRM_H_
 
-#include <stdint.h>
-
+#include <cstdint>
 #include <map>
 #include <tuple>
 
@@ -26,7 +25,6 @@
 #include "DrmCrtc.h"
 #include "DrmEncoder.h"
 #include "DrmFbImporter.h"
-#include "DrmPlane.h"
 #include "utils/UniqueFd.h"
 
 namespace android {
@@ -62,10 +60,7 @@
   }
 
   DrmConnector *GetConnectorForDisplay(int display) const;
-  DrmConnector *GetWritebackConnectorForDisplay(int display) const;
-  DrmConnector *AvailableWritebackConnector(int display) const;
   DrmCrtc *GetCrtcForDisplay(int display) const;
-  DrmPlane *GetPlane(uint32_t id) const;
 
   int GetCrtcProperty(const DrmCrtc &crtc, const char *prop_name,
                       DrmProperty *property) const;
@@ -87,7 +82,7 @@
   }
 
   DrmFbImporter &GetDrmFbImporter() {
-    return *mDrmFbImporter.get();
+    return *mDrmFbImporter;
   }
 
   static auto IsKMSDev(const char *path) -> bool;
@@ -99,7 +94,6 @@
   int TryEncoderForDisplay(int display, DrmEncoder *enc);
 
   int CreateDisplayPipe(DrmConnector *connector);
-  int AttachWriteback(DrmConnector *display_conn);
 
   UniqueFd fd_;
   uint32_t mode_id_ = 0;
diff --git a/drm/DrmEncoder.h b/drm/DrmEncoder.h
index 4c01bc1..b130b7d 100644
--- a/drm/DrmEncoder.h
+++ b/drm/DrmEncoder.h
@@ -17,9 +17,9 @@
 #ifndef ANDROID_DRM_ENCODER_H_
 #define ANDROID_DRM_ENCODER_H_
 
-#include <stdint.h>
 #include <xf86drmMode.h>
 
+#include <cstdint>
 #include <set>
 #include <vector>
 
diff --git a/drm/DrmFbImporter.cpp b/drm/DrmFbImporter.cpp
index 25f32b7..6f2abe8 100644
--- a/drm/DrmFbImporter.cpp
+++ b/drm/DrmFbImporter.cpp
@@ -124,7 +124,7 @@
 
   if (err != 0) {
     ALOGE("Failed to import prime fd %d ret=%d", bo->prime_fds[0], err);
-    return std::shared_ptr<DrmFbIdHandle>();
+    return {};
   }
 
   auto drm_fb_id_cached = drm_fb_id_handle_cache_.find(first_handle);
diff --git a/drm/DrmFbImporter.h b/drm/DrmFbImporter.h
index 167aa60..efeb457 100644
--- a/drm/DrmFbImporter.h
+++ b/drm/DrmFbImporter.h
@@ -57,7 +57,7 @@
   const std::shared_ptr<DrmDevice> drm_;
 
   uint32_t fb_id_{};
-  std::array<GemHandle, HWC_DRM_BO_MAX_PLANES> gem_handles_{};
+  std::array<GemHandle, kHwcDrmBoMaxPlanes> gem_handles_{};
 };
 
 class DrmFbImporter {
diff --git a/drm/DrmMode.cpp b/drm/DrmMode.cpp
index 1c8bd0f..010ea1b 100644
--- a/drm/DrmMode.cpp
+++ b/drm/DrmMode.cpp
@@ -94,6 +94,9 @@
 }
 
 float DrmMode::v_refresh() const {
+  if (clock_ == 0) {
+    return v_refresh_;
+  }
   // Always recalculate refresh to report correct float rate
   return static_cast<float>(clock_) / (float)(v_total_ * h_total_) * 1000.0F;
 }
diff --git a/drm/DrmMode.h b/drm/DrmMode.h
index 41b9e15..20515f9 100644
--- a/drm/DrmMode.h
+++ b/drm/DrmMode.h
@@ -17,10 +17,10 @@
 #ifndef ANDROID_DRM_MODE_H_
 #define ANDROID_DRM_MODE_H_
 
-#include <stdio.h>
 #include <xf86drmMode.h>
 
 #include <cstdint>
+#include <cstdio>
 #include <string>
 
 #include "DrmUnique.h"
@@ -32,7 +32,7 @@
 class DrmMode {
  public:
   DrmMode() = default;
-  DrmMode(drmModeModeInfoPtr m);
+  explicit DrmMode(drmModeModeInfoPtr m);
 
   bool operator==(const drmModeModeInfo &m) const;
 
diff --git a/drm/DrmPlane.cpp b/drm/DrmPlane.cpp
index f6ddad2..25a4902 100644
--- a/drm/DrmPlane.cpp
+++ b/drm/DrmPlane.cpp
@@ -33,6 +33,7 @@
     : drm_(drm),
       id_(p->plane_id),
       possible_crtc_mask_(p->possible_crtcs),
+      // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
       formats_(p->formats, p->formats + p->count_formats) {
 }
 
@@ -46,7 +47,7 @@
   int ret = 0;
   uint64_t type = 0;
   std::tie(ret, type) = p.value();
-  if (ret) {
+  if (ret != 0) {
     ALOGE("Failed to get plane type property value");
     return ret;
   }
@@ -133,10 +134,6 @@
   return 0;
 }
 
-uint32_t DrmPlane::id() const {
-  return id_;
-}
-
 bool DrmPlane::GetCrtcSupported(const DrmCrtc &crtc) const {
   return ((1 << crtc.pipe()) & possible_crtc_mask_) != 0;
 }
@@ -154,7 +151,7 @@
     }
   }
 
-  if (alpha_property_.id() == 0 && layer->alpha != 0xffff) {
+  if (alpha_property_.id() == 0 && layer->alpha != UINT16_MAX) {
     ALOGV("Alpha is not supported on plane %d", id_);
     return false;
   }
@@ -176,7 +173,7 @@
   return true;
 }
 
-uint32_t DrmPlane::type() const {
+uint32_t DrmPlane::GetType() const {
   return type_;
 }
 
@@ -194,15 +191,15 @@
 
 static uint64_t ToDrmRotation(DrmHwcTransform transform) {
   uint64_t rotation = 0;
-  if (transform & DrmHwcTransform::kFlipH)
+  if ((transform & DrmHwcTransform::kFlipH) != 0)
     rotation |= DRM_MODE_REFLECT_X;
-  if (transform & DrmHwcTransform::kFlipV)
+  if ((transform & DrmHwcTransform::kFlipV) != 0)
     rotation |= DRM_MODE_REFLECT_Y;
-  if (transform & DrmHwcTransform::kRotate90)
+  if ((transform & DrmHwcTransform::kRotate90) != 0)
     rotation |= DRM_MODE_ROTATE_90;
-  else if (transform & DrmHwcTransform::kRotate180)
+  else if ((transform & DrmHwcTransform::kRotate180) != 0)
     rotation |= DRM_MODE_ROTATE_180;
-  else if (transform & DrmHwcTransform::kRotate270)
+  else if ((transform & DrmHwcTransform::kRotate270) != 0)
     rotation |= DRM_MODE_ROTATE_270;
   else
     rotation |= DRM_MODE_ROTATE_0;
@@ -210,9 +207,15 @@
   return rotation;
 }
 
+/* Convert float to 16.16 fixed point */
+static int To1616FixPt(float in) {
+  constexpr int kBitShift = 16;
+  return int(in * (1 << kBitShift));
+}
+
 auto DrmPlane::AtomicSetState(drmModeAtomicReq &pset, DrmHwcLayer &layer,
                               uint32_t zpos, uint32_t crtc_id) -> int {
-  if (!layer.FbIdHandle) {
+  if (!layer.fb_id_handle) {
     ALOGE("Expected a valid framebuffer for pset");
     return -EINVAL;
   }
@@ -234,21 +237,19 @@
   }
 
   if (!crtc_property_.AtomicSet(pset, crtc_id) ||
-      !fb_property_.AtomicSet(pset, layer.FbIdHandle->GetFbId()) ||
+      !fb_property_.AtomicSet(pset, layer.fb_id_handle->GetFbId()) ||
       !crtc_x_property_.AtomicSet(pset, layer.display_frame.left) ||
       !crtc_y_property_.AtomicSet(pset, layer.display_frame.top) ||
       !crtc_w_property_.AtomicSet(pset, layer.display_frame.right -
                                             layer.display_frame.left) ||
       !crtc_h_property_.AtomicSet(pset, layer.display_frame.bottom -
                                             layer.display_frame.top) ||
-      !src_x_property_.AtomicSet(pset, (int)(layer.source_crop.left) << 16) ||
-      !src_y_property_.AtomicSet(pset, (int)(layer.source_crop.top) << 16) ||
-      !src_w_property_.AtomicSet(pset, (int)(layer.source_crop.right -
-                                             layer.source_crop.left)
-                                           << 16) ||
-      !src_h_property_.AtomicSet(pset, (int)(layer.source_crop.bottom -
-                                             layer.source_crop.top)
-                                           << 16)) {
+      !src_x_property_.AtomicSet(pset, To1616FixPt(layer.source_crop.left)) ||
+      !src_y_property_.AtomicSet(pset, To1616FixPt(layer.source_crop.top)) ||
+      !src_w_property_.AtomicSet(pset, To1616FixPt(layer.source_crop.right -
+                                                   layer.source_crop.left)) ||
+      !src_h_property_.AtomicSet(pset, To1616FixPt(layer.source_crop.bottom -
+                                                   layer.source_crop.top))) {
     return -EINVAL;
   }
 
@@ -289,7 +290,7 @@
   return 0;
 }
 
-const DrmProperty &DrmPlane::zpos_property() const {
+const DrmProperty &DrmPlane::GetZPosProperty() const {
   return zpos_property_;
 }
 
diff --git a/drm/DrmPlane.h b/drm/DrmPlane.h
index 34bba56..e1ee920 100644
--- a/drm/DrmPlane.h
+++ b/drm/DrmPlane.h
@@ -17,9 +17,9 @@
 #ifndef ANDROID_DRM_PLANE_H_
 #define ANDROID_DRM_PLANE_H_
 
-#include <stdint.h>
 #include <xf86drmMode.h>
 
+#include <cstdint>
 #include <vector>
 
 #include "DrmCrtc.h"
@@ -29,6 +29,7 @@
 namespace android {
 
 class DrmDevice;
+struct DrmHwcLayer;
 
 class DrmPlane {
  public:
@@ -38,12 +39,10 @@
 
   int Init();
 
-  uint32_t id() const;
-
   bool GetCrtcSupported(const DrmCrtc &crtc) const;
   bool IsValidForLayer(DrmHwcLayer *layer);
 
-  uint32_t type() const;
+  uint32_t GetType() const;
 
   bool IsFormatSupported(uint32_t format) const;
   bool HasNonRgbFormat() const;
@@ -51,7 +50,7 @@
   auto AtomicSetState(drmModeAtomicReq &pset, DrmHwcLayer &layer, uint32_t zpos,
                       uint32_t crtc_id) -> int;
   auto AtomicDisablePlane(drmModeAtomicReq &pset) -> int;
-  const DrmProperty &zpos_property() const;
+  const DrmProperty &GetZPosProperty() const;
 
  private:
   DrmDevice *drm_;
diff --git a/drm/DrmProperty.h b/drm/DrmProperty.h
index 68f300f..26a7c38 100644
--- a/drm/DrmProperty.h
+++ b/drm/DrmProperty.h
@@ -17,9 +17,9 @@
 #ifndef ANDROID_DRM_PROPERTY_H_
 #define ANDROID_DRM_PROPERTY_H_
 
-#include <stdint.h>
 #include <xf86drmMode.h>
 
+#include <cstdint>
 #include <map>
 #include <string>
 #include <vector>
@@ -62,14 +62,14 @@
   auto AddEnumToMap(const std::string &name, E key, std::map<E, uint64_t> &map)
       -> bool;
 
-  operator bool() const {
+  explicit operator bool() const {
     return id_ != 0;
   }
 
  private:
   class DrmPropertyEnum {
    public:
-    DrmPropertyEnum(drm_mode_property_enum *e);
+    explicit DrmPropertyEnum(drm_mode_property_enum *e);
     ~DrmPropertyEnum() = default;
 
     uint64_t value_;
diff --git a/drm/ResourceManager.cpp b/drm/ResourceManager.cpp
index 8baa4cb..46f77e4 100644
--- a/drm/ResourceManager.cpp
+++ b/drm/ResourceManager.cpp
@@ -24,6 +24,8 @@
 #include <sstream>
 
 #include "bufferinfo/BufferInfoGetter.h"
+#include "drm/DrmDevice.h"
+#include "drm/DrmPlane.h"
 #include "utils/log.h"
 #include "utils/properties.h"
 
@@ -32,6 +34,10 @@
 ResourceManager::ResourceManager() : num_displays_(0) {
 }
 
+ResourceManager::~ResourceManager() {
+  uevent_listener_.Exit();
+}
+
 int ResourceManager::Init() {
   char path_pattern[PROPERTY_VALUE_MAX];
   // Could be a valid path or it can have at the end of it the wildcard %
@@ -43,12 +49,12 @@
     ret = AddDrmDevice(std::string(path_pattern));
   } else {
     path_pattern[path_len - 1] = '\0';
-    for (int idx = 0; !ret; ++idx) {
+    for (int idx = 0; ret == 0; ++idx) {
       std::ostringstream path;
       path << path_pattern << idx;
 
       struct stat buf {};
-      if (stat(path.str().c_str(), &buf))
+      if (stat(path.str().c_str(), &buf) != 0)
         break;
 
       if (DrmDevice::IsKMSDev(path.str().c_str()))
@@ -56,22 +62,22 @@
     }
   }
 
-  if (!num_displays_) {
+  if (num_displays_ == 0) {
     ALOGE("Failed to initialize any displays");
-    return ret ? -EINVAL : ret;
+    return ret != 0 ? -EINVAL : ret;
   }
 
   char scale_with_gpu[PROPERTY_VALUE_MAX];
   property_get("vendor.hwc.drm.scale_with_gpu", scale_with_gpu, "0");
   scale_with_gpu_ = bool(strncmp(scale_with_gpu, "0", 1));
 
-  if (!BufferInfoGetter::GetInstance()) {
+  if (BufferInfoGetter::GetInstance() == nullptr) {
     ALOGE("Failed to initialize BufferInfoGetter");
     return -EINVAL;
   }
 
   ret = uevent_listener_.Init();
-  if (ret) {
+  if (ret != 0) {
     ALOGE("Can't initialize event listener %d", ret);
     return ret;
   }
diff --git a/drm/ResourceManager.h b/drm/ResourceManager.h
index 5ffe92c..f54d682 100644
--- a/drm/ResourceManager.h
+++ b/drm/ResourceManager.h
@@ -17,11 +17,11 @@
 #ifndef RESOURCEMANAGER_H
 #define RESOURCEMANAGER_H
 
-#include <string.h>
+#include <cstring>
 
 #include "DrmDevice.h"
-#include "UEventListener.h"
 #include "DrmFbImporter.h"
+#include "UEventListener.h"
 
 namespace android {
 
@@ -30,19 +30,17 @@
   ResourceManager();
   ResourceManager(const ResourceManager &) = delete;
   ResourceManager &operator=(const ResourceManager &) = delete;
-  ~ResourceManager() {
-    uevent_listener_.Exit();
-  }
+  ~ResourceManager();
 
   int Init();
   DrmDevice *GetDrmDevice(int display);
-  const std::vector<std::unique_ptr<DrmDevice>> &getDrmDevices() const {
+  const std::vector<std::unique_ptr<DrmDevice>> &GetDrmDevices() const {
     return drms_;
   }
-  int getDisplayCount() const {
+  int GetDisplayCount() const {
     return num_displays_;
   }
-  bool ForcedScalingWithGpu() {
+  bool ForcedScalingWithGpu() const {
     return scale_with_gpu_;
   }
 
@@ -50,6 +48,10 @@
     return &uevent_listener_;
   }
 
+  auto &GetMainLock() {
+    return main_lock_;
+  }
+
  private:
   int AddDrmDevice(std::string const &path);
 
@@ -59,6 +61,8 @@
   bool scale_with_gpu_{};
 
   UEventListener uevent_listener_;
+
+  std::mutex main_lock_;
 };
 }  // namespace android
 
diff --git a/drm/UEventListener.cpp b/drm/UEventListener.cpp
index eae0608..44c503d 100644
--- a/drm/UEventListener.cpp
+++ b/drm/UEventListener.cpp
@@ -40,6 +40,7 @@
   uevent_fd_ = UniqueFd(
       socket(PF_NETLINK, SOCK_DGRAM | SOCK_CLOEXEC, NETLINK_KOBJECT_UEVENT));
   if (!uevent_fd_) {
+    // NOLINTNEXTLINE(concurrency-mt-unsafe): Fixme
     ALOGE("Failed to open uevent socket: %s", strerror(errno));
     return -errno;
   }
@@ -51,6 +52,7 @@
 
   int ret = bind(uevent_fd_.Get(), (struct sockaddr *)&addr, sizeof(addr));
   if (ret) {
+    // NOLINTNEXTLINE(concurrency-mt-unsafe): Fixme
     ALOGE("Failed to bind uevent socket: %s", strerror(errno));
     return -errno;
   }
@@ -88,6 +90,10 @@
     }
 
     if (drm_event && hotplug_event && hotplug_handler_) {
+      constexpr useconds_t delay_after_uevent_us = 200000;
+      /* We need some delay to ensure DrmConnector::UpdateModes() will query
+       * correct modes list, otherwise at least RPI4 board may report 0 modes */
+      usleep(delay_after_uevent_us);
       hotplug_handler_();
     }
   }
diff --git a/drm/UEventListener.h b/drm/UEventListener.h
index 048eb40..0724443 100644
--- a/drm/UEventListener.h
+++ b/drm/UEventListener.h
@@ -27,16 +27,16 @@
 class UEventListener : public Worker {
  public:
   UEventListener();
-  virtual ~UEventListener() = default;
+  ~UEventListener() override = default;
 
   int Init();
 
   void RegisterHotplugHandler(std::function<void()> hotplug_handler) {
-    hotplug_handler_ = hotplug_handler;
+    hotplug_handler_ = std::move(hotplug_handler);
   }
 
  protected:
-  virtual void Routine();
+  void Routine() override;
 
  private:
   UniqueFd uevent_fd_;
diff --git a/drm/VSyncWorker.cpp b/drm/VSyncWorker.cpp
index 6e92838..8d1cb99 100644
--- a/drm/VSyncWorker.cpp
+++ b/drm/VSyncWorker.cpp
@@ -77,7 +77,7 @@
          last_timestamp_;
 }
 
-static const int64_t kOneSecondNs = 1 * 1000 * 1000 * 1000;
+static const int64_t kOneSecondNs = 1LL * 1000 * 1000 * 1000;
 
 int VSyncWorker::SyntheticWaitVBlank(int64_t *timestamp) {
   struct timespec vsync {};
diff --git a/drm/VSyncWorker.h b/drm/VSyncWorker.h
index 74ff487..67aaa16 100644
--- a/drm/VSyncWorker.h
+++ b/drm/VSyncWorker.h
@@ -20,9 +20,9 @@
 #include <hardware/hardware.h>
 #include <hardware/hwcomposer.h>
 #include <hardware/hwcomposer2.h>
-#include <stdint.h>
 
 #include <atomic>
+#include <cstdint>
 #include <functional>
 #include <map>
 
diff --git a/hwc2_device/DrmHwcTwo.cpp b/hwc2_device/DrmHwcTwo.cpp
new file mode 100644
index 0000000..a2a093f
--- /dev/null
+++ b/hwc2_device/DrmHwcTwo.cpp
@@ -0,0 +1,208 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "hwc-drm-two"
+
+#include "DrmHwcTwo.h"
+
+#include "backend/Backend.h"
+#include "utils/log.h"
+
+namespace android {
+
+DrmHwcTwo::DrmHwcTwo() = default;
+
+HWC2::Error DrmHwcTwo::CreateDisplay(hwc2_display_t displ,
+                                     HWC2::DisplayType type) {
+  DrmDevice *drm = resource_manager_.GetDrmDevice(static_cast<int>(displ));
+  if (!drm) {
+    ALOGE("Failed to get a valid drmresource");
+    return HWC2::Error::NoResources;
+  }
+  displays_.emplace(std::piecewise_construct, std::forward_as_tuple(displ),
+                    std::forward_as_tuple(&resource_manager_, drm, displ, type,
+                                          this));
+
+  DrmCrtc *crtc = drm->GetCrtcForDisplay(static_cast<int>(displ));
+  if (!crtc) {
+    ALOGE("Failed to get crtc for display %d", static_cast<int>(displ));
+    return HWC2::Error::BadDisplay;
+  }
+  auto display_planes = std::vector<DrmPlane *>();
+  for (const auto &plane : drm->planes()) {
+    if (plane->GetCrtcSupported(*crtc))
+      display_planes.push_back(plane.get());
+  }
+  displays_.at(displ).Init(&display_planes);
+  return HWC2::Error::None;
+}
+
+HWC2::Error DrmHwcTwo::Init() {
+  int rv = resource_manager_.Init();
+  if (rv) {
+    ALOGE("Can't initialize the resource manager %d", rv);
+    return HWC2::Error::NoResources;
+  }
+
+  HWC2::Error ret = HWC2::Error::None;
+  for (int i = 0; i < resource_manager_.GetDisplayCount(); i++) {
+    ret = CreateDisplay(i, HWC2::DisplayType::Physical);
+    if (ret != HWC2::Error::None) {
+      ALOGE("Failed to create display %d with error %d", i, ret);
+      return ret;
+    }
+  }
+
+  resource_manager_.GetUEventListener()->RegisterHotplugHandler([this] {
+    const std::lock_guard<std::mutex> lock(GetResMan().GetMainLock());
+
+    HandleHotplugUEvent();
+  });
+
+  return ret;
+}
+
+HWC2::Error DrmHwcTwo::CreateVirtualDisplay(uint32_t /*width*/,
+                                            uint32_t /*height*/,
+                                            int32_t * /*format*/,
+                                            hwc2_display_t * /*display*/) {
+  // TODO(nobody): Implement virtual display
+  return HWC2::Error::Unsupported;
+}
+
+HWC2::Error DrmHwcTwo::DestroyVirtualDisplay(hwc2_display_t /*display*/) {
+  // TODO(nobody): Implement virtual display
+  return HWC2::Error::Unsupported;
+}
+
+void DrmHwcTwo::Dump(uint32_t *outSize, char *outBuffer) {
+  if (outBuffer != nullptr) {
+    auto copied_bytes = mDumpString.copy(outBuffer, *outSize);
+    *outSize = static_cast<uint32_t>(copied_bytes);
+    return;
+  }
+
+  std::stringstream output;
+
+  output << "-- drm_hwcomposer --\n\n";
+
+  for (std::pair<const hwc2_display_t, HwcDisplay> &dp : displays_)
+    output << dp.second.Dump();
+
+  mDumpString = output.str();
+  *outSize = static_cast<uint32_t>(mDumpString.size());
+}
+
+uint32_t DrmHwcTwo::GetMaxVirtualDisplayCount() {
+  // TODO(nobody): Implement virtual display
+  return 0;
+}
+
+HWC2::Error DrmHwcTwo::RegisterCallback(int32_t descriptor,
+                                        hwc2_callback_data_t data,
+                                        hwc2_function_pointer_t function) {
+  switch (static_cast<HWC2::Callback>(descriptor)) {
+    case HWC2::Callback::Hotplug: {
+      hotplug_callback_ = std::make_pair(HWC2_PFN_HOTPLUG(function), data);
+      const auto &drm_devices = resource_manager_.GetDrmDevices();
+      for (const auto &device : drm_devices)
+        HandleInitialHotplugState(device.get());
+      break;
+    }
+    case HWC2::Callback::Refresh: {
+      refresh_callback_ = std::make_pair(HWC2_PFN_REFRESH(function), data);
+      break;
+    }
+    case HWC2::Callback::Vsync: {
+      vsync_callback_ = std::make_pair(HWC2_PFN_VSYNC(function), data);
+      break;
+    }
+#if PLATFORM_SDK_VERSION > 29
+    case HWC2::Callback::Vsync_2_4: {
+      vsync_2_4_callback_ = std::make_pair(HWC2_PFN_VSYNC_2_4(function), data);
+      break;
+    }
+#endif
+    default:
+      break;
+  }
+  return HWC2::Error::None;
+}
+
+void DrmHwcTwo::HandleDisplayHotplug(hwc2_display_t displayid, int state) {
+  auto &mutex = GetResMan().GetMainLock();
+  if (mutex.try_lock()) {
+    ALOGE("FIXME!!!: Main mutex must be locked in %s", __func__);
+    mutex.unlock();
+    return;
+  }
+
+  auto hc = hotplug_callback_;
+  if (hc.first != nullptr && hc.second != nullptr) {
+    /* For some reason CLIENT will call HWC2 API in hotplug callback handler,
+     * which will cause deadlock . Unlock main mutex to prevent this.
+     */
+    mutex.unlock();
+    hc.first(hc.second, displayid,
+             state == DRM_MODE_CONNECTED ? HWC2_CONNECTION_CONNECTED
+                                         : HWC2_CONNECTION_DISCONNECTED);
+    mutex.lock();
+  }
+}
+
+void DrmHwcTwo::HandleInitialHotplugState(DrmDevice *drmDevice) {
+  for (const auto &conn : drmDevice->connectors()) {
+    int display_id = conn->display();
+    auto &display = displays_.at(display_id);
+
+    if (conn->state() != DRM_MODE_CONNECTED && !display.IsInHeadlessMode())
+      continue;
+    HandleDisplayHotplug(conn->display(), display.IsInHeadlessMode()
+                                              ? DRM_MODE_CONNECTED
+                                              : conn->state());
+  }
+}
+
+void DrmHwcTwo::HandleHotplugUEvent() {
+  for (const auto &drm : resource_manager_.GetDrmDevices()) {
+    for (const auto &conn : drm->connectors()) {
+      drmModeConnection old_state = conn->state();
+      drmModeConnection cur_state = conn->UpdateModes()
+                                        ? DRM_MODE_UNKNOWNCONNECTION
+                                        : conn->state();
+
+      if (cur_state == old_state)
+        continue;
+
+      ALOGI("%s event for connector %u on display %d",
+            cur_state == DRM_MODE_CONNECTED ? "Plug" : "Unplug", conn->id(),
+            conn->display());
+
+      int display_id = conn->display();
+      auto &display = displays_.at(display_id);
+      display.ChosePreferredConfig();
+      if (cur_state != DRM_MODE_CONNECTED) {
+        display.ClearDisplay();
+      }
+
+      HandleDisplayHotplug(display_id, display.IsInHeadlessMode()
+                                           ? DRM_MODE_CONNECTED
+                                           : cur_state);
+    }
+  }
+}
+
+}  // namespace android
diff --git a/hwc2_device/DrmHwcTwo.h b/hwc2_device/DrmHwcTwo.h
new file mode 100644
index 0000000..f38ba05
--- /dev/null
+++ b/hwc2_device/DrmHwcTwo.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_DRM_HWC_TWO_H_
+#define ANDROID_DRM_HWC_TWO_H_
+
+#include <hardware/hwcomposer2.h>
+
+#include "drm/ResourceManager.h"
+#include "hwc2_device/HwcDisplay.h"
+
+namespace android {
+
+class DrmHwcTwo {
+ public:
+  DrmHwcTwo();
+
+  HWC2::Error Init();
+
+  std::pair<HWC2_PFN_HOTPLUG, hwc2_callback_data_t> hotplug_callback_{};
+  std::pair<HWC2_PFN_VSYNC, hwc2_callback_data_t> vsync_callback_{};
+#if PLATFORM_SDK_VERSION > 29
+  std::pair<HWC2_PFN_VSYNC_2_4, hwc2_callback_data_t> vsync_2_4_callback_{};
+#endif
+  std::pair<HWC2_PFN_REFRESH, hwc2_callback_data_t> refresh_callback_{};
+
+  static HwcDisplay *GetDisplay(DrmHwcTwo *hwc, hwc2_display_t display_handle) {
+    auto it = hwc->displays_.find(display_handle);
+    if (it == hwc->displays_.end())
+      return nullptr;
+
+    return &it->second;
+  }
+
+  // Device functions
+  HWC2::Error CreateVirtualDisplay(uint32_t width, uint32_t height,
+                                   int32_t *format, hwc2_display_t *display);
+  HWC2::Error DestroyVirtualDisplay(hwc2_display_t display);
+  void Dump(uint32_t *outSize, char *outBuffer);
+  uint32_t GetMaxVirtualDisplayCount();
+  HWC2::Error RegisterCallback(int32_t descriptor, hwc2_callback_data_t data,
+                               hwc2_function_pointer_t function);
+  HWC2::Error CreateDisplay(hwc2_display_t displ, HWC2::DisplayType type);
+
+  auto &GetResMan() {
+    return resource_manager_;
+  }
+
+ private:
+  void HandleDisplayHotplug(hwc2_display_t displayid, int state);
+  void HandleInitialHotplugState(DrmDevice *drmDevice);
+
+  void HandleHotplugUEvent();
+
+  ResourceManager resource_manager_;
+  std::map<hwc2_display_t, HwcDisplay> displays_;
+
+  std::string mDumpString;
+};
+}  // namespace android
+
+#endif
diff --git a/hwc2_device/HwcDisplay.cpp b/hwc2_device/HwcDisplay.cpp
new file mode 100644
index 0000000..8936136
--- /dev/null
+++ b/hwc2_device/HwcDisplay.cpp
@@ -0,0 +1,854 @@
+/*
+ * 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() {
+  if (IsInHeadlessMode()) {
+    ALOGE("%s: Headless mode, should never reach here: ", __func__);
+    return;
+  }
+
+  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_->GetResMan().GetMainLock());
+    /* 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_->GetResMan().GetMainLock());
+              /* 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() {
+  HWC2::Error err = configs_.Update(*connector_);
+  if (!IsInHeadlessMode() && err != HWC2::Error::None)
+    return HWC2::Error::BadDisplay;
+
+  return SetActiveConfig(configs_.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 (configs_.hwc_configs.count(configs_.active_config_id) == 0)
+    return HWC2::Error::BadConfig;
+
+  *config = configs_.active_config_id;
+  return HWC2::Error::None;
+}
+
+HWC2::Error HwcDisplay::GetChangedCompositionTypes(uint32_t *num_elements,
+                                                   hwc2_layer_t *layers,
+                                                   int32_t *types) {
+  if (IsInHeadlessMode()) {
+    *num_elements = 0;
+    return HWC2::Error::None;
+  }
+
+  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 (IsInHeadlessMode()) {
+    return HWC2::Error::None;
+  }
+
+  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 (configs_.hwc_configs.count(conf) == 0) {
+    ALOGE("Could not find active mode for %d", conf);
+    return HWC2::Error::BadConfig;
+  }
+
+  auto &hwc_config = configs_.hwc_configs[conf];
+
+  static const int32_t kUmPerInch = 25400;
+  uint32_t mm_width = configs_.mm_width;
+  uint32_t mm_height = configs_.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;
+}
+
+HWC2::Error HwcDisplay::GetDisplayConfigs(uint32_t *num_configs,
+                                          hwc2_config_t *configs) {
+  uint32_t idx = 0;
+  for (auto &hwc_config : configs_.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) {
+  if (IsInHeadlessMode()) {
+    *num_elements = 0;
+    return HWC2::Error::None;
+  }
+
+  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) {
+  if (IsInHeadlessMode()) {
+    ALOGE("%s: Display is in headless mode, should never reach here", __func__);
+    return HWC2::Error::None;
+  }
+
+  // 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) {
+  if (IsInHeadlessMode()) {
+    *present_fence = -1;
+    return HWC2::Error::None;
+  }
+  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 (configs_.hwc_configs.count(conf) == 0) {
+    ALOGE("Could not find active mode for %d", conf);
+    return HWC2::Error::BadConfig;
+  }
+
+  auto &mode = configs_.hwc_configs[conf].mode;
+
+  staged_mode = mode;
+
+  configs_.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) {
+  if (IsInHeadlessMode()) {
+    return HWC2::Error::None;
+  }
+
+  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 compositor_.ActivateDisplayUsingDPMS() == 0
+                 ? HWC2::Error::None
+                 : HWC2::Error::BadParameter;
+      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) {
+  if (IsInHeadlessMode()) {
+    *num_types = *num_requests = 0;
+    return HWC2::Error::None;
+  }
+  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(configs_.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..c3e0f6e
--- /dev/null
+++ b/hwc2_device/HwcDisplay.h
@@ -0,0 +1,262 @@
+/*
+ * 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 "HwcDisplayConfigs.h"
+#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;
+  };
+
+  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;
+  }
+
+  /* Headless mode required to keep SurfaceFlinger alive when all display are
+   * disconnected, Without headless mode Android will continuously crash.
+   * Only single internal (primary) display is required to be in HEADLESS mode
+   * to prevent the crash. See:
+   * https://source.android.com/devices/graphics/hotplug#handling-common-scenarios
+   */
+  bool IsInHeadlessMode() {
+    return handle_ == 0 && connector_->state() != DRM_MODE_CONNECTED;
+  }
+
+ 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;
+
+  HwcDisplayConfigs configs_;
+
+  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/HwcDisplayConfigs.cpp b/hwc2_device/HwcDisplayConfigs.cpp
new file mode 100644
index 0000000..16f1ed0
--- /dev/null
+++ b/hwc2_device/HwcDisplayConfigs.cpp
@@ -0,0 +1,198 @@
+/*
+ * 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-configs"
+
+#include "HwcDisplayConfigs.h"
+
+#include <cmath>
+
+#include "drm/DrmConnector.h"
+#include "utils/log.h"
+
+constexpr uint32_t kHeadlessModeDisplayWidthMm = 163;
+constexpr uint32_t kHeadlessModeDisplayHeightMm = 122;
+constexpr uint32_t kHeadlessModeDisplayWidthPx = 1024;
+constexpr uint32_t kHeadlessModeDisplayHeightPx = 768;
+constexpr uint32_t kHeadlessModeDisplayVRefresh = 60;
+
+namespace android {
+
+// NOLINTNEXTLINE (readability-function-cognitive-complexity): Fixme
+HWC2::Error HwcDisplayConfigs::Update(DrmConnector &connector) {
+  /* In case UpdateModes will fail we will still have one mode for headless
+   * mode*/
+  hwc_configs.clear();
+
+  last_config_id++;
+  preferred_config_id = active_config_id = last_config_id;
+  auto headless_drm_mode_info = (drmModeModeInfo){
+      .hdisplay = kHeadlessModeDisplayWidthPx,
+      .vdisplay = kHeadlessModeDisplayHeightPx,
+      .vrefresh = kHeadlessModeDisplayVRefresh,
+      .name = "HEADLESS-MODE",
+  };
+  hwc_configs[active_config_id] = (HwcDisplayConfig){
+      .id = active_config_id,
+      .group_id = 1,
+      .mode = DrmMode(&headless_drm_mode_info),
+  };
+
+  mm_width = kHeadlessModeDisplayWidthMm;
+  mm_height = kHeadlessModeDisplayHeightMm;
+
+  /* Read real configs */
+  int ret = connector.UpdateModes();
+  if (ret != 0) {
+    ALOGE("Failed to update display modes %d", ret);
+    return HWC2::Error::BadDisplay;
+  }
+
+  if (connector.modes().empty()) {
+    ALOGE("No modes reported by KMS");
+    return HWC2::Error::BadDisplay;
+  }
+
+  hwc_configs.clear();
+  mm_width = connector.mm_width();
+  mm_height = connector.mm_height();
+
+  preferred_config_id = 0;
+  int preferred_config_group_id = 0;
+
+  int first_config_id = last_config_id;
+  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) != 0) {
+      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 = first_config_id;
+    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
+   */
+  constexpr float kMinFpsDelta = 1.0;  // FPS
+  for (int m1 = first_config_id; m1 < last_config_id; m1++) {
+    for (int m2 = first_config_id; 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()) < kMinFpsDelta) {
+        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;
+      }
+    }
+  }
+
+  /* Set active mode to be valid mode */
+  active_config_id = preferred_config_id;
+  return HWC2::Error::None;
+}
+
+}  // namespace android
diff --git a/hwc2_device/HwcDisplayConfigs.h b/hwc2_device/HwcDisplayConfigs.h
new file mode 100644
index 0000000..5bcf696
--- /dev/null
+++ b/hwc2_device/HwcDisplayConfigs.h
@@ -0,0 +1,57 @@
+/*
+ * 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_CONFIGS_H
+#define ANDROID_HWC2_DEVICE_HWC_DISPLAY_CONFIGS_H
+
+#include <hardware/hwcomposer2.h>
+
+#include <map>
+
+#include "drm/DrmMode.h"
+
+namespace android {
+
+class DrmConnector;
+
+struct HwcDisplayConfig {
+  int id{};
+  int group_id{};
+  DrmMode mode;
+  bool disabled{};
+
+  bool IsInterlaced() const {
+    return (mode.flags() & DRM_MODE_FLAG_INTERLACE) != 0;
+  }
+};
+
+struct HwcDisplayConfigs {
+  HWC2::Error Update(DrmConnector &conn);
+
+  std::map<int /*config_id*/, struct HwcDisplayConfig> hwc_configs;
+
+  int active_config_id = 0;
+  int preferred_config_id = 0;
+
+  int last_config_id = 1;
+
+  uint32_t mm_width = 0;
+  uint32_t mm_height = 0;
+};
+
+}  // namespace android
+
+#endif
diff --git a/hwc2_device/HwcLayer.cpp b/hwc2_device/HwcLayer.cpp
new file mode 100644
index 0000000..66babda
--- /dev/null
+++ b/hwc2_device/HwcLayer.cpp
@@ -0,0 +1,180 @@
+/*
+ * 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-layer"
+
+#include "HwcLayer.h"
+
+#include <fcntl.h>
+
+#include "utils/log.h"
+
+namespace android {
+
+// NOLINTNEXTLINE(readability-convert-member-functions-to-static)
+HWC2::Error HwcLayer::SetCursorPosition(int32_t /*x*/, int32_t /*y*/) {
+  return HWC2::Error::None;
+}
+
+HWC2::Error HwcLayer::SetLayerBlendMode(int32_t mode) {
+  switch (static_cast<HWC2::BlendMode>(mode)) {
+    case HWC2::BlendMode::None:
+      blending_ = DrmHwcBlending::kNone;
+      break;
+    case HWC2::BlendMode::Premultiplied:
+      blending_ = DrmHwcBlending::kPreMult;
+      break;
+    case HWC2::BlendMode::Coverage:
+      blending_ = DrmHwcBlending::kCoverage;
+      break;
+    default:
+      ALOGE("Unknown blending mode b=%d", blending_);
+      blending_ = DrmHwcBlending::kNone;
+      break;
+  }
+  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=2314
+ */
+HWC2::Error HwcLayer::SetLayerBuffer(buffer_handle_t buffer,
+                                     int32_t acquire_fence) {
+  buffer_ = buffer;
+  acquire_fence_ = UniqueFd(acquire_fence);
+  return HWC2::Error::None;
+}
+
+// NOLINTNEXTLINE(readability-convert-member-functions-to-static)
+HWC2::Error HwcLayer::SetLayerColor(hwc_color_t /*color*/) {
+  // TODO(nobody): Put to client composition here?
+  return HWC2::Error::None;
+}
+
+HWC2::Error HwcLayer::SetLayerCompositionType(int32_t type) {
+  sf_type_ = static_cast<HWC2::Composition>(type);
+  return HWC2::Error::None;
+}
+
+HWC2::Error HwcLayer::SetLayerDataspace(int32_t dataspace) {
+  switch (dataspace & HAL_DATASPACE_STANDARD_MASK) {
+    case HAL_DATASPACE_STANDARD_BT709:
+      color_space_ = DrmHwcColorSpace::kItuRec709;
+      break;
+    case HAL_DATASPACE_STANDARD_BT601_625:
+    case HAL_DATASPACE_STANDARD_BT601_625_UNADJUSTED:
+    case HAL_DATASPACE_STANDARD_BT601_525:
+    case HAL_DATASPACE_STANDARD_BT601_525_UNADJUSTED:
+      color_space_ = DrmHwcColorSpace::kItuRec601;
+      break;
+    case HAL_DATASPACE_STANDARD_BT2020:
+    case HAL_DATASPACE_STANDARD_BT2020_CONSTANT_LUMINANCE:
+      color_space_ = DrmHwcColorSpace::kItuRec2020;
+      break;
+    default:
+      color_space_ = DrmHwcColorSpace::kUndefined;
+  }
+
+  switch (dataspace & HAL_DATASPACE_RANGE_MASK) {
+    case HAL_DATASPACE_RANGE_FULL:
+      sample_range_ = DrmHwcSampleRange::kFullRange;
+      break;
+    case HAL_DATASPACE_RANGE_LIMITED:
+      sample_range_ = DrmHwcSampleRange::kLimitedRange;
+      break;
+    default:
+      sample_range_ = DrmHwcSampleRange::kUndefined;
+  }
+  return HWC2::Error::None;
+}
+
+HWC2::Error HwcLayer::SetLayerDisplayFrame(hwc_rect_t frame) {
+  display_frame_ = frame;
+  return HWC2::Error::None;
+}
+
+HWC2::Error HwcLayer::SetLayerPlaneAlpha(float alpha) {
+  alpha_ = alpha;
+  return HWC2::Error::None;
+}
+
+// NOLINTNEXTLINE(readability-convert-member-functions-to-static)
+HWC2::Error HwcLayer::SetLayerSidebandStream(
+    const native_handle_t * /*stream*/) {
+  // TODO(nobody): We don't support sideband
+  return HWC2::Error::Unsupported;
+}
+
+HWC2::Error HwcLayer::SetLayerSourceCrop(hwc_frect_t crop) {
+  source_crop_ = crop;
+  return HWC2::Error::None;
+}
+
+// NOLINTNEXTLINE(readability-convert-member-functions-to-static)
+HWC2::Error HwcLayer::SetLayerSurfaceDamage(hwc_region_t /*damage*/) {
+  // TODO(nobody): We don't use surface damage, marking as unsupported
+  return HWC2::Error::None;
+}
+
+HWC2::Error HwcLayer::SetLayerTransform(int32_t transform) {
+  uint32_t l_transform = 0;
+
+  // 270* and 180* cannot be combined with flips. More specifically, they
+  // already contain both horizontal and vertical flips, so those fields are
+  // redundant in this case. 90* rotation can be combined with either horizontal
+  // flip or vertical flip, so treat it differently
+  if (transform == HWC_TRANSFORM_ROT_270) {
+    l_transform = DrmHwcTransform::kRotate270;
+  } else if (transform == HWC_TRANSFORM_ROT_180) {
+    l_transform = DrmHwcTransform::kRotate180;
+  } else {
+    if ((transform & HWC_TRANSFORM_FLIP_H) != 0)
+      l_transform |= DrmHwcTransform::kFlipH;
+    if ((transform & HWC_TRANSFORM_FLIP_V) != 0)
+      l_transform |= DrmHwcTransform::kFlipV;
+    if ((transform & HWC_TRANSFORM_ROT_90) != 0)
+      l_transform |= DrmHwcTransform::kRotate90;
+  }
+
+  transform_ = static_cast<DrmHwcTransform>(l_transform);
+  return HWC2::Error::None;
+}
+
+// NOLINTNEXTLINE(readability-convert-member-functions-to-static)
+HWC2::Error HwcLayer::SetLayerVisibleRegion(hwc_region_t /*visible*/) {
+  // TODO(nobody): We don't use this information, marking as unsupported
+  return HWC2::Error::None;
+}
+
+HWC2::Error HwcLayer::SetLayerZOrder(uint32_t order) {
+  z_order_ = order;
+  return HWC2::Error::None;
+}
+
+void HwcLayer::PopulateDrmLayer(DrmHwcLayer *layer) {
+  layer->sf_handle = buffer_;
+  // TODO(rsglobal): Avoid extra fd duplication
+  layer->acquire_fence = UniqueFd(fcntl(acquire_fence_.Get(), F_DUPFD_CLOEXEC));
+  layer->display_frame = display_frame_;
+  layer->alpha = std::lround(alpha_ * UINT16_MAX);
+  layer->blending = blending_;
+  layer->source_crop = source_crop_;
+  layer->transform = transform_;
+  layer->color_space = color_space_;
+  layer->sample_range = sample_range_;
+}
+
+}  // namespace android
\ No newline at end of file
diff --git a/hwc2_device/HwcLayer.h b/hwc2_device/HwcLayer.h
new file mode 100644
index 0000000..df4ce6d
--- /dev/null
+++ b/hwc2_device/HwcLayer.h
@@ -0,0 +1,123 @@
+/*
+ * 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_LAYER_H
+#define ANDROID_HWC2_DEVICE_HWC_LAYER_H
+
+#include <hardware/hwcomposer2.h>
+
+#include <cmath>
+
+#include "drmhwcomposer.h"
+
+namespace android {
+
+class HwcLayer {
+ public:
+  HWC2::Composition GetSfType() const {
+    return sf_type_;
+  }
+  HWC2::Composition GetValidatedType() const {
+    return validated_type_;
+  }
+  void AcceptTypeChange() {
+    sf_type_ = validated_type_;
+  }
+  void SetValidatedType(HWC2::Composition type) {
+    validated_type_ = type;
+  }
+  bool IsTypeChanged() const {
+    return sf_type_ != validated_type_;
+  }
+
+  uint32_t GetZOrder() const {
+    return z_order_;
+  }
+
+  buffer_handle_t GetBuffer() {
+    return buffer_;
+  }
+
+  hwc_rect_t GetDisplayFrame() {
+    return display_frame_;
+  }
+
+  UniqueFd GetReleaseFence() {
+    return std::move(release_fence_);
+  }
+
+  void PopulateDrmLayer(DrmHwcLayer *layer);
+
+  bool RequireScalingOrPhasing() const {
+    float src_width = source_crop_.right - source_crop_.left;
+    float src_height = source_crop_.bottom - source_crop_.top;
+
+    auto dest_width = float(display_frame_.right - display_frame_.left);
+    auto dest_height = float(display_frame_.bottom - display_frame_.top);
+
+    bool scaling = src_width != dest_width || src_height != dest_height;
+    bool phasing = (source_crop_.left - std::floor(source_crop_.left) != 0) ||
+                   (source_crop_.top - std::floor(source_crop_.top) != 0);
+    return scaling || phasing;
+  }
+
+  // Layer hooks
+  HWC2::Error SetCursorPosition(int32_t /*x*/, int32_t /*y*/);
+  HWC2::Error SetLayerBlendMode(int32_t mode);
+  HWC2::Error SetLayerBuffer(buffer_handle_t buffer, int32_t acquire_fence);
+  HWC2::Error SetLayerColor(hwc_color_t /*color*/);
+  HWC2::Error SetLayerCompositionType(int32_t type);
+  HWC2::Error SetLayerDataspace(int32_t dataspace);
+  HWC2::Error SetLayerDisplayFrame(hwc_rect_t frame);
+  HWC2::Error SetLayerPlaneAlpha(float alpha);
+  HWC2::Error SetLayerSidebandStream(const native_handle_t *stream);
+  HWC2::Error SetLayerSourceCrop(hwc_frect_t crop);
+  HWC2::Error SetLayerSurfaceDamage(hwc_region_t damage);
+  HWC2::Error SetLayerTransform(int32_t transform);
+  HWC2::Error SetLayerVisibleRegion(hwc_region_t visible);
+  HWC2::Error SetLayerZOrder(uint32_t order);
+
+ private:
+  // sf_type_ stores the initial type given to us by surfaceflinger,
+  // validated_type_ stores the type after running ValidateDisplay
+  HWC2::Composition sf_type_ = HWC2::Composition::Invalid;
+  HWC2::Composition validated_type_ = HWC2::Composition::Invalid;
+
+  buffer_handle_t buffer_ = nullptr;
+  hwc_rect_t display_frame_;
+  static constexpr float kOpaqueFloat = 1.0F;
+  float alpha_ = kOpaqueFloat;
+  hwc_frect_t source_crop_;
+  DrmHwcTransform transform_ = DrmHwcTransform::kIdentity;
+  uint32_t z_order_ = 0;
+  DrmHwcBlending blending_ = DrmHwcBlending::kNone;
+  DrmHwcColorSpace color_space_ = DrmHwcColorSpace::kUndefined;
+  DrmHwcSampleRange sample_range_ = DrmHwcSampleRange::kUndefined;
+
+  UniqueFd acquire_fence_;
+
+  /*
+   * Release fence is not used.
+   * There is no release fence support available in the DRM/KMS. In case no
+   * release fence provided application will use this buffer for writing when
+   * the next frame present fence is signaled.
+   */
+  UniqueFd release_fence_;
+};
+
+}  // namespace android
+
+#endif
diff --git a/hwc2_device/hwc2_device.cpp b/hwc2_device/hwc2_device.cpp
new file mode 100644
index 0000000..6d258e8
--- /dev/null
+++ b/hwc2_device/hwc2_device.cpp
@@ -0,0 +1,421 @@
+/*
+ * 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.
+ */
+
+// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
+// #define LOG_NDEBUG 0 // Uncomment to see HWC2 API calls in logcat
+
+#define LOG_TAG "hwc2-device"
+
+#include <cinttypes>
+
+#include "DrmHwcTwo.h"
+#include "backend/Backend.h"
+#include "utils/log.h"
+
+namespace android {
+
+/* Converts long __PRETTY_FUNCTION__ result, e.g.:
+ * "int32_t android::LayerHook(hwc2_device_t *, hwc2_display_t, hwc2_layer_t,"
+ * "Args...) [HookType = HWC2::Error (android::HwcLayer::*)(const native_handle"
+ * "*,int), func = &android::HwcLayer::SetLayerBuffer, Args = <const
+ * "native_handle, int>"
+ * to the short "android::HwcLayer::SetLayerBuffer" for better logs readability
+ */
+static std::string GetFuncName(const char *pretty_function) {
+  std::string str(pretty_function);
+  const char *start = "func = &";
+  size_t p1 = str.find(start);
+  p1 += strlen(start);
+  size_t p2 = str.find(',', p1);
+  return str.substr(p1, p2 - p1);
+}
+
+struct Drmhwc2Device : hwc2_device {
+  DrmHwcTwo drmhwctwo;
+};
+
+static DrmHwcTwo *ToDrmHwcTwo(hwc2_device_t *dev) {
+  // NOLINTNEXTLINE(cppcoreguidelines-pro-type-static-cast-downcast):
+  return &static_cast<Drmhwc2Device *>(dev)->drmhwctwo;
+}
+
+template <typename PFN, typename T>
+static hwc2_function_pointer_t ToHook(T function) {
+  static_assert(std::is_same<PFN, T>::value, "Incompatible fn pointer");
+  // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast):
+  return reinterpret_cast<hwc2_function_pointer_t>(function);
+}
+
+template <typename T, typename HookType, HookType func, typename... Args>
+static T DeviceHook(hwc2_device_t *dev, Args... args) {
+  ALOGV("Device hook: %s", GetFuncName(__PRETTY_FUNCTION__).c_str());
+  DrmHwcTwo *hwc = ToDrmHwcTwo(dev);
+  const std::lock_guard<std::mutex> lock(hwc->GetResMan().GetMainLock());
+  return static_cast<T>(((*hwc).*func)(std::forward<Args>(args)...));
+}
+
+template <typename HookType, HookType func, typename... Args>
+static int32_t DisplayHook(hwc2_device_t *dev, hwc2_display_t display_handle,
+                           Args... args) {
+  ALOGV("Display #%" PRIu64 " hook: %s", display_handle,
+        GetFuncName(__PRETTY_FUNCTION__).c_str());
+  DrmHwcTwo *hwc = ToDrmHwcTwo(dev);
+  const std::lock_guard<std::mutex> lock(hwc->GetResMan().GetMainLock());
+  HwcDisplay *display = DrmHwcTwo::GetDisplay(hwc, display_handle);
+  if (!display)
+    return static_cast<int32_t>(HWC2::Error::BadDisplay);
+
+  return static_cast<int32_t>((display->*func)(std::forward<Args>(args)...));
+}
+
+template <typename HookType, HookType func, typename... Args>
+static int32_t LayerHook(hwc2_device_t *dev, hwc2_display_t display_handle,
+                         hwc2_layer_t layer_handle, Args... args) {
+  ALOGV("Display #%" PRIu64 " Layer: #%" PRIu64 " hook: %s", display_handle,
+        layer_handle, GetFuncName(__PRETTY_FUNCTION__).c_str());
+  DrmHwcTwo *hwc = ToDrmHwcTwo(dev);
+  const std::lock_guard<std::mutex> lock(hwc->GetResMan().GetMainLock());
+  HwcDisplay *display = DrmHwcTwo::GetDisplay(hwc, display_handle);
+  if (!display)
+    return static_cast<int32_t>(HWC2::Error::BadDisplay);
+
+  HwcLayer *layer = display->get_layer(layer_handle);
+  if (!layer)
+    return static_cast<int32_t>(HWC2::Error::BadLayer);
+
+  return static_cast<int32_t>((layer->*func)(std::forward<Args>(args)...));
+}
+
+static int HookDevClose(hw_device_t *dev) {
+  // NOLINTNEXTLINE (cppcoreguidelines-pro-type-reinterpret-cast): Safe
+  auto *hwc2_dev = reinterpret_cast<hwc2_device_t *>(dev);
+  std::unique_ptr<DrmHwcTwo> ctx(ToDrmHwcTwo(hwc2_dev));
+  return 0;
+}
+
+static void HookDevGetCapabilities(hwc2_device_t * /*dev*/, uint32_t *out_count,
+                                   int32_t * /*out_capabilities*/) {
+  *out_count = 0;
+}
+
+static hwc2_function_pointer_t HookDevGetFunction(struct hwc2_device * /*dev*/,
+                                                  int32_t descriptor) {
+  auto func = static_cast<HWC2::FunctionDescriptor>(descriptor);
+  switch (func) {
+    // Device functions
+    case HWC2::FunctionDescriptor::CreateVirtualDisplay:
+      return ToHook<HWC2_PFN_CREATE_VIRTUAL_DISPLAY>(
+          DeviceHook<int32_t, decltype(&DrmHwcTwo::CreateVirtualDisplay),
+                     &DrmHwcTwo::CreateVirtualDisplay, uint32_t, uint32_t,
+                     int32_t *, hwc2_display_t *>);
+    case HWC2::FunctionDescriptor::DestroyVirtualDisplay:
+      return ToHook<HWC2_PFN_DESTROY_VIRTUAL_DISPLAY>(
+          DeviceHook<int32_t, decltype(&DrmHwcTwo::DestroyVirtualDisplay),
+                     &DrmHwcTwo::DestroyVirtualDisplay, hwc2_display_t>);
+    case HWC2::FunctionDescriptor::Dump:
+      return ToHook<HWC2_PFN_DUMP>(
+          DeviceHook<void, decltype(&DrmHwcTwo::Dump), &DrmHwcTwo::Dump,
+                     uint32_t *, char *>);
+    case HWC2::FunctionDescriptor::GetMaxVirtualDisplayCount:
+      return ToHook<HWC2_PFN_GET_MAX_VIRTUAL_DISPLAY_COUNT>(
+          DeviceHook<uint32_t, decltype(&DrmHwcTwo::GetMaxVirtualDisplayCount),
+                     &DrmHwcTwo::GetMaxVirtualDisplayCount>);
+    case HWC2::FunctionDescriptor::RegisterCallback:
+      return ToHook<HWC2_PFN_REGISTER_CALLBACK>(
+          DeviceHook<int32_t, decltype(&DrmHwcTwo::RegisterCallback),
+                     &DrmHwcTwo::RegisterCallback, int32_t,
+                     hwc2_callback_data_t, hwc2_function_pointer_t>);
+
+    // Display functions
+    case HWC2::FunctionDescriptor::AcceptDisplayChanges:
+      return ToHook<HWC2_PFN_ACCEPT_DISPLAY_CHANGES>(
+          DisplayHook<decltype(&HwcDisplay::AcceptDisplayChanges),
+                      &HwcDisplay::AcceptDisplayChanges>);
+    case HWC2::FunctionDescriptor::CreateLayer:
+      return ToHook<HWC2_PFN_CREATE_LAYER>(
+          DisplayHook<decltype(&HwcDisplay::CreateLayer),
+                      &HwcDisplay::CreateLayer, hwc2_layer_t *>);
+    case HWC2::FunctionDescriptor::DestroyLayer:
+      return ToHook<HWC2_PFN_DESTROY_LAYER>(
+          DisplayHook<decltype(&HwcDisplay::DestroyLayer),
+                      &HwcDisplay::DestroyLayer, hwc2_layer_t>);
+    case HWC2::FunctionDescriptor::GetActiveConfig:
+      return ToHook<HWC2_PFN_GET_ACTIVE_CONFIG>(
+          DisplayHook<decltype(&HwcDisplay::GetActiveConfig),
+                      &HwcDisplay::GetActiveConfig, hwc2_config_t *>);
+    case HWC2::FunctionDescriptor::GetChangedCompositionTypes:
+      return ToHook<HWC2_PFN_GET_CHANGED_COMPOSITION_TYPES>(
+          DisplayHook<decltype(&HwcDisplay::GetChangedCompositionTypes),
+                      &HwcDisplay::GetChangedCompositionTypes, uint32_t *,
+                      hwc2_layer_t *, int32_t *>);
+    case HWC2::FunctionDescriptor::GetClientTargetSupport:
+      return ToHook<HWC2_PFN_GET_CLIENT_TARGET_SUPPORT>(
+          DisplayHook<decltype(&HwcDisplay::GetClientTargetSupport),
+                      &HwcDisplay::GetClientTargetSupport, uint32_t, uint32_t,
+                      int32_t, int32_t>);
+    case HWC2::FunctionDescriptor::GetColorModes:
+      return ToHook<HWC2_PFN_GET_COLOR_MODES>(
+          DisplayHook<decltype(&HwcDisplay::GetColorModes),
+                      &HwcDisplay::GetColorModes, uint32_t *, int32_t *>);
+    case HWC2::FunctionDescriptor::GetDisplayAttribute:
+      return ToHook<HWC2_PFN_GET_DISPLAY_ATTRIBUTE>(
+          DisplayHook<decltype(&HwcDisplay::GetDisplayAttribute),
+                      &HwcDisplay::GetDisplayAttribute, hwc2_config_t, int32_t,
+                      int32_t *>);
+    case HWC2::FunctionDescriptor::GetDisplayConfigs:
+      return ToHook<HWC2_PFN_GET_DISPLAY_CONFIGS>(
+          DisplayHook<decltype(&HwcDisplay::GetDisplayConfigs),
+                      &HwcDisplay::GetDisplayConfigs, uint32_t *,
+                      hwc2_config_t *>);
+    case HWC2::FunctionDescriptor::GetDisplayName:
+      return ToHook<HWC2_PFN_GET_DISPLAY_NAME>(
+          DisplayHook<decltype(&HwcDisplay::GetDisplayName),
+                      &HwcDisplay::GetDisplayName, uint32_t *, char *>);
+    case HWC2::FunctionDescriptor::GetDisplayRequests:
+      return ToHook<HWC2_PFN_GET_DISPLAY_REQUESTS>(
+          DisplayHook<decltype(&HwcDisplay::GetDisplayRequests),
+                      &HwcDisplay::GetDisplayRequests, int32_t *, uint32_t *,
+                      hwc2_layer_t *, int32_t *>);
+    case HWC2::FunctionDescriptor::GetDisplayType:
+      return ToHook<HWC2_PFN_GET_DISPLAY_TYPE>(
+          DisplayHook<decltype(&HwcDisplay::GetDisplayType),
+                      &HwcDisplay::GetDisplayType, int32_t *>);
+    case HWC2::FunctionDescriptor::GetDozeSupport:
+      return ToHook<HWC2_PFN_GET_DOZE_SUPPORT>(
+          DisplayHook<decltype(&HwcDisplay::GetDozeSupport),
+                      &HwcDisplay::GetDozeSupport, int32_t *>);
+    case HWC2::FunctionDescriptor::GetHdrCapabilities:
+      return ToHook<HWC2_PFN_GET_HDR_CAPABILITIES>(
+          DisplayHook<decltype(&HwcDisplay::GetHdrCapabilities),
+                      &HwcDisplay::GetHdrCapabilities, uint32_t *, int32_t *,
+                      float *, float *, float *>);
+    case HWC2::FunctionDescriptor::GetReleaseFences:
+      return ToHook<HWC2_PFN_GET_RELEASE_FENCES>(
+          DisplayHook<decltype(&HwcDisplay::GetReleaseFences),
+                      &HwcDisplay::GetReleaseFences, uint32_t *, hwc2_layer_t *,
+                      int32_t *>);
+    case HWC2::FunctionDescriptor::PresentDisplay:
+      return ToHook<HWC2_PFN_PRESENT_DISPLAY>(
+          DisplayHook<decltype(&HwcDisplay::PresentDisplay),
+                      &HwcDisplay::PresentDisplay, int32_t *>);
+    case HWC2::FunctionDescriptor::SetActiveConfig:
+      return ToHook<HWC2_PFN_SET_ACTIVE_CONFIG>(
+          DisplayHook<decltype(&HwcDisplay::SetActiveConfig),
+                      &HwcDisplay::SetActiveConfig, hwc2_config_t>);
+    case HWC2::FunctionDescriptor::SetClientTarget:
+      return ToHook<HWC2_PFN_SET_CLIENT_TARGET>(
+          DisplayHook<decltype(&HwcDisplay::SetClientTarget),
+                      &HwcDisplay::SetClientTarget, buffer_handle_t, int32_t,
+                      int32_t, hwc_region_t>);
+    case HWC2::FunctionDescriptor::SetColorMode:
+      return ToHook<HWC2_PFN_SET_COLOR_MODE>(
+          DisplayHook<decltype(&HwcDisplay::SetColorMode),
+                      &HwcDisplay::SetColorMode, int32_t>);
+    case HWC2::FunctionDescriptor::SetColorTransform:
+      return ToHook<HWC2_PFN_SET_COLOR_TRANSFORM>(
+          DisplayHook<decltype(&HwcDisplay::SetColorTransform),
+                      &HwcDisplay::SetColorTransform, const float *, int32_t>);
+    case HWC2::FunctionDescriptor::SetOutputBuffer:
+      return ToHook<HWC2_PFN_SET_OUTPUT_BUFFER>(
+          DisplayHook<decltype(&HwcDisplay::SetOutputBuffer),
+                      &HwcDisplay::SetOutputBuffer, buffer_handle_t, int32_t>);
+    case HWC2::FunctionDescriptor::SetPowerMode:
+      return ToHook<HWC2_PFN_SET_POWER_MODE>(
+          DisplayHook<decltype(&HwcDisplay::SetPowerMode),
+                      &HwcDisplay::SetPowerMode, int32_t>);
+    case HWC2::FunctionDescriptor::SetVsyncEnabled:
+      return ToHook<HWC2_PFN_SET_VSYNC_ENABLED>(
+          DisplayHook<decltype(&HwcDisplay::SetVsyncEnabled),
+                      &HwcDisplay::SetVsyncEnabled, int32_t>);
+    case HWC2::FunctionDescriptor::ValidateDisplay:
+      return ToHook<HWC2_PFN_VALIDATE_DISPLAY>(
+          DisplayHook<decltype(&HwcDisplay::ValidateDisplay),
+                      &HwcDisplay::ValidateDisplay, uint32_t *, uint32_t *>);
+#if PLATFORM_SDK_VERSION > 27
+    case HWC2::FunctionDescriptor::GetRenderIntents:
+      return ToHook<HWC2_PFN_GET_RENDER_INTENTS>(
+          DisplayHook<decltype(&HwcDisplay::GetRenderIntents),
+                      &HwcDisplay::GetRenderIntents, int32_t, uint32_t *,
+                      int32_t *>);
+    case HWC2::FunctionDescriptor::SetColorModeWithRenderIntent:
+      return ToHook<HWC2_PFN_SET_COLOR_MODE_WITH_RENDER_INTENT>(
+          DisplayHook<decltype(&HwcDisplay::SetColorModeWithIntent),
+                      &HwcDisplay::SetColorModeWithIntent, int32_t, int32_t>);
+#endif
+#if PLATFORM_SDK_VERSION > 28
+    case HWC2::FunctionDescriptor::GetDisplayIdentificationData:
+      return ToHook<HWC2_PFN_GET_DISPLAY_IDENTIFICATION_DATA>(
+          DisplayHook<decltype(&HwcDisplay::GetDisplayIdentificationData),
+                      &HwcDisplay::GetDisplayIdentificationData, uint8_t *,
+                      uint32_t *, uint8_t *>);
+    case HWC2::FunctionDescriptor::GetDisplayCapabilities:
+      return ToHook<HWC2_PFN_GET_DISPLAY_CAPABILITIES>(
+          DisplayHook<decltype(&HwcDisplay::GetDisplayCapabilities),
+                      &HwcDisplay::GetDisplayCapabilities, uint32_t *,
+                      uint32_t *>);
+    case HWC2::FunctionDescriptor::GetDisplayBrightnessSupport:
+      return ToHook<HWC2_PFN_GET_DISPLAY_BRIGHTNESS_SUPPORT>(
+          DisplayHook<decltype(&HwcDisplay::GetDisplayBrightnessSupport),
+                      &HwcDisplay::GetDisplayBrightnessSupport, bool *>);
+    case HWC2::FunctionDescriptor::SetDisplayBrightness:
+      return ToHook<HWC2_PFN_SET_DISPLAY_BRIGHTNESS>(
+          DisplayHook<decltype(&HwcDisplay::SetDisplayBrightness),
+                      &HwcDisplay::SetDisplayBrightness, float>);
+#endif /* PLATFORM_SDK_VERSION > 28 */
+#if PLATFORM_SDK_VERSION > 29
+    case HWC2::FunctionDescriptor::GetDisplayConnectionType:
+      return ToHook<HWC2_PFN_GET_DISPLAY_CONNECTION_TYPE>(
+          DisplayHook<decltype(&HwcDisplay::GetDisplayConnectionType),
+                      &HwcDisplay::GetDisplayConnectionType, uint32_t *>);
+    case HWC2::FunctionDescriptor::GetDisplayVsyncPeriod:
+      return ToHook<HWC2_PFN_GET_DISPLAY_VSYNC_PERIOD>(
+          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(&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(&HwcDisplay::SetAutoLowLatencyMode),
+                      &HwcDisplay::SetAutoLowLatencyMode, bool>);
+    case HWC2::FunctionDescriptor::GetSupportedContentTypes:
+      return ToHook<HWC2_PFN_GET_SUPPORTED_CONTENT_TYPES>(
+          DisplayHook<decltype(&HwcDisplay::GetSupportedContentTypes),
+                      &HwcDisplay::GetSupportedContentTypes, uint32_t *,
+                      uint32_t *>);
+    case HWC2::FunctionDescriptor::SetContentType:
+      return ToHook<HWC2_PFN_SET_CONTENT_TYPE>(
+          DisplayHook<decltype(&HwcDisplay::SetContentType),
+                      &HwcDisplay::SetContentType, int32_t>);
+#endif
+    // Layer functions
+    case HWC2::FunctionDescriptor::SetCursorPosition:
+      return ToHook<HWC2_PFN_SET_CURSOR_POSITION>(
+          LayerHook<decltype(&HwcLayer::SetCursorPosition),
+                    &HwcLayer::SetCursorPosition, int32_t, int32_t>);
+    case HWC2::FunctionDescriptor::SetLayerBlendMode:
+      return ToHook<HWC2_PFN_SET_LAYER_BLEND_MODE>(
+          LayerHook<decltype(&HwcLayer::SetLayerBlendMode),
+                    &HwcLayer::SetLayerBlendMode, int32_t>);
+    case HWC2::FunctionDescriptor::SetLayerBuffer:
+      return ToHook<HWC2_PFN_SET_LAYER_BUFFER>(
+          LayerHook<decltype(&HwcLayer::SetLayerBuffer),
+                    &HwcLayer::SetLayerBuffer, buffer_handle_t, int32_t>);
+    case HWC2::FunctionDescriptor::SetLayerColor:
+      return ToHook<HWC2_PFN_SET_LAYER_COLOR>(
+          LayerHook<decltype(&HwcLayer::SetLayerColor),
+                    &HwcLayer::SetLayerColor, hwc_color_t>);
+    case HWC2::FunctionDescriptor::SetLayerCompositionType:
+      return ToHook<HWC2_PFN_SET_LAYER_COMPOSITION_TYPE>(
+          LayerHook<decltype(&HwcLayer::SetLayerCompositionType),
+                    &HwcLayer::SetLayerCompositionType, int32_t>);
+    case HWC2::FunctionDescriptor::SetLayerDataspace:
+      return ToHook<HWC2_PFN_SET_LAYER_DATASPACE>(
+          LayerHook<decltype(&HwcLayer::SetLayerDataspace),
+                    &HwcLayer::SetLayerDataspace, int32_t>);
+    case HWC2::FunctionDescriptor::SetLayerDisplayFrame:
+      return ToHook<HWC2_PFN_SET_LAYER_DISPLAY_FRAME>(
+          LayerHook<decltype(&HwcLayer::SetLayerDisplayFrame),
+                    &HwcLayer::SetLayerDisplayFrame, hwc_rect_t>);
+    case HWC2::FunctionDescriptor::SetLayerPlaneAlpha:
+      return ToHook<HWC2_PFN_SET_LAYER_PLANE_ALPHA>(
+          LayerHook<decltype(&HwcLayer::SetLayerPlaneAlpha),
+                    &HwcLayer::SetLayerPlaneAlpha, float>);
+    case HWC2::FunctionDescriptor::SetLayerSidebandStream:
+      return ToHook<HWC2_PFN_SET_LAYER_SIDEBAND_STREAM>(
+          LayerHook<decltype(&HwcLayer::SetLayerSidebandStream),
+                    &HwcLayer::SetLayerSidebandStream,
+                    const native_handle_t *>);
+    case HWC2::FunctionDescriptor::SetLayerSourceCrop:
+      return ToHook<HWC2_PFN_SET_LAYER_SOURCE_CROP>(
+          LayerHook<decltype(&HwcLayer::SetLayerSourceCrop),
+                    &HwcLayer::SetLayerSourceCrop, hwc_frect_t>);
+    case HWC2::FunctionDescriptor::SetLayerSurfaceDamage:
+      return ToHook<HWC2_PFN_SET_LAYER_SURFACE_DAMAGE>(
+          LayerHook<decltype(&HwcLayer::SetLayerSurfaceDamage),
+                    &HwcLayer::SetLayerSurfaceDamage, hwc_region_t>);
+    case HWC2::FunctionDescriptor::SetLayerTransform:
+      return ToHook<HWC2_PFN_SET_LAYER_TRANSFORM>(
+          LayerHook<decltype(&HwcLayer::SetLayerTransform),
+                    &HwcLayer::SetLayerTransform, int32_t>);
+    case HWC2::FunctionDescriptor::SetLayerVisibleRegion:
+      return ToHook<HWC2_PFN_SET_LAYER_VISIBLE_REGION>(
+          LayerHook<decltype(&HwcLayer::SetLayerVisibleRegion),
+                    &HwcLayer::SetLayerVisibleRegion, hwc_region_t>);
+    case HWC2::FunctionDescriptor::SetLayerZOrder:
+      return ToHook<HWC2_PFN_SET_LAYER_Z_ORDER>(
+          LayerHook<decltype(&HwcLayer::SetLayerZOrder),
+                    &HwcLayer::SetLayerZOrder, uint32_t>);
+    case HWC2::FunctionDescriptor::Invalid:
+    default:
+      return nullptr;
+  }
+}
+
+static int HookDevOpen(const struct hw_module_t *module, const char *name,
+                       struct hw_device_t **dev) {
+  if (strcmp(name, HWC_HARDWARE_COMPOSER) != 0) {
+    ALOGE("Invalid module name- %s", name);
+    return -EINVAL;
+  }
+
+  auto ctx = std::make_unique<Drmhwc2Device>();
+  if (!ctx) {
+    ALOGE("Failed to allocate DrmHwcTwo");
+    return -ENOMEM;
+  }
+
+  ctx->common.tag = HARDWARE_DEVICE_TAG;
+  ctx->common.version = HWC_DEVICE_API_VERSION_2_0;
+  ctx->common.close = HookDevClose;
+  // NOLINTNEXTLINE(cppcoreguidelines-pro-type-cstyle-cast)
+  ctx->common.module = (hw_module_t *)module;
+  ctx->getCapabilities = HookDevGetCapabilities;
+  ctx->getFunction = HookDevGetFunction;
+
+  HWC2::Error err = ctx->drmhwctwo.Init();
+  if (err != HWC2::Error::None) {
+    ALOGE("Failed to initialize DrmHwcTwo err=%d\n", err);
+    return -EINVAL;
+  }
+
+  *dev = &ctx.release()->common;
+
+  return 0;
+}
+
+}  // namespace android
+
+// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)
+static struct hw_module_methods_t hwc2_module_methods = {
+    .open = android::HookDevOpen,
+};
+
+// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)
+hw_module_t HAL_MODULE_INFO_SYM = {
+    .tag = HARDWARE_MODULE_TAG,
+    .module_api_version = HARDWARE_MODULE_API_VERSION(2, 0),
+    .id = HWC_HARDWARE_MODULE_ID,
+    .name = "DrmHwcTwo module",
+    .author = "The Android Open Source Project",
+    .methods = &hwc2_module_methods,
+    .dso = nullptr,
+    .reserved = {0},
+};
diff --git a/include/drmhwcgralloc.h b/include/drmhwcgralloc.h
index 09c7499..949912d 100644
--- a/include/drmhwcgralloc.h
+++ b/include/drmhwcgralloc.h
@@ -17,22 +17,26 @@
 #ifndef ANDROID_DRMHWCGRALLOC_H_
 #define ANDROID_DRMHWCGRALLOC_H_
 
-#include <stdint.h>
+#include <cstdint>
 
-#define HWC_DRM_BO_MAX_PLANES 4
-typedef struct hwc_drm_bo {
+constexpr int kHwcDrmBoMaxPlanes = 4;
+
+struct HwcDrmBo {
   uint32_t width;
   uint32_t height;
   uint32_t format;     /* DRM_FORMAT_* from drm_fourcc.h */
   uint32_t hal_format; /* HAL_PIXEL_FORMAT_* */
   uint32_t usage;
-  uint32_t pitches[HWC_DRM_BO_MAX_PLANES];
-  uint32_t offsets[HWC_DRM_BO_MAX_PLANES];
+  uint32_t pitches[kHwcDrmBoMaxPlanes];
+  uint32_t offsets[kHwcDrmBoMaxPlanes];
   /* sizes[] is used only by mapper@4 metadata getter for internal purposes */
-  uint32_t sizes[HWC_DRM_BO_MAX_PLANES];
-  int prime_fds[HWC_DRM_BO_MAX_PLANES];
-  uint64_t modifiers[HWC_DRM_BO_MAX_PLANES];
+  uint32_t sizes[kHwcDrmBoMaxPlanes];
+  int prime_fds[kHwcDrmBoMaxPlanes];
+  uint64_t modifiers[kHwcDrmBoMaxPlanes];
   int acquire_fence_fd;
-} hwc_drm_bo_t;
+};
+
+// NOLINTNEXTLINE(readability-identifier-naming)
+using hwc_drm_bo_t = HwcDrmBo;
 
 #endif  // ANDROID_DRMHWCGRALLOC_H_
diff --git a/include/drmhwcomposer.h b/include/drmhwcomposer.h
index d02445b..4fb0efd 100644
--- a/include/drmhwcomposer.h
+++ b/include/drmhwcomposer.h
@@ -19,9 +19,9 @@
 
 #include <hardware/hardware.h>
 #include <hardware/hwcomposer.h>
-#include <stdbool.h>
-#include <stdint.h>
 
+#include <cstdbool>
+#include <cstdint>
 #include <vector>
 
 #include "drm/DrmFbImporter.h"
@@ -61,14 +61,14 @@
 };
 
 struct DrmHwcLayer {
-  buffer_handle_t sf_handle = NULL;
+  buffer_handle_t sf_handle = nullptr;
   hwc_drm_bo_t buffer_info{};
-  std::shared_ptr<DrmFbIdHandle> FbIdHandle;
+  std::shared_ptr<DrmFbIdHandle> fb_id_handle;
 
   int gralloc_buffer_usage = 0;
   DrmHwcTransform transform{};
   DrmHwcBlending blending = DrmHwcBlending::kNone;
-  uint16_t alpha = 0xffff;
+  uint16_t alpha = UINT16_MAX;
   hwc_frect_t source_crop;
   hwc_rect_t display_frame;
   DrmHwcColorSpace color_space;
@@ -76,9 +76,9 @@
 
   UniqueFd acquire_fence;
 
-  int ImportBuffer(DrmDevice *drmDevice);
+  int ImportBuffer(DrmDevice *drm_device);
 
-  bool protected_usage() const {
+  bool IsProtected() const {
     return (gralloc_buffer_usage & GRALLOC_USAGE_PROTECTED) ==
            GRALLOC_USAGE_PROTECTED;
   }
diff --git a/presubmit.sh b/presubmit.sh
index 249aaf5..a551398 100755
--- a/presubmit.sh
+++ b/presubmit.sh
@@ -4,18 +4,10 @@
 
 echo "Run native build:"
 
-./.ci/.gitlab-ci-clang-build.sh
+make -f .ci/Makefile -j12
 
 echo "Run style check:"
 
 ./.ci/.gitlab-ci-checkcommit.sh
 
-echo "Run coarse clang-tidy check:"
-
-./.ci/.gitlab-ci-clang-tidy-coarse.sh
-
-echo "Run fine clang-tidy check:"
-
-./.ci/.gitlab-ci-clang-tidy-fine.sh
-
 echo -e "\n\e[32m --- SUCCESS ---"
diff --git a/utils/Worker.h b/utils/Worker.h
index 73a80da..ab01d5f 100644
--- a/utils/Worker.h
+++ b/utils/Worker.h
@@ -17,10 +17,9 @@
 #ifndef ANDROID_WORKER_H_
 #define ANDROID_WORKER_H_
 
-#include <stdint.h>
-#include <stdlib.h>
-
 #include <condition_variable>
+#include <cstdint>
+#include <cstdlib>
 #include <mutex>
 #include <string>
 #include <thread>
diff --git a/utils/autolock.cpp b/utils/autolock.cpp
deleted file mode 100644
index 3342e46..0000000
--- a/utils/autolock.cpp
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define ATRACE_TAG ATRACE_TAG_GRAPHICS
-#define LOG_TAG "hwc-drm-auto-lock"
-
-#include "autolock.h"
-
-#include <pthread.h>
-
-#include <cerrno>
-
-#include "utils/log.h"
-
-namespace android {
-
-int AutoLock::Lock() {
-  if (locked_) {
-    ALOGE("Invalid attempt to double lock AutoLock %s", name_);
-    return -EINVAL;
-  }
-  int ret = pthread_mutex_lock(mutex_);
-  if (ret) {
-    ALOGE("Failed to acquire %s lock %d", name_, ret);
-    return ret;
-  }
-  locked_ = true;
-  return 0;
-}
-
-int AutoLock::Unlock() {
-  if (!locked_) {
-    ALOGE("Invalid attempt to unlock unlocked AutoLock %s", name_);
-    return -EINVAL;
-  }
-  int ret = pthread_mutex_unlock(mutex_);
-  if (ret) {
-    ALOGE("Failed to release %s lock %d", name_, ret);
-    return ret;
-  }
-  locked_ = false;
-  return 0;
-}
-}  // namespace android
diff --git a/utils/autolock.h b/utils/autolock.h
deleted file mode 100644
index 006406a..0000000
--- a/utils/autolock.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (C) 2015 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.
- */
-
-#include <pthread.h>
-
-namespace android {
-
-class AutoLock {
- public:
-  AutoLock(pthread_mutex_t *mutex, const char *const name)
-      : mutex_(mutex), name_(name) {
-  }
-  ~AutoLock() {
-    if (locked_)
-      Unlock();
-  }
-
-  AutoLock(const AutoLock &rhs) = delete;
-  AutoLock &operator=(const AutoLock &rhs) = delete;
-
-  int Lock();
-  int Unlock();
-
- private:
-  pthread_mutex_t *const mutex_;
-  bool locked_ = false;
-  const char *const name_;
-};
-}  // namespace android
diff --git a/utils/hwcutils.cpp b/utils/hwcutils.cpp
index 5a46e9b..c537b99 100644
--- a/utils/hwcutils.cpp
+++ b/utils/hwcutils.cpp
@@ -17,30 +17,28 @@
 #define ATRACE_TAG ATRACE_TAG_GRAPHICS
 #define LOG_TAG "hwc-drm-utils"
 
-#include <log/log.h>
-#include <ui/Gralloc.h>
-#include <ui/GraphicBufferMapper.h>
+#include <utils/log.h>
+
+#include <cerrno>
 
 #include "bufferinfo/BufferInfoGetter.h"
 #include "drm/DrmFbImporter.h"
 #include "drmhwcomposer.h"
 
-#define UNUSED(x) (void)(x)
-
 namespace android {
 
-int DrmHwcLayer::ImportBuffer(DrmDevice *drmDevice) {
+int DrmHwcLayer::ImportBuffer(DrmDevice *drm_device) {
   buffer_info = hwc_drm_bo_t{};
 
   int ret = BufferInfoGetter::GetInstance()->ConvertBoInfo(sf_handle,
                                                            &buffer_info);
-  if (ret) {
+  if (ret != 0) {
     ALOGE("Failed to convert buffer info %d", ret);
     return ret;
   }
 
-  FbIdHandle = drmDevice->GetDrmFbImporter().GetOrCreateFbId(&buffer_info);
-  if (!FbIdHandle) {
+  fb_id_handle = drm_device->GetDrmFbImporter().GetOrCreateFbId(&buffer_info);
+  if (!fb_id_handle) {
     ALOGE("Failed to import buffer");
     return -EINVAL;
   }
diff --git a/utils/properties.h b/utils/properties.h
index c8ddbae..0b49c61 100644
--- a/utils/properties.h
+++ b/utils/properties.h
@@ -17,6 +17,7 @@
 // NOLINTNEXTLINE(readability-identifier-naming)
 auto inline property_get(const char *name, char *value,
                          const char *default_value) -> int {
+  // NOLINTNEXTLINE (concurrency-mt-unsafe)
   char *prop = std::getenv(name);
   snprintf(value, PROPERTY_VALUE_MAX, "%s",
            (prop == nullptr) ? default_value : prop);