diff --git a/Android.bp b/Android.bp
index 1eae1b0..8b6997e 100644
--- a/Android.bp
+++ b/Android.bp
@@ -1,40 +1,10 @@
-cc_defaults {
-    name: "display_defaults",
-    cflags: [
-        "-Wno-missing-field-initializers",
-        "-Wconversion",
-        "-Wall",
-        "-Werror",
-        "-std=c++14",
-    ],
-    shared_libs: [
-        "liblog",
-        "libcutils",
-        "libutils",
-    ],
-    header_libs: ["display_headers"],
-    clang: true,
-}
-
 cc_library_headers {
-    name: "display_headers",
+    name: "display_intf_headers",
     vendor_available: true,
     export_include_dirs: [
-        "include",
-        "libcopybit",
-        "libdrmutils",
-        "libqdutils",
-        "libqservice",
-        "gpu_tonemapper",
-        "sdm/include",
         "gralloc",
-        "libdebug",
+        "include",
+        "libdisplayconfig",
+        "libqdmetadata",
     ],
-    header_libs: ["libhardware_headers"],
-    export_header_lib_headers: ["libhardware_headers"],
 }
-
-subdirs = [
-    "libqservice",
-    "libqdutils",
-]
diff --git a/Android.mk b/Android.mk
deleted file mode 100644
index 707acf1..0000000
--- a/Android.mk
+++ /dev/null
@@ -1,19 +0,0 @@
-ifneq ($(TARGET_DISABLE_DISPLAY),true)
-sdm-libs := sdm/libs
-display-hals := include libdebug $(sdm-libs)/utils $(sdm-libs)/core
-
-ifneq ($(TARGET_IS_HEADLESS), true)
-    display-hals += libcopybit liblight libmemtrack hdmi_cec \
-                    $(sdm-libs)/hwc2 gpu_tonemapper libdrmutils libdisplayconfig
-endif
-
-display-hals += gralloc
-
-ifeq ($(call is-vendor-board-platform,QCOM),true)
-    include $(call all-named-subdir-makefiles,$(display-hals))
-else
-ifneq ($(filter msm% apq%,$(TARGET_BOARD_PLATFORM)),)
-    include $(call all-named-subdir-makefiles,$(display-hals))
-endif
-endif
-endif #TARGET_DISABLE_DISPLAY
diff --git a/Makefile.am b/Makefile.am
deleted file mode 100644
index 8ecc86b..0000000
--- a/Makefile.am
+++ /dev/null
@@ -1,5 +0,0 @@
-# Makefile.am - Automake script for sdm
-
-ACLOCAL_AMFLAGS = -I m4
-
-SUBDIRS = libqservice libqdutils sdm/libs/utils sdm/libs/core
diff --git a/common.mk b/common.mk
deleted file mode 100644
index c1b13ec..0000000
--- a/common.mk
+++ /dev/null
@@ -1,86 +0,0 @@
-#Common headers
-display_top := $(call my-dir)
-display_config_version := $(shell \
-    if [ -d "$(TOP)/vendor/qcom/opensource/interfaces/display/config/1.1" ];\
-    then echo DISPLAY_CONFIG_1_1; fi)
-
-#Common C flags
-common_flags := -Wno-missing-field-initializers
-common_flags += -Wconversion -Wall -Werror -std=c++14
-common_flags += -DUSE_GRALLOC1
-ifeq ($(TARGET_IS_HEADLESS), true)
-    common_flags += -DTARGET_HEADLESS
-    LOCAL_CLANG := false
-endif
-
-ifeq ($(display_config_version), DISPLAY_CONFIG_1_1)
-    common_flags += -DDISPLAY_CONFIG_1_1
-endif
-
-ifeq ($(TARGET_USES_COLOR_METADATA), true)
-    common_flags += -DUSE_COLOR_METADATA
-endif
-
-ifeq ($(TARGET_USES_QCOM_BSP),true)
-    common_flags += -DQTI_BSP
-endif
-
-ifeq ($(ARCH_ARM_HAVE_NEON),true)
-    common_flags += -D__ARM_HAVE_NEON
-endif
-
-ifeq ($(call is-board-platform-in-list, $(MASTER_SIDE_CP_TARGET_LIST)), true)
-    common_flags += -DMASTER_SIDE_CP
-endif
-
-use_hwc2 := false
-ifeq ($(TARGET_USES_HWC2), true)
-    use_hwc2 := true
-    common_flags += -DVIDEO_MODE_DEFER_RETIRE_FENCE
-endif
-
-ifneq (,$(filter userdebug eng, $(TARGET_BUILD_VARIANT)))
-    common_flags += -DUSER_DEBUG
-endif
-
-ifeq ($(LLVM_SA), true)
-    common_flags += --compile-and-analyze --analyzer-perf --analyzer-Werror
-endif
-
-common_includes := system/core/base/include
-CHECK_VERSION_LE = $(shell if [ $(1) -le $(2) ] ; then echo true ; else echo false ; fi)
-PLATFORM_SDK_NOUGAT = 25
-ifeq "REL" "$(PLATFORM_VERSION_CODENAME)"
-ifeq ($(call CHECK_VERSION_LE, $(PLATFORM_SDK_VERSION), $(PLATFORM_SDK_NOUGAT)), true)
-version_flag := -D__NOUGAT__
-
-# These include paths are deprecated post N
-common_includes += $(display_top)/libqdutils
-common_includes += $(display_top)/libqservice
-common_includes += $(display_top)/gpu_tonemapper
-ifneq ($(TARGET_IS_HEADLESS), true)
-    common_includes += $(display_top)/libcopybit
-endif
-
-common_includes += $(display_top)/include
-common_includes += $(display_top)/sdm/include
-common_flags += -isystem $(TARGET_OUT_HEADERS)/qcom/display
-endif
-endif
-
-common_header_export_path := qcom/display
-
-#Common libraries external to display HAL
-common_libs := liblog libutils libcutils libhardware
-common_deps  :=
-kernel_includes :=
-
-ifeq ($(TARGET_COMPILE_WITH_MSM_KERNEL),true)
-# This check is to pick the kernel headers from the right location.
-# If the macro above is defined, we make the assumption that we have the kernel
-# available in the build tree.
-# If the macro is not present, the headers are picked from hardware/qcom/msmXXXX
-# failing which, they are picked from bionic.
-    common_deps += $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr
-    kernel_includes += $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr/include
-endif
diff --git a/config/sdm845.mk b/config/sdm845.mk
deleted file mode 100644
index b7be15b..0000000
--- a/config/sdm845.mk
+++ /dev/null
@@ -1,43 +0,0 @@
-#Display related packages and configuration
-
-PRODUCT_PACKAGES += \
-    android.hardware.graphics.composer@2.1-impl \
-    android.hardware.graphics.composer@2.1-service \
-    android.hardware.graphics.mapper@2.0-impl-qti-display \
-    vendor.qti.hardware.display.allocator@1.0-service \
-    android.hardware.memtrack@1.0-impl \
-    android.hardware.memtrack@1.0-service \
-    android.hardware.light@2.0-impl \
-    android.hardware.light@2.0-service \
-    modetest \
-    gralloc.sdm845 \
-    lights.sdm845 \
-    hwcomposer.sdm845 \
-    memtrack.sdm845 \
-    libqdutils \
-    libqdMetaData \
-    libqdMetaData.system
-
-
-TARGET_FORCE_HWC_FOR_VIRTUAL_DISPLAYS := true
-MAX_VIRTUAL_DISPLAY_DIMENSION := 4096
-NUM_FRAMEBUFFER_SURFACE_BUFFERS := 2
-#Enable Charging Icon
-TARGET_RECOVERY_PIXEL_FORMAT := RGBX_8888
-TARGET_USES_GRALLOC1 := true
-TARGET_USES_HWC2 := true
-TARGET_USES_QCOM_DISPLAY_BSP := true
-TARGET_USES_COLOR_METADATA := true
-TARGET_USES_DRM_PP := true
-
-PRODUCT_PROPERTY_OVERRIDES += \
-    debug.sf.enable_hwc_vds=1 \
-    persist.demo.hdmirotationlock=false \
-    ro.vendor.display.cabl=2 \
-    debug.sf.hw=0 \
-    debug.egl.hw=0 \
-    debug.sf.latch_unsignaled=1
-
-
-
-
diff --git a/configure.ac b/configure.ac
deleted file mode 100644
index 24c41fd..0000000
--- a/configure.ac
+++ /dev/null
@@ -1,56 +0,0 @@
-#                                               -*- Autoconf -*-
-# configure.ac -- Autoconf script for sdm
-#
-
-# Process this file with autoconf to produce a configure script
-
-# Requires autoconf tool later than 2.61
-AC_PREREQ(2.61)
-# Initialize the display package version 1.0.0
-AC_INIT([display],1.0.0)
-# Does not strictly follow GNU Coding standards
-AM_INIT_AUTOMAKE([foreign])
-# Disables auto rebuilding of configure, Makefile.ins
-AM_MAINTAINER_MODE
-# defines some macros variable to be included by source
-AC_CONFIG_HEADERS([config.h])
-AC_CONFIG_MACRO_DIR([m4])
-AC_SUBST([COMMON_CFLAGS], [-Wall -Werror -Wno-sign-conversion -Wconversion -DDEBUG_CALC_FPS])
-AC_SUBST([AM_CPPFLAGS], [--std=c++11])
-
-AC_ARG_WITH([core_includes],
-    AC_HELP_STRING([--with-core-includes=@<:@dir@:>@],
-       [Specify the location of the core headers]),
-    [core_incdir=$withval],
-    with_core_includes=no)
-
-if test "x$with_core_includes" != "xno"; then
-   CFLAGS="${CFLAGS} -I${core_incdir}"
-fi
-
-AC_ARG_WITH(sanitized-headers,
-   AS_HELP_STRING([--with-sanitized-headers=DIR],
-       [Specify the location of the sanitized Linux headers]),
-   [CPPFLAGS="$CPPFLAGS -idirafter $withval"])
-
-# Checks for programs.
-AC_PROG_CC
-AM_PROG_CC_C_O
-AC_PROG_CXX
-AC_PROG_LIBTOOL
-AC_PROG_AWK
-AC_PROG_CPP
-AC_PROG_INSTALL
-AC_PROG_LN_S
-AC_PROG_MAKE_SET
-
-AC_SUBST([CFLAGS])
-AC_SUBST([CC])
-AC_CONFIG_FILES([ \
-        Makefile \
-        libqservice/Makefile \
-        libqdutils/Makefile \
-        sdm/libs/utils/Makefile \
-        sdm/libs/core/Makefile
-        ])
-AC_OUTPUT
diff --git a/gpu_tonemapper/Android.mk b/gpu_tonemapper/Android.mk
deleted file mode 100644
index 6c6ccd1..0000000
--- a/gpu_tonemapper/Android.mk
+++ /dev/null
@@ -1,28 +0,0 @@
-LOCAL_PATH := $(call my-dir)
-include $(LOCAL_PATH)/../common.mk
-
-include $(CLEAR_VARS)
-LOCAL_COPY_HEADERS_TO     := $(common_header_export_path)
-LOCAL_COPY_HEADERS        := TonemapFactory.h Tonemapper.h
-LOCAL_VENDOR_MODULE       := true
-include $(BUILD_COPY_HEADERS)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE              := libgpu_tonemapper
-LOCAL_VENDOR_MODULE       := true
-LOCAL_MODULE_TAGS         := optional
-LOCAL_C_INCLUDES          := $(TARGET_OUT_HEADERS)/qcom/display/
-LOCAL_C_INCLUDES          += $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr/include
-LOCAL_SHARED_LIBRARIES    := libEGL libGLESv2 libGLESv3 libui libutils liblog
-LOCAL_ADDITIONAL_DEPENDENCIES := $(common_deps) $(kernel_deps)
-
-LOCAL_CFLAGS              := $(version_flag) -Wno-missing-field-initializers -Wall \
-                             -Wno-unused-parameter -std=c++11 -DLOG_TAG=\"GPU_TONEMAPPER\"
-
-LOCAL_SRC_FILES           := TonemapFactory.cpp \
-                             glengine.cpp \
-                             EGLImageBuffer.cpp \
-                             EGLImageWrapper.cpp \
-                             Tonemapper.cpp
-
-include $(BUILD_SHARED_LIBRARY)
diff --git a/gpu_tonemapper/EGLImageBuffer.cpp b/gpu_tonemapper/EGLImageBuffer.cpp
deleted file mode 100644
index eeb0273..0000000
--- a/gpu_tonemapper/EGLImageBuffer.cpp
+++ /dev/null
@@ -1,161 +0,0 @@
-/*
- * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
- * Not a Contribution.
- *
- * Copyright 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 "EGLImageBuffer.h"
-#include <cutils/native_handle.h>
-#include <gralloc_priv.h>
-#include <ui/GraphicBuffer.h>
-#include <map>
-#include "EGLImageWrapper.h"
-#include "glengine.h"
-
-//-----------------------------------------------------------------------------
-EGLImageKHR create_eglImage(android::sp<android::GraphicBuffer> graphicBuffer)
-//-----------------------------------------------------------------------------
-{
-  bool isProtected = (graphicBuffer->getUsage() & GRALLOC_USAGE_PROTECTED);
-  EGLint attrs[] = {EGL_IMAGE_PRESERVED_KHR, EGL_TRUE,
-                    isProtected ? EGL_PROTECTED_CONTENT_EXT : EGL_NONE,
-                    isProtected ? EGL_TRUE : EGL_NONE, EGL_NONE};
-
-  EGLImageKHR eglImage = eglCreateImageKHR(
-      eglGetCurrentDisplay(), (EGLContext)EGL_NO_CONTEXT, EGL_NATIVE_BUFFER_ANDROID,
-      (EGLClientBuffer)(graphicBuffer->getNativeBuffer()), attrs);
-
-  return eglImage;
-}
-
-//-----------------------------------------------------------------------------
-EGLImageBuffer::EGLImageBuffer(android::sp<android::GraphicBuffer> graphicBuffer)
-//-----------------------------------------------------------------------------
-{
-  // this->graphicBuffer = graphicBuffer;
-  this->eglImageID = create_eglImage(graphicBuffer);
-  this->width = graphicBuffer->getWidth();
-  this->height = graphicBuffer->getHeight();
-
-  textureID = 0;
-  renderbufferID = 0;
-  framebufferID = 0;
-}
-
-//-----------------------------------------------------------------------------
-EGLImageBuffer::~EGLImageBuffer()
-//-----------------------------------------------------------------------------
-{
-  if (textureID != 0) {
-    GL(glDeleteTextures(1, &textureID));
-    textureID = 0;
-  }
-
-  if (renderbufferID != 0) {
-    GL(glDeleteRenderbuffers(1, &renderbufferID));
-    renderbufferID = 0;
-  }
-
-  if (framebufferID != 0) {
-    GL(glDeleteFramebuffers(1, &framebufferID));
-    framebufferID = 0;
-  }
-
-  // Delete the eglImage
-  if (eglImageID != 0)
-  {
-      eglDestroyImageKHR(eglGetCurrentDisplay(), eglImageID);
-      eglImageID = 0;
-  }
-}
-
-//-----------------------------------------------------------------------------
-int EGLImageBuffer::getWidth()
-//-----------------------------------------------------------------------------
-{
-  return width;
-}
-
-//-----------------------------------------------------------------------------
-int EGLImageBuffer::getHeight()
-//-----------------------------------------------------------------------------
-{
-  return height;
-}
-
-//-----------------------------------------------------------------------------
-unsigned int EGLImageBuffer::getTexture()
-//-----------------------------------------------------------------------------
-{
-  if (textureID == 0) {
-    bindAsTexture();
-  }
-
-  return textureID;
-}
-
-//-----------------------------------------------------------------------------
-unsigned int EGLImageBuffer::getFramebuffer()
-//-----------------------------------------------------------------------------
-{
-  if (framebufferID == 0) {
-    bindAsFramebuffer();
-  }
-
-  return framebufferID;
-}
-
-//-----------------------------------------------------------------------------
-void EGLImageBuffer::bindAsTexture()
-//-----------------------------------------------------------------------------
-{
-  if (textureID == 0) {
-    GL(glGenTextures(1, &textureID));
-    int target = 0x8D65;
-    GL(glBindTexture(target, textureID));
-    GL(glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
-    GL(glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
-    GL(glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
-    GL(glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
-
-    GL(glEGLImageTargetTexture2DOES(0x8D65, eglImageID));
-  }
-
-  GL(glBindTexture(0x8D65, textureID));
-}
-
-//-----------------------------------------------------------------------------
-void EGLImageBuffer::bindAsFramebuffer()
-//-----------------------------------------------------------------------------
-{
-  if (renderbufferID == 0) {
-    GL(glGenFramebuffers(1, &framebufferID));
-    GL(glGenRenderbuffers(1, &renderbufferID));
-
-    GL(glBindRenderbuffer(GL_RENDERBUFFER, renderbufferID));
-    GL(glEGLImageTargetRenderbufferStorageOES(GL_RENDERBUFFER, eglImageID));
-
-    GL(glBindFramebuffer(GL_FRAMEBUFFER, framebufferID));
-    GL(glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
-                                 renderbufferID));
-    GLenum result = glCheckFramebufferStatus(GL_FRAMEBUFFER);
-    if (result != GL_FRAMEBUFFER_COMPLETE) {
-      ALOGI("%s Framebuffer Invalid***************", __FUNCTION__);
-    }
-  }
-
-  GL(glBindFramebuffer(GL_FRAMEBUFFER, framebufferID));
-}
diff --git a/gpu_tonemapper/EGLImageBuffer.h b/gpu_tonemapper/EGLImageBuffer.h
deleted file mode 100644
index 23af573..0000000
--- a/gpu_tonemapper/EGLImageBuffer.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright (c) 2016, The Linux Foundation. All rights reserved.
- * Not a Contribution.
- *
- * Copyright 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.
- */
-
-#ifndef __EGLIMAGE_BUFFER_H__
-#define __EGLIMAGE_BUFFER_H__
-
-#include <cutils/native_handle.h>
-#include <gralloc_priv.h>
-#include <ui/GraphicBuffer.h>
-#include "engine.h"
-
-class EGLImageBuffer {
-  // android::sp<android::GraphicBuffer> graphicBuffer;
-  void *eglImageID;
-  int width;
-  int height;
-  uint textureID;
-  uint renderbufferID;
-  uint framebufferID;
-
- public:
-  int getWidth();
-  int getHeight();
-  EGLImageBuffer(android::sp<android::GraphicBuffer>);
-  unsigned int getTexture();
-  unsigned int getFramebuffer();
-  void bindAsTexture();
-  void bindAsFramebuffer();
-  ~EGLImageBuffer();
-  static EGLImageBuffer *from(const private_handle_t *src);
-  static void clear();
-};
-
-#endif  //__EGLIMAGE_BUFFER_H__
\ No newline at end of file
diff --git a/gpu_tonemapper/EGLImageWrapper.cpp b/gpu_tonemapper/EGLImageWrapper.cpp
deleted file mode 100644
index dfc16d8..0000000
--- a/gpu_tonemapper/EGLImageWrapper.cpp
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
- * Not a Contribution.
- *
- * Copyright 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 "EGLImageWrapper.h"
-#include <cutils/native_handle.h>
-#include <gralloc_priv.h>
-#include <ui/GraphicBuffer.h>
-#include <fcntl.h>
-#include <linux/msm_ion.h>
-
-//-----------------------------------------------------------------------------
-void free_ion_cookie(int ion_fd, int cookie)
-//-----------------------------------------------------------------------------
-{
-  if (ion_fd && !ioctl(ion_fd, ION_IOC_FREE, &cookie)) {
-  } else {
-      ALOGE("ION_IOC_FREE failed: ion_fd = %d, cookie = %d", ion_fd, cookie);
-  }
-}
-
-//-----------------------------------------------------------------------------
-int get_ion_cookie(int ion_fd, int fd)
-//-----------------------------------------------------------------------------
-{
-   int cookie = fd;
-
-   struct ion_fd_data fdData;
-   memset(&fdData, 0, sizeof(fdData));
-   fdData.fd = fd;
-
-   if (ion_fd && !ioctl(ion_fd, ION_IOC_IMPORT, &fdData)) {
-        cookie = fdData.handle;
-   } else {
-        ALOGE("ION_IOC_IMPORT failed: ion_fd = %d, fd = %d", ion_fd, fd);
-   }
-
-   return cookie;
-}
-
-//-----------------------------------------------------------------------------
-EGLImageWrapper::DeleteEGLImageCallback::DeleteEGLImageCallback(int fd)
-//-----------------------------------------------------------------------------
-{
-    ion_fd = fd;
-}
-
-//-----------------------------------------------------------------------------
-void EGLImageWrapper::DeleteEGLImageCallback::operator()(int& k, EGLImageBuffer*& eglImage)
-//-----------------------------------------------------------------------------
-{
-    free_ion_cookie(ion_fd,  k);
-    if( eglImage != 0 )
-    {
-        delete eglImage;
-    }
-}
-
-//-----------------------------------------------------------------------------
-EGLImageWrapper::EGLImageWrapper()
-//-----------------------------------------------------------------------------
-{
-    eglImageBufferMap = new android::LruCache<int, EGLImageBuffer*>(32);
-    ion_fd = open("/dev/ion", O_RDONLY);
-    callback = new DeleteEGLImageCallback(ion_fd);
-    eglImageBufferMap->setOnEntryRemovedListener(callback);
-}
-
-//-----------------------------------------------------------------------------
-EGLImageWrapper::~EGLImageWrapper()
-//-----------------------------------------------------------------------------
-{
-    if( eglImageBufferMap != 0 )
-    {
-        eglImageBufferMap->clear();
-        delete eglImageBufferMap;
-        eglImageBufferMap = 0;
-    }
-
-    if( callback != 0 )
-    {
-        delete callback;
-        callback = 0;
-    }
-
-    if( ion_fd > 0 )
-    {
-        close(ion_fd);
-    }
-    ion_fd = -1;
-}
-//-----------------------------------------------------------------------------
-static EGLImageBuffer* L_wrap(const private_handle_t *src)
-//-----------------------------------------------------------------------------
-{
-    EGLImageBuffer* result = 0;
-
-    native_handle_t *native_handle = const_cast<private_handle_t *>(src);
-
-    int flags = android::GraphicBuffer::USAGE_HW_TEXTURE |
-                android::GraphicBuffer::USAGE_SW_READ_NEVER |
-                android::GraphicBuffer::USAGE_SW_WRITE_NEVER;
-
-    if (src->flags & private_handle_t::PRIV_FLAGS_SECURE_BUFFER) {
-      flags |= android::GraphicBuffer::USAGE_PROTECTED;
-    }
-
-    android::sp<android::GraphicBuffer> graphicBuffer =
-        new android::GraphicBuffer(src->unaligned_width, src->unaligned_height, src->format,
-#ifndef __NOUGAT__
-                                   1, // Layer count
-#endif
-                                   flags, src->width /*src->stride*/,
-                                   native_handle, false);
-
-    result = new EGLImageBuffer(graphicBuffer);
-
-    return result;
-}
-
-//-----------------------------------------------------------------------------
-EGLImageBuffer *EGLImageWrapper::wrap(const void *pvt_handle)
-//-----------------------------------------------------------------------------
-{
-    const private_handle_t *src = static_cast<const private_handle_t *>(pvt_handle);
-
-    int ion_cookie = get_ion_cookie(ion_fd, src->fd);
-    EGLImageBuffer* eglImage = eglImageBufferMap->get(ion_cookie);
-    if( eglImage == 0 )
-    {
-        eglImage = L_wrap(src);
-        eglImageBufferMap->put(ion_cookie, eglImage);
-    }
-    else {
-        free_ion_cookie(ion_fd, ion_cookie);
-    }
-
-    return eglImage;
-}
diff --git a/gpu_tonemapper/EGLImageWrapper.h b/gpu_tonemapper/EGLImageWrapper.h
deleted file mode 100644
index e9a4d68..0000000
--- a/gpu_tonemapper/EGLImageWrapper.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
- * Not a Contribution.
- *
- * Copyright 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.
- */
-
-#ifndef __TONEMAPPER_EGLIMAGEWRAPPER_H__
-#define __TONEMAPPER_EGLIMAGEWRAPPER_H__
-
-#include <utils/LruCache.h>
-#include "EGLImageBuffer.h"
-
-class EGLImageWrapper {
-    private:
-        class DeleteEGLImageCallback : public android::OnEntryRemoved<int, EGLImageBuffer*>
-        {
-        private:
-          int ion_fd;
-        public:
-          DeleteEGLImageCallback(int ion_fd);
-          void operator()(int& ion_cookie, EGLImageBuffer*& eglImage);
-        };
-
-        android::LruCache<int, EGLImageBuffer *>* eglImageBufferMap;
-        DeleteEGLImageCallback* callback;
-        int ion_fd;
-
-    public:
-        EGLImageWrapper();
-        ~EGLImageWrapper();
-        EGLImageBuffer* wrap(const void *pvt_handle);
-};
-
-#endif  //__TONEMAPPER_EGLIMAGEWRAPPER_H__
diff --git a/gpu_tonemapper/TonemapFactory.cpp b/gpu_tonemapper/TonemapFactory.cpp
deleted file mode 100644
index db4b8be..0000000
--- a/gpu_tonemapper/TonemapFactory.cpp
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
- * Not a Contribution.
- *
- * Copyright 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 "TonemapFactory.h"
-#include <log/log.h>
-#include "Tonemapper.h"
-#include "engine.h"
-
-//----------------------------------------------------------------------------------------------------------------------------------------------------------
-Tonemapper *TonemapperFactory_GetInstance(int type, void *colorMap, int colorMapSize,
-                                          void *lutXform, int lutXformSize, bool isSecure)
-//----------------------------------------------------------------------------------------------------------------------------------------------------------
-{
-  // build the tonemapper
-  Tonemapper *tonemapper = Tonemapper::build(type, colorMap, colorMapSize, lutXform, lutXformSize, isSecure);
-
-  return tonemapper;
-}
diff --git a/gpu_tonemapper/TonemapFactory.h b/gpu_tonemapper/TonemapFactory.h
deleted file mode 100644
index 17cad40..0000000
--- a/gpu_tonemapper/TonemapFactory.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (c) 2016, The Linux Foundation. All rights reserved.
- * Not a Contribution.
- *
- * Copyright 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.
- */
-
-#ifndef __TONEMAPPER_TONEMAPPERFACTORY_H__
-#define __TONEMAPPER_TONEMAPPERFACTORY_H__
-
-#include "Tonemapper.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-// returns an instance of Tonemapper
-Tonemapper *TonemapperFactory_GetInstance(int type, void *colorMap, int colorMapSize,
-                                          void *lutXform, int lutXformSize, bool isSecure);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif  //__TONEMAPPER_TONEMAPPERFACTORY_H__
diff --git a/gpu_tonemapper/Tonemapper.cpp b/gpu_tonemapper/Tonemapper.cpp
deleted file mode 100644
index 811e091..0000000
--- a/gpu_tonemapper/Tonemapper.cpp
+++ /dev/null
@@ -1,153 +0,0 @@
-/*
- * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
- * Not a Contribution.
- *
- * Copyright 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 <utils/Log.h>
-
-#include "EGLImageWrapper.h"
-#include "Tonemapper.h"
-#include "engine.h"
-#include "forward_tonemap.inl"
-#include "fullscreen_vertex_shader.inl"
-#include "rgba_inverse_tonemap.inl"
-
-//-----------------------------------------------------------------------------
-Tonemapper::Tonemapper()
-//-----------------------------------------------------------------------------
-{
-  tonemapTexture = 0;
-  lutXformTexture = 0;
-  programID = 0;
-  eglImageWrapper = new EGLImageWrapper();
-
-  lutXformScaleOffset[0] = 1.0f;
-  lutXformScaleOffset[1] = 0.0f;
-
-  tonemapScaleOffset[0] = 1.0f;
-  tonemapScaleOffset[1] = 0.0f;
-}
-
-//-----------------------------------------------------------------------------
-Tonemapper::~Tonemapper()
-//-----------------------------------------------------------------------------
-{
-  engine_bind(engineContext);
-  engine_deleteInputBuffer(tonemapTexture);
-  engine_deleteInputBuffer(lutXformTexture);
-  engine_deleteProgram(programID);
-
-  // clear EGLImage mappings
-  if (eglImageWrapper != 0) {
-    delete eglImageWrapper;
-    eglImageWrapper = 0;
-  }
-
-  engine_shutdown(engineContext);
-}
-
-//-----------------------------------------------------------------------------
-Tonemapper *Tonemapper::build(int type, void *colorMap, int colorMapSize, void *lutXform,
-                              int lutXformSize, bool isSecure)
-//-----------------------------------------------------------------------------
-{
-  if (colorMapSize <= 0) {
-      ALOGE("Invalid Color Map size = %d", colorMapSize);
-      return NULL;
-  }
-
-  // build new tonemapper
-  Tonemapper *tonemapper = new Tonemapper();
-
-  tonemapper->engineContext = engine_initialize(isSecure);
-
-  engine_bind(tonemapper->engineContext);
-
-  // load the 3d lut
-  tonemapper->tonemapTexture = engine_load3DTexture(colorMap, colorMapSize, 0);
-  tonemapper->tonemapScaleOffset[0] = ((float)(colorMapSize-1))/((float)(colorMapSize));
-  tonemapper->tonemapScaleOffset[1] = 1.0f/(2.0f*colorMapSize);
-
-  // load the non-uniform xform
-  tonemapper->lutXformTexture = engine_load1DTexture(lutXform, lutXformSize, 0);
-  bool bUseXform = (tonemapper->lutXformTexture != 0) && (lutXformSize != 0);
-  if( bUseXform )
-  {
-      tonemapper->lutXformScaleOffset[0] = ((float)(lutXformSize-1))/((float)(lutXformSize));
-      tonemapper->lutXformScaleOffset[1] = 1.0f/(2.0f*lutXformSize);
-  }
-
-  // create the program
-  const char *fragmentShaders[3];
-  int fragmentShaderCount = 0;
-  const char *version = "#version 300 es\n";
-  const char *define = "#define USE_NONUNIFORM_SAMPLING\n";
-
-  fragmentShaders[fragmentShaderCount++] = version;
-
-  // non-uniform sampling
-  if (bUseXform) {
-    fragmentShaders[fragmentShaderCount++] = define;
-  }
-
-  if (type == TONEMAP_INVERSE) {  // inverse tonemapping
-    fragmentShaders[fragmentShaderCount++] = rgba_inverse_tonemap_shader;
-  } else {  // forward tonemapping
-    fragmentShaders[fragmentShaderCount++] = forward_tonemap_shader;
-  }
-
-  tonemapper->programID =
-      engine_loadProgram(1, &fullscreen_vertex_shader, fragmentShaderCount, fragmentShaders);
-
-  return tonemapper;
-}
-
-//-----------------------------------------------------------------------------
-int Tonemapper::blit(const void *dst, const void *src, int srcFenceFd)
-//-----------------------------------------------------------------------------
-{
-  // make current
-  engine_bind(engineContext);
-
-  // create eglimages if required
-  EGLImageBuffer *dst_buffer = eglImageWrapper->wrap(dst);
-  EGLImageBuffer *src_buffer = eglImageWrapper->wrap(src);
-
-  // bind the program
-  engine_setProgram(programID);
-
-  engine_setData2f(3, tonemapScaleOffset);
-  bool bUseXform = (lutXformTexture != 0);
-  if( bUseXform )
-  {
-    engine_setData2f(4, lutXformScaleOffset);
-  }
-
-  // set destination
-  engine_setDestination(dst_buffer->getFramebuffer(), 0, 0, dst_buffer->getWidth(),
-                        dst_buffer->getHeight());
-  // set source
-  engine_setExternalInputBuffer(0, src_buffer->getTexture());
-  // set 3d lut
-  engine_set3DInputBuffer(1, tonemapTexture);
-  // set non-uniform xform
-  engine_set2DInputBuffer(2, lutXformTexture);
-
-  // perform
-  int fenceFD = engine_blit(srcFenceFd);
-
-  return fenceFD;
-}
diff --git a/gpu_tonemapper/Tonemapper.h b/gpu_tonemapper/Tonemapper.h
deleted file mode 100644
index 707cdfe..0000000
--- a/gpu_tonemapper/Tonemapper.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
- * Not a Contribution.
- *
- * Copyright 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.
- */
-
-#ifndef __TONEMAPPER_TONEMAP_H__
-#define __TONEMAPPER_TONEMAP_H__
-
-#define TONEMAP_FORWARD 0
-#define TONEMAP_INVERSE 1
-
-#include "EGLImageWrapper.h"
-#include "engine.h"
-
-class Tonemapper {
- private:
-  void* engineContext;
-  unsigned int tonemapTexture;
-  unsigned int lutXformTexture;
-  unsigned int programID;
-  float lutXformScaleOffset[2];
-  float tonemapScaleOffset[2];
-  EGLImageWrapper* eglImageWrapper;
-  Tonemapper();
-
- public:
-  ~Tonemapper();
-  static Tonemapper *build(int type, void *colorMap, int colorMapSize, void *lutXform,
-                           int lutXformSize, bool isSecure);
-  int blit(const void *dst, const void *src, int srcFenceFd);
-};
-
-#endif  //__TONEMAPPER_TONEMAP_H__
diff --git a/gpu_tonemapper/engine.h b/gpu_tonemapper/engine.h
deleted file mode 100644
index 8fb9452..0000000
--- a/gpu_tonemapper/engine.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
- * Not a Contribution.
- *
- * Copyright 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.
- */
-
-#ifndef __TONEMAPPER_ENGINE_H__
-#define __TONEMAPPER_ENGINE_H__
-
-void* engine_initialize(bool isSecure);
-void engine_bind(void*);
-void engine_shutdown(void*);
-
-unsigned int engine_loadProgram(int, const char **, int, const char **);
-void engine_setProgram(int);
-void engine_deleteProgram(unsigned int);
-
-unsigned int engine_load3DTexture(void *data, int sz, int format);
-unsigned int engine_load1DTexture(void *xform, int xformSize, int format);
-void engine_deleteInputBuffer(unsigned int);
-
-void engine_set2DInputBuffer(int binding, unsigned int textureID);
-void engine_set3DInputBuffer(int binding, unsigned int textureID);
-void engine_setExternalInputBuffer(int binding, unsigned int textureID);
-void engine_setDestination(int id, int x, int y, int w, int h);
-void engine_setData2f(int loc, float* data);
-
-int engine_blit(int);
-
-#endif  //__TONEMAPPER_ENGINE_H__
diff --git a/gpu_tonemapper/forward_tonemap.inl b/gpu_tonemapper/forward_tonemap.inl
deleted file mode 100644
index 0d89a9e..0000000
--- a/gpu_tonemapper/forward_tonemap.inl
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
- * Not a Contribution.
- *
- * Copyright 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.
- */
-
-const char* forward_tonemap_shader = ""
-    "#extension GL_OES_EGL_image_external_essl3 : require                       \n"
-    "precision highp float;                                                     \n"
-    "precision highp sampler2D;                                                 \n"
-    "layout(binding = 0) uniform samplerExternalOES externalTexture;            \n"
-    "layout(binding = 1) uniform sampler3D tonemapper;                          \n"
-    "layout(binding = 2) uniform sampler2D xform;                               \n"
-    "layout(location = 3) uniform vec2 tSO;                                     \n"
-    "#ifdef USE_NONUNIFORM_SAMPLING                                             \n"
-    "layout(location = 4) uniform vec2 xSO;                                     \n"
-    "#endif                                                                     \n"
-    "in vec2 uv;                                                                \n"
-    "out vec4 fs_color;                                                         \n"
-    "                                                                           \n"
-    "vec3 ScaleOffset(in vec3 samplePt, in vec2 so)                             \n"
-    "{                                                                          \n"
-    "   vec3 adjPt = so.x * samplePt + so.y;                                    \n"
-    "   return adjPt;                                                           \n"
-    "}                                                                          \n"
-    "                                                                           \n"
-    "void main()                                                                \n"
-    "{                                                                          \n"
-    "vec2 flipped = vec2(uv.x, 1.0f - uv.y);                                    \n"
-    "vec4 rgb = texture(externalTexture, flipped);                              \n"
-    "#ifdef USE_NONUNIFORM_SAMPLING                                             \n"
-    "vec3 adj = ScaleOffset(rgb.xyz, xSO);                                      \n"
-    "float r = texture(xform, vec2(adj.r, 0.5f)).r;                             \n"
-    "float g = texture(xform, vec2(adj.g, 0.5f)).g;                             \n"
-    "float b = texture(xform, vec2(adj.b, 0.5f)).b;                             \n"
-    "#else                                                                      \n"
-    "float r = rgb.r;                                                           \n"
-    "float g = rgb.g;                                                           \n"
-    "float b = rgb.b;                                                           \n"
-    "#endif                                                                     \n"
-    "fs_color.rgb = texture(tonemapper, ScaleOffset(vec3(r, g, b), tSO)).rgb;   \n"
-    "}                                                                          \n";
diff --git a/gpu_tonemapper/fullscreen_vertex_shader.inl b/gpu_tonemapper/fullscreen_vertex_shader.inl
deleted file mode 100644
index 9a70c2b..0000000
--- a/gpu_tonemapper/fullscreen_vertex_shader.inl
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (c) 2016, The Linux Foundation. All rights reserved.
- * Not a Contribution.
- *
- * Copyright 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.
- */
-
-const char* fullscreen_vertex_shader = "                                      "
-"#version 300 es                                                            \n"
-"precision highp float;                                                     \n"
-"layout(location = 0) in vec2 iUV;                                          \n"
-"out vec2 uv;                                                               \n"
-"void main()                                                                \n"
-"{                                                                          \n"
-"    vec2 positions[3];                                                     \n"
-"    positions[0] = vec2(-1.0f, 3.0f);                                      \n"
-"    positions[1] = vec2(-1.0f, -1.0f);                                     \n"
-"    positions[2] = vec2(3.0f, -1.0f);                                      \n"
-"    vec2 uvs[3];                                                           \n"
-"    uvs[0] = vec2(0.0f, -1.0f);                                            \n"
-"    uvs[1] = vec2(0.0f, 1.0f);                                             \n"
-"    uvs[2] = vec2(2.0f, 1.0f);                                             \n"
-"    gl_Position = vec4(positions[gl_VertexID], -1.0f, 1.0f);               \n"
-"    uv = uvs[gl_VertexID];                                                 \n"
-"}                                                                          \n";
diff --git a/gpu_tonemapper/glengine.cpp b/gpu_tonemapper/glengine.cpp
deleted file mode 100644
index 35e1932..0000000
--- a/gpu_tonemapper/glengine.cpp
+++ /dev/null
@@ -1,415 +0,0 @@
-/*
- * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
- * Not a Contribution.
- *
- * Copyright 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 "glengine.h"
-#include <log/log.h>
-#include "engine.h"
-
-void checkGlError(const char *, int);
-void checkEglError(const char *, int);
-
-class EngineContext {
-    public:
-    EGLDisplay eglDisplay;
-    EGLContext eglContext;
-    EGLSurface eglSurface;
-    EngineContext()
-    {
-        eglDisplay = EGL_NO_DISPLAY;
-        eglContext = EGL_NO_CONTEXT;
-        eglSurface = EGL_NO_SURFACE;
-    }
-};
-
-//-----------------------------------------------------------------------------
-// Make Current
-void engine_bind(void* context)
-//-----------------------------------------------------------------------------
-{
-  EngineContext* engineContext = (EngineContext*)(context);
-  EGL(eglMakeCurrent(engineContext->eglDisplay, engineContext->eglSurface, engineContext->eglSurface, engineContext->eglContext));
-}
-
-//-----------------------------------------------------------------------------
-// initialize GL
-//
-void* engine_initialize(bool isSecure)
-//-----------------------------------------------------------------------------
-{
-  EngineContext* engineContext = new EngineContext();
-
-  // display
-  engineContext->eglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
-  EGL(eglBindAPI(EGL_OPENGL_ES_API));
-
-  // initialize
-  EGL(eglInitialize(engineContext->eglDisplay, 0, 0));
-
-  // config
-  EGLConfig eglConfig;
-  EGLint eglConfigAttribList[] = {EGL_SURFACE_TYPE, EGL_PBUFFER_BIT,
-                                  EGL_RED_SIZE,     8,
-                                  EGL_GREEN_SIZE,   8,
-                                  EGL_BLUE_SIZE,    8,
-                                  EGL_ALPHA_SIZE,   8,
-                                  EGL_NONE};
-  int numConfig = 0;
-  EGL(eglChooseConfig(engineContext->eglDisplay, eglConfigAttribList, &eglConfig, 1, &numConfig));
-
-  // context
-  EGLint eglContextAttribList[] = {EGL_CONTEXT_CLIENT_VERSION, 3,
-                                   isSecure ? EGL_PROTECTED_CONTENT_EXT : EGL_NONE,
-                                   isSecure ? EGL_TRUE : EGL_NONE,
-                                   EGL_NONE};
-  engineContext->eglContext = eglCreateContext(engineContext->eglDisplay, eglConfig, NULL, eglContextAttribList);
-
-  // surface
-  EGLint eglSurfaceAttribList[] = {EGL_WIDTH, 1,
-                                   EGL_HEIGHT, 1,
-                                   isSecure ? EGL_PROTECTED_CONTENT_EXT : EGL_NONE,
-                                   isSecure ? EGL_TRUE : EGL_NONE,
-                                   EGL_NONE};
-  engineContext->eglSurface = eglCreatePbufferSurface(engineContext->eglDisplay, eglConfig, eglSurfaceAttribList);
-
-  eglMakeCurrent(engineContext->eglDisplay, engineContext->eglSurface, engineContext->eglSurface, engineContext->eglContext);
-
-  ALOGI("In %s context = %p", __FUNCTION__, (void *)(engineContext->eglContext));
-
-  return (void*)(engineContext);
-}
-
-//-----------------------------------------------------------------------------
-// Shutdown.
-void engine_shutdown(void* context)
-//-----------------------------------------------------------------------------
-{
-  EngineContext* engineContext = (EngineContext*)context;
-  EGL(eglMakeCurrent(engineContext->eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));
-  EGL(eglDestroySurface(engineContext->eglDisplay, engineContext->eglSurface));
-  EGL(eglDestroyContext(engineContext->eglDisplay, engineContext->eglContext));
-  EGL(eglTerminate(engineContext->eglDisplay));
-  engineContext->eglDisplay = EGL_NO_DISPLAY;
-  engineContext->eglContext = EGL_NO_CONTEXT;
-  engineContext->eglSurface = EGL_NO_SURFACE;
-}
-
-//-----------------------------------------------------------------------------
-void engine_deleteInputBuffer(unsigned int id)
-//-----------------------------------------------------------------------------
-{
-  if (id != 0) {
-    GL(glDeleteTextures(1, &id));
-  }
-}
-
-//-----------------------------------------------------------------------------
-void engine_deleteProgram(unsigned int id)
-//-----------------------------------------------------------------------------
-{
-  if (id != 0) {
-    GL(glDeleteProgram(id));
-  }
-}
-
-//-----------------------------------------------------------------------------
-void engine_setData2f(int location, float* data)
-//-----------------------------------------------------------------------------
-{
-    GL(glUniform2f(location, data[0], data[1]));
-}
-
-//-----------------------------------------------------------------------------
-unsigned int engine_load3DTexture(void *colorMapData, int sz, int format)
-//-----------------------------------------------------------------------------
-{
-  GLuint texture = 0;
-  GL(glGenTextures(1, &texture));
-  GL(glBindTexture(GL_TEXTURE_3D, texture));
-  GL(glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
-  GL(glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
-  GL(glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE));
-  GL(glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
-  GL(glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
-
-  GL(glTexImage3D(GL_TEXTURE_3D, 0, GL_RGB10_A2, sz, sz, sz, 0, GL_RGBA,
-                  GL_UNSIGNED_INT_2_10_10_10_REV, colorMapData));
-
-  return texture;
-}
-//-----------------------------------------------------------------------------
-unsigned int engine_load1DTexture(void *data, int sz, int format)
-//-----------------------------------------------------------------------------
-{
-  GLuint texture = 0;
-  if ((data != 0) && (sz != 0)) {
-    GL(glGenTextures(1, &texture));
-    GL(glBindTexture(GL_TEXTURE_2D, texture));
-    GL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
-    GL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
-    GL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
-    GL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
-
-    GL(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB10_A2, sz, 1, 0, GL_RGBA,
-                    GL_UNSIGNED_INT_2_10_10_10_REV, data));
-  }
-  return texture;
-}
-
-//-----------------------------------------------------------------------------
-void dumpShaderLog(int shader)
-//-----------------------------------------------------------------------------
-{
-  int success = 0;
-  GLchar infoLog[512];
-  GL(glGetShaderiv(shader, GL_COMPILE_STATUS, &success));
-  if (!success) {
-    glGetShaderInfoLog(shader, 512, NULL, infoLog);
-    ALOGI("Shader Failed to compile: %s\n", infoLog);
-  }
-}
-
-//-----------------------------------------------------------------------------
-GLuint engine_loadProgram(int vertexEntries, const char **vertex, int fragmentEntries,
-                          const char **fragment)
-//-----------------------------------------------------------------------------
-{
-  GLuint progId = glCreateProgram();
-
-  int vertId = glCreateShader(GL_VERTEX_SHADER);
-  int fragId = glCreateShader(GL_FRAGMENT_SHADER);
-
-  GL(glShaderSource(vertId, vertexEntries, vertex, 0));
-  GL(glCompileShader(vertId));
-  dumpShaderLog(vertId);
-
-  GL(glShaderSource(fragId, fragmentEntries, fragment, 0));
-  GL(glCompileShader(fragId));
-  dumpShaderLog(fragId);
-
-  GL(glAttachShader(progId, vertId));
-  GL(glAttachShader(progId, fragId));
-
-  GL(glLinkProgram(progId));
-
-  GL(glDetachShader(progId, vertId));
-  GL(glDetachShader(progId, fragId));
-
-  GL(glDeleteShader(vertId));
-  GL(glDeleteShader(fragId));
-
-  return progId;
-}
-
-//-----------------------------------------------------------------------------
-void WaitOnNativeFence(int fd)
-//-----------------------------------------------------------------------------
-{
-  if (fd != -1) {
-    EGLint attribs[] = {EGL_SYNC_NATIVE_FENCE_FD_ANDROID, fd, EGL_NONE};
-
-    EGLSyncKHR sync = eglCreateSyncKHR(eglGetCurrentDisplay(), EGL_SYNC_NATIVE_FENCE_ANDROID, attribs);
-
-    if (sync == EGL_NO_SYNC_KHR) {
-      ALOGE("%s - Failed to Create sync from source fd", __FUNCTION__);
-    } else {
-      // the gpu will wait for this sync - not this cpu thread.
-      EGL(eglWaitSyncKHR(eglGetCurrentDisplay(), sync, 0));
-      EGL(eglDestroySyncKHR(eglGetCurrentDisplay(), sync));
-    }
-  }
-}
-
-//-----------------------------------------------------------------------------
-int CreateNativeFence()
-//-----------------------------------------------------------------------------
-{
-  int fd = -1;
-
-  EGLSyncKHR sync = eglCreateSyncKHR(eglGetCurrentDisplay(), EGL_SYNC_NATIVE_FENCE_ANDROID, NULL);
-  GL(glFlush());
-  if (sync == EGL_NO_SYNC_KHR) {
-    ALOGE("%s - Failed to Create Native Fence sync", __FUNCTION__);
-  } else {
-    fd = eglDupNativeFenceFDANDROID(eglGetCurrentDisplay(), sync);
-    if (fd == EGL_NO_NATIVE_FENCE_FD_ANDROID) {
-      ALOGE("%s - Failed to dup sync", __FUNCTION__);
-    }
-    EGL(eglDestroySyncKHR(eglGetCurrentDisplay(), sync));
-  }
-
-  return fd;
-}
-
-//-----------------------------------------------------------------------------
-void engine_setDestination(int id, int x, int y, int w, int h)
-//-----------------------------------------------------------------------------
-{
-  GL(glBindFramebuffer(GL_FRAMEBUFFER, id));
-  GL(glViewport(x, y, w, h));
-}
-
-//-----------------------------------------------------------------------------
-void engine_setProgram(int id)
-//-----------------------------------------------------------------------------
-{
-  GL(glUseProgram(id));
-}
-
-//-----------------------------------------------------------------------------
-void engine_set2DInputBuffer(int binding, unsigned int id)
-//-----------------------------------------------------------------------------
-{
-  GL(glActiveTexture(GL_TEXTURE0 + binding));
-  GL(glBindTexture(GL_TEXTURE_2D, id));
-}
-
-//-----------------------------------------------------------------------------
-void engine_set3DInputBuffer(int binding, unsigned int id)
-//-----------------------------------------------------------------------------
-{
-  GL(glActiveTexture(GL_TEXTURE0 + binding));
-  GL(glBindTexture(GL_TEXTURE_3D, id));
-}
-
-//-----------------------------------------------------------------------------
-void engine_setExternalInputBuffer(int binding, unsigned int id)
-//-----------------------------------------------------------------------------
-{
-  GL(glActiveTexture(GL_TEXTURE0 + binding));
-  GL(glBindTexture(0x8D65, id));
-}
-
-//-----------------------------------------------------------------------------
-int engine_blit(int srcFenceFd)
-//-----------------------------------------------------------------------------
-{
-  int fd = -1;
-  WaitOnNativeFence(srcFenceFd);
-  float fullscreen_vertices[]{0.0f, 2.0f, 0.0f, 0.0f, 2.0f, 0.0f};
-  GL(glEnableVertexAttribArray(0));
-  GL(glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, fullscreen_vertices));
-  GL(glDrawArrays(GL_TRIANGLES, 0, 3));
-  fd = CreateNativeFence();
-  GL(glFlush());
-  return fd;
-}
-
-//-----------------------------------------------------------------------------
-void checkGlError(const char *file, int line)
-//-----------------------------------------------------------------------------
-{
-  for (GLint error = glGetError(); error; error = glGetError()) {
-    char *pError;
-    switch (error) {
-      case GL_NO_ERROR:
-        pError = (char *)"GL_NO_ERROR";
-        break;
-      case GL_INVALID_ENUM:
-        pError = (char *)"GL_INVALID_ENUM";
-        break;
-      case GL_INVALID_VALUE:
-        pError = (char *)"GL_INVALID_VALUE";
-        break;
-      case GL_INVALID_OPERATION:
-        pError = (char *)"GL_INVALID_OPERATION";
-        break;
-      case GL_OUT_OF_MEMORY:
-        pError = (char *)"GL_OUT_OF_MEMORY";
-        break;
-      case GL_INVALID_FRAMEBUFFER_OPERATION:
-        pError = (char *)"GL_INVALID_FRAMEBUFFER_OPERATION";
-        break;
-
-      default:
-        ALOGE("glError (0x%x) %s:%d\n", error, file, line);
-        return;
-    }
-
-    ALOGE("glError (%s) %s:%d\n", pError, file, line);
-    return;
-  }
-  return;
-}
-
-//-----------------------------------------------------------------------------
-void checkEglError(const char *file, int line)
-//-----------------------------------------------------------------------------
-{
-  for (int i = 0; i < 5; i++) {
-    const EGLint error = eglGetError();
-    if (error == EGL_SUCCESS) {
-      break;
-    }
-
-    char *pError;
-    switch (error) {
-      case EGL_SUCCESS:
-        pError = (char *)"EGL_SUCCESS";
-        break;
-      case EGL_NOT_INITIALIZED:
-        pError = (char *)"EGL_NOT_INITIALIZED";
-        break;
-      case EGL_BAD_ACCESS:
-        pError = (char *)"EGL_BAD_ACCESS";
-        break;
-      case EGL_BAD_ALLOC:
-        pError = (char *)"EGL_BAD_ALLOC";
-        break;
-      case EGL_BAD_ATTRIBUTE:
-        pError = (char *)"EGL_BAD_ATTRIBUTE";
-        break;
-      case EGL_BAD_CONTEXT:
-        pError = (char *)"EGL_BAD_CONTEXT";
-        break;
-      case EGL_BAD_CONFIG:
-        pError = (char *)"EGL_BAD_CONFIG";
-        break;
-      case EGL_BAD_CURRENT_SURFACE:
-        pError = (char *)"EGL_BAD_CURRENT_SURFACE";
-        break;
-      case EGL_BAD_DISPLAY:
-        pError = (char *)"EGL_BAD_DISPLAY";
-        break;
-      case EGL_BAD_SURFACE:
-        pError = (char *)"EGL_BAD_SURFACE";
-        break;
-      case EGL_BAD_MATCH:
-        pError = (char *)"EGL_BAD_MATCH";
-        break;
-      case EGL_BAD_PARAMETER:
-        pError = (char *)"EGL_BAD_PARAMETER";
-        break;
-      case EGL_BAD_NATIVE_PIXMAP:
-        pError = (char *)"EGL_BAD_NATIVE_PIXMAP";
-        break;
-      case EGL_BAD_NATIVE_WINDOW:
-        pError = (char *)"EGL_BAD_NATIVE_WINDOW";
-        break;
-      case EGL_CONTEXT_LOST:
-        pError = (char *)"EGL_CONTEXT_LOST";
-        break;
-      default:
-        ALOGE("eglError (0x%x) %s:%d\n", error, file, line);
-        return;
-    }
-    ALOGE("eglError (%s) %s:%d\n", pError, file, line);
-    return;
-  }
-  return;
-}
diff --git a/gpu_tonemapper/glengine.h b/gpu_tonemapper/glengine.h
deleted file mode 100644
index f6aeec8..0000000
--- a/gpu_tonemapper/glengine.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (c) 2016, The Linux Foundation. All rights reserved.
- * Not a Contribution.
- *
- * Copyright 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.
- */
-
-#ifndef __TONEMAPPER_GLENGINE_H__
-#define __TONEMAPPER_GLENGINE_H__
-#include <EGL/egl.h>
-#define EGL_EGLEXT_PROTOTYPES
-#include <EGL/eglext.h>
-#include <GLES3/gl31.h>
-#define GL_GLEXT_PROTOTYPES
-#include <GLES2/gl2ext.h>
-#include <GLES3/gl3ext.h>
-
-#if defined(CHECK_GL_ERRORS)
-#define GL(func) func;
-#define EGL(func) func;
-#else
-#define GL(func) \
-  func;          \
-  checkGlError(__FILE__, __LINE__);
-#define EGL(func) \
-  func;           \
-  checkEglError(__FILE__, __LINE__);
-#endif
-
-#define EGL_PROTECTED_CONTENT_EXT 0x32C0
-
-void checkGlError(const char *file, int line);
-void checkEglError(const char *file, int line);
-
-#endif  //__TONEMAPPER_GLENGINE_H__
diff --git a/gpu_tonemapper/rgba_inverse_tonemap.inl b/gpu_tonemapper/rgba_inverse_tonemap.inl
deleted file mode 100644
index 2865fbe..0000000
--- a/gpu_tonemapper/rgba_inverse_tonemap.inl
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
- * Not a Contribution.
- *
- * Copyright 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.
- */
-
-const char* rgba_inverse_tonemap_shader = ""
-    "#extension GL_OES_EGL_image_external_essl3 : require                                               \n"
-    "precision highp float;                                                                             \n"
-    "precision highp sampler2D;                                                                         \n"
-    "layout(binding = 0) uniform samplerExternalOES externalTexture;                                    \n"
-    "layout(binding = 1) uniform sampler3D tonemapper;                                                  \n"
-    "layout(binding = 2) uniform sampler2D xform;                                                       \n"
-    "layout(location = 3) uniform vec2 tSO;                                                             \n"
-    "#if defined(USE_NONUNIFORM_SAMPLING)                                                               \n"
-    "layout(location = 4) uniform vec2 xSO;                                                             \n"
-    "#endif                                                                                             \n"
-    "in vec2 uv;                                                                                        \n"
-    "out vec4 fs_color;                                                                                 \n"
-    "                                                                                                   \n"
-    "vec3 ScaleOffset(in vec3 samplePt, in vec2 so)                                                     \n"
-    "{                                                                                                  \n"
-    "   vec3 adjPt = so.x * samplePt + so.y;                                                            \n"
-    "   return adjPt;                                                                                   \n"
-    "}                                                                                                  \n"
-    "                                                                                                   \n"
-    "void main()                                                                                        \n"
-    "{                                                                                                  \n"
-    "vec2 flipped = vec2(uv.x, 1.0f - uv.y);                                                            \n"
-    "vec4 rgb_premulalpha = texture(externalTexture, flipped);                                          \n"
-    "fs_color = rgb_premulalpha;                                                                        \n"
-    "if( rgb_premulalpha.a > 0.0 ) {                                                                    \n"
-    "vec3 rgb = rgb_premulalpha.rgb/rgb_premulalpha.a;                                                  \n"
-    "#if defined(USE_NONUNIFORM_SAMPLING)                                                               \n"
-    "vec3 adj = ScaleOffset(rgb.xyz, xSO);                                                              \n"
-    "float r = texture(xform, vec2(adj.r, 0.5f)).r;                                                     \n"
-    "float g = texture(xform, vec2(adj.g, 0.5f)).g;                                                     \n"
-    "float b = texture(xform, vec2(adj.b, 0.5f)).b;                                                     \n"
-    "#else                                                                                              \n"
-    "float r = rgb.r;                                                                                   \n"
-    "float g = rgb.g;                                                                                   \n"
-    "float b = rgb.b;                                                                                   \n"
-    "#endif                                                                                             \n"
-    "fs_color.rgb = texture(tonemapper, ScaleOffset(vec3(r, g, b), tSO)).rgb * rgb_premulalpha.a;       \n"
-    "fs_color.a = rgb_premulalpha.a;                                                                    \n"
-    "}                                                                                                  \n"
-    "}                                                                                                  \n";
diff --git a/gralloc/Android.mk b/gralloc/Android.mk
deleted file mode 100644
index 3d19ce1..0000000
--- a/gralloc/Android.mk
+++ /dev/null
@@ -1,101 +0,0 @@
-# Gralloc module
-LOCAL_PATH := $(call my-dir)
-include $(LOCAL_PATH)/../common.mk
-include $(CLEAR_VARS)
-
-LOCAL_MODULE                  := gralloc.$(TARGET_BOARD_PLATFORM)
-LOCAL_VENDOR_MODULE           := true
-LOCAL_MODULE_RELATIVE_PATH    := hw
-LOCAL_MODULE_TAGS             := optional
-LOCAL_C_INCLUDES              := $(common_includes)
-
-LOCAL_HEADER_LIBRARIES        := display_headers
-LOCAL_SHARED_LIBRARIES        := $(common_libs) libqdMetaData libsync libgrallocutils \
-                                  libgralloccore android.hardware.graphics.mapper@2.0
-LOCAL_CFLAGS                  := $(common_flags) -DLOG_TAG=\"qdgralloc\" -Wall -std=c++14 -Werror
-LOCAL_CFLAGS                  += -isystem  $(kernel_includes)
-LOCAL_CLANG                   := true
-LOCAL_ADDITIONAL_DEPENDENCIES := $(common_deps)
-LOCAL_SRC_FILES               := gr_device_impl.cpp
-LOCAL_COPY_HEADERS_TO         := $(common_header_export_path)
-LOCAL_COPY_HEADERS            := gr_device_impl.h gralloc_priv.h gr_priv_handle.h
-include $(BUILD_SHARED_LIBRARY)
-
-#libgrallocutils
-include $(CLEAR_VARS)
-LOCAL_MODULE                  := libgrallocutils
-LOCAL_VENDOR_MODULE           := true
-LOCAL_MODULE_TAGS             := optional
-LOCAL_C_INCLUDES              := $(common_includes) $(kernel_includes)
-LOCAL_HEADER_LIBRARIES        := display_headers
-LOCAL_SHARED_LIBRARIES        := $(common_libs) libqdMetaData libdl  \
-                                  android.hardware.graphics.mapper@2.0
-LOCAL_CFLAGS                  := $(common_flags) -DLOG_TAG=\"qdgralloc\" -Wno-sign-conversion
-LOCAL_ADDITIONAL_DEPENDENCIES := $(common_deps)
-LOCAL_SRC_FILES               := gr_utils.cpp gr_adreno_info.cpp
-include $(BUILD_SHARED_LIBRARY)
-
-#libgralloccore
-include $(CLEAR_VARS)
-LOCAL_MODULE                  := libgralloccore
-LOCAL_VENDOR_MODULE           := true
-LOCAL_MODULE_TAGS             := optional
-LOCAL_C_INCLUDES              := $(common_includes) $(kernel_includes)
-LOCAL_HEADER_LIBRARIES        := display_headers
-LOCAL_SHARED_LIBRARIES        := $(common_libs) libqdMetaData libdl libgrallocutils \
-                                  android.hardware.graphics.mapper@2.0
-LOCAL_CFLAGS                  := $(common_flags) -DLOG_TAG=\"qdgralloc\" -Wno-sign-conversion
-LOCAL_ADDITIONAL_DEPENDENCIES := $(common_deps)
-LOCAL_SRC_FILES               := gr_allocator.cpp gr_buf_mgr.cpp gr_ion_alloc.cpp
-include $(BUILD_SHARED_LIBRARY)
-
-
-qti_mapper_version := $(shell \
-    if [ -d "$(TOP)/vendor/qcom/opensource/interfaces/display/mapper/1.0" ];\
-    then echo QTI_MAPPER_1_0; fi)
-
-qti_allocator_version := $(shell \
-    if [ -d "$(TOP)/vendor/qcom/opensource/interfaces/display/allocator/1.0" ];\
-    then echo QTI_ALLOCATOR_1_0; fi)
-
-
-#mapper
-include $(CLEAR_VARS)
-LOCAL_MODULE                  := android.hardware.graphics.mapper@2.0-impl-qti-display
-LOCAL_VENDOR_MODULE           := true
-LOCAL_MODULE_RELATIVE_PATH    := hw
-LOCAL_MODULE_TAGS             := optional
-LOCAL_C_INCLUDES              := $(common_includes) $(kernel_includes)
-LOCAL_HEADER_LIBRARIES        := display_headers
-LOCAL_SHARED_LIBRARIES        := $(common_libs) \
-                                  libhidlbase \
-                                  libhidltransport \
-                                  libqdMetaData \
-                                  libgrallocutils \
-                                  libgralloccore \
-                                  libsync \
-                                  android.hardware.graphics.mapper@2.0
-LOCAL_CFLAGS                  := $(common_flags) -DLOG_TAG=\"qdgralloc\" -Wno-sign-conversion
-LOCAL_ADDITIONAL_DEPENDENCIES := $(common_deps)
-LOCAL_SRC_FILES               := QtiMapper.cpp
-include $(BUILD_SHARED_LIBRARY)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE                  := vendor.qti.hardware.display.allocator@1.0-service
-LOCAL_VENDOR_MODULE           := true
-LOCAL_MODULE_RELATIVE_PATH    := hw
-LOCAL_MODULE_TAGS             := optional
-LOCAL_HEADER_LIBRARIES        := display_headers
-LOCAL_SHARED_LIBRARIES        := $(common_libs) \
-                                 libhidlbase \
-                                 libhidltransport\
-                                 libqdMetaData \
-                                 libgrallocutils \
-                                 libgralloccore \
-                                 android.hardware.graphics.allocator@2.0
-LOCAL_CFLAGS                  := -DLOG_TAG=\"qdgralloc\" $(common_flags)
-LOCAL_ADDITIONAL_DEPENDENCIES := $(common_deps)
-LOCAL_C_INCLUDES              := $(common_includes) $(kernel_includes)
-LOCAL_SRC_FILES               := QtiAllocator.cpp service.cpp
-LOCAL_INIT_RC                 := vendor.qti.hardware.display.allocator@1.0-service.rc
-include $(BUILD_EXECUTABLE)
diff --git a/gralloc/QtiAllocator.cpp b/gralloc/QtiAllocator.cpp
deleted file mode 100644
index c4d7aef..0000000
--- a/gralloc/QtiAllocator.cpp
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * Copyright (c) 2018, The Linux Foundation. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *    * Redistributions of source code must retain the above copyright
- *      notice, this list of conditions and the following disclaimer.
- *    * Redistributions in binary form must reproduce the above
- *      copyright notice, this list of conditions and the following
- *      disclaimer in the documentation and/or other materials provided
- *      with the distribution.
- *    * Neither the name of The Linux Foundation. nor the names of its
- *      contributors may be used to endorse or promote products derived
- *      from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#define DEBUG 0
-#include "QtiAllocator.h"
-
-#include <log/log.h>
-#include <vector>
-
-#include "gr_utils.h"
-
-namespace vendor {
-namespace qti {
-namespace hardware {
-namespace display {
-namespace allocator {
-namespace V1_0 {
-namespace implementation {
-
-using android::hardware::hidl_handle;
-using gralloc::BufferDescriptor;
-
-QtiAllocator::QtiAllocator() {
-  buf_mgr_ = BufferManager::GetInstance();
-}
-
-// Methods from ::android::hardware::graphics::allocator::V2_0::IAllocator follow.
-Return<void> QtiAllocator::dumpDebugInfo(dumpDebugInfo_cb hidl_cb) {
-  std::ostringstream os;
-  buf_mgr_->Dump(&os);
-  hidl_string reply;
-  reply.setToExternal(os.str().c_str(), os.str().length());
-  hidl_cb(reply);
-  return Void();
-}
-
-Return<void> QtiAllocator::allocate(const hidl_vec<uint32_t> &descriptor, uint32_t count,
-                                    allocate_cb hidl_cb) {
-  ALOGD_IF(DEBUG, "Allocating buffers count: %d", count);
-  gralloc::BufferDescriptor desc;
-
-  auto err = desc.Decode(descriptor);
-  if (err != Error::NONE) {
-    hidl_cb(err, 0, hidl_vec<hidl_handle>());
-    return Void();
-  }
-
-  std::vector<hidl_handle> buffers;
-  buffers.reserve(count);
-  for (uint32_t i = 0; i < count; i++) {
-    buffer_handle_t buffer;
-    ALOGD_IF(DEBUG, "buffer: %p", &buffer);
-    err = buf_mgr_->AllocateBuffer(desc, &buffer);
-    if (err != Error::NONE) {
-      break;
-    }
-    buffers.emplace_back(hidl_handle(buffer));
-  }
-
-  uint32_t stride = 0;
-  hidl_vec<hidl_handle> hidl_buffers;
-  if (err == Error::NONE && buffers.size() > 0) {
-    stride = static_cast<uint32_t>(PRIV_HANDLE_CONST(buffers[0].getNativeHandle())->width);
-    hidl_buffers.setToExternal(buffers.data(), buffers.size());
-  }
-  hidl_cb(err, stride, hidl_buffers);
-
-  for (const auto &b : buffers) {
-    buf_mgr_->ReleaseBuffer(PRIV_HANDLE_CONST(b.getNativeHandle()));
-  }
-
-  return Void();
-}
-
-// Methods from ::android::hidl::base::V1_0::IBase follow.
-
-IAllocator *HIDL_FETCH_IAllocator(const char * /* name */) {
-  return new QtiAllocator();
-}
-
-}  // namespace implementation
-}  // namespace V1_0
-}  // namespace allocator
-}  // namespace display
-}  // namespace hardware
-}  // namespace qti
-}  // namespace vendor
diff --git a/gralloc/QtiAllocator.h b/gralloc/QtiAllocator.h
deleted file mode 100644
index 1e683e8..0000000
--- a/gralloc/QtiAllocator.h
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright (c) 2018, The Linux Foundation. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *    * Redistributions of source code must retain the above copyright
- *      notice, this list of conditions and the following disclaimer.
- *    * Redistributions in binary form must reproduce the above
- *      copyright notice, this list of conditions and the following
- *      disclaimer in the documentation and/or other materials provided
- *      with the distribution.
- *    * Neither the name of The Linux Foundation. nor the names of its
- *      contributors may be used to endorse or promote products derived
- *      from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef __QTIALLOCATOR_H__
-#define __QTIALLOCATOR_H__
-
-#include <hidl/MQDescriptor.h>
-#include <hidl/Status.h>
-#include <android/hardware/graphics/allocator/2.0/IAllocator.h>
-
-#include "gr_buf_mgr.h"
-
-namespace vendor {
-namespace qti {
-namespace hardware {
-namespace display {
-namespace allocator {
-namespace V1_0 {
-namespace implementation {
-
-using ::android::hardware::Return;
-using ::android::hardware::Void;
-using ::android::hardware::graphics::allocator::V2_0::IAllocator;
-using ::android::hardware::graphics::mapper::V2_0::Error;
-using ::android::hardware::hidl_array;
-using ::android::hardware::hidl_memory;
-using ::android::hardware::hidl_string;
-using ::android::hardware::hidl_vec;
-using ::android::hidl::base::V1_0::DebugInfo;
-using ::android::hidl::base::V1_0::IBase;
-using ::android::sp;
-using gralloc::BufferManager;
-
-class QtiAllocator : public IAllocator {
- public:
-  QtiAllocator();
-  // Methods from ::android::hardware::graphics::allocator::V2_0::IAllocator follow.
-  Return<void> dumpDebugInfo(dumpDebugInfo_cb _hidl_cb) override;
-  Return<void> allocate(const hidl_vec<uint32_t> &descriptor, uint32_t count,
-                        allocate_cb _hidl_cb) override;
-
-  // Methods from ::android::hidl::base::V1_0::IBase follow.
- private:
-  BufferManager *buf_mgr_ = nullptr;
-};
-
-extern "C" IAllocator *HIDL_FETCH_IAllocator(const char *name);
-
-}  // namespace implementation
-}  // namespace V1_0
-}  // namespace allocator
-}  // namespace display
-}  // namespace hardware
-}  // namespace qti
-}  // namespace vendor
-
-#endif  // __QTIALLOCATOR_H__
diff --git a/gralloc/QtiMapper.cpp b/gralloc/QtiMapper.cpp
deleted file mode 100644
index bcf3549..0000000
--- a/gralloc/QtiMapper.cpp
+++ /dev/null
@@ -1,345 +0,0 @@
-/*
- * Copyright (c) 2018, The Linux Foundation. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- *       copyright notice, this list of conditions and the following
- *       disclaimer in the documentation and/or other materials provided
- *       with the distribution.
- *     * Neither the name of The Linux Foundation nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#define ATRACE_TAG (ATRACE_TAG_GRAPHICS | ATRACE_TAG_HAL)
-#define DEBUG 0
-#include "QtiMapper.h"
-#include <cutils/trace.h>
-#include <qdMetaData.h>
-#include <sync/sync.h>
-#include "gr_utils.h"
-
-namespace vendor {
-namespace qti {
-namespace hardware {
-namespace display {
-namespace mapper {
-namespace V1_0 {
-namespace implementation {
-
-using gralloc::BufferInfo;
-
-QtiMapper::QtiMapper() {
-  buf_mgr_ = BufferManager::GetInstance();
-  ALOGD_IF(DEBUG, "Created QtiMapper instance");
-}
-
-bool QtiMapper::ValidDescriptor(const IMapper::BufferDescriptorInfo &bd) {
-  if (bd.width == 0 || bd.height == 0 || (static_cast<int32_t>(bd.format) <= 0) ||
-      bd.layerCount <= 0) {
-    return false;
-  }
-
-  return true;
-}
-
-// Methods from ::android::hardware::graphics::mapper::V2_0::IMapper follow.
-Return<void> QtiMapper::createDescriptor(const IMapper::BufferDescriptorInfo &descriptor_info,
-                                         createDescriptor_cb hidl_cb) {
-  ALOGD_IF(DEBUG,
-           "BufferDescriptorInfo: wxh: %dx%d usage: 0x%" PRIu64 " format: %d layer_count: %d",
-           descriptor_info.width, descriptor_info.height, descriptor_info.usage,
-           static_cast<uint32_t>(descriptor_info.format), descriptor_info.layerCount);
-
-  if (ValidDescriptor(descriptor_info)) {
-    auto vec = gralloc::BufferDescriptor::Encode(descriptor_info);
-    hidl_cb(Error::NONE, vec);
-  } else {
-    hidl_cb(Error::BAD_VALUE, hidl_vec<uint32_t>());
-  }
-  return Void();
-}
-
-Return<void> QtiMapper::importBuffer(const hidl_handle &raw_handle, importBuffer_cb hidl_cb) {
-  if (!raw_handle.getNativeHandle()) {
-    ALOGE("%s: Unable to import handle", __FUNCTION__);
-    hidl_cb(Error::BAD_BUFFER, nullptr);
-    return Void();
-  }
-
-  native_handle_t *buffer_handle = native_handle_clone(raw_handle.getNativeHandle());
-  if (!buffer_handle) {
-    ALOGE("%s: Unable to clone handle", __FUNCTION__);
-    hidl_cb(Error::NO_RESOURCES, nullptr);
-    return Void();
-  }
-
-  auto error = buf_mgr_->RetainBuffer(PRIV_HANDLE_CONST(buffer_handle));
-  if (error != Error::NONE) {
-    ALOGE("%s: Unable to retain handle: %p", __FUNCTION__, buffer_handle);
-    native_handle_close(buffer_handle);
-    native_handle_delete(buffer_handle);
-
-    hidl_cb(error, nullptr);
-    return Void();
-  }
-  ALOGD_IF(DEBUG, "Imported handle: %p id: %" PRIu64, buffer_handle,
-           PRIV_HANDLE_CONST(buffer_handle)->id);
-  hidl_cb(Error::NONE, buffer_handle);
-  return Void();
-}
-
-Return<Error> QtiMapper::freeBuffer(void *buffer) {
-  if (!buffer) {
-    return Error::BAD_BUFFER;
-  }
-  return buf_mgr_->ReleaseBuffer(PRIV_HANDLE_CONST(buffer));
-}
-
-bool QtiMapper::GetFenceFd(const hidl_handle &fence_handle, int *outFenceFd) {
-  auto handle = fence_handle.getNativeHandle();
-  if (handle && handle->numFds > 1) {
-    ALOGE("invalid fence handle with %d fds", handle->numFds);
-    return false;
-  }
-
-  *outFenceFd = (handle && handle->numFds == 1) ? handle->data[0] : -1;
-  return true;
-}
-
-void QtiMapper::WaitFenceFd(int fence_fd) {
-  if (fence_fd < 0) {
-    return;
-  }
-
-  const int timeout = 3000;
-  ATRACE_BEGIN("fence wait");
-  const int error = sync_wait(fence_fd, timeout);
-  ATRACE_END();
-  if (error < 0) {
-    ALOGE("QtiMapper: lock fence %d didn't signal in %u ms -  error: %s", fence_fd, timeout,
-          strerror(errno));
-  }
-}
-
-Error QtiMapper::LockBuffer(void *buffer, uint64_t usage, const hidl_handle &acquire_fence) {
-  if (!buffer) {
-    return Error::BAD_BUFFER;
-  }
-
-  int fence_fd;
-  if (!GetFenceFd(acquire_fence, &fence_fd)) {
-    return Error::BAD_VALUE;
-  }
-
-  if (fence_fd > 0) {
-    WaitFenceFd(fence_fd);
-  }
-
-  auto hnd = PRIV_HANDLE_CONST(buffer);
-
-  return buf_mgr_->LockBuffer(hnd, usage);
-}
-
-Return<void> QtiMapper::lock(void *buffer, uint64_t cpu_usage,
-                             const IMapper::Rect & /*access_region*/,
-                             const hidl_handle &acquire_fence, lock_cb hidl_cb) {
-  auto err = LockBuffer(buffer, cpu_usage, acquire_fence);
-  if (err != Error::NONE) {
-    hidl_cb(err, nullptr);
-    return Void();
-  }
-
-  auto hnd = PRIV_HANDLE_CONST(buffer);
-  auto *out_data = reinterpret_cast<void *>(hnd->base);
-  hidl_cb(Error::NONE, out_data);
-  return Void();
-}
-
-Return<void> QtiMapper::lockYCbCr(void *buffer, uint64_t cpu_usage,
-                                  const IMapper::Rect & /*access_region*/,
-                                  const hidl_handle &acquire_fence, lockYCbCr_cb hidl_cb) {
-  YCbCrLayout layout = {};
-  auto err = LockBuffer(buffer, cpu_usage, acquire_fence);
-  if (err != Error::NONE) {
-    hidl_cb(err, layout);
-    return Void();
-  }
-
-  auto hnd = PRIV_HANDLE_CONST(buffer);
-  android_ycbcr yuv_plane_info[2];
-  if (gralloc::GetYUVPlaneInfo(hnd, yuv_plane_info) != 0) {
-    hidl_cb(Error::BAD_VALUE, layout);
-  }
-  layout.y = yuv_plane_info[0].y;
-  layout.cr = yuv_plane_info[0].cr;
-  layout.cb = yuv_plane_info[0].cb;
-  layout.yStride = static_cast<uint32_t>(yuv_plane_info[0].ystride);
-  layout.cStride = static_cast<uint32_t>(yuv_plane_info[0].cstride);
-  layout.chromaStep = static_cast<uint32_t>(yuv_plane_info[0].chroma_step);
-  hidl_cb(Error::NONE, layout);
-  return Void();
-}
-
-Return<void> QtiMapper::unlock(void *buffer, unlock_cb hidl_cb) {
-  auto err = Error::BAD_BUFFER;
-  if (buffer != nullptr) {
-    err = buf_mgr_->UnlockBuffer(PRIV_HANDLE_CONST(buffer));
-  }
-  // We don't have a release fence
-  hidl_cb(err, hidl_handle(nullptr));
-  return Void();
-}
-
-#ifdef ENABLE_QTI_MAPPER_EXTENSION
-Return<void> QtiMapper::getMapSecureBufferFlag(void *buffer, getMapSecureBufferFlag_cb hidl_cb) {
-  auto err = Error::BAD_BUFFER;
-  auto hnd = static_cast<private_handle_t *>(buffer);
-  int *map_secure_buffer = 0;
-  if (buffer != nullptr && private_handle_t::validate(hnd) != 0) {
-    if (getMetaData(hnd, GET_MAP_SECURE_BUFFER, map_secure_buffer) != 0) {
-      *map_secure_buffer = 0;
-    } else {
-      err = Error::NONE;
-    }
-  }
-  hidl_cb(err, *map_secure_buffer != 0);
-  return Void();
-}
-
-Return<void> QtiMapper::getInterlacedFlag(void *buffer, getInterlacedFlag_cb hidl_cb) {
-  auto err = Error::BAD_BUFFER;
-  auto hnd = static_cast<private_handle_t *>(buffer);
-  int *interlaced_flag = nullptr;
-  if (buffer != nullptr && private_handle_t::validate(hnd) != 0) {
-    if (getMetaData(hnd, GET_PP_PARAM_INTERLACED, interlaced_flag) != 0) {
-      *interlaced_flag = 0;
-    } else {
-      err = Error::NONE;
-    }
-  }
-  hidl_cb(err, *interlaced_flag != 0);
-  return Void();
-}
-
-Return<void> QtiMapper::getCustomDimensions(void *buffer, getCustomDimensions_cb hidl_cb) {
-  auto err = Error::BAD_BUFFER;
-  auto hnd = static_cast<private_handle_t *>(buffer);
-  int stride = 0;
-  int height = 0;
-  if (buffer != nullptr && private_handle_t::validate(hnd) != 0) {
-    stride = hnd->width;
-    height = hnd->height;
-    gralloc::GetCustomDimensions(hnd, &stride, &height);
-    err = Error::NONE;
-  }
-  hidl_cb(err, stride, height);
-  return Void();
-}
-
-Return<void> QtiMapper::getRgbDataAddress(void *buffer, getRgbDataAddress_cb hidl_cb) {
-  auto err = Error::BAD_BUFFER;
-  auto hnd = static_cast<private_handle_t *>(buffer);
-  void *rgb_data = nullptr;
-  if (buffer != nullptr && private_handle_t::validate(hnd) != 0) {
-    if (gralloc::GetRgbDataAddress(hnd, &rgb_data) == 0) {
-      err = Error::NONE;
-    }
-  }
-  hidl_cb(err, rgb_data);
-  return Void();
-}
-
-Return<void> QtiMapper::calculateBufferAttributes(int32_t width, int32_t height, int32_t format,
-                                                  uint64_t usage,
-                                                  calculateBufferAttributes_cb hidl_cb) {
-  unsigned int alignedw, alignedh;
-  BufferInfo info(width, height, format, usage);
-  gralloc::GetAlignedWidthAndHeight(info, &alignedw, &alignedh);
-  bool ubwc_enabled = gralloc::IsUBwcEnabled(format, usage);
-  hidl_cb(Error::NONE, alignedw, alignedh, ubwc_enabled);
-  return Void();
-}
-
-Return<void> QtiMapper::getColorSpace(void *buffer, getColorSpace_cb hidl_cb) {
-  auto err = Error::BAD_BUFFER;
-  auto hnd = static_cast<private_handle_t *>(buffer);
-  int color_space = 0;
-  if (buffer != nullptr && private_handle_t::validate(hnd) != 0) {
-    gralloc::GetColorSpaceFromMetadata(hnd, &color_space);
-    err = Error::NONE;
-  }
-  hidl_cb(err, color_space);
-  return Void();
-}
-
-Return<void> QtiMapper::getYuvPlaneInfo(void *buffer, getYuvPlaneInfo_cb hidl_cb) {
-  auto err = Error::BAD_BUFFER;
-  auto hnd = static_cast<private_handle_t *>(buffer);
-  hidl_vec<YCbCrLayout> layout;
-  layout.resize(2);
-  android_ycbcr yuv_plane_info[2];
-  if (buffer != nullptr && private_handle_t::validate(hnd) != 0) {
-    if (gralloc::GetYUVPlaneInfo(hnd, yuv_plane_info) == 0) {
-      err = Error::NONE;
-      for (int i=0; i < 2; i++) {
-        layout[i].y = yuv_plane_info[i].y;
-        layout[i].cr = yuv_plane_info[i].cr;
-        layout[i].cb = yuv_plane_info[i].cb;
-        layout[i].yStride = static_cast<uint32_t>(yuv_plane_info[i].ystride);
-        layout[i].cStride = static_cast<uint32_t>(yuv_plane_info[i].cstride);
-        layout[i].chromaStep = static_cast<uint32_t>(yuv_plane_info[i].chroma_step);
-      }
-    }
-  }
-  hidl_cb(err, layout);
-  return Void();
-}
-
-Return<Error> QtiMapper::setSingleBufferMode(void *buffer, bool enable) {
-  auto err = Error::BAD_BUFFER;
-  auto hnd = static_cast<private_handle_t *>(buffer);
-  if (buffer != nullptr && private_handle_t::validate(hnd) != 0) {
-    if (setMetaData(hnd, SET_SINGLE_BUFFER_MODE, &enable) != 0) {
-      err = Error::UNSUPPORTED;
-    } else {
-      err = Error::NONE;
-    }
-  }
-  return err;
-}
-#endif
-
-// Methods from ::android::hidl::base::V1_0::IBase follow.
-
-// When we are in passthrough mode, this method is used
-// by hidl to obtain the SP HAL object
-IMapper *HIDL_FETCH_IMapper(const char * /* name */) {
-  ALOGD_IF(DEBUG, "Fetching IMapper from QtiMapper");
-  auto mapper = new QtiMapper();
-  return static_cast<IMapper *>(mapper);
-}
-
-}  // namespace implementation
-}  // namespace V1_0
-}  // namespace mapper
-}  // namespace display
-}  // namespace hardware
-}  // namespace qti
-}  // namespace vendor
diff --git a/gralloc/QtiMapper.h b/gralloc/QtiMapper.h
deleted file mode 100644
index 218f074..0000000
--- a/gralloc/QtiMapper.h
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * Copyright (c) 2018, The Linux Foundation. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- *       copyright notice, this list of conditions and the following
- *       disclaimer in the documentation and/or other materials provided
- *       with the distribution.
- *     * Neither the name of The Linux Foundation nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef __QTIMAPPER_H__
-#define __QTIMAPPER_H__
-
-#include <hidl/MQDescriptor.h>
-#include <hidl/Status.h>
-
-#include "gr_buf_mgr.h"
-namespace vendor {
-namespace qti {
-namespace hardware {
-namespace display {
-namespace mapper {
-namespace V1_0 {
-namespace implementation {
-
-using ::android::hardware::Return;
-using ::android::hardware::Void;
-using ::android::hardware::graphics::mapper::V2_0::Error;
-using ::android::hardware::graphics::mapper::V2_0::IMapper;
-using ::android::hardware::graphics::mapper::V2_0::YCbCrLayout;
-using ::android::hardware::hidl_array;
-using ::android::hardware::hidl_handle;
-using ::android::hardware::hidl_memory;
-using ::android::hardware::hidl_string;
-using ::android::hardware::hidl_vec;
-using ::android::hidl::base::V1_0::DebugInfo;
-using ::android::hidl::base::V1_0::IBase;
-using ::android::sp;
-using gralloc::BufferManager;
-
-class QtiMapper : public IMapper {
- public:
-  QtiMapper();
-  // Methods from ::android::hardware::graphics::mapper::V2_0::IMapper follow.
-  Return<void> createDescriptor(const IMapper::BufferDescriptorInfo &descriptor_info,
-                                createDescriptor_cb hidl_cb) override;
-  Return<void> importBuffer(const hidl_handle &raw_handle, importBuffer_cb hidl_cb) override;
-  Return<Error> freeBuffer(void *buffer) override;
-  Return<void> lock(void *buffer, uint64_t cpu_usage, const IMapper::Rect &access_region,
-                    const hidl_handle &acquire_fence, lock_cb hidl_cb) override;
-  Return<void> lockYCbCr(void *buffer, uint64_t cpu_usage, const IMapper::Rect &access_region,
-                         const hidl_handle &acquire_fence, lockYCbCr_cb hidl_cb) override;
-  Return<void> unlock(void *buffer, unlock_cb hidl_cb) override;
-
-#ifdef ENABLE_QTI_MAPPER_EXTENSION
-  Return<void> getMapSecureBufferFlag(void *buffer, getMapSecureBufferFlag_cb _hidl_cb) override;
-  Return<void> getInterlacedFlag(void *buffer, getInterlacedFlag_cb _hidl_cb) override;
-  Return<void> getCustomDimensions(void *buffer, getCustomDimensions_cb _hidl_cb) override;
-  Return<void> getRgbDataAddress(void *buffer, getRgbDataAddress_cb _hidl_cb) override;
-  Return<void> calculateBufferAttributes(int32_t width, int32_t height, int32_t format,
-                                         uint64_t usage,
-                                         calculateBufferAttributes_cb _hidl_cb) override;
-  Return<void> getColorSpace(void *buffer, getColorSpace_cb _hidl_cb) override;
-  Return<void> getYuvPlaneInfo(void *buffer, getYuvPlaneInfo_cb _hidl_cb) override;
-  Return<Error> setSingleBufferMode(void *buffer, bool enable) override;
-#endif
-
- private:
-  BufferManager *buf_mgr_ = nullptr;
-  bool ValidDescriptor(const IMapper::BufferDescriptorInfo &bd);
-  bool GetFenceFd(const hidl_handle &fence_handle, int *outFenceFd);
-  void WaitFenceFd(int fence_fd);
-  Error LockBuffer(void *buffer, uint64_t usage, const hidl_handle &acquire_fence);
-};
-
-extern "C" IMapper *HIDL_FETCH_IMapper(const char *name);
-}  // namespace implementation
-}  // namespace V1_0
-}  // namespace mapper
-}  // namespace display
-}  // namespace hardware
-}  // namespace qti
-}  // namespace vendor
-
-#endif  // __QTIMAPPER_H__
diff --git a/gralloc/gr_adreno_info.cpp b/gralloc/gr_adreno_info.cpp
deleted file mode 100644
index 03aacff..0000000
--- a/gralloc/gr_adreno_info.cpp
+++ /dev/null
@@ -1,223 +0,0 @@
-/*
- * Copyright (c) 2011-2018, The Linux Foundation. All rights reserved.
-
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *   * Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- *   * Redistributions in binary form must reproduce the above
- *     copyright notice, this list of conditions and the following
- *     disclaimer in the documentation and/or other materials provided
- *     with the distribution.
- *   * Neither the name of The Linux Foundation nor the names of its
- *     contributors may be used to endorse or promote products derived
- *     from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <log/log.h>
-#include <cutils/properties.h>
-#include <dlfcn.h>
-#include <mutex>
-
-#include "gr_adreno_info.h"
-#include "gr_utils.h"
-#include "gralloc_priv.h"
-
-using std::lock_guard;
-using std::mutex;
-
-namespace gralloc {
-
-AdrenoMemInfo *AdrenoMemInfo::s_instance = nullptr;
-
-AdrenoMemInfo *AdrenoMemInfo::GetInstance() {
-  static mutex s_lock;
-  lock_guard<mutex> obj(s_lock);
-  if (!s_instance) {
-    s_instance = new AdrenoMemInfo();
-  }
-
-  return s_instance;
-}
-
-AdrenoMemInfo::AdrenoMemInfo() {
-  libadreno_utils_ = ::dlopen("libadreno_utils.so", RTLD_NOW);
-  if (libadreno_utils_) {
-    *reinterpret_cast<void **>(&LINK_adreno_compute_aligned_width_and_height) =
-        ::dlsym(libadreno_utils_, "compute_aligned_width_and_height");
-    *reinterpret_cast<void **>(&LINK_adreno_compute_fmt_aligned_width_and_height) =
-        ::dlsym(libadreno_utils_, "compute_fmt_aligned_width_and_height");
-    *reinterpret_cast<void **>(&LINK_adreno_compute_padding) =
-        ::dlsym(libadreno_utils_, "compute_surface_padding");
-    *reinterpret_cast<void **>(&LINK_adreno_compute_compressedfmt_aligned_width_and_height) =
-        ::dlsym(libadreno_utils_, "compute_compressedfmt_aligned_width_and_height");
-    *reinterpret_cast<void **>(&LINK_adreno_isUBWCSupportedByGpu) =
-        ::dlsym(libadreno_utils_, "isUBWCSupportedByGpu");
-    *reinterpret_cast<void **>(&LINK_adreno_get_gpu_pixel_alignment) =
-        ::dlsym(libadreno_utils_, "get_gpu_pixel_alignment");
-  } else {
-    ALOGE(" Failed to load libadreno_utils.so");
-  }
-
-  // Check if the overriding property debug.gralloc.gfx_ubwc_disable
-  // that disables UBWC allocations for the graphics stack is set
-  char property[PROPERTY_VALUE_MAX];
-  property_get(DISABLE_UBWC_PROP, property, "0");
-  if (!(strncmp(property, "1", PROPERTY_VALUE_MAX)) ||
-      !(strncmp(property, "true", PROPERTY_VALUE_MAX))) {
-    gfx_ubwc_disable_ = true;
-  }
-
-}
-
-AdrenoMemInfo::~AdrenoMemInfo() {
-  if (libadreno_utils_) {
-    ::dlclose(libadreno_utils_);
-  }
-}
-
-void AdrenoMemInfo::AlignUnCompressedRGB(int width, int height, int format, int tile_enabled,
-                                         unsigned int *aligned_w, unsigned int *aligned_h) {
-  *aligned_w = (unsigned int)ALIGN(width, 32);
-  *aligned_h = (unsigned int)ALIGN(height, 32);
-
-  int bpp = 4;
-  switch (format) {
-    case HAL_PIXEL_FORMAT_RGB_888:
-    case HAL_PIXEL_FORMAT_BGR_888:
-      bpp = 3;
-      break;
-    case HAL_PIXEL_FORMAT_RGB_565:
-    case HAL_PIXEL_FORMAT_BGR_565:
-    case HAL_PIXEL_FORMAT_RGBA_5551:
-    case HAL_PIXEL_FORMAT_RGBA_4444:
-      bpp = 2;
-      break;
-    default:
-      break;
-  }
-
-  int raster_mode = 0;          // Adreno unknown raster mode.
-  int padding_threshold = 512;  // Threshold for padding surfaces.
-  // the function below computes aligned width and aligned height
-  // based on linear or macro tile mode selected.
-  if (LINK_adreno_compute_fmt_aligned_width_and_height) {
-    // We call into adreno_utils only for RGB formats. So plane_id is 0 and
-    // num_samples is 1 always. We may  have to add uitility function to
-    // find out these if there is a need to call this API for YUV formats.
-    LINK_adreno_compute_fmt_aligned_width_and_height(
-        width, height, 0 /*plane_id*/, GetGpuPixelFormat(format), 1 /*num_samples*/, tile_enabled,
-        raster_mode, padding_threshold, reinterpret_cast<int *>(aligned_w),
-        reinterpret_cast<int *>(aligned_h));
-  } else if (LINK_adreno_compute_aligned_width_and_height) {
-    LINK_adreno_compute_aligned_width_and_height(
-        width, height, bpp, tile_enabled, raster_mode, padding_threshold,
-        reinterpret_cast<int *>(aligned_w), reinterpret_cast<int *>(aligned_h));
-  } else if (LINK_adreno_compute_padding) {
-    int surface_tile_height = 1;  // Linear surface
-    *aligned_w = UINT(LINK_adreno_compute_padding(width, bpp, surface_tile_height, raster_mode,
-                                                  padding_threshold));
-    ALOGW("%s: Warning!! Old GFX API is used to calculate stride", __FUNCTION__);
-  } else {
-    ALOGW(
-        "%s: Warning!! Symbols compute_surface_padding and "
-        "compute_fmt_aligned_width_and_height and "
-        "compute_aligned_width_and_height not found",
-        __FUNCTION__);
-  }
-}
-
-void AdrenoMemInfo::AlignCompressedRGB(int width, int height, int format, unsigned int *aligned_w,
-                                       unsigned int *aligned_h) {
-  if (LINK_adreno_compute_compressedfmt_aligned_width_and_height) {
-    int bytesPerPixel = 0;
-    int raster_mode = 0;          // Adreno unknown raster mode.
-    int padding_threshold = 512;  // Threshold for padding
-    // surfaces.
-
-    LINK_adreno_compute_compressedfmt_aligned_width_and_height(
-        width, height, format, 0, raster_mode, padding_threshold,
-        reinterpret_cast<int *>(aligned_w), reinterpret_cast<int *>(aligned_h), &bytesPerPixel);
-  } else {
-    *aligned_w = (unsigned int)ALIGN(width, 32);
-    *aligned_h = (unsigned int)ALIGN(height, 32);
-    ALOGW("%s: Warning!! compute_compressedfmt_aligned_width_and_height not found", __FUNCTION__);
-  }
-}
-
-bool AdrenoMemInfo::IsUBWCSupportedByGPU(int format) {
-  if (!gfx_ubwc_disable_ && LINK_adreno_isUBWCSupportedByGpu) {
-    ADRENOPIXELFORMAT gpu_format = GetGpuPixelFormat(format);
-    return LINK_adreno_isUBWCSupportedByGpu(gpu_format);
-  }
-
-  return false;
-}
-
-uint32_t AdrenoMemInfo::GetGpuPixelAlignment() {
-  if (LINK_adreno_get_gpu_pixel_alignment) {
-    return LINK_adreno_get_gpu_pixel_alignment();
-  }
-
-  return 1;
-}
-
-ADRENOPIXELFORMAT AdrenoMemInfo::GetGpuPixelFormat(int hal_format) {
-  switch (hal_format) {
-    case HAL_PIXEL_FORMAT_RGBA_8888:
-      return ADRENO_PIXELFORMAT_R8G8B8A8;
-    case HAL_PIXEL_FORMAT_RGBX_8888:
-      return ADRENO_PIXELFORMAT_R8G8B8X8;
-    case HAL_PIXEL_FORMAT_BGRA_8888:
-      return ADRENO_PIXELFORMAT_B8G8R8A8;
-    case HAL_PIXEL_FORMAT_RGB_888:
-      return ADRENO_PIXELFORMAT_R8G8B8;
-    case HAL_PIXEL_FORMAT_RGB_565:
-      return ADRENO_PIXELFORMAT_B5G6R5;
-    case HAL_PIXEL_FORMAT_BGR_565:
-      return ADRENO_PIXELFORMAT_R5G6B5;
-    case HAL_PIXEL_FORMAT_RGBA_5551:
-      return ADRENO_PIXELFORMAT_R5G5B5A1;
-    case HAL_PIXEL_FORMAT_RGBA_4444:
-      return ADRENO_PIXELFORMAT_R4G4B4A4;
-    case HAL_PIXEL_FORMAT_RGBA_1010102:
-       return ADRENO_PIXELFORMAT_R10G10B10A2_UNORM;
-    case HAL_PIXEL_FORMAT_RGBX_1010102:
-       return ADRENO_PIXELFORMAT_R10G10B10X2_UNORM;
-    case HAL_PIXEL_FORMAT_ABGR_2101010:
-       return ADRENO_PIXELFORMAT_A2B10G10R10_UNORM;
-    case HAL_PIXEL_FORMAT_RGBA_FP16:
-       return ADRENO_PIXELFORMAT_R16G16B16A16_FLOAT;
-    case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
-      return ADRENO_PIXELFORMAT_NV12;
-    case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
-    case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
-      return ADRENO_PIXELFORMAT_NV12_EXT;
-    case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
-      return ADRENO_PIXELFORMAT_TP10;
-    case HAL_PIXEL_FORMAT_YCbCr_420_P010:
-    case HAL_PIXEL_FORMAT_YCbCr_420_P010_UBWC:
-    case HAL_PIXEL_FORMAT_YCbCr_420_P010_VENUS:
-      return ADRENO_PIXELFORMAT_P010;
-    default:
-      ALOGE("%s: No map for format: 0x%x", __FUNCTION__, hal_format);
-      break;
-  }
-
-  return ADRENO_PIXELFORMAT_UNKNOWN;
-}
-
-}  // namespace gralloc
diff --git a/gralloc/gr_adreno_info.h b/gralloc/gr_adreno_info.h
deleted file mode 100644
index b85e7c1..0000000
--- a/gralloc/gr_adreno_info.h
+++ /dev/null
@@ -1,153 +0,0 @@
-/*
- * Copyright (c) 2011-2018, The Linux Foundation. All rights reserved.
-
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *   * Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- *   * Redistributions in binary form must reproduce the above
- *     copyright notice, this list of conditions and the following
- *     disclaimer in the documentation and/or other materials provided
- *     with the distribution.
- *   * Neither the name of The Linux Foundation nor the names of its
- *     contributors may be used to endorse or promote products derived
- *     from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef __GR_ADRENO_INFO_H__
-#define __GR_ADRENO_INFO_H__
-
-#include <media/msm_media_info.h>
-
-namespace gralloc {
-
-// Adreno Pixel Formats
-typedef enum {
-  ADRENO_PIXELFORMAT_UNKNOWN = 0,
-  ADRENO_PIXELFORMAT_R16G16B16A16_FLOAT = 10,
-  ADRENO_PIXELFORMAT_R10G10B10A2_UNORM = 24,  // Vertex, Normalized GL_UNSIGNED_INT_10_10_10_2_OES
-  ADRENO_PIXELFORMAT_R8G8B8A8 = 28,
-  ADRENO_PIXELFORMAT_R8G8B8A8_SRGB = 29,
-  ADRENO_PIXELFORMAT_B5G6R5 = 85,
-  ADRENO_PIXELFORMAT_B5G5R5A1 = 86,
-  ADRENO_PIXELFORMAT_B8G8R8A8 = 90,
-  ADRENO_PIXELFORMAT_B8G8R8A8_SRGB = 91,
-  ADRENO_PIXELFORMAT_B8G8R8X8_SRGB = 93,
-  ADRENO_PIXELFORMAT_NV12 = 103,
-  ADRENO_PIXELFORMAT_P010 = 104,
-  ADRENO_PIXELFORMAT_YUY2 = 107,
-  ADRENO_PIXELFORMAT_B4G4R4A4 = 115,
-  ADRENO_PIXELFORMAT_NV12_EXT = 506,       // NV12 with non-std alignment and offsets
-  ADRENO_PIXELFORMAT_R8G8B8X8 = 507,       //  GL_RGB8 (Internal)
-  ADRENO_PIXELFORMAT_R8G8B8 = 508,         //  GL_RGB8
-  ADRENO_PIXELFORMAT_A1B5G5R5 = 519,       //  GL_RGB5_A1
-  ADRENO_PIXELFORMAT_R8G8B8X8_SRGB = 520,  //  GL_SRGB8
-  ADRENO_PIXELFORMAT_R8G8B8_SRGB = 521,    //  GL_SRGB8
-  ADRENO_PIXELFORMAT_A2B10G10R10_UNORM = 532,
-  // Vertex, Normalized GL_UNSIGNED_INT_10_10_10_2_OES
-  ADRENO_PIXELFORMAT_R10G10B10X2_UNORM = 537,
-  // Vertex, Normalized GL_UNSIGNED_INT_10_10_10_2_OES
-  ADRENO_PIXELFORMAT_R5G6B5 = 610,    //  RGBA version of B5G6R5
-  ADRENO_PIXELFORMAT_R5G5B5A1 = 611,  //  RGBA version of B5G5R5A1
-  ADRENO_PIXELFORMAT_R4G4B4A4 = 612,  //  RGBA version of B4G4R4A4
-  ADRENO_PIXELFORMAT_UYVY = 614,      //  YUV 4:2:2 packed progressive (1 plane)
-  ADRENO_PIXELFORMAT_NV21 = 619,
-  ADRENO_PIXELFORMAT_Y8U8V8A8 = 620,  // YUV 4:4:4 packed (1 plane)
-  ADRENO_PIXELFORMAT_Y8 = 625,        //  Single 8-bit luma only channel YUV format
-  ADRENO_PIXELFORMAT_TP10 = 654,      // YUV 4:2:0 planar 10 bits/comp (2 planes)
-} ADRENOPIXELFORMAT;
-
-class AdrenoMemInfo {
- public:
-  /*
-   * Function to compute aligned width and aligned height based on
-   * width, height, format and usage flags.
-   *
-   * @return aligned width, aligned height
-   */
-  void GetAlignedWidthAndHeight(int width, int height, int format, int usage,
-                                unsigned int *aligned_w, unsigned int *aligned_h, bool ubwc_enabled,
-                                bool tile_enabled);
-
-  /*
-   * Function to compute the adreno aligned width and aligned height
-   * based on the width and format.
-   *
-   * @return aligned width, aligned height
-   */
-  void AlignUnCompressedRGB(int width, int height, int format, int tileEnabled,
-                            unsigned int *aligned_w, unsigned int *aligned_h);
-
-  /*
-   * Function to compute the adreno aligned width and aligned height
-   * based on the width and format.
-   *
-   * @return aligned width, aligned height
-   */
-  void AlignCompressedRGB(int width, int height, int format, unsigned int *aligned_w,
-                          unsigned int *aligned_h);
-
-  /*
-   * Function to compute the pixel alignment requirement.
-   *
-   * @return alignment
-   */
-  uint32_t GetGpuPixelAlignment();
-
-  /*
-   * Function to query whether GPU supports UBWC for given HAL format
-   * @return > 0 : supported
-   *           0 : not supported
-   */
-  bool IsUBWCSupportedByGPU(int format);
-
-  /*
-   * Function to get the corresponding Adreno format for given HAL format
-   */
-  ADRENOPIXELFORMAT GetGpuPixelFormat(int hal_format);
-
-  static AdrenoMemInfo *GetInstance();
-
- private:
-  AdrenoMemInfo();
-  ~AdrenoMemInfo();
-  // link(s)to adreno surface padding library.
-  int (*LINK_adreno_compute_padding)(int width, int bpp, int surface_tile_height,
-                                     int screen_tile_height, int padding_threshold) = NULL;
-  void (*LINK_adreno_compute_aligned_width_and_height)(int width, int height, int bpp,
-                                                       int tile_mode, int raster_mode,
-                                                       int padding_threshold, int *aligned_w,
-                                                       int *aligned_h) = NULL;
-  void (*LINK_adreno_compute_fmt_aligned_width_and_height)(int width, int height, int plane_id,
-                                                           int format, int num_samples,
-                                                           int tile_mode, int raster_mode,
-                                                           int padding_threshold, int *aligned_w,
-                                                           int *aligned_h) = NULL;
-  void (*LINK_adreno_compute_compressedfmt_aligned_width_and_height)(
-      int width, int height, int format, int tile_mode, int raster_mode, int padding_threshold,
-      int *aligned_w, int *aligned_h, int *bpp) = NULL;
-  int (*LINK_adreno_isUBWCSupportedByGpu)(ADRENOPIXELFORMAT format) = NULL;
-  unsigned int (*LINK_adreno_get_gpu_pixel_alignment)() = NULL;
-
-  bool gfx_ubwc_disable_ = false;
-  void *libadreno_utils_ = NULL;
-
-  static AdrenoMemInfo *s_instance;
-};
-
-}  // namespace gralloc
-
-#endif  // __GR_ADRENO_INFO_H__
diff --git a/gralloc/gr_allocator.cpp b/gralloc/gr_allocator.cpp
deleted file mode 100644
index 912ada0..0000000
--- a/gralloc/gr_allocator.cpp
+++ /dev/null
@@ -1,301 +0,0 @@
-/*
- * Copyright (c) 2011-2018, The Linux Foundation. All rights reserved.
-
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *   * Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- *   * Redistributions in binary form must reproduce the above
- *     copyright notice, this list of conditions and the following
- *     disclaimer in the documentation and/or other materials provided
- *     with the distribution.
- *   * Neither the name of The Linux Foundation nor the names of its
- *     contributors may be used to endorse or promote products derived
- *     from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <log/log.h>
-#include <algorithm>
-#include <vector>
-
-#include "gr_allocator.h"
-#include "gr_utils.h"
-#include "gralloc_priv.h"
-
-#include "qd_utils.h"
-
-#ifndef ION_FLAG_CP_PIXEL
-#define ION_FLAG_CP_PIXEL 0
-#endif
-
-#ifndef ION_FLAG_ALLOW_NON_CONTIG
-#define ION_FLAG_ALLOW_NON_CONTIG 0
-#endif
-
-#ifndef ION_FLAG_CP_CAMERA_PREVIEW
-#define ION_FLAG_CP_CAMERA_PREVIEW 0
-#endif
-
-#ifdef MASTER_SIDE_CP
-#define CP_HEAP_ID ION_SECURE_HEAP_ID
-#define SD_HEAP_ID ION_SECURE_DISPLAY_HEAP_ID
-#define ION_CP_FLAGS (ION_SECURE | ION_FLAG_CP_PIXEL)
-#define ION_SD_FLAGS (ION_SECURE | ION_FLAG_CP_SEC_DISPLAY)
-#define ION_SC_FLAGS (ION_SECURE | ION_FLAG_CP_CAMERA)
-#define ION_SC_PREVIEW_FLAGS (ION_SECURE | ION_FLAG_CP_CAMERA_PREVIEW)
-#else  // SLAVE_SIDE_CP
-#define CP_HEAP_ID ION_CP_MM_HEAP_ID
-#define SD_HEAP_ID CP_HEAP_ID
-#define ION_CP_FLAGS (ION_SECURE | ION_FLAG_ALLOW_NON_CONTIG)
-#define ION_SD_FLAGS ION_SECURE
-#define ION_SC_FLAGS ION_SECURE
-#define ION_SC_PREVIEW_FLAGS ION_SECURE
-#endif
-
-using std::shared_ptr;
-using std::vector;
-
-namespace gralloc {
-
-static BufferInfo GetBufferInfo(const BufferDescriptor &descriptor) {
-  return BufferInfo(descriptor.GetWidth(), descriptor.GetHeight(), descriptor.GetFormat(),
-                    descriptor.GetUsage());
-}
-
-Allocator::Allocator() : ion_allocator_(nullptr) {}
-
-bool Allocator::Init() {
-  ion_allocator_ = new IonAlloc();
-  if (!ion_allocator_->Init()) {
-    return false;
-  }
-
-  return true;
-}
-
-Allocator::~Allocator() {
-  if (ion_allocator_) {
-    delete ion_allocator_;
-  }
-}
-
-int Allocator::AllocateMem(AllocData *alloc_data, uint64_t usage) {
-  int ret;
-  alloc_data->uncached = UseUncached(usage);
-
-  // After this point we should have the right heap set, there is no fallback
-  GetIonHeapInfo(usage, &alloc_data->heap_id, &alloc_data->alloc_type, &alloc_data->flags);
-
-  ret = ion_allocator_->AllocBuffer(alloc_data);
-  if (ret >= 0) {
-    alloc_data->alloc_type |= private_handle_t::PRIV_FLAGS_USES_ION;
-  } else {
-    ALOGE("%s: Failed to allocate buffer - heap: 0x%x flags: 0x%x", __FUNCTION__,
-          alloc_data->heap_id, alloc_data->flags);
-  }
-
-  return ret;
-}
-
-int Allocator::MapBuffer(void **base, unsigned int size, unsigned int offset, int fd) {
-  if (ion_allocator_) {
-    return ion_allocator_->MapBuffer(base, size, offset, fd);
-  }
-
-  return -EINVAL;
-}
-
-int Allocator::ImportBuffer(int fd) {
-  if (ion_allocator_) {
-    return ion_allocator_->ImportBuffer(fd);
-  }
-  return -EINVAL;
-}
-
-int Allocator::FreeBuffer(void *base, unsigned int size, unsigned int offset, int fd, int handle) {
-  if (ion_allocator_) {
-    return ion_allocator_->FreeBuffer(base, size, offset, fd, handle);
-  }
-
-  return -EINVAL;
-}
-
-int Allocator::CleanBuffer(void *base, unsigned int size, unsigned int offset, int handle, int op) {
-  if (ion_allocator_) {
-    return ion_allocator_->CleanBuffer(base, size, offset, handle, op);
-  }
-
-  return -EINVAL;
-}
-
-bool Allocator::CheckForBufferSharing(uint32_t num_descriptors,
-                                      const vector<shared_ptr<BufferDescriptor>> &descriptors,
-                                      ssize_t *max_index) {
-  unsigned int cur_heap_id = 0, prev_heap_id = 0;
-  unsigned int cur_alloc_type = 0, prev_alloc_type = 0;
-  unsigned int cur_ion_flags = 0, prev_ion_flags = 0;
-  bool cur_uncached = false, prev_uncached = false;
-  unsigned int alignedw, alignedh;
-  unsigned int max_size = 0;
-
-  *max_index = -1;
-  for (uint32_t i = 0; i < num_descriptors; i++) {
-    // Check Cached vs non-cached and all the ION flags
-    cur_uncached = UseUncached(descriptors[i]->GetUsage());
-    GetIonHeapInfo(descriptors[i]->GetUsage(), &cur_heap_id, &cur_alloc_type, &cur_ion_flags);
-
-    if (i > 0 && (cur_heap_id != prev_heap_id || cur_alloc_type != prev_alloc_type ||
-                  cur_ion_flags != prev_ion_flags)) {
-      return false;
-    }
-
-    // For same format type, find the descriptor with bigger size
-    GetAlignedWidthAndHeight(GetBufferInfo(*descriptors[i]), &alignedw, &alignedh);
-    unsigned int size = GetSize(GetBufferInfo(*descriptors[i]), alignedw, alignedh);
-    if (max_size < size) {
-      *max_index = INT(i);
-      max_size = size;
-    }
-
-    prev_heap_id = cur_heap_id;
-    prev_uncached = cur_uncached;
-    prev_ion_flags = cur_ion_flags;
-    prev_alloc_type = cur_alloc_type;
-  }
-
-  return true;
-}
-
-int Allocator::GetImplDefinedFormat(uint64_t usage, int format) {
-  int gr_format = format;
-
-  // If input format is HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED then based on
-  // the usage bits, gralloc assigns a format.
-  if (format == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED ||
-      format == HAL_PIXEL_FORMAT_YCbCr_420_888) {
-    if (usage & GRALLOC_USAGE_PRIVATE_ALLOC_UBWC) {
-      // Use of 10BIT_TP and 10BIT bits is supposed to be mutually exclusive.
-      // Each bit maps to only one format. Here we will check one of the bits
-      // and ignore the other.
-      if (usage & GRALLOC_USAGE_PRIVATE_10BIT_TP) {
-        gr_format = HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC;
-      } else if (usage & GRALLOC_USAGE_PRIVATE_10BIT) {
-        gr_format = HAL_PIXEL_FORMAT_YCbCr_420_P010_UBWC;
-      } else {
-        gr_format = HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC;
-      }
-    } else if (usage & GRALLOC_USAGE_PRIVATE_10BIT) {
-      gr_format = HAL_PIXEL_FORMAT_YCbCr_420_P010_VENUS;
-    } else if (usage & BufferUsage::VIDEO_ENCODER) {
-      gr_format = HAL_PIXEL_FORMAT_NV12_ENCODEABLE;  // NV12
-    } else if (usage & BufferUsage::CAMERA_INPUT) {
-      if (usage & BufferUsage::CAMERA_OUTPUT) {
-        // Assumed ZSL if both producer and consumer camera flags set
-        gr_format = HAL_PIXEL_FORMAT_NV21_ZSL;  // NV21
-      } else {
-        gr_format = HAL_PIXEL_FORMAT_YCrCb_420_SP;  // NV21
-      }
-    } else if (usage & BufferUsage::CAMERA_OUTPUT) {
-      if (format == HAL_PIXEL_FORMAT_YCbCr_420_888) {
-        gr_format = HAL_PIXEL_FORMAT_NV21_ZSL;  // NV21
-      } else {
-        gr_format = HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS;  // NV12 preview
-      }
-    } else if (usage & BufferUsage::COMPOSER_OVERLAY) {
-      // XXX: If we still haven't set a format, default to RGBA8888
-      gr_format = HAL_PIXEL_FORMAT_RGBA_8888;
-    } else if (format == HAL_PIXEL_FORMAT_YCbCr_420_888) {
-      // If no other usage flags are detected, default the
-      // flexible YUV format to NV21_ZSL
-      gr_format = HAL_PIXEL_FORMAT_NV21_ZSL;
-    }
-  }
-
-  return gr_format;
-}
-
-/* The default policy is to return cached buffers unless the client explicity
- * sets the PRIVATE_UNCACHED flag or indicates that the buffer will be rarely
- * read or written in software. */
-bool Allocator::UseUncached(uint64_t usage) {
-  if ((usage & GRALLOC_USAGE_PRIVATE_UNCACHED) || (usage & BufferUsage::PROTECTED)) {
-    return true;
-  }
-
-  // CPU read rarely
-  if ((usage & BufferUsage::CPU_READ_MASK) == static_cast<uint64_t>(BufferUsage::CPU_READ_RARELY)) {
-    return true;
-  }
-
-  // CPU  write rarely
-  if ((usage & BufferUsage::CPU_WRITE_MASK) ==
-      static_cast<uint64_t>(BufferUsage::CPU_WRITE_RARELY)) {
-    return true;
-  }
-
-  if ((usage & BufferUsage::SENSOR_DIRECT_DATA) || (usage & BufferUsage::GPU_DATA_BUFFER)) {
-    return true;
-  }
-
-  return false;
-}
-
-void Allocator::GetIonHeapInfo(uint64_t usage, unsigned int *ion_heap_id, unsigned int *alloc_type,
-                               unsigned int *ion_flags) {
-  unsigned int heap_id = 0;
-  unsigned int type = 0;
-  uint32_t flags = 0;
-  if (usage & GRALLOC_USAGE_PROTECTED) {
-    if (usage & GRALLOC_USAGE_PRIVATE_SECURE_DISPLAY) {
-      heap_id = ION_HEAP(SD_HEAP_ID);
-      /*
-       * There is currently no flag in ION for Secure Display
-       * VM. Please add it to the define once available.
-       */
-      flags |= UINT(ION_SD_FLAGS);
-    } else if (usage & BufferUsage::CAMERA_OUTPUT) {
-      heap_id = ION_HEAP(SD_HEAP_ID);
-      if (usage & BufferUsage::COMPOSER_OVERLAY) {
-        flags |= UINT(ION_SC_PREVIEW_FLAGS);
-      } else {
-        flags |= UINT(ION_SC_FLAGS);
-      }
-    } else {
-      heap_id = ION_HEAP(CP_HEAP_ID);
-      flags |= UINT(ION_CP_FLAGS);
-    }
-  }
-
-  if (usage & BufferUsage::SENSOR_DIRECT_DATA) {
-    heap_id |= ION_HEAP(ION_ADSP_HEAP_ID);
-  }
-
-  if (flags & UINT(ION_SECURE)) {
-    type |= private_handle_t::PRIV_FLAGS_SECURE_BUFFER;
-  }
-
-  // if no ion heap flags are set, default to system heap
-  if (!heap_id) {
-    heap_id = ION_HEAP(ION_SYSTEM_HEAP_ID);
-  }
-
-  *alloc_type = type;
-  *ion_flags = flags;
-  *ion_heap_id = heap_id;
-
-  return;
-}
-}  // namespace gralloc
diff --git a/gralloc/gr_allocator.h b/gralloc/gr_allocator.h
deleted file mode 100644
index fd316ef..0000000
--- a/gralloc/gr_allocator.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright (c) 2011-2018, The Linux Foundation. All rights reserved.
-
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *   * Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- *   * Redistributions in binary form must reproduce the above
- *     copyright notice, this list of conditions and the following
- *     disclaimer in the documentation and/or other materials provided
- *     with the distribution.
- *   * Neither the name of The Linux Foundation nor the names of its
- *     contributors may be used to endorse or promote products derived
- *     from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef __GR_ALLOCATOR_H__
-#define __GR_ALLOCATOR_H__
-
-#ifdef MASTER_SIDE_CP
-#define SECURE_ALIGN SZ_4K
-#else
-#define SECURE_ALIGN SZ_1M
-#endif
-
-#include <vector>
-
-#include "gr_buf_descriptor.h"
-#include "gr_ion_alloc.h"
-#include "gralloc_priv.h"
-
-namespace gralloc {
-
-class Allocator {
- public:
-  Allocator();
-  ~Allocator();
-  bool Init();
-  int MapBuffer(void **base, unsigned int size, unsigned int offset, int fd);
-  int ImportBuffer(int fd);
-  int FreeBuffer(void *base, unsigned int size, unsigned int offset, int fd, int handle);
-  int CleanBuffer(void *base, unsigned int size, unsigned int offset, int handle, int op);
-  int AllocateMem(AllocData *data, uint64_t usage);
-  // @return : index of the descriptor with maximum buffer size req
-  bool CheckForBufferSharing(uint32_t num_descriptors,
-                             const std::vector<std::shared_ptr<BufferDescriptor>> &descriptors,
-                             ssize_t *max_index);
-  int GetImplDefinedFormat(uint64_t usage, int format);
-  bool UseUncached(uint64_t usage);
-
- private:
-  void GetIonHeapInfo(uint64_t usage, unsigned int *ion_heap_id, unsigned int *alloc_type,
-                      unsigned int *ion_flags);
-
-  IonAlloc *ion_allocator_ = NULL;
-};
-
-}  // namespace gralloc
-
-#endif  // __GR_ALLOCATOR_H__
diff --git a/gralloc/gr_buf_descriptor.h b/gralloc/gr_buf_descriptor.h
deleted file mode 100644
index 932db33..0000000
--- a/gralloc/gr_buf_descriptor.h
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
-
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *   * Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- *   * Redistributions in binary form must reproduce the above
- *     copyright notice, this list of conditions and the following
- *     disclaimer in the documentation and/or other materials provided
- *     with the distribution.
- *   * Neither the name of The Linux Foundation nor the names of its
- *     contributors may be used to endorse or promote products derived
- *     from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef __GR_BUF_DESCRIPTOR_H__
-#define __GR_BUF_DESCRIPTOR_H__
-
-#include <android/hardware/graphics/mapper/2.0/IMapper.h>
-#include <atomic>
-
-namespace gralloc {
-using android::hardware::graphics::mapper::V2_0::Error;
-using android::hardware::graphics::mapper::V2_0::IMapper;
-using android::hardware::hidl_vec;
-
-const uint32_t kBufferDescriptorSize = 7;
-const uint32_t kMagicVersion = 0x76312E30;  // v1.0
-
-class BufferDescriptor {
- public:
-  BufferDescriptor() {}
-  explicit BufferDescriptor(uint64_t id) : id_(id) {}
-
-  static hidl_vec<uint32_t> Encode(const IMapper::BufferDescriptorInfo &bd_info) {
-    hidl_vec<uint32_t> out;
-    out.resize(kBufferDescriptorSize);
-    out[0] = kMagicVersion;
-    out[1] = bd_info.width;
-    out[2] = bd_info.height;
-    out[3] = bd_info.layerCount;
-    out[4] = static_cast<uint32_t>(bd_info.format);
-    out[5] = static_cast<uint32_t>(bd_info.usage);
-    out[6] = static_cast<uint32_t>(bd_info.usage >> 32);
-    return out;
-  }
-
-  Error Decode(const hidl_vec<uint32_t> &in) {
-    if (in.size() != kBufferDescriptorSize || in[0] != kMagicVersion) {
-      return Error::BAD_DESCRIPTOR;
-    }
-    width_ = static_cast<int32_t>(in[1]);
-    height_ = static_cast<int32_t>(in[2]);
-    layer_count_ = in[3];
-    format_ = static_cast<int32_t>(in[4]);
-    usage_ = static_cast<uint64_t>(in[6]) << 32 | in[5];
-    return Error::NONE;
-  }
-
-  void SetUsage(uint64_t usage) { usage_ |= usage; }
-
-  void SetDimensions(int w, int h) {
-    width_ = w;
-    height_ = h;
-  }
-
-  void SetColorFormat(int format) { format_ = format; }
-
-  void SetLayerCount(uint32_t layer_count) { layer_count_ = layer_count; }
-
-  uint64_t GetUsage() const { return usage_; }
-
-  int GetWidth() const { return width_; }
-
-  int GetHeight() const { return height_; }
-
-  int GetFormat() const { return format_; }
-
-  uint32_t GetLayerCount() const { return layer_count_; }
-
-  uint64_t GetId() const { return id_; }
-
- private:
-  int width_ = -1;
-  int height_ = -1;
-  int format_ = -1;
-  uint32_t layer_count_ = 1;
-  uint64_t usage_ = 0;
-  const uint64_t id_ = 0;
-};
-};      // namespace gralloc
-#endif  // __GR_BUF_DESCRIPTOR_H__
diff --git a/gralloc/gr_buf_mgr.cpp b/gralloc/gr_buf_mgr.cpp
deleted file mode 100644
index 687f3c1..0000000
--- a/gralloc/gr_buf_mgr.cpp
+++ /dev/null
@@ -1,399 +0,0 @@
-/*
- * Copyright (c) 2011-2018 The Linux Foundation. All rights reserved.
- * Not a Contribution
- *
- * Copyright (C) 2010 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 DEBUG 0
-
-#include <iomanip>
-#include <sstream>
-#include <utility>
-#include <vector>
-
-#include "gr_buf_descriptor.h"
-#include "gr_buf_mgr.h"
-#include "gr_priv_handle.h"
-#include "gr_utils.h"
-#include "qdMetaData.h"
-#include "qd_utils.h"
-
-namespace gralloc {
-
-static BufferInfo GetBufferInfo(const BufferDescriptor &descriptor) {
-  return BufferInfo(descriptor.GetWidth(), descriptor.GetHeight(), descriptor.GetFormat(),
-                    descriptor.GetUsage());
-}
-
-BufferManager::BufferManager() : next_id_(0) {
-  handles_map_.clear();
-  allocator_ = new Allocator();
-  allocator_->Init();
-}
-
-BufferManager *BufferManager::GetInstance() {
-  static BufferManager *instance = new BufferManager();
-  return instance;
-}
-
-BufferManager::~BufferManager() {
-  if (allocator_) {
-    delete allocator_;
-  }
-}
-
-Error BufferManager::FreeBuffer(std::shared_ptr<Buffer> buf) {
-  auto hnd = buf->handle;
-  ALOGD_IF(DEBUG, "FreeBuffer handle:%p", hnd);
-
-  if (private_handle_t::validate(hnd) != 0) {
-    ALOGE("FreeBuffer: Invalid handle: %p", hnd);
-    return Error::BAD_BUFFER;
-  }
-
-  if (allocator_->FreeBuffer(reinterpret_cast<void *>(hnd->base), hnd->size, hnd->offset, hnd->fd,
-                             buf->ion_handle_main) != 0) {
-    return Error::BAD_BUFFER;
-  }
-
-  unsigned int meta_size = ALIGN((unsigned int)sizeof(MetaData_t), PAGE_SIZE);
-  if (allocator_->FreeBuffer(reinterpret_cast<void *>(hnd->base_metadata), meta_size,
-                             hnd->offset_metadata, hnd->fd_metadata, buf->ion_handle_meta) != 0) {
-    return Error::BAD_BUFFER;
-  }
-
-  private_handle_t *handle = const_cast<private_handle_t *>(hnd);
-  handle->fd = -1;
-  handle->fd_metadata = -1;
-  if (!(handle->flags & private_handle_t::PRIV_FLAGS_CLIENT_ALLOCATED)) {
-    delete handle;
-  }
-  return Error::NONE;
-}
-
-void BufferManager::RegisterHandleLocked(const private_handle_t *hnd, int ion_handle,
-                                         int ion_handle_meta) {
-  auto buffer = std::make_shared<Buffer>(hnd, ion_handle, ion_handle_meta);
-  handles_map_.emplace(std::make_pair(hnd, buffer));
-}
-
-Error BufferManager::ImportHandleLocked(private_handle_t *hnd) {
-  ALOGD_IF(DEBUG, "Importing handle:%p id: %" PRIu64, hnd, hnd->id);
-  int ion_handle = allocator_->ImportBuffer(hnd->fd);
-  if (ion_handle < 0) {
-    ALOGE("Failed to import ion buffer: hnd: %p, fd:%d, id:%" PRIu64, hnd, hnd->fd, hnd->id);
-    return Error::BAD_BUFFER;
-  }
-  int ion_handle_meta = allocator_->ImportBuffer(hnd->fd_metadata);
-  if (ion_handle_meta < 0) {
-    ALOGE("Failed to import ion metadata buffer: hnd: %p, fd:%d, id:%" PRIu64, hnd, hnd->fd,
-          hnd->id);
-    return Error::BAD_BUFFER;
-  }
-  // Set base pointers to NULL since the data here was received over binder
-  hnd->base = 0;
-  hnd->base_metadata = 0;
-  RegisterHandleLocked(hnd, ion_handle, ion_handle_meta);
-  return Error::NONE;
-}
-
-std::shared_ptr<BufferManager::Buffer> BufferManager::GetBufferFromHandleLocked(
-    const private_handle_t *hnd) {
-  auto it = handles_map_.find(hnd);
-  if (it != handles_map_.end()) {
-    return it->second;
-  } else {
-    return nullptr;
-  }
-}
-
-Error BufferManager::MapBuffer(private_handle_t const *handle) {
-  private_handle_t *hnd = const_cast<private_handle_t *>(handle);
-  ALOGD_IF(DEBUG, "Map buffer handle:%p id: %" PRIu64, hnd, hnd->id);
-
-  hnd->base = 0;
-  if (allocator_->MapBuffer(reinterpret_cast<void **>(&hnd->base), hnd->size, hnd->offset,
-                            hnd->fd) != 0) {
-    return Error::BAD_BUFFER;
-  }
-  return Error::NONE;
-}
-
-Error BufferManager::RetainBuffer(private_handle_t const *hnd) {
-  ALOGD_IF(DEBUG, "Retain buffer handle:%p id: %" PRIu64, hnd, hnd->id);
-  auto err = Error::NONE;
-  std::lock_guard<std::mutex> lock(buffer_lock_);
-  auto buf = GetBufferFromHandleLocked(hnd);
-  if (buf != nullptr) {
-    buf->IncRef();
-  } else {
-    private_handle_t *handle = const_cast<private_handle_t *>(hnd);
-    err = ImportHandleLocked(handle);
-  }
-  return err;
-}
-
-Error BufferManager::ReleaseBuffer(private_handle_t const *hnd) {
-  ALOGD_IF(DEBUG, "Release buffer handle:%p", hnd);
-  std::lock_guard<std::mutex> lock(buffer_lock_);
-  auto buf = GetBufferFromHandleLocked(hnd);
-  if (buf == nullptr) {
-    ALOGE("Could not find handle: %p id: %" PRIu64, hnd, hnd->id);
-    return Error::BAD_BUFFER;
-  } else {
-    if (buf->DecRef()) {
-      handles_map_.erase(hnd);
-      // Unmap, close ion handle and close fd
-      FreeBuffer(buf);
-    }
-  }
-  return Error::NONE;
-}
-
-Error BufferManager::LockBuffer(const private_handle_t *hnd, uint64_t usage) {
-  std::lock_guard<std::mutex> lock(buffer_lock_);
-  auto err = Error::NONE;
-  ALOGD_IF(DEBUG, "LockBuffer buffer handle:%p id: %" PRIu64, hnd, hnd->id);
-
-  // If buffer is not meant for CPU return err
-  if (!CpuCanAccess(usage)) {
-    return Error::BAD_VALUE;
-  }
-
-  auto buf = GetBufferFromHandleLocked(hnd);
-  if (buf == nullptr) {
-    return Error::BAD_BUFFER;
-  }
-
-  if (hnd->base == 0) {
-    // we need to map for real
-    err = MapBuffer(hnd);
-  }
-
-  // Invalidate if CPU reads in software and there are non-CPU
-  // writers. No need to do this for the metadata buffer as it is
-  // only read/written in software.
-
-  // todo use handle here
-  if (err == Error::NONE && (hnd->flags & private_handle_t::PRIV_FLAGS_USES_ION) &&
-      (hnd->flags & private_handle_t::PRIV_FLAGS_CACHED)) {
-    if (allocator_->CleanBuffer(reinterpret_cast<void *>(hnd->base), hnd->size, hnd->offset,
-                                buf->ion_handle_main, CACHE_INVALIDATE)) {
-      return Error::BAD_BUFFER;
-    }
-  }
-
-  // Mark the buffer to be flushed after CPU write.
-  if (err == Error::NONE && CpuCanWrite(usage)) {
-    private_handle_t *handle = const_cast<private_handle_t *>(hnd);
-    handle->flags |= private_handle_t::PRIV_FLAGS_NEEDS_FLUSH;
-  }
-
-  return err;
-}
-
-Error BufferManager::UnlockBuffer(const private_handle_t *handle) {
-  std::lock_guard<std::mutex> lock(buffer_lock_);
-  auto status = Error::NONE;
-
-  private_handle_t *hnd = const_cast<private_handle_t *>(handle);
-  auto buf = GetBufferFromHandleLocked(hnd);
-  if (buf == nullptr) {
-    return Error::BAD_BUFFER;
-  }
-
-  if (hnd->flags & private_handle_t::PRIV_FLAGS_NEEDS_FLUSH) {
-    if (allocator_->CleanBuffer(reinterpret_cast<void *>(hnd->base), hnd->size, hnd->offset,
-                                buf->ion_handle_main, CACHE_CLEAN) != 0) {
-      status = Error::BAD_BUFFER;
-    }
-    hnd->flags &= ~private_handle_t::PRIV_FLAGS_NEEDS_FLUSH;
-  }
-
-  return status;
-}
-
-uint32_t BufferManager::GetDataAlignment(int format, uint64_t usage) {
-  uint32_t align = UINT(getpagesize());
-  if (format == HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED) {
-    align = 8192;
-  }
-
-  if (usage & BufferUsage::PROTECTED) {
-    if ((usage & BufferUsage::CAMERA_OUTPUT) || (usage & GRALLOC_USAGE_PRIVATE_SECURE_DISPLAY)) {
-      // The alignment here reflects qsee mmu V7L/V8L requirement
-      align = SZ_2M;
-    } else {
-      align = SECURE_ALIGN;
-    }
-  }
-
-  return align;
-}
-
-int BufferManager::GetHandleFlags(int format, uint64_t usage) {
-  int flags = 0;
-  if (usage & BufferUsage::VIDEO_ENCODER) {
-    flags |= private_handle_t::PRIV_FLAGS_VIDEO_ENCODER;
-  }
-
-  if (usage & BufferUsage::CAMERA_OUTPUT) {
-    flags |= private_handle_t::PRIV_FLAGS_CAMERA_WRITE;
-  }
-
-  if (usage & BufferUsage::CAMERA_INPUT) {
-    flags |= private_handle_t::PRIV_FLAGS_CAMERA_READ;
-  }
-
-  if (usage & BufferUsage::COMPOSER_OVERLAY) {
-    flags |= private_handle_t::PRIV_FLAGS_DISP_CONSUMER;
-  }
-
-  if (usage & BufferUsage::GPU_TEXTURE) {
-    flags |= private_handle_t::PRIV_FLAGS_HW_TEXTURE;
-  }
-
-  if (usage & GRALLOC_USAGE_PRIVATE_SECURE_DISPLAY) {
-    flags |= private_handle_t::PRIV_FLAGS_SECURE_DISPLAY;
-  }
-
-  if (IsUBwcEnabled(format, usage)) {
-    flags |= private_handle_t::PRIV_FLAGS_UBWC_ALIGNED;
-  }
-
-  if (usage & (BufferUsage::CPU_READ_MASK | BufferUsage::CPU_WRITE_MASK)) {
-    flags |= private_handle_t::PRIV_FLAGS_CPU_RENDERED;
-  }
-
-  if ((usage & (BufferUsage::VIDEO_ENCODER | BufferUsage::VIDEO_DECODER |
-                BufferUsage::CAMERA_OUTPUT | BufferUsage::GPU_RENDER_TARGET))) {
-    flags |= private_handle_t::PRIV_FLAGS_NON_CPU_WRITER;
-  }
-
-  if (!allocator_->UseUncached(usage)) {
-    flags |= private_handle_t::PRIV_FLAGS_CACHED;
-  }
-
-  return flags;
-}
-
-int BufferManager::GetBufferType(int inputFormat) {
-  int buffer_type = BUFFER_TYPE_VIDEO;
-  if (IsUncompressedRGBFormat(inputFormat)) {
-    // RGB formats
-    buffer_type = BUFFER_TYPE_UI;
-  }
-
-  return buffer_type;
-}
-
-Error BufferManager::AllocateBuffer(const BufferDescriptor &descriptor, buffer_handle_t *handle,
-                                    unsigned int bufferSize) {
-  if (!handle)
-    return Error::BAD_BUFFER;
-  std::lock_guard<std::mutex> buffer_lock(buffer_lock_);
-
-  uint64_t usage = descriptor.GetUsage();
-  int format = allocator_->GetImplDefinedFormat(usage, descriptor.GetFormat());
-  uint32_t layer_count = descriptor.GetLayerCount();
-
-  unsigned int size;
-  unsigned int alignedw, alignedh;
-
-  int buffer_type = GetBufferType(format);
-  BufferInfo info = GetBufferInfo(descriptor);
-  info.format = format;
-  GetBufferSizeAndDimensions(info, &size, &alignedw, &alignedh);
-  size = (bufferSize >= size) ? bufferSize : size;
-
-  int err = 0;
-  int flags = 0;
-  auto page_size = UINT(getpagesize());
-  AllocData data;
-  data.align = GetDataAlignment(format, usage);
-  size = ALIGN(size, data.align) * layer_count;
-  data.size = size;
-  data.handle = (uintptr_t)handle;
-  data.uncached = allocator_->UseUncached(usage);
-
-  // Allocate buffer memory
-  err = allocator_->AllocateMem(&data, usage);
-  if (err) {
-    ALOGE("gralloc failed to allocate err=%s", strerror(-err));
-    return Error::NO_RESOURCES;
-  }
-
-  // Allocate memory for MetaData
-  AllocData e_data;
-  e_data.size = ALIGN(UINT(sizeof(MetaData_t)), page_size);
-  e_data.handle = data.handle;
-  e_data.align = page_size;
-
-  err = allocator_->AllocateMem(&e_data, 0);
-  if (err) {
-    ALOGE("gralloc failed to allocate metadata error=%s", strerror(-err));
-    return Error::NO_RESOURCES;
-  }
-
-  flags = GetHandleFlags(format, usage);
-  flags |= data.alloc_type;
-
-  // Create handle
-  private_handle_t *hnd = new private_handle_t(
-      data.fd, e_data.fd, flags, INT(alignedw), INT(alignedh), descriptor.GetWidth(),
-      descriptor.GetHeight(), format, buffer_type, data.size, usage);
-
-  hnd->id = ++next_id_;
-  hnd->base = 0;
-  hnd->base_metadata = 0;
-  hnd->layer_count = layer_count;
-
-  ColorSpace_t colorSpace = ITU_R_601;
-  setMetaData(hnd, UPDATE_COLOR_SPACE, reinterpret_cast<void *>(&colorSpace));
-  *handle = hnd;
-  RegisterHandleLocked(hnd, data.ion_handle, e_data.ion_handle);
-  ALOGD_IF(DEBUG, "Allocated buffer handle: %p id: %" PRIu64, hnd, hnd->id);
-  if (DEBUG) {
-    private_handle_t::Dump(hnd);
-  }
-  return Error::NONE;
-}
-
-Error BufferManager::Dump(std::ostringstream *os) {
-  std::lock_guard<std::mutex> buffer_lock(buffer_lock_);
-  for (auto it : handles_map_) {
-    auto buf = it.second;
-    auto hnd = buf->handle;
-    *os << "handle id: " << std::setw(4) << hnd->id;
-    *os << " fd: " << std::setw(3) << hnd->fd;
-    *os << " fd_meta: " << std::setw(3) << hnd->fd_metadata;
-    *os << " wxh: " << std::setw(4) << hnd->width << " x " << std::setw(4) << hnd->height;
-    *os << " uwxuh: " << std::setw(4) << hnd->unaligned_width << " x ";
-    *os << std::setw(4) << hnd->unaligned_height;
-    *os << " size: " << std::setw(9) << hnd->size;
-    *os << std::hex << std::setfill('0');
-    *os << " priv_flags: "
-        << "0x" << std::setw(8) << hnd->flags;
-    *os << " usage: "
-        << "0x" << std::setw(8) << hnd->usage;
-    // TODO(user): get format string from qdutils
-    *os << " format: "
-        << "0x" << std::setw(8) << hnd->format;
-    *os << std::dec << std::setfill(' ') << std::endl;
-  }
-  return Error::NONE;
-}
-}  //  namespace gralloc
diff --git a/gralloc/gr_buf_mgr.h b/gralloc/gr_buf_mgr.h
deleted file mode 100644
index 258be2b..0000000
--- a/gralloc/gr_buf_mgr.h
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * Copyright (c) 2011-2018, The Linux Foundation. All rights reserved.
- * Not a Contribution
- *
- * Copyright (C) 2008 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 __GR_BUF_MGR_H__
-#define __GR_BUF_MGR_H__
-
-#include <pthread.h>
-#include <mutex>
-#include <unordered_map>
-#include <unordered_set>
-#include <utility>
-
-#include "gr_allocator.h"
-#include "gr_buf_descriptor.h"
-#include "gralloc_priv.h"
-
-namespace gralloc {
-
-using android::hardware::graphics::mapper::V2_0::Error;
-
-class BufferManager {
- public:
-  ~BufferManager();
-
-  Error AllocateBuffer(const BufferDescriptor &descriptor, buffer_handle_t *handle,
-                       unsigned int bufferSize = 0);
-  Error RetainBuffer(private_handle_t const *hnd);
-  Error ReleaseBuffer(private_handle_t const *hnd);
-  Error LockBuffer(const private_handle_t *hnd, uint64_t usage);
-  Error UnlockBuffer(const private_handle_t *hnd);
-  Error Dump(std::ostringstream *os);
-  static BufferManager *GetInstance();
-
- private:
-  BufferManager();
-  Error MapBuffer(private_handle_t const *hnd);
-  int GetBufferType(int format);
-  uint32_t GetDataAlignment(int format, uint64_t usage);
-  int GetHandleFlags(int format, uint64_t usage);
-
-  // Imports the ion fds into the current process. Returns an error for invalid handles
-  Error ImportHandleLocked(private_handle_t *hnd);
-
-  // Creates a Buffer from the valid private handle and adds it to the map
-  void RegisterHandleLocked(const private_handle_t *hnd, int ion_handle, int ion_handle_meta);
-
-  // Wrapper structure over private handle
-  // Values associated with the private handle
-  // that do not need to go over IPC can be placed here
-  // This structure is also not expected to be ABI stable
-  // unlike private_handle_t
-  struct Buffer {
-    const private_handle_t *handle = nullptr;
-    int ref_count = 1;
-    // Hold the main and metadata ion handles
-    // Freed from the allocator process
-    // and unused in the mapping process
-    int ion_handle_main = -1;
-    int ion_handle_meta = -1;
-
-    Buffer() = delete;
-    explicit Buffer(const private_handle_t *h, int ih_main = -1, int ih_meta = -1)
-        : handle(h), ion_handle_main(ih_main), ion_handle_meta(ih_meta) {}
-    void IncRef() { ++ref_count; }
-    bool DecRef() { return --ref_count == 0; }
-  };
-
-  Error FreeBuffer(std::shared_ptr<Buffer> buf);
-
-  // Get the wrapper Buffer object from the handle, returns nullptr if handle is not found
-  std::shared_ptr<Buffer> GetBufferFromHandleLocked(const private_handle_t *hnd);
-  Allocator *allocator_ = NULL;
-  std::mutex buffer_lock_;
-  std::unordered_map<const private_handle_t *, std::shared_ptr<Buffer>> handles_map_ = {};
-  std::atomic<uint64_t> next_id_;
-};
-
-}  // namespace gralloc
-
-#endif  // __GR_BUF_MGR_H__
diff --git a/gralloc/gr_device_impl.cpp b/gralloc/gr_device_impl.cpp
deleted file mode 100644
index a26ea81..0000000
--- a/gralloc/gr_device_impl.cpp
+++ /dev/null
@@ -1,869 +0,0 @@
-/*
- * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
-
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *   * Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- *   * Redistributions in binary form must reproduce the above
- *     copyright notice, this list of conditions and the following
- *     disclaimer in the documentation and/or other materials provided
- *     with the distribution.
- *   * Neither the name of The Linux Foundation nor the names of its
- *     contributors may be used to endorse or promote products derived
- *     from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#define ATRACE_TAG (ATRACE_TAG_GRAPHICS | ATRACE_TAG_HAL)
-#include <log/log.h>
-#include <cutils/trace.h>
-#include <sync/sync.h>
-#include <utils/Trace.h>
-#include <algorithm>
-#include <sstream>
-#include <string>
-
-#include "gr_buf_descriptor.h"
-#include "gr_device_impl.h"
-#include "gr_utils.h"
-#include "gralloc_priv.h"
-#include "qdMetaData.h"
-#include "qd_utils.h"
-
-int gralloc_device_open(const struct hw_module_t *module, const char *name, hw_device_t **device);
-
-int gralloc_device_close(struct hw_device_t *device);
-
-static struct hw_module_methods_t gralloc_module_methods = {.open = gralloc_device_open};
-
-struct gralloc_module_t HAL_MODULE_INFO_SYM = {
-    // clang-format off
-    .common = {
-            .tag = HARDWARE_MODULE_TAG,
-            .module_api_version = GRALLOC_MODULE_API_VERSION_1_0,
-            .hal_api_version = HARDWARE_HAL_API_VERSION,
-            .id = GRALLOC_HARDWARE_MODULE_ID,
-            .name = "Graphics Memory Module",
-            .author = "Code Aurora Forum",
-            .methods = &gralloc_module_methods,
-            .dso = 0,
-            .reserved = {0},
-        },
-    // clang-format on
-};
-
-int gralloc_device_open(const struct hw_module_t *module, const char *name, hw_device_t **device) {
-  int status = -EINVAL;
-  if (module && device && !strcmp(name, GRALLOC_HARDWARE_MODULE_ID)) {
-    gralloc::GrallocImpl * /*gralloc1_device_t*/ dev = gralloc::GrallocImpl::GetInstance(module);
-    *device = reinterpret_cast<hw_device_t *>(dev);
-    if (dev) {
-      status = 0;
-    } else {
-      ALOGE("Fatal error opening gralloc1 device");
-    }
-  }
-  return status;
-}
-
-namespace gralloc {
-
-std::atomic<uint64_t> GrallocImpl::next_descriptor_id_(1);
-
-GrallocImpl::GrallocImpl(const hw_module_t *module) {
-  common.tag = HARDWARE_DEVICE_TAG;
-  common.version = GRALLOC_MODULE_API_VERSION_1_0;
-  common.module = const_cast<hw_module_t *>(module);
-  common.close = CloseDevice;
-  getFunction = GetFunction;
-  getCapabilities = GetCapabilities;
-
-  initialized_ = Init();
-}
-
-inline gralloc1_error_t ToError(Error error) {
-  switch (error) {
-    case Error::NONE:
-      return GRALLOC1_ERROR_NONE;
-    case Error::BAD_DESCRIPTOR:
-      return GRALLOC1_ERROR_BAD_DESCRIPTOR;
-    case Error::BAD_BUFFER:
-      return GRALLOC1_ERROR_BAD_HANDLE;
-    case Error::BAD_VALUE:
-      return GRALLOC1_ERROR_BAD_VALUE;
-    case Error::NO_RESOURCES:
-      return GRALLOC1_ERROR_NO_RESOURCES;
-    case Error::UNSUPPORTED:
-    default:
-      return GRALLOC1_ERROR_UNSUPPORTED;
-  }
-}
-
-static uint64_t ProducerUsageToBufferUsage(gralloc1_producer_usage_t producer_usage) {
-  uint64_t usage = producer_usage & ~(GRALLOC1_PRODUCER_USAGE_CPU_READ_OFTEN |
-                                      GRALLOC1_PRODUCER_USAGE_CPU_WRITE_OFTEN);
-  if ((producer_usage & GRALLOC1_PRODUCER_USAGE_CPU_READ_OFTEN) ==
-      GRALLOC1_PRODUCER_USAGE_CPU_READ_OFTEN) {
-    usage |= BufferUsage::CPU_READ_OFTEN;
-  } else if ((producer_usage & GRALLOC1_PRODUCER_USAGE_CPU_READ) ==
-             GRALLOC1_PRODUCER_USAGE_CPU_READ) {
-    usage |= BufferUsage::CPU_READ_RARELY;
-  }
-
-  if ((producer_usage & GRALLOC1_PRODUCER_USAGE_CPU_WRITE_OFTEN) ==
-      GRALLOC1_PRODUCER_USAGE_CPU_WRITE_OFTEN) {
-    usage |= BufferUsage::CPU_WRITE_OFTEN;
-  } else if ((producer_usage & GRALLOC1_PRODUCER_USAGE_CPU_WRITE) ==
-             GRALLOC1_PRODUCER_USAGE_CPU_WRITE) {
-    usage |= BufferUsage::CPU_WRITE_RARELY;
-  }
-  return usage;
-}
-
-static uint64_t ConsumerUsageToBufferUsage(gralloc1_consumer_usage_t consumer_usage) {
-  uint64_t usage = consumer_usage & ~(GRALLOC1_CONSUMER_USAGE_CPU_READ_OFTEN);
-  if ((consumer_usage & GRALLOC1_CONSUMER_USAGE_CPU_READ_OFTEN) ==
-      GRALLOC1_CONSUMER_USAGE_CPU_READ_OFTEN) {
-    usage |= BufferUsage::CPU_READ_OFTEN;
-  } else if ((consumer_usage & GRALLOC1_CONSUMER_USAGE_CPU_READ) ==
-             GRALLOC1_CONSUMER_USAGE_CPU_READ) {
-    usage |= BufferUsage::CPU_READ_RARELY;
-  }
-  return usage;
-}
-
-bool GrallocImpl::Init() {
-  buf_mgr_ = BufferManager::GetInstance();
-  return buf_mgr_ != nullptr;
-}
-
-GrallocImpl::~GrallocImpl() {}
-
-gralloc1_error_t GrallocImpl::CreateBufferDescriptorLocked(
-    gralloc1_buffer_descriptor_t *descriptor_id) {
-  std::lock_guard<std::mutex> lock(descriptor_lock_);
-  auto descriptor = std::make_shared<BufferDescriptor>(next_descriptor_id_++);
-  *descriptor_id = static_cast<gralloc1_buffer_descriptor_t>(descriptor->GetId());
-  descriptors_map_.emplace(*descriptor_id, descriptor);
-  return GRALLOC1_ERROR_NONE;
-}
-
-gralloc1_error_t GrallocImpl::DestroyBufferDescriptorLocked(
-    gralloc1_buffer_descriptor_t descriptor_id) {
-  std::lock_guard<std::mutex> lock(descriptor_lock_);
-  const auto descriptor = descriptors_map_.find(descriptor_id);
-  if (descriptor == descriptors_map_.end()) {
-    return GRALLOC1_ERROR_BAD_DESCRIPTOR;
-  }
-  descriptors_map_.erase(descriptor);
-  return GRALLOC1_ERROR_NONE;
-}
-
-int GrallocImpl::CloseDevice(hw_device_t *device __unused) {
-  // No-op since the gralloc device is a singleton
-  return 0;
-}
-
-void GrallocImpl::GetCapabilities(struct gralloc1_device *device, uint32_t *out_count,
-                                  int32_t /*gralloc1_capability_t*/ *out_capabilities) {
-  if (device != nullptr && out_count != nullptr) {
-    if (out_capabilities != nullptr && *out_count >= 3) {
-      out_capabilities[0] = GRALLOC1_CAPABILITY_TEST_ALLOCATE;
-      out_capabilities[1] = GRALLOC1_CAPABILITY_LAYERED_BUFFERS;
-      out_capabilities[2] = GRALLOC1_CAPABILITY_RELEASE_IMPLY_DELETE;
-    }
-    *out_count = 3;
-  }
-  return;
-}
-
-gralloc1_function_pointer_t GrallocImpl::GetFunction(gralloc1_device_t *device, int32_t function) {
-  if (!device) {
-    return NULL;
-  }
-
-  switch (function) {
-    case GRALLOC1_FUNCTION_DUMP:
-      return reinterpret_cast<gralloc1_function_pointer_t>(Dump);
-    case GRALLOC1_FUNCTION_CREATE_DESCRIPTOR:
-      return reinterpret_cast<gralloc1_function_pointer_t>(CreateBufferDescriptor);
-    case GRALLOC1_FUNCTION_DESTROY_DESCRIPTOR:
-      return reinterpret_cast<gralloc1_function_pointer_t>(DestroyBufferDescriptor);
-    case GRALLOC1_FUNCTION_SET_CONSUMER_USAGE:
-      return reinterpret_cast<gralloc1_function_pointer_t>(SetConsumerUsage);
-    case GRALLOC1_FUNCTION_SET_DIMENSIONS:
-      return reinterpret_cast<gralloc1_function_pointer_t>(SetBufferDimensions);
-    case GRALLOC1_FUNCTION_SET_FORMAT:
-      return reinterpret_cast<gralloc1_function_pointer_t>(SetColorFormat);
-    case GRALLOC1_FUNCTION_SET_LAYER_COUNT:
-      return reinterpret_cast<gralloc1_function_pointer_t>(SetLayerCount);
-    case GRALLOC1_FUNCTION_SET_PRODUCER_USAGE:
-      return reinterpret_cast<gralloc1_function_pointer_t>(SetProducerUsage);
-    case GRALLOC1_FUNCTION_GET_BACKING_STORE:
-      return reinterpret_cast<gralloc1_function_pointer_t>(GetBackingStore);
-    case GRALLOC1_FUNCTION_GET_CONSUMER_USAGE:
-      return reinterpret_cast<gralloc1_function_pointer_t>(GetConsumerUsage);
-    case GRALLOC1_FUNCTION_GET_DIMENSIONS:
-      return reinterpret_cast<gralloc1_function_pointer_t>(GetBufferDimensions);
-    case GRALLOC1_FUNCTION_GET_FORMAT:
-      return reinterpret_cast<gralloc1_function_pointer_t>(GetColorFormat);
-    case GRALLOC1_FUNCTION_GET_LAYER_COUNT:
-      return reinterpret_cast<gralloc1_function_pointer_t>(GetLayerCount);
-    case GRALLOC1_FUNCTION_GET_PRODUCER_USAGE:
-      return reinterpret_cast<gralloc1_function_pointer_t>(GetProducerUsage);
-    case GRALLOC1_FUNCTION_GET_STRIDE:
-      return reinterpret_cast<gralloc1_function_pointer_t>(GetBufferStride);
-    case GRALLOC1_FUNCTION_ALLOCATE:
-      return reinterpret_cast<gralloc1_function_pointer_t>(AllocateBuffers);
-    case GRALLOC1_FUNCTION_RETAIN:
-      return reinterpret_cast<gralloc1_function_pointer_t>(RetainBuffer);
-    case GRALLOC1_FUNCTION_RELEASE:
-      return reinterpret_cast<gralloc1_function_pointer_t>(ReleaseBuffer);
-    case GRALLOC1_FUNCTION_GET_NUM_FLEX_PLANES:
-      return reinterpret_cast<gralloc1_function_pointer_t>(GetNumFlexPlanes);
-    case GRALLOC1_FUNCTION_LOCK:
-      return reinterpret_cast<gralloc1_function_pointer_t>(LockBuffer);
-    case GRALLOC1_FUNCTION_LOCK_FLEX:
-      return reinterpret_cast<gralloc1_function_pointer_t>(LockFlex);
-    case GRALLOC1_FUNCTION_UNLOCK:
-      return reinterpret_cast<gralloc1_function_pointer_t>(UnlockBuffer);
-    case GRALLOC1_FUNCTION_PERFORM:
-      return reinterpret_cast<gralloc1_function_pointer_t>(Gralloc1Perform);
-    default:
-      ALOGE("%s:Gralloc Error. Client Requested for unsupported function", __FUNCTION__);
-      return NULL;
-  }
-
-  return NULL;
-}
-
-gralloc1_error_t GrallocImpl::Dump(gralloc1_device_t *device, uint32_t *out_size,
-                                   char *out_buffer) {
-  if (!device || !out_size) {
-    ALOGE("Gralloc Error : device=%p", (void *)device);
-    return GRALLOC1_ERROR_BAD_DESCRIPTOR;
-  }
-  const size_t max_dump_size = 8192;
-  if (out_buffer == nullptr) {
-    *out_size = max_dump_size;
-  } else {
-    std::ostringstream os;
-    os << "-------------------------------" << std::endl;
-    os << "QTI gralloc dump:" << std::endl;
-    os << "-------------------------------" << std::endl;
-    GrallocImpl const *dev = GRALLOC_IMPL(device);
-    dev->buf_mgr_->Dump(&os);
-    os << "-------------------------------" << std::endl;
-    auto copied = os.str().copy(out_buffer, std::min(os.str().size(), max_dump_size), 0);
-    *out_size = UINT(copied);
-  }
-
-  return GRALLOC1_ERROR_NONE;
-}
-
-gralloc1_error_t GrallocImpl::CheckDeviceAndHandle(gralloc1_device_t *device,
-                                                   buffer_handle_t buffer) {
-  const private_handle_t *hnd = PRIV_HANDLE_CONST(buffer);
-  if (!device || (private_handle_t::validate(hnd) != 0)) {
-    ALOGE("Gralloc Error : device= %p, buffer-handle=%p", (void *)device, (void *)buffer);
-    return GRALLOC1_ERROR_BAD_HANDLE;
-  }
-
-  return GRALLOC1_ERROR_NONE;
-}
-
-gralloc1_error_t GrallocImpl::CreateBufferDescriptor(gralloc1_device_t *device,
-                                                     gralloc1_buffer_descriptor_t *out_descriptor) {
-  if (!device || !out_descriptor) {
-    return GRALLOC1_ERROR_BAD_DESCRIPTOR;
-  }
-  auto *dev = reinterpret_cast<GrallocImpl *>(device);
-  return dev->CreateBufferDescriptorLocked(out_descriptor);
-}
-
-gralloc1_error_t GrallocImpl::DestroyBufferDescriptor(gralloc1_device_t *device,
-                                                      gralloc1_buffer_descriptor_t descriptor) {
-  if (!device) {
-    return GRALLOC1_ERROR_BAD_DESCRIPTOR;
-  }
-  auto *dev = reinterpret_cast<GrallocImpl *>(device);
-  return dev->DestroyBufferDescriptorLocked(descriptor);
-}
-
-gralloc1_error_t GrallocImpl::SetConsumerUsage(gralloc1_device_t *device,
-                                               gralloc1_buffer_descriptor_t descriptor,
-                                               gralloc1_consumer_usage_t usage) {
-  if (!device) {
-    return GRALLOC1_ERROR_BAD_DESCRIPTOR;
-  } else {
-    auto *dev = reinterpret_cast<GrallocImpl *>(device);
-    return dev->CallBufferDescriptorFunction(descriptor, &BufferDescriptor::SetUsage,
-                                             ConsumerUsageToBufferUsage(usage));
-  }
-}
-
-gralloc1_error_t GrallocImpl::SetBufferDimensions(gralloc1_device_t *device,
-                                                  gralloc1_buffer_descriptor_t descriptor,
-                                                  uint32_t width, uint32_t height) {
-  if (!device) {
-    return GRALLOC1_ERROR_BAD_DESCRIPTOR;
-  } else {
-    auto *dev = reinterpret_cast<GrallocImpl *>(device);
-    return dev->CallBufferDescriptorFunction(descriptor, &BufferDescriptor::SetDimensions,
-                                             INT(width), INT(height));
-  }
-}
-
-gralloc1_error_t GrallocImpl::SetColorFormat(gralloc1_device_t *device,
-                                             gralloc1_buffer_descriptor_t descriptor,
-                                             int32_t format) {
-  if (!device) {
-    return GRALLOC1_ERROR_BAD_DESCRIPTOR;
-  } else {
-    auto *dev = reinterpret_cast<GrallocImpl *>(device);
-    return dev->CallBufferDescriptorFunction(descriptor, &BufferDescriptor::SetColorFormat, format);
-  }
-}
-
-gralloc1_error_t GrallocImpl::SetLayerCount(gralloc1_device_t *device,
-                                            gralloc1_buffer_descriptor_t descriptor,
-                                            uint32_t layer_count) {
-  if (!device) {
-    return GRALLOC1_ERROR_BAD_DESCRIPTOR;
-  } else {
-    auto *dev = reinterpret_cast<GrallocImpl *>(device);
-    return dev->CallBufferDescriptorFunction(descriptor, &BufferDescriptor::SetLayerCount,
-                                             layer_count);
-  }
-}
-
-gralloc1_error_t GrallocImpl::SetProducerUsage(gralloc1_device_t *device,
-                                               gralloc1_buffer_descriptor_t descriptor,
-                                               gralloc1_producer_usage_t usage) {
-  if (!device) {
-    return GRALLOC1_ERROR_BAD_DESCRIPTOR;
-  } else {
-    auto *dev = reinterpret_cast<GrallocImpl *>(device);
-    return dev->CallBufferDescriptorFunction(descriptor, &BufferDescriptor::SetUsage,
-                                             ProducerUsageToBufferUsage(usage));
-  }
-}
-
-gralloc1_error_t GrallocImpl::GetBackingStore(gralloc1_device_t *device, buffer_handle_t buffer,
-                                              gralloc1_backing_store_t *out_backstore) {
-  if (!device || !buffer) {
-    return GRALLOC1_ERROR_BAD_HANDLE;
-  }
-
-  *out_backstore =
-      static_cast<gralloc1_backing_store_t>(PRIV_HANDLE_CONST(buffer)->GetBackingstore());
-
-  return GRALLOC1_ERROR_NONE;
-}
-
-gralloc1_error_t GrallocImpl::GetConsumerUsage(gralloc1_device_t *device, buffer_handle_t buffer,
-                                               gralloc1_consumer_usage_t *outUsage) {
-  gralloc1_error_t status = CheckDeviceAndHandle(device, buffer);
-  if (status == GRALLOC1_ERROR_NONE) {
-    *outUsage = static_cast<gralloc1_consumer_usage_t>(PRIV_HANDLE_CONST(buffer)->GetUsage());
-  }
-
-  return status;
-}
-
-gralloc1_error_t GrallocImpl::GetBufferDimensions(gralloc1_device_t *device, buffer_handle_t buffer,
-                                                  uint32_t *outWidth, uint32_t *outHeight) {
-  gralloc1_error_t status = CheckDeviceAndHandle(device, buffer);
-  if (status == GRALLOC1_ERROR_NONE) {
-    const private_handle_t *hnd = PRIV_HANDLE_CONST(buffer);
-    *outWidth = UINT(hnd->GetUnalignedWidth());
-    *outHeight = UINT(hnd->GetUnalignedHeight());
-  }
-
-  return status;
-}
-
-gralloc1_error_t GrallocImpl::GetColorFormat(gralloc1_device_t *device, buffer_handle_t buffer,
-                                             int32_t *outFormat) {
-  gralloc1_error_t status = CheckDeviceAndHandle(device, buffer);
-  if (status == GRALLOC1_ERROR_NONE) {
-    *outFormat = PRIV_HANDLE_CONST(buffer)->GetColorFormat();
-  }
-
-  return status;
-}
-
-gralloc1_error_t GrallocImpl::GetLayerCount(gralloc1_device_t *device, buffer_handle_t buffer,
-                                            uint32_t *outLayerCount) {
-  gralloc1_error_t status = CheckDeviceAndHandle(device, buffer);
-  if (status == GRALLOC1_ERROR_NONE) {
-    *outLayerCount = PRIV_HANDLE_CONST(buffer)->GetLayerCount();
-  }
-
-  return status;
-}
-
-gralloc1_error_t GrallocImpl::GetProducerUsage(gralloc1_device_t *device, buffer_handle_t buffer,
-                                               gralloc1_producer_usage_t *outUsage) {
-  if (!outUsage) {
-    return GRALLOC1_ERROR_BAD_VALUE;
-  }
-
-  gralloc1_error_t status = CheckDeviceAndHandle(device, buffer);
-  if (status == GRALLOC1_ERROR_NONE) {
-    *outUsage = static_cast<gralloc1_producer_usage_t>(PRIV_HANDLE_CONST(buffer)->GetUsage());
-  }
-
-  return status;
-}
-
-gralloc1_error_t GrallocImpl::GetBufferStride(gralloc1_device_t *device, buffer_handle_t buffer,
-                                              uint32_t *outStride) {
-  if (!outStride) {
-    return GRALLOC1_ERROR_BAD_VALUE;
-  }
-
-  gralloc1_error_t status = CheckDeviceAndHandle(device, buffer);
-  if (status == GRALLOC1_ERROR_NONE) {
-    *outStride = UINT(PRIV_HANDLE_CONST(buffer)->GetStride());
-  }
-
-  return status;
-}
-
-gralloc1_error_t GrallocImpl::AllocateBuffer(const gralloc1_buffer_descriptor_t *descriptor_ids,
-                                             buffer_handle_t *out_buffers) {
-  gralloc1_error_t status = GRALLOC1_ERROR_NONE;
-
-  // Validate descriptor
-  std::lock_guard<std::mutex> descriptor_lock(descriptor_lock_);
-  std::shared_ptr<gralloc::BufferDescriptor> descriptor;
-  const auto map_descriptor = descriptors_map_.find(descriptor_ids[0]);
-  if (map_descriptor == descriptors_map_.end()) {
-    return GRALLOC1_ERROR_BAD_DESCRIPTOR;
-  } else {
-    descriptor = map_descriptor->second;
-  }
-
-  // Allocate separate buffer for each descriptor
-  if (buf_mgr_->AllocateBuffer(*descriptor, &out_buffers[0]) != Error::NONE) {
-    return GRALLOC1_ERROR_NO_RESOURCES;
-  }
-
-  return status;
-}
-
-gralloc1_error_t GrallocImpl::AllocateBuffers(gralloc1_device_t *device, uint32_t num_descriptors,
-                                              const gralloc1_buffer_descriptor_t *descriptors,
-                                              buffer_handle_t *out_buffers) {
-  if (!num_descriptors || !descriptors) {
-    return GRALLOC1_ERROR_BAD_DESCRIPTOR;
-  }
-
-  if (!device) {
-    return GRALLOC1_ERROR_BAD_VALUE;
-  }
-
-  if (num_descriptors != 1) {
-    return GRALLOC1_ERROR_UNSUPPORTED;
-  }
-
-  auto *dev = reinterpret_cast<GrallocImpl *>(device);
-  gralloc1_error_t status = dev->AllocateBuffer(descriptors, out_buffers);
-
-  return status;
-}
-
-gralloc1_error_t GrallocImpl::RetainBuffer(gralloc1_device_t *device, buffer_handle_t buffer) {
-  gralloc1_error_t status = CheckDeviceAndHandle(device, buffer);
-  if (status == GRALLOC1_ERROR_NONE) {
-    const private_handle_t *hnd = PRIV_HANDLE_CONST(buffer);
-    GrallocImpl const *dev = GRALLOC_IMPL(device);
-    status = ToError(dev->buf_mgr_->RetainBuffer(hnd));
-  }
-
-  return status;
-}
-
-gralloc1_error_t GrallocImpl::ReleaseBuffer(gralloc1_device_t *device, buffer_handle_t buffer) {
-  if (!device || !buffer) {
-    return GRALLOC1_ERROR_BAD_DESCRIPTOR;
-  }
-
-  const private_handle_t *hnd = PRIV_HANDLE_CONST(buffer);
-  GrallocImpl const *dev = GRALLOC_IMPL(device);
-  return ToError(dev->buf_mgr_->ReleaseBuffer(hnd));
-}
-
-gralloc1_error_t GrallocImpl::GetFlexLayout(const private_handle_t *hnd,
-                                            struct android_flex_layout *layout) {
-  if (!IsYuvFormat(hnd)) {
-    return GRALLOC1_ERROR_UNSUPPORTED;
-  }
-
-  android_ycbcr yuvPlaneInfo[2];
-  int err = GetYUVPlaneInfo(hnd, yuvPlaneInfo);
-
-  if (err != 0) {
-    return GRALLOC1_ERROR_BAD_HANDLE;
-  }
-
-  layout->format = FLEX_FORMAT_YCbCr;
-  layout->num_planes = 3;
-
-  for (uint32_t i = 0; i < layout->num_planes; i++) {
-    layout->planes[i].bits_per_component = 8;
-    layout->planes[i].bits_used = 8;
-    layout->planes[i].h_increment = 1;
-    layout->planes[i].v_increment = 1;
-    layout->planes[i].h_subsampling = 2;
-    layout->planes[i].v_subsampling = 2;
-  }
-
-  // We are only returning flex layout for progressive or single field formats.
-  struct android_ycbcr ycbcr = yuvPlaneInfo[0];
-  layout->planes[0].top_left = static_cast<uint8_t *>(ycbcr.y);
-  layout->planes[0].component = FLEX_COMPONENT_Y;
-  layout->planes[0].v_increment = static_cast<int32_t>(ycbcr.ystride);
-
-  layout->planes[1].top_left = static_cast<uint8_t *>(ycbcr.cb);
-  layout->planes[1].component = FLEX_COMPONENT_Cb;
-  layout->planes[1].h_increment = static_cast<int32_t>(ycbcr.chroma_step);
-  layout->planes[1].v_increment = static_cast<int32_t>(ycbcr.cstride);
-
-  layout->planes[2].top_left = static_cast<uint8_t *>(ycbcr.cr);
-  layout->planes[2].component = FLEX_COMPONENT_Cr;
-  layout->planes[2].h_increment = static_cast<int32_t>(ycbcr.chroma_step);
-  layout->planes[2].v_increment = static_cast<int32_t>(ycbcr.cstride);
-  return GRALLOC1_ERROR_NONE;
-}
-
-gralloc1_error_t GrallocImpl::GetNumFlexPlanes(gralloc1_device_t *device, buffer_handle_t buffer,
-                                               uint32_t *out_num_planes) {
-  if (!out_num_planes) {
-    return GRALLOC1_ERROR_BAD_VALUE;
-  }
-
-  gralloc1_error_t status = CheckDeviceAndHandle(device, buffer);
-  if (status == GRALLOC1_ERROR_NONE) {
-    const private_handle_t *hnd = PRIV_HANDLE_CONST(buffer);
-    if (!IsYuvFormat(hnd)) {
-      status = GRALLOC1_ERROR_UNSUPPORTED;
-    } else {
-      *out_num_planes = 3;
-    }
-  }
-  return status;
-}
-
-static inline void CloseFdIfValid(int fd) {
-  if (fd > 0) {
-    close(fd);
-  }
-}
-
-gralloc1_error_t GrallocImpl::LockBuffer(gralloc1_device_t *device, buffer_handle_t buffer,
-                                         gralloc1_producer_usage_t prod_usage,
-                                         gralloc1_consumer_usage_t cons_usage,
-                                         const gralloc1_rect_t *region, void **out_data,
-                                         int32_t acquire_fence) {
-  ATRACE_CALL();
-  gralloc1_error_t status = CheckDeviceAndHandle(device, buffer);
-  if (status != GRALLOC1_ERROR_NONE || !out_data ||
-      !region) {  // currently we ignore the region/rect client wants to lock
-    CloseFdIfValid(acquire_fence);
-    return status;
-  }
-
-  if (acquire_fence > 0) {
-    ATRACE_BEGIN("fence wait");
-    int error = sync_wait(acquire_fence, 1000);
-    ATRACE_END();
-    CloseFdIfValid(acquire_fence);
-    if (error < 0) {
-      ALOGE("%s: sync_wait timedout! error = %s", __FUNCTION__, strerror(errno));
-      return GRALLOC1_ERROR_UNDEFINED;
-    }
-  }
-
-  const private_handle_t *hnd = PRIV_HANDLE_CONST(buffer);
-  GrallocImpl const *dev = GRALLOC_IMPL(device);
-
-  // Either producer usage or consumer usage must be *_USAGE_NONE
-  if ((prod_usage != GRALLOC1_PRODUCER_USAGE_NONE) &&
-      (cons_usage != GRALLOC1_CONSUMER_USAGE_NONE)) {
-    // Current gralloc1 clients do not satisfy this restriction.
-    // See b/33588773 for details
-    // return GRALLOC1_ERROR_BAD_VALUE;
-  }
-
-  status = ToError(dev->buf_mgr_->LockBuffer(
-      hnd, ProducerUsageToBufferUsage(prod_usage) | ConsumerUsageToBufferUsage(cons_usage)));
-  *out_data = reinterpret_cast<void *>(hnd->base);
-
-  return status;
-}
-
-gralloc1_error_t GrallocImpl::LockFlex(gralloc1_device_t *device, buffer_handle_t buffer,
-                                       gralloc1_producer_usage_t prod_usage,
-                                       gralloc1_consumer_usage_t cons_usage,
-                                       const gralloc1_rect_t *region,
-                                       struct android_flex_layout *out_flex_layout,
-                                       int32_t acquire_fence) {
-  if (!out_flex_layout) {
-    CloseFdIfValid(acquire_fence);
-    return GRALLOC1_ERROR_BAD_VALUE;
-  }
-
-  void *out_data{};
-  gralloc1_error_t status = GrallocImpl::LockBuffer(device, buffer, prod_usage, cons_usage, region,
-                                                    &out_data, acquire_fence);
-  if (status != GRALLOC1_ERROR_NONE) {
-    return status;
-  }
-
-  auto *dev = reinterpret_cast<GrallocImpl *>(device);
-  const private_handle_t *hnd = PRIV_HANDLE_CONST(buffer);
-  dev->GetFlexLayout(hnd, out_flex_layout);
-  return status;
-}
-
-gralloc1_error_t GrallocImpl::UnlockBuffer(gralloc1_device_t *device, buffer_handle_t buffer,
-                                           int32_t *release_fence) {
-  gralloc1_error_t status = CheckDeviceAndHandle(device, buffer);
-  if (status != GRALLOC1_ERROR_NONE) {
-    return status;
-  }
-
-  if (!release_fence) {
-    return GRALLOC1_ERROR_BAD_VALUE;
-  }
-
-  const private_handle_t *hnd = PRIV_HANDLE_CONST(buffer);
-  GrallocImpl const *dev = GRALLOC_IMPL(device);
-
-  *release_fence = -1;
-
-  return ToError(dev->buf_mgr_->UnlockBuffer(hnd));
-}
-
-static gralloc1_error_t Perform(int operation, va_list args) {
-  switch (operation) {
-    case GRALLOC_MODULE_PERFORM_GET_STRIDE: {
-      int width = va_arg(args, int);
-      int format = va_arg(args, int);
-      int *stride = va_arg(args, int *);
-      unsigned int alignedw = 0, alignedh = 0;
-
-      if (!stride) {
-        return GRALLOC1_ERROR_BAD_VALUE;
-      }
-
-      BufferInfo info(width, width, format);
-      GetAlignedWidthAndHeight(info, &alignedw, &alignedh);
-      *stride = INT(alignedw);
-    } break;
-
-    case GRALLOC_MODULE_PERFORM_GET_CUSTOM_STRIDE_FROM_HANDLE: {
-      private_handle_t *hnd = va_arg(args, private_handle_t *);
-      int *stride = va_arg(args, int *);
-      if (private_handle_t::validate(hnd) != 0) {
-        return GRALLOC1_ERROR_BAD_HANDLE;
-      }
-
-      if (!stride) {
-        return GRALLOC1_ERROR_BAD_VALUE;
-      }
-
-      BufferDim_t buffer_dim;
-      if (getMetaData(hnd, GET_BUFFER_GEOMETRY, &buffer_dim) == 0) {
-        *stride = buffer_dim.sliceWidth;
-      } else {
-        *stride = hnd->width;
-      }
-    } break;
-
-    case GRALLOC_MODULE_PERFORM_GET_CUSTOM_STRIDE_AND_HEIGHT_FROM_HANDLE: {
-      private_handle_t *hnd = va_arg(args, private_handle_t *);
-      int *stride = va_arg(args, int *);
-      int *height = va_arg(args, int *);
-      if (private_handle_t::validate(hnd) != 0) {
-        return GRALLOC1_ERROR_BAD_HANDLE;
-      }
-
-      if (!stride || !height) {
-        return GRALLOC1_ERROR_BAD_VALUE;
-      }
-
-      GetCustomDimensions(hnd, stride, height);
-    } break;
-
-    case GRALLOC_MODULE_PERFORM_GET_ATTRIBUTES: {
-      int width = va_arg(args, int);
-      int height = va_arg(args, int);
-      int format = va_arg(args, int);
-      uint64_t usage = va_arg(args, uint64_t);
-      usage |= va_arg(args, uint64_t);
-
-      int *aligned_width = va_arg(args, int *);
-      int *aligned_height = va_arg(args, int *);
-      int *tile_enabled = va_arg(args, int *);
-      if (!aligned_width || !aligned_height || !tile_enabled) {
-        return GRALLOC1_ERROR_BAD_VALUE;
-      }
-
-      unsigned int alignedw, alignedh;
-      BufferInfo info(width, height, format, usage);
-      *tile_enabled = IsUBwcEnabled(format, usage);
-      GetAlignedWidthAndHeight(info, &alignedw, &alignedh);
-      *aligned_width = INT(alignedw);
-      *aligned_height = INT(alignedh);
-    } break;
-
-    case GRALLOC_MODULE_PERFORM_GET_COLOR_SPACE_FROM_HANDLE: {
-      private_handle_t *hnd = va_arg(args, private_handle_t *);
-      int *color_space = va_arg(args, int *);
-
-      if (private_handle_t::validate(hnd) != 0) {
-        return GRALLOC1_ERROR_BAD_HANDLE;
-      }
-
-      if (!color_space) {
-        return GRALLOC1_ERROR_BAD_VALUE;
-      }
-
-      *color_space = 0;
-      GetColorSpaceFromMetadata(hnd, color_space);
-    } break;
-    case GRALLOC_MODULE_PERFORM_GET_YUV_PLANE_INFO: {
-      private_handle_t *hnd = va_arg(args, private_handle_t *);
-      android_ycbcr *ycbcr = va_arg(args, struct android_ycbcr *);
-      if (private_handle_t::validate(hnd) != 0) {
-        return GRALLOC1_ERROR_BAD_HANDLE;
-      }
-
-      if (!ycbcr) {
-        return GRALLOC1_ERROR_BAD_VALUE;
-      }
-
-      if (GetYUVPlaneInfo(hnd, ycbcr)) {
-        return GRALLOC1_ERROR_UNDEFINED;
-      }
-    } break;
-
-    case GRALLOC_MODULE_PERFORM_GET_MAP_SECURE_BUFFER_INFO: {
-      private_handle_t *hnd = va_arg(args, private_handle_t *);
-      int *map_secure_buffer = va_arg(args, int *);
-
-      if (private_handle_t::validate(hnd) != 0) {
-        return GRALLOC1_ERROR_BAD_HANDLE;
-      }
-
-      if (!map_secure_buffer) {
-        return GRALLOC1_ERROR_BAD_VALUE;
-      }
-
-      if (getMetaData(hnd, GET_MAP_SECURE_BUFFER, map_secure_buffer) != 0) {
-        *map_secure_buffer = 0;
-      }
-    } break;
-
-    case GRALLOC_MODULE_PERFORM_GET_UBWC_FLAG: {
-      private_handle_t *hnd = va_arg(args, private_handle_t *);
-      int *flag = va_arg(args, int *);
-
-      if (private_handle_t::validate(hnd) != 0) {
-        return GRALLOC1_ERROR_BAD_HANDLE;
-      }
-
-      if (!flag) {
-        return GRALLOC1_ERROR_BAD_VALUE;
-      }
-
-      *flag = hnd->flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED;
-      int linear_format = 0;
-      if (getMetaData(hnd, GET_LINEAR_FORMAT, &linear_format) == 0) {
-        if (linear_format) {
-          *flag = 0;
-        }
-      }
-    } break;
-
-    case GRALLOC_MODULE_PERFORM_GET_RGB_DATA_ADDRESS: {
-      private_handle_t *hnd = va_arg(args, private_handle_t *);
-      void **rgb_data = va_arg(args, void **);
-
-      if (private_handle_t::validate(hnd) != 0) {
-        return GRALLOC1_ERROR_BAD_HANDLE;
-      }
-
-      if (!rgb_data) {
-        return GRALLOC1_ERROR_BAD_VALUE;
-      }
-
-      if (GetRgbDataAddress(hnd, rgb_data)) {
-        return GRALLOC1_ERROR_UNDEFINED;
-      }
-    } break;
-
-    case GRALLOC1_MODULE_PERFORM_GET_INTERLACE_FLAG: {
-      private_handle_t *hnd = va_arg(args, private_handle_t *);
-      int *flag = va_arg(args, int *);
-
-      if (private_handle_t::validate(hnd) != 0) {
-        return GRALLOC1_ERROR_BAD_HANDLE;
-      }
-
-      if (!flag) {
-        return GRALLOC1_ERROR_BAD_VALUE;
-      }
-
-      if (getMetaData(hnd, GET_PP_PARAM_INTERLACED, flag) != 0) {
-        *flag = 0;
-      }
-    } break;
-
-    case GRALLOC_MODULE_PERFORM_SET_SINGLE_BUFFER_MODE: {
-      private_handle_t *hnd = va_arg(args, private_handle_t *);
-      uint32_t *enable = va_arg(args, uint32_t *);
-      if (private_handle_t::validate(hnd) != 0) {
-        return GRALLOC1_ERROR_BAD_HANDLE;
-      }
-      if (setMetaData(hnd, SET_SINGLE_BUFFER_MODE, enable) != 0) {
-        return GRALLOC1_ERROR_UNSUPPORTED;
-      }
-    } break;
-
-    default:
-      break;
-  }
-  return GRALLOC1_ERROR_NONE;
-}
-
-gralloc1_error_t GrallocImpl::Gralloc1Perform(gralloc1_device_t *device, int operation, ...) {
-  if (!device) {
-    return GRALLOC1_ERROR_BAD_VALUE;
-  }
-
-  va_list args;
-  va_start(args, operation);
-  gralloc1_error_t err = Perform(operation, args);
-  va_end(args);
-
-  return err;
-}
-
-}  // namespace gralloc
diff --git a/gralloc/gr_device_impl.h b/gralloc/gr_device_impl.h
deleted file mode 100644
index 82e9e71..0000000
--- a/gralloc/gr_device_impl.h
+++ /dev/null
@@ -1,157 +0,0 @@
-/*
- * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
-
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *   * Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- *   * Redistributions in binary form must reproduce the above
- *     copyright notice, this list of conditions and the following
- *     disclaimer in the documentation and/or other materials provided
- *     with the distribution.
- *   * Neither the name of The Linux Foundation nor the names of its
- *     contributors may be used to endorse or promote products derived
- *     from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef __GR_DEVICE_IMPL_H__
-#define __GR_DEVICE_IMPL_H__
-
-#include <hardware/gralloc1.h>
-#include <hardware/hardware.h>
-#include "gr_buf_mgr.h"
-
-struct private_module_t {
-  hw_module_t base;
-};
-
-#define GRALLOC_IMPL(exp) reinterpret_cast<GrallocImpl const *>(exp)
-
-namespace gralloc {
-
-class GrallocImpl : public gralloc1_device_t {
- public:
-  static int CloseDevice(hw_device_t *device);
-  static void GetCapabilities(struct gralloc1_device *device, uint32_t *out_count,
-                              int32_t * /*gralloc1_capability_t*/ out_capabilities);
-  static gralloc1_function_pointer_t GetFunction(
-      struct gralloc1_device *device, int32_t /*gralloc1_function_descriptor_t*/ descriptor);
-
-  static GrallocImpl *GetInstance(const struct hw_module_t *module) {
-    static GrallocImpl *instance = new GrallocImpl(module);
-    if (instance->IsInitialized()) {
-      return instance;
-    } else {
-      return nullptr;
-    }
-  }
-
- private:
-  static inline gralloc1_error_t Dump(gralloc1_device_t *device, uint32_t *out_size,
-                                      char *out_buffer);
-  static inline gralloc1_error_t CheckDeviceAndHandle(gralloc1_device_t *device,
-                                                      buffer_handle_t buffer);
-  static gralloc1_error_t CreateBufferDescriptor(gralloc1_device_t *device,
-                                                 gralloc1_buffer_descriptor_t *out_descriptor);
-  static gralloc1_error_t DestroyBufferDescriptor(gralloc1_device_t *device,
-                                                  gralloc1_buffer_descriptor_t descriptor);
-  static gralloc1_error_t SetConsumerUsage(gralloc1_device_t *device,
-                                           gralloc1_buffer_descriptor_t descriptor,
-                                           gralloc1_consumer_usage_t usage);
-  static gralloc1_error_t SetBufferDimensions(gralloc1_device_t *device,
-                                              gralloc1_buffer_descriptor_t descriptor,
-                                              uint32_t width, uint32_t height);
-  static gralloc1_error_t SetColorFormat(gralloc1_device_t *device,
-                                         gralloc1_buffer_descriptor_t descriptor, int32_t format);
-  static gralloc1_error_t SetLayerCount(gralloc1_device_t *device,
-                                        gralloc1_buffer_descriptor_t descriptor,
-                                        uint32_t layer_count);
-  static gralloc1_error_t SetProducerUsage(gralloc1_device_t *device,
-                                           gralloc1_buffer_descriptor_t descriptor,
-                                           gralloc1_producer_usage_t usage);
-  static gralloc1_error_t GetBackingStore(gralloc1_device_t *device, buffer_handle_t buffer,
-                                          gralloc1_backing_store_t *out_store);
-  static gralloc1_error_t GetConsumerUsage(gralloc1_device_t *device, buffer_handle_t buffer,
-                                           gralloc1_consumer_usage_t *out_usage);
-  static gralloc1_error_t GetBufferDimensions(gralloc1_device_t *device, buffer_handle_t buffer,
-                                              uint32_t *out_width, uint32_t *out_height);
-  static gralloc1_error_t GetColorFormat(gralloc1_device_t *device, buffer_handle_t descriptor,
-                                         int32_t *outFormat);
-  static gralloc1_error_t GetLayerCount(gralloc1_device_t *device, buffer_handle_t buffer,
-                                        uint32_t *out_layer_count);
-  static gralloc1_error_t GetProducerUsage(gralloc1_device_t *device, buffer_handle_t buffer,
-                                           gralloc1_producer_usage_t *out_usage);
-  static gralloc1_error_t GetBufferStride(gralloc1_device_t *device, buffer_handle_t buffer,
-                                          uint32_t *out_stride);
-  static gralloc1_error_t AllocateBuffers(gralloc1_device_t *device, uint32_t num_dptors,
-                                          const gralloc1_buffer_descriptor_t *descriptors,
-                                          buffer_handle_t *out_buffers);
-  static gralloc1_error_t RetainBuffer(gralloc1_device_t *device, buffer_handle_t buffer);
-  static gralloc1_error_t ReleaseBuffer(gralloc1_device_t *device, buffer_handle_t buffer);
-  static gralloc1_error_t GetNumFlexPlanes(gralloc1_device_t *device, buffer_handle_t buffer,
-                                           uint32_t *out_num_planes);
-  static gralloc1_error_t LockBuffer(gralloc1_device_t *device, buffer_handle_t buffer,
-                                     gralloc1_producer_usage_t prod_usage,
-                                     gralloc1_consumer_usage_t cons_usage,
-                                     const gralloc1_rect_t *region, void **out_data,
-                                     int32_t acquire_fence);
-  static gralloc1_error_t LockFlex(gralloc1_device_t *device, buffer_handle_t buffer,
-                                   gralloc1_producer_usage_t prod_usage,
-                                   gralloc1_consumer_usage_t cons_usage,
-                                   const gralloc1_rect_t *region,
-                                   struct android_flex_layout *out_flex_layout,
-                                   int32_t acquire_fence);
-
-  static gralloc1_error_t UnlockBuffer(gralloc1_device_t *device, buffer_handle_t buffer,
-                                       int32_t *release_fence);
-  static gralloc1_error_t Gralloc1Perform(gralloc1_device_t *device, int operation, ...);
-
-  gralloc1_error_t CreateBufferDescriptorLocked(gralloc1_buffer_descriptor_t *descriptor_id);
-  gralloc1_error_t DestroyBufferDescriptorLocked(gralloc1_buffer_descriptor_t descriptor_id);
-  gralloc1_error_t AllocateBuffer(const gralloc1_buffer_descriptor_t *descriptor_ids,
-                                  buffer_handle_t *out_buffers);
-  gralloc1_error_t GetFlexLayout(const private_handle_t *hnd, struct android_flex_layout *layout);
-
-  template <typename... Args>
-  gralloc1_error_t CallBufferDescriptorFunction(gralloc1_buffer_descriptor_t descriptor_id,
-                                                void (BufferDescriptor::*member)(Args...),
-                                                Args... args) {
-    std::lock_guard<std::mutex> lock(descriptor_lock_);
-    const auto map_descriptor = descriptors_map_.find(descriptor_id);
-    if (map_descriptor == descriptors_map_.end()) {
-      return GRALLOC1_ERROR_BAD_DESCRIPTOR;
-    }
-    const auto descriptor = map_descriptor->second;
-    (descriptor.get()->*member)(std::forward<Args>(args)...);
-    return GRALLOC1_ERROR_NONE;
-  }
-
-  explicit GrallocImpl(const hw_module_t *module);
-  ~GrallocImpl();
-  bool Init();
-  bool IsInitialized() const { return initialized_; }
-
-  BufferManager *buf_mgr_ = NULL;
-  bool initialized_ = false;
-  std::mutex descriptor_lock_;
-  std::unordered_map<gralloc1_buffer_descriptor_t, std::shared_ptr<gralloc::BufferDescriptor>>
-      descriptors_map_ = {};
-  static std::atomic<uint64_t> next_descriptor_id_;
-};
-
-}  // namespace gralloc
-
-#endif  // __GR_DEVICE_IMPL_H__
diff --git a/gralloc/gr_ion_alloc.cpp b/gralloc/gr_ion_alloc.cpp
deleted file mode 100644
index 33a13ab..0000000
--- a/gralloc/gr_ion_alloc.cpp
+++ /dev/null
@@ -1,213 +0,0 @@
-/*
- * Copyright (c) 2011-2018, The Linux Foundation. All rights reserved.
-
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *   * Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- *   * Redistributions in binary form must reproduce the above
- *     copyright notice, this list of conditions and the following
- *     disclaimer in the documentation and/or other materials provided
- *     with the distribution.
- *   * Neither the name of The Linux Foundation nor the names of its
- *     contributors may be used to endorse or promote products derived
- *     from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#define DEBUG 0
-#define ATRACE_TAG (ATRACE_TAG_GRAPHICS | ATRACE_TAG_HAL)
-#include <log/log.h>
-#include <cutils/trace.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <stdlib.h>
-#include <sys/ioctl.h>
-#include <sys/mman.h>
-#include <utils/Trace.h>
-#include <string>
-
-#include "gr_ion_alloc.h"
-#include "gr_utils.h"
-#include "gralloc_priv.h"
-
-namespace gralloc {
-
-bool IonAlloc::Init() {
-  if (ion_dev_fd_ == FD_INIT) {
-    ion_dev_fd_ = open(kIonDevice, O_RDONLY);
-  }
-
-  if (ion_dev_fd_ < 0) {
-    ALOGE("%s: Failed to open ion device - %s", __FUNCTION__, strerror(errno));
-    ion_dev_fd_ = FD_INIT;
-    return false;
-  }
-
-  return true;
-}
-
-void IonAlloc::CloseIonDevice() {
-  if (ion_dev_fd_ > FD_INIT) {
-    close(ion_dev_fd_);
-  }
-
-  ion_dev_fd_ = FD_INIT;
-}
-
-int IonAlloc::AllocBuffer(AllocData *data) {
-  ATRACE_CALL();
-  int err = 0;
-  struct ion_handle_data handle_data;
-  struct ion_fd_data fd_data;
-  struct ion_allocation_data ion_alloc_data;
-
-  ion_alloc_data.len = data->size;
-  ion_alloc_data.align = data->align;
-  ion_alloc_data.heap_id_mask = data->heap_id;
-  ion_alloc_data.flags = data->flags;
-  ion_alloc_data.flags |= data->uncached ? 0 : ION_FLAG_CACHED;
-  std::string tag_name{};
-  if (ATRACE_ENABLED()) {
-    tag_name = "ION_IOC_ALLOC size: " + std::to_string(data->size);
-  }
-
-  ATRACE_BEGIN(tag_name.c_str());
-  if (ioctl(ion_dev_fd_, INT(ION_IOC_ALLOC), &ion_alloc_data)) {
-    err = -errno;
-    ALOGE("ION_IOC_ALLOC failed with error - %s", strerror(errno));
-    return err;
-  }
-  ATRACE_END();
-
-  fd_data.handle = ion_alloc_data.handle;
-  handle_data.handle = ion_alloc_data.handle;
-  ATRACE_BEGIN("ION_IOC_MAP");
-  if (ioctl(ion_dev_fd_, INT(ION_IOC_MAP), &fd_data)) {
-    err = -errno;
-    ALOGE("%s: ION_IOC_MAP failed with error - %s", __FUNCTION__, strerror(errno));
-    ioctl(ion_dev_fd_, INT(ION_IOC_FREE), &handle_data);
-    return err;
-  }
-  ATRACE_END();
-
-  data->fd = fd_data.fd;
-  data->ion_handle = handle_data.handle;
-  ALOGD_IF(DEBUG, "ion: Allocated buffer size:%zu fd:%d handle:0x%x", ion_alloc_data.len, data->fd,
-           data->ion_handle);
-
-  return 0;
-}
-
-int IonAlloc::FreeBuffer(void *base, unsigned int size, unsigned int offset, int fd,
-                         int ion_handle) {
-  ATRACE_CALL();
-  int err = 0;
-  ALOGD_IF(DEBUG, "ion: Freeing buffer base:%p size:%u fd:%d handle:0x%x", base, size, fd,
-           ion_handle);
-
-  if (base) {
-    err = UnmapBuffer(base, size, offset);
-  }
-
-  if (ion_handle > 0) {
-    struct ion_handle_data handle_data;
-    handle_data.handle = ion_handle;
-    ioctl(ion_dev_fd_, INT(ION_IOC_FREE), &handle_data);
-  }
-  close(fd);
-  return err;
-}
-
-int IonAlloc::MapBuffer(void **base, unsigned int size, unsigned int offset, int fd) {
-  ATRACE_CALL();
-  int err = 0;
-  void *addr = 0;
-
-  // It is a (quirky) requirement of ION to have opened the
-  // ion fd in the process that is doing the mapping
-  addr = mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
-  *base = addr;
-  if (addr == MAP_FAILED) {
-    err = -errno;
-    ALOGE("ion: Failed to map memory in the client: %s", strerror(errno));
-  } else {
-    ALOGD_IF(DEBUG, "ion: Mapped buffer base:%p size:%u offset:%u fd:%d", addr, size, offset, fd);
-  }
-
-  return err;
-}
-
-int IonAlloc::ImportBuffer(int fd) {
-  struct ion_fd_data fd_data;
-  int err = 0;
-  fd_data.fd = fd;
-  if (ioctl(ion_dev_fd_, INT(ION_IOC_IMPORT), &fd_data)) {
-    err = -errno;
-    ALOGE("%s: ION_IOC_IMPORT failed with error - %s", __FUNCTION__, strerror(errno));
-    return err;
-  }
-  return fd_data.handle;
-}
-
-int IonAlloc::UnmapBuffer(void *base, unsigned int size, unsigned int /*offset*/) {
-  ATRACE_CALL();
-  ALOGD_IF(DEBUG, "ion: Unmapping buffer  base:%p size:%u", base, size);
-
-  int err = 0;
-  if (munmap(base, size)) {
-    err = -errno;
-    ALOGE("ion: Failed to unmap memory at %p : %s", base, strerror(errno));
-  }
-
-  return err;
-}
-
-int IonAlloc::CleanBuffer(void *base, unsigned int size, unsigned int offset, int handle, int op) {
-  ATRACE_CALL();
-  ATRACE_INT("operation id", op);
-  struct ion_flush_data flush_data;
-  int err = 0;
-
-  flush_data.handle = handle;
-  flush_data.vaddr = base;
-  // offset and length are unsigned int
-  flush_data.offset = offset;
-  flush_data.length = size;
-
-  struct ion_custom_data d;
-  switch (op) {
-    case CACHE_CLEAN:
-      d.cmd = ION_IOC_CLEAN_CACHES;
-      break;
-    case CACHE_INVALIDATE:
-      d.cmd = ION_IOC_INV_CACHES;
-      break;
-    case CACHE_CLEAN_AND_INVALIDATE:
-    default:
-      d.cmd = ION_IOC_CLEAN_INV_CACHES;
-  }
-
-  d.arg = (unsigned long)(&flush_data);  // NOLINT
-  if (ioctl(ion_dev_fd_, INT(ION_IOC_CUSTOM), &d)) {
-    err = -errno;
-    ALOGE("%s: ION_IOC_CLEAN_INV_CACHES failed with error - %s", __FUNCTION__, strerror(errno));
-    return err;
-  }
-
-  return 0;
-}
-
-}  // namespace gralloc
diff --git a/gralloc/gr_ion_alloc.h b/gralloc/gr_ion_alloc.h
deleted file mode 100644
index 6a1fd7f..0000000
--- a/gralloc/gr_ion_alloc.h
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * Copyright (c) 2011-2018, The Linux Foundation. All rights reserved.
-
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *   * Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- *   * Redistributions in binary form must reproduce the above
- *     copyright notice, this list of conditions and the following
- *     disclaimer in the documentation and/or other materials provided
- *     with the distribution.
- *   * Neither the name of The Linux Foundation nor the names of its
- *     contributors may be used to endorse or promote products derived
- *     from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef __GR_ION_ALLOC_H__
-#define __GR_ION_ALLOC_H__
-
-#include <linux/msm_ion.h>
-
-#define FD_INIT -1
-
-namespace gralloc {
-
-enum {
-  CACHE_CLEAN = 0x1,
-  CACHE_INVALIDATE,
-  CACHE_CLEAN_AND_INVALIDATE,
-};
-
-struct AllocData {
-  void *base = NULL;
-  int fd = -1;
-  int ion_handle = -1;
-  unsigned int offset = 0;
-  unsigned int size = 0;
-  unsigned int align = 1;
-  uintptr_t handle = 0;
-  bool uncached = false;
-  unsigned int flags = 0x0;
-  unsigned int heap_id = 0x0;
-  unsigned int alloc_type = 0x0;
-};
-
-class IonAlloc {
- public:
-  IonAlloc() { ion_dev_fd_ = FD_INIT; }
-
-  ~IonAlloc() { CloseIonDevice(); }
-
-  bool Init();
-  int AllocBuffer(AllocData *data);
-  int FreeBuffer(void *base, unsigned int size, unsigned int offset, int fd, int ion_handle);
-  int MapBuffer(void **base, unsigned int size, unsigned int offset, int fd);
-  int ImportBuffer(int fd);
-  int UnmapBuffer(void *base, unsigned int size, unsigned int offset);
-  int CleanBuffer(void *base, unsigned int size, unsigned int offset, int handle, int op);
-
- private:
-  const char *kIonDevice = "/dev/ion";
-
-  int OpenIonDevice();
-  void CloseIonDevice();
-
-  int ion_dev_fd_;
-};
-
-}  // namespace gralloc
-
-#endif  // __GR_ION_ALLOC_H__
diff --git a/gralloc/gr_utils.cpp b/gralloc/gr_utils.cpp
deleted file mode 100644
index 68bdb4c..0000000
--- a/gralloc/gr_utils.cpp
+++ /dev/null
@@ -1,933 +0,0 @@
-/*
- * Copyright (c) 2011-2018, The Linux Foundation. All rights reserved.
-
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *   * Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- *   * Redistributions in binary form must reproduce the above
- *     copyright notice, this list of conditions and the following
- *     disclaimer in the documentation and/or other materials provided
- *     with the distribution.
- *   * Neither the name of The Linux Foundation nor the names of its
- *     contributors may be used to endorse or promote products derived
- *     from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <media/msm_media_info.h>
-#include <algorithm>
-
-#include "gr_adreno_info.h"
-#include "gr_utils.h"
-#include "qdMetaData.h"
-
-#define ASTC_BLOCK_SIZE 16
-
-#ifndef COLOR_FMT_P010_UBWC
-#define COLOR_FMT_P010_UBWC 9
-#endif
-
-namespace gralloc {
-
-bool IsYuvFormat(const private_handle_t *hnd) {
-  switch (hnd->format) {
-    case HAL_PIXEL_FORMAT_YCbCr_420_SP:
-    case HAL_PIXEL_FORMAT_YCbCr_422_SP:
-    case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
-    case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:  // Same as YCbCr_420_SP_VENUS
-    case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
-    case HAL_PIXEL_FORMAT_YCrCb_420_SP:
-    case HAL_PIXEL_FORMAT_YCrCb_422_SP:
-    case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO:
-    case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS:
-    case HAL_PIXEL_FORMAT_NV21_ZSL:
-    case HAL_PIXEL_FORMAT_RAW16:
-    case HAL_PIXEL_FORMAT_Y16:
-    case HAL_PIXEL_FORMAT_RAW12:
-    case HAL_PIXEL_FORMAT_RAW10:
-    case HAL_PIXEL_FORMAT_YV12:
-    case HAL_PIXEL_FORMAT_Y8:
-    case HAL_PIXEL_FORMAT_YCbCr_420_P010:
-    case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
-    case HAL_PIXEL_FORMAT_YCbCr_420_P010_UBWC:
-    case HAL_PIXEL_FORMAT_YCbCr_420_P010_VENUS:
-      return true;
-    default:
-      return false;
-  }
-}
-
-bool IsUncompressedRGBFormat(int format) {
-  switch (format) {
-    case HAL_PIXEL_FORMAT_RGBA_8888:
-    case HAL_PIXEL_FORMAT_RGBX_8888:
-    case HAL_PIXEL_FORMAT_RGB_888:
-    case HAL_PIXEL_FORMAT_RGB_565:
-    case HAL_PIXEL_FORMAT_BGR_565:
-    case HAL_PIXEL_FORMAT_BGRA_8888:
-    case HAL_PIXEL_FORMAT_RGBA_5551:
-    case HAL_PIXEL_FORMAT_RGBA_4444:
-    case HAL_PIXEL_FORMAT_R_8:
-    case HAL_PIXEL_FORMAT_RG_88:
-    case HAL_PIXEL_FORMAT_BGRX_8888:
-    case HAL_PIXEL_FORMAT_RGBA_1010102:
-    case HAL_PIXEL_FORMAT_ARGB_2101010:
-    case HAL_PIXEL_FORMAT_RGBX_1010102:
-    case HAL_PIXEL_FORMAT_XRGB_2101010:
-    case HAL_PIXEL_FORMAT_BGRA_1010102:
-    case HAL_PIXEL_FORMAT_ABGR_2101010:
-    case HAL_PIXEL_FORMAT_BGRX_1010102:
-    case HAL_PIXEL_FORMAT_XBGR_2101010:
-    case HAL_PIXEL_FORMAT_RGBA_FP16:
-    case HAL_PIXEL_FORMAT_BGR_888:
-      return true;
-    default:
-      break;
-  }
-
-  return false;
-}
-
-bool IsCompressedRGBFormat(int format) {
-  switch (format) {
-    case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_4x4_KHR:
-    case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR:
-    case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_5x4_KHR:
-    case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR:
-    case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_5x5_KHR:
-    case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR:
-    case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_6x5_KHR:
-    case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR:
-    case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_6x6_KHR:
-    case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR:
-    case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x5_KHR:
-    case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR:
-    case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x6_KHR:
-    case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR:
-    case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x8_KHR:
-    case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR:
-    case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x5_KHR:
-    case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR:
-    case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x6_KHR:
-    case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR:
-    case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x8_KHR:
-    case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR:
-    case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x10_KHR:
-    case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR:
-    case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_12x10_KHR:
-    case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR:
-    case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_12x12_KHR:
-    case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR:
-      return true;
-    default:
-      break;
-  }
-
-  return false;
-}
-
-uint32_t GetBppForUncompressedRGB(int format) {
-  uint32_t bpp = 0;
-  switch (format) {
-    case HAL_PIXEL_FORMAT_RGBA_FP16:
-      bpp = 8;
-      break;
-    case HAL_PIXEL_FORMAT_RGBA_8888:
-    case HAL_PIXEL_FORMAT_RGBX_8888:
-    case HAL_PIXEL_FORMAT_BGRA_8888:
-    case HAL_PIXEL_FORMAT_BGRX_8888:
-    case HAL_PIXEL_FORMAT_RGBA_1010102:
-    case HAL_PIXEL_FORMAT_ARGB_2101010:
-    case HAL_PIXEL_FORMAT_RGBX_1010102:
-    case HAL_PIXEL_FORMAT_XRGB_2101010:
-    case HAL_PIXEL_FORMAT_BGRA_1010102:
-    case HAL_PIXEL_FORMAT_ABGR_2101010:
-    case HAL_PIXEL_FORMAT_BGRX_1010102:
-    case HAL_PIXEL_FORMAT_XBGR_2101010:
-      bpp = 4;
-      break;
-    case HAL_PIXEL_FORMAT_RGB_888:
-    case HAL_PIXEL_FORMAT_BGR_888:
-      bpp = 3;
-      break;
-    case HAL_PIXEL_FORMAT_RGB_565:
-    case HAL_PIXEL_FORMAT_BGR_565:
-    case HAL_PIXEL_FORMAT_RGBA_5551:
-    case HAL_PIXEL_FORMAT_RGBA_4444:
-      bpp = 2;
-      break;
-    default:
-      ALOGE("Error : %s New format request = 0x%x", __FUNCTION__, format);
-      break;
-  }
-
-  return bpp;
-}
-
-bool CpuCanAccess(uint64_t usage) {
-  return CpuCanRead(usage) || CpuCanWrite(usage);
-}
-
-bool CpuCanRead(uint64_t usage) {
-  if (usage & BufferUsage::CPU_READ_MASK) {
-    return true;
-  }
-
-  return false;
-}
-
-bool CpuCanWrite(uint64_t usage) {
-  if (usage & BufferUsage::CPU_WRITE_MASK) {
-    // Application intends to use CPU for rendering
-    return true;
-  }
-
-  return false;
-}
-
-unsigned int GetSize(const BufferInfo &info, unsigned int alignedw, unsigned int alignedh) {
-  unsigned int size = 0;
-  int format = info.format;
-  int width = info.width;
-  int height = info.height;
-  uint64_t usage = info.usage;
-
-  if (IsUBwcEnabled(format, usage)) {
-    return GetUBwcSize(width, height, format, alignedw, alignedh);
-  }
-
-  if (IsUncompressedRGBFormat(format)) {
-    uint32_t bpp = GetBppForUncompressedRGB(format);
-    size = alignedw * alignedh * bpp;
-    return size;
-  }
-
-  if (IsCompressedRGBFormat(format)) {
-    size = alignedw * alignedh * ASTC_BLOCK_SIZE;
-    return size;
-  }
-
-  // Below switch should be for only YUV/custom formats
-  switch (format) {
-    case HAL_PIXEL_FORMAT_RAW16:
-    case HAL_PIXEL_FORMAT_Y16:
-      size = alignedw * alignedh * 2;
-      break;
-    case HAL_PIXEL_FORMAT_RAW10:
-    case HAL_PIXEL_FORMAT_RAW12:
-      size = ALIGN(alignedw * alignedh, SIZE_4K);
-      break;
-    case HAL_PIXEL_FORMAT_RAW8:
-    case HAL_PIXEL_FORMAT_Y8:
-      size = alignedw * alignedh * 1;
-      break;
-
-      // adreno formats
-    case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO:  // NV21
-      size = ALIGN(alignedw * alignedh, SIZE_4K);
-      size += (unsigned int)ALIGN(2 * ALIGN(width / 2, 32) * ALIGN(height / 2, 32), SIZE_4K);
-      break;
-    case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED:  // NV12
-      // The chroma plane is subsampled,
-      // but the pitch in bytes is unchanged
-      // The GPU needs 4K alignment, but the video decoder needs 8K
-      size = ALIGN(alignedw * alignedh, SIZE_8K);
-      size += ALIGN(alignedw * (unsigned int)ALIGN(height / 2, 32), SIZE_8K);
-      break;
-    case HAL_PIXEL_FORMAT_YV12:
-      if ((format == HAL_PIXEL_FORMAT_YV12) && ((width & 1) || (height & 1))) {
-        ALOGE("w or h is odd for the YV12 format");
-        return 0;
-      }
-      size = alignedw * alignedh + (ALIGN(alignedw / 2, 16) * (alignedh / 2)) * 2;
-      size = ALIGN(size, (unsigned int)SIZE_4K);
-      break;
-    case HAL_PIXEL_FORMAT_YCbCr_420_SP:
-    case HAL_PIXEL_FORMAT_YCrCb_420_SP:
-      size = ALIGN((alignedw * alignedh) + (alignedw * alignedh) / 2 + 1, SIZE_4K);
-      break;
-    case HAL_PIXEL_FORMAT_YCbCr_420_P010:
-      size = ALIGN((alignedw * alignedh * 2) + (alignedw * alignedh) + 1, SIZE_4K);
-      break;
-    case HAL_PIXEL_FORMAT_YCbCr_420_P010_VENUS:
-      size = VENUS_BUFFER_SIZE(COLOR_FMT_P010, width, height);
-      break;
-    case HAL_PIXEL_FORMAT_YCbCr_422_SP:
-    case HAL_PIXEL_FORMAT_YCrCb_422_SP:
-    case HAL_PIXEL_FORMAT_YCbCr_422_I:
-    case HAL_PIXEL_FORMAT_YCrCb_422_I:
-    case HAL_PIXEL_FORMAT_CbYCrY_422_I:
-      if (width & 1) {
-        ALOGE("width is odd for the YUV422_SP format");
-        return 0;
-      }
-      size = ALIGN(alignedw * alignedh * 2, SIZE_4K);
-      break;
-    case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
-    case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
-      size = VENUS_BUFFER_SIZE(COLOR_FMT_NV12, width, height);
-      break;
-    case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS:
-      size = VENUS_BUFFER_SIZE(COLOR_FMT_NV21, width, height);
-      break;
-    case HAL_PIXEL_FORMAT_BLOB:
-    case HAL_PIXEL_FORMAT_RAW_OPAQUE:
-      if (height != 1) {
-        ALOGE("%s: Buffers with HAL_PIXEL_FORMAT_BLOB must have height 1 ", __FUNCTION__);
-        return 0;
-      }
-      size = (unsigned int)width;
-      break;
-    case HAL_PIXEL_FORMAT_NV21_ZSL:
-      size = ALIGN((alignedw * alignedh) + (alignedw * alignedh) / 2, SIZE_4K);
-      break;
-    default:
-      ALOGE("%s: Unrecognized pixel format: 0x%x", __FUNCTION__, format);
-      return 0;
-  }
-
-  return size;
-}
-
-void GetBufferSizeAndDimensions(const BufferInfo &info, unsigned int *size, unsigned int *alignedw,
-                                unsigned int *alignedh) {
-  GetAlignedWidthAndHeight(info, alignedw, alignedh);
-  *size = GetSize(info, *alignedw, *alignedh);
-}
-
-void GetYuvUbwcSPPlaneInfo(uint64_t base, uint32_t width, uint32_t height, int color_format,
-                           struct android_ycbcr *ycbcr) {
-  // UBWC buffer has these 4 planes in the following sequence:
-  // Y_Meta_Plane, Y_Plane, UV_Meta_Plane, UV_Plane
-  unsigned int y_meta_stride, y_meta_height, y_meta_size;
-  unsigned int y_stride, y_height, y_size;
-  unsigned int c_meta_stride, c_meta_height, c_meta_size;
-  unsigned int alignment = 4096;
-
-  y_meta_stride = VENUS_Y_META_STRIDE(color_format, INT(width));
-  y_meta_height = VENUS_Y_META_SCANLINES(color_format, INT(height));
-  y_meta_size = ALIGN((y_meta_stride * y_meta_height), alignment);
-
-  y_stride = VENUS_Y_STRIDE(color_format, INT(width));
-  y_height = VENUS_Y_SCANLINES(color_format, INT(height));
-  y_size = ALIGN((y_stride * y_height), alignment);
-
-  c_meta_stride = VENUS_UV_META_STRIDE(color_format, INT(width));
-  c_meta_height = VENUS_UV_META_SCANLINES(color_format, INT(height));
-  c_meta_size = ALIGN((c_meta_stride * c_meta_height), alignment);
-
-  ycbcr->y = reinterpret_cast<void *>(base + y_meta_size);
-  ycbcr->cb = reinterpret_cast<void *>(base + y_meta_size + y_size + c_meta_size);
-  ycbcr->cr = reinterpret_cast<void *>(base + y_meta_size + y_size + c_meta_size + 1);
-  ycbcr->ystride = y_stride;
-  ycbcr->cstride = VENUS_UV_STRIDE(color_format, INT(width));
-}
-
-void GetYuvUbwcInterlacedSPPlaneInfo(uint64_t base, uint32_t width, uint32_t height,
-                                     int color_format, struct android_ycbcr ycbcr[2]) {
-  unsigned int uv_stride, uv_height, uv_size;
-  unsigned int alignment = 4096;
-  uint64_t field_base;
-
-  // UBWC interlaced has top-bottom field layout with each field as
-  // 4-plane NV12_UBWC with width = image_width & height = image_height / 2.
-  // Client passed ycbcr argument is ptr to struct android_ycbcr[2].
-  // Plane info to be filled for each field separately.
-  height = (height + 1) >> 1;
-  uv_stride = VENUS_UV_STRIDE(color_format, INT(width));
-  uv_height = VENUS_UV_SCANLINES(color_format, INT(height));
-  uv_size = ALIGN((uv_stride * uv_height), alignment);
-
-  field_base = base;
-  GetYuvUbwcSPPlaneInfo(field_base, width, height, COLOR_FMT_NV12_UBWC, &ycbcr[0]);
-
-  memset(ycbcr[1].reserved, 0, sizeof(ycbcr[1].reserved));
-  field_base = reinterpret_cast<uint64_t>(ycbcr[0].cb) + uv_size;
-  GetYuvUbwcSPPlaneInfo(field_base, width, height, COLOR_FMT_NV12_UBWC, &ycbcr[1]);
-}
-
-void GetYuvSPPlaneInfo(uint64_t base, uint32_t width, uint32_t height, uint32_t bpp,
-                       struct android_ycbcr *ycbcr) {
-  unsigned int ystride, cstride;
-
-  ystride = cstride = UINT(width) * bpp;
-  ycbcr->y = reinterpret_cast<void *>(base);
-  ycbcr->cb = reinterpret_cast<void *>(base + ystride * UINT(height));
-  ycbcr->cr = reinterpret_cast<void *>(base + ystride * UINT(height) + 1);
-  ycbcr->ystride = ystride;
-  ycbcr->cstride = cstride;
-  ycbcr->chroma_step = 2 * bpp;
-}
-
-int GetYUVPlaneInfo(const private_handle_t *hnd, struct android_ycbcr ycbcr[2]) {
-  int err = 0;
-  uint32_t width = UINT(hnd->width);
-  uint32_t height = UINT(hnd->height);
-  int format = hnd->format;
-  uint64_t usage = hnd->usage;
-  unsigned int ystride, cstride;
-  bool interlaced = false;
-
-  memset(ycbcr->reserved, 0, sizeof(ycbcr->reserved));
-
-  // Check if UBWC buffer has been rendered in linear format.
-  int linear_format = 0;
-  if (getMetaData(const_cast<private_handle_t *>(hnd), GET_LINEAR_FORMAT, &linear_format) == 0) {
-    format = INT(linear_format);
-  }
-
-  // Check metadata if the geometry has been updated.
-  BufferDim_t buffer_dim;
-  if (getMetaData(const_cast<private_handle_t *>(hnd), GET_BUFFER_GEOMETRY, &buffer_dim) == 0) {
-    BufferInfo info(buffer_dim.sliceWidth, buffer_dim.sliceHeight, format, usage);
-    GetAlignedWidthAndHeight(info, &width, &height);
-  }
-
-  // Check metadata for interlaced content.
-  int interlace_flag = 0;
-  if (getMetaData(const_cast<private_handle_t *>(hnd), GET_PP_PARAM_INTERLACED, &interlace_flag) ==
-      0) {
-    interlaced = interlace_flag;
-  }
-
-  // Get the chroma offsets from the handle width/height. We take advantage
-  // of the fact the width _is_ the stride
-  switch (format) {
-    // Semiplanar
-    case HAL_PIXEL_FORMAT_YCbCr_420_SP:
-    case HAL_PIXEL_FORMAT_YCbCr_422_SP:
-    case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
-    case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
-      // Same as YCbCr_420_SP_VENUS
-      GetYuvSPPlaneInfo(hnd->base, width, height, 1, ycbcr);
-      break;
-
-    case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
-      if (!interlaced) {
-        GetYuvUbwcSPPlaneInfo(hnd->base, width, height, COLOR_FMT_NV12_UBWC, ycbcr);
-      } else {
-        GetYuvUbwcInterlacedSPPlaneInfo(hnd->base, width, height, COLOR_FMT_NV12_UBWC, ycbcr);
-      }
-      ycbcr->chroma_step = 2;
-      break;
-
-    case HAL_PIXEL_FORMAT_YCbCr_420_P010:
-      GetYuvSPPlaneInfo(hnd->base, width, height, 2, ycbcr);
-      break;
-
-    case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
-      GetYuvUbwcSPPlaneInfo(hnd->base, width, height, COLOR_FMT_NV12_BPP10_UBWC, ycbcr);
-      ycbcr->chroma_step = 3;
-      break;
-
-    case HAL_PIXEL_FORMAT_YCbCr_420_P010_UBWC:
-      GetYuvUbwcSPPlaneInfo(hnd->base, width, height, COLOR_FMT_P010_UBWC, ycbcr);
-      ycbcr->chroma_step = 4;
-      break;
-
-    case HAL_PIXEL_FORMAT_YCbCr_420_P010_VENUS:
-      ystride = VENUS_Y_STRIDE(COLOR_FMT_P010, width);
-      cstride = VENUS_UV_STRIDE(COLOR_FMT_P010, width);
-      ycbcr->y = reinterpret_cast<void *>(hnd->base);
-      ycbcr->cb =
-          reinterpret_cast<void *>(hnd->base + ystride * VENUS_Y_SCANLINES(COLOR_FMT_P010, height));
-      ycbcr->cr = reinterpret_cast<void *>(hnd->base +
-                                           ystride * VENUS_Y_SCANLINES(COLOR_FMT_P010, height) + 1);
-      ycbcr->ystride = ystride;
-      ycbcr->cstride = cstride;
-      ycbcr->chroma_step = 4;
-      break;
-
-    case HAL_PIXEL_FORMAT_YCrCb_420_SP:
-    case HAL_PIXEL_FORMAT_YCrCb_422_SP:
-    case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO:
-    case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS:
-    case HAL_PIXEL_FORMAT_NV21_ZSL:
-    case HAL_PIXEL_FORMAT_RAW16:
-    case HAL_PIXEL_FORMAT_Y16:
-    case HAL_PIXEL_FORMAT_RAW10:
-    case HAL_PIXEL_FORMAT_RAW8:
-    case HAL_PIXEL_FORMAT_Y8:
-      GetYuvSPPlaneInfo(hnd->base, width, height, 1, ycbcr);
-      std::swap(ycbcr->cb, ycbcr->cr);
-      break;
-
-      // Planar
-    case HAL_PIXEL_FORMAT_YV12:
-      ystride = width;
-      cstride = ALIGN(width / 2, 16);
-      ycbcr->y = reinterpret_cast<void *>(hnd->base);
-      ycbcr->cr = reinterpret_cast<void *>(hnd->base + ystride * height);
-      ycbcr->cb = reinterpret_cast<void *>(hnd->base + ystride * height + cstride * height / 2);
-      ycbcr->ystride = ystride;
-      ycbcr->cstride = cstride;
-      ycbcr->chroma_step = 1;
-      break;
-    case HAL_PIXEL_FORMAT_CbYCrY_422_I:
-      ystride = width * 2;
-      cstride = 0;
-      ycbcr->y = reinterpret_cast<void *>(hnd->base);
-      ycbcr->cr = NULL;
-      ycbcr->cb = NULL;
-      ycbcr->ystride = ystride;
-      ycbcr->cstride = 0;
-      ycbcr->chroma_step = 0;
-      break;
-      // Unsupported formats
-    case HAL_PIXEL_FORMAT_YCbCr_422_I:
-    case HAL_PIXEL_FORMAT_YCrCb_422_I:
-    case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED:
-    default:
-      ALOGD("%s: Invalid format passed: 0x%x", __FUNCTION__, format);
-      err = -EINVAL;
-  }
-
-  return err;
-}
-
-// Explicitly defined UBWC formats
-bool IsUBwcFormat(int format) {
-  switch (format) {
-    case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
-    case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
-    case HAL_PIXEL_FORMAT_YCbCr_420_P010_UBWC:
-      return true;
-    default:
-      return false;
-  }
-}
-
-bool IsUBwcSupported(int format) {
-  // Existing HAL formats with UBWC support
-  switch (format) {
-    case HAL_PIXEL_FORMAT_BGR_565:
-    case HAL_PIXEL_FORMAT_RGBA_8888:
-    case HAL_PIXEL_FORMAT_RGBX_8888:
-    case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
-    case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
-    case HAL_PIXEL_FORMAT_RGBA_1010102:
-    case HAL_PIXEL_FORMAT_RGBX_1010102:
-      return true;
-    default:
-      break;
-  }
-
-  return false;
-}
-
-bool IsUBwcEnabled(int format, uint64_t usage) {
-  // Allow UBWC, if client is using an explicitly defined UBWC pixel format.
-  if (IsUBwcFormat(format)) {
-    return true;
-  }
-
-  // Allow UBWC, if an OpenGL client sets UBWC usage flag and GPU plus MDP
-  // support the format. OR if a non-OpenGL client like Rotator, sets UBWC
-  // usage flag and MDP supports the format.
-  if ((usage & GRALLOC_USAGE_PRIVATE_ALLOC_UBWC) && IsUBwcSupported(format)) {
-    bool enable = true;
-    // Query GPU for UBWC only if buffer is intended to be used by GPU.
-    if ((usage & BufferUsage::GPU_TEXTURE) || (usage & BufferUsage::GPU_RENDER_TARGET)) {
-      if (AdrenoMemInfo::GetInstance()) {
-        enable = AdrenoMemInfo::GetInstance()->IsUBWCSupportedByGPU(format);
-      }
-    }
-
-    // Allow UBWC, only if CPU usage flags are not set
-    if (enable && !(CpuCanAccess(usage))) {
-      return true;
-    }
-  }
-
-  return false;
-}
-
-void GetYuvUBwcWidthAndHeight(int width, int height, int format, unsigned int *aligned_w,
-                              unsigned int *aligned_h) {
-  switch (format) {
-    case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
-    case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
-    case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
-      *aligned_w = VENUS_Y_STRIDE(COLOR_FMT_NV12_UBWC, width);
-      *aligned_h = VENUS_Y_SCANLINES(COLOR_FMT_NV12_UBWC, height);
-      break;
-    case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
-      // The macro returns the stride which is 4/3 times the width, hence * 3/4
-      *aligned_w = (VENUS_Y_STRIDE(COLOR_FMT_NV12_BPP10_UBWC, width) * 3) / 4;
-      *aligned_h = VENUS_Y_SCANLINES(COLOR_FMT_NV12_BPP10_UBWC, height);
-      break;
-    case HAL_PIXEL_FORMAT_YCbCr_420_P010_UBWC:
-      // The macro returns the stride which is 2 times the width, hence / 2
-      *aligned_w = (VENUS_Y_STRIDE(COLOR_FMT_P010_UBWC, width) / 2);
-      *aligned_h = VENUS_Y_SCANLINES(COLOR_FMT_P010_UBWC, height);
-      break;
-    default:
-      ALOGE("%s: Unsupported pixel format: 0x%x", __FUNCTION__, format);
-      *aligned_w = 0;
-      *aligned_h = 0;
-      break;
-  }
-}
-
-void GetRgbUBwcBlockSize(uint32_t bpp, int *block_width, int *block_height) {
-  *block_width = 0;
-  *block_height = 0;
-
-  switch (bpp) {
-    case 2:
-    case 4:
-      *block_width = 16;
-      *block_height = 4;
-      break;
-    case 8:
-      *block_width = 8;
-      *block_height = 4;
-      break;
-    case 16:
-      *block_width = 4;
-      *block_height = 4;
-      break;
-    default:
-      ALOGE("%s: Unsupported bpp: %d", __FUNCTION__, bpp);
-      break;
-  }
-}
-
-unsigned int GetRgbUBwcMetaBufferSize(int width, int height, uint32_t bpp) {
-  unsigned int size = 0;
-  int meta_width, meta_height;
-  int block_width, block_height;
-
-  GetRgbUBwcBlockSize(bpp, &block_width, &block_height);
-  if (!block_width || !block_height) {
-    ALOGE("%s: Unsupported bpp: %d", __FUNCTION__, bpp);
-    return size;
-  }
-
-  // Align meta buffer height to 16 blocks
-  meta_height = ALIGN(((height + block_height - 1) / block_height), 16);
-
-  // Align meta buffer width to 64 blocks
-  meta_width = ALIGN(((width + block_width - 1) / block_width), 64);
-
-  // Align meta buffer size to 4K
-  size = (unsigned int)ALIGN((meta_width * meta_height), 4096);
-
-  return size;
-}
-
-unsigned int GetUBwcSize(int width, int height, int format, unsigned int alignedw,
-                         unsigned int alignedh) {
-  unsigned int size = 0;
-  uint32_t bpp = 0;
-  switch (format) {
-    case HAL_PIXEL_FORMAT_BGR_565:
-    case HAL_PIXEL_FORMAT_RGBA_8888:
-    case HAL_PIXEL_FORMAT_RGBX_8888:
-    case HAL_PIXEL_FORMAT_RGBA_1010102:
-    case HAL_PIXEL_FORMAT_RGBX_1010102:
-      bpp = GetBppForUncompressedRGB(format);
-      size = alignedw * alignedh * bpp;
-      size += GetRgbUBwcMetaBufferSize(width, height, bpp);
-      break;
-    case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
-    case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
-    case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
-      size = VENUS_BUFFER_SIZE(COLOR_FMT_NV12_UBWC, width, height);
-      break;
-    case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
-      size = VENUS_BUFFER_SIZE(COLOR_FMT_NV12_BPP10_UBWC, width, height);
-      break;
-    case HAL_PIXEL_FORMAT_YCbCr_420_P010_UBWC:
-      size = VENUS_BUFFER_SIZE(COLOR_FMT_P010_UBWC, width, height);
-      break;
-    default:
-      ALOGE("%s: Unsupported pixel format: 0x%x", __FUNCTION__, format);
-      break;
-  }
-
-  return size;
-}
-
-int GetRgbDataAddress(private_handle_t *hnd, void **rgb_data) {
-  int err = 0;
-
-  // This api is for RGB* formats
-  if (!IsUncompressedRGBFormat(hnd->format)) {
-    return -EINVAL;
-  }
-
-  // linear buffer, nothing to do further
-  if (!(hnd->flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED)) {
-    *rgb_data = reinterpret_cast<void *>(hnd->base);
-    return err;
-  }
-
-  unsigned int meta_size = 0;
-  uint32_t bpp = GetBppForUncompressedRGB(hnd->format);
-  switch (hnd->format) {
-    case HAL_PIXEL_FORMAT_BGR_565:
-    case HAL_PIXEL_FORMAT_RGBA_8888:
-    case HAL_PIXEL_FORMAT_RGBX_8888:
-    case HAL_PIXEL_FORMAT_RGBA_1010102:
-    case HAL_PIXEL_FORMAT_RGBX_1010102:
-      meta_size = GetRgbUBwcMetaBufferSize(hnd->width, hnd->height, bpp);
-      break;
-    default:
-      ALOGE("%s:Unsupported RGB format: 0x%x", __FUNCTION__, hnd->format);
-      err = -EINVAL;
-      break;
-  }
-  *rgb_data = reinterpret_cast<void *>(hnd->base + meta_size);
-
-  return err;
-}
-
-void GetCustomDimensions(private_handle_t *hnd, int *stride, int *height) {
-  BufferDim_t buffer_dim;
-  int interlaced = 0;
-
-  *stride = hnd->width;
-  *height = hnd->height;
-  if (getMetaData(hnd, GET_BUFFER_GEOMETRY, &buffer_dim) == 0) {
-    *stride = buffer_dim.sliceWidth;
-    *height = buffer_dim.sliceHeight;
-  } else if (getMetaData(hnd, GET_PP_PARAM_INTERLACED, &interlaced) == 0) {
-    if (interlaced && IsUBwcFormat(hnd->format)) {
-      unsigned int alignedw = 0, alignedh = 0;
-      // Get re-aligned height for single ubwc interlaced field and
-      // multiply by 2 to get frame height.
-      BufferInfo info(hnd->width, ((hnd->height + 1) >> 1), hnd->format);
-      GetAlignedWidthAndHeight(info, &alignedw, &alignedh);
-      *stride = static_cast<int>(alignedw);
-      *height = static_cast<int>(alignedh * 2);
-    }
-  }
-}
-
-void GetColorSpaceFromMetadata(private_handle_t *hnd, int *color_space) {
-  ColorMetaData color_metadata;
-  if (getMetaData(hnd, GET_COLOR_METADATA, &color_metadata) == 0) {
-    switch (color_metadata.colorPrimaries) {
-      case ColorPrimaries_BT709_5:
-        *color_space = HAL_CSC_ITU_R_709;
-        break;
-      case ColorPrimaries_BT601_6_525:
-      case ColorPrimaries_BT601_6_625:
-        *color_space = ((color_metadata.range) ? HAL_CSC_ITU_R_601_FR : HAL_CSC_ITU_R_601);
-        break;
-      case ColorPrimaries_BT2020:
-        *color_space = (color_metadata.range) ? HAL_CSC_ITU_R_2020_FR : HAL_CSC_ITU_R_2020;
-        break;
-      default:
-        ALOGE("Unknown Color Space = %d", color_metadata.colorPrimaries);
-        break;
-    }
-  } else if (getMetaData(hnd, GET_COLOR_SPACE, color_space) != 0) {
-    *color_space = 0;
-  }
-}
-
-void GetAlignedWidthAndHeight(const BufferInfo &info, unsigned int *alignedw,
-                              unsigned int *alignedh) {
-  int width = info.width;
-  int height = info.height;
-  int format = info.format;
-  uint64_t usage = info.usage;
-
-  // Currently surface padding is only computed for RGB* surfaces.
-  bool ubwc_enabled = IsUBwcEnabled(format, usage);
-  int tile = ubwc_enabled;
-
-  if (IsUncompressedRGBFormat(format)) {
-    if (AdrenoMemInfo::GetInstance()) {
-      AdrenoMemInfo::GetInstance()->AlignUnCompressedRGB(width, height, format, tile, alignedw,
-                                                         alignedh);
-    }
-    return;
-  }
-
-  if (ubwc_enabled) {
-    GetYuvUBwcWidthAndHeight(width, height, format, alignedw, alignedh);
-    return;
-  }
-
-  if (IsCompressedRGBFormat(format)) {
-    if (AdrenoMemInfo::GetInstance()) {
-      AdrenoMemInfo::GetInstance()->AlignCompressedRGB(width, height, format, alignedw, alignedh);
-    }
-    return;
-  }
-
-  int aligned_w = width;
-  int aligned_h = height;
-  unsigned int alignment = 32;
-
-  // Below should be only YUV family
-  switch (format) {
-    case HAL_PIXEL_FORMAT_YCrCb_420_SP:
-    case HAL_PIXEL_FORMAT_YCbCr_420_SP:
-      if (AdrenoMemInfo::GetInstance() == nullptr) {
-        return;
-      }
-      alignment = AdrenoMemInfo::GetInstance()->GetGpuPixelAlignment();
-      aligned_w = ALIGN(width, alignment);
-      break;
-    case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO:
-      aligned_w = ALIGN(width, alignment);
-      break;
-    case HAL_PIXEL_FORMAT_RAW16:
-    case HAL_PIXEL_FORMAT_Y16:
-    case HAL_PIXEL_FORMAT_Y8:
-      aligned_w = ALIGN(width, 16);
-      break;
-    case HAL_PIXEL_FORMAT_RAW12:
-      aligned_w = ALIGN(width * 12 / 8, 16);
-      break;
-    case HAL_PIXEL_FORMAT_RAW10:
-      aligned_w = ALIGN(width * 10 / 8, 16);
-      break;
-    case HAL_PIXEL_FORMAT_RAW8:
-      aligned_w = ALIGN(width, 16);
-      break;
-    case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED:
-      aligned_w = ALIGN(width, 128);
-      break;
-    case HAL_PIXEL_FORMAT_YV12:
-    case HAL_PIXEL_FORMAT_YCbCr_422_SP:
-    case HAL_PIXEL_FORMAT_YCrCb_422_SP:
-    case HAL_PIXEL_FORMAT_YCbCr_422_I:
-    case HAL_PIXEL_FORMAT_YCrCb_422_I:
-    case HAL_PIXEL_FORMAT_YCbCr_420_P010:
-      aligned_w = ALIGN(width, 16);
-      break;
-    case HAL_PIXEL_FORMAT_YCbCr_420_P010_VENUS:
-      aligned_w = INT(VENUS_Y_STRIDE(COLOR_FMT_P010, width) / 2);
-      aligned_h = INT(VENUS_Y_SCANLINES(COLOR_FMT_P010, height));
-      break;
-    case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
-    case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
-      aligned_w = INT(VENUS_Y_STRIDE(COLOR_FMT_NV12, width));
-      aligned_h = INT(VENUS_Y_SCANLINES(COLOR_FMT_NV12, height));
-      break;
-    case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS:
-      aligned_w = INT(VENUS_Y_STRIDE(COLOR_FMT_NV21, width));
-      aligned_h = INT(VENUS_Y_SCANLINES(COLOR_FMT_NV21, height));
-      break;
-    case HAL_PIXEL_FORMAT_BLOB:
-    case HAL_PIXEL_FORMAT_RAW_OPAQUE:
-      break;
-    case HAL_PIXEL_FORMAT_NV21_ZSL:
-      aligned_w = ALIGN(width, 64);
-      aligned_h = ALIGN(height, 64);
-      break;
-    default:
-      break;
-  }
-
-  *alignedw = (unsigned int)aligned_w;
-  *alignedh = (unsigned int)aligned_h;
-}
-
-int GetBufferLayout(private_handle_t *hnd, uint32_t stride[4], uint32_t offset[4],
-                    uint32_t *num_planes) {
-  if (!hnd || !stride || !offset || !num_planes) {
-    return -EINVAL;
-  }
-
-  struct android_ycbcr yuvPlaneInfo[2] = {};
-  *num_planes = 1;
-  stride[0] = 0;
-
-  switch (hnd->format) {
-    case HAL_PIXEL_FORMAT_RGB_565:
-    case HAL_PIXEL_FORMAT_BGR_565:
-    case HAL_PIXEL_FORMAT_RGBA_5551:
-    case HAL_PIXEL_FORMAT_RGBA_4444:
-      stride[0] = static_cast<uint32_t>(hnd->width * 2);
-      break;
-    case HAL_PIXEL_FORMAT_RGB_888:
-      stride[0] = static_cast<uint32_t>(hnd->width * 3);
-      break;
-    case HAL_PIXEL_FORMAT_RGBA_8888:
-    case HAL_PIXEL_FORMAT_BGRA_8888:
-    case HAL_PIXEL_FORMAT_RGBX_8888:
-    case HAL_PIXEL_FORMAT_BGRX_8888:
-    case HAL_PIXEL_FORMAT_RGBA_1010102:
-    case HAL_PIXEL_FORMAT_ARGB_2101010:
-    case HAL_PIXEL_FORMAT_RGBX_1010102:
-    case HAL_PIXEL_FORMAT_XRGB_2101010:
-    case HAL_PIXEL_FORMAT_BGRA_1010102:
-    case HAL_PIXEL_FORMAT_ABGR_2101010:
-    case HAL_PIXEL_FORMAT_BGRX_1010102:
-    case HAL_PIXEL_FORMAT_XBGR_2101010:
-      stride[0] = static_cast<uint32_t>(hnd->width * 4);
-      break;
-  }
-
-  // Format is RGB
-  if (stride[0]) {
-    return 0;
-  }
-
-  (*num_planes)++;
-  int ret = GetYUVPlaneInfo(hnd, yuvPlaneInfo);
-  if (ret < 0) {
-    ALOGE("%s failed", __FUNCTION__);
-    return ret;
-  }
-
-  // We are only returning buffer layout for progressive or single field formats.
-  struct android_ycbcr yuvInfo = yuvPlaneInfo[0];
-  stride[0] = static_cast<uint32_t>(yuvInfo.ystride);
-  offset[0] = static_cast<uint32_t>(reinterpret_cast<uint64_t>(yuvInfo.y) - hnd->base);
-  stride[1] = static_cast<uint32_t>(yuvInfo.cstride);
-  switch (hnd->format) {
-    case HAL_PIXEL_FORMAT_YCbCr_420_SP:
-    case HAL_PIXEL_FORMAT_YCbCr_422_SP:
-    case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
-    case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
-    case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
-    case HAL_PIXEL_FORMAT_YCbCr_420_P010:
-    case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
-    case HAL_PIXEL_FORMAT_YCbCr_420_P010_UBWC:
-    case HAL_PIXEL_FORMAT_YCbCr_420_P010_VENUS:
-      offset[1] = static_cast<uint32_t>(reinterpret_cast<uint64_t>(yuvInfo.cb) - hnd->base);
-      break;
-    case HAL_PIXEL_FORMAT_YCrCb_420_SP:
-    case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS:
-    case HAL_PIXEL_FORMAT_YCrCb_422_SP:
-      offset[1] = static_cast<uint32_t>(reinterpret_cast<uint64_t>(yuvInfo.cr) - hnd->base);
-      break;
-    case HAL_PIXEL_FORMAT_YV12:
-      offset[1] = static_cast<uint32_t>(reinterpret_cast<uint64_t>(yuvInfo.cr) - hnd->base);
-      stride[2] = static_cast<uint32_t>(yuvInfo.cstride);
-      offset[2] = static_cast<uint32_t>(reinterpret_cast<uint64_t>(yuvInfo.cb) - hnd->base);
-      (*num_planes)++;
-      break;
-    default:
-      ALOGW("%s: Unsupported format", __FUNCTION__);
-      ret = -EINVAL;
-  }
-
-  if (hnd->flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED) {
-    std::fill(offset, offset + 4, 0);
-  }
-
-  return 0;
-}
-
-}  // namespace gralloc
diff --git a/gralloc/gr_utils.h b/gralloc/gr_utils.h
deleted file mode 100644
index eb35a6a..0000000
--- a/gralloc/gr_utils.h
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * Copyright (c) 2011-2016,2018, The Linux Foundation. All rights reserved.
-
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *   * Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- *   * Redistributions in binary form must reproduce the above
- *     copyright notice, this list of conditions and the following
- *     disclaimer in the documentation and/or other materials provided
- *     with the distribution.
- *   * Neither the name of The Linux Foundation nor the names of its
- *     contributors may be used to endorse or promote products derived
- *     from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef __GR_UTILS_H__
-#define __GR_UTILS_H__
-
-#include <android/hardware/graphics/common/1.0/types.h>
-#include "gralloc_priv.h"
-
-#define SZ_2M 0x200000
-#define SZ_1M 0x100000
-#define SZ_4K 0x1000
-
-#define SIZE_4K 4096
-#define SIZE_8K 4096
-
-#define INT(exp) static_cast<int>(exp)
-#define UINT(exp) static_cast<unsigned int>(exp)
-
-using android::hardware::graphics::common::V1_0::BufferUsage;
-
-namespace gralloc {
-struct BufferInfo {
-  BufferInfo(int w, int h, int f, uint64_t usage = 0)
-      : width(w), height(h), format(f), usage(usage) {}
-  int width;
-  int height;
-  int format;
-  uint64_t usage;
-};
-
-template <class Type1, class Type2>
-inline Type1 ALIGN(Type1 x, Type2 align) {
-  return (Type1)((x + (Type1)align - 1) & ~((Type1)align - 1));
-}
-
-bool IsYuvFormat(const private_handle_t *hnd);
-bool IsCompressedRGBFormat(int format);
-bool IsUncompressedRGBFormat(int format);
-uint32_t GetBppForUncompressedRGB(int format);
-bool CpuCanAccess(uint64_t usage);
-bool CpuCanRead(uint64_t usage);
-bool CpuCanWrite(uint64_t usage);
-unsigned int GetSize(const BufferInfo &d, unsigned int alignedw, unsigned int alignedh);
-void GetBufferSizeAndDimensions(const BufferInfo &d, unsigned int *size, unsigned int *alignedw,
-                                unsigned int *alignedh);
-void GetCustomDimensions(private_handle_t *hnd, int *stride, int *height);
-void GetColorSpaceFromMetadata(private_handle_t *hnd, int *color_space);
-void GetAlignedWidthAndHeight(const BufferInfo &d, unsigned int *aligned_w,
-                              unsigned int *aligned_h);
-int GetYUVPlaneInfo(const private_handle_t *hnd, struct android_ycbcr ycbcr[2]);
-int GetRgbDataAddress(private_handle_t *hnd, void **rgb_data);
-bool IsUBwcFormat(int format);
-bool IsUBwcSupported(int format);
-bool IsUBwcEnabled(int format, uint64_t usage);
-void GetYuvUBwcWidthAndHeight(int width, int height, int format, unsigned int *aligned_w,
-                              unsigned int *aligned_h);
-void GetYuvSPPlaneInfo(uint64_t base, uint32_t width, uint32_t height, uint32_t bpp,
-                       struct android_ycbcr *ycbcr);
-void GetYuvUbwcSPPlaneInfo(uint64_t base, uint32_t width, uint32_t height, int color_format,
-                           struct android_ycbcr *ycbcr);
-void GetYuvUbwcInterlacedSPPlaneInfo(uint64_t base, uint32_t width, uint32_t height,
-                                     int color_format, struct android_ycbcr ycbcr[2]);
-void GetRgbUBwcBlockSize(uint32_t bpp, int *block_width, int *block_height);
-unsigned int GetRgbUBwcMetaBufferSize(int width, int height, uint32_t bpp);
-unsigned int GetUBwcSize(int width, int height, int format, unsigned int alignedw,
-                         unsigned int alignedh);
-int GetBufferLayout(private_handle_t *hnd, uint32_t stride[4], uint32_t offset[4],
-                    uint32_t *num_planes);
-
-}  // namespace gralloc
-
-#endif  // __GR_UTILS_H__
diff --git a/gralloc/service.cpp b/gralloc/service.cpp
deleted file mode 100644
index 5832386..0000000
--- a/gralloc/service.cpp
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (c) 2018, The Linux Foundation. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *    * Redistributions of source code must retain the above copyright
- *      notice, this list of conditions and the following disclaimer.
- *    * Redistributions in binary form must reproduce the above
- *      copyright notice, this list of conditions and the following
- *      disclaimer in the documentation and/or other materials provided
- *      with the distribution.
- *    * Neither the name of The Linux Foundation. nor the names of its
- *      contributors may be used to endorse or promote products derived
- *      from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-#include <hidl/LegacySupport.h>
-#include "QtiAllocator.h"
-
-using android::hardware::configureRpcThreadpool;
-using android::hardware::joinRpcThreadpool;
-using vendor::qti::hardware::display::allocator::V1_0::implementation::QtiAllocator;
-using android::hardware::graphics::allocator::V2_0::IAllocator;
-
-int main(int, char **) {
-  android::sp<IAllocator> service = new QtiAllocator();
-  configureRpcThreadpool(4, true /*callerWillJoin*/);
-  if (service->registerAsService() != android::OK) {
-    ALOGE("Cannot register QTI Allocator service");
-    return -EINVAL;
-  }
-  ALOGI("Initialized qti-allocator");
-  joinRpcThreadpool();
-  return 0;
-}
diff --git a/gralloc/vendor.qti.hardware.display.allocator@1.0-service.rc b/gralloc/vendor.qti.hardware.display.allocator@1.0-service.rc
deleted file mode 100644
index 07bb2ff..0000000
--- a/gralloc/vendor.qti.hardware.display.allocator@1.0-service.rc
+++ /dev/null
@@ -1,6 +0,0 @@
-service vendor.qti.hardware.display.allocator /vendor/bin/hw/vendor.qti.hardware.display.allocator@1.0-service
-    class hal animation
-    user system
-    group graphics drmrpc
-    capabilities SYS_NICE
-    onrestart restart surfaceflinger
diff --git a/hdmi_cec/Android.mk b/hdmi_cec/Android.mk
deleted file mode 100644
index a333654..0000000
--- a/hdmi_cec/Android.mk
+++ /dev/null
@@ -1,18 +0,0 @@
-LOCAL_PATH := $(call my-dir)
-include $(LOCAL_PATH)/../common.mk
-include $(CLEAR_VARS)
-
-LOCAL_MODULE                  := hdmi_cec.$(TARGET_BOARD_PLATFORM)
-LOCAL_VENDOR_MODULE           := true
-LOCAL_MODULE_RELATIVE_PATH    := hw
-LOCAL_MODULE_TAGS             := optional
-LOCAL_C_INCLUDES              := $(common_includes)
-LOCAL_HEADER_LIBRARIES        := display_headers
-LOCAL_SHARED_LIBRARIES        := $(common_libs) libqservice libbinder libqdutils
-
-LOCAL_CFLAGS                  := $(common_flags) -DLOG_TAG=\"qdhdmi_cec\" -Wno-sign-conversion
-LOCAL_CLANG                   := true
-LOCAL_ADDITIONAL_DEPENDENCIES := $(common_deps)
-LOCAL_SRC_FILES               := qhdmi_cec.cpp \
-                                 QHDMIClient.cpp
-include $(BUILD_SHARED_LIBRARY)
diff --git a/hdmi_cec/QHDMIClient.cpp b/hdmi_cec/QHDMIClient.cpp
deleted file mode 100644
index 2b2b1e6..0000000
--- a/hdmi_cec/QHDMIClient.cpp
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
-* Copyright (c) 2014 The Linux Foundation. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without
-* modification, are permitted provided that the following conditions are
-* met:
-*    * Redistributions of source code must retain the above copyright
-*      notice, this list of conditions and the following disclaimer.
-*    * Redistributions in binary form must reproduce the above
-*      copyright notice, this list of conditions and the following
-*      disclaimer in the documentation and/or other materials provided
-*      with the distribution.
-*    * Neither the name of The Linux Foundation. nor the names of its
-*      contributors may be used to endorse or promote products derived
-*      from this software without specific prior written permission.
-*
-* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
-* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
-* ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
-* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
-* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#define DEBUG 0
-#include <QServiceUtils.h>
-#include "QHDMIClient.h"
-
-using namespace android;
-using namespace qhdmicec;
-using namespace qService;
-
-namespace qClient {
-
-void QHDMIClient::binderDied(const wp<IBinder>& who __unused)
-{
-    ALOGW("%s: Display QService died", __FUNCTION__);
-}
-
-void QHDMIClient::onHdmiHotplug(int connected)
-{
-    ALOGD("%s: HDMI connected event connected: %d", __FUNCTION__, connected);
-    cec_hdmi_hotplug(mCtx, connected);
-}
-
-void QHDMIClient::onCECMessageRecieved(char *msg, ssize_t len)
-{
-    ALOGD_IF(DEBUG, "%s: CEC message received len: %zd", __FUNCTION__, len);
-    cec_receive_message(mCtx, msg, len);
-}
-
-void QHDMIClient::registerClient(sp<QHDMIClient>& client)
-{
-    sp<IServiceManager> sm = defaultServiceManager();
-    sp<IBinder> binder = sm->getService(String16("display.qservice"));
-    binder->linkToDeath(client);
-    mQService = interface_cast<IQService>(binder);
-    mQService->connect(interface_cast<IQHDMIClient>(client));
-}
-
-};
diff --git a/hdmi_cec/QHDMIClient.h b/hdmi_cec/QHDMIClient.h
deleted file mode 100644
index 9e54f2f..0000000
--- a/hdmi_cec/QHDMIClient.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
-* Copyright (c) 2014 The Linux Foundation. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without
-* modification, are permitted provided that the following conditions are
-* met:
-*    * Redistributions of source code must retain the above copyright
-*      notice, this list of conditions and the following disclaimer.
-*    * Redistributions in binary form must reproduce the above
-*      copyright notice, this list of conditions and the following
-*      disclaimer in the documentation and/or other materials provided
-*      with the distribution.
-*    * Neither the name of The Linux Foundation. nor the names of its
-*      contributors may be used to endorse or promote products derived
-*      from this software without specific prior written permission.
-*
-* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
-* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
-* ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
-* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
-* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#include "IQHDMIClient.h"
-#include "qhdmi_cec.h"
-#include <IQService.h>
-
-namespace qClient {
-
-class QHDMIClient: public android::IBinder::DeathRecipient,
-    public BnQHDMIClient
-{
-public:
-    QHDMIClient() {}
-
-    virtual void binderDied(const android::wp<android::IBinder>& who);
-
-    virtual void onHdmiHotplug(int connected);
-
-    virtual void onCECMessageRecieved(char *msg, ssize_t len);
-
-    void setCECContext(qhdmicec::cec_context_t* ctx) { mCtx = ctx; }
-
-    void registerClient(android::sp<QHDMIClient>& client);
-
-private:
-    qhdmicec::cec_context_t* mCtx;
-    android::sp<qService::IQService> mQService;
-
-};
-};
diff --git a/hdmi_cec/qhdmi_cec.cpp b/hdmi_cec/qhdmi_cec.cpp
deleted file mode 100644
index 2760334..0000000
--- a/hdmi_cec/qhdmi_cec.cpp
+++ /dev/null
@@ -1,520 +0,0 @@
-/*
-* Copyright (c) 2014, 2016-2017, The Linux Foundation. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without
-* modification, are permitted provided that the following conditions are
-* met:
-*    * Redistributions of source code must retain the above copyright
-*      notice, this list of conditions and the following disclaimer.
-*    * Redistributions in binary form must reproduce the above
-*      copyright notice, this list of conditions and the following
-*      disclaimer in the documentation and/or other materials provided
-*      with the distribution.
-*    * Neither the name of The Linux Foundation. nor the names of its
-*      contributors may be used to endorse or promote products derived
-*      from this software without specific prior written permission.
-*
-* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
-* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
-* ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
-* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
-* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#define DEBUG 0
-#define ATRACE_TAG (ATRACE_TAG_GRAPHICS | ATRACE_TAG_HAL)
-#include <cstdlib>
-#include <log/log.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <hardware/hdmi_cec.h>
-#include <utils/Trace.h>
-#include "qhdmi_cec.h"
-#include "QHDMIClient.h"
-
-namespace qhdmicec {
-
-const int NUM_HDMI_PORTS = 1;
-const int MAX_SYSFS_DATA = 128;
-const int MAX_CEC_FRAME_SIZE = 20;
-const int MAX_SEND_MESSAGE_RETRIES = 1;
-
-enum {
-    LOGICAL_ADDRESS_SET   =  1,
-    LOGICAL_ADDRESS_UNSET = -1,
-};
-
-// Offsets of members of struct hdmi_cec_msg
-// drivers/video/msm/mdss/mdss_hdmi_cec.c
-// XXX: Get this from a driver header
-enum {
-    CEC_OFFSET_SENDER_ID,
-    CEC_OFFSET_RECEIVER_ID,
-    CEC_OFFSET_OPCODE,
-    CEC_OFFSET_OPERAND,
-    CEC_OFFSET_FRAME_LENGTH = 17,
-    CEC_OFFSET_RETRANSMIT,
-};
-
-//Forward declarations
-static void cec_close_context(cec_context_t* ctx __unused);
-static int cec_enable(cec_context_t *ctx, int enable);
-static int cec_is_connected(const struct hdmi_cec_device* dev, int port_id);
-
-static ssize_t read_node(const char *path, char *data)
-{
-    ssize_t err = 0;
-    FILE *fp = NULL;
-    err = access(path, R_OK);
-    if (!err) {
-        fp = fopen(path, "r");
-        if (fp) {
-            err = fread(data, sizeof(char), MAX_SYSFS_DATA ,fp);
-            fclose(fp);
-        }
-    }
-    return err;
-}
-
-static ssize_t write_node(const char *path, const char *data, size_t len)
-{
-    ssize_t err = 0;
-    int fd = -1;
-    err = access(path, W_OK);
-    if (!err) {
-        fd = open(path, O_WRONLY);
-        errno = 0;
-        err = write(fd, data, len);
-        if (err < 0) {
-            err = -errno;
-        }
-        close(fd);
-    } else {
-        ALOGE("%s: Failed to access path: %s error: %s",
-                __FUNCTION__, path, strerror(errno));
-        err = -errno;
-    }
-    return err;
-}
-
-// Helper function to write integer values to the full sysfs path
-static ssize_t write_int_to_node(cec_context_t *ctx,
-        const char *path_postfix,
-        const int value)
-{
-    char sysfs_full_path[MAX_PATH_LENGTH];
-    char sysfs_data[MAX_SYSFS_DATA];
-    snprintf(sysfs_data, sizeof(sysfs_data), "%d",value);
-    snprintf(sysfs_full_path,sizeof(sysfs_full_path), "%s/%s",
-            ctx->fb_sysfs_path, path_postfix);
-    ssize_t err = write_node(sysfs_full_path, sysfs_data, strlen(sysfs_data));
-    return err;
-}
-
-static void hex_to_string(const char *msg, ssize_t len, char *str)
-{
-    //Functions assumes sufficient memory in str
-    char *ptr = str;
-    for(int i=0; i < len ; i++) {
-        ptr += snprintf(ptr, 3,  "%02X", msg[i]);
-        // Overwrite null termination of snprintf in all except the last byte
-        if (i < len - 1)
-            *ptr = ':';
-        ptr++;
-    }
-}
-
-static ssize_t cec_get_fb_node_number(cec_context_t *ctx)
-{
-    //XXX: Do this from a common utility library across the display HALs
-    const int MAX_FB_DEVICES = 2;
-    ssize_t len = 0;
-    char fb_type_path[MAX_PATH_LENGTH];
-    char fb_type[MAX_SYSFS_DATA];
-    const char *dtv_panel_str = "dtv panel";
-
-    for(int num = 0; num < MAX_FB_DEVICES; num++) {
-        snprintf(fb_type_path, sizeof(fb_type_path),"%s%d/msm_fb_type",
-                SYSFS_BASE,num);
-        ALOGD_IF(DEBUG, "%s: num: %d fb_type_path: %s", __FUNCTION__, num, fb_type_path);
-        len = read_node(fb_type_path, fb_type);
-        ALOGD_IF(DEBUG, "%s: fb_type:%s", __FUNCTION__, fb_type);
-        if(len > 0 && (strncmp(fb_type, dtv_panel_str, strlen(dtv_panel_str)) == 0)){
-            ALOGD_IF(DEBUG, "%s: Found DTV panel at fb%d", __FUNCTION__, num);
-            ctx->fb_num = num;
-            snprintf(ctx->fb_sysfs_path, sizeof(ctx->fb_sysfs_path),
-                    "%s%d", SYSFS_BASE, num);
-            break;
-        }
-    }
-    if (len < 0)
-        return len;
-    else
-        return 0;
-}
-
-static int cec_add_logical_address(const struct hdmi_cec_device* dev,
-        cec_logical_address_t addr)
-{
-    if (addr <  CEC_ADDR_TV || addr > CEC_ADDR_BROADCAST) {
-        ALOGE("%s: Received invalid address: %d ", __FUNCTION__, addr);
-        return -EINVAL;
-    }
-    cec_context_t* ctx = (cec_context_t*)(dev);
-    ctx->logical_address[addr] = LOGICAL_ADDRESS_SET;
-
-    //XXX: We can get multiple logical addresses here but we can only send one
-    //to the driver. Store locally for now
-    ssize_t err = write_int_to_node(ctx, "cec/logical_addr", addr);
-    ALOGI("%s: Allocated logical address: %d ", __FUNCTION__, addr);
-    return (int) err;
-}
-
-static void cec_clear_logical_address(const struct hdmi_cec_device* dev)
-{
-    cec_context_t* ctx = (cec_context_t*)(dev);
-    memset(ctx->logical_address, LOGICAL_ADDRESS_UNSET,
-            sizeof(ctx->logical_address));
-    //XXX: Find logical_addr that needs to be reset
-    write_int_to_node(ctx, "cec/logical_addr", 15);
-    ALOGD_IF(DEBUG, "%s: Cleared logical addresses", __FUNCTION__);
-}
-
-static int cec_get_physical_address(const struct hdmi_cec_device* dev,
-        uint16_t* addr)
-{
-    cec_context_t* ctx = (cec_context_t*)(dev);
-    char pa_path[MAX_PATH_LENGTH];
-    char pa_data[MAX_SYSFS_DATA];
-    snprintf (pa_path, sizeof(pa_path),"%s/pa",
-            ctx->fb_sysfs_path);
-    int err = (int) read_node(pa_path, pa_data);
-    *addr = (uint16_t) atoi(pa_data);
-    ALOGD_IF(DEBUG, "%s: Physical Address: 0x%x", __FUNCTION__, *addr);
-    if (err < 0)
-        return err;
-    else
-        return 0;
-}
-
-static int cec_send_message(const struct hdmi_cec_device* dev,
-        const cec_message_t* msg)
-{
-    ATRACE_CALL();
-    if(cec_is_connected(dev, 0) <= 0)
-        return HDMI_RESULT_FAIL;
-
-    cec_context_t* ctx = (cec_context_t*)(dev);
-    ALOGD_IF(DEBUG, "%s: initiator: %d destination: %d length: %u",
-            __FUNCTION__, msg->initiator, msg->destination,
-            (uint32_t) msg->length);
-
-    // Dump message received from framework
-    char dump[128];
-    if(msg->length > 0) {
-        hex_to_string((char*)msg->body, msg->length, dump);
-        ALOGD_IF(DEBUG, "%s: message from framework: %s", __FUNCTION__, dump);
-    }
-
-    char write_msg_path[MAX_PATH_LENGTH];
-    char write_msg[MAX_CEC_FRAME_SIZE];
-    memset(write_msg, 0, sizeof(write_msg));
-    // See definition of struct hdmi_cec_msg in driver code
-    // drivers/video/msm/mdss/mdss_hdmi_cec.c
-    // Write header block
-    // XXX: Include this from header in kernel
-    write_msg[CEC_OFFSET_SENDER_ID] = msg->initiator;
-    write_msg[CEC_OFFSET_RECEIVER_ID] = msg->destination;
-    //Kernel splits opcode/operand, but Android sends it in one byte array
-    write_msg[CEC_OFFSET_OPCODE] = msg->body[0];
-    if(msg->length > 1) {
-        memcpy(&write_msg[CEC_OFFSET_OPERAND], &msg->body[1],
-                sizeof(char)*(msg->length - 1));
-    }
-    //msg length + initiator + destination
-    write_msg[CEC_OFFSET_FRAME_LENGTH] = (unsigned char) (msg->length + 1);
-    hex_to_string(write_msg, sizeof(write_msg), dump);
-    ALOGD_IF(DEBUG, "%s: message to driver: %s", __FUNCTION__, dump);
-    snprintf(write_msg_path, sizeof(write_msg_path), "%s/cec/wr_msg",
-            ctx->fb_sysfs_path);
-    int retry_count = 0;
-    ssize_t err = 0;
-    //HAL spec requires us to retry at least once.
-    while (true) {
-        err = write_node(write_msg_path, write_msg, sizeof(write_msg));
-        retry_count++;
-        if (err == -EAGAIN && retry_count <= MAX_SEND_MESSAGE_RETRIES) {
-            ALOGE("%s: CEC line busy, retrying", __FUNCTION__);
-        } else {
-            break;
-        }
-    }
-
-    if (err < 0) {
-       if (err == -ENXIO) {
-           ALOGI("%s: No device exists with the destination address",
-                   __FUNCTION__);
-           return HDMI_RESULT_NACK;
-       } else if (err == -EAGAIN) {
-            ALOGE("%s: CEC line is busy, max retry count exceeded",
-                    __FUNCTION__);
-            return HDMI_RESULT_BUSY;
-        } else {
-            return HDMI_RESULT_FAIL;
-            ALOGE("%s: Failed to send CEC message err: %zd - %s",
-                    __FUNCTION__, err, strerror(int(-err)));
-        }
-    } else {
-        ALOGD_IF(DEBUG, "%s: Sent CEC message - %zd bytes written",
-                __FUNCTION__, err);
-        return HDMI_RESULT_SUCCESS;
-    }
-}
-
-void cec_receive_message(cec_context_t *ctx, char *msg, ssize_t len)
-{
-    if(!ctx->system_control)
-        return;
-
-    char dump[128];
-    if(len > 0) {
-        hex_to_string(msg, len, dump);
-        ALOGD_IF(DEBUG, "%s: Message from driver: %s", __FUNCTION__, dump);
-    }
-
-    hdmi_event_t event;
-    event.type = HDMI_EVENT_CEC_MESSAGE;
-    event.dev = (hdmi_cec_device *) ctx;
-    // Remove initiator/destination from this calculation
-    event.cec.length = msg[CEC_OFFSET_FRAME_LENGTH] - 1;
-    event.cec.initiator = (cec_logical_address_t) msg[CEC_OFFSET_SENDER_ID];
-    event.cec.destination = (cec_logical_address_t) msg[CEC_OFFSET_RECEIVER_ID];
-    //Copy opcode and operand
-    size_t copy_size = event.cec.length > sizeof(event.cec.body) ?
-                       sizeof(event.cec.body) : event.cec.length;
-    memcpy(event.cec.body, &msg[CEC_OFFSET_OPCODE],copy_size);
-    hex_to_string((char *) event.cec.body, copy_size, dump);
-    ALOGD_IF(DEBUG, "%s: Message to framework: %s", __FUNCTION__, dump);
-    ctx->callback.callback_func(&event, ctx->callback.callback_arg);
-}
-
-void cec_hdmi_hotplug(cec_context_t *ctx, int connected)
-{
-    //Ignore unplug events when system control is disabled
-    if(!ctx->system_control && connected == 0)
-        return;
-    hdmi_event_t event;
-    event.type = HDMI_EVENT_HOT_PLUG;
-    event.dev = (hdmi_cec_device *) ctx;
-    event.hotplug.connected = connected ? HDMI_CONNECTED : HDMI_NOT_CONNECTED;
-    ctx->callback.callback_func(&event, ctx->callback.callback_arg);
-}
-
-static void cec_register_event_callback(const struct hdmi_cec_device* dev,
-            event_callback_t callback, void* arg)
-{
-    ALOGD_IF(DEBUG, "%s: Registering callback", __FUNCTION__);
-    cec_context_t* ctx = (cec_context_t*)(dev);
-    ctx->callback.callback_func = callback;
-    ctx->callback.callback_arg = arg;
-}
-
-static void cec_get_version(const struct hdmi_cec_device* dev, int* version)
-{
-    cec_context_t* ctx = (cec_context_t*)(dev);
-    *version = ctx->version;
-    ALOGD_IF(DEBUG, "%s: version: %d", __FUNCTION__, *version);
-}
-
-static void cec_get_vendor_id(const struct hdmi_cec_device* dev,
-        uint32_t* vendor_id)
-{
-    cec_context_t* ctx = (cec_context_t*)(dev);
-    *vendor_id = ctx->vendor_id;
-    ALOGD_IF(DEBUG, "%s: vendor id: %u", __FUNCTION__, *vendor_id);
-}
-
-static void cec_get_port_info(const struct hdmi_cec_device* dev,
-            struct hdmi_port_info* list[], int* total)
-{
-    ALOGD_IF(DEBUG, "%s: Get port info", __FUNCTION__);
-    cec_context_t* ctx = (cec_context_t*)(dev);
-    *total = NUM_HDMI_PORTS;
-    *list = ctx->port_info;
-}
-
-static void cec_set_option(const struct hdmi_cec_device* dev, int flag,
-        int value)
-{
-    cec_context_t* ctx = (cec_context_t*)(dev);
-    switch (flag) {
-        case HDMI_OPTION_WAKEUP:
-            ALOGD_IF(DEBUG, "%s: Wakeup: value: %d", __FUNCTION__, value);
-            //XXX
-            break;
-        case HDMI_OPTION_ENABLE_CEC:
-            ALOGD_IF(DEBUG, "%s: Enable CEC: value: %d", __FUNCTION__, value);
-            cec_enable(ctx, value? 1 : 0);
-            break;
-        case HDMI_OPTION_SYSTEM_CEC_CONTROL:
-            ALOGD_IF(DEBUG, "%s: system_control: value: %d",
-                    __FUNCTION__, value);
-            ctx->system_control = !!value;
-            break;
-    }
-}
-
-static void cec_set_audio_return_channel(const struct hdmi_cec_device* dev,
-        int port, int flag)
-{
-    cec_context_t* ctx = (cec_context_t*)(dev);
-    ctx->arc_enabled = flag ? true : false;
-    ALOGD_IF(DEBUG, "%s: ARC flag: %d port: %d", __FUNCTION__, flag, port);
-}
-
-static int cec_is_connected(const struct hdmi_cec_device* dev, int port_id)
-{
-    // Ignore port_id since we have only one port
-    int connected = 0;
-    cec_context_t* ctx = (cec_context_t*)(dev);
-    char connected_path[MAX_PATH_LENGTH];
-    char connected_data[MAX_SYSFS_DATA];
-    snprintf (connected_path, sizeof(connected_path),"%s/connected",
-            ctx->fb_sysfs_path);
-    ssize_t err = read_node(connected_path, connected_data);
-    connected = atoi(connected_data);
-
-    ALOGD_IF(DEBUG, "%s: HDMI at port %d is - %s", __FUNCTION__, port_id,
-            connected ? "connected":"disconnected");
-    if (err < 0)
-        return (int) err;
-    else
-        return connected;
-}
-
-static int cec_device_close(struct hw_device_t *dev)
-{
-    ALOGD_IF(DEBUG, "%s: Close CEC HAL ", __FUNCTION__);
-    if (!dev) {
-        ALOGE("%s: NULL device pointer", __FUNCTION__);
-        return -EINVAL;
-    }
-    cec_context_t* ctx = (cec_context_t*)(dev);
-    cec_close_context(ctx);
-    free(dev);
-    return 0;
-}
-
-static int cec_enable(cec_context_t *ctx, int enable)
-{
-    ssize_t err;
-    // Enable CEC
-    int value = enable ? 0x3 : 0x0;
-    err = write_int_to_node(ctx, "cec/enable", value);
-    if(err < 0) {
-        ALOGE("%s: Failed to toggle CEC: enable: %d",
-                __FUNCTION__, enable);
-        return (int) err;
-    }
-    ctx->enabled = enable;
-    return 0;
-}
-
-static void cec_init_context(cec_context_t *ctx)
-{
-    ALOGD_IF(DEBUG, "%s: Initializing context", __FUNCTION__);
-    cec_get_fb_node_number(ctx);
-
-    //Initialize ports - We support only one output port
-    ctx->port_info = new hdmi_port_info[NUM_HDMI_PORTS];
-    ctx->port_info[0].type = HDMI_OUTPUT;
-    ctx->port_info[0].port_id = 1;
-    ctx->port_info[0].cec_supported = 1;
-    //XXX: Enable ARC if supported
-    ctx->port_info[0].arc_supported = 0;
-    cec_get_physical_address((hdmi_cec_device *) ctx,
-            &ctx->port_info[0].physical_address );
-
-    ctx->version = 0x4;
-    ctx->vendor_id = 0xA47733;
-    cec_clear_logical_address((hdmi_cec_device_t*)ctx);
-
-    //Set up listener for HDMI events
-    ctx->disp_client = new qClient::QHDMIClient();
-    ctx->disp_client->setCECContext(ctx);
-    ctx->disp_client->registerClient(ctx->disp_client);
-
-    //Enable CEC - framework expects it to be enabled by default
-    cec_enable(ctx, true);
-
-    ALOGD("%s: CEC enabled", __FUNCTION__);
-}
-
-static void cec_close_context(cec_context_t* ctx __unused)
-{
-    ALOGD("%s: Closing context", __FUNCTION__);
-}
-
-static int cec_device_open(const struct hw_module_t* module,
-        const char* name,
-        struct hw_device_t** device)
-{
-    ALOGD_IF(DEBUG, "%s: name: %s", __FUNCTION__, name);
-    int status = -EINVAL;
-    if (!strcmp(name, HDMI_CEC_HARDWARE_INTERFACE )) {
-        struct cec_context_t *dev;
-        dev = (cec_context_t *) calloc (1, sizeof(*dev));
-        if (dev) {
-            cec_init_context(dev);
-
-            //Setup CEC methods
-            dev->device.common.tag       = HARDWARE_DEVICE_TAG;
-            dev->device.common.version   = HDMI_CEC_DEVICE_API_VERSION_1_0;
-            dev->device.common.module    = const_cast<hw_module_t* >(module);
-            dev->device.common.close     = cec_device_close;
-            dev->device.add_logical_address = cec_add_logical_address;
-            dev->device.clear_logical_address = cec_clear_logical_address;
-            dev->device.get_physical_address = cec_get_physical_address;
-            dev->device.send_message = cec_send_message;
-            dev->device.register_event_callback = cec_register_event_callback;
-            dev->device.get_version = cec_get_version;
-            dev->device.get_vendor_id = cec_get_vendor_id;
-            dev->device.get_port_info = cec_get_port_info;
-            dev->device.set_option = cec_set_option;
-            dev->device.set_audio_return_channel = cec_set_audio_return_channel;
-            dev->device.is_connected = cec_is_connected;
-
-            *device = &dev->device.common;
-            status = 0;
-        } else {
-            status = -EINVAL;
-        }
-    }
-    return status;
-}
-}; //namespace qhdmicec
-
-// Standard HAL module, should be outside qhdmicec namespace
-static struct hw_module_methods_t cec_module_methods = {
-        .open = qhdmicec::cec_device_open
-};
-
-hdmi_module_t HAL_MODULE_INFO_SYM = {
-    .common = {
-        .tag = HARDWARE_MODULE_TAG,
-        .version_major = 1,
-        .version_minor = 0,
-        .id = HDMI_CEC_HARDWARE_MODULE_ID,
-        .name = "QTI HDMI CEC module",
-        .author = "The Linux Foundation",
-        .methods = &cec_module_methods,
-    }
-};
-
-
diff --git a/hdmi_cec/qhdmi_cec.h b/hdmi_cec/qhdmi_cec.h
deleted file mode 100644
index aa97620..0000000
--- a/hdmi_cec/qhdmi_cec.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
-* Copyright (c) 2014 The Linux Foundation. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without
-* modification, are permitted provided that the following conditions are
-* met:
-*    * Redistributions of source code must retain the above copyright
-*      notice, this list of conditions and the following disclaimer.
-*    * Redistributions in binary form must reproduce the above
-*      copyright notice, this list of conditions and the following
-*      disclaimer in the documentation and/or other materials provided
-*      with the distribution.
-*    * Neither the name of The Linux Foundation. nor the names of its
-*      contributors may be used to endorse or promote products derived
-*      from this software without specific prior written permission.
-*
-* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
-* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
-* ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
-* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
-* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-#ifndef QHDMI_CEC_H
-#define QHDMI_CEC_H
-
-#include <hardware/hdmi_cec.h>
-#include <utils/RefBase.h>
-
-namespace qClient {
-    class QHDMIClient;
-};
-
-namespace qhdmicec {
-
-#define SYSFS_BASE  "/sys/class/graphics/fb"
-#define MAX_PATH_LENGTH  128
-
-struct cec_callback_t {
-    // Function in HDMI service to call back on CEC messages
-    event_callback_t callback_func;
-    // This stores the object to pass back to the framework
-    void* callback_arg;
-
-};
-
-struct cec_context_t {
-    hdmi_cec_device_t device;    // Device for HW module
-    cec_callback_t callback;     // Struct storing callback object
-    bool enabled;
-    bool arc_enabled;
-    bool system_control;         // If true, HAL/driver handle CEC messages
-    int fb_num;                  // Framebuffer node for HDMI
-    char fb_sysfs_path[MAX_PATH_LENGTH];
-    hdmi_port_info *port_info;   // HDMI port info
-
-    // Logical address is stored in an array, the index of the array is the
-    // logical address and the value in the index shows whether it is set or not
-    int logical_address[CEC_ADDR_BROADCAST];
-    int version;
-    uint32_t vendor_id;
-    android::sp<qClient::QHDMIClient> disp_client;
-};
-
-void cec_receive_message(cec_context_t *ctx, char *msg, ssize_t len);
-void cec_hdmi_hotplug(cec_context_t *ctx, int connected);
-
-}; //namespace
-#endif /* end of include guard: QHDMI_CEC_H */
diff --git a/include/Android.mk b/include/Android.mk
deleted file mode 100644
index 58653c1..0000000
--- a/include/Android.mk
+++ /dev/null
@@ -1,21 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-include $(LOCAL_PATH)/../common.mk
-include $(CLEAR_VARS)
-
-# Legacy header copy. This is deprecated.
-# Modules using these headers should shift to using
-# LOCAL_HEADER_LIBRARIES := display_headers
-LOCAL_VENDOR_MODULE           := true
-LOCAL_COPY_HEADERS_TO         := $(common_header_export_path)
-LOCAL_COPY_HEADERS            := color_metadata.h \
-                                 display_properties.h \
-                                 ../libqdutils/qd_utils.h \
-                                 ../libqdutils/qdMetaData.h \
-                                 ../libqdutils/display_config.h \
-                                 ../libdebug/debug_handler.h \
-                                 ../libqservice/QServiceUtils.h \
-                                 ../libqservice/IQService.h \
-                                 ../libqservice/IQHDMIClient.h \
-                                 ../libqservice/IQClient.h
-
-include $(BUILD_COPY_HEADERS)
diff --git a/include/color_metadata.h b/include/color_metadata.h
index 3ddf757..25dc5b5 100644
--- a/include/color_metadata.h
+++ b/include/color_metadata.h
@@ -1,5 +1,5 @@
 /*
-* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
+* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification, are permitted
 * provided that the following conditions are met:
@@ -33,8 +33,9 @@
 #include <stdint.h>
 
 typedef enum ColorRange {
-  Range_Limited = 0,
-  Range_Full    = 1,
+  Range_Limited   = 0,
+  Range_Full      = 1,
+  Range_Extended  = 2,
   Range_Max     = 0xff,
 } ColorRange;
 
diff --git a/include/display_properties.h b/include/display_properties.h
deleted file mode 100644
index df29eb0..0000000
--- a/include/display_properties.h
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
-* Copyright (c) 2018, The Linux Foundation. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without
-* modification, are permitted provided that the following conditions are
-* met:
-*     * Redistributions of source code must retain the above copyright
-*       notice, this list of conditions and the following disclaimer.
-*     * Redistributions in binary form must reproduce the above
-*       copyright notice, this list of conditions and the following
-*       disclaimer in the documentation and/or other materials provided
-*       with the distribution.
-*     * Neither the name of The Linux Foundation nor the names of its
-*       contributors may be used to endorse or promote products derived
-*       from this software without specific prior written permission.
-*
-* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
-* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
-* ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
-* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
-* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#ifndef __DISPLAY_PROPERTIES_H__
-#define __DISPLAY_PROPERTIES_H__
-
-#define DISP_PROP_PREFIX                     "vendor.display."
-#define GRALLOC_PROP_PREFIX                  "vendor.gralloc."
-#define RO_DISP_PROP_PREFIX                  "ro.vendor.display."
-#define PERSIST_DISP_PROP_PREFIX             "persist.vendor.display."
-
-#define DISPLAY_PROP(prop_name)              DISP_PROP_PREFIX prop_name
-#define GRALLOC_PROP(prop_name)              GRALLOC_PROP_PREFIX prop_name
-#define RO_DISPLAY_PROP(prop_name)           RO_DISP_PROP_PREFIX prop_name
-#define PERSIST_DISPLAY_PROP(prop_name)      PERSIST_DISP_PROP_PREFIX prop_name
-
-#define COMPOSITION_MASK_PROP                DISPLAY_PROP("comp_mask")
-#define HDMI_CONFIG_INDEX_PROP               DISPLAY_PROP("hdmi_cfg_idx")
-#define IDLE_TIME_PROP                       DISPLAY_PROP("idle_time")
-#define IDLE_TIME_INACTIVE_PROP              DISPLAY_PROP("idle_time_inactive")
-#define BOOT_ANIMATION_LAYER_COUNT_PROP      DISPLAY_PROP("boot_anim_layer_count")
-#define DISABLE_ROTATOR_DOWNSCALE_PROP       DISPLAY_PROP("disable_rotator_downscale")
-#define DISABLE_DECIMATION_PROP              DISPLAY_PROP("disable_decimation")
-#define PRIMARY_MIXER_STAGES_PROP            DISPLAY_PROP("primary_mixer_stages")
-#define EXTERNAL_MIXER_STAGES_PROP           DISPLAY_PROP("external_mixer_stages")
-#define VIRTUAL_MIXER_STAGES_PROP            DISPLAY_PROP("virtual_mixer_stages")
-#define MAX_UPSCALE_PROP                     DISPLAY_PROP("max_upscale")
-#define VIDEO_MODE_PANEL_PROP                DISPLAY_PROP("video_mode_panel")
-#define DISABLE_ROTATOR_UBWC_PROP            DISPLAY_PROP("disable_rotator_ubwc")
-#define DISABLE_ROTATOR_SPLIT_PROP           DISPLAY_PROP("disable_rotator_split")
-#define DISABLE_SCALER_PROP                  DISPLAY_PROP("disable_scaler")
-#define DISABLE_AVR_PROP                     DISPLAY_PROP("disable_avr")
-#define DISABLE_EXTERNAL_ANIMATION_PROP      DISPLAY_PROP("disable_ext_anim")
-#define DISABLE_PARTIAL_SPLIT_PROP           DISPLAY_PROP("disable_partial_split")
-#define PREFER_SOURCE_SPLIT_PROP             DISPLAY_PROP("prefer_source_split")
-#define MIXER_RESOLUTION_PROP                DISPLAY_PROP("mixer_resolution")
-#define SIMULATED_CONFIG_PROP                DISPLAY_PROP("simulated_config")
-#define MAX_EXTERNAL_LAYERS_PROP             DISPLAY_PROP("max_external_layers")
-#define PERF_HINT_WINDOW_PROP                DISPLAY_PROP("perf_hint_window")
-#define ENABLE_EXTERNAL_DOWNSCALE_PROP       DISPLAY_PROP("enable_external_downscale")
-#define EXTERNAL_ACTION_SAFE_WIDTH_PROP      DISPLAY_PROP("external_action_safe_width")
-#define EXTERNAL_ACTION_SAFE_HEIGHT_PROP     DISPLAY_PROP("external_action_safe_height")
-#define FB_WIDTH_PROP                        DISPLAY_PROP("fb_width")
-#define FB_HEIGHT_PROP                       DISPLAY_PROP("fb_height")
-#define DISABLE_METADATA_DYNAMIC_FPS_PROP    DISPLAY_PROP("disable_metadata_dynamic_fps")
-#define DISABLE_BLIT_COMPOSITION_PROP        DISPLAY_PROP("disable_blit_comp")
-#define DISABLE_SKIP_VALIDATE_PROP           DISPLAY_PROP("disable_skip_validate")
-#define HDMI_S3D_MODE_PROP                   DISPLAY_PROP("hdmi_s3d_mode")
-#define DISABLE_DESTINATION_SCALER_PROP      DISPLAY_PROP("disable_dest_scaler")
-#define ENABLE_PARTIAL_UPDATE_PROP           DISPLAY_PROP("enable_partial_update")
-#define DISABLE_UBWC_PROP                    GRALLOC_PROP("disable_ubwc")
-#define ENABLE_FB_UBWC_PROP                  GRALLOC_PROP("enable_fb_ubwc")
-#define MAP_FB_MEMORY_PROP                   GRALLOC_PROP("map_fb_memory")
-
-#define MAX_BLIT_FACTOR_PROP                 DISPLAY_PROP("max_blit_factor")
-#define DISABLE_SECURE_INLINE_ROTATOR_PROP   DISPLAY_PROP("disable_secure_inline_rotator")
-#define DISABLE_MULTIRECT_PROP               DISPLAY_PROP("disable_multirect")
-#define DISABLE_UBWC_FF_VOTING_PROP          DISPLAY_PROP("disable_ubwc_ff_voting")
-#define DISABLE_INLINE_ROTATOR_PROP          DISPLAY_PROP("disable_inline_rotator")
-#define DISABLE_FB_CROPPING_PROP             DISPLAY_PROP("disable_fb_cropping")
-#define PRIORITIZE_CACHE_COMPOSITION_PROP    DISPLAY_PROP("prioritize_cache_comp")
-
-#define DISABLE_HDR_LUT_GEN                  DISPLAY_PROP("disable_hdr_lut_gen")
-#define ENABLE_DEFAULT_COLOR_MODE            DISPLAY_PROP("enable_default_color_mode")
-#define DISABLE_HDR                          DISPLAY_PROP("hwc_disable_hdr")
-
-#define HDR_CONFIG_PROP                      RO_DISPLAY_PROP("hdr.config")
-#define QDCM_PCC_TRANS_PROP                  DISPLAY_PROP("qdcm.pcc_for_trans")
-#define QDCM_DIAGONAL_MATRIXMODE_PROP        DISPLAY_PROP("qdcm.diagonal_matrix_mode")
-#define QDCM_DISABLE_TIMEOUT_PROP            PERSIST_DISPLAY_PROP("qdcm.disable_timeout")
-
-#define ZERO_SWAP_INTERVAL                   "vendor.debug.egl.swapinterval"
-
-#endif  // __DISPLAY_PROPERTIES_H__
diff --git a/libcopybit/Android.mk b/libcopybit/Android.mk
deleted file mode 100644
index 8396d51..0000000
--- a/libcopybit/Android.mk
+++ /dev/null
@@ -1,23 +0,0 @@
-# Copyright (C) 2008 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.
-
-LOCAL_PATH:= $(call my-dir)
-include $(LOCAL_PATH)/../common.mk
-include $(CLEAR_VARS)
-
-LOCAL_VENDOR_MODULE           := true
-LOCAL_COPY_HEADERS_TO         := $(common_header_export_path)
-LOCAL_COPY_HEADERS            := copybit.h copybit_priv.h c2d2.h
-#Copy the headers regardless of whether copybit is built
-include $(BUILD_COPY_HEADERS)
diff --git a/libcopybit/MODULE_LICENSE_APACHE2 b/libcopybit/MODULE_LICENSE_APACHE2
deleted file mode 100644
index e69de29..0000000
--- a/libcopybit/MODULE_LICENSE_APACHE2
+++ /dev/null
diff --git a/libcopybit/NOTICE b/libcopybit/NOTICE
deleted file mode 100644
index 9c1e63a..0000000
--- a/libcopybit/NOTICE
+++ /dev/null
@@ -1,189 +0,0 @@
-
-   Copyright (c) 2008, 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.
-
-   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.
-
-
-                                 Apache License
-                           Version 2.0, January 2004
-                        http://www.apache.org/licenses/
-
-   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-   1. Definitions.
-
-      "License" shall mean the terms and conditions for use, reproduction,
-      and distribution as defined by Sections 1 through 9 of this document.
-
-      "Licensor" shall mean the copyright owner or entity authorized by
-      the copyright owner that is granting the License.
-
-      "Legal Entity" shall mean the union of the acting entity and all
-      other entities that control, are controlled by, or are under common
-      control with that entity. For the purposes of this definition,
-      "control" means (i) the power, direct or indirect, to cause the
-      direction or management of such entity, whether by contract or
-      otherwise, or (ii) ownership of fifty percent (50%) or more of the
-      outstanding shares, or (iii) beneficial ownership of such entity.
-
-      "You" (or "Your") shall mean an individual or Legal Entity
-      exercising permissions granted by this License.
-
-      "Source" form shall mean the preferred form for making modifications,
-      including but not limited to software source code, documentation
-      source, and configuration files.
-
-      "Object" form shall mean any form resulting from mechanical
-      transformation or translation of a Source form, including but
-      not limited to compiled object code, generated documentation,
-      and conversions to other media types.
-
-      "Work" shall mean the work of authorship, whether in Source or
-      Object form, made available under the License, as indicated by a
-      copyright notice that is included in or attached to the work
-      (an example is provided in the Appendix below).
-
-      "Derivative Works" shall mean any work, whether in Source or Object
-      form, that is based on (or derived from) the Work and for which the
-      editorial revisions, annotations, elaborations, or other modifications
-      represent, as a whole, an original work of authorship. For the purposes
-      of this License, Derivative Works shall not include works that remain
-      separable from, or merely link (or bind by name) to the interfaces of,
-      the Work and Derivative Works thereof.
-
-      "Contribution" shall mean any work of authorship, including
-      the original version of the Work and any modifications or additions
-      to that Work or Derivative Works thereof, that is intentionally
-      submitted to Licensor for inclusion in the Work by the copyright owner
-      or by an individual or Legal Entity authorized to submit on behalf of
-      the copyright owner. For the purposes of this definition, "submitted"
-      means any form of electronic, verbal, or written communication sent
-      to the Licensor or its representatives, including but not limited to
-      communication on electronic mailing lists, source code control systems,
-      and issue tracking systems that are managed by, or on behalf of, the
-      Licensor for the purpose of discussing and improving the Work, but
-      excluding communication that is conspicuously marked or otherwise
-      designated in writing by the copyright owner as "Not a Contribution."
-
-      "Contributor" shall mean Licensor and any individual or Legal Entity
-      on behalf of whom a Contribution has been received by Licensor and
-      subsequently incorporated within the Work.
-
-   2. Grant of Copyright License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      copyright license to reproduce, prepare Derivative Works of,
-      publicly display, publicly perform, sublicense, and distribute the
-      Work and such Derivative Works in Source or Object form.
-
-   3. Grant of Patent License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      (except as stated in this section) patent license to make, have made,
-      use, offer to sell, sell, import, and otherwise transfer the Work,
-      where such license applies only to those patent claims licensable
-      by such Contributor that are necessarily infringed by their
-      Contribution(s) alone or by combination of their Contribution(s)
-      with the Work to which such Contribution(s) was submitted. If You
-      institute patent litigation against any entity (including a
-      cross-claim or counterclaim in a lawsuit) alleging that the Work
-      or a Contribution incorporated within the Work constitutes direct
-      or contributory patent infringement, then any patent licenses
-      granted to You under this License for that Work shall terminate
-      as of the date such litigation is filed.
-
-   4. Redistribution. You may reproduce and distribute copies of the
-      Work or Derivative Works thereof in any medium, with or without
-      modifications, and in Source or Object form, provided that You
-      meet the following conditions:
-
-      (a) You must give any other recipients of the Work or
-          Derivative Works a copy of this License; and
-
-      (b) You must cause any modified files to carry prominent notices
-          stating that You changed the files; and
-
-      (c) You must retain, in the Source form of any Derivative Works
-          that You distribute, all copyright, patent, trademark, and
-          attribution notices from the Source form of the Work,
-          excluding those notices that do not pertain to any part of
-          the Derivative Works; and
-
-      (d) If the Work includes a "NOTICE" text file as part of its
-          distribution, then any Derivative Works that You distribute must
-          include a readable copy of the attribution notices contained
-          within such NOTICE file, excluding those notices that do not
-          pertain to any part of the Derivative Works, in at least one
-          of the following places: within a NOTICE text file distributed
-          as part of the Derivative Works; within the Source form or
-          documentation, if provided along with the Derivative Works; or,
-          within a display generated by the Derivative Works, if and
-          wherever such third-party notices normally appear. The contents
-          of the NOTICE file are for informational purposes only and
-          do not modify the License. You may add Your own attribution
-          notices within Derivative Works that You distribute, alongside
-          or as an addendum to the NOTICE text from the Work, provided
-          that such additional attribution notices cannot be construed
-          as modifying the License.
-
-      You may add Your own copyright statement to Your modifications and
-      may provide additional or different license terms and conditions
-      for use, reproduction, or distribution of Your modifications, or
-      for any such Derivative Works as a whole, provided Your use,
-      reproduction, and distribution of the Work otherwise complies with
-      the conditions stated in this License.
-
-   5. Submission of Contributions. Unless You explicitly state otherwise,
-      any Contribution intentionally submitted for inclusion in the Work
-      by You to the Licensor shall be under the terms and conditions of
-      this License, without any additional terms or conditions.
-      Notwithstanding the above, nothing herein shall supersede or modify
-      the terms of any separate license agreement you may have executed
-      with Licensor regarding such Contributions.
-
-   6. Trademarks. This License does not grant permission to use the trade
-      names, trademarks, service marks, or product names of the Licensor,
-      except as required for reasonable and customary use in describing the
-      origin of the Work and reproducing the content of the NOTICE file.
-
-   7. Disclaimer of Warranty. Unless required by applicable law or
-      agreed to in writing, Licensor provides the Work (and each
-      Contributor provides its Contributions) on an "AS IS" BASIS,
-      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-      implied, including, without limitation, any warranties or conditions
-      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
-      PARTICULAR PURPOSE. You are solely responsible for determining the
-      appropriateness of using or redistributing the Work and assume any
-      risks associated with Your exercise of permissions under this License.
-
-   8. Limitation of Liability. In no event and under no legal theory,
-      whether in tort (including negligence), contract, or otherwise,
-      unless required by applicable law (such as deliberate and grossly
-      negligent acts) or agreed to in writing, shall any Contributor be
-      liable to You for damages, including any direct, indirect, special,
-      incidental, or consequential damages of any character arising as a
-      result of this License or out of the use or inability to use the
-      Work (including but not limited to damages for loss of goodwill,
-      work stoppage, computer failure or malfunction, or any and all
-      other commercial damages or losses), even if such Contributor
-      has been advised of the possibility of such damages.
-
-   9. Accepting Warranty or Additional Liability. While redistributing
-      the Work or Derivative Works thereof, You may choose to offer,
-      and charge a fee for, acceptance of support, warranty, indemnity,
-      or other liability obligations and/or rights consistent with this
-      License. However, in accepting such obligations, You may act only
-      on Your own behalf and on Your sole responsibility, not on behalf
-      of any other Contributor, and only if You agree to indemnify,
-      defend, and hold each Contributor harmless for any liability
-      incurred by, or claims asserted against, such Contributor by reason
-      of your accepting any such warranty or additional liability.
-
-   END OF TERMS AND CONDITIONS
diff --git a/libcopybit/c2d2.h b/libcopybit/c2d2.h
deleted file mode 100644
index 315a3ba..0000000
--- a/libcopybit/c2d2.h
+++ /dev/null
@@ -1,685 +0,0 @@
-/* Copyright (c) 2010-2013, The Linux Foundation. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- *       copyright notice, this list of conditions and the following
- *       disclaimer in the documentation and/or other materials provided
- *       with the distribution.
- *     * Neither the name of The Linux Foundation. nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-#ifndef __c2d2_h_
-#define __c2d2_h_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifndef C2D_API
-#define C2D_API /* define API export as needed */
-#endif
-#if !defined(int32) && !defined(_INT32_DEFINED)
-typedef int                     int32;
-#define _INT32_DEFINED
-#endif
-#if !defined(uint32) && !defined(_UINT32_DEFINED)
-typedef unsigned int            uint32;
-#define _UINT32_DEFINED
-#endif
-
-/*****************************************************************************/
-/*********************** Blit definitions *****************************/
-/*****************************************************************************/
-
-/* Status codes, returned by any blit function */
-typedef enum {
-    C2D_STATUS_OK              = 0,
-    C2D_STATUS_NOT_SUPPORTED   = 1,
-    C2D_STATUS_OUT_OF_MEMORY   = 2,
-    C2D_STATUS_INVALID_PARAM   = 3,
-    C2D_STATUS_SURFACE_IN_USE  = 4,
-} C2D_STATUS;
-
-
-/* Definitions of color format modes, used together with color formats */
-typedef enum {
-    C2D_FORMAT_PACK_INTO_32BIT   = (1 <<  8), /* pack into dword if set */
-    C2D_FORMAT_SWAP_ENDIANNESS   = (1 <<  9), /* swaps the order */
-    C2D_FORMAT_LINEAR_SPACE      = (1 << 10), /* linear color space */
-    C2D_FORMAT_PREMULTIPLIED     = (1 << 11), /* alpha premultiplied */
-    C2D_FORMAT_INVERT_ALPHA      = (1 << 12), /* inverts alpha */
-    C2D_FORMAT_DISABLE_ALPHA     = (1 << 13), /* disables alpha */
-    C2D_FORMAT_INTERLACED        = (1 << 14), /* YUV line-interlaced */
-    C2D_FORMAT_TRANSPARENT       = (1 << 15), /* YUV 1-bit alpha in Y */
-    C2D_FORMAT_MACROTILED        = (1 << 16), /* tiled in macro level */
-    C2D_FORMAT_TILED_4x4         = (1 << 17), /* 4x4 tiled format */
-    C2D_FORMAT_SWAP_RB           = (1 << 18), /* Swap R & B color components */
-    C2D_FORMAT_UBWC_COMPRESSED   = (1 << 23), /* UBWC compressed format */
-} C2D_FORMAT_MODE;
-
-/* Definitions of supported RGB formats, used in C2D_RGB_SURFACE_DEF.
- * The bits of each color channel are packed into a machine word
- * representing a single pixel from left to right (MSB to LSB) in the
- * order indicated by format name. For the sub-byte formats the pixels
- * are packed into bytes from left to right (MSbit to LSBit).
- * If the C2D_FORMAT_PACK_INTO_32BIT bit is set, the minimal
- * machine word used for pixel storage is 32-bit and the whole word
- * is reversed if endianness is swapped.
- * If the C2D_FORMAT_SWAP_ENDIANNESS bit is set, the order within a
- * minimal machine word representing a pixel
- * is reversed for both sub-byte and multi-byte formats.
- * If the C2D_FORMAT_LINEAR_SPACE bit is set, the color space of
- * the formats below is considered linear, if applicable.
- * If the C2D_FORMAT_PREMULTIPLIED bit is set, the color channels
- * are premultiplied with the alpha, if applicable.
- * If the C2D_FORMAT_INVERT_ALPHA bit is set, the alpha interpretation
- * is inverted: 0 - opaque, 1 - transparent, if applicable.
- * If the C2D_FORMAT_DISABLE_ALPHA bit is set, the alpha channel serves
- * as a placeholder and is ignored during blit, if applicable.
- * If the C2D_FORMAT_MACROTILED bit is set, the surface is in the
- * tiled format : 64x32 for 8bpp, 32x32 for 16bpp formats  */
-typedef enum {
-    C2D_COLOR_FORMAT_1            = 0,   /* 1-bit alpha/color expansion */
-
-    C2D_COLOR_FORMAT_2_PALETTE    = 1,   /* 2-bit indices for palette */
-    C2D_COLOR_FORMAT_4_PALETTE    = 2,   /* 4-bit indices for palette */
-    C2D_COLOR_FORMAT_8_PALETTE    = 3,   /* 8-bit indices for palette */
-
-    C2D_COLOR_FORMAT_2_L          = 4,   /* 2-bit grayscale */
-    C2D_COLOR_FORMAT_4_L          = 5,   /* 4-bit grayscale */
-    C2D_COLOR_FORMAT_8_L          = 6,   /* 8-bit grayscale */
-
-    C2D_COLOR_FORMAT_2_A          = 7,   /* 2-bit alpha only */
-    C2D_COLOR_FORMAT_4_A          = 8,   /* 4-bit alpha only */
-    C2D_COLOR_FORMAT_8_A          = 9,   /* 8-bit alpha only */
-
-    C2D_COLOR_FORMAT_444_RGB      = 10,  /* 12-bit colors */
-    C2D_COLOR_FORMAT_565_RGB      = 11,  /* 16-bit colors */
-    C2D_COLOR_FORMAT_888_RGB      = 12,  /* 24-bit colors */
-
-    C2D_COLOR_FORMAT_1555_ARGB    = 13,  /* 16-bit colors (1-bit alpha) */
-    C2D_COLOR_FORMAT_4444_ARGB    = 14,  /* 16-bit colors (4-bit alpha) */
-    C2D_COLOR_FORMAT_8565_ARGB    = 15,  /* 24-bit colors (8-bit alpha) */
-    C2D_COLOR_FORMAT_8888_ARGB    = 16,  /* 32-bit colors (8-bit alpha) */
-
-    C2D_COLOR_FORMAT_5551_RGBA    = 17,  /* 16-bit colors (1-bit alpha) */
-    C2D_COLOR_FORMAT_4444_RGBA    = 18,  /* 16-bit colors (4-bit alpha) */
-    C2D_COLOR_FORMAT_5658_RGBA    = 19,  /* 24-bit colors (8-bit alpha) */
-    C2D_COLOR_FORMAT_8888_RGBA    = 20,  /* 32-bit colors (8-bit alpha) */
-
-    /* derived RGB color formats (base format + mode bits) */
-
-} C2D_RGB_FORMAT;
-
-/* Definitions of supported YUV formats, used in C2D_YUV_SURFACE_DEF.
- * Each of Y,U,V channels usually takes 1 byte and therefore is
- * individually addressable. The definitions below show how Y,U,V
- * channels are packed into macropixels for each particular format.
- * The order is from left (smaller byte addresses) to right (larger
- * byte addresses). The first three digits (4xx) denote the chroma
- * subsampling in standard YUV notation. The digits in the macropixel
- * denote that the whole block (from the previous digit or from the
- * beginning) has to be repeated the number of times. Underscores
- * between Y,U,V channels are used to describe separate planes for
- * planar YUV formats. Formats are mapped to numbers so that future
- * versions with various YUV permutations are easy to add.
- * If the C2D_FORMAT_INTERLACED bit is set, the line order is
- * interlaced: 0,2,4,...1,3,5... if applicable.
- * If the C2D_FORMAT_TRANSPARENT bit is set, the least significant
- * bit of Y channel serves as alpha: 0 - transparent, 1 - opaque. */
-typedef enum {
-    C2D_COLOR_FORMAT_411_YYUYYV   = 110, /* packed, 12-bit         */
-    C2D_COLOR_FORMAT_411_YUYYVY   = 111, /* packed, 12-bit         */
-    C2D_COLOR_FORMAT_411_UYYVYY   = 112, /* packed, 12-bit, "Y411" */
-    C2D_COLOR_FORMAT_411_YUYV2Y4  = 116, /* packed, 12-bit         */
-    C2D_COLOR_FORMAT_411_UYVY2Y4  = 117, /* packed, 12-bit, "Y41P" */
-
-    C2D_COLOR_FORMAT_422_YUYV     = 120, /* packed, 16-bit, "YUY2" */
-    C2D_COLOR_FORMAT_422_UYVY     = 121, /* packed, 16-bit, "UYVY" */
-    C2D_COLOR_FORMAT_422_YVYU     = 122, /* packed, 16-bit, "YVYU" */
-    C2D_COLOR_FORMAT_422_VYUY     = 123, /* packed, 16-bit         */
-
-    C2D_COLOR_FORMAT_444_YUV      = 130, /* packed, 24-bit         */
-    C2D_COLOR_FORMAT_444_UYV      = 131, /* packed, 24-bit, "IYU2" */
-    C2D_COLOR_FORMAT_444_AYUV     = 136, /* packed, 24-bit, "AYUV" */
-
-    C2D_COLOR_FORMAT_410_Y_UV     = 150, /* planar, Y + interleaved UV */
-    C2D_COLOR_FORMAT_411_Y_UV     = 151, /* planar, Y + interleaved UV */
-    C2D_COLOR_FORMAT_420_Y_UV     = 152, /* planar, Y + interleaved UV */
-    C2D_COLOR_FORMAT_422_Y_UV     = 153, /* planar, Y + interleaved UV */
-    C2D_COLOR_FORMAT_444_Y_UV     = 154, /* planar, Y + interleaved UV */
-
-    C2D_COLOR_FORMAT_410_Y_VU     = 160, /* planar, Y + interleaved VU */
-    C2D_COLOR_FORMAT_411_Y_VU     = 161, /* planar, Y + interleaved VU */
-    C2D_COLOR_FORMAT_420_Y_VU     = 162, /* planar, Y + interleaved VU */
-    C2D_COLOR_FORMAT_422_Y_VU     = 163, /* planar, Y + interleaved VU */
-    C2D_COLOR_FORMAT_444_Y_VU     = 164, /* planar, Y + interleaved VU */
-
-    C2D_COLOR_FORMAT_410_Y_U_V    = 170, /* planar, Y + U + V separate */
-    C2D_COLOR_FORMAT_411_Y_U_V    = 171, /* planar, Y + U + V separate */
-    C2D_COLOR_FORMAT_420_Y_V_U    = 172, /* planar, Y + V + U separate */
-    C2D_COLOR_FORMAT_420_Y_U_V    = 173, /* planar, Y + U + V separate */
-    C2D_COLOR_FORMAT_422_Y_U_V    = 174, /* planar, Y + U + V separate */
-    C2D_COLOR_FORMAT_444_Y_U_V    = 175, /* planar, Y + U + V separate */
-
-    C2D_COLOR_FORMAT_800_Y        = 190, /* planar, Y only, grayscale */
-
-    /* derived YUV color formats (base format + mode bits), FOURCC */
-
-    C2D_COLOR_FORMAT_411_Y411     = 112,
-    C2D_COLOR_FORMAT_411_Y41P     = 117,
-    C2D_COLOR_FORMAT_411_IY41     = 117 | (1 << 14),
-    C2D_COLOR_FORMAT_411_Y41T     = 117 | (1 << 15),
-
-    C2D_COLOR_FORMAT_422_YUY2     = 120,
-    C2D_COLOR_FORMAT_422_IUYV     = 121 | (1 << 14),
-    C2D_COLOR_FORMAT_422_Y42T     = 121 | (1 << 15),
-    C2D_COLOR_FORMAT_444_IYU2     = 131,
-
-    C2D_COLOR_FORMAT_420_NV12     = 152,
-    C2D_COLOR_FORMAT_420_NV21     = 162,
-
-    C2D_COLOR_FORMAT_410_YUV9     = 170,
-    C2D_COLOR_FORMAT_410_YVU9     = 170,
-    C2D_COLOR_FORMAT_411_Y41B     = 171,
-    C2D_COLOR_FORMAT_420_YV12     = 172,
-    C2D_COLOR_FORMAT_420_IYUV     = 173,
-    C2D_COLOR_FORMAT_420_I420     = 173,
-    C2D_COLOR_FORMAT_422_YV16     = 174,
-    C2D_COLOR_FORMAT_422_Y42B     = 174,
-
-    C2D_COLOR_FORMAT_800_Y800     = 190,
-
-} C2D_YUV_FORMAT;
-
-
-/* Configuration bits, used in the config_mask field of C2D_OBJECT struct */
-typedef enum {
-    C2D_SOURCE_RECT_BIT      = (1 <<  0), /* enables source_rect field */
-    C2D_MIRROR_H_BIT         = (1 <<  1), /* enables horizontal flipping */
-    C2D_MIRROR_V_BIT         = (1 <<  2), /* enables vertical flipping */
-    C2D_SOURCE_TILE_BIT      = (1 <<  3), /* enables source surface tiling */
-    C2D_TARGET_RECT_BIT      = (1 <<  4), /* enables target_rect field */
-    C2D_ROTATE_BIT           = (1 <<  5), /* enables all rotation fields */
-    C2D_SCISSOR_RECT_BIT     = (1 <<  6), /* enables scissor_rect field */
-    C2D_MASK_SURFACE_BIT     = (1 <<  7), /* enables mask_surface_id field */
-    C2D_MASK_ALIGN_BIT       = (1 <<  8), /* aligns mask to source_rect */
-    C2D_MASK_SCALE_BIT       = (1 <<  9), /* enables mask surface scaling */
-    C2D_MASK_TILE_BIT        = (1 << 10), /* enables mask surface tiling */
-    C2D_GLOBAL_ALPHA_BIT     = (1 << 11), /* enables global_alpha field */
-    C2D_COLOR_KEY_BIT        = (1 << 12), /* enables color_key field */
-    C2D_NO_PIXEL_ALPHA_BIT   = (1 << 13), /* disables source alpha channel */
-    C2D_NO_BILINEAR_BIT      = (1 << 14), /* disables bilinear on scaling */
-    C2D_NO_ANTIALIASING_BIT  = (1 << 15), /* disables antialiasing on edges */
-    C2D_DRAW_LINE_BIT        = (1 << 16), /* enables line drawing with source rectangle */
-    C2D_DRAW_LINE_NOLAST     = (1 << 17), /* disable last pixel draw for line */
-} C2D_SOURCE_CONFIG;
-
-
-/* Target configuration bits, defines rotation + mirroring.
- * Mirror is applied prior to rotation if enabled. */
-typedef enum {
-    C2D_TARGET_MIRROR_H        = (1 << 0), /* horizontal flip */
-    C2D_TARGET_MIRROR_V        = (1 << 1), /* vertical flip */
-    C2D_TARGET_ROTATE_0        = (0 << 2), /* no rotation */
-    C2D_TARGET_ROTATE_90       = (1 << 2), /* 90 degree rotation */
-    C2D_TARGET_ROTATE_180      = (2 << 2), /* 180 degree rotation */
-    C2D_TARGET_ROTATE_270      = (3 << 2), /* 270 degree rotation, 90 + 180 */
-    C2D_TARGET_MASK_ALIGN      = (1 << 4), /* aligns mask to target scissor */
-    C2D_TARGET_MASK_SCALE      = (1 << 5), /* enables mask scaling */
-    C2D_TARGET_MASK_TILE       = (1 << 6), /* enables mask tiling */
-    C2D_TARGET_COLOR_KEY       = (1 << 7), /* enables target_color_key */
-    C2D_TARGET_NO_PIXEL_ALPHA  = (1 << 8), /* disables target alpha channel */
-} C2D_TARGET_CONFIG;
-
-#define C2D_TARGET_ROTATION_MASK  (C2D_TARGET_ROTATE_90*3)
-
-/* Additional blend modes, can be used with both source and target configs.
-   If none of the below is set, the default "SRC over DST" is applied. */
-typedef enum {
-    C2D_ALPHA_BLEND_SRC_OVER   = (0  << 20), /* Default, Porter-Duff "SRC over DST" */
-    C2D_ALPHA_BLEND_SRC        = (1  << 20), /* Porter-Duff "SRC" */
-    C2D_ALPHA_BLEND_SRC_IN     = (2  << 20), /* Porter-Duff "SRC in DST" */
-    C2D_ALPHA_BLEND_DST_IN     = (3  << 20), /* Porter-Duff "DST in SRC" */
-    C2D_ALPHA_BLEND_SRC_OUT    = (4  << 20), /* Porter-Duff "SRC out DST" */
-    C2D_ALPHA_BLEND_DST_OUT    = (5  << 20), /* Porter-Duff "DST out SRC" */
-    C2D_ALPHA_BLEND_DST_OVER   = (6  << 20), /* Porter-Duff "DST over SRC" */
-    C2D_ALPHA_BLEND_SRC_ATOP   = (7  << 20), /* Porter-Duff "SRC ATOP" */
-    C2D_ALPHA_BLEND_DST_ATOP   = (8  << 20), /* Porter-Duff "DST ATOP" */
-    C2D_ALPHA_BLEND_XOR        = (9  << 20), /* Xor */
-    C2D_ALPHA_BLEND_MULTIPLY   = (10 << 20), /* OpenVG "MULTIPLY" */
-    C2D_ALPHA_BLEND_SCREEN     = (11 << 20), /* OpenVG "SCREEN" */
-    C2D_ALPHA_BLEND_DARKEN     = (12 << 20), /* OpenVG "DARKEN" */
-    C2D_ALPHA_BLEND_LIGHTEN    = (13 << 20), /* OpenVG "LIGHTEN" */
-    C2D_ALPHA_BLEND_ADDITIVE   = (14 << 20), /* OpenVG "ADDITIVE" */
-    C2D_ALPHA_BLEND_DIRECT     = (15 << 20), /* Direct alpha blitting */
-    C2D_ALPHA_BLEND_INVERTC    = (16 << 20), /* Invert color */
-    C2D_ALPHA_BLEND_NONE       = (1  << 25), /* disables alpha blending */
-} C2D_ALPHA_BLEND_MODE;
-
-/* Configuration bits, used in the config_mask field of C2D_OBJECT struct */
-typedef enum {
-    C2D_OVERRIDE_GLOBAL_TARGET_ROTATE_CONFIG = (1 << 27), /* Overrides TARGET Config */
-    C2D_OVERRIDE_TARGET_ROTATE_0             = (0 << 28), /* no rotation             */
-    C2D_OVERRIDE_TARGET_ROTATE_90            = (1 << 28), /* 90 degree rotation      */
-    C2D_OVERRIDE_TARGET_ROTATE_180           = (2 << 28), /* 180 degree rotation     */
-    C2D_OVERRIDE_TARGET_ROTATE_270           = (3 << 28), /* 270 degree rotation     */
-} C2D_SOURCE_TARGET_CONFIG;
-
-#define C2D_OVERRIDE_SOURCE_CONFIG_TARGET_ROTATION_SHIFT_MASK  28
-#define C2D_OVERRIDE_TARGET_CONFIG_TARGET_ROTATION_SHIFT_MASK  2
-
-
-/* Surface caps enumeration */
-typedef enum {
-    C2D_SOURCE          = (1 << 0), /* allows to use as a source */
-    C2D_TARGET          = (1 << 1), /* allows to use as a target */
-    C2D_MASK            = (1 << 2), /* allows to use as a mask */
-    C2D_PALETTE         = (1 << 3), /* allows to use as a palette */
-} C2D_SURFACE_BITS;
-
-/* Surface type enumeration */
-typedef enum {
-    C2D_SURFACE_RGB_HOST        = 1, /* Host memory RGB surface */
-    C2D_SURFACE_RGB_EXT         = 2, /* External memory RGB surface */
-    C2D_SURFACE_YUV_HOST        = 3, /* Host memory YUV surface */
-    C2D_SURFACE_YUV_EXT         = 4, /* External memory YUV surface */
-    C2D_SURFACE_WITH_PHYS       = (1<<3), /* physical address already mapped */
-                                        /* this bit is valid with HOST types */
-    C2D_SURFACE_WITH_PHYS_DUMMY = (1<<4), /* physical address already mapped */
-                                        /* this bit is valid with HOST types */
-} C2D_SURFACE_TYPE;
-
-/* Structure for registering a RGB buffer as a blit surface */
-typedef struct {
-    uint32 format;   /* RGB color format plus additional mode bits */
-    uint32 width;    /* defines width in pixels */
-    uint32 height;   /* defines height in pixels */
-    void  *buffer;   /* pointer to the RGB buffer */
-    void  *phys;     /* physical address */
-    int32  stride;   /* defines stride in bytes, negative stride is allowed */
-} C2D_RGB_SURFACE_DEF;
-
-/* Structure for registering a YUV plane(s) as a blit surface */
-typedef struct {
-    uint32 format;   /* YUV color format plus additional mode bits */
-    uint32 width;    /* defines width in pixels */
-    uint32 height;   /* defines height in pixels */
-    void  *plane0;  /* holds the whole buffer if YUV format is not planar */
-    void  *phys0;   /* physical address */
-    int32  stride0; /* stride in bytes if YUV format is not planar */
-    void  *plane1;  /* holds UV or VU plane for planar interleaved */
-    void  *phys1;   /* physical address */
-    int32  stride1; /* stride for UV or VU plane for planar interleaved */
-    void  *plane2;  /* holds the 3. plane, ignored if YUV format is not planar */
-    void  *phys2;    /* physical address */
-    int32  stride2; /* stride for the 3. plane, ignored if YUV format is not planar */
-} C2D_YUV_SURFACE_DEF;
-
-
-/* Rectangle definition */
-typedef struct {
-    int32 x;        /* upper-left x */
-    int32 y;        /* upper-left y */
-    int32 width;    /* width */
-    int32 height;   /* height */
-} C2D_RECT;
-
-/* C2D_OBJECT encapsulates the blit parameters for a source surface.
- * The fg_color defines color in target format for bits equal to 1
- * in the source C2D_COLOR_FORMAT_1 format. It also defines rendering
- * color for all alpha-only source formats. If the surface_id is 0
- * the fg_color defines a constant fill color used instead of the surface.
- * The bg_color defines color in target format for bits equal to 0
- * in the source C2D_COLOR_FORMAT_1 format, otherwise both are ignored.
- * The palette_id is used for all palette source formats, otherwise ignored.
-
- * The source_rect first defines the content of the source surface,
- * it is then horizontally/vertically flipped if C2D_MIRROR_*_BIT is set,
- * then scaled with bilinear interpolation to exactly fit target_rect
- * or repeated across target_rect if C2D_SOURCE_TILE_BIT is set,
- * target_rect is then rotated clockwise by an arbitrary angle in degrees
- * around the rot_orig_x/y, defined relative to target_rect's top left point,
- * and then clipped to scissor_rect defined in target coordinate system.
-
- * Finally alpha blending is applied before pixels get written into the target.
- * Surface's pixel alpha is combined with mask alpha and with global alpha.
- * Mask surface follows all transformations applied to the source surface.
- * Source color key defines transparent color, applied together with alpha. */
-typedef struct C2D_OBJECT_STR {
-    uint32 surface_id;      /* source surface */
-
-    uint32 fg_color;        /* foreground color */
-    uint32 bg_color;        /* background color */
-    uint32 palette_id;      /* one-dimensional horizontal palette surface */
-
-    uint32 config_mask;     /* defines which fields below are enabled */
-
-    C2D_RECT source_rect;  /* region of the source surface,   16.16 fp */
-    C2D_RECT target_rect;  /* position and scaling in target, 16.16 fp */
-
-    int32 rot_orig_x;       /* rotation origin relative to target_rect's... */
-    int32 rot_orig_y;       /* ...top left point,     both are 16.16 fp */
-    int32 rotation;         /* clock-wise rotation in degrees, 16.16 fp */
-
-    C2D_RECT scissor_rect; /* defines the clip rectangle in target surface */
-
-    uint32 mask_surface_id; /* source alpha-mask surface */
-    uint32 global_alpha;    /* 0 = fully transparent, 255 = fully opaque */
-    uint32 color_key;       /* transparent color for the source surface */
-
-    struct C2D_OBJECT_STR *next; /* pointer to the next object or NULL */
-} C2D_OBJECT;
-
-/* Configuration bits, driver capabilities used by 2Dapplications */
-typedef enum {
-    C2D_DRIVER_SUPPORTS_GLOBAL_ALPHA_OP           = (1 << 0),
-    C2D_DRIVER_SUPPORTS_TILE_OP                   = (1 << 1),
-    C2D_DRIVER_SUPPORTS_COLOR_KEY_OP              = (1 << 2),
-    C2D_DRIVER_SUPPORTS_NO_PIXEL_ALPHA_OP         = (1 << 3),
-    C2D_DRIVER_SUPPORTS_TARGET_ROTATE_OP          = (1 << 4),
-    C2D_DRIVER_SUPPORTS_ANTI_ALIASING_OP          = (1 << 5), /* antialiasing */
-    C2D_DRIVER_SUPPORTS_BILINEAR_FILTER_OP        = (1 << 6),
-    C2D_DRIVER_SUPPORTS_LENS_CORRECTION_OP        = (1 << 7),
-    C2D_DRIVER_SUPPORTS_OVERRIDE_TARGET_ROTATE_OP = (1 << 8),
-    C2D_DRIVER_SUPPORTS_SHADER_BLOB_OP            = (1 << 9),
-    C2D_DRIVER_SUPPORTS_MASK_SURFACE_OP           = (1 << 10), /* mask surface */
-    C2D_DRIVER_SUPPORTS_MIRROR_H_OP               = (1 << 11), /* horizontal flip */
-    C2D_DRIVER_SUPPORTS_MIRROR_V_OP               = (1 << 12), /* vertical flip */
-    C2D_DRIVER_SUPPORTS_SCISSOR_RECT_OP           = (1 << 13),
-    C2D_DRIVER_SUPPORTS_SOURCE_RECT_OP            = (1 << 14),
-    C2D_DRIVER_SUPPORTS_TARGET_RECT_OP            = (1 << 15),
-    C2D_DRIVER_SUPPORTS_ROTATE_OP                 = (1 << 16), /* all rotations */
-    C2D_DRIVER_SUPPORTS_FLUSH_WITH_FENCE_FD_OP    = (1 << 17), /* all rotations */
-    C2D_DRIVER_SUPPORTS_UBWC_COMPRESSED_OP        = (1 << 18), /* UBWC Compression */
-    C2D_DRIVER_SUPPORTS_ALL_CAPABILITIES_OP       = ((0xFFFFFFFF) >> (31 - 18)) /* mask for all capabilities supported */
-} C2D_DRIVER_CAPABILITIES;
-
-/* 2D driver workaround bits used by the 2D applications */
-typedef enum {
-    C2D_DRIVER_WORKAROUND_NONE  = 0, /* NO workaround */
-    C2D_DRIVER_WORKAROUND_SWAP_UV_FOR_YUV_TARGET  = (1 << 0), /* Swap UV when this flag set */
-} C2D_DRIVER_WORKAROUND;
-
-/* Structure to query Driver information */
-typedef struct {
-    uint32 capabilities_mask;
-    uint32 workaround_mask;
-    uint32 reserved1;
-    uint32 reserved2;
-    uint32 reserved3;
-} C2D_DRIVER_INFO;
-
-/* Structure to query Driver information */
-typedef struct {
-    uint32          max_surface_template_needed;
-    uint32          reserved1;
-    uint32          reserved2;
-    uint32          reserved3;
-} C2D_DRIVER_SETUP_INFO;
-
-/*****************************************************************************/
-/**************************** C2D API 2.0 ********************************/
-/*****************************************************************************/
-
-/******************************************************************************
- * Functions to create/destroy surfaces */
-
-/* Creates a generic blit surface according to its type.
- * Pass a combination of desired surface bits according to planned usage.
- * Accepted values for surface_bits may include bits from C2D_SURFACE_BITS,
- * and also from C2D_DISPLAY for compatibility with HW display controller.
- * For host memory types the memory is preallocated outside the API
- * and should remain valid until surface is destroyed.
- * For external memory types the memory is allocated within API.
- * On success, the non-zero surface identifier is returned.
- * All numbers greater that 0 are valid surface identifiers, 0 is invalid.
-
- * Host memory RGB surface:
- * surface_type       = C2D_SURFACE_RGB_HOST
- * surface_definition = C2D_RGB_SURFACE_DEF
- * all fields in definition structure should be set
-
- * External memory RGB surface:
- * surface_type       = C2D_SURFACE_RGB_EXT
- * surface_definition = C2D_RGB_SURFACE_DEF
- * buffer field in definition structure is ignored
-
- * Host memory YUV surface:
- * surface_type       = C2D_SURFACE_YUV_HOST
- * surface_definition = C2D_YUV_SURFACE_DEF
- * one or all plane and stride fields in definition structure
- * should be set depending on whether the format is planar or not
-
- * External memory YUV surface:
- * surface_type       = C2D_SURFACE_YUV_EXT
- * surface_definition = C2D_YUV_SURFACE_DEF
- * all plane and stride fields in definition structure are ignored */
-C2D_API C2D_STATUS c2dCreateSurface( uint32 *surface_id,
-                         uint32 surface_bits,
-                         C2D_SURFACE_TYPE surface_type,
-                         void *surface_definition );
-
-/* Requests properties of the specified surface. */
-C2D_API C2D_STATUS c2dQuerySurface( uint32 surface_id,
-                         uint32 *surface_bits,
-                         C2D_SURFACE_TYPE *surface_type,
-                         uint32 *width, uint32 *height,
-                         uint32 *format );
-
-/* Destroys a generic blit surface.
- * For external memory surfaces also deallocates the memory.
- * It is safe to free any external resources associated with a given
- * surface on c2dCreateSurface call after this function returns. */
-C2D_API C2D_STATUS c2dDestroySurface( uint32 surface_id );
-
-
-/******************************************************************************
- * Functions to modify/exchange surface data */
-
-/* The format of fill_color is the same as color format being used
- * for specified surface. If fill_rect is NULL the whole surface is filled.
- * Alpha-blending is not performed while filling.
- * The operation is complete when function returns. */
-C2D_API C2D_STATUS c2dFillSurface( uint32 surface_id,
-                         uint32 fill_color,
-                         C2D_RECT *fill_rect );
-
-/* Writes data located in host memory into the specified surface.
- * The chunk of host memory is identified with surface_type and
- * surface_definition, no surface registration needed in this case.
- * Only C2D_SURFACE_RGB_HOST, C2D_SURFACE_YUV_HOST are accepted.
- * If only part of the host memory buffer should be loaded, it should
- * be configured in surface_definition using width, height and stride.
- * The x and y are defined in target surface coordinate space.
- * Color conversion has to be done, if color formats differ.
- * Alpha-blending is not performed while writing.
- * The operation is complete when function returns. */
-C2D_API C2D_STATUS c2dWriteSurface( uint32 surface_id,
-                         C2D_SURFACE_TYPE surface_type,
-                         void *surface_definition,
-                         int32 x, int32 y );
-
-/* Reads data from the specified surface into the host memory.
- * The chunk of host memory is identified with surface_type and
- * surface_definition, no surface registration needed in this case.
- * Only C2D_SURFACE_RGB_HOST, C2D_SURFACE_YUV_HOST are accepted.
- * If only part of the surface should be read, it should
- * be configured in surface_definition using width, height and stride.
- * The x and y are defined in source surface coordinate space.
- * Color conversion has to be done, if color formats differ.
- * Alpha-blending is not performed while reading.
- * The operation is complete when function returns. */
-C2D_API C2D_STATUS c2dReadSurface( uint32 surface_id,
-                         C2D_SURFACE_TYPE surface_type,
-                         void *surface_definition,
-                         int32 x, int32 y );
-
-/* Notifies c2d imlementation that surface has been updated from outside the API,
- * if updated_rect is NULL then the whole surface has been updated. */
-C2D_API C2D_STATUS c2dSurfaceUpdated( uint32 surface_id,
-                         C2D_RECT *updated_rect );
-
-/* Updates surface information.
- * Could be called only for host surfaces set with parameter "C2D_SURFACE_WITH_PHYS".
- * Count for surface planes have to be same than for already allocated surface */
-C2D_API C2D_STATUS c2dUpdateSurface( uint32 surface_id,
-                         uint32 surface_bits,
-                         C2D_SURFACE_TYPE surface_type,
-                         void *surface_definition );
-
-/******************************************************************************
- * Functions to do actual blit */
-
-/* Draw a list of blit objects into the given target.
- * The target_config is a bitwise OR of values from C2D_TARGET_CONFIG.
- * The target transformation creates the effect that target surface
- * is transformed before the blit and then transformed back
- * after blit, however no physical target transform is performed.
- * The objects_list is a linked list of blit objects, no more
- * than num_objects is drawn from the given list.
- * If num_objects is 0, the whole list is drawn.
- * The blit is not guaranteed to complete after function returns. */
-C2D_API C2D_STATUS c2dDraw( uint32 target_id,
-                         uint32 target_config, C2D_RECT *target_scissor,
-                         uint32 target_mask_id, uint32 target_color_key,
-                         C2D_OBJECT *objects_list, uint32 num_objects );
-
-
-/* timstamp set in the blit commands flush */
-typedef void*                   c2d_ts_handle;
-
-/* Forces any pending blit to complete for a given target.
- * Non-blocking. All input surfaces for this target except those
- * which are shared with other targets are expected to be immediately
- * writable after client has been waiting returned timestamp with
- * c2dWaitTimestamp funtion or c2dFinish has been called for same target */
-C2D_API C2D_STATUS c2dFlush( uint32 target_id, c2d_ts_handle *timestamp);
-
-
-/* Waits the pending timestamp */
-C2D_API C2D_STATUS c2dWaitTimestamp( c2d_ts_handle timestamp );
-
-
-/* Forces any pending blit to complete for a given target.
- * Blocking version, returns when blit is done.
- * All input surfaces for this target except those which are shared with
- * other targets are expected to be immediately
- * writable after this function returns. */
-C2D_API C2D_STATUS c2dFinish( uint32 target_id );
-
-
-/*****************************************************************************/
-/****************************** Display API **********************************/
-/*****************************************************************************/
-
-
-/* Display input enumeration */
-typedef enum {
-    C2D_DISPLAY_INPUT_0      = 0,       /*!< default input */
-    C2D_DISPLAY_INPUT_1      = (1<<16), /*!< Overlay 1     */
-    C2D_DISPLAY_INPUT_2      = (1<<17), /*!< Overlay 2...    */
-} C2D_DISPLAY_INPUT;
-
-
-/******************************************************************************
- * Functions for display output. */
-
-/* Functionality described in this section is optional and is
- * provided only for the cases when blit HW
- * is tightly bound to the display controller. */
-
-/* Display enumeration, may also be used in surface caps */
-typedef enum {
-    C2D_DISPLAY_MAIN         = (1 << 10), /* main display */
-    C2D_DISPLAY_SECONDARY    = (1 << 11), /* secondary display */
-    C2D_DISPLAY_TV_OUT       = (1 << 12), /* tv-out */
-} C2D_DISPLAY;
-
-/* Display window enumeration */
-typedef enum {
-    C2D_DISPLAY_OVERLAY      = C2D_DISPLAY_INPUT_1, /*!< Overlay window bit. This defines display input.
-                                                When defined the surface is set on the overlay window
-                                                otherwise the surface is set on the background window. */
-} C2D_DISPLAY_WINDOW;                    /*!< Window bit set with display parameter */
-
-
-/* Display update modes */
-typedef enum {
-    C2D_DISPLAY_MODE_TEAR_SYNC   = (1 << 0), /* enables tearing sync */
-    C2D_DISPLAY_MODE_SURF_REMOVE = (1 << 1), /* Remove surface from given display + input */
-} C2D_DISPLAY_MODE;
-
-
-/* Sets the given surface as a current display front buffer.
- * Several displays can be specified as an output if supported.
- * Still only one input can be specified at a time fro display/displays.
- * The surface remains shown until it gets replaced with another one. */
-C2D_API C2D_STATUS c2dDisplaySetSurface( uint32 display,
-                         uint32 surface_id, uint32 mode );
-
-/* Returns the current surface for a particular display.
- * Only one display can be specified at a time.
- * The latest surface set with compDisplaySetSurface or
- * the default pre-allocated surface is returned. */
-C2D_API C2D_STATUS c2dDisplayGetSurface( uint32 display,
-                         uint32 *surface_id );
-
-/* Returns the properties for a particular display.
- * Only one display can be specified at a time. */
-C2D_API C2D_STATUS c2dDisplayGetProperties( uint32 display,
-                         uint32 *width, uint32 *height,
-                         uint32 *format );
-
-/* Sets the properties for a particular display input.
- * Only one display + input can be specified at a time.
- * C2D_OBJECT used to set input rect(target rect),
- * blending operations, rotation...etc for display source */
-C2D_API C2D_STATUS c2dDisplaySetObject( uint32 display,
-                         uint32 target_config, uint32 target_color_key,
-                         C2D_OBJECT * c2dObject, uint32 mode);
-
-/* allows user to map a memory region to the gpu. only supported on linux
- * mem_fd is the fd of the memory region, hostptr is the host pointer to the region,
- * len and offset are the size and offset of the memory.
- * flags is one of the memory types supported by gsl
- * gpaddr is passed by refernce back to the user
- */
-C2D_API C2D_STATUS c2dMapAddr ( int mem_fd, void * hostptr, uint32 len, uint32 offset, uint32 flags, void ** gpuaddr);
-
-/* allows user to unmap memory region mapped by c2dMapAddr.
- * gpaddr is the gpuaddr to unmap */
-C2D_API C2D_STATUS c2dUnMapAddr (void * gpuaddr);
-
-/* allows user to query driver capabilities.
- * driver_info is the information about driver */
-C2D_API C2D_STATUS c2dGetDriverCapabilities( C2D_DRIVER_INFO * driver_info);
-
-/* create a fence fd for the timestamp */
-C2D_API C2D_STATUS c2dCreateFenceFD( uint32 target_id, c2d_ts_handle timestamp, int32 *fd);
-
-/*****************************************************************************/
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __c2d2_h_ */
diff --git a/libcopybit/copybit.cpp b/libcopybit/copybit.cpp
deleted file mode 100644
index bd49edc..0000000
--- a/libcopybit/copybit.cpp
+++ /dev/null
@@ -1,794 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- * Copyright (c) 2010 - 2014, The Linux Foundation. All rights reserved.
- *
- * Not a Contribution, Apache license notifications and license are retained
- * for attribution purposes only.
- *
- * 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 <log/log.h>
-
-#include <linux/msm_mdp.h>
-#include <linux/fb.h>
-
-#include <stdint.h>
-#include <string.h>
-#include <unistd.h>
-#include <errno.h>
-#include <fcntl.h>
-
-#include <sys/ioctl.h>
-#include <sys/types.h>
-#include <sys/mman.h>
-
-#include <copybit.h>
-
-#include "gralloc_priv.h"
-#include "software_converter.h"
-#include <qdMetaData.h>
-
-#define DEBUG_MDP_ERRORS 1
-
-/******************************************************************************/
-
-#define MAX_SCALE_FACTOR    (4)
-#define MAX_DIMENSION       (4096)
-
-/******************************************************************************/
-struct blitReq{
-    struct  mdp_buf_sync sync;
-    uint32_t count;
-    struct mdp_blit_req req[10];
-};
-
-/** State information for each device instance */
-struct copybit_context_t {
-    struct copybit_device_t device;
-    int     mFD;
-    uint8_t mAlpha;
-    int     mFlags;
-    bool    mBlitToFB;
-    int     acqFence[MDP_MAX_FENCE_FD];
-    int     relFence;
-    struct  mdp_buf_sync sync;
-    struct  blitReq list;
-    uint8_t dynamic_fps;
-};
-
-/**
- * Common hardware methods
- */
-
-static int open_copybit(const struct hw_module_t* module, const char* name,
-                        struct hw_device_t** device);
-
-static struct hw_module_methods_t copybit_module_methods = {
-open:  open_copybit
-};
-
-/*
- * The COPYBIT Module
- */
-struct copybit_module_t HAL_MODULE_INFO_SYM = {
-common: {
-tag: HARDWARE_MODULE_TAG,
-     version_major: 1,
-     version_minor: 0,
-     id: COPYBIT_HARDWARE_MODULE_ID,
-     name: "QCT MSM7K COPYBIT Module",
-     author: "Google, Inc.",
-     methods: &copybit_module_methods
-        }
-};
-
-/******************************************************************************/
-
-/** min of int a, b */
-static inline int min(int a, int b) {
-    return (a<b) ? a : b;
-}
-
-/** max of int a, b */
-static inline int max(int a, int b) {
-    return (a>b) ? a : b;
-}
-
-/** scale each parameter by mul/div. Assume div isn't 0 */
-static inline void MULDIV(uint32_t *a, uint32_t *b, int mul, int div) {
-    if (mul != div) {
-        *a = (mul * *a) / div;
-        *b = (mul * *b) / div;
-    }
-}
-
-/** Determine the intersection of lhs & rhs store in out */
-static void intersect(struct copybit_rect_t *out,
-                      const struct copybit_rect_t *lhs,
-                      const struct copybit_rect_t *rhs) {
-    out->l = max(lhs->l, rhs->l);
-    out->t = max(lhs->t, rhs->t);
-    out->r = min(lhs->r, rhs->r);
-    out->b = min(lhs->b, rhs->b);
-}
-
-static bool validateCopybitRect(struct copybit_rect_t *rect) {
-    return ((rect->b > rect->t) && (rect->r > rect->l)) ;
-}
-
-/** convert COPYBIT_FORMAT to MDP format */
-static int get_format(int format) {
-    switch (format) {
-        case HAL_PIXEL_FORMAT_RGB_565:       return MDP_RGB_565;
-        case HAL_PIXEL_FORMAT_RGBA_5551:     return MDP_RGBA_5551;
-        case HAL_PIXEL_FORMAT_RGBA_4444:     return MDP_RGBA_4444;
-        case HAL_PIXEL_FORMAT_RGBX_8888:     return MDP_RGBX_8888;
-        case HAL_PIXEL_FORMAT_BGRX_8888:     return MDP_BGRX_8888;
-        case HAL_PIXEL_FORMAT_RGB_888:       return MDP_RGB_888;
-        case HAL_PIXEL_FORMAT_RGBA_8888:     return MDP_RGBA_8888;
-        case HAL_PIXEL_FORMAT_BGRA_8888:     return MDP_BGRA_8888;
-        case HAL_PIXEL_FORMAT_YCrCb_422_I:   return MDP_YCRYCB_H2V1;
-        case HAL_PIXEL_FORMAT_YCbCr_422_I:   return MDP_YCBYCR_H2V1;
-        case HAL_PIXEL_FORMAT_YCrCb_422_SP:  return MDP_Y_CRCB_H2V1;
-        case HAL_PIXEL_FORMAT_YCrCb_420_SP:  return MDP_Y_CRCB_H2V2;
-        case HAL_PIXEL_FORMAT_YCbCr_422_SP:  return MDP_Y_CBCR_H2V1;
-        case HAL_PIXEL_FORMAT_YCbCr_420_SP:  return MDP_Y_CBCR_H2V2;
-        case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO: return MDP_Y_CBCR_H2V2_ADRENO;
-        case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS: return MDP_Y_CBCR_H2V2_VENUS;
-        case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS: return MDP_Y_CRCB_H2V2_VENUS;
-        case HAL_PIXEL_FORMAT_NV12_ENCODEABLE: return MDP_Y_CBCR_H2V2;
-        case HAL_PIXEL_FORMAT_CbYCrY_422_I: return MDP_CBYCRY_H2V1;
-        case HAL_PIXEL_FORMAT_BGR_888: return MDP_BGR_888;
-    }
-    return -1;
-}
-
-/** convert from copybit image to mdp image structure */
-static void set_image(struct mdp_img *img, const struct copybit_image_t *rhs)
-{
-    private_handle_t* hnd = (private_handle_t*)rhs->handle;
-    if(hnd == NULL){
-        ALOGE("copybit: Invalid handle");
-        return;
-    }
-    img->width      = rhs->w;
-    img->height     = rhs->h;
-    img->format     = get_format(rhs->format);
-    img->offset     = (uint32_t)hnd->offset;
-    img->memory_id  = hnd->fd;
-}
-/** setup rectangles */
-static bool set_rects(struct copybit_context_t *dev,
-                      struct mdp_blit_req *e,
-                      const struct copybit_rect_t *dst,
-                      const struct copybit_rect_t *src,
-                      const struct copybit_rect_t *scissor) {
-    struct copybit_rect_t clip;
-    intersect(&clip, scissor, dst);
-
-    if (!validateCopybitRect(&clip))
-       return false;
-
-    e->dst_rect.x  = clip.l;
-    e->dst_rect.y  = clip.t;
-    e->dst_rect.w  = clip.r - clip.l;
-    e->dst_rect.h  = clip.b - clip.t;
-
-    uint32_t W, H, delta_x, delta_y;
-    if (dev->mFlags & COPYBIT_TRANSFORM_ROT_90) {
-        delta_x = (clip.t - dst->t);
-        delta_y = (dst->r - clip.r);
-        e->src_rect.w = (clip.b - clip.t);
-        e->src_rect.h = (clip.r - clip.l);
-        W = dst->b - dst->t;
-        H = dst->r - dst->l;
-    } else {
-        delta_x  = (clip.l - dst->l);
-        delta_y  = (clip.t - dst->t);
-        e->src_rect.w  = (clip.r - clip.l);
-        e->src_rect.h  = (clip.b - clip.t);
-        W = dst->r - dst->l;
-        H = dst->b - dst->t;
-    }
-
-    MULDIV(&delta_x, &e->src_rect.w, src->r - src->l, W);
-    MULDIV(&delta_y, &e->src_rect.h, src->b - src->t, H);
-
-    e->src_rect.x = delta_x + src->l;
-    e->src_rect.y = delta_y + src->t;
-
-    if (dev->mFlags & COPYBIT_TRANSFORM_FLIP_V) {
-        if (dev->mFlags & COPYBIT_TRANSFORM_ROT_90) {
-            e->src_rect.x = (src->l + src->r) - (e->src_rect.x + e->src_rect.w);
-        }else{
-            e->src_rect.y = (src->t + src->b) - (e->src_rect.y + e->src_rect.h);
-        }
-    }
-
-    if (dev->mFlags & COPYBIT_TRANSFORM_FLIP_H) {
-        if (dev->mFlags & COPYBIT_TRANSFORM_ROT_90) {
-            e->src_rect.y = (src->t + src->b) - (e->src_rect.y + e->src_rect.h);
-        }else{
-            e->src_rect.x = (src->l + src->r) - (e->src_rect.x + e->src_rect.w);
-        }
-    }
-    return true;
-}
-
-/** setup mdp request */
-static void set_infos(struct copybit_context_t *dev,
-                      struct mdp_blit_req *req, int flags)
-{
-    req->alpha = dev->mAlpha;
-    req->fps = dev->dynamic_fps;
-    req->transp_mask = MDP_TRANSP_NOP;
-    req->flags = dev->mFlags | flags;
-    // check if we are blitting to f/b
-    if (COPYBIT_ENABLE == dev->mBlitToFB) {
-        req->flags |= MDP_MEMORY_ID_TYPE_FB;
-    }
-#if defined(COPYBIT_QSD8K)
-    req->flags |= MDP_BLEND_FG_PREMULT;
-#endif
-}
-
-/** copy the bits */
-static int msm_copybit(struct copybit_context_t *dev, void const *list)
-{
-    int err;
-    if (dev->relFence != -1) {
-        close(dev->relFence);
-        dev->relFence = -1;
-    }
-    err = ioctl(dev->mFD, MSMFB_ASYNC_BLIT,
-                    (struct mdp_async_blit_req_list const*)list);
-    ALOGE_IF(err<0, "copyBits failed (%s)", strerror(errno));
-    if (err == 0) {
-        return 0;
-    } else {
-#if DEBUG_MDP_ERRORS
-        struct mdp_async_blit_req_list const* l =
-            (struct mdp_async_blit_req_list const*)list;
-        for (unsigned int i=0 ; i<l->count ; i++) {
-            ALOGE("%d: src={w=%d, h=%d, f=%d, rect={%d,%d,%d,%d}}\n"
-                  "    dst={w=%d, h=%d, f=%d, rect={%d,%d,%d,%d}}\n"
-                  "    flags=%08x, fps=%d"
-                  ,
-                  i,
-                  l->req[i].src.width,
-                  l->req[i].src.height,
-                  l->req[i].src.format,
-                  l->req[i].src_rect.x,
-                  l->req[i].src_rect.y,
-                  l->req[i].src_rect.w,
-                  l->req[i].src_rect.h,
-                  l->req[i].dst.width,
-                  l->req[i].dst.height,
-                  l->req[i].dst.format,
-                  l->req[i].dst_rect.x,
-                  l->req[i].dst_rect.y,
-                  l->req[i].dst_rect.w,
-                  l->req[i].dst_rect.h,
-                  l->req[i].flags,
-                  l->req[i].fps
-                 );
-        }
-#endif
-        return -errno;
-    }
-}
-
-/*****************************************************************************/
-
-/** Set a parameter to value */
-static int set_parameter_copybit(
-    struct copybit_device_t *dev,
-    int name,
-    int value)
-{
-    struct copybit_context_t* ctx = (struct copybit_context_t*)dev;
-    int status = 0;
-    if (ctx) {
-        switch(name) {
-            case COPYBIT_ROTATION_DEG:
-                switch (value) {
-                    case 0:
-                        ctx->mFlags &= ~0x7;
-                        break;
-                    case 90:
-                        ctx->mFlags &= ~0x7;
-                        ctx->mFlags |= MDP_ROT_90;
-                        break;
-                    case 180:
-                        ctx->mFlags &= ~0x7;
-                        ctx->mFlags |= MDP_ROT_180;
-                        break;
-                    case 270:
-                        ctx->mFlags &= ~0x7;
-                        ctx->mFlags |= MDP_ROT_270;
-                        break;
-                    default:
-                        ALOGE("Invalid value for COPYBIT_ROTATION_DEG");
-                        status = -EINVAL;
-                        break;
-                }
-                break;
-            case COPYBIT_PLANE_ALPHA:
-                if (value < 0)      value = MDP_ALPHA_NOP;
-                if (value >= 256)   value = 255;
-                ctx->mAlpha = (uint8_t)value;
-                break;
-            case COPYBIT_DYNAMIC_FPS:
-                ctx->dynamic_fps = (uint8_t)value;
-                break;
-            case COPYBIT_DITHER:
-                if (value == COPYBIT_ENABLE) {
-                    ctx->mFlags |= MDP_DITHER;
-                } else if (value == COPYBIT_DISABLE) {
-                    ctx->mFlags &= ~MDP_DITHER;
-                }
-                break;
-            case COPYBIT_BLUR:
-                if (value == COPYBIT_ENABLE) {
-                    ctx->mFlags |= MDP_BLUR;
-                } else if (value == COPYBIT_DISABLE) {
-                    ctx->mFlags &= ~MDP_BLUR;
-                }
-                break;
-            case COPYBIT_BLEND_MODE:
-                if(value == COPYBIT_BLENDING_PREMULT) {
-                    ctx->mFlags |= MDP_BLEND_FG_PREMULT;
-                } else {
-                    ctx->mFlags &= ~MDP_BLEND_FG_PREMULT;
-                }
-                break;
-            case COPYBIT_TRANSFORM:
-                ctx->mFlags &= ~0x7;
-                ctx->mFlags |= value & 0x7;
-                break;
-            case COPYBIT_BLIT_TO_FRAMEBUFFER:
-                if (COPYBIT_ENABLE == value) {
-                    ctx->mBlitToFB = value;
-                } else if (COPYBIT_DISABLE == value) {
-                    ctx->mBlitToFB = value;
-                } else {
-                    ALOGE ("%s:Invalid input for COPYBIT_BLIT_TO_FRAMEBUFFER : %d",
-                            __FUNCTION__, value);
-                }
-                break;
-            case COPYBIT_FG_LAYER:
-                if(value == COPYBIT_ENABLE) {
-                     ctx->mFlags |= MDP_IS_FG;
-                } else if (value == COPYBIT_DISABLE) {
-                    ctx->mFlags &= ~MDP_IS_FG;
-                }
-                break ;
-            default:
-                status = -EINVAL;
-                break;
-        }
-    } else {
-        status = -EINVAL;
-    }
-    return status;
-}
-
-/** Get a static info value */
-static int get(struct copybit_device_t *dev, int name)
-{
-    struct copybit_context_t* ctx = (struct copybit_context_t*)dev;
-    int value;
-    if (ctx) {
-        switch(name) {
-            case COPYBIT_MINIFICATION_LIMIT:
-                value = MAX_SCALE_FACTOR;
-                break;
-            case COPYBIT_MAGNIFICATION_LIMIT:
-                value = MAX_SCALE_FACTOR;
-                break;
-            case COPYBIT_SCALING_FRAC_BITS:
-                value = 32;
-                break;
-            case COPYBIT_ROTATION_STEP_DEG:
-                value = 90;
-                break;
-            default:
-                value = -EINVAL;
-        }
-    } else {
-        value = -EINVAL;
-    }
-    return value;
-}
-
-static int set_sync_copybit(struct copybit_device_t *dev,
-    int acquireFenceFd)
-{
-    struct copybit_context_t* ctx = (struct copybit_context_t*)dev;
-    if (acquireFenceFd != -1) {
-        if (ctx->list.sync.acq_fen_fd_cnt < (MDP_MAX_FENCE_FD - 1)) {
-            ctx->acqFence[ctx->list.sync.acq_fen_fd_cnt++] = acquireFenceFd;
-        } else {
-            int ret = -EINVAL;
-            struct blitReq *list = &ctx->list;
-
-            // Since fence is full kick off what is already in the list
-            ret = msm_copybit(ctx, list);
-            if (ret < 0) {
-                ALOGE("%s: Blit call failed", __FUNCTION__);
-                return -EINVAL;
-            }
-            list->count = 0;
-            list->sync.acq_fen_fd_cnt = 0;
-            ctx->acqFence[list->sync.acq_fen_fd_cnt++] = acquireFenceFd;
-        }
-    }
-    return 0;
-}
-
-/** do a stretch blit type operation */
-static int stretch_copybit(
-    struct copybit_device_t *dev,
-    struct copybit_image_t const *dst,
-    struct copybit_image_t const *src,
-    struct copybit_rect_t const *dst_rect,
-    struct copybit_rect_t const *src_rect,
-    struct copybit_region_t const *region)
-{
-    struct copybit_context_t* ctx = (struct copybit_context_t*)dev;
-    struct blitReq *list;
-    int status = 0;
-    private_handle_t *yv12_handle = NULL;
-
-    if (ctx) {
-        list = &ctx->list;
-
-        if (ctx->mAlpha < 255) {
-            switch (src->format) {
-                // we don't support plane alpha with RGBA formats
-                case HAL_PIXEL_FORMAT_RGBA_8888:
-                case HAL_PIXEL_FORMAT_BGRA_8888:
-                case HAL_PIXEL_FORMAT_RGBA_5551:
-                case HAL_PIXEL_FORMAT_RGBA_4444:
-                    ALOGE ("%s : Unsupported Pixel format %d", __FUNCTION__,
-                           src->format);
-                    return -EINVAL;
-            }
-        }
-
-        if (src_rect->l < 0 || (uint32_t)src_rect->r > src->w ||
-            src_rect->t < 0 || (uint32_t)src_rect->b > src->h) {
-            // this is always invalid
-            ALOGE ("%s : Invalid source rectangle : src_rect l %d t %d r %d b %d",\
-                   __FUNCTION__, src_rect->l, src_rect->t, src_rect->r, src_rect->b);
-
-            return -EINVAL;
-        }
-
-        if (src->w > MAX_DIMENSION || src->h > MAX_DIMENSION) {
-            ALOGE ("%s : Invalid source dimensions w %d h %d", __FUNCTION__, src->w, src->h);
-            return -EINVAL;
-        }
-
-        if (dst->w > MAX_DIMENSION || dst->h > MAX_DIMENSION) {
-            ALOGE ("%s : Invalid DST dimensions w %d h %d", __FUNCTION__, dst->w, dst->h);
-            return -EINVAL;
-        }
-
-        if(src->format ==  HAL_PIXEL_FORMAT_YV12) {
-            int usage =
-            GRALLOC_USAGE_PRIVATE_IOMMU_HEAP | GRALLOC_USAGE_PRIVATE_UNCACHED;
-            if (0 == alloc_buffer(&yv12_handle,src->w,src->h,
-                                  src->format, usage)){
-                if(0 == convertYV12toYCrCb420SP(src,yv12_handle)){
-                    (const_cast<copybit_image_t *>(src))->format =
-                        HAL_PIXEL_FORMAT_YCrCb_420_SP;
-                    (const_cast<copybit_image_t *>(src))->handle =
-                        yv12_handle;
-                    (const_cast<copybit_image_t *>(src))->base =
-                        (void *)yv12_handle->base;
-                }
-                else{
-                    ALOGE("Error copybit conversion from yv12 failed");
-                    if(yv12_handle)
-                        free_buffer(yv12_handle);
-                    return -EINVAL;
-                }
-            }
-            else{
-                ALOGE("Error:unable to allocate memeory for yv12 software conversion");
-                return -EINVAL;
-            }
-        }
-        const uint32_t maxCount =
-                (uint32_t)(sizeof(list->req)/sizeof(list->req[0]));
-        const struct copybit_rect_t bounds = { 0, 0, (int)dst->w, (int)dst->h };
-        struct copybit_rect_t clip;
-        status = 0;
-        while ((status == 0) && region->next(region, &clip)) {
-            intersect(&clip, &bounds, &clip);
-            mdp_blit_req* req = &list->req[list->count];
-            int flags = 0;
-
-            private_handle_t* src_hnd = (private_handle_t*)src->handle;
-            if(src_hnd != NULL &&
-                (!(src_hnd->flags & private_handle_t::PRIV_FLAGS_CACHED))) {
-                flags |=  MDP_BLIT_NON_CACHED;
-            }
-
-            // Set Color Space for MDP to configure CSC matrix
-            req->color_space = ITU_R_601;
-            MetaData_t *metadata = NULL;
-
-            if (src_hnd != NULL)
-                metadata = (MetaData_t *)src_hnd->base_metadata;
-
-            if (metadata && (metadata->operation & UPDATE_COLOR_SPACE)) {
-                req->color_space = metadata->colorSpace;
-            }
-
-            set_infos(ctx, req, flags);
-            set_image(&req->dst, dst);
-            set_image(&req->src, src);
-            if (set_rects(ctx, req, dst_rect, src_rect, &clip) == false)
-                continue;
-
-            if (req->src_rect.w<=0 || req->src_rect.h<=0)
-                continue;
-
-            if (req->dst_rect.w<=0 || req->dst_rect.h<=0)
-                continue;
-
-            if (++list->count == maxCount) {
-                status = msm_copybit(ctx, list);
-                list->sync.acq_fen_fd_cnt = 0;
-                list->count = 0;
-            }
-        }
-        if(yv12_handle) {
-            //Before freeing the buffer we need buffer passed through blit call
-            if (list->count != 0) {
-                status = msm_copybit(ctx, list);
-                list->sync.acq_fen_fd_cnt = 0;
-                list->count = 0;
-            }
-            free_buffer(yv12_handle);
-        }
-    } else {
-        ALOGE ("%s : Invalid COPYBIT context", __FUNCTION__);
-        status = -EINVAL;
-    }
-    return status;
-}
-
-/** Perform a blit type operation */
-static int blit_copybit(
-    struct copybit_device_t *dev,
-    struct copybit_image_t const *dst,
-    struct copybit_image_t const *src,
-    struct copybit_region_t const *region)
-{
-    struct copybit_rect_t dr = { 0, 0, (int)dst->w, (int)dst->h };
-    struct copybit_rect_t sr = { 0, 0, (int)src->w, (int)src->h };
-    return stretch_copybit(dev, dst, src, &dr, &sr, region);
-}
-
-static int finish_copybit(struct copybit_device_t *dev)
-{
-    // NOP for MDP copybit
-    if(!dev)
-       return -EINVAL;
-
-    return 0;
-}
-static int clear_copybit(struct copybit_device_t *dev,
-                         struct copybit_image_t const *buf,
-                         struct copybit_rect_t *rect)
-{
-    struct copybit_context_t* ctx = (struct copybit_context_t*)dev;
-    uint32_t color = 0; // black color
-
-    if (!ctx) {
-        ALOGE ("%s: Invalid copybit context", __FUNCTION__);
-        return -EINVAL;
-    }
-
-    struct blitReq list1;
-    memset((char *)&list1 , 0 ,sizeof (struct blitReq) );
-    list1.count = 1;
-    int my_tmp_get_fence = -1;
-
-    list1.sync.acq_fen_fd  =  ctx->acqFence;
-    list1.sync.rel_fen_fd  =  &my_tmp_get_fence;
-    list1.sync.acq_fen_fd_cnt = ctx->list.sync.acq_fen_fd_cnt;
-    mdp_blit_req* req = &list1.req[0];
-
-    if(!req) {
-        ALOGE ("%s : Invalid request", __FUNCTION__);
-        return -EINVAL;
-    }
-
-    set_image(&req->dst, buf);
-    set_image(&req->src, buf);
-
-    if (rect->l < 0 || (uint32_t)(rect->r - rect->l) > req->dst.width ||
-       rect->t < 0 || (uint32_t)(rect->b - rect->t) > req->dst.height) {
-       ALOGE ("%s : Invalid rect : src_rect l %d t %d r %d b %d",\
-       __FUNCTION__, rect->l, rect->t, rect->r, rect->b);
-       return -EINVAL;
-    }
-
-    req->dst_rect.x  = rect->l;
-    req->dst_rect.y  = rect->t;
-    req->dst_rect.w  = rect->r - rect->l;
-    req->dst_rect.h  = rect->b - rect->t;
-
-    req->src_rect = req->dst_rect;
-
-    req->const_color.b = (uint32_t)((color >> 16) & 0xff);
-    req->const_color.g = (uint32_t)((color >> 8) & 0xff);
-    req->const_color.r = (uint32_t)((color >> 0) & 0xff);
-    req->const_color.alpha = MDP_ALPHA_NOP;
-
-    req->transp_mask = MDP_TRANSP_NOP;
-    req->flags = MDP_SOLID_FILL | MDP_MEMORY_ID_TYPE_FB | MDP_BLEND_FG_PREMULT;
-    int status = msm_copybit(ctx, &list1);
-
-    ctx->list.sync.acq_fen_fd_cnt = 0;
-    if (my_tmp_get_fence !=  -1)
-        close(my_tmp_get_fence);
-
-    return status;
-}
-
-/** Fill the rect on dst with RGBA color **/
-static int fill_color(struct copybit_device_t *dev,
-                      struct copybit_image_t const *dst,
-                      struct copybit_rect_t const *rect,
-                      uint32_t color)
-{
-    struct copybit_context_t* ctx = (struct copybit_context_t*)dev;
-    if (!ctx) {
-        ALOGE("%s: Invalid copybit context", __FUNCTION__);
-        return -EINVAL;
-    }
-
-    if (dst->w > MAX_DIMENSION || dst->h > MAX_DIMENSION) {
-        ALOGE("%s: Invalid DST w=%d h=%d", __FUNCTION__, dst->w, dst->h);
-        return -EINVAL;
-    }
-
-    if (rect->l < 0 || (uint32_t)(rect->r - rect->l) > dst->w ||
-        rect->t < 0 || (uint32_t)(rect->b - rect->t) > dst->h) {
-        ALOGE("%s: Invalid destination rect: l=%d t=%d r=%d b=%d",
-                __FUNCTION__, rect->l, rect->t, rect->r, rect->b);
-        return -EINVAL;
-    }
-
-    int status = 0;
-    struct blitReq* list = &ctx->list;
-    mdp_blit_req* req = &list->req[list->count++];
-    set_infos(ctx, req, MDP_SOLID_FILL);
-    set_image(&req->src, dst);
-    set_image(&req->dst, dst);
-
-    req->dst_rect.x = rect->l;
-    req->dst_rect.y = rect->t;
-    req->dst_rect.w = rect->r - rect->l;
-    req->dst_rect.h = rect->b - rect->t;
-    req->src_rect = req->dst_rect;
-
-    req->const_color.r = (uint32_t)((color >> 0) & 0xff);
-    req->const_color.g = (uint32_t)((color >> 8) & 0xff);
-    req->const_color.b = (uint32_t)((color >> 16) & 0xff);
-    req->const_color.alpha = (uint32_t)((color >> 24) & 0xff);
-
-    if (list->count == sizeof(list->req)/sizeof(list->req[0])) {
-        status = msm_copybit(ctx, list);
-        list->sync.acq_fen_fd_cnt = 0;
-        list->count = 0;
-    }
-    return status;
-}
-
-/*****************************************************************************/
-
-/** Close the copybit device */
-static int close_copybit(struct hw_device_t *dev)
-{
-    struct copybit_context_t* ctx = (struct copybit_context_t*)dev;
-    if (ctx) {
-        close(ctx->mFD);
-        free(ctx);
-    }
-    return 0;
-}
-
-static int flush_get_fence(struct copybit_device_t *dev, int* fd)
-{
-    struct copybit_context_t* ctx = (struct copybit_context_t*)dev;
-    struct blitReq *list = &ctx->list;
-    int ret = -EINVAL;
-
-    if (list->count) {
-        ret = msm_copybit(ctx, list);
-        if (ret < 0)
-            ALOGE("%s: Blit call failed", __FUNCTION__);
-        list->count = 0;
-    }
-    *fd = ctx->relFence;
-    list->sync.acq_fen_fd_cnt = 0;
-    ctx->relFence = -1;
-    return ret;
-}
-
-/** Open a new instance of a copybit device using name */
-static int open_copybit(const struct hw_module_t* module, const char* name,
-                        struct hw_device_t** device)
-{
-    int status = -EINVAL;
-
-    if (strcmp(name, COPYBIT_HARDWARE_COPYBIT0)) {
-        return COPYBIT_FAILURE;
-    }
-    copybit_context_t *ctx;
-    ctx = (copybit_context_t *)malloc(sizeof(copybit_context_t));
-
-    if (ctx == NULL ) {
-       return COPYBIT_FAILURE;
-    }
-
-    memset(ctx, 0, sizeof(*ctx));
-
-    ctx->device.common.tag = HARDWARE_DEVICE_TAG;
-    ctx->device.common.version = 1;
-    ctx->device.common.module = const_cast<hw_module_t*>(module);
-    ctx->device.common.close = close_copybit;
-    ctx->device.set_parameter = set_parameter_copybit;
-    ctx->device.get = get;
-    ctx->device.blit = blit_copybit;
-    ctx->device.set_sync = set_sync_copybit;
-    ctx->device.stretch = stretch_copybit;
-    ctx->device.finish = finish_copybit;
-    ctx->device.fill_color = fill_color;
-    ctx->device.flush_get_fence = flush_get_fence;
-    ctx->device.clear = clear_copybit;
-    ctx->mAlpha = MDP_ALPHA_NOP;
-    //dynamic_fps is zero means default
-    //panel refresh rate for driver.
-    ctx->dynamic_fps = 0;
-    ctx->mFlags = 0;
-    ctx->sync.flags = 0;
-    ctx->relFence = -1;
-    for (int i=0; i < MDP_MAX_FENCE_FD; i++) {
-        ctx->acqFence[i] = -1;
-    }
-    ctx->sync.acq_fen_fd = ctx->acqFence;
-    ctx->sync.rel_fen_fd = &ctx->relFence;
-    ctx->list.count = 0;
-    ctx->list.sync.acq_fen_fd_cnt = 0;
-    ctx->list.sync.rel_fen_fd = ctx->sync.rel_fen_fd;
-    ctx->list.sync.acq_fen_fd = ctx->sync.acq_fen_fd;
-    ctx->mFD = open("/dev/graphics/fb0", O_RDWR, 0);
-    if (ctx->mFD < 0) {
-        status = errno;
-        ALOGE("Error opening frame buffer errno=%d (%s)",
-              status, strerror(status));
-        status = -status;
-    } else {
-        status = 0;
-        *device = &ctx->device.common;
-    }
-    return status;
-}
diff --git a/libcopybit/copybit.h b/libcopybit/copybit.h
deleted file mode 100644
index de585ee..0000000
--- a/libcopybit/copybit.h
+++ /dev/null
@@ -1,319 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- * Copyright (c) 2012-2015, The Linux Foundation. All rights reserved.
- *
- * Not a Contribution, Apache license notifications and license are retained
- * for attribution purposes only.
- *
- * 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_COPYBIT_INTERFACE_H
-#define ANDROID_COPYBIT_INTERFACE_H
-
-#include <hardware/hardware.h>
-
-#include <stdint.h>
-#include <sys/cdefs.h>
-#include <sys/types.h>
-#include <gralloc_priv.h>
-
-__BEGIN_DECLS
-
-/**
- * The id of this module
- */
-#define COPYBIT_HARDWARE_MODULE_ID "copybit"
-
-/**
- * Name of the graphics device to open
- */
-#define COPYBIT_HARDWARE_COPYBIT0 "copybit0"
-
-/* supported pixel-formats. these must be compatible with
- * graphics/PixelFormat.java, ui/PixelFormat.h, pixelflinger/format.h
- */
-enum {
-    COPYBIT_FORMAT_RGBA_8888    = HAL_PIXEL_FORMAT_RGBA_8888,
-    COPYBIT_FORMAT_RGBX_8888    = HAL_PIXEL_FORMAT_RGBX_8888,
-    COPYBIT_FORMAT_RGB_888      = HAL_PIXEL_FORMAT_RGB_888,
-    COPYBIT_FORMAT_RGB_565      = HAL_PIXEL_FORMAT_RGB_565,
-    COPYBIT_FORMAT_BGRA_8888    = HAL_PIXEL_FORMAT_BGRA_8888,
-    COPYBIT_FORMAT_RGBA_5551    = HAL_PIXEL_FORMAT_RGBA_5551,
-    COPYBIT_FORMAT_RGBA_4444    = HAL_PIXEL_FORMAT_RGBA_4444,
-    COPYBIT_FORMAT_YCbCr_422_SP = 0x10,
-    COPYBIT_FORMAT_YCrCb_420_SP = 0x11,
-};
-
-/* name for copybit_set_parameter */
-enum {
-    /* Default blit destination is offline buffer */
-    /* clients to set this to '1', if blitting to framebuffer */
-    /* and reset to '0', after calling blit/stretch */
-    COPYBIT_BLIT_TO_FRAMEBUFFER = 0,
-    /* rotation of the source image in degrees (0 to 359) */
-    COPYBIT_ROTATION_DEG    = 1,
-    /* plane alpha value */
-    COPYBIT_PLANE_ALPHA     = 2,
-    /* enable or disable dithering */
-    COPYBIT_DITHER          = 3,
-    /* transformation applied (this is a superset of COPYBIT_ROTATION_DEG) */
-    COPYBIT_TRANSFORM       = 4,
-    /* blurs the copied bitmap. The amount of blurring cannot be changed
-     * at this time. */
-    COPYBIT_BLUR            = 5,
-    /* Blend mode */
-    COPYBIT_BLEND_MODE  = 6,
-    /* FB width */
-    COPYBIT_FRAMEBUFFER_WIDTH = 7,
-    /* FB height */
-    COPYBIT_FRAMEBUFFER_HEIGHT = 8,
-    COPYBIT_FG_LAYER = 9,
-    COPYBIT_DYNAMIC_FPS = 10,
-    /* Source Format Mode */
-    COPYBIT_SRC_FORMAT_MODE = 11,
-    /* Destination Format Mode */
-    COPYBIT_DST_FORMAT_MODE = 12,
-};
-
-/* values for copybit_set_parameter(COPYBIT_TRANSFORM) */
-enum {
-    /* flip source image horizontally */
-    COPYBIT_TRANSFORM_FLIP_H    = HAL_TRANSFORM_FLIP_H,
-    /* flip source image vertically */
-    COPYBIT_TRANSFORM_FLIP_V    = HAL_TRANSFORM_FLIP_V,
-    /* rotate source image 90 degres */
-    COPYBIT_TRANSFORM_ROT_90    = HAL_TRANSFORM_ROT_90,
-    /* rotate source image 180 degres */
-    COPYBIT_TRANSFORM_ROT_180   = HAL_TRANSFORM_ROT_180,
-    /* rotate source image 270 degres */
-    COPYBIT_TRANSFORM_ROT_270   = HAL_TRANSFORM_ROT_270,
-};
-
-/* enable/disable value copybit_set_parameter */
-enum {
-    COPYBIT_DISABLE = 0,
-    COPYBIT_ENABLE  = 1
-};
-
-/*
- * copybit blending values. same as HWC blending values
- */
-enum {
-    /* no blending */
-    COPYBIT_BLENDING_NONE     = 0x0100,
-
-    /* ONE / ONE_MINUS_SRC_ALPHA */
-    COPYBIT_BLENDING_PREMULT  = 0x0105,
-
-    /* SRC_ALPHA / ONE_MINUS_SRC_ALPHA */
-    COPYBIT_BLENDING_COVERAGE = 0x0405
-};
-
-enum {
-    /* Linear format mode*/
-    COPYBIT_LINEAR = 0x0000,
-    /* UBWC format mode*/
-    COPYBIT_UBWC_COMPRESSED = 0x0001,
-};
-
-/* use get_static_info() to query static informations about the hardware */
-enum {
-    /* Maximum amount of minification supported by the hardware*/
-    COPYBIT_MINIFICATION_LIMIT  = 1,
-    /* Maximum amount of magnification supported by the hardware */
-    COPYBIT_MAGNIFICATION_LIMIT = 2,
-    /* Number of fractional bits support by the scaling engine */
-    COPYBIT_SCALING_FRAC_BITS   = 3,
-    /* Supported rotation step in degres. */
-    COPYBIT_ROTATION_STEP_DEG   = 4,
-    /* UBWC support*/
-    COPYBIT_UBWC_SUPPORT        = 5,
-};
-
-/* Image structure */
-struct copybit_image_t {
-    /* width */
-    uint32_t    w;
-    /* height */
-    uint32_t    h;
-    /* format COPYBIT_FORMAT_xxx */
-    int32_t     format;
-    /* base of buffer with image */
-    void        *base;
-    /* handle to the image */
-    native_handle_t* handle;
-    /* number of pixels added for the stride */
-    uint32_t    horiz_padding;
-    /* number of pixels added for the vertical stride */
-    uint32_t    vert_padding;
-};
-
-/* Rectangle */
-struct copybit_rect_t {
-    /* left */
-    int l;
-    /* top */
-    int t;
-    /* right */
-    int r;
-    /* bottom */
-    int b;
-};
-
-/* Region */
-struct copybit_region_t {
-    int (*next)(struct copybit_region_t const *region, struct copybit_rect_t *rect);
-};
-
-/**
- * Every hardware module must have a data structure named HAL_MODULE_INFO_SYM
- * and the fields of this data structure must begin with hw_module_t
- * followed by module specific information.
- */
-struct copybit_module_t {
-    struct hw_module_t common;
-};
-
-/**
- * Every device data structure must begin with hw_device_t
- * followed by module specific public methods and attributes.
- */
-struct copybit_device_t {
-    struct hw_device_t common;
-
-    /**
-     * Set a copybit parameter.
-     *
-     * @param dev from open
-     * @param name one for the COPYBIT_NAME_xxx
-     * @param value one of the COPYBIT_VALUE_xxx
-     *
-     * @return 0 if successful
-     */
-    int (*set_parameter)(struct copybit_device_t *dev, int name, int value);
-
-    /**
-     * Get a static copybit information.
-     *
-     * @param dev from open
-     * @param name one of the COPYBIT_STATIC_xxx
-     *
-     * @return value or -EINVAL if error
-     */
-    int (*get)(struct copybit_device_t *dev, int name);
-
-    /**
-     * Execute the bit blit copy operation
-     *
-     * @param dev from open
-     * @param dst is the destination image
-     * @param src is the source image
-     * @param region the clip region
-     *
-     * @return 0 if successful
-     */
-    int (*blit)(struct copybit_device_t *dev,
-                struct copybit_image_t const *dst,
-                struct copybit_image_t const *src,
-                struct copybit_region_t const *region);
-
-    /**
-     * Give acquire fence to copybit to be used in upcoming stretch
-     * call
-     *
-     * @param dev from open
-     * @param acquireFenceFd is the acquire fence
-     *
-     * @return 0 if successful
-     */
-    int (*set_sync)(struct copybit_device_t *dev,
-                   int acquireFenceFd);
-
-    /**
-     * Execute the stretch bit blit copy operation
-     *
-     * @param dev from open
-     * @param dst is the destination image
-     * @param src is the source image
-     * @param dst_rect is the destination rectangle
-     * @param src_rect is the source rectangle
-     * @param region the clip region
-     *
-     * @return 0 if successful
-     */
-    int (*stretch)(struct copybit_device_t *dev,
-                   struct copybit_image_t const *dst,
-                   struct copybit_image_t const *src,
-                   struct copybit_rect_t const *dst_rect,
-                   struct copybit_rect_t const *src_rect,
-                   struct copybit_region_t const *region);
-
-    /**
-     * Fill the rect on dst with RGBA color
-     *
-     * @param dev from open
-     * @param dst is destination image
-     * @param rect is destination rectangle
-     * @param color is RGBA color to fill
-     *
-     * @return 0 if successful
-     */
-    int (*fill_color)(struct copybit_device_t *dev,
-                      struct copybit_image_t const *dst,
-                      struct copybit_rect_t const *rect,
-                      uint32_t color);
-
-  /**
-    * Execute the completion of the copybit draw operation.
-    *
-    * @param dev from open
-    *
-    * @return 0 if successful
-    */
-  int (*finish)(struct copybit_device_t *dev);
-
-  /**
-    * Trigger the copybit draw operation(async).
-    *
-    * @param dev from open
-    *
-    * @param fd - gets the fencefd
-    *
-    * @return 0 if successful
-    */
-  int (*flush_get_fence)(struct copybit_device_t *dev, int* fd);
-
-  /* Clears the buffer
-   */
-  int (*clear)(struct copybit_device_t *dev, struct copybit_image_t const *buf,
-               struct copybit_rect_t *rect);
-};
-
-
-/** convenience API for opening and closing a device */
-
-static inline int copybit_open(const struct hw_module_t* module,
-                               struct copybit_device_t** device) {
-    return module->methods->open(module,
-                                 COPYBIT_HARDWARE_COPYBIT0, (struct hw_device_t**)device);
-}
-
-static inline int copybit_close(struct copybit_device_t* device) {
-    return device->common.close(&device->common);
-}
-
-
-__END_DECLS
-
-#endif  // ANDROID_COPYBIT_INTERFACE_H
diff --git a/libcopybit/copybit_c2d.cpp b/libcopybit/copybit_c2d.cpp
deleted file mode 100644
index 63c1379..0000000
--- a/libcopybit/copybit_c2d.cpp
+++ /dev/null
@@ -1,1776 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- * Copyright (c) 2010-2015, The Linux Foundation. All rights reserved.
- *
- * Not a Contribution, Apache license notifications and license are retained
- * for attribution purposes only.
- *
- * 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 <log/log.h>
-#include <sys/resource.h>
-#include <sys/prctl.h>
-
-#include <stdint.h>
-#include <string.h>
-#include <unistd.h>
-#include <errno.h>
-#include <fcntl.h>
-
-#include <sys/ioctl.h>
-#include <sys/types.h>
-#include <sys/mman.h>
-
-#include <linux/msm_kgsl.h>
-
-#include <EGL/eglplatform.h>
-#include <cutils/native_handle.h>
-
-#include <copybit.h>
-#include <alloc_controller.h>
-#include <memalloc.h>
-
-#include "c2d2.h"
-#include "software_converter.h"
-
-#include <dlfcn.h>
-
-using gralloc::IMemAlloc;
-using gralloc::IonController;
-using gralloc::alloc_data;
-
-C2D_STATUS (*LINK_c2dCreateSurface)( uint32 *surface_id,
-                                     uint32 surface_bits,
-                                     C2D_SURFACE_TYPE surface_type,
-                                     void *surface_definition );
-
-C2D_STATUS (*LINK_c2dUpdateSurface)( uint32 surface_id,
-                                     uint32 surface_bits,
-                                     C2D_SURFACE_TYPE surface_type,
-                                     void *surface_definition );
-
-C2D_STATUS (*LINK_c2dReadSurface)( uint32 surface_id,
-                                   C2D_SURFACE_TYPE surface_type,
-                                   void *surface_definition,
-                                   int32 x, int32 y );
-
-C2D_STATUS (*LINK_c2dDraw)( uint32 target_id,
-                            uint32 target_config, C2D_RECT *target_scissor,
-                            uint32 target_mask_id, uint32 target_color_key,
-                            C2D_OBJECT *objects_list, uint32 num_objects );
-
-C2D_STATUS (*LINK_c2dFinish)( uint32 target_id);
-
-C2D_STATUS (*LINK_c2dFlush)( uint32 target_id, c2d_ts_handle *timestamp);
-
-C2D_STATUS (*LINK_c2dWaitTimestamp)( c2d_ts_handle timestamp );
-
-C2D_STATUS (*LINK_c2dDestroySurface)( uint32 surface_id );
-
-C2D_STATUS (*LINK_c2dMapAddr) ( int mem_fd, void * hostptr, size_t len,
-                                size_t offset, uint32 flags, void ** gpuaddr);
-
-C2D_STATUS (*LINK_c2dUnMapAddr) ( void * gpuaddr);
-
-C2D_STATUS (*LINK_c2dGetDriverCapabilities) ( C2D_DRIVER_INFO * driver_info);
-
-/* create a fence fd for the timestamp */
-C2D_STATUS (*LINK_c2dCreateFenceFD) ( uint32 target_id, c2d_ts_handle timestamp,
-                                                            int32 *fd);
-
-C2D_STATUS (*LINK_c2dFillSurface) ( uint32 surface_id, uint32 fill_color,
-                                    C2D_RECT * fill_rect);
-
-/******************************************************************************/
-
-#if defined(COPYBIT_Z180)
-#define MAX_SCALE_FACTOR    (4096)
-#define MAX_DIMENSION       (4096)
-#else
-#error "Unsupported HW version"
-#endif
-
-// The following defines can be changed as required i.e. as we encounter
-// complex use cases.
-#define MAX_RGB_SURFACES 32       // Max. RGB layers currently supported per draw
-#define MAX_YUV_2_PLANE_SURFACES 4// Max. 2-plane YUV layers currently supported per draw
-#define MAX_YUV_3_PLANE_SURFACES 1// Max. 3-plane YUV layers currently supported per draw
-// +1 for the destination surface. We cannot have multiple destination surfaces.
-#define MAX_SURFACES (MAX_RGB_SURFACES + MAX_YUV_2_PLANE_SURFACES + MAX_YUV_3_PLANE_SURFACES + 1)
-#define NUM_SURFACE_TYPES 3      // RGB_SURFACE + YUV_SURFACE_2_PLANES + YUV_SURFACE_3_PLANES
-#define MAX_BLIT_OBJECT_COUNT 50 // Max. blit objects that can be passed per draw
-
-enum {
-    RGB_SURFACE,
-    YUV_SURFACE_2_PLANES,
-    YUV_SURFACE_3_PLANES
-};
-
-enum eConversionType {
-    CONVERT_TO_ANDROID_FORMAT,
-    CONVERT_TO_C2D_FORMAT
-};
-
-enum eC2DFlags {
-    FLAGS_PREMULTIPLIED_ALPHA  = 1<<0,
-    FLAGS_YUV_DESTINATION      = 1<<1,
-    FLAGS_TEMP_SRC_DST         = 1<<2,
-    FLAGS_UBWC_FORMAT_MODE     = 1<<3
-};
-
-static gralloc::IAllocController* sAlloc = 0;
-/******************************************************************************/
-
-/** State information for each device instance */
-struct copybit_context_t {
-    struct copybit_device_t device;
-    // Templates for the various source surfaces. These templates are created
-    // to avoid the expensive create/destroy C2D Surfaces
-    C2D_OBJECT_STR blit_rgb_object[MAX_RGB_SURFACES];
-    C2D_OBJECT_STR blit_yuv_2_plane_object[MAX_YUV_2_PLANE_SURFACES];
-    C2D_OBJECT_STR blit_yuv_3_plane_object[MAX_YUV_3_PLANE_SURFACES];
-    C2D_OBJECT_STR blit_list[MAX_BLIT_OBJECT_COUNT]; // Z-ordered list of blit objects
-    C2D_DRIVER_INFO c2d_driver_info;
-    void *libc2d2;
-    alloc_data temp_src_buffer;
-    alloc_data temp_dst_buffer;
-    unsigned int dst[NUM_SURFACE_TYPES]; // dst surfaces
-    uintptr_t mapped_gpu_addr[MAX_SURFACES]; // GPU addresses mapped inside copybit
-    int blit_rgb_count;         // Total RGB surfaces being blit
-    int blit_yuv_2_plane_count; // Total 2 plane YUV surfaces being
-    int blit_yuv_3_plane_count; // Total 3 plane YUV  surfaces being blit
-    int blit_count;             // Total blit objects.
-    unsigned int trg_transform;      /* target transform */
-    int fb_width;
-    int fb_height;
-    int src_global_alpha;
-    int config_mask;
-    int dst_surface_type;
-    bool is_premultiplied_alpha;
-    void* time_stamp;
-    bool dst_surface_mapped; // Set when dst surface is mapped to GPU addr
-    void* dst_surface_base; // Stores the dst surface addr
-    bool is_src_ubwc_format;
-    bool is_dst_ubwc_format;
-
-    // used for signaling the wait thread
-    bool wait_timestamp;
-    pthread_t wait_thread_id;
-    bool stop_thread;
-    pthread_mutex_t wait_cleanup_lock;
-    pthread_cond_t wait_cleanup_cond;
-
-};
-
-struct bufferInfo {
-    int width;
-    int height;
-    int format;
-};
-
-struct yuvPlaneInfo {
-    int yStride;       //luma stride
-    int plane1_stride;
-    int plane2_stride;
-    size_t plane1_offset;
-    size_t plane2_offset;
-};
-
-/**
- * Common hardware methods
- */
-
-static int open_copybit(const struct hw_module_t* module, const char* name,
-                        struct hw_device_t** device);
-
-static struct hw_module_methods_t copybit_module_methods = {
-    .open = open_copybit,
-};
-
-/*
- * The COPYBIT Module
- */
-struct copybit_module_t HAL_MODULE_INFO_SYM = {
-    .common = {
-        .tag =  HARDWARE_MODULE_TAG,
-        .version_major = 1,
-        .version_minor = 0,
-        .id = COPYBIT_HARDWARE_MODULE_ID,
-        .name = "QCT COPYBIT C2D 2.0 Module",
-        .author = "Qualcomm",
-        .methods =  &copybit_module_methods
-    }
-};
-
-
-/* thread function which waits on the timeStamp and cleans up the surfaces */
-static void* c2d_wait_loop(void* ptr) {
-    copybit_context_t* ctx = (copybit_context_t*)(ptr);
-    char thread_name[64] = "copybitWaitThr";
-    prctl(PR_SET_NAME, (unsigned long) &thread_name, 0, 0, 0);
-    setpriority(PRIO_PROCESS, 0, HAL_PRIORITY_URGENT_DISPLAY);
-
-    while(ctx->stop_thread == false) {
-        pthread_mutex_lock(&ctx->wait_cleanup_lock);
-        while(ctx->wait_timestamp == false && !ctx->stop_thread) {
-            pthread_cond_wait(&(ctx->wait_cleanup_cond),
-                              &(ctx->wait_cleanup_lock));
-        }
-        if(ctx->wait_timestamp) {
-            if(LINK_c2dWaitTimestamp(ctx->time_stamp)) {
-                ALOGE("%s: LINK_c2dWaitTimeStamp ERROR!!", __FUNCTION__);
-            }
-            ctx->wait_timestamp = false;
-            // Unmap any mapped addresses.
-            for (int i = 0; i < MAX_SURFACES; i++) {
-                if (ctx->mapped_gpu_addr[i]) {
-                    LINK_c2dUnMapAddr( (void*)ctx->mapped_gpu_addr[i]);
-                    ctx->mapped_gpu_addr[i] = 0;
-                }
-            }
-            // Reset the counts after the draw.
-            ctx->blit_rgb_count = 0;
-            ctx->blit_yuv_2_plane_count = 0;
-            ctx->blit_yuv_3_plane_count = 0;
-            ctx->blit_count = 0;
-            ctx->dst_surface_mapped = false;
-            ctx->dst_surface_base = 0;
-        }
-        pthread_mutex_unlock(&ctx->wait_cleanup_lock);
-        if(ctx->stop_thread)
-            break;
-    }
-    pthread_exit(NULL);
-    return NULL;
-}
-
-
-/* convert COPYBIT_FORMAT to C2D format */
-static int get_format(int format) {
-    switch (format) {
-        case HAL_PIXEL_FORMAT_RGB_565:        return C2D_COLOR_FORMAT_565_RGB;
-        case HAL_PIXEL_FORMAT_RGB_888:        return C2D_COLOR_FORMAT_888_RGB |
-                                              C2D_FORMAT_SWAP_RB;
-        case HAL_PIXEL_FORMAT_RGBX_8888:      return C2D_COLOR_FORMAT_8888_ARGB |
-                                              C2D_FORMAT_SWAP_RB |
-                                                  C2D_FORMAT_DISABLE_ALPHA;
-        case HAL_PIXEL_FORMAT_RGBA_8888:      return C2D_COLOR_FORMAT_8888_ARGB |
-                                              C2D_FORMAT_SWAP_RB;
-        case HAL_PIXEL_FORMAT_BGRA_8888:      return C2D_COLOR_FORMAT_8888_ARGB;
-        case HAL_PIXEL_FORMAT_RGBA_5551:      return C2D_COLOR_FORMAT_5551_RGBA;
-        case HAL_PIXEL_FORMAT_RGBA_4444:      return C2D_COLOR_FORMAT_4444_RGBA;
-        case HAL_PIXEL_FORMAT_YCbCr_420_SP:   return C2D_COLOR_FORMAT_420_NV12;
-        case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:return C2D_COLOR_FORMAT_420_NV12;
-        case HAL_PIXEL_FORMAT_YCrCb_420_SP:   return C2D_COLOR_FORMAT_420_NV21;
-        case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED: return C2D_COLOR_FORMAT_420_NV12 |
-                                                  C2D_FORMAT_MACROTILED;
-        default:                              ALOGE("%s: invalid format (0x%x",
-                                                     __FUNCTION__, format);
-                                              return -EINVAL;
-    }
-    return -EINVAL;
-}
-
-/* Get the C2D formats needed for conversion to YUV */
-static int get_c2d_format_for_yuv_destination(int halFormat) {
-    switch (halFormat) {
-        // We do not swap the RB when the target is YUV
-        case HAL_PIXEL_FORMAT_RGBX_8888:      return C2D_COLOR_FORMAT_8888_ARGB |
-                                              C2D_FORMAT_DISABLE_ALPHA;
-        case HAL_PIXEL_FORMAT_RGBA_8888:      return C2D_COLOR_FORMAT_8888_ARGB;
-        // The U and V need to be interchanged when the target is YUV
-        case HAL_PIXEL_FORMAT_YCbCr_420_SP:   return C2D_COLOR_FORMAT_420_NV21;
-        case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:return C2D_COLOR_FORMAT_420_NV21;
-        case HAL_PIXEL_FORMAT_YCrCb_420_SP:   return C2D_COLOR_FORMAT_420_NV12;
-        default:                              return get_format(halFormat);
-    }
-    return -EINVAL;
-}
-
-/* ------------------------------------------------------------------- *//*!
- * \internal
- * \brief Get the bpp for a particular color format
- * \param color format
- * \return bits per pixel
- *//* ------------------------------------------------------------------- */
-int c2diGetBpp(int32 colorformat)
-{
-
-    int c2dBpp = 0;
-
-    switch(colorformat&0xFF)
-    {
-        case C2D_COLOR_FORMAT_4444_RGBA:
-        case C2D_COLOR_FORMAT_4444_ARGB:
-        case C2D_COLOR_FORMAT_1555_ARGB:
-        case C2D_COLOR_FORMAT_565_RGB:
-        case C2D_COLOR_FORMAT_5551_RGBA:
-            c2dBpp = 16;
-            break;
-        case C2D_COLOR_FORMAT_8888_RGBA:
-        case C2D_COLOR_FORMAT_8888_ARGB:
-            c2dBpp = 32;
-            break;
-        case C2D_COLOR_FORMAT_888_RGB:
-            c2dBpp = 24;
-            break;
-        case C2D_COLOR_FORMAT_8_L:
-        case C2D_COLOR_FORMAT_8_A:
-            c2dBpp = 8;
-            break;
-        case C2D_COLOR_FORMAT_4_A:
-            c2dBpp = 4;
-            break;
-        case C2D_COLOR_FORMAT_1:
-            c2dBpp = 1;
-            break;
-        default:
-            ALOGE("%s ERROR", __func__);
-            break;
-    }
-    return c2dBpp;
-}
-
-static size_t c2d_get_gpuaddr(copybit_context_t* ctx,
-                              struct private_handle_t *handle, int &mapped_idx)
-{
-    uint32 memtype;
-    size_t *gpuaddr = 0;
-    C2D_STATUS rc;
-    int freeindex = 0;
-    bool mapaddr = false;
-
-    if(!handle)
-        return 0;
-
-    if (handle->flags & private_handle_t::PRIV_FLAGS_USES_ION)
-        memtype = KGSL_USER_MEM_TYPE_ION;
-    else {
-        ALOGE("Invalid handle flags: 0x%x", handle->flags);
-        return 0;
-    }
-
-    // Check for a freeindex in the mapped_gpu_addr list
-    for (freeindex = 0; freeindex < MAX_SURFACES; freeindex++) {
-        if (ctx->mapped_gpu_addr[freeindex] == 0) {
-            // free index is available
-            // map GPU addr and use this as mapped_idx
-            mapaddr = true;
-            break;
-        }
-    }
-
-    if(mapaddr) {
-        rc = LINK_c2dMapAddr(handle->fd, (void*)handle->base, handle->size,
-                             handle->offset, memtype, (void**)&gpuaddr);
-
-        if (rc == C2D_STATUS_OK) {
-            // We have mapped the GPU address inside copybit. We need to unmap
-            // this address after the blit. Store this address
-            ctx->mapped_gpu_addr[freeindex] = (size_t)gpuaddr;
-            mapped_idx = freeindex;
-        }
-    }
-    return (size_t)gpuaddr;
-}
-
-static void unmap_gpuaddr(copybit_context_t* ctx, int mapped_idx)
-{
-    if (!ctx || (mapped_idx == -1))
-        return;
-
-    if (ctx->mapped_gpu_addr[mapped_idx]) {
-        LINK_c2dUnMapAddr( (void*)ctx->mapped_gpu_addr[mapped_idx]);
-        ctx->mapped_gpu_addr[mapped_idx] = 0;
-    }
-}
-
-static int is_supported_rgb_format(int format)
-{
-    switch(format) {
-        case HAL_PIXEL_FORMAT_RGBA_8888:
-        case HAL_PIXEL_FORMAT_RGBX_8888:
-        case HAL_PIXEL_FORMAT_RGB_888:
-        case HAL_PIXEL_FORMAT_RGB_565:
-        case HAL_PIXEL_FORMAT_BGRA_8888:
-        case HAL_PIXEL_FORMAT_RGBA_5551:
-        case HAL_PIXEL_FORMAT_RGBA_4444: {
-            return COPYBIT_SUCCESS;
-        }
-        default:
-            return COPYBIT_FAILURE;
-    }
-}
-
-static int get_num_planes(int format)
-{
-    switch(format) {
-        case HAL_PIXEL_FORMAT_YCbCr_420_SP:
-        case HAL_PIXEL_FORMAT_YCrCb_420_SP:
-        case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
-        case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED: {
-            return 2;
-        }
-        case HAL_PIXEL_FORMAT_YV12: {
-            return 3;
-        }
-        default:
-            return COPYBIT_FAILURE;
-    }
-}
-
-static int is_supported_yuv_format(int format)
-{
-    switch(format) {
-        case HAL_PIXEL_FORMAT_YCbCr_420_SP:
-        case HAL_PIXEL_FORMAT_YCrCb_420_SP:
-        case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
-        case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED: {
-            return COPYBIT_SUCCESS;
-        }
-        default:
-            return COPYBIT_FAILURE;
-    }
-}
-
-static int is_valid_destination_format(int format)
-{
-    if (format == HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED) {
-        // C2D does not support NV12Tile as a destination format.
-        return COPYBIT_FAILURE;
-    }
-    return COPYBIT_SUCCESS;
-}
-
-static int calculate_yuv_offset_and_stride(const bufferInfo& info,
-                                           yuvPlaneInfo& yuvInfo)
-{
-    int width  = info.width;
-    int height = info.height;
-    int format = info.format;
-
-    int aligned_height = 0;
-    int aligned_width = 0, size = 0;
-
-    switch (format) {
-        case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED: {
-            /* NV12 Tile buffers have their luma height aligned to 32bytes and width
-             * aligned to 128 bytes. The chroma offset starts at an 8K boundary
-             */
-            aligned_height = ALIGN(height, 32);
-            aligned_width  = ALIGN(width, 128);
-            size = aligned_width * aligned_height;
-            yuvInfo.plane1_offset = ALIGN(size,8192);
-            yuvInfo.yStride = aligned_width;
-            yuvInfo.plane1_stride = aligned_width;
-            break;
-        }
-        case HAL_PIXEL_FORMAT_YCbCr_420_SP:
-        case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
-        case HAL_PIXEL_FORMAT_YCrCb_420_SP: {
-            aligned_width = ALIGN(width, 32);
-            yuvInfo.yStride = aligned_width;
-            yuvInfo.plane1_stride = aligned_width;
-            if (HAL_PIXEL_FORMAT_NV12_ENCODEABLE == format) {
-                // The encoder requires a 2K aligned chroma offset
-                yuvInfo.plane1_offset = ALIGN(aligned_width * height, 2048);
-            } else
-                yuvInfo.plane1_offset = aligned_width * height;
-
-            break;
-        }
-        default: {
-            return COPYBIT_FAILURE;
-        }
-    }
-    return COPYBIT_SUCCESS;
-}
-
-/** create C2D surface from copybit image */
-static int set_image(copybit_context_t* ctx, uint32 surfaceId,
-                      const struct copybit_image_t *rhs,
-                      const eC2DFlags flags, int &mapped_idx)
-{
-    struct private_handle_t* handle = (struct private_handle_t*)rhs->handle;
-    C2D_SURFACE_TYPE surfaceType;
-    int status = COPYBIT_SUCCESS;
-    uint64_t gpuaddr = 0;
-    int c2d_format;
-    mapped_idx = -1;
-
-    if (flags & FLAGS_YUV_DESTINATION) {
-        c2d_format = get_c2d_format_for_yuv_destination(rhs->format);
-    } else {
-        c2d_format = get_format(rhs->format);
-    }
-
-    if(c2d_format == -EINVAL) {
-        ALOGE("%s: invalid format", __FUNCTION__);
-        return -EINVAL;
-    }
-
-    if(handle == NULL) {
-        ALOGE("%s: invalid handle", __func__);
-        return -EINVAL;
-    }
-
-    if (handle->gpuaddr == 0) {
-        gpuaddr = c2d_get_gpuaddr(ctx, handle, mapped_idx);
-        if(!gpuaddr) {
-            ALOGE("%s: c2d_get_gpuaddr failed", __FUNCTION__);
-            return COPYBIT_FAILURE;
-        }
-    } else {
-        gpuaddr = handle->gpuaddr;
-    }
-
-    /* create C2D surface */
-    if(is_supported_rgb_format(rhs->format) == COPYBIT_SUCCESS) {
-        /* RGB */
-        C2D_RGB_SURFACE_DEF surfaceDef;
-
-        surfaceType = (C2D_SURFACE_TYPE) (C2D_SURFACE_RGB_HOST | C2D_SURFACE_WITH_PHYS);
-
-        surfaceDef.phys = (void*) gpuaddr;
-        surfaceDef.buffer = (void*) (handle->base);
-
-        surfaceDef.format = c2d_format |
-            ((flags & FLAGS_PREMULTIPLIED_ALPHA) ? C2D_FORMAT_PREMULTIPLIED : 0);
-
-        surfaceDef.format = surfaceDef.format |
-            ((flags & FLAGS_UBWC_FORMAT_MODE) ? C2D_FORMAT_UBWC_COMPRESSED : 0);
-
-        surfaceDef.width = rhs->w;
-        surfaceDef.height = rhs->h;
-        int aligned_width = ALIGN((int)surfaceDef.width,32);
-        surfaceDef.stride = (aligned_width * c2diGetBpp(surfaceDef.format))>>3;
-
-        if(LINK_c2dUpdateSurface( surfaceId,C2D_TARGET | C2D_SOURCE, surfaceType,
-                                  &surfaceDef)) {
-            ALOGE("%s: RGB Surface c2dUpdateSurface ERROR", __FUNCTION__);
-            unmap_gpuaddr(ctx, mapped_idx);
-            status = COPYBIT_FAILURE;
-        }
-    } else if (is_supported_yuv_format(rhs->format) == COPYBIT_SUCCESS) {
-        C2D_YUV_SURFACE_DEF surfaceDef;
-        memset(&surfaceDef, 0, sizeof(surfaceDef));
-        surfaceType = (C2D_SURFACE_TYPE)(C2D_SURFACE_YUV_HOST | C2D_SURFACE_WITH_PHYS);
-        surfaceDef.format = c2d_format;
-
-        bufferInfo info;
-        info.width = rhs->w;
-        info.height = rhs->h;
-        info.format = rhs->format;
-
-        yuvPlaneInfo yuvInfo = {0};
-        status = calculate_yuv_offset_and_stride(info, yuvInfo);
-        if(status != COPYBIT_SUCCESS) {
-            ALOGE("%s: calculate_yuv_offset_and_stride error", __FUNCTION__);
-            unmap_gpuaddr(ctx, mapped_idx);
-        }
-
-        surfaceDef.width = rhs->w;
-        surfaceDef.height = rhs->h;
-        surfaceDef.plane0 = (void*) (handle->base);
-        surfaceDef.phys0 = (void*) (gpuaddr);
-        surfaceDef.stride0 = yuvInfo.yStride;
-
-        surfaceDef.plane1 = (void*) (handle->base + yuvInfo.plane1_offset);
-        surfaceDef.phys1 = (void*) (gpuaddr + yuvInfo.plane1_offset);
-        surfaceDef.stride1 = yuvInfo.plane1_stride;
-        if (3 == get_num_planes(rhs->format)) {
-            surfaceDef.plane2 = (void*) (handle->base + yuvInfo.plane2_offset);
-            surfaceDef.phys2 = (void*) (gpuaddr + yuvInfo.plane2_offset);
-            surfaceDef.stride2 = yuvInfo.plane2_stride;
-        }
-
-        if(LINK_c2dUpdateSurface( surfaceId,C2D_TARGET | C2D_SOURCE, surfaceType,
-                                  &surfaceDef)) {
-            ALOGE("%s: YUV Surface c2dUpdateSurface ERROR", __FUNCTION__);
-            unmap_gpuaddr(ctx, mapped_idx);
-            status = COPYBIT_FAILURE;
-        }
-    } else {
-        ALOGE("%s: invalid format 0x%x", __FUNCTION__, rhs->format);
-        unmap_gpuaddr(ctx, mapped_idx);
-        status = COPYBIT_FAILURE;
-    }
-
-    return status;
-}
-
-/** copy the bits */
-static int msm_copybit(struct copybit_context_t *ctx, unsigned int target)
-{
-    if (ctx->blit_count == 0) {
-        return COPYBIT_SUCCESS;
-    }
-
-    for (int i = 0; i < ctx->blit_count; i++)
-    {
-        ctx->blit_list[i].next = &(ctx->blit_list[i+1]);
-    }
-    ctx->blit_list[ctx->blit_count-1].next = NULL;
-    uint32_t target_transform = ctx->trg_transform;
-    if (ctx->c2d_driver_info.capabilities_mask &
-        C2D_DRIVER_SUPPORTS_OVERRIDE_TARGET_ROTATE_OP) {
-        // For A3xx - set 0x0 as the transform is set in the config_mask
-        target_transform = 0x0;
-    }
-    if(LINK_c2dDraw(target, target_transform, 0x0, 0, 0, ctx->blit_list,
-                    ctx->blit_count)) {
-        ALOGE("%s: LINK_c2dDraw ERROR", __FUNCTION__);
-        return COPYBIT_FAILURE;
-    }
-    return COPYBIT_SUCCESS;
-}
-
-
-
-static int flush_get_fence_copybit (struct copybit_device_t *dev, int* fd)
-{
-    struct copybit_context_t* ctx = (struct copybit_context_t*)dev;
-    int status = COPYBIT_FAILURE;
-    if (!ctx)
-        return COPYBIT_FAILURE;
-    pthread_mutex_lock(&ctx->wait_cleanup_lock);
-    status = msm_copybit(ctx, ctx->dst[ctx->dst_surface_type]);
-
-    if(LINK_c2dFlush(ctx->dst[ctx->dst_surface_type], &ctx->time_stamp)) {
-        ALOGE("%s: LINK_c2dFlush ERROR", __FUNCTION__);
-        // unlock the mutex and return failure
-        pthread_mutex_unlock(&ctx->wait_cleanup_lock);
-        return COPYBIT_FAILURE;
-    }
-    if(LINK_c2dCreateFenceFD(ctx->dst[ctx->dst_surface_type], ctx->time_stamp,
-                                                                        fd)) {
-        ALOGE("%s: LINK_c2dCreateFenceFD ERROR", __FUNCTION__);
-        status = COPYBIT_FAILURE;
-    }
-    if(status == COPYBIT_SUCCESS) {
-        //signal the wait_thread
-        ctx->wait_timestamp = true;
-        pthread_cond_signal(&ctx->wait_cleanup_cond);
-    }
-    pthread_mutex_unlock(&ctx->wait_cleanup_lock);
-    return status;
-}
-
-static int finish_copybit(struct copybit_device_t *dev)
-{
-    struct copybit_context_t* ctx = (struct copybit_context_t*)dev;
-    if (!ctx)
-        return COPYBIT_FAILURE;
-
-   int status = msm_copybit(ctx, ctx->dst[ctx->dst_surface_type]);
-
-   if(LINK_c2dFinish(ctx->dst[ctx->dst_surface_type])) {
-        ALOGE("%s: LINK_c2dFinish ERROR", __FUNCTION__);
-        return COPYBIT_FAILURE;
-    }
-
-    // Unmap any mapped addresses.
-    for (int i = 0; i < MAX_SURFACES; i++) {
-        if (ctx->mapped_gpu_addr[i]) {
-            LINK_c2dUnMapAddr( (void*)ctx->mapped_gpu_addr[i]);
-            ctx->mapped_gpu_addr[i] = 0;
-        }
-    }
-
-    // Reset the counts after the draw.
-    ctx->blit_rgb_count = 0;
-    ctx->blit_yuv_2_plane_count = 0;
-    ctx->blit_yuv_3_plane_count = 0;
-    ctx->blit_count = 0;
-    ctx->dst_surface_mapped = false;
-    ctx->dst_surface_base = 0;
-
-    return status;
-}
-
-static int clear_copybit(struct copybit_device_t *dev,
-                         struct copybit_image_t const *buf,
-                         struct copybit_rect_t *rect)
-{
-    int ret = COPYBIT_SUCCESS;
-    int flags = FLAGS_PREMULTIPLIED_ALPHA;
-    int mapped_dst_idx = -1;
-    struct copybit_context_t* ctx = (struct copybit_context_t*)dev;
-    if (ctx->is_dst_ubwc_format)
-        flags |= FLAGS_UBWC_FORMAT_MODE;
-    C2D_RECT c2drect = {rect->l, rect->t, rect->r - rect->l, rect->b - rect->t};
-    pthread_mutex_lock(&ctx->wait_cleanup_lock);
-    if(!ctx->dst_surface_mapped) {
-        ret = set_image(ctx, ctx->dst[RGB_SURFACE], buf,
-                        (eC2DFlags)flags, mapped_dst_idx);
-        if(ret) {
-            ALOGE("%s: set_image error", __FUNCTION__);
-            unmap_gpuaddr(ctx, mapped_dst_idx);
-            pthread_mutex_unlock(&ctx->wait_cleanup_lock);
-            return COPYBIT_FAILURE;
-        }
-        //clear_copybit is the first call made by HWC for each composition
-        //with the dest surface, hence set dst_surface_mapped.
-        ctx->dst_surface_mapped = true;
-        ctx->dst_surface_base = buf->base;
-        ret = LINK_c2dFillSurface(ctx->dst[RGB_SURFACE], 0x0, &c2drect);
-    }
-    pthread_mutex_unlock(&ctx->wait_cleanup_lock);
-    return ret;
-}
-
-
-/** setup rectangles */
-static void set_rects(struct copybit_context_t *ctx,
-                      C2D_OBJECT *c2dObject,
-                      const struct copybit_rect_t *dst,
-                      const struct copybit_rect_t *src,
-                      const struct copybit_rect_t *scissor)
-{
-    // Set the target rect.
-    if((ctx->trg_transform & C2D_TARGET_ROTATE_90) &&
-       (ctx->trg_transform & C2D_TARGET_ROTATE_180)) {
-        /* target rotation is 270 */
-        c2dObject->target_rect.x        = (dst->t)<<16;
-        c2dObject->target_rect.y        = ctx->fb_width?
-                (ALIGN(ctx->fb_width,32)- dst->r):dst->r;
-        c2dObject->target_rect.y        = c2dObject->target_rect.y<<16;
-        c2dObject->target_rect.height   = ((dst->r) - (dst->l))<<16;
-        c2dObject->target_rect.width    = ((dst->b) - (dst->t))<<16;
-    } else if(ctx->trg_transform & C2D_TARGET_ROTATE_90) {
-        c2dObject->target_rect.x        = ctx->fb_height?(ctx->fb_height - dst->b):dst->b;
-        c2dObject->target_rect.x        = c2dObject->target_rect.x<<16;
-        c2dObject->target_rect.y        = (dst->l)<<16;
-        c2dObject->target_rect.height   = ((dst->r) - (dst->l))<<16;
-        c2dObject->target_rect.width    = ((dst->b) - (dst->t))<<16;
-    } else if(ctx->trg_transform & C2D_TARGET_ROTATE_180) {
-        c2dObject->target_rect.y        = ctx->fb_height?(ctx->fb_height - dst->b):dst->b;
-        c2dObject->target_rect.y        = c2dObject->target_rect.y<<16;
-        c2dObject->target_rect.x        = ctx->fb_width?
-                (ALIGN(ctx->fb_width,32) - dst->r):dst->r;
-        c2dObject->target_rect.x        = c2dObject->target_rect.x<<16;
-        c2dObject->target_rect.height   = ((dst->b) - (dst->t))<<16;
-        c2dObject->target_rect.width    = ((dst->r) - (dst->l))<<16;
-    } else {
-        c2dObject->target_rect.x        = (dst->l)<<16;
-        c2dObject->target_rect.y        = (dst->t)<<16;
-        c2dObject->target_rect.height   = ((dst->b) - (dst->t))<<16;
-        c2dObject->target_rect.width    = ((dst->r) - (dst->l))<<16;
-    }
-    c2dObject->config_mask |= C2D_TARGET_RECT_BIT;
-
-    // Set the source rect
-    c2dObject->source_rect.x        = (src->l)<<16;
-    c2dObject->source_rect.y        = (src->t)<<16;
-    c2dObject->source_rect.height   = ((src->b) - (src->t))<<16;
-    c2dObject->source_rect.width    = ((src->r) - (src->l))<<16;
-    c2dObject->config_mask |= C2D_SOURCE_RECT_BIT;
-
-    // Set the scissor rect
-    c2dObject->scissor_rect.x       = scissor->l;
-    c2dObject->scissor_rect.y       = scissor->t;
-    c2dObject->scissor_rect.height  = (scissor->b) - (scissor->t);
-    c2dObject->scissor_rect.width   = (scissor->r) - (scissor->l);
-    c2dObject->config_mask |= C2D_SCISSOR_RECT_BIT;
-}
-
-/*****************************************************************************/
-
-/** Set a parameter to value */
-static int set_parameter_copybit(
-    struct copybit_device_t *dev,
-    int name,
-    int value)
-{
-    struct copybit_context_t* ctx = (struct copybit_context_t*)dev;
-    int status = COPYBIT_SUCCESS;
-    if (!ctx) {
-        ALOGE("%s: null context", __FUNCTION__);
-        return -EINVAL;
-    }
-
-    pthread_mutex_lock(&ctx->wait_cleanup_lock);
-    switch(name) {
-        case COPYBIT_PLANE_ALPHA:
-        {
-            if (value < 0)      value = 0;
-            if (value >= 256)   value = 255;
-
-            ctx->src_global_alpha = value;
-            if (value < 255)
-                ctx->config_mask |= C2D_GLOBAL_ALPHA_BIT;
-            else
-                ctx->config_mask &= ~C2D_GLOBAL_ALPHA_BIT;
-        }
-        break;
-        case COPYBIT_BLEND_MODE:
-        {
-            if (value == COPYBIT_BLENDING_NONE) {
-                ctx->config_mask |= C2D_ALPHA_BLEND_NONE;
-                ctx->is_premultiplied_alpha = true;
-            } else if (value == COPYBIT_BLENDING_PREMULT) {
-                ctx->is_premultiplied_alpha = true;
-            } else {
-                ctx->config_mask &= ~C2D_ALPHA_BLEND_NONE;
-            }
-        }
-        break;
-        case COPYBIT_TRANSFORM:
-        {
-            unsigned int transform = 0;
-            uint32 config_mask = 0;
-            config_mask |= C2D_OVERRIDE_GLOBAL_TARGET_ROTATE_CONFIG;
-            if((value & 0x7) == COPYBIT_TRANSFORM_ROT_180) {
-                transform = C2D_TARGET_ROTATE_180;
-                config_mask |= C2D_OVERRIDE_TARGET_ROTATE_180;
-            } else if((value & 0x7) == COPYBIT_TRANSFORM_ROT_270) {
-                transform = C2D_TARGET_ROTATE_90;
-                config_mask |= C2D_OVERRIDE_TARGET_ROTATE_90;
-            } else if(value == COPYBIT_TRANSFORM_ROT_90) {
-                transform = C2D_TARGET_ROTATE_270;
-                config_mask |= C2D_OVERRIDE_TARGET_ROTATE_270;
-            } else {
-                config_mask |= C2D_OVERRIDE_TARGET_ROTATE_0;
-                if(value & COPYBIT_TRANSFORM_FLIP_H) {
-                    config_mask |= C2D_MIRROR_H_BIT;
-                } else if(value & COPYBIT_TRANSFORM_FLIP_V) {
-                    config_mask |= C2D_MIRROR_V_BIT;
-                }
-            }
-
-            if (ctx->c2d_driver_info.capabilities_mask &
-                C2D_DRIVER_SUPPORTS_OVERRIDE_TARGET_ROTATE_OP) {
-                ctx->config_mask |= config_mask;
-            } else {
-                // The transform for this surface does not match the current
-                // target transform. Draw all previous surfaces. This will be
-                // changed once we have a new mechanism to send different
-                // target rotations to c2d.
-                finish_copybit(dev);
-            }
-            ctx->trg_transform = transform;
-        }
-        break;
-        case COPYBIT_FRAMEBUFFER_WIDTH:
-            ctx->fb_width = value;
-            break;
-        case COPYBIT_FRAMEBUFFER_HEIGHT:
-            ctx->fb_height = value;
-            break;
-        case COPYBIT_ROTATION_DEG:
-        case COPYBIT_DITHER:
-        case COPYBIT_BLUR:
-        case COPYBIT_BLIT_TO_FRAMEBUFFER:
-            // Do nothing
-            break;
-        case COPYBIT_SRC_FORMAT_MODE:
-            ctx->is_src_ubwc_format = (value == COPYBIT_UBWC_COMPRESSED);
-            break;
-        case COPYBIT_DST_FORMAT_MODE:
-            ctx->is_dst_ubwc_format = (value == COPYBIT_UBWC_COMPRESSED);
-            break;
-        default:
-            ALOGE("%s: default case param=0x%x", __FUNCTION__, name);
-            status = -EINVAL;
-            break;
-    }
-    pthread_mutex_unlock(&ctx->wait_cleanup_lock);
-    return status;
-}
-
-/** Get a static info value */
-static int get(struct copybit_device_t *dev, int name)
-{
-    struct copybit_context_t* ctx = (struct copybit_context_t*)dev;
-    int value;
-
-    if (!ctx) {
-        ALOGE("%s: null context error", __FUNCTION__);
-        return -EINVAL;
-    }
-
-    switch(name) {
-        case COPYBIT_MINIFICATION_LIMIT:
-            value = MAX_SCALE_FACTOR;
-            break;
-        case COPYBIT_MAGNIFICATION_LIMIT:
-            value = MAX_SCALE_FACTOR;
-            break;
-        case COPYBIT_SCALING_FRAC_BITS:
-            value = 32;
-            break;
-        case COPYBIT_ROTATION_STEP_DEG:
-            value = 1;
-            break;
-        case COPYBIT_UBWC_SUPPORT:
-            value = 0;
-            if (ctx->c2d_driver_info.capabilities_mask & C2D_DRIVER_SUPPORTS_UBWC_COMPRESSED_OP) {
-                value = 1;
-            }
-            break;
-        default:
-            ALOGE("%s: default case param=0x%x", __FUNCTION__, name);
-            value = -EINVAL;
-    }
-    return value;
-}
-
-/* Function to check if we need a temporary buffer for the blit.
- * This would happen if the requested destination stride and the
- * C2D stride do not match. We ignore RGB buffers, since their
- * stride is always aligned to 32.
- */
-static bool need_temp_buffer(struct copybit_image_t const *img)
-{
-    if (COPYBIT_SUCCESS == is_supported_rgb_format(img->format))
-        return false;
-
-    struct private_handle_t* handle = (struct private_handle_t*)img->handle;
-
-    // The width parameter in the handle contains the aligned_w. We check if we
-    // need to convert based on this param. YUV formats have bpp=1, so checking
-    // if the requested stride is aligned should suffice.
-    if (0 == (handle->width)%32) {
-        return false;
-    }
-
-    return true;
-}
-
-/* Function to extract the information from the copybit image and set the corresponding
- * values in the bufferInfo struct.
- */
-static void populate_buffer_info(struct copybit_image_t const *img, bufferInfo& info)
-{
-    info.width = img->w;
-    info.height = img->h;
-    info.format = img->format;
-}
-
-/* Function to get the required size for a particular format, inorder for C2D to perform
- * the blit operation.
- */
-static int get_size(const bufferInfo& info)
-{
-    int size = 0;
-    int w = info.width;
-    int h = info.height;
-    int aligned_w = ALIGN(w, 32);
-    switch(info.format) {
-        case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
-            {
-                // Chroma for this format is aligned to 2K.
-                size = ALIGN((aligned_w*h), 2048) +
-                        ALIGN(aligned_w/2, 32) * (h/2) *2;
-                size = ALIGN(size, 4096);
-            } break;
-        case HAL_PIXEL_FORMAT_YCbCr_420_SP:
-        case HAL_PIXEL_FORMAT_YCrCb_420_SP:
-            {
-                size = aligned_w * h +
-                       ALIGN(aligned_w/2, 32) * (h/2) * 2;
-                size = ALIGN(size, 4096);
-            } break;
-        default: break;
-    }
-    return size;
-}
-
-/* Function to allocate memory for the temporary buffer. This memory is
- * allocated from Ashmem. It is the caller's responsibility to free this
- * memory.
- */
-static int get_temp_buffer(const bufferInfo& info, alloc_data& data)
-{
-    ALOGD("%s E", __FUNCTION__);
-    // Alloc memory from system heap
-    data.base = 0;
-    data.fd = -1;
-    data.offset = 0;
-    data.size = get_size(info);
-    data.align = getpagesize();
-    data.uncached = true;
-    int allocFlags = 0;
-
-    if (sAlloc == 0) {
-        sAlloc = gralloc::IAllocController::getInstance();
-    }
-
-    if (sAlloc == 0) {
-        ALOGE("%s: sAlloc is still NULL", __FUNCTION__);
-        return COPYBIT_FAILURE;
-    }
-
-    int err = sAlloc->allocate(data, allocFlags);
-    if (0 != err) {
-        ALOGE("%s: allocate failed", __FUNCTION__);
-        return COPYBIT_FAILURE;
-    }
-
-    ALOGD("%s X", __FUNCTION__);
-    return err;
-}
-
-/* Function to free the temporary allocated memory.*/
-static void free_temp_buffer(alloc_data &data)
-{
-    if (-1 != data.fd) {
-        IMemAlloc* memalloc = sAlloc->getAllocator(data.allocType);
-        memalloc->free_buffer(data.base, data.size, 0, data.fd);
-    }
-}
-
-/* Function to perform the software color conversion. Convert the
- * C2D compatible format to the Android compatible format
- */
-static int copy_image(private_handle_t *src_handle,
-                      struct copybit_image_t const *rhs,
-                      eConversionType conversionType)
-{
-    if (src_handle->fd == -1) {
-        ALOGE("%s: src_handle fd is invalid", __FUNCTION__);
-        return COPYBIT_FAILURE;
-    }
-
-    // Copy the info.
-    int ret = COPYBIT_SUCCESS;
-    switch(rhs->format) {
-        case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
-        case HAL_PIXEL_FORMAT_YCbCr_420_SP:
-        case HAL_PIXEL_FORMAT_YCrCb_420_SP:
-            {
-                if (CONVERT_TO_ANDROID_FORMAT == conversionType) {
-                    return convert_yuv_c2d_to_yuv_android(src_handle, rhs);
-                } else {
-                    return convert_yuv_android_to_yuv_c2d(src_handle, rhs);
-                }
-
-            } break;
-        default: {
-            ALOGE("%s: invalid format 0x%x", __FUNCTION__, rhs->format);
-            ret = COPYBIT_FAILURE;
-        } break;
-    }
-    return ret;
-}
-
-static void delete_handle(private_handle_t *handle)
-{
-    if (handle) {
-        delete handle;
-        handle = 0;
-    }
-}
-
-static bool need_to_execute_draw(eC2DFlags flags)
-{
-    if (flags & FLAGS_TEMP_SRC_DST) {
-        return true;
-    }
-    if (flags & FLAGS_YUV_DESTINATION) {
-        return true;
-    }
-    return false;
-}
-
-/** do a stretch blit type operation */
-static int stretch_copybit_internal(
-    struct copybit_device_t *dev,
-    struct copybit_image_t const *dst,
-    struct copybit_image_t const *src,
-    struct copybit_rect_t const *dst_rect,
-    struct copybit_rect_t const *src_rect,
-    struct copybit_region_t const *region,
-    bool enableBlend)
-{
-    struct copybit_context_t* ctx = (struct copybit_context_t*)dev;
-    int status = COPYBIT_SUCCESS;
-    int flags = 0;
-    int src_surface_type;
-    int mapped_src_idx = -1, mapped_dst_idx = -1;
-    C2D_OBJECT_STR src_surface;
-
-    if (!ctx) {
-        ALOGE("%s: null context error", __FUNCTION__);
-        return -EINVAL;
-    }
-
-    if (src->w > MAX_DIMENSION || src->h > MAX_DIMENSION) {
-        ALOGE("%s: src dimension error", __FUNCTION__);
-        return -EINVAL;
-    }
-
-    if (dst->w > MAX_DIMENSION || dst->h > MAX_DIMENSION) {
-        ALOGE("%s : dst dimension error dst w %d h %d",  __FUNCTION__, dst->w,
-                                                         dst->h);
-        return -EINVAL;
-    }
-
-    if (is_valid_destination_format(dst->format) == COPYBIT_FAILURE) {
-        ALOGE("%s: Invalid destination format format = 0x%x", __FUNCTION__,
-                                                              dst->format);
-        return COPYBIT_FAILURE;
-    }
-
-    int dst_surface_type;
-    if (ctx->is_dst_ubwc_format)
-        flags |= FLAGS_UBWC_FORMAT_MODE;
-
-    if (is_supported_rgb_format(dst->format) == COPYBIT_SUCCESS) {
-        dst_surface_type = RGB_SURFACE;
-        flags |= FLAGS_PREMULTIPLIED_ALPHA;
-    } else if (is_supported_yuv_format(dst->format) == COPYBIT_SUCCESS) {
-        int num_planes = get_num_planes(dst->format);
-        flags |= FLAGS_YUV_DESTINATION;
-        if (num_planes == 2) {
-            dst_surface_type = YUV_SURFACE_2_PLANES;
-        } else if (num_planes == 3) {
-            dst_surface_type = YUV_SURFACE_3_PLANES;
-        } else {
-            ALOGE("%s: dst number of YUV planes is invalid dst format = 0x%x",
-                  __FUNCTION__, dst->format);
-            return COPYBIT_FAILURE;
-        }
-    } else {
-        ALOGE("%s: Invalid dst surface format 0x%x", __FUNCTION__,
-                                                     dst->format);
-        return COPYBIT_FAILURE;
-    }
-
-    if (ctx->blit_rgb_count == MAX_RGB_SURFACES ||
-        ctx->blit_yuv_2_plane_count == MAX_YUV_2_PLANE_SURFACES ||
-        ctx->blit_yuv_3_plane_count == MAX_YUV_2_PLANE_SURFACES ||
-        ctx->blit_count == MAX_BLIT_OBJECT_COUNT ||
-        ctx->dst_surface_type != dst_surface_type) {
-        // we have reached the max. limits of our internal structures or
-        // changed the target.
-        // Draw the remaining surfaces. We need to do the finish here since
-        // we need to free up the surface templates.
-        finish_copybit(dev);
-    }
-
-    ctx->dst_surface_type = dst_surface_type;
-
-    // Update the destination
-    copybit_image_t dst_image;
-    dst_image.w = dst->w;
-    dst_image.h = dst->h;
-    dst_image.format = dst->format;
-    dst_image.handle = dst->handle;
-    // Check if we need a temp. copy for the destination. We'd need this the destination
-    // width is not aligned to 32. This case occurs for YUV formats. RGB formats are
-    // aligned to 32.
-    bool need_temp_dst = need_temp_buffer(dst);
-    bufferInfo dst_info;
-    populate_buffer_info(dst, dst_info);
-    private_handle_t* dst_hnd = new private_handle_t(-1, 0, 0, 0, dst_info.format,
-                                                     dst_info.width, dst_info.height);
-    if (dst_hnd == NULL) {
-        ALOGE("%s: dst_hnd is null", __FUNCTION__);
-        return COPYBIT_FAILURE;
-    }
-    if (need_temp_dst) {
-        if (get_size(dst_info) != (int) ctx->temp_dst_buffer.size) {
-            free_temp_buffer(ctx->temp_dst_buffer);
-            // Create a temp buffer and set that as the destination.
-            if (COPYBIT_FAILURE == get_temp_buffer(dst_info, ctx->temp_dst_buffer)) {
-                ALOGE("%s: get_temp_buffer(dst) failed", __FUNCTION__);
-                delete_handle(dst_hnd);
-                return COPYBIT_FAILURE;
-            }
-        }
-        dst_hnd->fd = ctx->temp_dst_buffer.fd;
-        dst_hnd->size = ctx->temp_dst_buffer.size;
-        dst_hnd->flags = ctx->temp_dst_buffer.allocType;
-        dst_hnd->base = (uintptr_t)(ctx->temp_dst_buffer.base);
-        dst_hnd->offset = ctx->temp_dst_buffer.offset;
-        dst_hnd->gpuaddr = 0;
-        dst_image.handle = dst_hnd;
-    }
-    if(!ctx->dst_surface_mapped) {
-        //map the destination surface to GPU address
-        status = set_image(ctx, ctx->dst[ctx->dst_surface_type], &dst_image,
-                           (eC2DFlags)flags, mapped_dst_idx);
-        if(status) {
-            ALOGE("%s: dst: set_image error", __FUNCTION__);
-            delete_handle(dst_hnd);
-            unmap_gpuaddr(ctx, mapped_dst_idx);
-            return COPYBIT_FAILURE;
-        }
-        ctx->dst_surface_mapped = true;
-        ctx->dst_surface_base = dst->base;
-    } else if(ctx->dst_surface_mapped && ctx->dst_surface_base != dst->base) {
-        // Destination surface for the operation should be same for multiple
-        // requests, this check is catch if there is any case when the
-        // destination changes
-        ALOGE("%s: a different destination surface!!", __FUNCTION__);
-    }
-
-    // Update the source
-    flags = 0;
-    if(is_supported_rgb_format(src->format) == COPYBIT_SUCCESS) {
-        src_surface_type = RGB_SURFACE;
-        src_surface = ctx->blit_rgb_object[ctx->blit_rgb_count];
-    } else if (is_supported_yuv_format(src->format) == COPYBIT_SUCCESS) {
-        int num_planes = get_num_planes(src->format);
-        if (num_planes == 2) {
-            src_surface_type = YUV_SURFACE_2_PLANES;
-            src_surface = ctx->blit_yuv_2_plane_object[ctx->blit_yuv_2_plane_count];
-        } else if (num_planes == 3) {
-            src_surface_type = YUV_SURFACE_3_PLANES;
-            src_surface = ctx->blit_yuv_3_plane_object[ctx->blit_yuv_2_plane_count];
-        } else {
-            ALOGE("%s: src number of YUV planes is invalid src format = 0x%x",
-                  __FUNCTION__, src->format);
-            delete_handle(dst_hnd);
-            unmap_gpuaddr(ctx, mapped_dst_idx);
-            return -EINVAL;
-        }
-    } else {
-        ALOGE("%s: Invalid source surface format 0x%x", __FUNCTION__,
-                                                        src->format);
-        delete_handle(dst_hnd);
-        unmap_gpuaddr(ctx, mapped_dst_idx);
-        return -EINVAL;
-    }
-
-    copybit_image_t src_image;
-    src_image.w = src->w;
-    src_image.h = src->h;
-    src_image.format = src->format;
-    src_image.handle = src->handle;
-
-    bool need_temp_src = need_temp_buffer(src);
-    bufferInfo src_info;
-    populate_buffer_info(src, src_info);
-    private_handle_t* src_hnd = new private_handle_t(-1, 0, 0, 0, src_info.format,
-                                                 src_info.width, src_info.height);
-    if (NULL == src_hnd) {
-        ALOGE("%s: src_hnd is null", __FUNCTION__);
-        delete_handle(dst_hnd);
-        unmap_gpuaddr(ctx, mapped_dst_idx);
-        return COPYBIT_FAILURE;
-    }
-    if (need_temp_src) {
-        if (get_size(src_info) != (int) ctx->temp_src_buffer.size) {
-            free_temp_buffer(ctx->temp_src_buffer);
-            // Create a temp buffer and set that as the destination.
-            if (COPYBIT_SUCCESS != get_temp_buffer(src_info,
-                                               ctx->temp_src_buffer)) {
-                ALOGE("%s: get_temp_buffer(src) failed", __FUNCTION__);
-                delete_handle(dst_hnd);
-                delete_handle(src_hnd);
-                unmap_gpuaddr(ctx, mapped_dst_idx);
-                return COPYBIT_FAILURE;
-            }
-        }
-        src_hnd->fd = ctx->temp_src_buffer.fd;
-        src_hnd->size = ctx->temp_src_buffer.size;
-        src_hnd->flags = ctx->temp_src_buffer.allocType;
-        src_hnd->base = (uintptr_t)(ctx->temp_src_buffer.base);
-        src_hnd->offset = ctx->temp_src_buffer.offset;
-        src_hnd->gpuaddr = 0;
-        src_image.handle = src_hnd;
-
-        // Copy the source.
-        status = copy_image((private_handle_t *)src->handle, &src_image,
-                                CONVERT_TO_C2D_FORMAT);
-        if (status == COPYBIT_FAILURE) {
-            ALOGE("%s:copy_image failed in temp source",__FUNCTION__);
-            delete_handle(dst_hnd);
-            delete_handle(src_hnd);
-            unmap_gpuaddr(ctx, mapped_dst_idx);
-            return status;
-        }
-
-        // Clean the cache
-        IMemAlloc* memalloc = sAlloc->getAllocator(src_hnd->flags);
-        if (memalloc->clean_buffer((void *)(src_hnd->base), src_hnd->size,
-                                   src_hnd->offset, src_hnd->fd,
-                                   gralloc::CACHE_CLEAN)) {
-            ALOGE("%s: clean_buffer failed", __FUNCTION__);
-            delete_handle(dst_hnd);
-            delete_handle(src_hnd);
-            unmap_gpuaddr(ctx, mapped_dst_idx);
-            return COPYBIT_FAILURE;
-        }
-    }
-
-    flags |= (ctx->is_premultiplied_alpha) ? FLAGS_PREMULTIPLIED_ALPHA : 0;
-    flags |= (ctx->dst_surface_type != RGB_SURFACE) ? FLAGS_YUV_DESTINATION : 0;
-    flags |= (ctx->is_src_ubwc_format) ? FLAGS_UBWC_FORMAT_MODE : 0;
-    status = set_image(ctx, src_surface.surface_id, &src_image,
-                       (eC2DFlags)flags, mapped_src_idx);
-    if(status) {
-        ALOGE("%s: set_image (src) error", __FUNCTION__);
-        delete_handle(dst_hnd);
-        delete_handle(src_hnd);
-        unmap_gpuaddr(ctx, mapped_dst_idx);
-        unmap_gpuaddr(ctx, mapped_src_idx);
-        return COPYBIT_FAILURE;
-    }
-
-    src_surface.config_mask = C2D_NO_ANTIALIASING_BIT | ctx->config_mask;
-    src_surface.global_alpha = ctx->src_global_alpha;
-    if (enableBlend) {
-        if(src_surface.config_mask & C2D_GLOBAL_ALPHA_BIT) {
-            src_surface.config_mask &= ~C2D_ALPHA_BLEND_NONE;
-            if(!(src_surface.global_alpha)) {
-                // src alpha is zero
-                delete_handle(dst_hnd);
-                delete_handle(src_hnd);
-                unmap_gpuaddr(ctx, mapped_dst_idx);
-                unmap_gpuaddr(ctx, mapped_src_idx);
-                return COPYBIT_FAILURE;
-            }
-        }
-    } else {
-        src_surface.config_mask |= C2D_ALPHA_BLEND_NONE;
-    }
-
-    if (src_surface_type == RGB_SURFACE) {
-        ctx->blit_rgb_object[ctx->blit_rgb_count] = src_surface;
-        ctx->blit_rgb_count++;
-    } else if (src_surface_type == YUV_SURFACE_2_PLANES) {
-        ctx->blit_yuv_2_plane_object[ctx->blit_yuv_2_plane_count] = src_surface;
-        ctx->blit_yuv_2_plane_count++;
-    } else {
-        ctx->blit_yuv_3_plane_object[ctx->blit_yuv_3_plane_count] = src_surface;
-        ctx->blit_yuv_3_plane_count++;
-    }
-
-    struct copybit_rect_t clip;
-    while ((status == 0) && region->next(region, &clip)) {
-        set_rects(ctx, &(src_surface), dst_rect, src_rect, &clip);
-        if (ctx->blit_count == MAX_BLIT_OBJECT_COUNT) {
-            ALOGW("Reached end of blit count");
-            finish_copybit(dev);
-        }
-        ctx->blit_list[ctx->blit_count] = src_surface;
-        ctx->blit_count++;
-    }
-
-    // Check if we need to perform an early draw-finish.
-    flags |= (need_temp_dst || need_temp_src) ? FLAGS_TEMP_SRC_DST : 0;
-    if (need_to_execute_draw((eC2DFlags)flags))
-    {
-        finish_copybit(dev);
-    }
-
-    if (need_temp_dst) {
-        // copy the temp. destination without the alignment to the actual
-        // destination.
-        status = copy_image(dst_hnd, dst, CONVERT_TO_ANDROID_FORMAT);
-        if (status == COPYBIT_FAILURE) {
-            ALOGE("%s:copy_image failed in temp Dest",__FUNCTION__);
-            delete_handle(dst_hnd);
-            delete_handle(src_hnd);
-            unmap_gpuaddr(ctx, mapped_dst_idx);
-            unmap_gpuaddr(ctx, mapped_src_idx);
-            return status;
-        }
-        // Clean the cache.
-        IMemAlloc* memalloc = sAlloc->getAllocator(dst_hnd->flags);
-        memalloc->clean_buffer((void *)(dst_hnd->base), dst_hnd->size,
-                               dst_hnd->offset, dst_hnd->fd,
-                               gralloc::CACHE_CLEAN);
-    }
-    delete_handle(dst_hnd);
-    delete_handle(src_hnd);
-
-    ctx->is_premultiplied_alpha = false;
-    ctx->fb_width = 0;
-    ctx->fb_height = 0;
-    ctx->config_mask = 0;
-    return status;
-}
-
-static int set_sync_copybit(struct copybit_device_t *dev,
-    int /*acquireFenceFd*/)
-{
-    if(!dev)
-        return -EINVAL;
-
-    return 0;
-}
-
-static int stretch_copybit(
-    struct copybit_device_t *dev,
-    struct copybit_image_t const *dst,
-    struct copybit_image_t const *src,
-    struct copybit_rect_t const *dst_rect,
-    struct copybit_rect_t const *src_rect,
-    struct copybit_region_t const *region)
-{
-    struct copybit_context_t* ctx = (struct copybit_context_t*)dev;
-    int status = COPYBIT_SUCCESS;
-    bool needsBlending = (ctx->src_global_alpha != 0);
-    pthread_mutex_lock(&ctx->wait_cleanup_lock);
-    status = stretch_copybit_internal(dev, dst, src, dst_rect, src_rect,
-                                    region, needsBlending);
-    pthread_mutex_unlock(&ctx->wait_cleanup_lock);
-    return status;
-}
-
-/** Perform a blit type operation */
-static int blit_copybit(
-    struct copybit_device_t *dev,
-    struct copybit_image_t const *dst,
-    struct copybit_image_t const *src,
-    struct copybit_region_t const *region)
-{
-    int status = COPYBIT_SUCCESS;
-    struct copybit_context_t* ctx = (struct copybit_context_t*)dev;
-    struct copybit_rect_t dr = { 0, 0, (int)dst->w, (int)dst->h };
-    struct copybit_rect_t sr = { 0, 0, (int)src->w, (int)src->h };
-    pthread_mutex_lock(&ctx->wait_cleanup_lock);
-    status = stretch_copybit_internal(dev, dst, src, &dr, &sr, region, false);
-    pthread_mutex_unlock(&ctx->wait_cleanup_lock);
-    return status;
-}
-
-/** Fill the rect on dst with RGBA color **/
-static int fill_color(struct copybit_device_t *dev,
-                      struct copybit_image_t const *dst,
-                      struct copybit_rect_t const *rect,
-                      uint32_t /*color*/)
-{
-    // TODO: Implement once c2d driver supports color fill
-    if(!dev || !dst || !rect)
-       return -EINVAL;
-
-    return -EINVAL;
-}
-
-/*****************************************************************************/
-
-static void clean_up(copybit_context_t* ctx)
-{
-    void* ret;
-    if (!ctx)
-        return;
-
-    // stop the wait_cleanup_thread
-    pthread_mutex_lock(&ctx->wait_cleanup_lock);
-    ctx->stop_thread = true;
-    // Signal waiting thread
-    pthread_cond_signal(&ctx->wait_cleanup_cond);
-    pthread_mutex_unlock(&ctx->wait_cleanup_lock);
-    // waits for the cleanup thread to exit
-    pthread_join(ctx->wait_thread_id, &ret);
-    pthread_mutex_destroy(&ctx->wait_cleanup_lock);
-    pthread_cond_destroy (&ctx->wait_cleanup_cond);
-
-    for (int i = 0; i < NUM_SURFACE_TYPES; i++) {
-        if (ctx->dst[i])
-            LINK_c2dDestroySurface(ctx->dst[i]);
-    }
-
-    for (int i = 0; i < MAX_RGB_SURFACES; i++) {
-        if (ctx->blit_rgb_object[i].surface_id)
-            LINK_c2dDestroySurface(ctx->blit_rgb_object[i].surface_id);
-    }
-
-    for (int i = 0; i < MAX_YUV_2_PLANE_SURFACES; i++) {
-        if (ctx->blit_yuv_2_plane_object[i].surface_id)
-            LINK_c2dDestroySurface(ctx->blit_yuv_2_plane_object[i].surface_id);
-    }
-
-    for (int i = 0; i < MAX_YUV_3_PLANE_SURFACES; i++) {
-        if (ctx->blit_yuv_3_plane_object[i].surface_id)
-            LINK_c2dDestroySurface(ctx->blit_yuv_3_plane_object[i].surface_id);
-    }
-
-    if (ctx->libc2d2) {
-        ::dlclose(ctx->libc2d2);
-        ALOGV("dlclose(libc2d2)");
-    }
-
-    free(ctx);
-}
-
-/** Close the copybit device */
-static int close_copybit(struct hw_device_t *dev)
-{
-    struct copybit_context_t* ctx = (struct copybit_context_t*)dev;
-    if (ctx) {
-        free_temp_buffer(ctx->temp_src_buffer);
-        free_temp_buffer(ctx->temp_dst_buffer);
-    }
-    clean_up(ctx);
-    return 0;
-}
-
-/** Open a new instance of a copybit device using name */
-static int open_copybit(const struct hw_module_t* module, const char* name,
-                        struct hw_device_t** device)
-{
-    int status = COPYBIT_SUCCESS;
-    if (strcmp(name, COPYBIT_HARDWARE_COPYBIT0)) {
-        return COPYBIT_FAILURE;
-    }
-
-    C2D_RGB_SURFACE_DEF surfDefinition = {0};
-    C2D_YUV_SURFACE_DEF yuvSurfaceDef = {0} ;
-    struct copybit_context_t *ctx;
-
-    ctx = (struct copybit_context_t *)malloc(sizeof(struct copybit_context_t));
-    if(!ctx) {
-        ALOGE("%s: malloc failed", __FUNCTION__);
-        return COPYBIT_FAILURE;
-    }
-
-    /* initialize drawstate */
-    memset(ctx, 0, sizeof(*ctx));
-    ctx->libc2d2 = ::dlopen("libC2D2.so", RTLD_NOW);
-    if (!ctx->libc2d2) {
-        ALOGE("FATAL ERROR: could not dlopen libc2d2.so: %s", dlerror());
-        clean_up(ctx);
-        status = COPYBIT_FAILURE;
-        *device = NULL;
-        return status;
-    }
-    *(void **)&LINK_c2dCreateSurface = ::dlsym(ctx->libc2d2,
-                                               "c2dCreateSurface");
-    *(void **)&LINK_c2dUpdateSurface = ::dlsym(ctx->libc2d2,
-                                               "c2dUpdateSurface");
-    *(void **)&LINK_c2dReadSurface = ::dlsym(ctx->libc2d2,
-                                             "c2dReadSurface");
-    *(void **)&LINK_c2dDraw = ::dlsym(ctx->libc2d2, "c2dDraw");
-    *(void **)&LINK_c2dFlush = ::dlsym(ctx->libc2d2, "c2dFlush");
-    *(void **)&LINK_c2dFinish = ::dlsym(ctx->libc2d2, "c2dFinish");
-    *(void **)&LINK_c2dWaitTimestamp = ::dlsym(ctx->libc2d2,
-                                               "c2dWaitTimestamp");
-    *(void **)&LINK_c2dDestroySurface = ::dlsym(ctx->libc2d2,
-                                                "c2dDestroySurface");
-    *(void **)&LINK_c2dMapAddr = ::dlsym(ctx->libc2d2,
-                                         "c2dMapAddr");
-    *(void **)&LINK_c2dUnMapAddr = ::dlsym(ctx->libc2d2,
-                                           "c2dUnMapAddr");
-    *(void **)&LINK_c2dGetDriverCapabilities = ::dlsym(ctx->libc2d2,
-                                           "c2dGetDriverCapabilities");
-    *(void **)&LINK_c2dCreateFenceFD = ::dlsym(ctx->libc2d2,
-                                           "c2dCreateFenceFD");
-    *(void **)&LINK_c2dFillSurface = ::dlsym(ctx->libc2d2,
-                                           "c2dFillSurface");
-
-    if (!LINK_c2dCreateSurface || !LINK_c2dUpdateSurface || !LINK_c2dReadSurface
-        || !LINK_c2dDraw || !LINK_c2dFlush || !LINK_c2dWaitTimestamp ||
-        !LINK_c2dFinish  || !LINK_c2dDestroySurface ||
-        !LINK_c2dGetDriverCapabilities || !LINK_c2dCreateFenceFD ||
-        !LINK_c2dFillSurface) {
-        ALOGE("%s: dlsym ERROR", __FUNCTION__);
-        clean_up(ctx);
-        status = COPYBIT_FAILURE;
-        *device = NULL;
-        return status;
-    }
-
-    ctx->device.common.tag = HARDWARE_DEVICE_TAG;
-    ctx->device.common.version = 1;
-    ctx->device.common.module = (hw_module_t*)(module);
-    ctx->device.common.close = close_copybit;
-    ctx->device.set_parameter = set_parameter_copybit;
-    ctx->device.get = get;
-    ctx->device.blit = blit_copybit;
-    ctx->device.set_sync = set_sync_copybit;
-    ctx->device.stretch = stretch_copybit;
-    ctx->device.finish = finish_copybit;
-    ctx->device.flush_get_fence = flush_get_fence_copybit;
-    ctx->device.clear = clear_copybit;
-    ctx->device.fill_color = fill_color;
-
-    /* Create RGB Surface */
-    surfDefinition.buffer = (void*)0xdddddddd;
-    surfDefinition.phys = (void*)0xdddddddd;
-    surfDefinition.stride = 1 * 4;
-    surfDefinition.width = 1;
-    surfDefinition.height = 1;
-    surfDefinition.format = C2D_COLOR_FORMAT_8888_ARGB;
-    if (LINK_c2dCreateSurface(&(ctx->dst[RGB_SURFACE]), C2D_TARGET | C2D_SOURCE,
-                              (C2D_SURFACE_TYPE)(C2D_SURFACE_RGB_HOST |
-                                                 C2D_SURFACE_WITH_PHYS |
-                                                 C2D_SURFACE_WITH_PHYS_DUMMY ),
-                                                 &surfDefinition)) {
-        ALOGE("%s: create ctx->dst_surface[RGB_SURFACE] failed", __FUNCTION__);
-        ctx->dst[RGB_SURFACE] = 0;
-        clean_up(ctx);
-        status = COPYBIT_FAILURE;
-        *device = NULL;
-        return status;
-    }
-
-    unsigned int surface_id = 0;
-    for (int i = 0; i < MAX_RGB_SURFACES; i++)
-    {
-        if (LINK_c2dCreateSurface(&surface_id, C2D_TARGET | C2D_SOURCE,
-                              (C2D_SURFACE_TYPE)(C2D_SURFACE_RGB_HOST |
-                                                 C2D_SURFACE_WITH_PHYS |
-                                                 C2D_SURFACE_WITH_PHYS_DUMMY ),
-                                                 &surfDefinition)) {
-            ALOGE("%s: create RGB source surface %d failed", __FUNCTION__, i);
-            ctx->blit_rgb_object[i].surface_id = 0;
-            status = COPYBIT_FAILURE;
-            break;
-        } else {
-            ctx->blit_rgb_object[i].surface_id = surface_id;
-            ALOGW("%s i = %d surface_id=%d",  __FUNCTION__, i,
-                                          ctx->blit_rgb_object[i].surface_id);
-        }
-    }
-
-    if (status == COPYBIT_FAILURE) {
-        clean_up(ctx);
-        status = COPYBIT_FAILURE;
-        *device = NULL;
-        return status;
-    }
-
-    // Create 2 plane YUV surfaces
-    yuvSurfaceDef.format = C2D_COLOR_FORMAT_420_NV12;
-    yuvSurfaceDef.width = 4;
-    yuvSurfaceDef.height = 4;
-    yuvSurfaceDef.plane0 = (void*)0xaaaaaaaa;
-    yuvSurfaceDef.phys0 = (void*) 0xaaaaaaaa;
-    yuvSurfaceDef.stride0 = 4;
-
-    yuvSurfaceDef.plane1 = (void*)0xaaaaaaaa;
-    yuvSurfaceDef.phys1 = (void*) 0xaaaaaaaa;
-    yuvSurfaceDef.stride1 = 4;
-    if (LINK_c2dCreateSurface(&(ctx->dst[YUV_SURFACE_2_PLANES]),
-                              C2D_TARGET | C2D_SOURCE,
-                              (C2D_SURFACE_TYPE)(C2D_SURFACE_YUV_HOST |
-                               C2D_SURFACE_WITH_PHYS |
-                               C2D_SURFACE_WITH_PHYS_DUMMY),
-                              &yuvSurfaceDef)) {
-        ALOGE("%s: create ctx->dst[YUV_SURFACE_2_PLANES] failed", __FUNCTION__);
-        ctx->dst[YUV_SURFACE_2_PLANES] = 0;
-        clean_up(ctx);
-        status = COPYBIT_FAILURE;
-        *device = NULL;
-        return status;
-    }
-
-    for (int i=0; i < MAX_YUV_2_PLANE_SURFACES; i++)
-    {
-        if (LINK_c2dCreateSurface(&surface_id, C2D_TARGET | C2D_SOURCE,
-                              (C2D_SURFACE_TYPE)(C2D_SURFACE_YUV_HOST |
-                                                 C2D_SURFACE_WITH_PHYS |
-                                                 C2D_SURFACE_WITH_PHYS_DUMMY ),
-                              &yuvSurfaceDef)) {
-            ALOGE("%s: create YUV source %d failed", __FUNCTION__, i);
-            ctx->blit_yuv_2_plane_object[i].surface_id = 0;
-            status = COPYBIT_FAILURE;
-            break;
-        } else {
-            ctx->blit_yuv_2_plane_object[i].surface_id = surface_id;
-            ALOGW("%s: 2 Plane YUV i=%d surface_id=%d",  __FUNCTION__, i,
-                                   ctx->blit_yuv_2_plane_object[i].surface_id);
-        }
-    }
-
-    if (status == COPYBIT_FAILURE) {
-        clean_up(ctx);
-        status = COPYBIT_FAILURE;
-        *device = NULL;
-        return status;
-    }
-
-    // Create YUV 3 plane surfaces
-    yuvSurfaceDef.format = C2D_COLOR_FORMAT_420_YV12;
-    yuvSurfaceDef.plane2 = (void*)0xaaaaaaaa;
-    yuvSurfaceDef.phys2 = (void*) 0xaaaaaaaa;
-    yuvSurfaceDef.stride2 = 4;
-
-    if (LINK_c2dCreateSurface(&(ctx->dst[YUV_SURFACE_3_PLANES]),
-                              C2D_TARGET | C2D_SOURCE,
-                              (C2D_SURFACE_TYPE)(C2D_SURFACE_YUV_HOST |
-                                                 C2D_SURFACE_WITH_PHYS |
-                                                 C2D_SURFACE_WITH_PHYS_DUMMY),
-                              &yuvSurfaceDef)) {
-        ALOGE("%s: create ctx->dst[YUV_SURFACE_3_PLANES] failed", __FUNCTION__);
-        ctx->dst[YUV_SURFACE_3_PLANES] = 0;
-        clean_up(ctx);
-        status = COPYBIT_FAILURE;
-        *device = NULL;
-        return status;
-    }
-
-    for (int i=0; i < MAX_YUV_3_PLANE_SURFACES; i++)
-    {
-        if (LINK_c2dCreateSurface(&(surface_id),
-                              C2D_TARGET | C2D_SOURCE,
-                              (C2D_SURFACE_TYPE)(C2D_SURFACE_YUV_HOST |
-                                                 C2D_SURFACE_WITH_PHYS |
-                                                 C2D_SURFACE_WITH_PHYS_DUMMY),
-                              &yuvSurfaceDef)) {
-            ALOGE("%s: create 3 plane YUV surface %d failed", __FUNCTION__, i);
-            ctx->blit_yuv_3_plane_object[i].surface_id = 0;
-            status = COPYBIT_FAILURE;
-            break;
-        } else {
-            ctx->blit_yuv_3_plane_object[i].surface_id = surface_id;
-            ALOGW("%s: 3 Plane YUV i=%d surface_id=%d",  __FUNCTION__, i,
-                                   ctx->blit_yuv_3_plane_object[i].surface_id);
-        }
-    }
-
-    if (status == COPYBIT_FAILURE) {
-        clean_up(ctx);
-        status = COPYBIT_FAILURE;
-        *device = NULL;
-        return status;
-    }
-
-    if (LINK_c2dGetDriverCapabilities(&(ctx->c2d_driver_info))) {
-         ALOGE("%s: LINK_c2dGetDriverCapabilities failed", __FUNCTION__);
-         clean_up(ctx);
-         status = COPYBIT_FAILURE;
-        *device = NULL;
-        return status;
-    }
-    // Initialize context variables.
-    ctx->trg_transform = C2D_TARGET_ROTATE_0;
-
-    ctx->temp_src_buffer.fd = -1;
-    ctx->temp_src_buffer.base = 0;
-    ctx->temp_src_buffer.size = 0;
-
-    ctx->temp_dst_buffer.fd = -1;
-    ctx->temp_dst_buffer.base = 0;
-    ctx->temp_dst_buffer.size = 0;
-
-    ctx->fb_width = 0;
-    ctx->fb_height = 0;
-
-    ctx->blit_rgb_count = 0;
-    ctx->blit_yuv_2_plane_count = 0;
-    ctx->blit_yuv_3_plane_count = 0;
-    ctx->blit_count = 0;
-
-    ctx->wait_timestamp = false;
-    ctx->stop_thread = false;
-    pthread_mutex_init(&(ctx->wait_cleanup_lock), NULL);
-    pthread_cond_init(&(ctx->wait_cleanup_cond), NULL);
-    /* Start the wait thread */
-    pthread_attr_t attr;
-    pthread_attr_init(&attr);
-    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
-
-    pthread_create(&ctx->wait_thread_id, &attr, &c2d_wait_loop,
-                                                            (void *)ctx);
-    pthread_attr_destroy(&attr);
-
-    *device = &ctx->device.common;
-    return status;
-}
diff --git a/libcopybit/copybit_priv.h b/libcopybit/copybit_priv.h
deleted file mode 100644
index 68dfac4..0000000
--- a/libcopybit/copybit_priv.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright (c) 2011, The Linux Foundation. All rights reserved.
-
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *   * Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- *   * Redistributions in binary form must reproduce the above
- *     copyright notice, this list of conditions and the following
- *     disclaimer in the documentation and/or other materials provided
- *     with the distribution.
- *   * Neither the name of The Linux Foundation nor the names of its
- *     contributors may be used to endorse or promote products derived
- *     from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <copybit.h>
-struct copybit_iterator : public copybit_region_t {
-    copybit_iterator(const copybit_rect_t& rect) {
-        mRect = rect;
-        mCount = 1;
-        this->next = iterate;
-    }
-private:
-    static int iterate(copybit_region_t const * self, copybit_rect_t* rect) {
-        if (!self || !rect) {
-            return 0;
-        }
-
-        copybit_iterator const* me = static_cast<copybit_iterator const*>(self);
-        if (me->mCount) {
-            rect->l = me->mRect.l;
-            rect->t = me->mRect.t;
-            rect->r = me->mRect.r;
-            rect->b = me->mRect.b;
-            me->mCount--;
-            return 1;
-        }
-        return 0;
-    }
-    copybit_rect_t mRect;
-    mutable int mCount;
-};
diff --git a/libcopybit/software_converter.cpp b/libcopybit/software_converter.cpp
deleted file mode 100644
index 1aa3ce6..0000000
--- a/libcopybit/software_converter.cpp
+++ /dev/null
@@ -1,263 +0,0 @@
-/*
- * Copyright (c) 2011-2014, The Linux Foundation. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- *       copyright notice, this list of conditions and the following
- *       disclaimer in the documentation and/or other materials provided
- *       with the distribution.
- *     * Neither the name of The Linux Foundation nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <log/log.h>
-#include <stdlib.h>
-#include <errno.h>
-#include "software_converter.h"
-
-/** Convert YV12 to YCrCb_420_SP */
-int convertYV12toYCrCb420SP(const copybit_image_t *src, private_handle_t *yv12_handle)
-{
-    private_handle_t* hnd = (private_handle_t*)src->handle;
-
-    if(hnd == NULL || yv12_handle == NULL){
-        ALOGE("Invalid handle");
-        return -1;
-    }
-
-    // Please refer to the description of YV12 in hardware.h
-    // for the formulae used to calculate buffer sizes and offsets
-
-    // In a copybit_image_t, w is the stride and
-    // stride - horiz_padding is the actual width
-    // vertical stride is the same as height, so not considered
-    unsigned int   stride  = src->w;
-    unsigned int   width   = src->w - src->horiz_padding;
-    unsigned int   height  = src->h;
-    unsigned int   y_size  = stride * src->h;
-    unsigned int   c_width = ALIGN(stride/2, (unsigned int)16);
-    unsigned int   c_size  = c_width * src->h/2;
-    unsigned int   chromaPadding = c_width - width/2;
-    unsigned int   chromaSize = c_size * 2;
-    unsigned char* newChroma = (unsigned char *)(yv12_handle->base + y_size);
-    unsigned char* oldChroma = (unsigned char*)(hnd->base + y_size);
-    memcpy((char *)yv12_handle->base,(char *)hnd->base,y_size);
-
-#if defined(__ARM_HAVE_NEON) && !defined(__aarch64__)
-   /* interleave */
-    if(!chromaPadding) {
-        unsigned char * t1 = newChroma;
-        unsigned char * t2 = oldChroma;
-        unsigned char * t3 = t2 + chromaSize/2;
-        for(unsigned int i=0; i < (chromaSize/2)>>3; i++) {
-            __asm__ __volatile__ (
-                                    "vld1.u8 d0, [%0]! \n"
-                                    "vld1.u8 d1, [%1]! \n"
-                                    "vst2.u8 {d0, d1}, [%2]! \n"
-                                    :"+r"(t2), "+r"(t3), "+r"(t1)
-                                    :
-                                    :"memory","d0","d1"
-                                 );
-
-        }
-    }
-#else  //__ARM_HAVE_NEON
-    if(!chromaPadding) {
-        for(unsigned int i = 0; i< chromaSize/2; i++) {
-            newChroma[i*2]   = oldChroma[i];
-            newChroma[i*2+1] = oldChroma[i+chromaSize/2];
-        }
-
-    }
-#endif
-    // If the image is not aligned to 16 pixels,
-    // convert using the C routine below
-    // r1 tracks the row of the source buffer
-    // r2 tracks the row of the destination buffer
-    // The width/2 checks are to avoid copying
-    // from the padding
-
-    if(chromaPadding) {
-        unsigned int r1 = 0, r2 = 0, i = 0, j = 0;
-        while(r1 < height/2) {
-            if(j == width) {
-                j = 0;
-                r2++;
-                continue;
-            }
-            if (j+1 == width) {
-                newChroma[r2*width + j] = oldChroma[r1*c_width+i];
-                r2++;
-                newChroma[r2*width] = oldChroma[r1*c_width+i+c_size];
-                j = 1;
-            } else {
-                newChroma[r2*width + j] = oldChroma[r1*c_width+i];
-                newChroma[r2*width + j + 1] = oldChroma[r1*c_width+i+c_size];
-                j+=2;
-            }
-            i++;
-            if (i == width/2 ) {
-                i = 0;
-                r1++;
-            }
-        }
-    }
-
-  return 0;
-}
-
-struct copyInfo{
-    int width;
-    int height;
-    int src_stride;
-    int dst_stride;
-    size_t src_plane1_offset;
-    size_t src_plane2_offset;
-    size_t dst_plane1_offset;
-    size_t dst_plane2_offset;
-};
-
-/* Internal function to do the actual copy of source to destination */
-static int copy_source_to_destination(const uintptr_t src_base,
-                                      const uintptr_t dst_base,
-                                      copyInfo& info)
-{
-    if (!src_base || !dst_base) {
-        ALOGE("%s: invalid memory src_base = 0x%p dst_base=0x%p",
-             __FUNCTION__, (void*)src_base, (void*)dst_base);
-         return COPYBIT_FAILURE;
-    }
-
-    int width = info.width;
-    int height = info.height;
-    unsigned char *src = (unsigned char*)src_base;
-    unsigned char *dst = (unsigned char*)dst_base;
-
-    // Copy the luma
-    for (int i = 0; i < height; i++) {
-        memcpy(dst, src, width);
-        src += info.src_stride;
-        dst += info.dst_stride;
-    }
-
-    // Copy plane 1
-    src = (unsigned char*)(src_base + info.src_plane1_offset);
-    dst = (unsigned char*)(dst_base + info.dst_plane1_offset);
-    width = width/2;
-    height = height/2;
-    for (int i = 0; i < height; i++) {
-        memcpy(dst, src, info.src_stride);
-        src += info.src_stride;
-        dst += info.dst_stride;
-    }
-    return 0;
-}
-
-
-/*
- * Function to convert the c2d format into an equivalent Android format
- *
- * @param: source buffer handle
- * @param: destination image
- *
- * @return: return status
- */
-int convert_yuv_c2d_to_yuv_android(private_handle_t *hnd,
-                                   struct copybit_image_t const *rhs)
-{
-    ALOGD("Enter %s", __FUNCTION__);
-    if (!hnd || !rhs) {
-        ALOGE("%s: invalid inputs hnd=%p rhs=%p", __FUNCTION__, hnd, rhs);
-        return COPYBIT_FAILURE;
-    }
-
-    int ret = COPYBIT_SUCCESS;
-    private_handle_t *dst_hnd = (private_handle_t *)rhs->handle;
-
-    copyInfo info;
-    info.width = rhs->w;
-    info.height = rhs->h;
-    info.src_stride = ALIGN(info.width, 32);
-    info.dst_stride = ALIGN(info.width, 16);
-    switch(rhs->format) {
-        case HAL_PIXEL_FORMAT_YCbCr_420_SP:
-        case HAL_PIXEL_FORMAT_YCrCb_420_SP: {
-            info.src_plane1_offset = info.src_stride*info.height;
-            info.dst_plane1_offset = info.dst_stride*info.height;
-        } break;
-        case HAL_PIXEL_FORMAT_NV12_ENCODEABLE: {
-            // Chroma is 2K aligned for the NV12 encodeable format.
-            info.src_plane1_offset = ALIGN(info.src_stride*info.height, 2048);
-            info.dst_plane1_offset = ALIGN(info.dst_stride*info.height, 2048);
-        } break;
-        default:
-            ALOGE("%s: unsupported format (format=0x%x)", __FUNCTION__,
-                 rhs->format);
-            return COPYBIT_FAILURE;
-    }
-
-    ret = copy_source_to_destination((uintptr_t) hnd->base, (uintptr_t) dst_hnd->base, info);
-    return ret;
-}
-
-/*
- * Function to convert the Android format into an equivalent C2D format
- *
- * @param: source buffer handle
- * @param: destination image
- *
- * @return: return status
- */
-int convert_yuv_android_to_yuv_c2d(private_handle_t *hnd,
-                                   struct copybit_image_t const *rhs)
-{
-    if (!hnd || !rhs) {
-        ALOGE("%s: invalid inputs hnd=%p rhs=%p", __FUNCTION__, hnd, rhs);
-        return COPYBIT_FAILURE;
-    }
-
-    int ret = COPYBIT_SUCCESS;
-    private_handle_t *dst_hnd = (private_handle_t *)rhs->handle;
-
-    copyInfo info;
-    info.width = rhs->w;
-    info.height = rhs->h;
-    info.src_stride = ALIGN(hnd->width, 16);
-    info.dst_stride = ALIGN(info.width, 32);
-    switch(rhs->format) {
-        case HAL_PIXEL_FORMAT_YCbCr_420_SP:
-        case HAL_PIXEL_FORMAT_YCrCb_420_SP: {
-            info.src_plane1_offset = info.src_stride*info.height;
-            info.dst_plane1_offset = info.dst_stride*info.height;
-        } break;
-        case HAL_PIXEL_FORMAT_NV12_ENCODEABLE: {
-            // Chroma is 2K aligned for the NV12 encodeable format.
-            info.src_plane1_offset = ALIGN(info.src_stride*info.height, 2048);
-            info.dst_plane1_offset = ALIGN(info.dst_stride*info.height, 2048);
-        } break;
-        default:
-            ALOGE("%s: unsupported format (format=0x%x)", __FUNCTION__,
-                 rhs->format);
-            return -1;
-    }
-
-    ret = copy_source_to_destination((uintptr_t) hnd->base, (uintptr_t) dst_hnd->base, info);
-    return ret;
-}
diff --git a/libcopybit/software_converter.h b/libcopybit/software_converter.h
deleted file mode 100644
index cc6ae34..0000000
--- a/libcopybit/software_converter.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright (c) 2011, The Linux Foundation. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- *       copyright notice, this list of conditions and the following
- *       disclaimer in the documentation and/or other materials provided
- *       with the distribution.
- *     * Neither the name of The Linux Foundation nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-
-#include <copybit.h>
-#include "gralloc_priv.h"
-
-#define COPYBIT_SUCCESS 0
-#define COPYBIT_FAILURE -1
-
-#define ALIGN(x, y) (((x) + y - 1) & (~(y - 1)))
-
-int convertYV12toYCrCb420SP(const copybit_image_t *src,private_handle_t *yv12_handle);
-
-/*
- * Function to convert the c2d format into an equivalent Android format
- *
- * @param: source buffer handle
- * @param: destination image
- *
- * @return: return status
- */
-int convert_yuv_c2d_to_yuv_android(private_handle_t *hnd,
-                                   struct copybit_image_t const *rhs);
-
-
-/*
- * Function to convert the Android format into an equivalent C2D format
- *
- * @param: source buffer handle
- * @param: destination image
- *
- * @return: return status
- */
-int convert_yuv_android_to_yuv_c2d(private_handle_t *hnd,
-                                   struct copybit_image_t const *rhs);
diff --git a/libdebug/Android.mk b/libdebug/Android.mk
deleted file mode 100644
index e975a22..0000000
--- a/libdebug/Android.mk
+++ /dev/null
@@ -1,14 +0,0 @@
-LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_MODULE                  := libdisplaydebug
-LOCAL_VENDOR_MODULE           := true
-LOCAL_MODULE_TAGS             := optional
-LOCAL_SHARED_LIBRARIES        := libdl
-LOCAL_CFLAGS                  := -DLOG_TAG=\"SDM\" -Wall -std=c++11 -Werror -fno-operator-names
-LOCAL_CLANG                   := true
-LOCAL_SRC_FILES               := debug_handler.cpp
-LOCAL_COPY_HEADERS_TO         := qcom/display
-LOCAL_COPY_HEADERS            := debug_handler.h
-
-include $(BUILD_SHARED_LIBRARY)
diff --git a/libdebug/debug_handler.cpp b/libdebug/debug_handler.cpp
deleted file mode 100644
index 00c3ec9..0000000
--- a/libdebug/debug_handler.cpp
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
-* Copyright (c) 2018, The Linux Foundation. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without
-* modification, are permitted provided that the following conditions are
-* met:
-*     * Redistributions of source code must retain the above copyright
-*       notice, this list of conditions and the following disclaimer.
-*     * Redistributions in binary form must reproduce the above
-*       copyright notice, this list of conditions and the following
-*       disclaimer in the documentation and/or other materials provided
-*       with the distribution.
-*     * Neither the name of The Linux Foundation nor the names of its
-*       contributors may be used to endorse or promote products derived
-*       from this software without specific prior written permission.
-*
-* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
-* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
-* ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
-* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
-* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#include "debug_handler.h"
-
-namespace display {
-
-// By default, drop any log messages/traces. It need to be overridden by client.
-class DefaultDebugHandler : public DebugHandler {
- public:
-  virtual void Error(const char *, ...) { }
-  virtual void Warning(const char *, ...) { }
-  virtual void Info(const char *, ...) { }
-  virtual void Debug(const char *, ...) { }
-  virtual void Verbose(const char *, ...) { }
-  virtual void BeginTrace(const char *, const char *, const char *) { }
-  virtual void EndTrace() { }
-  virtual int GetProperty(const char *, int *) { return -1; }
-  virtual int GetProperty(const char *, char *) { return -1; }
-};
-
-DefaultDebugHandler g_default_debug_handler;
-DebugHandler * DebugHandler::debug_handler_ = &g_default_debug_handler;
-std::bitset<32> DebugHandler::log_mask_ = 0x1;  // Always print logs tagged with value 0
-
-void DebugHandler::Set(DebugHandler *debug_handler) {
-  if (debug_handler) {
-    debug_handler_ = debug_handler;
-  } else {
-    debug_handler_ = &g_default_debug_handler;
-  }
-}
-
-}  // namespace display
diff --git a/libdebug/debug_handler.h b/libdebug/debug_handler.h
deleted file mode 100644
index 81795e4..0000000
--- a/libdebug/debug_handler.h
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
-* Copyright (c) 2018, The Linux Foundation. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without
-* modification, are permitted provided that the following conditions are
-* met:
-*     * Redistributions of source code must retain the above copyright
-*       notice, this list of conditions and the following disclaimer.
-*     * Redistributions in binary form must reproduce the above
-*       copyright notice, this list of conditions and the following
-*       disclaimer in the documentation and/or other materials provided
-*       with the distribution.
-*     * Neither the name of The Linux Foundation nor the names of its
-*       contributors may be used to endorse or promote products derived
-*       from this software without specific prior written permission.
-*
-* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
-* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
-* ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
-* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
-* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#ifndef __DEBUG_HANDLER_H__
-#define __DEBUG_HANDLER_H__
-
-#include <bitset>
-
-#define DLOG(method, format, ...) \
-  display::DebugHandler::Get()->method(__CLASS__ "::%s: " format, __FUNCTION__, ##__VA_ARGS__)
-
-#define DLOG_IF(tag, method, format, ...) \
-  if (display::DebugHandler::GetLogMask()[tag]) { \
-    DLOG(method, format, ##__VA_ARGS__); \
-  }
-
-#define DLOGE_IF(tag, format, ...) DLOG_IF(tag, Error, format, ##__VA_ARGS__)
-#define DLOGW_IF(tag, format, ...) DLOG_IF(tag, Warning, format, ##__VA_ARGS__)
-#define DLOGI_IF(tag, format, ...) DLOG_IF(tag, Info, format, ##__VA_ARGS__)
-#define DLOGD_IF(tag, format, ...) DLOG_IF(tag, Debug, format, ##__VA_ARGS__)
-#define DLOGV_IF(tag, format, ...) DLOG_IF(tag, Verbose, format, ##__VA_ARGS__)
-
-#define DLOGE(format, ...) DLOG(Error, format, ##__VA_ARGS__)
-#define DLOGW(format, ...) DLOG(Warning, format, ##__VA_ARGS__)
-#define DLOGI(format, ...) DLOG(Info, format, ##__VA_ARGS__)
-#define DLOGD(format, ...) DLOG(Debug, format, ##__VA_ARGS__)
-#define DLOGV(format, ...) DLOG(Verbose, format, ##__VA_ARGS__)
-
-#define DTRACE_BEGIN(custom_string) display::DebugHandler::Get()->BeginTrace( \
-                                          __CLASS__, __FUNCTION__, custom_string)
-#define DTRACE_END() display::DebugHandler::Get()->EndTrace()
-#define DTRACE_SCOPED() display::ScopeTracer <display::DebugHandler> \
-                                          scope_tracer(__CLASS__, __FUNCTION__)
-
-namespace display {
-
-class DebugHandler {
- public:
-  virtual void Error(const char *format, ...) = 0;
-  virtual void Warning(const char *format, ...) = 0;
-  virtual void Info(const char *format, ...) = 0;
-  virtual void Debug(const char *format, ...) = 0;
-  virtual void Verbose(const char *format, ...) = 0;
-  virtual void BeginTrace(const char *class_name, const char *function_name,
-                          const char *custom_string) = 0;
-  virtual void EndTrace() = 0;
-  virtual int GetProperty(const char *property_name, int *value) = 0;
-  virtual int GetProperty(const char *property_name, char *value) = 0;
-
-  static inline DebugHandler *Get() { return debug_handler_; }
-  static void Set(DebugHandler *debug_handler);
-  static inline std::bitset<32> & GetLogMask() { return log_mask_; }
-  static void SetLogMask(const std::bitset<32> &log_mask) { log_mask_ = log_mask; }
-
- protected:
-  virtual ~DebugHandler() { }
-
- private:
-  static DebugHandler *debug_handler_;
-  static std::bitset<32> log_mask_;
-};
-
-template <class T>
-class ScopeTracer {
- public:
-  ScopeTracer(const char *class_name, const char *function_name) {
-    T::Get()->BeginTrace(class_name, function_name, "");
-  }
-
-  ~ScopeTracer() { T::Get()->EndTrace(); }
-};
-
-}  // namespace display
-
-#endif  // __DEBUG_HANDLER_H__
diff --git a/libdrmutils/Android.mk b/libdrmutils/Android.mk
deleted file mode 100644
index 97c052b..0000000
--- a/libdrmutils/Android.mk
+++ /dev/null
@@ -1,18 +0,0 @@
-LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_MODULE                  := libdrmutils
-LOCAL_VENDOR_MODULE           := true
-LOCAL_MODULE_TAGS             := optional
-LOCAL_C_INCLUDES              := external/libdrm \
-                                 $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr/include
-LOCAL_HEADER_LIBRARIES        := display_headers
-LOCAL_SHARED_LIBRARIES        := libdrm libdl libdisplaydebug
-LOCAL_CFLAGS                  := -DLOG_TAG=\"DRMUTILS\" -Wall -std=c++11 -Werror -fno-operator-names
-LOCAL_CLANG                   := true
-LOCAL_ADDITIONAL_DEPENDENCIES := $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr
-LOCAL_SRC_FILES               := drm_master.cpp drm_res_mgr.cpp drm_lib_loader.cpp
-LOCAL_COPY_HEADERS_TO         := qcom/display
-LOCAL_COPY_HEADERS            := drm_master.h drm_res_mgr.h drm_lib_loader.h drm_logger.h drm_interface.h
-
-include $(BUILD_SHARED_LIBRARY)
diff --git a/libdrmutils/drm_interface.h b/libdrmutils/drm_interface.h
deleted file mode 100644
index 8dcab3a..0000000
--- a/libdrmutils/drm_interface.h
+++ /dev/null
@@ -1,718 +0,0 @@
-/*
-* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without
-* modification, are permitted provided that the following conditions are
-* met:
-*   * Redistributions of source code must retain the above copyright
-*     notice, this list of conditions and the following disclaimer.
-*   * Redistributions in binary form must reproduce the above
-*     copyright notice, this list of conditions and the following
-*     disclaimer in the documentation and/or other materials provided
-*     with the distribution.
-*   * Neither the name of The Linux Foundation nor the names of its
-*     contributors may be used to endorse or promote products derived
-*     from this software without specific prior written permission.
-*
-* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
-* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
-* ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
-* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
-* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#ifndef __DRM_INTERFACE_H__
-#define __DRM_INTERFACE_H__
-
-#include <map>
-#include <string>
-#include <utility>
-#include <vector>
-
-#include "xf86drm.h"
-#include "xf86drmMode.h"
-#include <drm/msm_drm.h>
-
-namespace sde_drm {
-
-typedef std::map<std::pair<uint32_t, uint64_t>, float> CompRatioMap;
-
-/*
- * Drm Atomic Operation Codes
- */
-enum struct DRMOps {
-  /*
-   * Op: Sets plane source crop
-   * Arg: uint32_t - Plane ID
-   *      DRMRect  - Source Rectangle
-   */
-  PLANE_SET_SRC_RECT,
-  /*
-   * Op: Sets plane destination rect
-   * Arg: uint32_t - Plane ID
-   *      DRMRect - Dst Rectangle
-   */
-  PLANE_SET_DST_RECT,
-  /*
-   * Op: Sets plane zorder
-   * Arg: uint32_t - Plane ID
-   *      uint32_t - zorder
-   */
-  PLANE_SET_ZORDER,
-  /*
-   * Op: Sets plane rotation flags
-   * Arg: uint32_t - Plane ID
-   *      uint32_t - bit mask of rotation flags (See drm_mode.h for enums)
-   */
-  PLANE_SET_ROTATION,
-  /*
-   * Op: Sets plane alpha
-   * Arg: uint32_t - Plane ID
-   *      uint32_t - alpha value
-   */
-  PLANE_SET_ALPHA,
-  /*
-   * Op: Sets the blend type
-   * Arg: uint32_t - Plane ID
-   *      uint32_t - blend type (see DRMBlendType)
-   */
-  PLANE_SET_BLEND_TYPE,
-  /*
-   * Op: Sets horizontal decimation
-   * Arg: uint32_t - Plane ID
-   *      uint32_t - decimation factor
-   */
-  PLANE_SET_H_DECIMATION,
-  /*
-   * Op: Sets vertical decimation
-   * Arg: uint32_t - Plane ID
-   *      uint32_t - decimation factor
-   */
-  PLANE_SET_V_DECIMATION,
-  /*
-   * Op: Sets source config flags
-   * Arg: uint32_t - Plane ID
-   *      uint32_t - flags to enable or disable a specific op. E.g. deinterlacing
-   */
-  PLANE_SET_SRC_CONFIG,
-  /*
-   * Op: Sets frame buffer ID for plane. Set together with CRTC.
-   * Arg: uint32_t - Plane ID
-   *      uint32_t - Framebuffer ID
-   */
-  PLANE_SET_FB_ID,
-  /*
-   * Op: Sets the crtc for this plane. Set together with FB_ID.
-   * Arg: uint32_t - Plane ID
-   *      uint32_t - CRTC ID
-   */
-  PLANE_SET_CRTC,
-  /*
-   * Op: Sets acquire fence for this plane's buffer. Set together with FB_ID, CRTC.
-   * Arg: uint32_t - Plane ID
-   *      uint32_t - Input fence
-   */
-  PLANE_SET_INPUT_FENCE,
-  /*
-   * Op: Sets scaler config on this plane.
-   * Arg: uint32_t - Plane ID
-   *      uint64_t - Address of the scaler config object (version based)
-   */
-  PLANE_SET_SCALER_CONFIG,
-  /*
-   * Op: Sets plane rotation destination rect
-   * Arg: uint32_t - Plane ID
-   *      DRMRect - rotator dst Rectangle
-   */
-  PLANE_SET_ROTATION_DST_RECT,
-  /*
-   * Op: Sets FB Secure mode for this plane.
-   * Arg: uint32_t - Plane ID
-   *      uint32_t - Value of the FB Secure mode.
-   */
-  PLANE_SET_FB_SECURE_MODE,
-  /*
-   * Op: Sets csc config on this plane.
-   * Arg: uint32_t - Plane ID
-   *      uint32_t* - pointer to csc type
-   */
-  PLANE_SET_CSC_CONFIG,
-  /*
-   * Op: Sets multirect mode on this plane.
-   * Arg: uint32_t - Plane ID
-   *      uint32_t - multirect mode
-   */
-  PLANE_SET_MULTIRECT_MODE,
-  /*
-   * Op: Activate or deactivate a CRTC
-   * Arg: uint32_t - CRTC ID
-   *      uint32_t - 1 to enable, 0 to disable
-   */
-  CRTC_SET_ACTIVE,
-  /*
-   * Op: Sets display mode
-   * Arg: uint32_t - CRTC ID
-   *      drmModeModeInfo* - Pointer to display mode
-   */
-  CRTC_SET_MODE,
-  /*
-   * Op: Sets an offset indicating when a release fence should be signalled.
-   * Arg: uint32_t - offset
-   *      0: non-speculative, default
-   *      1: speculative
-   */
-  CRTC_SET_OUTPUT_FENCE_OFFSET,
-  /*
-   * Op: Sets overall SDE core clock
-   * Arg: uint32_t - CRTC ID
-   *      uint32_t - core_clk
-   */
-  CRTC_SET_CORE_CLK,
-  /*
-   * Op: Sets MNOC bus average bandwidth
-   * Arg: uint32_t - CRTC ID
-   *      uint32_t - core_ab
-   */
-  CRTC_SET_CORE_AB,
-   /*
-   * Op: Sets MNOC bus instantaneous bandwidth
-   * Arg: uint32_t - CRTC ID
-   *      uint32_t - core_ib
-   */
-  CRTC_SET_CORE_IB,
-  /*
-   * Op: Sets LLCC Bus average bandwidth
-   * Arg: uint32_t - CRTC ID
-   *      uint32_t - llcc_ab
-   */
-  CRTC_SET_LLCC_AB,
-  /*
-   * Op: Sets LLCC Bus instantaneous bandwidth
-   * Arg: uint32_t - CRTC ID
-   *      uint32_t - llcc_ib
-   */
-  CRTC_SET_LLCC_IB,
-  /*
-   * Op: Sets DRAM bus average bandwidth
-   * Arg: uint32_t - CRTC ID
-   *      uint32_t - dram_ab
-   */
-  CRTC_SET_DRAM_AB,
-  /*
-   * Op: Sets DRAM bus instantaneous bandwidth
-   * Arg: uint32_t - CRTC ID
-   *      uint32_t - dram_ib
-   */
-  CRTC_SET_DRAM_IB,
-  /*
-   * Op: Sets Rotator BW for inline rotation
-   * Arg: uint32_t - CRTC ID
-   *      uint32_t - rot_bw
-   */
-  CRTC_SET_ROT_PREFILL_BW,
-  /*
-   * Op: Sets rotator clock for inline rotation
-   * Arg: uint32_t - CRTC ID
-   *      uint32_t - rot_clk
-   */
-  CRTC_SET_ROT_CLK,
-  /*
-   * Op: Sets destination scalar data
-   * Arg: uint32_t - CRTC ID
-   *      uint64_t - Pointer to destination scalar data
-   */
-  CRTC_SET_DEST_SCALER_CONFIG,
-  /*
-   * Op: Returns release fence for this frame. Should be called after Commit() on
-   * DRMAtomicReqInterface.
-   * Arg: uint32_t - CRTC ID
-   *      int * - Pointer to an integer that will hold the returned fence
-   */
-  CRTC_GET_RELEASE_FENCE,
-  /*
-   * Op: Sets PP feature
-   * Arg: uint32_t - CRTC ID
-   *      DRMPPFeatureInfo * - PP feature data pointer
-   */
-  CRTC_SET_POST_PROC,
-  /*
-   * Op: Sets CRTC ROIs.
-   * Arg: uint32_t - CRTC ID
-   *      uint32_t - number of ROIs
-   *      DRMRect * - Array of CRTC ROIs
-   */
-  CRTC_SET_ROI,
-  /*
-   * Op: Sets Security level for CRTC.
-   * Arg: uint32_t - CRTC ID
-   *      uint32_t - Security level
-   */
-  CRTC_SET_SECURITY_LEVEL,
-  /*
-   * Op: sets solid fill stages
-   * Arg: uint32_t - CRTC ID
-   *      Vector of DRMSolidfillStage
-   */
-  CRTC_SET_SOLIDFILL_STAGES,
-  /*
-   * Op: Sets idle timeout.
-   * Arg: uint32_t - CRTC ID
-   *      uint32_t - idle timeout in ms
-   */
-  CRTC_SET_IDLE_TIMEOUT,
-  /*
-   * Op: Returns retire fence for this commit. Should be called after Commit() on
-   * DRMAtomicReqInterface.
-   * Arg: uint32_t - Connector ID
-   *      int * - Pointer to an integer that will hold the returned fence
-   */
-  CONNECTOR_GET_RETIRE_FENCE,
-  /*
-   * Op: Sets writeback connector destination rect
-   * Arg: uint32_t - Connector ID
-   *      DRMRect - Dst Rectangle
-   */
-  CONNECTOR_SET_OUTPUT_RECT,
-  /*
-   * Op: Sets frame buffer ID for writeback connector.
-   * Arg: uint32_t - Connector ID
-   *      uint32_t - Framebuffer ID
-   */
-  CONNECTOR_SET_OUTPUT_FB_ID,
-  /*
-   * Op: Sets power mode for connector.
-   * Arg: uint32_t - Connector ID
-   *      uint32_t - Power Mode
-   */
-  CONNECTOR_SET_POWER_MODE,
-  /*
-   * Op: Sets panel ROIs.
-   * Arg: uint32_t - Connector ID
-   *      uint32_t - number of ROIs
-   *      DRMRect * - Array of Connector ROIs
-   */
-  CONNECTOR_SET_ROI,
-  /*
-   * Op: Sets the connector to autorefresh mode.
-   * Arg: uint32_t - Connector ID
-   *      uint32_t - Enable-1, Disable-0
-   */
-  CONNECTOR_SET_AUTOREFRESH,
-  /*
-   * Op: Set FB secure mode for Writeback connector.
-   * Arg: uint32_t - Connector ID
-   *      uint32_t - FB Secure mode
-   */
-  CONNECTOR_SET_FB_SECURE_MODE,
-  /*
-   * Op: Sets a crtc id to this connector
-   * Arg: uint32_t - Connector ID
-   *      uint32_t - CRTC ID
-   */
-  CONNECTOR_SET_CRTC,
-  /*
-   * Op: Sets PP feature
-   * Arg: uint32_t - Connector ID
-   * DRMPPFeatureInfo * - PP feature data pointer
-   */
-   CONNECTOR_SET_POST_PROC,
-  /*
-   * Op: Sets connector hdr metadata
-   * Arg: uint32_t - Connector ID
-   *      drm_msm_ext_hdr_metadata - hdr_metadata
-   */
-  CONNECTOR_SET_HDR_METADATA,
-};
-
-enum struct DRMRotation {
-  FLIP_H = 0x1,
-  FLIP_V = 0x2,
-  ROT_180 = FLIP_H | FLIP_V,
-  ROT_90 = 0x4,
-};
-
-enum struct DRMPowerMode {
-  ON,
-  DOZE,
-  DOZE_SUSPEND,
-  OFF,
-};
-
-enum struct DRMBlendType {
-  UNDEFINED = 0,
-  OPAQUE = 1,
-  PREMULTIPLIED = 2,
-  COVERAGE = 3,
-};
-
-enum struct DRMSrcConfig {
-  DEINTERLACE = 0,
-};
-
-/* Display type to identify a suitable connector */
-enum struct DRMDisplayType {
-  PERIPHERAL,
-  TV,
-  VIRTUAL,
-};
-
-struct DRMRect {
-  uint32_t left;    // Left-most pixel coordinate.
-  uint32_t top;     // Top-most pixel coordinate.
-  uint32_t right;   // Right-most pixel coordinate.
-  uint32_t bottom;  // Bottom-most pixel coordinate.
-};
-
-//------------------------------------------------------------------------
-// DRM Info Query Types
-//------------------------------------------------------------------------
-
-enum struct QSEEDVersion {
-  V1,
-  V2,
-  V3,
-};
-
-/* QSEED3 Step version */
-enum struct QSEEDStepVersion {
-  V2,
-  V3,
-  V4,
-};
-
-enum struct SmartDMARevision {
-  V1,
-  V2,
-};
-
-/* Per CRTC Resource Info*/
-struct DRMCrtcInfo {
-  bool has_src_split;
-  bool has_hdr;
-  uint32_t max_blend_stages;
-  uint32_t max_solidfill_stages;
-  QSEEDVersion qseed_version;
-  SmartDMARevision smart_dma_rev;
-  float ib_fudge_factor;
-  float clk_fudge_factor;
-  uint32_t dest_scale_prefill_lines;
-  uint32_t undersized_prefill_lines;
-  uint32_t macrotile_prefill_lines;
-  uint32_t nv12_prefill_lines;
-  uint32_t linear_prefill_lines;
-  uint32_t downscale_prefill_lines;
-  uint32_t extra_prefill_lines;
-  uint32_t amortized_threshold;
-  uint64_t max_bandwidth_low;
-  uint64_t max_bandwidth_high;
-  uint32_t max_sde_clk;
-  CompRatioMap comp_ratio_rt_map;
-  CompRatioMap comp_ratio_nrt_map;
-  uint32_t hw_version;
-  uint32_t dest_scaler_count = 0;
-  uint32_t max_dest_scaler_input_width = 0;
-  uint32_t max_dest_scaler_output_width = 0;
-  uint32_t max_dest_scale_up = 1;
-  uint32_t min_prefill_lines = 0;
-};
-
-enum struct DRMPlaneType {
-  // Has CSC and scaling capability
-  VIG = 0,
-  // Has scaling capability but no CSC
-  RGB,
-  // No scaling support
-  DMA,
-  // Supports a small dimension and doesn't use a CRTC stage
-  CURSOR,
-  MAX,
-};
-
-struct DRMPlaneTypeInfo {
-  DRMPlaneType type;
-  uint32_t master_plane_id;
-  // FourCC format enum and modifier
-  std::vector<std::pair<uint32_t, uint64_t>> formats_supported;
-  uint32_t max_linewidth;
-  uint32_t max_upscale;
-  uint32_t max_downscale;
-  uint32_t max_horizontal_deci;
-  uint32_t max_vertical_deci;
-  uint64_t max_pipe_bandwidth;
-  uint32_t cache_size;  // cache size in bytes for inline rotation support.
-  QSEEDStepVersion qseed3_version;
-  bool multirect_prop_present = false;
-};
-
-// All DRM Planes as map<Plane_id , plane_type_info> listed from highest to lowest priority
-typedef std::vector<std::pair<uint32_t, DRMPlaneTypeInfo>>  DRMPlanesInfo;
-
-enum struct DRMTopology {
-  UNKNOWN,  // To be compat with driver defs in sde_rm.h
-  SINGLE_LM,
-  SINGLE_LM_DSC,
-  DUAL_LM,
-  DUAL_LM_DSC,
-  DUAL_LM_MERGE,
-  DUAL_LM_MERGE_DSC,
-  DUAL_LM_DSCMERGE,
-  PPSPLIT,
-};
-
-enum struct DRMPanelMode {
-  VIDEO,
-  COMMAND,
-};
-
-/* Per mode info */
-struct DRMModeInfo {
-  drmModeModeInfo mode;
-  DRMTopology topology;
-  // Valid only if mode is command
-  int num_roi;
-  int xstart;
-  int ystart;
-  int walign;
-  int halign;
-  int wmin;
-  int hmin;
-  bool roi_merge;
-};
-
-/* Per Connector Info*/
-struct DRMConnectorInfo {
-  uint32_t mmWidth;
-  uint32_t mmHeight;
-  uint32_t type;
-  std::vector<DRMModeInfo> modes;
-  std::string panel_name;
-  DRMPanelMode panel_mode;
-  bool is_primary;
-  // Valid only if DRMPanelMode is VIDEO
-  bool dynamic_fps;
-  // FourCC format enum and modifier
-  std::vector<std::pair<uint32_t, uint64_t>> formats_supported;
-  // Valid only if type is DRM_MODE_CONNECTOR_VIRTUAL
-  uint32_t max_linewidth;
-  DRMRotation panel_orientation;
-  drm_panel_hdr_properties panel_hdr_prop;
-  uint32_t transfer_time_us;
-  drm_msm_ext_hdr_properties ext_hdr_prop;
-};
-
-/* Identifier token for a display */
-struct DRMDisplayToken {
-  uint32_t conn_id;
-  uint32_t crtc_id;
-  uint32_t crtc_index;
-};
-
-enum DRMPPFeatureID {
-  kFeaturePcc,
-  kFeatureIgc,
-  kFeaturePgc,
-  kFeatureMixerGc,
-  kFeaturePaV2,
-  kFeatureDither,
-  kFeatureGamut,
-  kFeaturePADither,
-  kFeaturePAHsic,
-  kFeaturePASixZone,
-  kFeaturePAMemColSkin,
-  kFeaturePAMemColSky,
-  kFeaturePAMemColFoliage,
-  kFeaturePAMemColProt,
-  kPPFeaturesMax,
-};
-
-enum DRMPPPropType {
-  kPropEnum,
-  kPropRange,
-  kPropBlob,
-  kPropTypeMax,
-};
-
-struct DRMPPFeatureInfo {
-  DRMPPFeatureID id;
-  DRMPPPropType type;
-  uint32_t version;
-  uint32_t payload_size;
-  void *payload;
-  uint32_t object_type;
-};
-
-enum DRMCscType {
-  kCscYuv2Rgb601L,
-  kCscYuv2Rgb601FR,
-  kCscYuv2Rgb709L,
-  kCscYuv2Rgb2020L,
-  kCscYuv2Rgb2020FR,
-  kCscTypeMax,
-};
-
-struct DRMScalerLUTInfo {
-  uint32_t dir_lut_size = 0;
-  uint32_t cir_lut_size = 0;
-  uint32_t sep_lut_size = 0;
-  uint64_t dir_lut = 0;
-  uint64_t cir_lut = 0;
-  uint64_t sep_lut = 0;
-};
-
-enum struct DRMSecureMode {
-  NON_SECURE,
-  SECURE,
-  NON_SECURE_DIR_TRANSLATION,
-  SECURE_DIR_TRANSLATION,
-};
-
-enum struct DRMSecurityLevel {
-  SECURE_NON_SECURE,
-  SECURE_ONLY,
-};
-
-enum struct DRMMultiRectMode {
-  NONE = 0,
-  PARALLEL = 1,
-  SERIAL = 2,
-};
-
-struct DRMSolidfillStage {
- DRMRect bounding_rect {};
- bool is_exclusion_rect = false;
- uint32_t color = 0xff000000; // in 8bit argb
- uint32_t red = 0;
- uint32_t blue = 0;
- uint32_t green = 0;
- uint32_t alpha = 0xff;
- uint32_t color_bit_depth = 0;
- uint32_t z_order = 0;
- uint32_t plane_alpha = 0xff;
-};
-
-/* DRM Atomic Request Property Set.
- *
- * Helper class to create and populate atomic properties of DRM components
- * when rendered in DRM atomic mode */
-class DRMAtomicReqInterface {
- public:
-  virtual ~DRMAtomicReqInterface() {}
-  /* Perform request operation.
-   *
-   * [input]: opcode: operation code from DRMOps list.
-   *          var_arg: arguments for DRMOps's can differ in number and
-   *          data type. Refer above DRMOps to details.
-   * [return]: Error code if the API fails, 0 on success.
-   */
-  virtual int Perform(DRMOps opcode, ...) = 0;
-
-  /*
-   * Commit the params set via Perform(). Also resets the properties after commit. Needs to be
-   * called every frame.
-   * [input]: synchronous: Determines if the call should block until a h/w flip
-   * [input]: retain_planes: Retains already staged planes. Useful when not explicitly programming
-   *          planes but still need the previously staged ones to not be unstaged
-   * [return]: Error code if the API fails, 0 on success.
-   */
-  virtual int Commit(bool synchronous, bool retain_planes) = 0;
-  /*
-   * Validate the params set via Perform().
-   * [return]: Error code if the API fails, 0 on success.
-   */
-  virtual int Validate() = 0;
-};
-
-class DRMManagerInterface;
-
-/* Populates a singleton instance of DRMManager */
-typedef int (*GetDRMManager)(int fd, DRMManagerInterface **intf);
-
-/* Destroy DRMManager instance */
-typedef int (*DestroyDRMManager)();
-
-/*
- * DRM Manager Interface - Any class which plans to implement helper function for vendor
- * specific DRM driver implementation must implement the below interface routines to work
- * with SDM.
- */
-
-class DRMManagerInterface {
- public:
-  virtual ~DRMManagerInterface() {}
-
-  /*
-   * Since SDM completely manages the planes. GetPlanesInfo will provide all
-   * the plane information.
-   * [output]: DRMPlanesInfo: Resource Info for planes.
-   */
-  virtual void GetPlanesInfo(DRMPlanesInfo *info) = 0;
-
-  /*
-   * Will provide all the information of a selected crtc.
-   * [input]: Use crtc id 0 to obtain system wide info
-   * [output]: DRMCrtcInfo: Resource Info for the given CRTC id.
-   */
-  virtual void GetCrtcInfo(uint32_t crtc_id, DRMCrtcInfo *info) = 0;
-
-  /*
-   * Will provide all the information of a selected connector.
-   * [output]: DRMConnectorInfo: Resource Info for the given connector id
-   */
-  virtual void GetConnectorInfo(uint32_t conn_id, DRMConnectorInfo *info) = 0;
-
-  /*
-   * Will query post propcessing feature info of a CRTC.
-   * [output]: DRMPPFeatureInfo: CRTC post processing feature info
-   */
-  virtual void GetCrtcPPInfo(uint32_t crtc_id, DRMPPFeatureInfo *info) = 0;
-  /*
-   * Register a logical display to receive a token.
-   * Each display pipeline in DRM is identified by its CRTC and Connector(s).
-   * On display connect(bootup or hotplug), clients should invoke this interface to
-   * establish the pipeline for the display and should get a DisplayToken
-   * populated with crtc and connnector(s) id's. Here onwards, Client should
-   * use this token to represent the display for any Perform operations if
-   * needed.
-   *
-   * [input]: disp_type - Peripheral / TV / Virtual
-   * [output]: DRMDisplayToken - CRTC and Connector id's for the display
-   * [return]: 0 on success, a negative error value otherwise
-   */
-  virtual int RegisterDisplay(DRMDisplayType disp_type, DRMDisplayToken *tok) = 0;
-
-  /* Client should invoke this interface on display disconnect.
-   * [input]: DRMDisplayToken - identifier for the display.
-   */
-  virtual void UnregisterDisplay(const DRMDisplayToken &token) = 0;
-
-  /*
-   * Creates and returns an instance of DRMAtomicReqInterface corresponding to a display token
-   * returned as part of RegisterDisplay API. Needs to be called per display.
-   * [input]: DRMDisplayToken that identifies a display pipeline
-   * [output]: Pointer to an instance of DRMAtomicReqInterface.
-   * [return]: Error code if the API fails, 0 on success.
-   */
-  virtual int CreateAtomicReq(const DRMDisplayToken &token, DRMAtomicReqInterface **intf) = 0;
-
-  /*
-   * Destroys the instance of DRMAtomicReqInterface
-   * [input]: Pointer to a DRMAtomicReqInterface
-   * [return]: Error code if the API fails, 0 on success.
-   */
-  virtual int DestroyAtomicReq(DRMAtomicReqInterface *intf) = 0;
-  /*
-   * Sets the global scaler LUT
-   * [input]: LUT Info
-   * [return]: Error code if the API fails, 0 on success.
-   */
-  virtual int SetScalerLUT(const DRMScalerLUTInfo &lut_info) = 0;
-};
-
-}  // namespace sde_drm
-#endif  // __DRM_INTERFACE_H__
diff --git a/libdrmutils/drm_lib_loader.cpp b/libdrmutils/drm_lib_loader.cpp
deleted file mode 100644
index 83c9f1b..0000000
--- a/libdrmutils/drm_lib_loader.cpp
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
-* Copyright (c) 2017, The Linux Foundation. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without
-* modification, are permitted provided that the following conditions are
-* met:
-*   * Redistributions of source code must retain the above copyright
-*     notice, this list of conditions and the following disclaimer.
-*   * Redistributions in binary form must reproduce the above
-*     copyright notice, this list of conditions and the following
-*     disclaimer in the documentation and/or other materials provided
-*     with the distribution.
-*   * Neither the name of The Linux Foundation nor the names of its
-*     contributors may be used to endorse or promote products derived
-*     from this software without specific prior written permission.
-*
-* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
-* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
-* ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
-* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
-* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#include <dlfcn.h>
-
-#include "drm_lib_loader.h"
-
-#define __CLASS__ "DRMLibLoader"
-
-using std::mutex;
-using std::lock_guard;
-
-namespace drm_utils {
-
-DRMLibLoader *DRMLibLoader::s_instance = nullptr;
-mutex DRMLibLoader::s_lock;
-
-DRMLibLoader *DRMLibLoader::GetInstance() {
-  lock_guard<mutex> obj(s_lock);
-
-  if (!s_instance) {
-    s_instance = new DRMLibLoader();
-  }
-
-  return s_instance;
-}
-
-void DRMLibLoader::Destroy() {
-  lock_guard<mutex> obj(s_lock);
-  if (s_instance) {
-    delete s_instance;
-    s_instance = nullptr;
-  }
-}
-
-DRMLibLoader::DRMLibLoader() {
-  if (Open("libsdedrm.so")) {
-    if (Sym("GetDRMManager", reinterpret_cast<void **>(&func_get_drm_manager_)) &&
-        Sym("DestroyDRMManager", reinterpret_cast<void **>(&func_destroy_drm_manager_))) {
-      is_loaded_ = true;
-    }
-  }
-}
-
-DRMLibLoader::~DRMLibLoader() {
-  if (lib_) {
-    ::dlclose(lib_);
-    lib_ = nullptr;
-  }
-}
-
-bool DRMLibLoader::Open(const char *lib_name) {
-  lib_ = ::dlopen(lib_name, RTLD_NOW);
-
-  return (lib_ != nullptr);
-}
-
-bool DRMLibLoader::Sym(const char *func_name, void **func_ptr) {
-  if (lib_) {
-    *func_ptr = ::dlsym(lib_, func_name);
-  }
-
-  return (*func_ptr != nullptr);
-}
-
-}  // namespace drm_utils
diff --git a/libdrmutils/drm_lib_loader.h b/libdrmutils/drm_lib_loader.h
deleted file mode 100644
index d132d69..0000000
--- a/libdrmutils/drm_lib_loader.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
-* Copyright (c) 2017, The Linux Foundation. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without
-* modification, are permitted provided that the following conditions are
-* met:
-*   * Redistributions of source code must retain the above copyright
-*     notice, this list of conditions and the following disclaimer.
-*   * Redistributions in binary form must reproduce the above
-*     copyright notice, this list of conditions and the following
-*     disclaimer in the documentation and/or other materials provided
-*     with the distribution.
-*   * Neither the name of The Linux Foundation nor the names of its
-*     contributors may be used to endorse or promote products derived
-*     from this software without specific prior written permission.
-*
-* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
-* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
-* ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
-* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
-* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#ifndef __DRM_LIB_LOADER_H__
-#define __DRM_LIB_LOADER_H__
-
-#include <drm_interface.h>
-#include <mutex>
-
-namespace drm_utils {
-
-class DRMLibLoader {
- public:
-  ~DRMLibLoader();
-  bool IsLoaded() { return is_loaded_; }
-  sde_drm::GetDRMManager FuncGetDRMManager() { return func_get_drm_manager_; }
-  sde_drm::DestroyDRMManager FuncDestroyDRMManager() { return func_destroy_drm_manager_; }
-
-  static DRMLibLoader *GetInstance();
-  static void Destroy();
-
- private:
-  DRMLibLoader();
-  bool Open(const char *lib_name);
-  bool Sym(const char *func_name, void **func_ptr);
-
-  void *lib_ = {};
-  sde_drm::GetDRMManager func_get_drm_manager_ = {};
-  sde_drm::DestroyDRMManager func_destroy_drm_manager_ = {};
-  bool is_loaded_ = false;
-
-  static DRMLibLoader *s_instance;  // Singleton instance
-  static std::mutex s_lock;
-};
-
-}  // namespace drm_utils
-
-#endif  // __DRM_LIB_LOADER_H__
diff --git a/libdrmutils/drm_logger.h b/libdrmutils/drm_logger.h
deleted file mode 100644
index 7f81d88..0000000
--- a/libdrmutils/drm_logger.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
-* Copyright (c) 2017 - 2018, The Linux Foundation. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without
-* modification, are permitted provided that the following conditions are
-* met:
-*   * Redistributions of source code must retain the above copyright
-*     notice, this list of conditions and the following disclaimer.
-*   * Redistributions in binary form must reproduce the above
-*     copyright notice, this list of conditions and the following
-*     disclaimer in the documentation and/or other materials provided
-*     with the distribution.
-*   * Neither the name of The Linux Foundation nor the names of its
-*     contributors may be used to endorse or promote products derived
-*     from this software without specific prior written permission.
-*
-* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
-* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
-* ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
-* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
-* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#ifndef __DRM_LOGGER_H__
-#define __DRM_LOGGER_H__
-
-#include <debug_handler.h>
-#include <utility>
-
-namespace drm_utils {
-
-#define DRM_LOG_TAG  4  // = kTagRotator
-
-#define DRM_LOGE(format, ...) DLOGE(format, ##__VA_ARGS__)
-#define DRM_LOGW(format, ...) DLOGW_IF(DRM_LOG_TAG, format, ##__VA_ARGS__)
-#define DRM_LOGI(format, ...) DLOGI_IF(DRM_LOG_TAG, format, ##__VA_ARGS__)
-#define DRM_LOGD(format, ...) DLOGD_IF(DRM_LOG_TAG, format, ##__VA_ARGS__)
-#define DRM_LOGV(format, ...) DLOGV_IF(DRM_LOG_TAG, format, ##__VA_ARGS__)
-
-}  // namespace drm_utils
-
-#endif  // __DRM_LOGGER_H__
diff --git a/libdrmutils/drm_master.cpp b/libdrmutils/drm_master.cpp
deleted file mode 100644
index 96429e2..0000000
--- a/libdrmutils/drm_master.cpp
+++ /dev/null
@@ -1,155 +0,0 @@
-/*
-* Copyright (c) 2017 - 2018, The Linux Foundation. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without
-* modification, are permitted provided that the following conditions are
-* met:
-*   * Redistributions of source code must retain the above copyright
-*     notice, this list of conditions and the following disclaimer.
-*   * Redistributions in binary form must reproduce the above
-*     copyright notice, this list of conditions and the following
-*     disclaimer in the documentation and/or other materials provided
-*     with the distribution.
-*   * Neither the name of The Linux Foundation nor the names of its
-*     contributors may be used to endorse or promote products derived
-*     from this software without specific prior written permission.
-*
-* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
-* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
-* ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
-* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
-* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#include <errno.h>
-#include <fcntl.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <xf86drm.h>
-#include <xf86drmMode.h>
-// Intentionally included after xf86 headers so that they in-turn include libdrm version of drm.h
-// that doesn't use keyword "virtual" for a variable name. Not doing so leads to the kernel version
-// of drm.h being included causing compilation to fail
-#include <drm/msm_drm.h>
-#include <algorithm>
-#include <iterator>
-
-#include "drm_master.h"
-
-#define __CLASS__ "DRMMaster"
-
-using std::mutex;
-using std::lock_guard;
-using std::begin;
-using std::copy;
-using std::end;
-using std::fill;
-
-namespace drm_utils {
-
-DRMMaster *DRMMaster::s_instance = nullptr;
-mutex DRMMaster::s_lock;
-
-int DRMMaster::GetInstance(DRMMaster **master) {
-  lock_guard<mutex> obj(s_lock);
-
-  if (!s_instance) {
-    s_instance = new DRMMaster();
-    if (s_instance->Init() < 0) {
-      delete s_instance;
-      s_instance = nullptr;
-      return -ENODEV;
-    }
-  }
-
-  *master = s_instance;
-  return 0;
-}
-
-void DRMMaster::DestroyInstance() {
-  lock_guard<mutex> obj(s_lock);
-  delete s_instance;
-  s_instance = nullptr;
-}
-
-int DRMMaster::Init() {
-  dev_fd_ = drmOpen("msm_drm", nullptr);
-  if (dev_fd_ < 0) {
-    DRM_LOGE("drmOpen failed with error %d", dev_fd_);
-    return -ENODEV;
-  }
-
-  return 0;
-}
-
-DRMMaster::~DRMMaster() {
-  drmClose(dev_fd_);
-  dev_fd_ = -1;
-}
-
-int DRMMaster::CreateFbId(const DRMBuffer &drm_buffer, uint32_t *fb_id) {
-  uint32_t gem_handle = 0;
-  int ret = drmPrimeFDToHandle(dev_fd_, drm_buffer.fd, &gem_handle);
-  if (ret) {
-    DRM_LOGW("drmPrimeFDToHandle failed with error %d", ret);
-    return ret;
-  }
-
-  struct drm_mode_fb_cmd2 cmd2 {};
-  cmd2.width = drm_buffer.width;
-  cmd2.height = drm_buffer.height;
-  cmd2.pixel_format = drm_buffer.drm_format;
-  cmd2.flags = DRM_MODE_FB_MODIFIERS;
-  fill(begin(cmd2.handles), begin(cmd2.handles) + drm_buffer.num_planes, gem_handle);
-  copy(begin(drm_buffer.stride), end(drm_buffer.stride), begin(cmd2.pitches));
-  copy(begin(drm_buffer.offset), end(drm_buffer.offset), begin(cmd2.offsets));
-  fill(begin(cmd2.modifier), begin(cmd2.modifier) + drm_buffer.num_planes,
-       drm_buffer.drm_format_modifier);
-
-  if ((ret = drmIoctl(dev_fd_, DRM_IOCTL_MODE_ADDFB2, &cmd2))) {
-    DRM_LOGE("DRM_IOCTL_MODE_ADDFB2 failed with error %d", ret);
-  } else {
-    *fb_id = cmd2.fb_id;
-  }
-
-  struct drm_gem_close gem_close = {};
-  gem_close.handle = gem_handle;
-  int ret1 = drmIoctl(dev_fd_, DRM_IOCTL_GEM_CLOSE, &gem_close);
-  if (ret1) {
-    DRM_LOGE("drmIoctl::DRM_IOCTL_GEM_CLOSE failed with error %d", ret1);
-    return ret1;
-  }
-
-  return ret;
-}
-
-int DRMMaster::RemoveFbId(uint32_t fb_id) {
-  int ret = 0;
-#ifdef DRM_IOCTL_MSM_RMFB2
-  ret = drmIoctl(dev_fd_, DRM_IOCTL_MSM_RMFB2, &fb_id);
-  if (ret) {
-    DRM_LOGE("drmIoctl::DRM_IOCTL_MSM_RMFB2 failed for fb_id %d with error %d", fb_id, errno);
-  }
-#else
-  ret = drmModeRmFB(dev_fd_, fb_id);
-  if (ret) {
-    DRM_LOGE("drmModeRmFB failed for fb_id %d with error %d", fb_id, ret);
-  }
-#endif
-  return ret;
-}
-
-bool DRMMaster::IsRmFbRefCounted() {
-#ifdef DRM_IOCTL_MSM_RMFB2
-  return true;
-#endif
-  return false;
-}
-
-}  // namespace drm_utils
diff --git a/libdrmutils/drm_master.h b/libdrmutils/drm_master.h
deleted file mode 100644
index 18f51eb..0000000
--- a/libdrmutils/drm_master.h
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
-* Copyright (c) 2017, The Linux Foundation. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without
-* modification, are permitted provided that the following conditions are
-* met:
-*   * Redistributions of source code must retain the above copyright
-*     notice, this list of conditions and the following disclaimer.
-*   * Redistributions in binary form must reproduce the above
-*     copyright notice, this list of conditions and the following
-*     disclaimer in the documentation and/or other materials provided
-*     with the distribution.
-*   * Neither the name of The Linux Foundation nor the names of its
-*     contributors may be used to endorse or promote products derived
-*     from this software without specific prior written permission.
-*
-* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
-* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
-* ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
-* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
-* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#ifndef __DRM_MASTER_H__
-#define __DRM_MASTER_H__
-
-#include <mutex>
-
-#include "drm_logger.h"
-
-namespace drm_utils {
-
-struct DRMBuffer {
-  int fd = -1;
-  uint32_t width = 0;
-  uint32_t height = 0;
-  uint32_t drm_format = 0;
-  uint64_t drm_format_modifier = 0;
-  uint32_t stride[4] = {};
-  uint32_t offset[4] = {};
-  uint32_t num_planes = 1;
-};
-
-class DRMMaster {
- public:
-  ~DRMMaster();
-  /* Converts from ION fd --> Prime Handle --> FB_ID.
-   * Input:
-   *   drm_buffer: A DRMBuffer obj that packages description of buffer
-   * Output:
-   *   fb_id: Pointer to store DRM framebuffer id into
-   * Returns:
-   *   ioctl error code
-   */
-  int CreateFbId(const DRMBuffer &drm_buffer, uint32_t *fb_id);
-  /* Removes the fb_id from DRM
-   * Input:
-   *   fb_id: DRM FB to be removed
-   * Returns:
-   *   ioctl error code
-   */
-  int RemoveFbId(uint32_t fb_id);
-  /* Poplulates master DRM fd
-   * Input:
-   *   fd: Pointer to store master fd into
-   */
-  void GetHandle(int *fd) { *fd = dev_fd_; }
-  /* Returns true if the ref counted version of rmfb is being used */
-  bool IsRmFbRefCounted();
-
-  /* Creates an instance of DRMMaster if it doesn't exist and initializes it. Threadsafe.
-   * Input:
-   *   master: Pointer to store a pointer to the instance
-   * Returns:
-   *   -ENODEV if device cannot be opened or initilization fails
-   */
-  static int GetInstance(DRMMaster **master);
-  static void DestroyInstance();
-
- private:
-  DRMMaster() {}
-  int Init();
-
-  int dev_fd_ = -1;              // Master fd for DRM
-  static DRMMaster *s_instance;  // Singleton instance
-  static std::mutex s_lock;
-};
-
-}  // namespace drm_utils
-
-#endif  // __DRM_MASTER_H__
diff --git a/libdrmutils/drm_res_mgr.cpp b/libdrmutils/drm_res_mgr.cpp
deleted file mode 100644
index 1d29495..0000000
--- a/libdrmutils/drm_res_mgr.cpp
+++ /dev/null
@@ -1,151 +0,0 @@
-/*
-* Copyright (c) 2017, The Linux Foundation. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without
-* modification, are permitted provided that the following conditions are
-* met:
-*   * Redistributions of source code must retain the above copyright
-*     notice, this list of conditions and the following disclaimer.
-*   * Redistributions in binary form must reproduce the above
-*     copyright notice, this list of conditions and the following
-*     disclaimer in the documentation and/or other materials provided
-*     with the distribution.
-*   * Neither the name of The Linux Foundation nor the names of its
-*     contributors may be used to endorse or promote products derived
-*     from this software without specific prior written permission.
-*
-* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
-* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
-* ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
-* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
-* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#include <errno.h>
-
-#include "drm_master.h"
-#include "drm_res_mgr.h"
-
-#define DEBUG 0
-#define __CLASS__ "DRMResMgr"
-
-using std::mutex;
-using std::lock_guard;
-
-namespace drm_utils {
-
-DRMResMgr *DRMResMgr::s_instance = nullptr;
-mutex DRMResMgr::s_lock;
-
-static bool GetConnector(int dev_fd, drmModeRes *res, drmModeConnector **connector) {
-  for (auto i = 0; i < res->count_connectors; i++) {
-    drmModeConnector *conn = drmModeGetConnector(dev_fd, res->connectors[i]);
-    if (conn && conn->connector_type == DRM_MODE_CONNECTOR_DSI && conn->count_modes &&
-        conn->connection == DRM_MODE_CONNECTED) {
-      *connector = conn;
-      DRM_LOGI("Found connector %d", conn->connector_id);
-      return true;
-    }
-  }
-
-  return false;
-}
-
-static bool GetEncoder(int dev_fd, drmModeConnector *conn, drmModeEncoder **encoder) {
-  for (auto i = 0; i < conn->count_encoders; i++) {
-    drmModeEncoder *enc = drmModeGetEncoder(dev_fd, conn->encoders[i]);
-    if (enc && enc->encoder_type == DRM_MODE_ENCODER_DSI) {
-      *encoder = enc;
-      DRM_LOGI("Found encoder %d", enc->encoder_id);
-      return true;
-    }
-  }
-  return false;
-}
-
-static bool GetCrtc(int dev_fd, drmModeRes *res, drmModeEncoder *enc, drmModeCrtc **crtc) {
-  for (auto i = 0; i < res->count_crtcs; i++) {
-    if (enc->possible_crtcs & (1 << i)) {
-      drmModeCrtc *c = drmModeGetCrtc(dev_fd, res->crtcs[i]);
-      if (c) {
-        *crtc = c;
-        DRM_LOGI("Found crtc %d", c->crtc_id);
-        return true;
-      }
-    }
-  }
-
-  return false;
-}
-
-#define __CLASS__ "DRMResMgr"
-
-int DRMResMgr::GetInstance(DRMResMgr **res_mgr) {
-  lock_guard<mutex> obj(s_lock);
-
-  if (!s_instance) {
-    s_instance = new DRMResMgr();
-    if (s_instance->Init() < 0) {
-      delete s_instance;
-      s_instance = nullptr;
-      return -ENODEV;
-    }
-  }
-
-  *res_mgr = s_instance;
-  return 0;
-}
-
-int DRMResMgr::Init() {
-  DRMMaster *master = nullptr;
-  int dev_fd = -1;
-
-  int ret = DRMMaster::GetInstance(&master);
-  if (ret < 0) {
-    return ret;
-  }
-
-  master->GetHandle(&dev_fd);
-  drmModeRes *res = drmModeGetResources(dev_fd);
-  if (res == nullptr) {
-    DRM_LOGE("drmModeGetResources failed");
-    return -ENODEV;
-  }
-
-  drmModeConnector *conn = nullptr;
-  if (!GetConnector(dev_fd, res, &conn)) {
-    DRM_LOGE("Failed to find a connector");
-    return -ENODEV;
-  }
-
-  drmModeEncoder *enc = nullptr;
-  if (!GetEncoder(dev_fd, conn, &enc)) {
-    DRM_LOGE("Failed to find an encoder");
-    drmModeFreeConnector(conn);
-    return -ENODEV;
-  }
-
-  drmModeCrtc *crtc = nullptr;
-  if (!GetCrtc(dev_fd, res, enc, &crtc)) {
-    DRM_LOGE("Failed to find a crtc");
-    drmModeFreeEncoder(enc);
-    drmModeFreeConnector(conn);
-    drmModeFreeResources(res);
-    return -ENODEV;
-  }
-
-  res_ = res;
-  conn_ = conn;
-  enc_ = enc;
-  crtc_ = crtc;
-
-  return 0;
-}
-
-}  // namespace drm_utils
diff --git a/libdrmutils/drm_res_mgr.h b/libdrmutils/drm_res_mgr.h
deleted file mode 100644
index 3a8378c..0000000
--- a/libdrmutils/drm_res_mgr.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
-* Copyright (c) 2017, The Linux Foundation. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without
-* modification, are permitted provided that the following conditions are
-* met:
-*   * Redistributions of source code must retain the above copyright
-*     notice, this list of conditions and the following disclaimer.
-*   * Redistributions in binary form must reproduce the above
-*     copyright notice, this list of conditions and the following
-*     disclaimer in the documentation and/or other materials provided
-*     with the distribution.
-*   * Neither the name of The Linux Foundation nor the names of its
-*     contributors may be used to endorse or promote products derived
-*     from this software without specific prior written permission.
-*
-* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
-* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
-* ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
-* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
-* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#ifndef __DRM_RES_MGR_H__
-#define __DRM_RES_MGR_H__
-
-#include <xf86drm.h>
-#include <xf86drmMode.h>
-
-#include <mutex>
-
-namespace drm_utils {
-
-class DRMResMgr {
- public:
-  /* Returns the default connector id for primary panel */
-  void GetConnectorId(uint32_t *id) { *id = conn_->connector_id; }
-  /* Returns the default crtc id for primary pipeline */
-  void GetCrtcId(uint32_t *id) { *id = crtc_->crtc_id; }
-  /* Returns the default mode currently used by the connector */
-  void GetMode(drmModeModeInfo *mode) { *mode = conn_->modes[0]; }
-  /* Returns the panel dimensions in mm */
-  void GetDisplayDimInMM(uint32_t *w, uint32_t *h) {
-    *w = conn_->mmWidth;
-    *h = conn_->mmHeight;
-  }
-
-  /* Creates and initializes an instance of DRMResMgr. On success, returns a pointer to it, on
-   * failure returns -ENODEV */
-  static int GetInstance(DRMResMgr **res_mgr);
-
- private:
-  int Init();
-
-  drmModeRes *res_ = nullptr;
-  drmModeConnector *conn_ = nullptr;
-  drmModeEncoder *enc_ = nullptr;
-  drmModeCrtc *crtc_ = nullptr;
-
-  static DRMResMgr *s_instance;
-  static std::mutex s_lock;
-};
-
-}  // namespace drm_utils
-
-#endif  // __DRM_RES_MGR_H__
diff --git a/liblight/Android.mk b/liblight/Android.mk
deleted file mode 100644
index 5720bba..0000000
--- a/liblight/Android.mk
+++ /dev/null
@@ -1,33 +0,0 @@
-# Copyright (C) 2008 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.
-
-LOCAL_PATH:= $(call my-dir)
-# HAL module implemenation stored in
-# hw/<COPYPIX_HARDWARE_MODULE_ID>.<ro.board.platform>.so
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := lights.c
-LOCAL_MODULE_RELATIVE_PATH := hw
-LOCAL_SHARED_LIBRARIES := liblog
-LOCAL_HEADER_LIBRARIES := libhardware_headers
-LOCAL_CFLAGS := -DLOG_TAG=\"qdlights\"
-ifeq ($(LLVM_SA), true)
-    LOCAL_CFLAGS += --compile-and-analyze --analyzer-perf --analyzer-Werror
-endif
-LOCAL_CLANG  := true
-LOCAL_MODULE := lights.$(TARGET_BOARD_PLATFORM)
-LOCAL_MODULE_TAGS := optional
-LOCAL_VENDOR_MODULE := true
-
-include $(BUILD_SHARED_LIBRARY)
diff --git a/liblight/NOTICE b/liblight/NOTICE
deleted file mode 100644
index 7340b9e..0000000
--- a/liblight/NOTICE
+++ /dev/null
@@ -1,190 +0,0 @@
-
-   Copyright (c) 2008, 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.
-
-   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.
-
-
-                                 Apache License
-                           Version 2.0, January 2004
-                        http://www.apache.org/licenses/
-
-   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-   1. Definitions.
-
-      "License" shall mean the terms and conditions for use, reproduction,
-      and distribution as defined by Sections 1 through 9 of this document.
-
-      "Licensor" shall mean the copyright owner or entity authorized by
-      the copyright owner that is granting the License.
-
-      "Legal Entity" shall mean the union of the acting entity and all
-      other entities that control, are controlled by, or are under common
-      control with that entity. For the purposes of this definition,
-      "control" means (i) the power, direct or indirect, to cause the
-      direction or management of such entity, whether by contract or
-      otherwise, or (ii) ownership of fifty percent (50%) or more of the
-      outstanding shares, or (iii) beneficial ownership of such entity.
-
-      "You" (or "Your") shall mean an individual or Legal Entity
-      exercising permissions granted by this License.
-
-      "Source" form shall mean the preferred form for making modifications,
-      including but not limited to software source code, documentation
-      source, and configuration files.
-
-      "Object" form shall mean any form resulting from mechanical
-      transformation or translation of a Source form, including but
-      not limited to compiled object code, generated documentation,
-      and conversions to other media types.
-
-      "Work" shall mean the work of authorship, whether in Source or
-      Object form, made available under the License, as indicated by a
-      copyright notice that is included in or attached to the work
-      (an example is provided in the Appendix below).
-
-      "Derivative Works" shall mean any work, whether in Source or Object
-      form, that is based on (or derived from) the Work and for which the
-      editorial revisions, annotations, elaborations, or other modifications
-      represent, as a whole, an original work of authorship. For the purposes
-      of this License, Derivative Works shall not include works that remain
-      separable from, or merely link (or bind by name) to the interfaces of,
-      the Work and Derivative Works thereof.
-
-      "Contribution" shall mean any work of authorship, including
-      the original version of the Work and any modifications or additions
-      to that Work or Derivative Works thereof, that is intentionally
-      submitted to Licensor for inclusion in the Work by the copyright owner
-      or by an individual or Legal Entity authorized to submit on behalf of
-      the copyright owner. For the purposes of this definition, "submitted"
-      means any form of electronic, verbal, or written communication sent
-      to the Licensor or its representatives, including but not limited to
-      communication on electronic mailing lists, source code control systems,
-      and issue tracking systems that are managed by, or on behalf of, the
-      Licensor for the purpose of discussing and improving the Work, but
-      excluding communication that is conspicuously marked or otherwise
-      designated in writing by the copyright owner as "Not a Contribution."
-
-      "Contributor" shall mean Licensor and any individual or Legal Entity
-      on behalf of whom a Contribution has been received by Licensor and
-      subsequently incorporated within the Work.
-
-   2. Grant of Copyright License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      copyright license to reproduce, prepare Derivative Works of,
-      publicly display, publicly perform, sublicense, and distribute the
-      Work and such Derivative Works in Source or Object form.
-
-   3. Grant of Patent License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      (except as stated in this section) patent license to make, have made,
-      use, offer to sell, sell, import, and otherwise transfer the Work,
-      where such license applies only to those patent claims licensable
-      by such Contributor that are necessarily infringed by their
-      Contribution(s) alone or by combination of their Contribution(s)
-      with the Work to which such Contribution(s) was submitted. If You
-      institute patent litigation against any entity (including a
-      cross-claim or counterclaim in a lawsuit) alleging that the Work
-      or a Contribution incorporated within the Work constitutes direct
-      or contributory patent infringement, then any patent licenses
-      granted to You under this License for that Work shall terminate
-      as of the date such litigation is filed.
-
-   4. Redistribution. You may reproduce and distribute copies of the
-      Work or Derivative Works thereof in any medium, with or without
-      modifications, and in Source or Object form, provided that You
-      meet the following conditions:
-
-      (a) You must give any other recipients of the Work or
-          Derivative Works a copy of this License; and
-
-      (b) You must cause any modified files to carry prominent notices
-          stating that You changed the files; and
-
-      (c) You must retain, in the Source form of any Derivative Works
-          that You distribute, all copyright, patent, trademark, and
-          attribution notices from the Source form of the Work,
-          excluding those notices that do not pertain to any part of
-          the Derivative Works; and
-
-      (d) If the Work includes a "NOTICE" text file as part of its
-          distribution, then any Derivative Works that You distribute must
-          include a readable copy of the attribution notices contained
-          within such NOTICE file, excluding those notices that do not
-          pertain to any part of the Derivative Works, in at least one
-          of the following places: within a NOTICE text file distributed
-          as part of the Derivative Works; within the Source form or
-          documentation, if provided along with the Derivative Works; or,
-          within a display generated by the Derivative Works, if and
-          wherever such third-party notices normally appear. The contents
-          of the NOTICE file are for informational purposes only and
-          do not modify the License. You may add Your own attribution
-          notices within Derivative Works that You distribute, alongside
-          or as an addendum to the NOTICE text from the Work, provided
-          that such additional attribution notices cannot be construed
-          as modifying the License.
-
-      You may add Your own copyright statement to Your modifications and
-      may provide additional or different license terms and conditions
-      for use, reproduction, or distribution of Your modifications, or
-      for any such Derivative Works as a whole, provided Your use,
-      reproduction, and distribution of the Work otherwise complies with
-      the conditions stated in this License.
-
-   5. Submission of Contributions. Unless You explicitly state otherwise,
-      any Contribution intentionally submitted for inclusion in the Work
-      by You to the Licensor shall be under the terms and conditions of
-      this License, without any additional terms or conditions.
-      Notwithstanding the above, nothing herein shall supersede or modify
-      the terms of any separate license agreement you may have executed
-      with Licensor regarding such Contributions.
-
-   6. Trademarks. This License does not grant permission to use the trade
-      names, trademarks, service marks, or product names of the Licensor,
-      except as required for reasonable and customary use in describing the
-      origin of the Work and reproducing the content of the NOTICE file.
-
-   7. Disclaimer of Warranty. Unless required by applicable law or
-      agreed to in writing, Licensor provides the Work (and each
-      Contributor provides its Contributions) on an "AS IS" BASIS,
-      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-      implied, including, without limitation, any warranties or conditions
-      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
-      PARTICULAR PURPOSE. You are solely responsible for determining the
-      appropriateness of using or redistributing the Work and assume any
-      risks associated with Your exercise of permissions under this License.
-
-   8. Limitation of Liability. In no event and under no legal theory,
-      whether in tort (including negligence), contract, or otherwise,
-      unless required by applicable law (such as deliberate and grossly
-      negligent acts) or agreed to in writing, shall any Contributor be
-      liable to You for damages, including any direct, indirect, special,
-      incidental, or consequential damages of any character arising as a
-      result of this License or out of the use or inability to use the
-      Work (including but not limited to damages for loss of goodwill,
-      work stoppage, computer failure or malfunction, or any and all
-      other commercial damages or losses), even if such Contributor
-      has been advised of the possibility of such damages.
-
-   9. Accepting Warranty or Additional Liability. While redistributing
-      the Work or Derivative Works thereof, You may choose to offer,
-      and charge a fee for, acceptance of support, warranty, indemnity,
-      or other liability obligations and/or rights consistent with this
-      License. However, in accepting such obligations, You may act only
-      on Your own behalf and on Your sole responsibility, not on behalf
-      of any other Contributor, and only if You agree to indemnify,
-      defend, and hold each Contributor harmless for any liability
-      incurred by, or claims asserted against, such Contributor by reason
-      of your accepting any such warranty or additional liability.
-
-   END OF TERMS AND CONDITIONS
-
diff --git a/liblight/lights.c b/liblight/lights.c
deleted file mode 100644
index e83be16..0000000
--- a/liblight/lights.c
+++ /dev/null
@@ -1,382 +0,0 @@
-/*
- * Copyright (C) 2014, 2017-2018 The  Linux Foundation. All rights reserved.
- * Not a contribution
- * Copyright (C) 2008 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_NDEBUG 0
-
-#include <log/log.h>
-#include <cutils/properties.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <pthread.h>
-
-#include <sys/ioctl.h>
-#include <sys/types.h>
-
-#include <hardware/lights.h>
-
-#ifndef DEFAULT_LOW_PERSISTENCE_MODE_BRIGHTNESS
-#define DEFAULT_LOW_PERSISTENCE_MODE_BRIGHTNESS 0x80
-#endif
-
-/******************************************************************************/
-
-static pthread_once_t g_init = PTHREAD_ONCE_INIT;
-static pthread_mutex_t g_lock = PTHREAD_MUTEX_INITIALIZER;
-static struct light_state_t g_notification;
-static struct light_state_t g_battery;
-static int g_last_backlight_mode = BRIGHTNESS_MODE_USER;
-static int g_attention = 0;
-static bool g_has_persistence_node = false;
-
-char const*const RED_LED_FILE
-        = "/sys/class/leds/red/brightness";
-
-char const*const GREEN_LED_FILE
-        = "/sys/class/leds/green/brightness";
-
-char const*const BLUE_LED_FILE
-        = "/sys/class/leds/blue/brightness";
-
-char const*const LCD_FILE
-        = "/sys/class/leds/lcd-backlight/brightness";
-
-char const*const LCD_FILE2
-        = "/sys/class/backlight/panel0-backlight/brightness";
-
-char const*const BUTTON_FILE
-        = "/sys/class/leds/button-backlight/brightness";
-
-char const*const RED_BLINK_FILE
-        = "/sys/class/leds/red/blink";
-
-char const*const GREEN_BLINK_FILE
-        = "/sys/class/leds/green/blink";
-
-char const*const BLUE_BLINK_FILE
-        = "/sys/class/leds/blue/blink";
-
-char const*const PERSISTENCE_FILE
-        = "/sys/class/graphics/fb0/msm_fb_persist_mode";
-
-/**
- * device methods
- */
-
-void init_globals(void)
-{
-    // init the mutex
-    pthread_mutex_init(&g_lock, NULL);
-}
-
-static int
-write_int(char const* path, int value)
-{
-    int fd;
-    static int already_warned = 0;
-
-    fd = open(path, O_RDWR);
-    if (fd >= 0) {
-        char buffer[20];
-        int bytes = snprintf(buffer, sizeof(buffer), "%d\n", value);
-        ssize_t amt = write(fd, buffer, (size_t)bytes);
-        close(fd);
-        return amt == -1 ? -errno : 0;
-    } else {
-        if (already_warned == 0) {
-            ALOGE("write_int failed to open %s\n", path);
-            already_warned = 1;
-        }
-        return -errno;
-    }
-}
-
-static int
-is_lit(struct light_state_t const* state)
-{
-    return state->color & 0x00ffffff;
-}
-
-static int
-rgb_to_brightness(struct light_state_t const* state)
-{
-    int color = state->color & 0x00ffffff;
-    return ((77*((color>>16)&0x00ff))
-            + (150*((color>>8)&0x00ff)) + (29*(color&0x00ff))) >> 8;
-}
-
-static int
-set_light_backlight(struct light_device_t* dev,
-        struct light_state_t const* state)
-{
-    int err = 0;
-    int brightness = rgb_to_brightness(state);
-    unsigned int lpEnabled =
-        state->brightnessMode == BRIGHTNESS_MODE_LOW_PERSISTENCE;
-    if(!dev) {
-        return -1;
-    }
-
-    pthread_mutex_lock(&g_lock);
-    // Toggle low persistence mode state
-    bool persistence_mode = ((g_last_backlight_mode != state->brightnessMode && lpEnabled) ||
-                            (!lpEnabled &&
-                            g_last_backlight_mode == BRIGHTNESS_MODE_LOW_PERSISTENCE));
-    bool cannot_handle_persistence = !g_has_persistence_node && persistence_mode;
-    if (g_has_persistence_node) {
-        if (persistence_mode) {
-            if ((err = write_int(PERSISTENCE_FILE, lpEnabled)) != 0) {
-                ALOGE("%s: Failed to write to %s: %s\n", __FUNCTION__,
-                       PERSISTENCE_FILE, strerror(errno));
-            }
-            if (lpEnabled != 0) {
-                brightness = DEFAULT_LOW_PERSISTENCE_MODE_BRIGHTNESS;
-            }
-        }
-        g_last_backlight_mode = state->brightnessMode;
-    }
-
-    if (!err) {
-        if (!access(LCD_FILE, F_OK)) {
-            err = write_int(LCD_FILE, brightness);
-        } else {
-            err = write_int(LCD_FILE2, brightness);
-        }
-    }
-
-    pthread_mutex_unlock(&g_lock);
-    return cannot_handle_persistence ? -ENOSYS : err;
-}
-
-static int
-set_speaker_light_locked(struct light_device_t* dev,
-        struct light_state_t const* state)
-{
-    int red, green, blue;
-    int blink;
-    int onMS, offMS;
-    unsigned int colorRGB;
-
-    if(!dev) {
-        return -1;
-    }
-
-    switch (state->flashMode) {
-        case LIGHT_FLASH_TIMED:
-            onMS = state->flashOnMS;
-            offMS = state->flashOffMS;
-            break;
-        case LIGHT_FLASH_NONE:
-        default:
-            onMS = 0;
-            offMS = 0;
-            break;
-    }
-
-    colorRGB = state->color;
-
-#if 0
-    ALOGD("set_speaker_light_locked mode %d, colorRGB=%08X, onMS=%d, offMS=%d\n",
-            state->flashMode, colorRGB, onMS, offMS);
-#endif
-
-    red = (colorRGB >> 16) & 0xFF;
-    green = (colorRGB >> 8) & 0xFF;
-    blue = colorRGB & 0xFF;
-
-    if (onMS > 0 && offMS > 0) {
-        /*
-         * if ON time == OFF time
-         *   use blink mode 2
-         * else
-         *   use blink mode 1
-         */
-        if (onMS == offMS)
-            blink = 2;
-        else
-            blink = 1;
-    } else {
-        blink = 0;
-    }
-
-    if (blink) {
-        if (red) {
-            if (write_int(RED_BLINK_FILE, blink))
-                write_int(RED_LED_FILE, 0);
-        }
-        if (green) {
-            if (write_int(GREEN_BLINK_FILE, blink))
-                write_int(GREEN_LED_FILE, 0);
-        }
-        if (blue) {
-            if (write_int(BLUE_BLINK_FILE, blink))
-                write_int(BLUE_LED_FILE, 0);
-        }
-    } else {
-        write_int(RED_LED_FILE, red);
-        write_int(GREEN_LED_FILE, green);
-        write_int(BLUE_LED_FILE, blue);
-    }
-
-    return 0;
-}
-
-static void
-handle_speaker_battery_locked(struct light_device_t* dev)
-{
-    if (is_lit(&g_battery)) {
-        set_speaker_light_locked(dev, &g_battery);
-    } else {
-        set_speaker_light_locked(dev, &g_notification);
-    }
-}
-
-static int
-set_light_battery(struct light_device_t* dev,
-        struct light_state_t const* state)
-{
-    pthread_mutex_lock(&g_lock);
-    g_battery = *state;
-    handle_speaker_battery_locked(dev);
-    pthread_mutex_unlock(&g_lock);
-    return 0;
-}
-
-static int
-set_light_notifications(struct light_device_t* dev,
-        struct light_state_t const* state)
-{
-    pthread_mutex_lock(&g_lock);
-    g_notification = *state;
-    handle_speaker_battery_locked(dev);
-    pthread_mutex_unlock(&g_lock);
-    return 0;
-}
-
-static int
-set_light_attention(struct light_device_t* dev,
-        struct light_state_t const* state)
-{
-    pthread_mutex_lock(&g_lock);
-    if (state->flashMode == LIGHT_FLASH_HARDWARE) {
-        g_attention = state->flashOnMS;
-    } else if (state->flashMode == LIGHT_FLASH_NONE) {
-        g_attention = 0;
-    }
-    handle_speaker_battery_locked(dev);
-    pthread_mutex_unlock(&g_lock);
-    return 0;
-}
-
-static int
-set_light_buttons(struct light_device_t* dev,
-        struct light_state_t const* state)
-{
-    int err = 0;
-    if(!dev) {
-        return -1;
-    }
-    pthread_mutex_lock(&g_lock);
-    err = write_int(BUTTON_FILE, state->color & 0xFF);
-    pthread_mutex_unlock(&g_lock);
-    return err;
-}
-
-/** Close the lights device */
-static int
-close_lights(struct light_device_t *dev)
-{
-    if (dev) {
-        free(dev);
-    }
-    return 0;
-}
-
-
-/******************************************************************************/
-
-/**
- * module methods
- */
-
-/** Open a new instance of a lights device using name */
-static int open_lights(const struct hw_module_t* module, char const* name,
-        struct hw_device_t** device)
-{
-    int (*set_light)(struct light_device_t* dev,
-            struct light_state_t const* state);
-
-    if (0 == strcmp(LIGHT_ID_BACKLIGHT, name)) {
-        g_has_persistence_node = !access(PERSISTENCE_FILE, F_OK);
-        set_light = set_light_backlight;
-    } else if (0 == strcmp(LIGHT_ID_BATTERY, name))
-        set_light = set_light_battery;
-    else if (0 == strcmp(LIGHT_ID_NOTIFICATIONS, name))
-        set_light = set_light_notifications;
-    else if (0 == strcmp(LIGHT_ID_BUTTONS, name)) {
-        if (!access(BUTTON_FILE, F_OK)) {
-          // enable light button when the file is present
-          set_light = set_light_buttons;
-        } else {
-          return -EINVAL;
-        }
-    }
-    else if (0 == strcmp(LIGHT_ID_ATTENTION, name))
-        set_light = set_light_attention;
-    else
-        return -EINVAL;
-
-    pthread_once(&g_init, init_globals);
-
-    struct light_device_t *dev = malloc(sizeof(struct light_device_t));
-
-    if(!dev)
-        return -ENOMEM;
-
-    memset(dev, 0, sizeof(*dev));
-
-    dev->common.tag = HARDWARE_DEVICE_TAG;
-    dev->common.version = LIGHTS_DEVICE_API_VERSION_2_0;
-    dev->common.module = (struct hw_module_t*)module;
-    dev->common.close = (int (*)(struct hw_device_t*))close_lights;
-    dev->set_light = set_light;
-
-    *device = (struct hw_device_t*)dev;
-    return 0;
-}
-
-static struct hw_module_methods_t lights_module_methods = {
-    .open =  open_lights,
-};
-
-/*
- * The lights Module
- */
-struct hw_module_t HAL_MODULE_INFO_SYM = {
-    .tag = HARDWARE_MODULE_TAG,
-    .version_major = 1,
-    .version_minor = 0,
-    .id = LIGHTS_HARDWARE_MODULE_ID,
-    .name = "lights Module",
-    .author = "Google, Inc.",
-    .methods = &lights_module_methods,
-};
diff --git a/libmemtrack/Android.mk b/libmemtrack/Android.mk
deleted file mode 100644
index 10fd40a..0000000
--- a/libmemtrack/Android.mk
+++ /dev/null
@@ -1,30 +0,0 @@
-# Copyright (C) 2013 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.
-
-LOCAL_PATH := $(call my-dir)
-
-# HAL module implemenation stored in
-# hw/<POWERS_HARDWARE_MODULE_ID>.<ro.hardware>.so
-include $(CLEAR_VARS)
-
-LOCAL_MODULE_RELATIVE_PATH := hw
-LOCAL_VENDOR_MODULE := true
-LOCAL_C_INCLUDES += hardware/libhardware/include
-LOCAL_CFLAGS := -Wconversion -Wall -Werror -Wno-sign-conversion
-LOCAL_CLANG  := true
-LOCAL_SHARED_LIBRARIES := liblog
-LOCAL_HEADER_LIBRARIES := libhardware_headers
-LOCAL_SRC_FILES := memtrack_msm.c kgsl.c
-LOCAL_MODULE := memtrack.$(TARGET_BOARD_PLATFORM)
-include $(BUILD_SHARED_LIBRARY)
diff --git a/libmemtrack/kgsl.c b/libmemtrack/kgsl.c
deleted file mode 100644
index 69ee901..0000000
--- a/libmemtrack/kgsl.c
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- * Copyright (C) 2013 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 <errno.h>
-#include <stdbool.h>
-#include <stdio.h>
-#include <string.h>
-#include <sys/mman.h>
-
-#include <hardware/memtrack.h>
-
-#include "memtrack_msm.h"
-
-#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))
-#define min(x, y) ((x) < (y) ? (x) : (y))
-
-struct memtrack_record record_templates[] = {
-    {
-        .flags = MEMTRACK_FLAG_SMAPS_ACCOUNTED |
-                 MEMTRACK_FLAG_PRIVATE |
-                 MEMTRACK_FLAG_NONSECURE,
-    },
-    {
-        .flags = MEMTRACK_FLAG_SMAPS_UNACCOUNTED |
-                 MEMTRACK_FLAG_PRIVATE |
-                 MEMTRACK_FLAG_NONSECURE,
-    },
-};
-
-int kgsl_memtrack_get_memory(pid_t pid, enum memtrack_type type,
-                             struct memtrack_record *records,
-                             size_t *num_records)
-{
-    size_t allocated_records = min(*num_records, ARRAY_SIZE(record_templates));
-    FILE *fp;
-    char line[1024];
-    char tmp[128];
-    size_t accounted_size = 0;
-    size_t unaccounted_size = 0;
-
-    *num_records = ARRAY_SIZE(record_templates);
-
-    /* fastpath to return the necessary number of records */
-    if (allocated_records == 0) {
-        return 0;
-    }
-
-    memcpy(records, record_templates,
-           sizeof(struct memtrack_record) * allocated_records);
-
-    snprintf(tmp, sizeof(tmp), "/d/kgsl/proc/%d/mem", pid);
-    fp = fopen(tmp, "r");
-    if (fp == NULL) {
-        return -errno;
-    }
-
-    /* Go through each line of <pid>/mem file and for every entry of type "gpumem"
-     * check if the gpubuffer entry is usermapped or not. If the entry is usermapped
-     * count the entry as accounted else count the entry as unaccounted.
-     */
-    while (1) {
-        unsigned long size, mapsize;
-        char line_type[7];
-        char flags[10];
-        char line_usage[19];
-        int ret, egl_surface_count = 0, egl_image_count = 0;
-
-        if (fgets(line, sizeof(line), fp) == NULL) {
-            break;
-        }
-
-        /* Format:
-         *  gpuaddr useraddr     size    id flags       type            usage sglen mapsize eglsrf eglimg
-         * 545ba000 545ba000     4096     1 -----pY     gpumem      arraybuffer     1  4096      0      0
-         */
-        ret = sscanf(line, "%*x %*x %lu %*d %9s %6s %18s %*d %lu %6d %6d\n",
-                       &size, flags, line_type, line_usage, &mapsize,
-                       &egl_surface_count, &egl_image_count);
-        if (ret != 7) {
-            continue;
-        }
-
-        if (size == 0) {
-            fclose(fp);
-            return -EINVAL;
-        }
-
-        if (unaccounted_size + size < size) {
-            fclose(fp);
-            return -ERANGE;
-        }
-
-        if (type == MEMTRACK_TYPE_GL && strcmp(line_type, "gpumem") == 0) {
-
-            if (flags[6] == 'Y') {
-                if (accounted_size + mapsize < accounted_size) {
-                    fclose(fp);
-                    return -ERANGE;
-                }
-
-                accounted_size += mapsize;
-
-                if (mapsize > size) {
-                    fclose(fp);
-                    return -EINVAL;
-                }
-                unaccounted_size += size - mapsize;
-            } else {
-                unaccounted_size += size;
-            }
-        } else if (type == MEMTRACK_TYPE_GRAPHICS && strcmp(line_type, "ion") == 0) {
-            if (strcmp(line_usage, "egl_surface") == 0) {
-                unaccounted_size += size;
-            }
-            else if (egl_surface_count == 0) {
-                unaccounted_size += size / (egl_image_count ? egl_image_count : 1);
-            }
-        }
-    }
-
-    if (allocated_records > 0) {
-        records[0].size_in_bytes = accounted_size;
-    }
-    if (allocated_records > 1) {
-        records[1].size_in_bytes = unaccounted_size;
-    }
-
-    fclose(fp);
-
-    return 0;
-}
diff --git a/libmemtrack/memtrack_msm.c b/libmemtrack/memtrack_msm.c
deleted file mode 100644
index e369d5f..0000000
--- a/libmemtrack/memtrack_msm.c
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright (C) 2013 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 <errno.h>
-
-#include <hardware/memtrack.h>
-
-#include "memtrack_msm.h"
-
-int msm_memtrack_init(const struct memtrack_module *module)
-{
-    if(!module)
-        return -1;
-    return 0;
-}
-
-int msm_memtrack_get_memory(const struct memtrack_module *module,
-                                pid_t pid,
-                                int type,
-                                struct memtrack_record *records,
-                                size_t *num_records)
-{
-    if(!module)
-        return -1;
-    if (type == MEMTRACK_TYPE_GL || type == MEMTRACK_TYPE_GRAPHICS) {
-        return kgsl_memtrack_get_memory(pid, type, records, num_records);
-    }
-
-    return -EINVAL;
-}
-
-static struct hw_module_methods_t memtrack_module_methods = {
-    .open = NULL,
-};
-
-struct memtrack_module HAL_MODULE_INFO_SYM = {
-    .common = {
-        .tag = HARDWARE_MODULE_TAG,
-        .module_api_version = MEMTRACK_MODULE_API_VERSION_0_1,
-        .hal_api_version = HARDWARE_HAL_API_VERSION,
-        .id = MEMTRACK_HARDWARE_MODULE_ID,
-        .name = "MSM Memory Tracker HAL",
-        .author = "The Android Open Source Project",
-        .methods = &memtrack_module_methods,
-    },
-
-    .init = msm_memtrack_init,
-    .getMemory = msm_memtrack_get_memory,
-};
-
diff --git a/libmemtrack/memtrack_msm.h b/libmemtrack/memtrack_msm.h
deleted file mode 100644
index 74aa576..0000000
--- a/libmemtrack/memtrack_msm.h
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Copyright (C) 2013 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 _MEMTRACK_MSM_H_
-#define _MEMTRACK_MSM_H_
-
-int kgsl_memtrack_get_memory(pid_t pid, enum memtrack_type type,
-                             struct memtrack_record *records,
-                             size_t *num_records);
-
-#endif
diff --git a/libqdmetadata/Android.bp b/libqdmetadata/Android.bp
new file mode 100644
index 0000000..fdf577f
--- /dev/null
+++ b/libqdmetadata/Android.bp
@@ -0,0 +1,34 @@
+cc_library_shared {
+    name: "libqdMetaData",
+    vendor_available: true,
+    cflags: [
+        "-Wno-sign-conversion",
+        "-DLOG_TAG=\"qdmetadata\"",
+    ],
+    shared_libs: [
+        "liblog",
+        "libcutils",
+        "libutils",
+    ],
+    header_libs: ["libhardware_headers", "display_intf_headers"],
+    srcs: ["qdMetaData.cpp", "qd_utils.cpp"],
+    export_header_lib_headers: ["display_intf_headers"],
+}
+
+// Remove after WFD moves to use libqdMetaData directly
+cc_library_shared {
+    name: "libqdMetaData.system",
+    vendor_available: true,
+    cflags: [
+        "-Wno-sign-conversion",
+        "-DLOG_TAG=\"qdmetadata\"",
+    ],
+    shared_libs: [
+        "liblog",
+        "libcutils",
+        "libutils",
+    ],
+    header_libs: ["libhardware_headers", "display_intf_headers"],
+    srcs: ["qdMetaData.cpp", "qd_utils.cpp"],
+    export_header_lib_headers: ["display_intf_headers"],
+}
diff --git a/libqdutils/Makefile.am b/libqdmetadata/Makefile.am
similarity index 100%
rename from libqdutils/Makefile.am
rename to libqdmetadata/Makefile.am
diff --git a/libqdutils/qdMetaData.cpp b/libqdmetadata/qdMetaData.cpp
similarity index 100%
rename from libqdutils/qdMetaData.cpp
rename to libqdmetadata/qdMetaData.cpp
diff --git a/libqdutils/qdMetaData.h b/libqdmetadata/qdMetaData.h
similarity index 100%
rename from libqdutils/qdMetaData.h
rename to libqdmetadata/qdMetaData.h
diff --git a/libqdmetadata/qd_utils.cpp b/libqdmetadata/qd_utils.cpp
new file mode 100644
index 0000000..108514b
--- /dev/null
+++ b/libqdmetadata/qd_utils.cpp
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2013, 2018 The Linux Foundation. All rights reserved.
+
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ *       copyright notice, this list of conditions and the following
+ *       disclaimer in the documentation and/or other materials provided
+ *       with the distribution.
+ *     * Neither the name of The Linux Foundation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <unistd.h>
+#include <gralloc_priv.h>
+#include "qd_utils.h"
+
+static const int kFBNodeMax = 4;
+namespace qdutils {
+
+static int getExternalNode(const char *type) {
+    FILE *displayDeviceFP = NULL;
+    char fbType[MAX_FRAME_BUFFER_NAME_SIZE];
+    char msmFbTypePath[MAX_FRAME_BUFFER_NAME_SIZE];
+    int j = 0;
+
+    for(j = 0; j < kFBNodeMax; j++) {
+        snprintf (msmFbTypePath, sizeof(msmFbTypePath),
+                  "/sys/devices/virtual/graphics/fb%d/msm_fb_type", j);
+        displayDeviceFP = fopen(msmFbTypePath, "r");
+        if(displayDeviceFP) {
+            fread(fbType, sizeof(char), MAX_FRAME_BUFFER_NAME_SIZE,
+                    displayDeviceFP);
+            if(strncmp(fbType, type, strlen(type)) == 0) {
+                ALOGD("%s: %s is at fb%d", __func__, type, j);
+                fclose(displayDeviceFP);
+                break;
+            }
+            fclose(displayDeviceFP);
+        } else {
+            ALOGE("%s: Failed to open fb node %s", __func__, msmFbTypePath);
+        }
+    }
+
+    if (j < kFBNodeMax)
+        return j;
+    else
+        ALOGE("%s: Failed to find %s node", __func__, type);
+
+    return -1;
+}
+
+int getHDMINode(void) {
+    return getExternalNode("dtv panel");
+}
+
+int getEdidRawData(char *buffer)
+{
+    int size;
+    int edidFile;
+    char msmFbTypePath[MAX_FRAME_BUFFER_NAME_SIZE];
+    int node_id = getHDMINode();
+
+    if (node_id < 0) {
+        ALOGE("%s no HDMI node found", __func__);
+        return 0;
+    }
+
+    snprintf(msmFbTypePath, sizeof(msmFbTypePath),
+                 "/sys/devices/virtual/graphics/fb%d/edid_raw_data", node_id);
+
+    edidFile = open(msmFbTypePath, O_RDONLY, 0);
+
+    if (edidFile < 0) {
+        ALOGE("%s no edid raw data found %s", __func__,msmFbTypePath);
+        return 0;
+    }
+
+    size = (int)read(edidFile, (char*)buffer, EDID_RAW_DATA_SIZE);
+    close(edidFile);
+    return size;
+}
+
+}; //namespace qdutils
diff --git a/libqdutils/qd_utils.h b/libqdmetadata/qd_utils.h
similarity index 100%
rename from libqdutils/qd_utils.h
rename to libqdmetadata/qd_utils.h
diff --git a/libqdutils/Android.bp b/libqdutils/Android.bp
deleted file mode 100644
index 0c1b96a..0000000
--- a/libqdutils/Android.bp
+++ /dev/null
@@ -1,40 +0,0 @@
-cc_library_shared {
-    name: "libqdutils",
-    vendor: true,
-    defaults: ["display_defaults"],
-    header_libs: ["libhardware_headers", "libutils_headers"],
-    shared_libs: [
-        "libbinder",
-        "libqservice",
-    ],
-    cflags: [
-        "-DLOG_TAG=\"qdutils\"",
-        "-Wno-sign-conversion",
-    ],
-    srcs: [
-        "qd_utils.cpp",
-        "display_config.cpp",
-    ],
-}
-
-cc_library_shared {
-    name: "libqdMetaData",
-    vendor: true,
-    defaults: ["display_defaults"],
-    cflags: [
-        "-Wno-sign-conversion",
-        "-DLOG_TAG=\"qdmetadata\"",
-    ],
-    srcs: ["qdMetaData.cpp","qd_utils.cpp"],
-}
-
-// Remove after WFD moves to use libqdMetaData directly
-cc_library_shared {
-    name: "libqdMetaData.system",
-    defaults: ["display_defaults"],
-    cflags: [
-        "-Wno-sign-conversion",
-        "-DLOG_TAG=\"qdmetadata\"",
-    ],
-    srcs: ["qdMetaData.cpp","qd_utils.cpp"],
-}
diff --git a/libqdutils/display_config.cpp b/libqdutils/display_config.cpp
deleted file mode 100644
index 87ca401..0000000
--- a/libqdutils/display_config.cpp
+++ /dev/null
@@ -1,390 +0,0 @@
-/*
-* Copyright (c) 2013-2014, 2016, The Linux Foundation. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without
-* modification, are permitted provided that the following conditions are
-* met:
-*    * Redistributions of source code must retain the above copyright
-*      notice, this list of conditions and the following disclaimer.
-*    * Redistributions in binary form must reproduce the above
-*      copyright notice, this list of conditions and the following
-*      disclaimer in the documentation and/or other materials provided
-*      with the distribution.
-*    * Neither the name of The Linux Foundation. nor the names of its
-*      contributors may be used to endorse or promote products derived
-*      from this software without specific prior written permission.
-*
-* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
-* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
-* ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
-* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
-* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#include <fcntl.h>
-#include <stdio.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <display_config.h>
-#include <QServiceUtils.h>
-#include <qd_utils.h>
-
-using namespace android;
-using namespace qService;
-
-namespace qdutils {
-
-//=============================================================================
-// The functions below run in the client process and wherever necessary
-// do a binder call to HWC to get/set data.
-
-int isExternalConnected(void) {
-    int ret;
-    status_t err = (status_t) FAILED_TRANSACTION;
-    sp<IQService> binder = getBinder();
-    Parcel inParcel, outParcel;
-    if(binder != NULL) {
-        err = binder->dispatch(IQService::CHECK_EXTERNAL_STATUS,
-                &inParcel , &outParcel);
-    }
-    if(err) {
-        ALOGE("%s: Failed to get external status err=%d", __FUNCTION__, err);
-        ret = err;
-    } else {
-        ret = outParcel.readInt32();
-    }
-    return ret;
-}
-
-int getDisplayAttributes(int dpy, DisplayAttributes_t& dpyattr) {
-    status_t err = (status_t) FAILED_TRANSACTION;
-    sp<IQService> binder = getBinder();
-    Parcel inParcel, outParcel;
-    inParcel.writeInt32(dpy);
-    if(binder != NULL) {
-        err = binder->dispatch(IQService::GET_DISPLAY_ATTRIBUTES,
-                &inParcel, &outParcel);
-    }
-    if(!err) {
-        dpyattr.vsync_period = outParcel.readInt32();
-        dpyattr.xres = outParcel.readInt32();
-        dpyattr.yres = outParcel.readInt32();
-        dpyattr.xdpi = outParcel.readFloat();
-        dpyattr.ydpi = outParcel.readFloat();
-        dpyattr.panel_type = outParcel.readInt32();
-    } else {
-        ALOGE("%s() failed with err %d", __FUNCTION__, err);
-    }
-    return err;
-}
-
-int setHSIC(int dpy, const HSICData_t& hsic_data) {
-    status_t err = (status_t) FAILED_TRANSACTION;
-    sp<IQService> binder = getBinder();
-    Parcel inParcel, outParcel;
-    inParcel.writeInt32(dpy);
-    inParcel.writeInt32(hsic_data.hue);
-    inParcel.writeFloat(hsic_data.saturation);
-    inParcel.writeInt32(hsic_data.intensity);
-    inParcel.writeFloat(hsic_data.contrast);
-    if(binder != NULL) {
-        err = binder->dispatch(IQService::SET_HSIC_DATA, &inParcel, &outParcel);
-    }
-    if(err)
-        ALOGE("%s: Failed to get external status err=%d", __FUNCTION__, err);
-    return err;
-}
-
-int getDisplayVisibleRegion(int dpy, hwc_rect_t &rect) {
-    status_t err = (status_t) FAILED_TRANSACTION;
-    sp<IQService> binder = getBinder();
-    Parcel inParcel, outParcel;
-    inParcel.writeInt32(dpy);
-    if(binder != NULL) {
-        err = binder->dispatch(IQService::GET_DISPLAY_VISIBLE_REGION,
-                &inParcel, &outParcel);
-    }
-    if(!err) {
-        rect.left = outParcel.readInt32();
-        rect.top = outParcel.readInt32();
-        rect.right = outParcel.readInt32();
-        rect.bottom = outParcel.readInt32();
-    } else {
-        ALOGE("%s: Failed to getVisibleRegion for dpy =%d: err = %d",
-              __FUNCTION__, dpy, err);
-    }
-    return err;
-}
-
-int setViewFrame(int dpy, int l, int t, int r, int b) {
-    status_t err = (status_t) FAILED_TRANSACTION;
-    sp<IQService> binder = getBinder();
-    Parcel inParcel, outParcel;
-    inParcel.writeInt32(dpy);
-    inParcel.writeInt32(l);
-    inParcel.writeInt32(t);
-    inParcel.writeInt32(r);
-    inParcel.writeInt32(b);
-
-    if(binder != NULL) {
-        err = binder->dispatch(IQService::SET_VIEW_FRAME,
-                &inParcel, &outParcel);
-    }
-    if(err)
-        ALOGE("%s: Failed to set view frame for dpy %d err=%d",
-                            __FUNCTION__, dpy, err);
-
-    return err;
-}
-
-int setSecondaryDisplayStatus(int dpy, uint32_t status) {
-    status_t err = (status_t) FAILED_TRANSACTION;
-    sp<IQService> binder = getBinder();
-    Parcel inParcel, outParcel;
-    inParcel.writeInt32(dpy);
-    inParcel.writeInt32(status);
-
-    if(binder != NULL) {
-        err = binder->dispatch(IQService::SET_SECONDARY_DISPLAY_STATUS,
-                &inParcel, &outParcel);
-    }
-    if(err)
-        ALOGE("%s: Failed for dpy %d status = %d err=%d", __FUNCTION__, dpy,
-                                                        status, err);
-
-    return err;
-}
-
-int configureDynRefreshRate(uint32_t op, uint32_t refreshRate) {
-    status_t err = (status_t) FAILED_TRANSACTION;
-    sp<IQService> binder = getBinder();
-    Parcel inParcel, outParcel;
-    inParcel.writeInt32(op);
-    inParcel.writeInt32(refreshRate);
-
-    if(binder != NULL) {
-        err = binder->dispatch(IQService::CONFIGURE_DYN_REFRESH_RATE,
-                               &inParcel, &outParcel);
-    }
-
-    if(err)
-        ALOGE("%s: Failed setting op %d err=%d", __FUNCTION__, op, err);
-
-    return err;
-}
-
-int getConfigCount(int /*dpy*/) {
-    int numConfigs = -1;
-    sp<IQService> binder = getBinder();
-    if(binder != NULL) {
-        Parcel inParcel, outParcel;
-        inParcel.writeInt32(DISPLAY_PRIMARY);
-        status_t err = binder->dispatch(IQService::GET_CONFIG_COUNT,
-                &inParcel, &outParcel);
-        if(!err) {
-            numConfigs = outParcel.readInt32();
-            ALOGI("%s() Received num configs %d", __FUNCTION__, numConfigs);
-        } else {
-            ALOGE("%s() failed with err %d", __FUNCTION__, err);
-        }
-    }
-    return numConfigs;
-}
-
-int getActiveConfig(int dpy) {
-    int configIndex = -1;
-    sp<IQService> binder = getBinder();
-    if(binder != NULL) {
-        Parcel inParcel, outParcel;
-        inParcel.writeInt32(dpy);
-        status_t err = binder->dispatch(IQService::GET_ACTIVE_CONFIG,
-                &inParcel, &outParcel);
-        if(!err) {
-            configIndex = outParcel.readInt32();
-            ALOGI("%s() Received active config index %d", __FUNCTION__,
-                    configIndex);
-        } else {
-            ALOGE("%s() failed with err %d", __FUNCTION__, err);
-        }
-    }
-    return configIndex;
-}
-
-int setActiveConfig(int configIndex, int /*dpy*/) {
-    status_t err = (status_t) FAILED_TRANSACTION;
-    sp<IQService> binder = getBinder();
-    if(binder != NULL) {
-        Parcel inParcel, outParcel;
-        inParcel.writeInt32(configIndex);
-        inParcel.writeInt32(DISPLAY_PRIMARY);
-        err = binder->dispatch(IQService::SET_ACTIVE_CONFIG,
-                &inParcel, &outParcel);
-        if(!err) {
-            ALOGI("%s() Successfully set active config index %d", __FUNCTION__,
-                    configIndex);
-        } else {
-            ALOGE("%s() failed with err %d", __FUNCTION__, err);
-        }
-    }
-    return err;
-}
-
-DisplayAttributes getDisplayAttributes(int configIndex, int dpy) {
-    DisplayAttributes dpyattr = {};
-    sp<IQService> binder = getBinder();
-    if(binder != NULL) {
-        Parcel inParcel, outParcel;
-        inParcel.writeInt32(configIndex);
-        inParcel.writeInt32(dpy);
-        status_t err = binder->dispatch(
-                IQService::GET_DISPLAY_ATTRIBUTES_FOR_CONFIG, &inParcel,
-                &outParcel);
-        if(!err) {
-            dpyattr.vsync_period = outParcel.readInt32();
-            dpyattr.xres = outParcel.readInt32();
-            dpyattr.yres = outParcel.readInt32();
-            dpyattr.xdpi = outParcel.readFloat();
-            dpyattr.ydpi = outParcel.readFloat();
-            dpyattr.panel_type = outParcel.readInt32();
-            dpyattr.is_yuv = outParcel.readInt32();
-            ALOGI("%s() Received attrs for index %d: xres %d, yres %d",
-                    __FUNCTION__, configIndex, dpyattr.xres, dpyattr.yres);
-        } else {
-            ALOGE("%s() failed with err %d", __FUNCTION__, err);
-        }
-    }
-    return dpyattr;
-}
-
-int setPanelMode(int mode) {
-    status_t err = (status_t) FAILED_TRANSACTION;
-    sp<IQService> binder = getBinder();
-    if(binder != NULL) {
-        Parcel inParcel, outParcel;
-        inParcel.writeInt32(mode);
-        err = binder->dispatch(IQService::SET_DISPLAY_MODE,
-                               &inParcel, &outParcel);
-        if(!err) {
-            ALOGI("%s() Successfully set the display mode to %d", __FUNCTION__,
-                  mode);
-        } else {
-            ALOGE("%s() failed with err %d", __FUNCTION__, err);
-        }
-    }
-    return err;
-}
-
-int setPanelBrightness(int level) {
-    status_t err = (status_t) FAILED_TRANSACTION;
-    sp<IQService> binder = getBinder();
-    Parcel inParcel, outParcel;
-
-    if(binder != NULL) {
-        inParcel.writeInt32(level);
-        status_t err = binder->dispatch(IQService::SET_PANEL_BRIGHTNESS,
-                &inParcel, &outParcel);
-        if(err) {
-            ALOGE("%s() failed with err %d", __FUNCTION__, err);
-        }
-    }
-    return err;
-}
-
-int getPanelBrightness() {
-    int panel_brightness = -1;
-    sp<IQService> binder = getBinder();
-    Parcel inParcel, outParcel;
-
-    if(binder != NULL) {
-        status_t err = binder->dispatch(IQService::GET_PANEL_BRIGHTNESS,
-                &inParcel, &outParcel);
-        if(!err) {
-            panel_brightness = outParcel.readInt32();
-            ALOGI("%s() Current panel brightness value %d", __FUNCTION__,
-                    panel_brightness);
-        } else {
-            ALOGE("%s() failed with err %d", __FUNCTION__, err);
-        }
-    }
-    return panel_brightness;
-}
-
-}// namespace
-
-// ----------------------------------------------------------------------------
-// Functions for linking dynamically to libqdutils
-// ----------------------------------------------------------------------------
-extern "C" int minHdcpEncryptionLevelChanged(int dpy, int min_enc_level) {
-    status_t err = (status_t) FAILED_TRANSACTION;
-    sp<IQService> binder = getBinder();
-    Parcel inParcel, outParcel;
-    inParcel.writeInt32(dpy);
-    inParcel.writeInt32(min_enc_level);
-
-    if(binder != NULL) {
-        err = binder->dispatch(IQService::MIN_HDCP_ENCRYPTION_LEVEL_CHANGED,
-                &inParcel, &outParcel);
-    }
-
-    if(err) {
-        ALOGE("%s: Failed for dpy %d err=%d", __FUNCTION__, dpy, err);
-    } else {
-        err = outParcel.readInt32();
-    }
-
-    return err;
-}
-
-extern "C" int refreshScreen() {
-    int ret = 0;
-    ret = screenRefresh();
-    return ret;
-}
-
-extern "C" int controlPartialUpdate(int dpy, int mode) {
-    status_t err = (status_t) FAILED_TRANSACTION;
-    sp<IQService> binder = getBinder();
-    if(binder != NULL) {
-        Parcel inParcel, outParcel;
-        inParcel.writeInt32(dpy);
-        inParcel.writeInt32(mode);
-        err = binder->dispatch(IQService::CONTROL_PARTIAL_UPDATE, &inParcel, &outParcel);
-        if(err != 0) {
-            ALOGE_IF(getBinder(), "%s() failed with err %d", __FUNCTION__, err);
-        } else {
-            return outParcel.readInt32();
-        }
-    }
-
-    return err;
-}
-
-// returns 0 if composer is up
-extern "C" int waitForComposerInit() {
-    int status = false;
-    sp<IQService> binder = getBinder();
-    if (binder == NULL) {
-        sleep(2);
-        binder = getBinder();
-    }
-
-    if (binder != NULL) {
-        Parcel inParcel, outParcel;
-        binder->dispatch(IQService::GET_COMPOSER_STATUS, &inParcel, &outParcel);
-        status = !!outParcel.readInt32();
-        if (!status) {
-            sleep(2);
-            binder->dispatch(IQService::GET_COMPOSER_STATUS, &inParcel, &outParcel);
-            status = !!outParcel.readInt32();
-        }
-    }
-
-    return !status;
-}
diff --git a/libqdutils/display_config.h b/libqdutils/display_config.h
deleted file mode 100644
index c692699..0000000
--- a/libqdutils/display_config.h
+++ /dev/null
@@ -1,165 +0,0 @@
-/*
- * Copyright (c) 2013 - 2016 The Linux Foundation. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *    * Redistributions of source code must retain the above copyright
- *      notice, this list of conditions and the following disclaimer.
- *    * Redistributions in binary form must reproduce the above
- *      copyright notice, this list of conditions and the following
- *      disclaimer in the documentation and/or other materials provided
- *      with the distribution.
- *    * Neither the name of The Linux Foundation. nor the names of its
- *      contributors may be used to endorse or promote products derived
- *      from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef _DISPLAY_CONFIG_H
-#define _DISPLAY_CONFIG_H
-
-#include <gralloc_priv.h>
-#include <qdMetaData.h>
-#include <hardware/hwcomposer.h>
-
-// This header is for clients to use to set/get global display configuration.
-// Only primary and external displays are supported here.
-
-namespace qdutils {
-
-
-/* TODO: Have all the common enums that need be exposed to clients and which
- * are also needed in hwc defined here. Remove such definitions we have in
- * hwc_utils.h
- */
-
-// Use this enum to specify the dpy parameters where needed
-enum {
-    DISPLAY_PRIMARY = HWC_DISPLAY_PRIMARY,
-    DISPLAY_EXTERNAL = HWC_DISPLAY_EXTERNAL,
-#ifdef QTI_BSP
-    DISPLAY_TERTIARY = HWC_DISPLAY_TERTIARY,
-#endif
-    DISPLAY_VIRTUAL = HWC_DISPLAY_VIRTUAL,
-};
-
-// External Display states - used in setSecondaryDisplayStatus()
-// To be consistent with the same defined in hwc_utils.h
-enum {
-    EXTERNAL_OFFLINE = 0,
-    EXTERNAL_ONLINE,
-    EXTERNAL_PAUSE,
-    EXTERNAL_RESUME,
-};
-
-enum {
-    DISABLE_METADATA_DYN_REFRESH_RATE = 0,
-    ENABLE_METADATA_DYN_REFRESH_RATE,
-    SET_BINDER_DYN_REFRESH_RATE,
-};
-
-enum {
-    DEFAULT_MODE = 0,
-    VIDEO_MODE,
-    COMMAND_MODE,
-};
-
-enum {
-    DISPLAY_PORT_DEFAULT = 0,
-    DISPLAY_PORT_DSI,
-    DISPLAY_PORT_DTV,
-    DISPLAY_PORT_WRITEBACK,
-    DISPLAY_PORT_LVDS,
-    DISPLAY_PORT_EDP,
-    DISPLAY_PORT_DP,
-};
-
-// Display Attributes that are available to clients of this library
-// Not to be confused with a similar struct in hwc_utils (in the hwc namespace)
-typedef struct DisplayAttributes {
-    uint32_t vsync_period = 0; //nanoseconds
-    uint32_t xres = 0;
-    uint32_t yres = 0;
-    float xdpi = 0.0f;
-    float ydpi = 0.0f;
-    int panel_type = DISPLAY_PORT_DEFAULT;
-    bool is_yuv = false;
-} DisplayAttributes_t;
-
-//=============================================================================
-// The functions below run in the client process and wherever necessary
-// do a binder call to HWC to get/set data.
-
-// Check if external display is connected. Useful to check before making
-// calls for external displays
-// Returns 1 if connected, 0 if disconnected, negative values on errors
-int isExternalConnected(void);
-
-// Get display vsync period which is in nanoseconds
-// i.e vsync_period = 1000000000l / fps
-// Returns 0 on success, negative values on errors
-int getDisplayAttributes(int dpy, DisplayAttributes_t& dpyattr);
-
-// Set HSIC data on a given display ID
-// Returns 0 on success, negative values on errors
-int setHSIC(int dpy, const HSICData_t& hsic_data);
-
-// get the active visible region for the display
-// Returns 0 on success, negative values on errors
-int getDisplayVisibleRegion(int dpy, hwc_rect_t &rect);
-
-// set the view frame information in hwc context from surfaceflinger
-int setViewFrame(int dpy, int l, int t, int r, int b);
-
-// Set the secondary display status(pause/resume/offline etc.,)
-int setSecondaryDisplayStatus(int dpy, uint32_t status);
-
-// Enable/Disable/Set refresh rate dynamically
-int configureDynRefreshRate(uint32_t op, uint32_t refreshRate);
-
-// Returns the number of configs supported for the display on success.
-// Returns -1 on error.
-// Only primary display supported for now, value of dpy ignored.
-int getConfigCount(int dpy);
-
-// Returns the index of config that is current set for the display on success.
-// Returns -1 on error.
-// Only primary display supported for now, value of dpy ignored.
-int getActiveConfig(int dpy);
-
-// Sets the config for the display on success and returns 0.
-// Returns -1 on error.
-// Only primary display supported for now, value of dpy ignored
-int setActiveConfig(int configIndex, int dpy);
-
-// Returns the attributes for the specified config for the display on success.
-// Returns xres and yres as 0 on error.
-// Only primary display supported for now, value of dpy ignored
-DisplayAttributes getDisplayAttributes(int configIndex, int dpy);
-
-// Set the primary display mode to command or video mode
-int setDisplayMode(int mode);
-
-// Sets the panel brightness of the primary display
-int setPanelBrightness(int level);
-
-// Retrieves the current panel brightness value
-int getPanelBrightness();
-
-}; //namespace
-
-
-extern "C" int waitForComposerInit();
-#endif
diff --git a/libqdutils/qd_utils.cpp b/libqdutils/qd_utils.cpp
deleted file mode 100644
index e1afd7c..0000000
--- a/libqdutils/qd_utils.cpp
+++ /dev/null
@@ -1,365 +0,0 @@
-/*
- * Copyright (c) 2013, 2018 The Linux Foundation. All rights reserved.
-
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- *       copyright notice, this list of conditions and the following
- *       disclaimer in the documentation and/or other materials provided
- *       with the distribution.
- *     * Neither the name of The Linux Foundation nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <unistd.h>
-#include <gralloc_priv.h>
-#include "qd_utils.h"
-
-static const int kFBNodeMax = 4;
-namespace qdutils {
-
-static int parseLine(char *input, char *tokens[], const uint32_t maxToken, uint32_t *count) {
-    char *tmpToken = NULL;
-    char *tmpPtr;
-    uint32_t index = 0;
-    const char *delim = ", =\n";
-    if (!input) {
-      return -1;
-    }
-    tmpToken = strtok_r(input, delim, &tmpPtr);
-    while (tmpToken && index < maxToken) {
-      tokens[index++] = tmpToken;
-      tmpToken = strtok_r(NULL, delim, &tmpPtr);
-    }
-    *count = index;
-
-    return 0;
-}
-
-static int getExternalNode(const char *type) {
-    FILE *displayDeviceFP = NULL;
-    char fbType[MAX_FRAME_BUFFER_NAME_SIZE];
-    char msmFbTypePath[MAX_FRAME_BUFFER_NAME_SIZE];
-    int j = 0;
-
-    for(j = 0; j < kFBNodeMax; j++) {
-        snprintf (msmFbTypePath, sizeof(msmFbTypePath),
-                  "/sys/devices/virtual/graphics/fb%d/msm_fb_type", j);
-        displayDeviceFP = fopen(msmFbTypePath, "r");
-        if(displayDeviceFP) {
-            fread(fbType, sizeof(char), MAX_FRAME_BUFFER_NAME_SIZE,
-                    displayDeviceFP);
-            if(strncmp(fbType, type, strlen(type)) == 0) {
-                ALOGD("%s: %s is at fb%d", __func__, type, j);
-                fclose(displayDeviceFP);
-                break;
-            }
-            fclose(displayDeviceFP);
-        } else {
-            ALOGE("%s: Failed to open fb node %s", __func__, msmFbTypePath);
-        }
-    }
-
-    if (j < kFBNodeMax)
-        return j;
-    else
-        ALOGE("%s: Failed to find %s node", __func__, type);
-
-    return -1;
-}
-
-static int querySDEInfoDRM(HWQueryType type, int *value) {
-    char property[PROPERTY_VALUE_MAX] = {0};
-
-    // TODO(user): If future targets don't support WB UBWC, add separate
-    // properties in target specific system.prop and have clients like WFD
-    // directly rely on those.
-    switch(type) {
-    case HAS_UBWC:
-    case HAS_WB_UBWC:  // WFD stack still uses this
-        *value = 1;
-        property_get(DISABLE_UBWC_PROP, property, "0");
-        if(!(strncmp(property, "1", PROPERTY_VALUE_MAX)) ||
-                !(strncmp(property, "true", PROPERTY_VALUE_MAX))) {
-            *value = 0;
-        }
-        break;
-    default:
-        ALOGE("Invalid query type %d", type);
-        return -EINVAL;
-    }
-
-    return 0;
-}
-
-static int querySDEInfoFB(HWQueryType type, int *value) {
-    FILE *fileptr = NULL;
-    const char *featureName;
-    char stringBuffer[MAX_STRING_LENGTH];
-    uint32_t tokenCount = 0;
-    const uint32_t maxCount = 10;
-    char *tokens[maxCount] = { NULL };
-
-    switch(type) {
-    case HAS_UBWC:
-        featureName = "ubwc";
-        break;
-    case HAS_WB_UBWC:
-        featureName = "wb_ubwc";
-        break;
-    default:
-        ALOGE("Invalid query type %d", type);
-        return -EINVAL;
-    }
-
-    fileptr = fopen("/sys/devices/virtual/graphics/fb0/mdp/caps", "rb");
-    if (!fileptr) {
-        ALOGE("File '%s' not found", stringBuffer);
-        return -EINVAL;
-    }
-
-    size_t len = MAX_STRING_LENGTH;
-    ssize_t read;
-    char *line = stringBuffer;
-    while ((read = getline(&line, &len, fileptr)) != -1) {
-        // parse the line and update information accordingly
-        if (parseLine(line, tokens, maxCount, &tokenCount)) {
-            continue;
-        }
-
-        if (strncmp(tokens[0], "features", strlen("features"))) {
-            continue;
-        }
-
-        for (uint32_t i = 0; i < tokenCount; i++) {
-            if (!strncmp(tokens[i], featureName, strlen(featureName))) {
-              *value = 1;
-            }
-        }
-    }
-    fclose(fileptr);
-
-    return 0;
-}
-
-int querySDEInfo(HWQueryType type, int *value) {
-    if (!value) {
-        return -EINVAL;
-    }
-
-    if (getDriverType() ==  DriverType::DRM) {
-        return querySDEInfoDRM(type, value);
-    }
-
-    return querySDEInfoFB(type, value);
-}
-
-int getHDMINode(void) {
-    return getExternalNode("dtv panel");
-}
-
-int getEdidRawData(char *buffer)
-{
-    int size;
-    int edidFile;
-    char msmFbTypePath[MAX_FRAME_BUFFER_NAME_SIZE];
-    int node_id = getHDMINode();
-
-    if (node_id < 0) {
-        ALOGE("%s no HDMI node found", __func__);
-        return 0;
-    }
-
-    snprintf(msmFbTypePath, sizeof(msmFbTypePath),
-                 "/sys/devices/virtual/graphics/fb%d/edid_raw_data", node_id);
-
-    edidFile = open(msmFbTypePath, O_RDONLY, 0);
-
-    if (edidFile < 0) {
-        ALOGE("%s no edid raw data found %s", __func__,msmFbTypePath);
-        return 0;
-    }
-
-    size = (int)read(edidFile, (char*)buffer, EDID_RAW_DATA_SIZE);
-    close(edidFile);
-    return size;
-}
-
-bool isDPConnected() {
-    char connectPath[MAX_FRAME_BUFFER_NAME_SIZE];
-    FILE *connectFile = NULL;
-    size_t len = MAX_STRING_LENGTH;
-    char stringBuffer[MAX_STRING_LENGTH];
-    char *line = stringBuffer;
-
-    int nodeId = getExternalNode("dp panel");
-    if (nodeId < 0) {
-        ALOGE("%s no DP node found", __func__);
-        return false;
-    }
-
-    snprintf(connectPath, sizeof(connectPath),
-             "/sys/devices/virtual/graphics/fb%d/connected", nodeId);
-
-    connectFile = fopen(connectPath, "rb");
-    if (!connectFile) {
-        ALOGW("Failed to open connect node for device node %s", connectPath);
-        return false;
-    }
-
-    if (getline(&line, &len, connectFile) < 0) {
-        fclose(connectFile);
-        return false;
-    }
-
-    fclose(connectFile);
-
-    return atoi(line);
-}
-
-int getDPTestConfig(uint32_t *panelBpp, uint32_t *patternType) {
-    if (!panelBpp || !patternType) {
-        return -1;
-    }
-
-    char configPath[MAX_FRAME_BUFFER_NAME_SIZE];
-    FILE *configFile = NULL;
-    uint32_t tokenCount = 0;
-    const uint32_t maxCount = 10;
-    char *tokens[maxCount] = { NULL };
-    size_t len = MAX_STRING_LENGTH;
-    char stringBuffer[MAX_STRING_LENGTH];
-    char *line = stringBuffer;
-
-    int nodeId = getExternalNode("dp panel");
-    if (nodeId < 0) {
-        ALOGE("%s no DP node found", __func__);
-        return -EINVAL;
-    }
-
-    snprintf(configPath, sizeof(configPath),
-             "/sys/devices/virtual/graphics/fb%d/config", nodeId);
-
-    configFile = fopen(configPath, "rb");
-    if (!configFile) {
-        ALOGW("Failed to open config node for device node %s", configPath);
-        return -EINVAL;
-    }
-
-    while (getline(&line, &len, configFile) != -1) {
-        if (!parseLine(line, tokens, maxCount, &tokenCount)) {
-            if (tokens[0] != NULL) {
-              if (!strncmp(tokens[0], "bpp", strlen("bpp"))) {
-                *panelBpp = static_cast<uint32_t>(atoi(tokens[1]));
-              } else  if (!strncmp(tokens[0], "pattern", strlen("pattern"))) {
-                *patternType = static_cast<uint32_t>(atoi(tokens[1]));
-              }
-            }
-        }
-    }
-
-    fclose(configFile);
-
-    return 0;
-}
-
-DriverType getDriverType() {
-    const char *fb_caps = "/sys/devices/virtual/graphics/fb0/mdp/caps";
-    // 0 - File exists
-    return access(fb_caps, F_OK) ? DriverType::DRM : DriverType::FB;
-}
-
-const char *GetHALPixelFormatString(int format) {
-  switch (format) {
-  case HAL_PIXEL_FORMAT_RGBA_8888:
-    return "RGBA_8888";
-  case HAL_PIXEL_FORMAT_RGBX_8888:
-    return "RGBX_8888";
-  case HAL_PIXEL_FORMAT_RGB_888:
-    return "RGB_888";
-  case HAL_PIXEL_FORMAT_RGB_565:
-    return "RGB_565";
-  case HAL_PIXEL_FORMAT_BGR_565:
-    return "BGR_565";
-  case HAL_PIXEL_FORMAT_BGRA_8888:
-    return "BGRA_8888";
-  case HAL_PIXEL_FORMAT_RGBA_5551:
-    return "RGBA_5551";
-  case HAL_PIXEL_FORMAT_RGBA_4444:
-    return "RGBA_4444";
-  case HAL_PIXEL_FORMAT_YV12:
-    return "YV12";
-  case HAL_PIXEL_FORMAT_YCbCr_422_SP:
-    return "YCbCr_422_SP_NV16";
-  case HAL_PIXEL_FORMAT_YCrCb_420_SP:
-    return "YCrCb_420_SP_NV21";
-  case HAL_PIXEL_FORMAT_YCbCr_422_I:
-    return "YCbCr_422_I_YUY2";
-  case HAL_PIXEL_FORMAT_YCrCb_422_I:
-    return "YCrCb_422_I_YVYU";
-  case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
-    return "NV12_ENCODEABLE";
-  case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED:
-    return "YCbCr_420_SP_TILED_TILE_4x2";
-  case HAL_PIXEL_FORMAT_YCbCr_420_SP:
-    return "YCbCr_420_SP";
-  case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO:
-    return "YCrCb_420_SP_ADRENO";
-  case HAL_PIXEL_FORMAT_YCrCb_422_SP:
-    return "YCrCb_422_SP";
-  case HAL_PIXEL_FORMAT_R_8:
-    return "R_8";
-  case HAL_PIXEL_FORMAT_RG_88:
-    return "RG_88";
-  case HAL_PIXEL_FORMAT_INTERLACE:
-    return "INTERLACE";
-  case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
-    return "YCbCr_420_SP_VENUS";
-  case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS:
-    return "YCrCb_420_SP_VENUS";
-  case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
-    return "YCbCr_420_SP_VENUS_UBWC";
-  case HAL_PIXEL_FORMAT_RGBA_1010102:
-    return "RGBA_1010102";
-  case HAL_PIXEL_FORMAT_ARGB_2101010:
-    return "ARGB_2101010";
-  case HAL_PIXEL_FORMAT_RGBX_1010102:
-    return "RGBX_1010102";
-  case HAL_PIXEL_FORMAT_XRGB_2101010:
-    return "XRGB_2101010";
-  case HAL_PIXEL_FORMAT_BGRA_1010102:
-    return "BGRA_1010102";
-  case HAL_PIXEL_FORMAT_ABGR_2101010:
-    return "ABGR_2101010";
-  case HAL_PIXEL_FORMAT_BGRX_1010102:
-    return "BGRX_1010102";
-  case HAL_PIXEL_FORMAT_XBGR_2101010:
-    return "XBGR_2101010";
-  case HAL_PIXEL_FORMAT_YCbCr_420_P010:
-    return "YCbCr_420_P010";
-  case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
-    return "YCbCr_420_TP10_UBWC";
-  case HAL_PIXEL_FORMAT_YCbCr_420_P010_VENUS:
-    return "YCbCr_420_P010_VENUS";
-  default:
-    return "Unknown_format";
-  }
-}
-
-}; //namespace qdutils
diff --git a/libqservice/Android.bp b/libqservice/Android.bp
deleted file mode 100644
index fe69d39..0000000
--- a/libqservice/Android.bp
+++ /dev/null
@@ -1,16 +0,0 @@
-cc_library_shared {
-    name: "libqservice",
-    vendor: true,
-    defaults: ["display_defaults"],
-    shared_libs: ["libbinder"],
-    cflags: [
-        "-DLOG_TAG=\"qdqservice\"",
-        "-Wno-sign-conversion",
-    ],
-    srcs: [
-        "QService.cpp",
-        "IQService.cpp",
-        "IQClient.cpp",
-        "IQHDMIClient.cpp",
-    ],
-}
diff --git a/libqservice/IQClient.cpp b/libqservice/IQClient.cpp
deleted file mode 100644
index a6251c8..0000000
--- a/libqservice/IQClient.cpp
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- * Copyright (C) 2012-2013, The Linux Foundation. All rights reserved.
- *
- * Not a Contribution, Apache license notifications and license are
- * retained for attribution purposes only.
-
- * 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 <sys/types.h>
-#include <binder/Parcel.h>
-#include <binder/IBinder.h>
-#include <binder/IInterface.h>
-#include <utils/Errors.h>
-#include <IQClient.h>
-
-using namespace android;
-
-// ---------------------------------------------------------------------------
-// XXX: Since qservice currently runs as part of hwc instead of a standalone
-// process, the implementation below is overridden and the notifyCallback in
-// hwc_qclient is directly called.
-
-namespace qClient {
-
-enum {
-    NOTIFY_CALLBACK = IBinder::FIRST_CALL_TRANSACTION,
-};
-
-class BpQClient : public BpInterface<IQClient>
-{
-public:
-    BpQClient(const sp<IBinder>& impl)
-        : BpInterface<IQClient>(impl) {}
-
-    virtual status_t notifyCallback(uint32_t command,
-            const Parcel* inParcel,
-            Parcel* outParcel) {
-        Parcel data;
-        Parcel *reply = outParcel;
-        data.writeInterfaceToken(IQClient::getInterfaceDescriptor());
-        data.writeInt32(command);
-        if (inParcel->dataAvail())
-            data.appendFrom(inParcel, inParcel->dataPosition(),
-                    inParcel->dataAvail());
-        status_t result = remote()->transact(NOTIFY_CALLBACK, data, reply);
-        return result;
-    }
-};
-
-IMPLEMENT_META_INTERFACE(QClient, "android.display.IQClient");
-
-// ----------------------------------------------------------------------
-//Stub implementation - nothing needed here
-status_t BnQClient::onTransact(
-    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
-{
-    switch(code) {
-        case NOTIFY_CALLBACK: {
-            CHECK_INTERFACE(IQClient, data, reply);
-            uint32_t command = data.readInt32();
-            notifyCallback(command, &data, reply);
-            return NO_ERROR;
-        } break;
-        default:
-            return BBinder::onTransact(code, data, reply, flags);
-    }
-
-}
-
-}; // namespace qClient
diff --git a/libqservice/IQClient.h b/libqservice/IQClient.h
deleted file mode 100644
index 7d816d2..0000000
--- a/libqservice/IQClient.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- * Copyright (C) 2012-2013, The Linux Foundation. All rights reserved.
- *
- * Not a Contribution, Apache license notifications and license are
- * retained for attribution purposes only.
-
- * 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_IQCLIENT_H
-#define ANDROID_IQCLIENT_H
-
-#include <stdint.h>
-#include <sys/types.h>
-#include <utils/Errors.h>
-#include <utils/RefBase.h>
-#include <binder/IInterface.h>
-
-namespace qClient {
-// ----------------------------------------------------------------------------
-class IQClient : public android::IInterface
-{
-public:
-    DECLARE_META_INTERFACE(QClient);
-    virtual android::status_t notifyCallback(uint32_t command,
-            const android::Parcel* inParcel,
-            android::Parcel* outParcel) = 0;
-};
-
-// ----------------------------------------------------------------------------
-
-class BnQClient : public android::BnInterface<IQClient>
-{
-public:
-    virtual android::status_t onTransact( uint32_t code,
-                                          const android::Parcel& data,
-                                          android::Parcel* reply,
-                                          uint32_t flags = 0);
-};
-
-// ----------------------------------------------------------------------------
-}; // namespace qClient
-
-#endif // ANDROID_IQCLIENT_H
diff --git a/libqservice/IQHDMIClient.cpp b/libqservice/IQHDMIClient.cpp
deleted file mode 100644
index 6379e57..0000000
--- a/libqservice/IQHDMIClient.cpp
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
-* Copyright (c) 2014 The Linux Foundation. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without
-* modification, are permitted provided that the following conditions are
-* met:
-*    * Redistributions of source code must retain the above copyright
-*      notice, this list of conditions and the following disclaimer.
-*    * Redistributions in binary form must reproduce the above
-*      copyright notice, this list of conditions and the following
-*      disclaimer in the documentation and/or other materials provided
-*      with the distribution.
-*    * Neither the name of The Linux Foundation. nor the names of its
-*      contributors may be used to endorse or promote products derived
-*      from this software without specific prior written permission.
-*
-* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
-* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
-* ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
-* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
-* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-#include <log/log.h>
-#include <binder/Parcel.h>
-#include "IQHDMIClient.h"
-
-using namespace android;
-namespace qClient {
-
-enum {
-    HDMI_CONNECTED = IBinder::FIRST_CALL_TRANSACTION,
-    CEC_MESSAGE_RECEIVED
-};
-
-class BpQHDMIClient : public BpInterface<IQHDMIClient>
-{
-public:
-    BpQHDMIClient(const sp<IBinder>& impl)
-            :BpInterface<IQHDMIClient>(impl)
-    {
-    }
-
-    void onHdmiHotplug(int connected)
-    {
-        Parcel data, reply;
-        data.writeInterfaceToken(IQHDMIClient::getInterfaceDescriptor());
-        data.writeInt32(connected);
-        remote()->transact(HDMI_CONNECTED, data, &reply, IBinder::FLAG_ONEWAY);
-    }
-
-    void onCECMessageRecieved(char *msg, ssize_t len)
-    {
-        Parcel data, reply;
-        data.writeInterfaceToken(IQHDMIClient::getInterfaceDescriptor());
-        data.writeInt32((int32_t)len);
-        void *buf = data.writeInplace(len);
-        if (buf != NULL)
-            memcpy(buf, msg, len);
-        remote()->transact(CEC_MESSAGE_RECEIVED, data, &reply,
-                IBinder::FLAG_ONEWAY);
-    }
-};
-
-IMPLEMENT_META_INTERFACE(QHDMIClient,
-        "android.display.IQHDMIClient");
-
-status_t BnQHDMIClient::onTransact(uint32_t code, const Parcel& data,
-        Parcel* reply, uint32_t flags)
-{
-    switch(code) {
-        case HDMI_CONNECTED: {
-            CHECK_INTERFACE(IQHDMIClient, data, reply);
-            int connected = data.readInt32();
-            onHdmiHotplug(connected);
-            return NO_ERROR;
-        }
-        case CEC_MESSAGE_RECEIVED: {
-            CHECK_INTERFACE(IQHDMIClient, data, reply);
-            ssize_t len = data.readInt32();
-            const void* msg;
-            if(len >= 0 && len <= (ssize_t) data.dataAvail()) {
-                msg = data.readInplace(len);
-            } else {
-                msg = NULL;
-                len = 0;
-            }
-            if (msg != NULL)
-                onCECMessageRecieved((char*) msg, len);
-            return NO_ERROR;
-        }
-        default: {
-            return BBinder::onTransact(code, data, reply, flags);
-        }
-    }
-}
-
-}; //namespace qClient
diff --git a/libqservice/IQHDMIClient.h b/libqservice/IQHDMIClient.h
deleted file mode 100644
index c3d012a..0000000
--- a/libqservice/IQHDMIClient.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
-* Copyright (c) 2014 The Linux Foundation. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without
-* modification, are permitted provided that the following conditions are
-* met:
-*    * Redistributions of source code must retain the above copyright
-*      notice, this list of conditions and the following disclaimer.
-*    * Redistributions in binary form must reproduce the above
-*      copyright notice, this list of conditions and the following
-*      disclaimer in the documentation and/or other materials provided
-*      with the distribution.
-*    * Neither the name of The Linux Foundation. nor the names of its
-*      contributors may be used to endorse or promote products derived
-*      from this software without specific prior written permission.
-*
-* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
-* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
-* ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
-* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
-* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#ifndef HDMI_EVENTS_LISTENER_H_
-#define HDMI_EVENTS_LISTENER_H_
-
-#include <utils/RefBase.h>
-#include <binder/IInterface.h>
-
-namespace qClient {
-
-class IQHDMIClient : public android::IInterface
-{
-public:
-    DECLARE_META_INTERFACE(QHDMIClient);
-    virtual void onHdmiHotplug(int connected) = 0;
-    virtual void onCECMessageRecieved(char *msg, ssize_t len) = 0;
-};
-
-class BnQHDMIClient : public android::BnInterface<IQHDMIClient>
-{
-public:
-    virtual android::status_t onTransact( uint32_t code,
-            const android::Parcel& data,
-            android::Parcel* reply, uint32_t flags = 0);
-};
-
-}; //namespace qhdmi
-
-#endif // HDMI_EVENTS_LISTENER_H_
-
diff --git a/libqservice/IQService.cpp b/libqservice/IQService.cpp
deleted file mode 100644
index d45a141..0000000
--- a/libqservice/IQService.cpp
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- * Copyright (C) 2012-2016, The Linux Foundation. All rights reserved.
- *
- * Not a Contribution, Apache license notifications and license are
- * retained for attribution purposes only.
-
- * 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 <fcntl.h>
-#include <stdint.h>
-#include <sys/types.h>
-#include <binder/Parcel.h>
-#include <binder/IBinder.h>
-#include <binder/IInterface.h>
-#include <binder/IPCThreadState.h>
-#include <cutils/android_filesystem_config.h>
-#include <utils/Errors.h>
-#include <IQService.h>
-
-#define QSERVICE_DEBUG 0
-
-using namespace android;
-using namespace qClient;
-
-// ---------------------------------------------------------------------------
-
-namespace qService {
-
-class BpQService : public BpInterface<IQService>
-{
-public:
-    BpQService(const sp<IBinder>& impl)
-        : BpInterface<IQService>(impl) {}
-
-    virtual void connect(const sp<IQClient>& client) {
-        ALOGD_IF(QSERVICE_DEBUG, "%s: connect HWC client", __FUNCTION__);
-        Parcel data, reply;
-        data.writeInterfaceToken(IQService::getInterfaceDescriptor());
-        data.writeStrongBinder(IInterface::asBinder(client));
-        remote()->transact(CONNECT_HWC_CLIENT, data, &reply);
-    }
-
-    virtual void connect(const sp<IQHDMIClient>& client) {
-        ALOGD_IF(QSERVICE_DEBUG, "%s: connect HDMI client", __FUNCTION__);
-        Parcel data, reply;
-        data.writeInterfaceToken(IQService::getInterfaceDescriptor());
-        data.writeStrongBinder(IInterface::asBinder(client));
-        remote()->transact(CONNECT_HDMI_CLIENT, data, &reply);
-    }
-
-
-    virtual android::status_t dispatch(uint32_t command, const Parcel* inParcel,
-            Parcel* outParcel) {
-        ALOGD_IF(QSERVICE_DEBUG, "%s: dispatch in:%p", __FUNCTION__, inParcel);
-        status_t err = (status_t) android::FAILED_TRANSACTION;
-        Parcel data;
-        Parcel *reply = outParcel;
-        data.writeInterfaceToken(IQService::getInterfaceDescriptor());
-        if (inParcel && inParcel->dataSize() > 0)
-            data.appendFrom(inParcel, 0, inParcel->dataSize());
-        err = remote()->transact(command, data, reply);
-        return err;
-    }
-};
-
-IMPLEMENT_META_INTERFACE(QService, "android.display.IQService");
-
-// ----------------------------------------------------------------------
-
-status_t BnQService::onTransact(
-    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
-{
-    ALOGD_IF(QSERVICE_DEBUG, "%s: code: %d", __FUNCTION__, code);
-    // IPC should be from certain processes only
-    IPCThreadState* ipc = IPCThreadState::self();
-    const int callerPid = ipc->getCallingPid();
-    const int callerUid = ipc->getCallingUid();
-
-    const bool permission = (callerUid == AID_MEDIA ||
-            callerUid == AID_GRAPHICS ||
-            callerUid == AID_ROOT ||
-            callerUid == AID_CAMERASERVER ||
-            callerUid == AID_AUDIO ||
-            callerUid == AID_SYSTEM ||
-            callerUid == AID_MEDIA_CODEC);
-
-    if (code == CONNECT_HWC_CLIENT) {
-        CHECK_INTERFACE(IQService, data, reply);
-        if(callerUid != AID_GRAPHICS) {
-            ALOGE("display.qservice CONNECT_HWC_CLIENT access denied: pid=%d uid=%d",
-                   callerPid, callerUid);
-            return PERMISSION_DENIED;
-        }
-        sp<IQClient> client =
-                interface_cast<IQClient>(data.readStrongBinder());
-        connect(client);
-        return NO_ERROR;
-    } else if(code == CONNECT_HDMI_CLIENT) {
-        CHECK_INTERFACE(IQService, data, reply);
-        if(callerUid != AID_SYSTEM && callerUid != AID_ROOT) {
-            ALOGE("display.qservice CONNECT_HDMI_CLIENT access denied: pid=%d uid=%d",
-                   callerPid, callerUid);
-            return PERMISSION_DENIED;
-        }
-        sp<IQHDMIClient> client =
-                interface_cast<IQHDMIClient>(data.readStrongBinder());
-        connect(client);
-        return NO_ERROR;
-    } else if (code > COMMAND_LIST_START && code < COMMAND_LIST_END) {
-        if(!permission) {
-            ALOGE("display.qservice access denied: command=%d pid=%d uid=%d",
-                   code, callerPid, callerUid);
-            return PERMISSION_DENIED;
-        }
-        CHECK_INTERFACE(IQService, data, reply);
-        dispatch(code, &data, reply);
-        return NO_ERROR;
-    } else {
-        return BBinder::onTransact(code, data, reply, flags);
-    }
-}
-
-}; // namespace qService
diff --git a/libqservice/IQService.h b/libqservice/IQService.h
deleted file mode 100644
index 5765b10..0000000
--- a/libqservice/IQService.h
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- * Copyright (C) 2012-2014, 2016-2017 The Linux Foundation. All rights reserved.
- *
- * Not a Contribution, Apache license notifications and license are
- * retained for attribution purposes only.
-
- * 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_IQSERVICE_H
-#define ANDROID_IQSERVICE_H
-
-#include <stdint.h>
-#include <sys/types.h>
-#include <utils/Errors.h>
-#include <utils/RefBase.h>
-#include <binder/IInterface.h>
-#include <binder/IBinder.h>
-#include <IQClient.h>
-#include <IQHDMIClient.h>
-
-
-namespace qService {
-// ----------------------------------------------------------------------------
-
-class IQService : public android::IInterface
-{
-public:
-    DECLARE_META_INTERFACE(QService);
-    enum {
-        COMMAND_LIST_START = android::IBinder::FIRST_CALL_TRANSACTION,
-        GET_PANEL_BRIGHTNESS = 2, // Provides ability to set the panel brightness
-        SET_PANEL_BRIGHTNESS = 3, // Provides ability to get the panel brightness
-        CONNECT_HWC_CLIENT = 4, // Connect to qservice
-        SCREEN_REFRESH = 5,     // Refresh screen through SF invalidate
-        EXTERNAL_ORIENTATION = 6,// Set external orientation
-        BUFFER_MIRRORMODE = 7,  // Buffer mirrormode
-        CHECK_EXTERNAL_STATUS = 8,// Check status of external display
-        GET_DISPLAY_ATTRIBUTES = 9,// Get display attributes
-        SET_HSIC_DATA = 10,     // Set HSIC on dspp
-        GET_DISPLAY_VISIBLE_REGION = 11,// Get the visibleRegion for dpy
-        SET_SECONDARY_DISPLAY_STATUS = 12,// Sets secondary display status
-        SET_MAX_PIPES_PER_MIXER = 13,// Set max pipes per mixer for MDPComp
-        SET_VIEW_FRAME = 14,    // Set view frame of display
-        DYNAMIC_DEBUG = 15,     // Enable more logging on the fly
-        SET_IDLE_TIMEOUT = 16,  // Set idle timeout for GPU fallback
-        TOGGLE_BWC = 17,           // Toggle BWC On/Off on targets that support
-        /* Enable/Disable/Set refresh rate dynamically */
-        CONFIGURE_DYN_REFRESH_RATE = 18,
-        CONTROL_PARTIAL_UPDATE = 19,   // Provides ability to enable/disable partial update
-        TOGGLE_SCREEN_UPDATES = 20, // Provides ability to set the panel brightness
-        SET_FRAME_DUMP_CONFIG = 21,  // Provides ability to set the frame dump config
-        SET_S3D_MODE = 22, // Set the 3D mode as specified in msm_hdmi_modes.h
-        CONNECT_HDMI_CLIENT = 23,  // Connect HDMI CEC HAL Client
-        QDCM_SVC_CMDS = 24,        // request QDCM services.
-        SET_ACTIVE_CONFIG = 25, //Set a specified display config
-        GET_ACTIVE_CONFIG = 26, //Get the current config index
-        GET_CONFIG_COUNT = 27, //Get the number of supported display configs
-        GET_DISPLAY_ATTRIBUTES_FOR_CONFIG = 28, //Get attr for specified config
-        SET_DISPLAY_MODE = 29, // Set display mode to command or video mode
-        SET_CAMERA_STATUS = 30, // To notify display when camera is on and off
-        MIN_HDCP_ENCRYPTION_LEVEL_CHANGED = 31,
-        GET_BW_TRANSACTION_STATUS = 32, //Client can query BW transaction status.
-        SET_LAYER_MIXER_RESOLUTION = 33, // Enables client to set layer mixer resolution.
-        SET_COLOR_MODE = 34, // Overrides the QDCM mode on the display
-        GET_HDR_CAPABILITIES = 35, // Get HDR capabilities for legacy HWC interface
-        SET_COLOR_MODE_BY_ID = 36, // Overrides the QDCM mode using the given mode ID
-        GET_COMPOSER_STATUS = 37, // Get composer init status-true if primary display init is done
-        COMMAND_LIST_END = 400,
-    };
-
-    enum {
-        END = 0,
-        START,
-    };
-
-    enum {
-        DEBUG_ALL,
-        DEBUG_MDPCOMP,
-        DEBUG_VSYNC,
-        DEBUG_VD,
-        DEBUG_PIPE_LIFECYCLE,
-        DEBUG_DRIVER_CONFIG,
-        DEBUG_ROTATOR,
-        DEBUG_QDCM,
-        DEBUG_SCALAR,
-        DEBUG_CLIENT,
-        DEBUG_DISPLAY,
-        DEBUG_MAX_VAL = DEBUG_DISPLAY, // Used to check each bit of the debug command paramater.
-        // Update DEBUG_MAX_VAL when adding new debug tag.
-    };
-
-    enum {
-        PREF_POST_PROCESSING,
-        PREF_PARTIAL_UPDATE,
-        ENABLE_PARTIAL_UPDATE,
-    };
-
-    // Register a HWC client that can be notified
-    // This client is generic and is intended to get
-    // dispatches of all events calling into QService
-    virtual void connect(const android::sp<qClient::IQClient>& client) = 0;
-    // Register an HDMI client. This client gets notification of HDMI events
-    // such as plug/unplug and CEC messages
-    virtual void connect(const android::sp<qClient::IQHDMIClient>& client) = 0;
-    // Generic function to dispatch binder commands
-    // The type of command decides how the data is parceled
-    virtual android::status_t dispatch(uint32_t command,
-            const android::Parcel* inParcel,
-            android::Parcel* outParcel) = 0;
-};
-
-// ----------------------------------------------------------------------------
-
-class BnQService : public android::BnInterface<IQService>
-{
-public:
-    virtual android::status_t onTransact( uint32_t code,
-                                          const android::Parcel& data,
-                                          android::Parcel* reply,
-                                          uint32_t flags = 0);
-};
-
-// ----------------------------------------------------------------------------
-}; // namespace qService
-
-#endif // ANDROID_IQSERVICE_H
diff --git a/libqservice/Makefile.am b/libqservice/Makefile.am
deleted file mode 100644
index 79935b8..0000000
--- a/libqservice/Makefile.am
+++ /dev/null
@@ -1,18 +0,0 @@
-h_sources = IQService.h \
-            IQClient.h
-
-cpp_sources = QService.cpp \
-              IQService.cpp \
-              IQClient.cpp \
-              IQHDMIClient.cpp
-
-library_includedir = $(includedir)
-library_include_HEADERS = $(h_sources)
-
-lib_LTLIBRARIES = libqservice.la
-libqservice_la_CC = @CC@
-libqservice_la_SOURCES = $(cpp_sources)
-libqservice_la_CFLAGS = $(COMMON_CFLAGS) -DLOG_TAG=\"qdqservice\"
-libqservice_la_CPPFLAGS = $(AM_CPPFLAGS)
-libqservice_LDADD = -lhardware -lcutils -llog -lbinder
-libqservice_la_LDFLAGS = -shared -avoid-version
\ No newline at end of file
diff --git a/libqservice/QService.cpp b/libqservice/QService.cpp
deleted file mode 100644
index 546ad7e..0000000
--- a/libqservice/QService.cpp
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- *  Copyright (c) 2012-2014, 2016, The Linux Foundation. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- *       copyright notice, this list of conditions and the following
- *       disclaimer in the documentation and/or other materials provided
- *       with the distribution.
- *     * Neither the name of The Linux Foundation nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <QService.h>
-#include <binder/Parcel.h>
-#include <binder/IPCThreadState.h>
-
-#define QSERVICE_DEBUG 0
-
-using namespace android;
-
-namespace qService {
-
-QService* QService::sQService = NULL;
-// ----------------------------------------------------------------------------
-QService::QService()
-{
-    ALOGD_IF(QSERVICE_DEBUG, "QService Constructor invoked");
-}
-
-QService::~QService()
-{
-    ALOGD_IF(QSERVICE_DEBUG,"QService Destructor invoked");
-}
-
-void QService::connect(const sp<qClient::IQClient>& client) {
-    ALOGD_IF(QSERVICE_DEBUG,"HWC client connected");
-    mClient = client;
-}
-
-void QService::connect(const sp<qClient::IQHDMIClient>& client) {
-    ALOGD_IF(QSERVICE_DEBUG,"HDMI client connected");
-    mHDMIClient = client;
-}
-
-status_t QService::dispatch(uint32_t command, const Parcel* inParcel,
-        Parcel* outParcel) {
-    status_t err = (status_t) FAILED_TRANSACTION;
-    IPCThreadState* ipc = IPCThreadState::self();
-    //Rewind parcel in case we're calling from the same process
-    bool sameProcess = (ipc->getCallingPid() == getpid());
-    if(sameProcess)
-        inParcel->setDataPosition(0);
-    if (mClient.get()) {
-        ALOGD_IF(QSERVICE_DEBUG, "Dispatching command: %d", command);
-        err = mClient->notifyCallback(command, inParcel, outParcel);
-        //Rewind parcel in case we're calling from the same process
-        if (sameProcess)
-            outParcel->setDataPosition(0);
-    }
-    return err;
-}
-
-void QService::onHdmiHotplug(int connected) {
-    if(mHDMIClient.get()) {
-        ALOGD_IF(QSERVICE_DEBUG, "%s: HDMI hotplug", __FUNCTION__);
-        mHDMIClient->onHdmiHotplug(connected);
-    } else {
-        ALOGW("%s: Failed to get a valid HDMI client", __FUNCTION__);
-    }
-}
-
-void QService::onCECMessageReceived(char *msg, ssize_t len) {
-    if(mHDMIClient.get()) {
-        ALOGD_IF(QSERVICE_DEBUG, "%s: CEC message received", __FUNCTION__);
-        mHDMIClient->onCECMessageRecieved(msg, len);
-    } else {
-        ALOGW("%s: Failed to get a valid HDMI client", __FUNCTION__);
-    }
-}
-
-
-void QService::init()
-{
-    if(!sQService) {
-        sQService = new QService();
-        sp<IServiceManager> sm = defaultServiceManager();
-        sm->addService(String16("display.qservice"), sQService);
-        if(sm->checkService(String16("display.qservice")) != NULL)
-            ALOGD_IF(QSERVICE_DEBUG, "adding display.qservice succeeded");
-        else
-            ALOGD_IF(QSERVICE_DEBUG, "adding display.qservice failed");
-    }
-}
-
-}
diff --git a/libqservice/QService.h b/libqservice/QService.h
deleted file mode 100644
index 6bb4d7d..0000000
--- a/libqservice/QService.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- *  Copyright (c) 2012-2013, 2016, The Linux Foundation. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- *       copyright notice, this list of conditions and the following
- *       disclaimer in the documentation and/or other materials provided
- *       with the distribution.
- *     * Neither the name of The Linux Foundation nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef ANDROID_QSERVICE_H
-#define ANDROID_QSERVICE_H
-
-#include <utils/Errors.h>
-#include <sys/types.h>
-#include <log/log.h>
-#include <binder/IServiceManager.h>
-#include <IQService.h>
-#include <IQClient.h>
-
-struct hwc_context_t;
-
-namespace qService {
-// ----------------------------------------------------------------------------
-
-class QService : public BnQService {
-public:
-    virtual ~QService();
-    virtual void connect(const android::sp<qClient::IQClient>& client);
-    virtual void connect(const android::sp<qClient::IQHDMIClient>& client);
-    virtual android::status_t dispatch(uint32_t command,
-            const android::Parcel* data,
-            android::Parcel* reply);
-    virtual void onHdmiHotplug(int connected);
-    virtual void onCECMessageReceived(char *msg, ssize_t len);
-    static void init();
-private:
-    QService();
-    android::sp<qClient::IQClient> mClient;
-    android::sp<qClient::IQHDMIClient> mHDMIClient;
-    static QService *sQService;
-};
-}; // namespace qService
-#endif // ANDROID_QSERVICE_H
diff --git a/libqservice/QServiceUtils.h b/libqservice/QServiceUtils.h
deleted file mode 100644
index 8f25253..0000000
--- a/libqservice/QServiceUtils.h
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
-* Copyright (c) 2013-14 The Linux Foundation. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without
-* modification, are permitted provided that the following conditions are
-* met:
-*    * Redistributions of source code must retain the above copyright
-*      notice, this list of conditions and the following disclaimer.
-*    * Redistributions in binary form must reproduce the above
-*      copyright notice, this list of conditions and the following
-*      disclaimer in the documentation and/or other materials provided
-*      with the distribution.
-*    * Neither the name of The Linux Foundation. nor the names of its
-*      contributors may be used to endorse or promote products derived
-*      from this software without specific prior written permission.
-*
-* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
-* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
-* ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
-* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
-* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#ifndef QSERVICEUTILS_H
-#define QSERVICEUTILS_H
-#include <binder/Parcel.h>
-#include <binder/IServiceManager.h>
-#include <utils/RefBase.h>
-#include <IQService.h>
-
-// ----------------------------------------------------------------------------
-// Helpers
-// ----------------------------------------------------------------------------
-inline android::sp<qService::IQService> getBinder() {
-    android::sp<android::IServiceManager> sm = android::defaultServiceManager();
-    android::sp<qService::IQService> binder =
-            android::interface_cast<qService::IQService>
-            (sm->getService(android::String16("display.qservice")));
-    if (binder == NULL) {
-        ALOGE("%s: invalid binder object", __FUNCTION__);
-    }
-    return binder;
-}
-
-inline android::status_t sendSingleParam(uint32_t command, uint32_t value) {
-    android::status_t err = (android::status_t) android::FAILED_TRANSACTION;
-    android::sp<qService::IQService> binder = getBinder();
-    android::Parcel inParcel, outParcel;
-    inParcel.writeInt32(value);
-    if(binder != NULL) {
-        err = binder->dispatch(command, &inParcel , &outParcel);
-    }
-    return err;
-}
-
-// ----------------------------------------------------------------------------
-// Convenience wrappers that clients can call
-// ----------------------------------------------------------------------------
-inline android::status_t screenRefresh() {
-    return sendSingleParam(qService::IQService::SCREEN_REFRESH, 1);
-}
-
-inline android::status_t toggleScreenUpdate(uint32_t on) {
-    return sendSingleParam(qService::IQService::TOGGLE_SCREEN_UPDATES, on);
-}
-
-inline android::status_t setExtOrientation(uint32_t orientation) {
-    return sendSingleParam(qService::IQService::EXTERNAL_ORIENTATION,
-            orientation);
-}
-
-inline android::status_t setBufferMirrorMode(uint32_t enable) {
-    return sendSingleParam(qService::IQService::BUFFER_MIRRORMODE, enable);
-}
-
-inline android::status_t setCameraLaunchStatus(uint32_t on) {
-    return sendSingleParam(qService::IQService::SET_CAMERA_STATUS, on);
-}
-
-inline bool displayBWTransactionPending() {
-    android::status_t err = (android::status_t) android::FAILED_TRANSACTION;
-    bool ret = false;
-    android::sp<qService::IQService> binder = getBinder();
-    android::Parcel inParcel, outParcel;
-    if(binder != NULL) {
-        err = binder->dispatch(qService::IQService::GET_BW_TRANSACTION_STATUS,
-                &inParcel , &outParcel);
-        if(err != android::NO_ERROR){
-          ALOGE("GET_BW_TRANSACTION_STATUS binder call failed err=%d", err);
-          return ret;
-        }
-    }
-    ret = outParcel.readInt32();
-    return ret;
-}
-#endif /* end of include guard: QSERVICEUTILS_H */
diff --git a/sdm/include/core/buffer_allocator.h b/sdm/include/core/buffer_allocator.h
deleted file mode 100644
index 6d77bcd..0000000
--- a/sdm/include/core/buffer_allocator.h
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
-* Copyright (c) 2015 - 2017, The Linux Foundation. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without
-* modification, are permitted provided that the following conditions are
-* met:
-*  * Redistributions of source code must retain the above copyright
-*    notice, this list of conditions and the following disclaimer.
-*  * Redistributions in binary form must reproduce the above
-*    copyright notice, this list of conditions and the following
-*    disclaimer in the documentation and/or other materials provided
-*    with the distribution.
-*  * Neither the name of The Linux Foundation nor the names of its
-*    contributors may be used to endorse or promote products derived
-*    from this software without specific prior written permission.
-*
-* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
-* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
-* ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
-* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
-* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-/*! @file buffer_allocator.h
-  @brief Interface file for platform specific buffer allocator.
-
-  @details This interface is used by SDM to allocate internal buffers.
-*/
-
-#ifndef __BUFFER_ALLOCATOR_H__
-#define __BUFFER_ALLOCATOR_H__
-
-#include "layer_buffer.h"
-
-namespace sdm {
-/*! @brief Input configuration set by the client for buffer allocation.
-
-  @sa BufferInfo::BufferConfig
-*/
-
-struct BufferConfig {
-  uint32_t width = 0;                         //!< Specifies buffer width for buffer allocation.
-  uint32_t height = 0;                        //!< Specifies buffer height for buffer allocation.
-  LayerBufferFormat format = kFormatInvalid;  //!< Specifies buffer format for buffer allocation.
-  uint32_t buffer_count = 0;                  //!< Specifies number of buffers to be allocated.
-  bool secure = false;                        //!< Specifies buffer to be allocated from
-                                              //!< secure region.
-  bool cache = false;                         //!< Specifies whether the buffer needs to be cache.
-  bool secure_camera = false;                 //!< Specifies buffer to be allocated from specific
-                                              //!< secure heap and with a specific alignment.
-  bool gfx_client = false;                    //!< Specifies whether buffer is used by gfx.
-};
-
-/*! @brief Holds the information about the allocated buffer.
-
-  @sa BufferAllocator::AllocateBuffer
-  @sa BufferAllocator::FreeBuffer
-  @sa BufferAllocator::GetAllocatedBufferInfo
-*/
-struct AllocatedBufferInfo {
-  int fd = -1;                   //!< Specifies the fd of the allocated buffer.
-  uint32_t stride = 0;           //!< Specifies allocated buffer stride in bytes.
-  uint32_t aligned_width = 0;    //!< Specifies aligned allocated buffer width in pixels.
-  uint32_t aligned_height = 0;   //!< Specifies aligned allocated buffer height in pixels.
-  LayerBufferFormat format = kFormatInvalid;  // Specifies buffer format for allocated buffer.
-  uint32_t size = 0;             //!< Specifies the size of the allocated buffer.
-};
-
-/*! @brief Holds the information about the input/output configuration of an output buffer.
-
-  @sa BufferAllocator::AllocateBuffer
-  @sa BufferAllocator::FreeBuffer
-*/
-struct BufferInfo {
-  BufferConfig buffer_config;             //!< Specifies configuration of a buffer to be allocated.
-  AllocatedBufferInfo alloc_buffer_info;  //!< Specifies buffer information of allocated buffer.
-
-  void *private_data = NULL;              //!< Pointer to private data.
-};
-
-/*! @brief Buffer allocator implemented by the client
-
-  @details This class declares prototype for BufferAllocator methods which must be
-  implemented by the client. Buffer manager in display manager will use these methods to
-  allocate/deallocate buffers for display manager.
-
-  @sa CoreInterface::CreateCore
-*/
-class BufferAllocator {
- public:
-  /*! @brief Method to allocate ouput buffer for the given input configuration.
-
-    @details This method allocates memory based on input configuration.
-
-    @param[in] buffer_info \link BufferInfo \endlink
-
-    @return \link DisplayError \endlink
-  */
-  virtual DisplayError AllocateBuffer(BufferInfo *buffer_info) = 0;
-
-
-  /*! @brief Method to deallocate the ouput buffer.
-
-    @details This method deallocates the memory allocated using AllocateBuffer method.
-
-    @param[in] buffer_info \link BufferInfo \endlink
-
-    @return \link DisplayError \endlink
-  */
-  virtual DisplayError FreeBuffer(BufferInfo *buffer_info) = 0;
-
-
-  /*! @brief Method to get the buffer size.
-
-    @details This method returns buffer size for a specific configuration mentioned in buffer info.
-
-    @param[in] buffer_info \link BufferInfo \endlink
-
-    @return \link unsigned int \endlink
-  */
-  virtual uint32_t GetBufferSize(BufferInfo *buffer_info) = 0;
-
-  /*! @brief Method to Get the AllocatedBufferInfo only.
-
-    @details This method populates the AllocatedBufferInfo as per the configuration in BufferInfo,
-    but fd will be invalid.
-
-    @param[in] buffer_info \link BufferInfo \endlink
-
-    @param[out] allocated_buffer_info \link AllocatedBufferInfo \endlink
-
-    @return \link DisplayError \endlink
-  */
-  virtual DisplayError GetAllocatedBufferInfo(const BufferConfig &buffer_config,
-                                              AllocatedBufferInfo *allocated_buffer_info) = 0;
-
-  /*
-   * Retuns a buffer's layout in terms of number of planes, stride and offset of each plane
-   * Input: AllocatedBufferInfo with a valid aligned width, aligned height, SDM format
-   * Output: stride for each plane, offset of each plane from base, number of planes
-   */
-  virtual DisplayError GetBufferLayout(const AllocatedBufferInfo &buf_info,
-                                       uint32_t stride[4], uint32_t offset[4],
-                                       uint32_t *num_planes) { return kErrorNotSupported; }
-
- protected:
-  virtual ~BufferAllocator() { }
-};
-
-}  // namespace sdm
-
-#endif  // __BUFFER_ALLOCATOR_H__
-
diff --git a/sdm/include/core/buffer_sync_handler.h b/sdm/include/core/buffer_sync_handler.h
deleted file mode 100644
index 1dc5413..0000000
--- a/sdm/include/core/buffer_sync_handler.h
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
-* Copyright (c) 2015, The Linux Foundation. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without
-* modification, are permitted provided that the following conditions are
-* met:
-*  * Redistributions of source code must retain the above copyright
-*    notice, this list of conditions and the following disclaimer.
-*  * Redistributions in binary form must reproduce the above
-*    copyright notice, this list of conditions and the following
-*    disclaimer in the documentation and/or other materials provided
-*    with the distribution.
-*  * Neither the name of The Linux Foundation nor the names of its
-*    contributors may be used to endorse or promote products derived
-*    from this software without specific prior written permission.
-*
-* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
-* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
-* ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
-* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
-* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-/*! @file buffer_sync_handler.h
-  @brief Interface file for platform specific buffer allocator.
-
-  @details SDM will use this interface to wait for buffer sync fd to be signaled/merge
-  the two buffer sync fds into one.
-*/
-
-#ifndef __BUFFER_SYNC_HANDLER_H__
-#define __BUFFER_SYNC_HANDLER_H__
-
-#include "sdm_types.h"
-
-namespace sdm {
-
-/*! @brief Buffer sync handler implemented by the client
-
-  @details This class declares prototype for BufferSyncHandler methods which must be
-  implemented by the client. SDM will use these methods to wait for buffer sync fd to be
-  signaled/merge two buffer sync fds into one.
-
-  @sa CoreInterface::CreateCore
-*/
-class BufferSyncHandler {
- public:
-  /*! @brief Method to wait for ouput buffer to be released.
-
-    @details This method waits for fd to be signaled by the producer/consumer.
-    It is responsibility of the caller to close file descriptor.
-
-    @param[in] fd
-
-    @return \link DisplayError \endlink
-  */
-
-  virtual DisplayError SyncWait(int fd) = 0;
-
-  /*! @brief Method to merge two sync fds into one sync fd
-
-    @details This method merges two buffer sync fds into one sync fd, if a producer/consumer
-    requires to wait for more than one sync fds. It is responsibility of the caller to close file
-    descriptor.
-
-    @param[in] fd1
-    @param[in] fd2
-    @param[out] merged_fd
-
-    @return \link DisplayError \endlink
- */
-
-  virtual DisplayError SyncMerge(int fd1, int fd2, int *merged_fd) = 0;
-
-  /*! @brief Method to detect if sync fd is signaled
-
-    @details This method detects if sync fd is signaled. It is responsibility of the caller to
-    close file descriptor.
-
-    @param[in] fd
-
-    @return \link Tue if fd has been signaled \endlink
- */
-  virtual bool IsSyncSignaled(int fd) = 0;
-
- protected:
-  virtual ~BufferSyncHandler() { }
-};
-
-}  // namespace sdm
-
-#endif  // __BUFFER_SYNC_HANDLER_H__
-
diff --git a/sdm/include/core/core_interface.h b/sdm/include/core/core_interface.h
deleted file mode 100644
index d169956..0000000
--- a/sdm/include/core/core_interface.h
+++ /dev/null
@@ -1,205 +0,0 @@
-/*
-* Copyright (c) 2014 - 2016, 2018 The Linux Foundation. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without
-* modification, are permitted provided that the following conditions are
-* met:
-*     * Redistributions of source code must retain the above copyright
-*       notice, this list of conditions and the following disclaimer.
-*     * Redistributions in binary form must reproduce the above
-*       copyright notice, this list of conditions and the following
-*       disclaimer in the documentation and/or other materials provided
-*       with the distribution.
-*     * Neither the name of The Linux Foundation nor the names of its
-*       contributors may be used to endorse or promote products derived
-*       from this software without specific prior written permission.
-*
-* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
-* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
-* ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
-* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
-* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-/*! @file core_interface.h
-  @brief Interface file for core of the display subsystem.
-
-  @details Display core is primarily used for loading and unloading different display device
-  components viz primary, external and virtual. Display core is a statically linked library which
-  runs in caller's process context.
-*/
-#ifndef __CORE_INTERFACE_H__
-#define __CORE_INTERFACE_H__
-
-#include <stdint.h>
-
-#include "display_interface.h"
-#include "sdm_types.h"
-#include "buffer_allocator.h"
-#include "buffer_sync_handler.h"
-#include "socket_handler.h"
-
-/*! @brief Display manager interface version.
-
-  @details Display manager interfaces are version tagged to maintain backward compatibility. This
-  version is supplied as a default argument during display core initialization.
-
-  Client may use an older version of interfaces and link to a higher version of display manager
-  library, but vice versa is not allowed.
-
-  A 32-bit client must use 32-bit display core library and a 64-bit client must use 64-bit display
-  core library.
-
-  Display manager interfaces follow default data structures alignment. Client must not override the
-  default padding rules while using these interfaces.
-
-  @warning It is assumed that client upgrades or downgrades display core interface all at once
-  and recompile all binaries which use these interfaces. Mix and match of these interfaces can
-  lead to unpredictable behaviour.
-
-  @sa CoreInterface::CreateCore
-*/
-#define SDM_REVISION_MAJOR (1)
-#define SDM_REVISION_MINOR (0)
-
-#define SDM_VERSION_TAG ((uint32_t) ((SDM_REVISION_MAJOR << 24) | (SDM_REVISION_MINOR << 16) | \
-                                    (sizeof(SDMCompatibility) << 8) | sizeof(int *)))
-
-namespace sdm {
-
-/*! @brief This enum represents max bandwidth limit mode.
-
-  @sa DisplayInterface::SetMaxBandwidthMode
-*/
-enum HWBwModes {
-  kBwDefault,      //!< Default state. No change in device bandwidth limit.
-  kBwCamera,       //!< Camera is on. Bandwidth limit should be reduced accordingly.
-  kBwVFlip,        //!< VFlip is required. Reduce bandwidth limit accordingly.
-  kBwHFlip,        //!< HFlip is required.  Reduce bandwidth limit accordingly.
-  kBwModeMax,      //!< Limiter for maximum available bandwidth modes.
-};
-
-
-/*! @brief Information on hardware for the first display
-
-  @details This structure returns the display type of the first display on the device
-  (internal display or HDMI etc) and whether it is currently connected,
-
-*/
-struct HWDisplayInterfaceInfo {
-  DisplayType type;
-  bool is_connected;
-};
-
-/*! @brief Display core interface.
-
-  @details This class defines display core interfaces. It contains methods which client shall use
-  to create/destroy different display devices. This interface is created during display core
-  CreateCore() and remains valid until DestroyCore().
-
-  @sa CoreInterface::CreateCore
-  @sa CoreInterface::DestroyCore
-*/
-class CoreInterface {
- public:
-  /*! @brief Method to create and get handle to display core interface.
-
-    @details This method is the entry point into the display core. Client can create and operate on
-    different display devices only through a valid interface handle obtained using this method. An
-    object of display core is created and handle to this object is returned via output parameter.
-    This interface shall be called only once.
-
-    @param[in] buffer_allocator \link BufferAllocator \endlink
-    @param[in] buffer_sync_handler \link BufferSyncHandler \endlink
-    @param[in] socket_handler \link SocketHandler \endlink
-    @param[out] interface \link CoreInterface \endlink
-    @param[in] version \link SDM_VERSION_TAG \endlink. Client must not override this argument.
-
-    @return \link DisplayError \endlink
-
-    @sa DestroyCore
-  */
-  static DisplayError CreateCore(BufferAllocator *buffer_allocator,
-                                 BufferSyncHandler *buffer_sync_handler,
-                                 SocketHandler *socket_handler, CoreInterface **interface,
-                                 uint32_t version = SDM_VERSION_TAG);
-
-  /*! @brief Method to release handle to display core interface.
-
-    @details The object of corresponding display core is destroyed when this method is invoked.
-    Client must explicitly destroy all created display device objects associated with this handle
-    before invoking this method.
-
-    @param[in] interface \link CoreInterface \endlink
-
-    @return \link DisplayError \endlink
-
-    @sa CreateCore
-  */
-  static DisplayError DestroyCore();
-
-  /*! @brief Method to create a display device for a given type.
-
-    @details Client shall use this method to create each of the connected display type. A handle to
-    interface associated with this object is returned via output parameter which can be used to
-    interact further with the display device.
-
-    @param[in] type \link DisplayType \endlink
-    @param[in] event_handler \link DisplayEventHandler \endlink
-    @param[out] interface \link DisplayInterface \endlink
-
-    @return \link DisplayError \endlink
-
-    @sa DestroyDisplay
-  */
-  virtual DisplayError CreateDisplay(DisplayType type, DisplayEventHandler *event_handler,
-                                     DisplayInterface **interface) = 0;
-
-  /*! @brief Method to destroy a display device.
-
-    @details Client shall use this method to destroy each of the created display device objects.
-
-    @param[in] interface \link DisplayInterface \endlink
-
-    @return \link DisplayError \endlink
-
-    @sa CreateDisplay
-  */
-  virtual DisplayError DestroyDisplay(DisplayInterface *interface) = 0;
-
-  /*! @brief Method to update the bandwidth limit as per given mode.
-
-    @param[in] mode indicate the mode or use case
-
-    @return \link DisplayError \endlink
-
-   */
-    virtual DisplayError SetMaxBandwidthMode(HWBwModes mode) = 0;
-
-  /*! @brief Method to get characteristics of the first display.
-
-    @details Client shall use this method to determine if the first display is HDMI, and whether
-    it is currently connected.
-
-    @param[in] hw_disp_info structure that this method will fill up with info.
-
-    @return \link DisplayError \endlink
-
-   */
-    virtual DisplayError GetFirstDisplayInterfaceType(HWDisplayInterfaceInfo *hw_disp_info) = 0;
-
-
- protected:
-  virtual ~CoreInterface() { }
-};
-
-}  // namespace sdm
-
-#endif  // __CORE_INTERFACE_H__
-
diff --git a/sdm/include/core/display_interface.h b/sdm/include/core/display_interface.h
deleted file mode 100644
index 8156ca4..0000000
--- a/sdm/include/core/display_interface.h
+++ /dev/null
@@ -1,700 +0,0 @@
-/*
-* Copyright (c) 2014 - 2018, The Linux Foundation. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without modification, are permitted
-* provided that the following conditions are met:
-*    * Redistributions of source code must retain the above copyright notice, this list of
-*      conditions and the following disclaimer.
-*    * Redistributions in binary form must reproduce the above copyright notice, this list of
-*      conditions and the following disclaimer in the documentation and/or other materials provided
-*      with the distribution.
-*    * Neither the name of The Linux Foundation nor the names of its contributors may be used to
-*      endorse or promote products derived from this software without specific prior written
-*      permission.
-*
-* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-* NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
-* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
-* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
-* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-/*! @file display_interface.h
-  @brief Interface file for display device which represents a physical panel or an output buffer
-  where contents can be rendered.
-
-  @details Display device is used to send layer buffers for composition and get them rendered onto
-  the target device. Each display device represents a unique display target which may be either a
-  physical panel or an output buffer..
-*/
-#ifndef __DISPLAY_INTERFACE_H__
-#define __DISPLAY_INTERFACE_H__
-
-#include <stdint.h>
-#include <string>
-#include <vector>
-#include <utility>
-
-#include "layer_stack.h"
-#include "sdm_types.h"
-
-namespace sdm {
-
-typedef std::vector<std::pair<std::string, std::string>> AttrVal;
-
-/*! @brief This enum represents display device types where contents can be rendered.
-
-  @sa CoreInterface::CreateDisplay
-  @sa CoreInterface::IsDisplaySupported
-*/
-enum DisplayType {
-  kPrimary,         //!< Main physical display which is attached to the handheld device.
-  kHDMI,            //!< HDMI physical display which is generally detachable.
-  kVirtual,         //!< Contents would be rendered into the output buffer provided by the client
-                    //!< e.g. wireless display.
-  kDisplayMax,
-};
-
-/*! @brief This enum represents states of a display device.
-
-  @sa DisplayInterface::GetDisplayState
-  @sa DisplayInterface::SetDisplayState
-*/
-enum DisplayState {
-  kStateOff,        //!< Display is OFF. Contents are not rendered in this state. Client will not
-                    //!< receive VSync events in this state. This is default state as well.
-
-  kStateOn,         //!< Display is ON. Contents are rendered in this state.
-
-  kStateDoze,       //!< Display is ON and it is configured in a low power state.
-
-  kStateDozeSuspend,
-                    //!< Display is ON in a low power state and continue showing its current
-                    //!< contents indefinitely until the mode changes.
-
-  kStateStandby,    //!< Display is OFF. Client will continue to receive VSync events in this state
-                    //!< if VSync is enabled. Contents are not rendered in this state.
-};
-
-/*! @brief This enum represents flags to override detail enhancer parameters.
-
-  @sa DisplayInterface::SetDetailEnhancerData
-*/
-enum DetailEnhancerOverrideFlags {
-  kOverrideDEEnable            = 0x1,     // Specifies to enable detail enhancer
-  kOverrideDESharpen1          = 0x2,     // Specifies user defined Sharpening/smooth for noise
-  kOverrideDESharpen2          = 0x4,     // Specifies user defined Sharpening/smooth for signal
-  kOverrideDEClip              = 0x8,     // Specifies user defined DE clip shift
-  kOverrideDELimit             = 0x10,    // Specifies user defined DE limit value
-  kOverrideDEThrQuiet          = 0x20,    // Specifies user defined DE quiet threshold
-  kOverrideDEThrDieout         = 0x40,    // Specifies user defined DE dieout threshold
-  kOverrideDEThrLow            = 0x80,    // Specifies user defined DE low threshold
-  kOverrideDEThrHigh           = 0x100,   // Specifies user defined DE high threshold
-  kOverrideDEFilterConfig      = 0x200,   // Specifies user defined scaling filter config
-  kOverrideDEMax               = 0xFFFFFFFF,
-};
-
-/*! @brief This enum represents Y/RGB scaling filter configuration.
-
-  @sa DisplayInterface::SetDetailEnhancerData
-*/
-enum ScalingFilterConfig {
-  kFilterEdgeDirected,
-  kFilterCircular,
-  kFilterSeparable,
-  kFilterBilinear,
-  kFilterMax,
-};
-
-/*! @brief This enum represents the quality level of the content.
-
-  @sa DisplayInterface::SetDetailEnhancerData
-*/
-enum ContentQuality {
-  kContentQualityUnknown,  // Default: high artifact and noise
-  kContentQualityLow,      // Low quality content, high artifact and noise,
-  kContentQualityMedium,   // Medium quality, medium artifact and noise,
-  kContentQualityHigh,     // High quality content, low artifact and noise
-  kContentQualityMax,
-};
-
-/*! @brief This enum represents the display port.
-
-  @sa DisplayInterface::GetDisplayPort
-*/
-enum DisplayPort {
-  kPortDefault,
-  kPortDSI,        // Display is connected to DSI port.
-  kPortDTV,        // Display is connected to DTV port
-  kPortWriteBack,  // Display is connected to writeback port
-  kPortLVDS,       // Display is connected to LVDS port
-  kPortEDP,        // Display is connected to EDP port
-  kPortDP,         // Display is connected to DP port.
-};
-
-/*! @brief This enum represents the events received by Display HAL. */
-enum DisplayEvent {
-  kIdleTimeout,        // Event triggered by Idle Timer.
-  kThermalEvent,       // Event triggered by Thermal.
-  kIdlePowerCollapse,  // Event triggered by Idle Power Collapse.
-  kPanelDeadEvent,     // Event triggered by ESD.
-};
-
-/*! @brief This structure defines configuration for fixed properties of a display device.
-
-  @sa DisplayInterface::GetConfig
-  @sa DisplayInterface::SetConfig
-*/
-struct DisplayConfigFixedInfo {
-  bool underscan = false;   //!< If display support CE underscan.
-  bool secure = false;      //!< If this display is capable of handling secure content.
-  bool is_cmdmode = false;  //!< If panel is command mode panel.
-  bool hdr_supported = false;  //!< if HDR is enabled
-  bool hdr_metadata_type_one = false;  //!< Metadata type one obtained from HDR sink
-  uint32_t hdr_eotf = 0;  //!< Electro optical transfer function
-  uint32_t max_luminance = 0;  //!< From Panel's peak luminance
-  uint32_t average_luminance = 0;  //!< From Panel's average luminance
-  uint32_t min_luminance = 0;  //!< From Panel's blackness level
-};
-
-/*! @brief This structure defines configuration for variable properties of a display device.
-
-  @sa DisplayInterface::GetConfig
-  @sa DisplayInterface::SetConfig
-*/
-struct DisplayConfigVariableInfo {
-  uint32_t x_pixels = 0;          //!< Total number of pixels in X-direction on the display panel.
-  uint32_t y_pixels = 0;          //!< Total number of pixels in Y-direction on the display panel.
-  float x_dpi = 0.0f;             //!< Dots per inch in X-direction.
-  float y_dpi = 0.0f;             //!< Dots per inch in Y-direction.
-  uint32_t fps = 0;               //!< Frame rate per second.
-  uint32_t vsync_period_ns = 0;   //!< VSync period in nanoseconds.
-  bool is_yuv = false;            //!< If the display output is in YUV format.
-};
-
-/*! @brief Event data associated with VSync event.
-
-  @sa DisplayEventHandler::VSync
-*/
-struct DisplayEventVSync {
-  int64_t timestamp = 0;    //!< System monotonic clock timestamp in nanoseconds.
-};
-
-/*! @brief The structure defines the user input for detail enhancer module.
-
-  @sa DisplayInterface::SetDetailEnhancerData
-*/
-struct DisplayDetailEnhancerData {
-  uint32_t override_flags = 0;        // flags to specify which data to be set.
-  uint16_t enable = 0;                // Detail enchancer enable
-  int16_t sharpen_level1 = 0;         // Sharpening/smooth strenght for noise
-  int16_t sharpen_level2 = 0;         // Sharpening/smooth strenght for signal
-  uint16_t clip = 0;                  // DE clip shift
-  uint16_t limit = 0;                 // DE limit value
-  uint16_t thr_quiet = 0;             // DE quiet threshold
-  uint16_t thr_dieout = 0;            // DE dieout threshold
-  uint16_t thr_low = 0;               // DE low threshold
-  uint16_t thr_high = 0;              // DE high threshold
-  int32_t sharp_factor = 50;          // sharp_factor specifies sharpness/smoothness level,
-                                      // range -100..100 positive for sharpness and negative for
-                                      // smoothness
-  ContentQuality quality_level = kContentQualityUnknown;
-                                      // Specifies context quality level
-  ScalingFilterConfig filter_config = kFilterEdgeDirected;
-                                      // Y/RGB filter configuration
-};
-
-/*! @brief Display device event handler implemented by the client.
-
-  @details This class declares prototype for display device event handler methods which must be
-  implemented by the client. Display device will use these methods to notify events to the client.
-  Client must post heavy-weight event handling to a separate thread and unblock display manager
-  thread instantly.
-
-  @sa CoreInterface::CreateDisplay
-*/
-class DisplayEventHandler {
- public:
-  /*! @brief Event handler for VSync event.
-
-    @details This event is dispatched on every vertical synchronization. The event is disabled by
-    default.
-
-    @param[in] vsync \link DisplayEventVSync \endlink
-
-    @return \link DisplayError \endlink
-
-    @sa DisplayInterface::GetDisplayState
-    @sa DisplayInterface::SetDisplayState
-  */
-  virtual DisplayError VSync(const DisplayEventVSync &vsync) = 0;
-
-  /*! @brief Event handler for Refresh event.
-
-    @details This event is dispatched to trigger a screen refresh. Client must call Prepare() and
-    Commit() in response to it from a separate thread. There is no data associated with this
-    event.
-
-    @return \link DisplayError \endlink
-
-    @sa DisplayInterface::Prepare
-    @sa DisplayInterface::Commit
-  */
-  virtual DisplayError Refresh() = 0;
-
-  /*! @brief Event handler for CEC messages.
-
-    @details This event is dispatched to send CEC messages to the CEC HAL.
-
-    @param[in] message message to be sent
-
-    @return \link DisplayError \endlink
-  */
-  virtual DisplayError CECMessage(char *message) = 0;
-
-  /*! @brief Event handler for events received by Display HAL. */
-  virtual DisplayError HandleEvent(DisplayEvent event) = 0;
-
- protected:
-  virtual ~DisplayEventHandler() { }
-};
-
-struct PPDisplayAPIPayload;
-struct PPPendingParams;
-
-/*! @brief Display device interface.
-
-  @details This class defines display device interface. It contains methods which client shall use
-  to configure or submit layers for composition on the display device. This interface is created
-  during display device creation and remains valid until destroyed.
-
-  @sa CoreInterface::CreateDisplay
-  @sa CoreInterface::DestroyDisplay
-*/
-class DisplayInterface {
- public:
-  /*! @brief Method to determine hardware capability to compose layers associated with given frame.
-
-    @details Client shall send all layers associated with a frame targeted for current display
-    using this method and check the layers which can be handled completely in display manager.
-
-    Client shall mark composition type for one of the layer as kCompositionGPUTarget; the GPU
-    composed output would be rendered at the specified layer if some of the layers are not handled
-    by SDM.
-
-    Display manager will set each layer as kCompositionGPU or kCompositionSDE upon return. Client
-    shall render all the layers marked as kCompositionGPU using GPU.
-
-    This method can be called multiple times but only last call prevails. This method must be
-    followed by Commit().
-
-    @param[inout] layer_stack \link LayerStack \endlink
-
-    @return \link DisplayError \endlink
-
-    @sa Commit
-  */
-  virtual DisplayError Prepare(LayerStack *layer_stack) = 0;
-
-  /*! @brief Method to commit layers of a frame submitted in a former call to Prepare().
-
-    @details Client shall call this method to submit layers for final composition. The composed
-    output would be displayed on the panel or written in output buffer.
-
-    Client must ensure that layer stack is same as previous call to Prepare.
-
-    This method shall be called only once for each frame.
-
-    In the event of an error as well, this call will cause any fences returned in the previous call
-    to Commit() to eventually become signaled, so the client's wait on fences can be released to
-    prevent deadlocks.
-
-    @param[in] layer_stack \link LayerStack \endlink
-
-    @return \link DisplayError \endlink
-
-    @sa Prepare
-  */
-  virtual DisplayError Commit(LayerStack *layer_stack) = 0;
-
-  /*! @brief Method to flush any pending buffers/fences submitted previously via Commit() call.
-
-    @details Client shall call this method to request the Display manager to release all buffers and
-    respective fences currently in use. This operation may result in a blank display on the panel
-    until a new frame is submitted for composition.
-
-    @return \link DisplayError \endlink
-
-    @sa Prepare
-    @sa Commit
-  */
-  virtual DisplayError Flush() = 0;
-
-  /*! @brief Method to get current state of the display device.
-
-    @param[out] state \link DisplayState \endlink
-
-    @return \link DisplayError \endlink
-
-    @sa SetDisplayState
-  */
-  virtual DisplayError GetDisplayState(DisplayState *state) = 0;
-
-  /*! @brief Method to get number of configurations(variable properties) supported on the display
-    device.
-
-    @param[out] count Number of modes supported; mode index starts with 0.
-
-    @return \link DisplayError \endlink
-  */
-  virtual DisplayError GetNumVariableInfoConfigs(uint32_t *count) = 0;
-
-  /*! @brief Method to get configuration for fixed properties of the display device.
-
-    @param[out] fixed_info \link DisplayConfigFixedInfo \endlink
-
-    @return \link DisplayError \endlink
-  */
-  virtual DisplayError GetConfig(DisplayConfigFixedInfo *fixed_info) = 0;
-
-  /*! @brief Method to get configuration for variable properties of the display device.
-
-    @param[in] index index of the mode
-    @param[out] variable_info \link DisplayConfigVariableInfo \endlink
-
-    @return \link DisplayError \endlink
-  */
-  virtual DisplayError GetConfig(uint32_t index, DisplayConfigVariableInfo *variable_info) = 0;
-
-  /*! @brief Method to get index of active configuration of the display device.
-
-    @param[out] index index of the mode corresponding to variable properties.
-
-    @return \link DisplayError \endlink
-  */
-  virtual DisplayError GetActiveConfig(uint32_t *index) = 0;
-
-  /*! @brief Method to get VSync event state. Default event state is disabled.
-
-    @param[out] enabled vsync state
-
-    @return \link DisplayError \endlink
-  */
-  virtual DisplayError GetVSyncState(bool *enabled) = 0;
-
-  /*! @brief Method to set current state of the display device.
-
-    @param[in] state \link DisplayState \endlink
-    @param[in] pointer to release fence
-
-    @return \link DisplayError \endlink
-
-    @sa SetDisplayState
-  */
-  virtual DisplayError SetDisplayState(DisplayState state, int *release_fence) = 0;
-
-  /*! @brief Method to set active configuration for variable properties of the display device.
-
-    @param[in] variable_info \link DisplayConfigVariableInfo \endlink
-
-    @return \link DisplayError \endlink
-  */
-  virtual DisplayError SetActiveConfig(DisplayConfigVariableInfo *variable_info) = 0;
-
-  /*! @brief Method to set active configuration for variable properties of the display device.
-
-    @param[in] index index of the mode corresponding to variable properties.
-
-    @return \link DisplayError \endlink
-  */
-  virtual DisplayError SetActiveConfig(uint32_t index) = 0;
-
-  /*! @brief Method to set VSync event state. Default event state is disabled.
-
-    @param[out] enabled vsync state
-
-    @return \link DisplayError \endlink
-  */
-  virtual DisplayError SetVSyncState(bool enable) = 0;
-
-  /*! @brief Method to set idle timeout value. Idle fallback is disabled with timeout value 0.
-
-    @param[in] active_ms value in milliseconds.
-
-    @return \link void \endlink
-  */
-  virtual void SetIdleTimeoutMs(uint32_t active_ms) = 0;
-
-  /*! @brief Method to set maximum number of mixer stages for each display.
-
-    @param[in] max_mixer_stages maximum number of mixer stages.
-
-    @return \link DisplayError \endlink
-  */
-  virtual DisplayError SetMaxMixerStages(uint32_t max_mixer_stages) = 0;
-
-  /*! @brief Method to control partial update feature for each display.
-
-    @param[in] enable partial update feature control flag
-    @param[out] pending whether the operation is completed or pending for completion
-
-    @return \link DisplayError \endlink
-  */
-  virtual DisplayError ControlPartialUpdate(bool enable, uint32_t *pending) = 0;
-
-  /*! @brief Method to disable partial update for at least 1 frame.
-    @return \link DisplayError \endlink
-  */
-  virtual DisplayError DisablePartialUpdateOneFrame() = 0;
-
-  /*! @brief Method to set the mode of the primary display.
-
-    @param[in] mode the new display mode.
-
-    @return \link DisplayError \endlink
-  */
-  virtual DisplayError SetDisplayMode(uint32_t mode) = 0;
-
-  /*! @brief Method to get the min and max refresh rate of a display.
-
-    @param[out] min and max refresh rate.
-
-    @return \link DisplayError \endlink
-  */
-  virtual DisplayError GetRefreshRateRange(uint32_t *min_refresh_rate,
-                                           uint32_t *max_refresh_rate) = 0;
-
-  /*! @brief Method to set the refresh rate of a display.
-
-    @param[in] refresh_rate new refresh rate of the display.
-
-    @param[in] final_rate indicates whether refresh rate is final rate or can be changed by sdm
-
-    @return \link DisplayError \endlink
-  */
-  virtual DisplayError SetRefreshRate(uint32_t refresh_rate, bool final_rate) = 0;
-
-  /*! @brief Method to query whether scanning is support for the HDMI display.
-
-    @return \link DisplayError \endlink
-  */
-  virtual bool IsUnderscanSupported() = 0;
-
-  /*! @brief Method to set brightness of the primary display.
-
-    @param[in] level the new backlight level.
-
-    @return \link DisplayError \endlink
-  */
-  virtual DisplayError SetPanelBrightness(int level) = 0;
-
-  /*! @brief Method to notify display about change in min HDCP encryption level.
-
-    @param[in] min_enc_level minimum encryption level value.
-
-    @return \link DisplayError \endlink
-  */
-  virtual DisplayError OnMinHdcpEncryptionLevelChange(uint32_t min_enc_level) = 0;
-
-  /*! @brief Method to route display API requests to color service.
-
-    @param[in] in_payload \link PPDisplayAPIPayload \endlink
-    @param[out] out_payload \link PPDisplayPayload \endlink
-    @param[out] pending_action \link PPPendingParams \endlink
-
-    @return \link DisplayError \endlink
-  */
-  virtual DisplayError ColorSVCRequestRoute(const PPDisplayAPIPayload &in_payload,
-                                            PPDisplayAPIPayload *out_payload,
-                                            PPPendingParams *pending_action) = 0;
-
-  /*! @brief Method to request the number of color modes supported.
-
-    @param[out] mode_count Number of modes
-
-    @return \link DisplayError \endlink
-  */
-  virtual DisplayError GetColorModeCount(uint32_t *mode_count) = 0;
-
-  /*! @brief Method to request the information of supported color modes.
-
-    @param[inout] mode_count Number of updated modes
-    @param[out] vector of mode strings
-
-    @return \link DisplayError \endlink
-  */
-  virtual DisplayError GetColorModes(uint32_t *mode_count,
-                                     std::vector<std::string> *color_modes) = 0;
-
-  /*! @brief Method to request the attributes of color mode.
-
-    @param[in] mode name
-    @param[out] vector of mode attributes
-
-    @return \link DisplayError \endlink
-  */
-  virtual DisplayError GetColorModeAttr(const std::string &color_mode,
-                                        AttrVal *attr_map) = 0;
-
-  /*! @brief Method to set the color mode
-
-    @param[in] mode_name Mode name which needs to be set
-
-    @return \link DisplayError \endlink
-  */
-  virtual DisplayError SetColorMode(const std::string &color_mode) = 0;
-
-  /*! @brief Method to set the color mode by ID. This method is used for debugging only.
-
-  @param[in] mode_name Mode ID which needs to be set
-
-  @return \link DisplayError \endlink
-  */
-  virtual DisplayError SetColorModeById(int32_t color_mode_id) = 0;
-  /*! @brief Method to set the color transform
-
-    @param[in] length Mode name which needs to be set
-    @param[in] color_transform  4x4 Matrix for color transform
-
-    @return \link DisplayError \endlink
-  */
-  virtual DisplayError SetColorTransform(const uint32_t length, const double *color_transform) = 0;
-
-  /*! @brief Method to get the default color mode.
-
-    @param[out] default mode name
-
-    @return \link DisplayError \endlink
-  */
-  virtual DisplayError GetDefaultColorMode(std::string *color_mode) = 0;
-
-  /*! @brief Method to request applying default display mode.
-
-    @return \link DisplayError \endlink
-  */
-  virtual DisplayError ApplyDefaultDisplayMode() = 0;
-
-  /*! @brief Method to set the position of the hw cursor.
-
-    @param[in] x \link x position \endlink
-    @param[in] y \link y position \endlink
-
-    @return \link DisplayError \endlink
-  */
-  virtual DisplayError SetCursorPosition(int x, int y) = 0;
-
-  /*! @brief Method to get the brightness level of the display
-
-    @param[out] level brightness level
-
-    @return \link DisplayError \endlink
-  */
-  virtual DisplayError GetPanelBrightness(int *level) = 0;
-
-  /*! @brief Method to set layer mixer resolution.
-
-    @param[in] width layer mixer width
-    @param[in] height layer mixer height
-
-    @return \link DisplayError \endlink
-  */
-  virtual DisplayError SetMixerResolution(uint32_t width, uint32_t height) = 0;
-
-  /*! @brief Method to get layer mixer resolution.
-
-    @param[out] width layer mixer width
-    @param[out] height layer mixer height
-
-    @return \link DisplayError \endlink
-  */
-  virtual DisplayError GetMixerResolution(uint32_t *width, uint32_t *height) = 0;
-
-  /*! @brief Method to set  frame buffer configuration.
-
-    @param[in] variable_info \link DisplayConfigVariableInfo \endlink
-
-    @return \link DisplayError \endlink
-  */
-  virtual DisplayError SetFrameBufferConfig(const DisplayConfigVariableInfo &variable_info) = 0;
-
-  /*! @brief Method to get frame buffer configuration.
-
-    @param[out] variable_info \link DisplayConfigVariableInfo \endlink
-
-    @return \link DisplayError \endlink
-  */
-  virtual DisplayError GetFrameBufferConfig(DisplayConfigVariableInfo *variable_info) = 0;
-
-  /*! @brief Method to set detail enhancement data.
-
-    @param[in] de_data \link DisplayDetailEnhancerData \endlink
-
-    @return \link DisplayError \endlink
-  */
-  virtual DisplayError SetDetailEnhancerData(const DisplayDetailEnhancerData &de_data) = 0;
-
-  /*! @brief Method to get display port information.
-
-    @param[out] port \link DisplayPort \endlink
-
-    @return \link DisplayError \endlink
-  */
-  virtual DisplayError GetDisplayPort(DisplayPort *port) = 0;
-
-  /*! @brief Method to query whether it is Primrary device.
-
-    @return true if this interface is primary.
-  */
-  virtual bool IsPrimaryDisplay() = 0;
-
-  /*! @brief Method to toggle composition types handling by SDM.
-
-    @details Client shall call this method to request SDM to enable/disable a specific type of
-    layer composition. If client disables a composition type, SDM will not handle any of the layer
-    composition using the disabled method in a draw cycle. On lack of resources to handle all
-    layers using other enabled composition methods, Prepare() will return an error.
-
-    Request to toggle composition type is applied from subsequent draw cycles.
-
-    Default state of all defined composition types is enabled.
-
-    @param[in] composition_type \link LayerComposition \endlink
-    @param[in] enable \link enable composition type \endlink
-
-    @return \link DisplayError \endlink
-
-    @sa Prepare
-  */
-  virtual DisplayError SetCompositionState(LayerComposition composition_type, bool enable) = 0;
-
-  /*! @brief Method to check whether a client target with the given properties
-      can be supported/handled by hardware.
-
-    @param[in] width client target width
-    @param[in] height client target height
-    @param[in] format client target format
-    @param[in] colorMetaData client target colorMetaData
-
-    @return \link DisplayError \endlink
-  */
-  virtual DisplayError GetClientTargetSupport(uint32_t width, uint32_t height,
-                                              LayerBufferFormat format,
-                                              const ColorMetaData &color_metadata) = 0;
-
-  /*
-   * Returns a string consisting of a dump of SDM's display and layer related state
-   * as programmed to driver
-  */
-  virtual std::string Dump() = 0;
-
- protected:
-  virtual ~DisplayInterface() { }
-};
-
-}  // namespace sdm
-
-#endif  // __DISPLAY_INTERFACE_H__
-
diff --git a/sdm/include/core/layer_buffer.h b/sdm/include/core/layer_buffer.h
deleted file mode 100644
index 649dda4..0000000
--- a/sdm/include/core/layer_buffer.h
+++ /dev/null
@@ -1,293 +0,0 @@
-/*
-* Copyright (c) 2014, 2016-2017, The Linux Foundation. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without modification, are permitted
-* provided that the following conditions are met:
-*    * Redistributions of source code must retain the above copyright notice, this list of
-*      conditions and the following disclaimer.
-*    * Redistributions in binary form must reproduce the above copyright notice, this list of
-*      conditions and the following disclaimer in the documentation and/or other materials provided
-*      with the distribution.
-*    * Neither the name of The Linux Foundation nor the names of its contributors may be used to
-*      endorse or promote products derived from this software without specific prior written
-*      permission.
-*
-* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-* NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
-* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
-* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
-* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-/*! @file layer_buffer.h
-  @brief File for layer buffer structure.
-
-*/
-#ifndef __LAYER_BUFFER_H__
-#define __LAYER_BUFFER_H__
-
-#include <stdint.h>
-#include <color_metadata.h>
-#include <utility>
-#include <vector>
-
-#include "sdm_types.h"
-
-namespace sdm {
-
-#define NUM_UBWC_CR_STATS_LAYERS 2
-typedef std::vector<std::pair<int, int>> UbwcCrStatsVector;
-
-/*! @brief This enum represents display layer inverse gamma correction (IGC) types.
-
-  @sa Layer
-*/
-enum LayerIGC {
-  kIGCNotSpecified,       //!< IGC is not specified.
-  kIGCsRGB,               //!< sRGB IGC type.
-};
-
-/*! @brief This enum represents different buffer formats supported by display manager.
-
-  @sa LayerBuffer
-*/
-enum LayerBufferFormat {
-  /* All RGB formats, Any new format will be added towards end of this group to maintain backward
-     compatibility.
-  */
-  kFormatARGB8888,      //!< 8-bits Alpha, Red, Green, Blue interleaved in ARGB order.
-  kFormatRGBA8888,      //!< 8-bits Red, Green, Blue, Alpha interleaved in RGBA order.
-  kFormatBGRA8888,      //!< 8-bits Blue, Green, Red, Alpha interleaved in BGRA order.
-  kFormatXRGB8888,      //!< 8-bits Padding, Red, Green, Blue interleaved in XRGB order. No Alpha.
-  kFormatRGBX8888,      //!< 8-bits Red, Green, Blue, Padding interleaved in RGBX order. No Alpha.
-  kFormatBGRX8888,      //!< 8-bits Blue, Green, Red, Padding interleaved in BGRX order. No Alpha.
-  kFormatRGBA5551,      //!< 5-bits Red, Green, Blue, and 1 bit Alpha interleaved in RGBA order.
-  kFormatRGBA4444,      //!< 4-bits Red, Green, Blue, Alpha interleaved in RGBA order.
-  kFormatRGB888,        //!< 8-bits Red, Green, Blue interleaved in RGB order. No Alpha.
-  kFormatBGR888,        //!< 8-bits Blue, Green, Red interleaved in BGR order. No Alpha.
-  kFormatRGB565,        //!< 5-bit Red, 6-bit Green, 5-bit Blue interleaved in RGB order. No Alpha.
-  kFormatBGR565,        //!< 5-bit Blue, 6-bit Green, 5-bit Red interleaved in BGR order. No Alpha.
-  kFormatRGBA8888Ubwc,  //!< UBWC aligned RGBA8888 format
-  kFormatRGBX8888Ubwc,  //!< UBWC aligned RGBX8888 format
-  kFormatBGR565Ubwc,    //!< UBWC aligned BGR565 format
-  kFormatRGBA1010102,   //!< 10-bits Red, Green, Blue, Alpha interleaved in RGBA order.
-  kFormatARGB2101010,   //!< 10-bits Alpha, Red, Green, Blue interleaved in ARGB order.
-  kFormatRGBX1010102,   //!< 10-bits Red, Green, Blue, Padding interleaved in RGBX order. No Alpha.
-  kFormatXRGB2101010,   //!< 10-bits Padding, Red, Green, Blue interleaved in XRGB order. No Alpha.
-  kFormatBGRA1010102,   //!< 10-bits Blue, Green, Red, Alpha interleaved in BGRA order.
-  kFormatABGR2101010,   //!< 10-bits Alpha, Blue, Green, Red interleaved in ABGR order.
-  kFormatBGRX1010102,   //!< 10-bits Blue, Green, Red, Padding interleaved in BGRX order. No Alpha.
-  kFormatXBGR2101010,   //!< 10-bits Padding, Blue, Green, Red interleaved in XBGR order. No Alpha.
-  kFormatRGBA1010102Ubwc,  //!< UBWC aligned RGBA1010102 format
-  kFormatRGBX1010102Ubwc,  //!< UBWC aligned RGBX1010102 format
-  kFormatRGB101010,     // 10-bits Red, Green, Blue, interleaved in RGB order. No Alpha.
-
-  /* All YUV-Planar formats, Any new format will be added towards end of this group to maintain
-     backward compatibility.
-  */
-  kFormatYCbCr420Planar = 0x100,  //!< Y-plane: y(0), y(1), y(2) ... y(n)
-                                  //!< 2x2 subsampled U-plane: u(0), u(2) ... u(n-1)
-                                  //!< 2x2 subsampled V-plane: v(0), v(2) ... v(n-1)
-
-  kFormatYCrCb420Planar,          //!< Y-plane: y(0), y(1), y(2) ... y(n)
-                                  //!< 2x2 subsampled V-plane: v(0), v(2) ... v(n-1)
-                                  //!< 2x2 subsampled U-plane: u(0), u(2) ... u(n-1)
-
-  kFormatYCrCb420PlanarStride16,  //!< kFormatYCrCb420Planar with stride aligned to 16 bytes
-
-  /* All YUV-Semiplanar formats, Any new format will be added towards end of this group to
-     maintain backward compatibility.
-  */
-  kFormatYCbCr420SemiPlanar = 0x200,  //!< Y-plane: y(0), y(1), y(2) ... y(n)
-                                      //!< 2x2 subsampled interleaved UV-plane:
-                                      //!<    u(0), v(0), u(2), v(2) ... u(n-1), v(n-1)
-                                      //!< aka NV12.
-
-  kFormatYCrCb420SemiPlanar,          //!< Y-plane: y(0), y(1), y(2) ... y(n)
-                                      //!< 2x2 subsampled interleaved VU-plane:
-                                      //!<    v(0), u(0), v(2), u(2) ... v(n-1), u(n-1)
-                                      //!< aka NV21.
-
-  kFormatYCbCr420SemiPlanarVenus,     //!< Y-plane: y(0), y(1), y(2) ... y(n)
-                                      //!< 2x2 subsampled interleaved UV-plane:
-                                      //!<    u(0), v(0), u(2), v(2) ... u(n-1), v(n-1)
-
-  kFormatYCbCr422H1V2SemiPlanar,      //!< Y-plane: y(0), y(1), y(2) ... y(n)
-                                      //!< vertically subsampled interleaved UV-plane:
-                                      //!<    u(0), v(1), u(2), v(3) ... u(n-1), v(n)
-
-  kFormatYCrCb422H1V2SemiPlanar,      //!< Y-plane: y(0), y(1), y(2) ... y(n)
-                                      //!< vertically subsampled interleaved VU-plane:
-                                      //!<    v(0), u(1), v(2), u(3) ... v(n-1), u(n)
-
-  kFormatYCbCr422H2V1SemiPlanar,      //!< Y-plane: y(0), y(1), y(2) ... y(n)
-                                      //!< horizontally subsampled interleaved UV-plane:
-                                      //!<    u(0), v(1), u(2), v(3) ... u(n-1), v(n)
-
-  kFormatYCrCb422H2V1SemiPlanar,      //!< Y-plane: y(0), y(1), y(2) ... y(n)
-                                      //!< horizontally subsampled interleaved VU-plane:
-                                      //!<    v(0), u(1), v(2), u(3) ... v(n-1), u(n)
-
-  kFormatYCbCr420SPVenusUbwc,         //!< UBWC aligned YCbCr420SemiPlanarVenus format
-
-  kFormatYCrCb420SemiPlanarVenus,     //!< Y-plane: y(0), y(1), y(2) ... y(n)
-                                      //!< 2x2 subsampled interleaved UV-plane:
-                                      //!<    v(0), u(0), v(2), u(2) ... v(n-1), u(n-1)
-
-  kFormatYCbCr420P010,                //!< 16 bit Y-plane with 5 MSB bits set to 0:
-                                      //!< y(0), y(1), y(2) ... y(n)
-                                      //!< 2x2 subsampled interleaved 10 bit UV-plane with
-                                      //!< 5 MSB bits set to 0:
-                                      //!<    u(0), v(0), u(2), v(2) ... u(n-1), v(n-1)
-                                      //!< aka P010.
-
-  kFormatYCbCr420TP10Ubwc,            //!< UBWC aligned YCbCr420TP10 format.
-
-  kFormatYCbCr420P010Ubwc,            //!< UBWC aligned YCbCr420P010 format.
-
-  kFormatYCbCr420P010Venus,           //!< Venus aligned YCbCr420P010 format.
-
-  /* All YUV-Packed formats, Any new format will be added towards end of this group to maintain
-     backward compatibility.
-  */
-  kFormatYCbCr422H2V1Packed = 0x300,  //!< Y-plane interleaved with horizontally subsampled U/V by
-                                      //!< factor of 2
-                                      //!<    y(0), u(0), y(1), v(0), y(2), u(2), y(3), v(2)
-                                      //!<    y(n-1), u(n-1), y(n), v(n-1)
-
-  kFormatCbYCrY422H2V1Packed,
-  kFormatInvalid = 0xFFFFFFFF,
-};
-
-
-/*! @brief This enum represents different types of 3D formats supported.
-
-  @sa LayerBufferS3DFormat
-*/
-enum LayerBufferS3DFormat {
-  kS3dFormatNone,            //!< Layer buffer content is not 3D content.
-  kS3dFormatLeftRight,       //!< Left and Right view of a 3D content stitched left and right.
-  kS3dFormatRightLeft,       //!< Right and Left view of a 3D content stitched left and right.
-  kS3dFormatTopBottom,       //!< Left and RightView of a 3D content stitched top and bottom.
-  kS3dFormatFramePacking     //!< Left and right view of 3D content coded in consecutive frames.
-};
-
-/*! @brief This structure defines a color sample plane belonging to a buffer format. RGB buffer
-  formats have 1 plane whereas YUV buffer formats may have upto 4 planes.
-
-  @sa LayerBuffer
-*/
-struct LayerBufferPlane {
-  int fd = -1;           //!< File descriptor referring to the buffer associated with this plane.
-  uint32_t offset = 0;   //!< Offset of the plane in bytes from beginning of the buffer.
-  uint32_t stride = 0;   //!< Stride in bytes i.e. length of a scanline including padding.
-};
-
-/*! @brief This structure defines flags associated with a layer buffer. The 1-bit flag can be set
-  to ON(1) or OFF(0).
-
-  @sa LayerBuffer
-*/
-struct LayerBufferFlags {
-  union {
-    struct {
-      uint32_t secure : 1;          //!< This flag shall be set by client to indicate that the
-                                    //!< buffer need to be handled securely.
-
-      uint32_t video  : 1;          //!< This flag shall be set by client to indicate that the
-                                    //!< buffer is video/ui buffer.
-
-      uint32_t macro_tile : 1;      //!< This flag shall be set by client to indicate that the
-                                    //!< buffer format is macro tiled.
-
-      uint32_t interlace : 1;       //!< This flag shall be set by the client to indicate that
-                                    //!< the buffer has interlaced content.
-
-      uint32_t secure_display : 1;  //!< This flag shall be set by the client to indicate that the
-                                    //!< secure display session is in progress. Secure display
-                                    //!< session can not coexist with non-secure session.
-
-      uint32_t secure_camera : 1;   //!< This flag shall be set by the client to indicate that the
-                                    //!< buffer is associated with secure camera session. A secure
-                                    //!< camera layer can co-exist with non-secure layer(s).
-
-      uint32_t hdr : 1;             //!< This flag shall be set by the client to indicate that the
-                                    //!< the content is HDR.
-    };
-
-    uint32_t flags = 0;             //!< For initialization purpose only.
-                                    //!< Client shall not refer to it directly.
-  };
-};
-
-/*! @brief This structure defines a layer buffer handle which contains raw buffer and its associated
-  properties.
-
-  @sa LayerBuffer
-  @sa LayerStack
-*/
-struct LayerBuffer {
-  uint32_t width = 0;           //!< Aligned width of the Layer that this buffer is for.
-  uint32_t height = 0;          //!< Aligned height of the Layer that this buffer is for.
-  uint32_t unaligned_width = 0;
-                                //!< Unaligned width of the Layer that this buffer is for.
-  uint32_t unaligned_height = 0;
-                                //!< Unaligned height of the Layer that this buffer is for.
-  uint32_t size = 0;            //!< Size of a single buffer (even if multiple clubbed together)
-  LayerBufferFormat format = kFormatRGBA8888;     //!< Format of the buffer content.
-  ColorMetaData color_metadata = {};              //!< CSC + Range + Transfer + Matrix + HDR Info
-  LayerIGC igc = kIGCNotSpecified;                //!< IGC that will be applied on this layer.
-  LayerBufferPlane planes[4] = {};
-                                //!< Array of planes that this buffer contains. RGB buffer formats
-                                //!< have 1 plane whereas YUV buffer formats may have upto 4 planes
-                                //!< Total number of planes for the buffer will be interpreted based
-                                //!< on the buffer format specified.
-
-  int acquire_fence_fd = -1;    //!< File descriptor referring to a sync fence object which will be
-                                //!< signaled when buffer can be read/write by display manager.
-                                //!< This fence object is set by the client during Commit(). For
-                                //!< input buffers client shall signal this fence when buffer
-                                //!< content is available and can be read by display manager. For
-                                //!< output buffers, client shall signal fence when buffer is ready
-                                //!< to be written by display manager.
-
-                                //!< This field is used only during Commit() and shall be set to -1
-                                //!< by the client when buffer is already available for read/write.
-
-  int release_fence_fd = -1;    //!< File descriptor referring to a sync fence object which will be
-                                //!< signaled when buffer has been read/written by display manager.
-                                //!< This fence object is set by display manager during Commit().
-                                //!< For input buffers display manager will signal this fence when
-                                //!< buffer has been consumed. For output buffers, display manager
-                                //!< will signal this fence when buffer is produced.
-
-                                //!< This field is used only during Commit() and will be set to -1
-                                //!< by display manager when buffer is already available for
-                                //!< read/write.
-
-  LayerBufferFlags flags;       //!< Flags associated with this buffer.
-
-  LayerBufferS3DFormat s3d_format = kS3dFormatNone;
-                                //!< Represents the format of the buffer content in 3D. This field
-                                //!< could be modified by both client and SDM.
-  uint64_t buffer_id __attribute__((aligned(8))) = 0;
-                                //!< Specifies the buffer id.
-  UbwcCrStatsVector  ubwc_crstats[NUM_UBWC_CR_STATS_LAYERS] = {};
-                                //! < UBWC Compression ratio,stats. Stored as a vector of pair of
-                                //! of (tile size, #of tiles)
-};
-
-// This enum represents buffer layout types.
-enum BufferLayout {
-  kLinear,    //!< Linear data
-  kUBWC,      //!< UBWC aligned data
-  kTPTiled    //!< Tightly Packed data
-};
-
-}  // namespace sdm
-
-#endif  // __LAYER_BUFFER_H__
-
diff --git a/sdm/include/core/layer_stack.h b/sdm/include/core/layer_stack.h
deleted file mode 100644
index 3dd1c6f..0000000
--- a/sdm/include/core/layer_stack.h
+++ /dev/null
@@ -1,414 +0,0 @@
-/*
-* Copyright (c) 2014 - 2017, The Linux Foundation. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without modification, are permitted
-* provided that the following conditions are met:
-*    * Redistributions of source code must retain the above copyright notice, this list of
-*      conditions and the following disclaimer.
-*    * Redistributions in binary form must reproduce the above copyright notice, this list of
-*      conditions and the following disclaimer in the documentation and/or other materials provided
-*      with the distribution.
-*    * Neither the name of The Linux Foundation nor the names of its contributors may be used to
-*      endorse or promote products derived from this software without specific prior written
-*      permission.
-*
-* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-* NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
-* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
-* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
-* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-/*! @file layer_stack.h
-  @brief File for display layer stack structure which represents a drawing buffer.
-
-  @details Display layer is a drawing buffer object which will be blended with other drawing buffers
-  under blending rules.
-*/
-#ifndef __LAYER_STACK_H__
-#define __LAYER_STACK_H__
-
-#include <stdint.h>
-#include <utils/constants.h>
-
-#include <vector>
-#include <utility>
-
-#include "layer_buffer.h"
-#include "sdm_types.h"
-
-namespace sdm {
-
-/*! @brief This enum represents display layer blending types.
-
-  @sa Layer
-*/
-enum LayerBlending {
-  kBlendingPremultiplied,   //!< Pixel color is expressed using premultiplied alpha in RGBA tuples.
-                            //!< If plane alpha is less than 0xFF, apply modulation as well.
-                            //!<   pixel.rgb = src.rgb + dest.rgb x (1 - src.a)
-
-  kBlendingOpaque,          //!< Pixel color is expressed using straight alpha in color tuples. It
-                            //!< is constant blend operation. The layer would appear opaque if plane
-                            //!< alpha is 0xFF.
-
-  kBlendingCoverage,        //!< Pixel color is expressed using straight alpha in color tuples. If
-                            //!< plane alpha is less than 0xff, apply modulation as well.
-                            //!<   pixel.rgb = src.rgb x src.a + dest.rgb x (1 - src.a)
-};
-
-/*! @brief This enum represents display layer composition types.
-
-  @sa Layer
-*/
-enum LayerComposition {
-  /* ==== List of composition types set by SDM === */
-  /* These composition types represent SDM composition decision for the layers which need to
-     be blended. Composition types are set during Prepare() by SDM.
-     Client can set default composition type to any of the below before calling into Prepare(),
-     however client's input value is ignored and does not play any role in composition decision.
-  */
-  kCompositionGPU,          //!< This layer will be drawn onto the target buffer by GPU. Display
-                            //!< device will mark the layer for GPU composition if it can not
-                            //!< handle composition for it.
-                            //!< This composition type is used only if GPUTarget layer is provided
-                            //!< in a composition cycle.
-
-  kCompositionGPUS3D,       //!< This layer will be drawn onto the target buffer in s3d mode by GPU.
-                            //!< Display device will mark the layer for GPU composition if it can
-                            //!< not handle composition for it.
-                            //!< This composition type is used only if GPUTarget layer is provided
-                            //!< in a composition cycle.
-
-  kCompositionSDE,          //!< This layer will be composed by SDE. It must not be composed by
-                            //!< GPU or Blit.
-
-  kCompositionCursor,       // This cursor layer can receive async position updates irrespective of
-                            // dedicated h/w cursor usage. It must not be composed by GPU or Blit
-
-  kCompositionHybrid,       //!< This layer will be drawn by a blit engine and SDE together.
-                            //!< Display device will split the layer, update the blit rectangle
-                            //!< that need to be composed by a blit engine and update original
-                            //!< source rectangle that will be composed by SDE.
-                            //!< This composition type is used only if GPUTarget and BlitTarget
-                            //!< layers are provided in a composition cycle.
-
-  kCompositionBlit,         //!< This layer will be composed using Blit Engine.
-                            //!< This composition type is used only if BlitTarget layer is provided
-                            //!< in a composition cycle.
-
-  /* === List of composition types set by Client === */
-  /* These composition types represent target buffer layers onto which GPU or Blit will draw if SDM
-     decide to have some or all layers drawn by respective composition engine.
-     Client must provide a target buffer layer, if respective composition type is not disabled by
-     an explicit call to SetCompositionState() method. If a composition type is not disabled,
-     providing a target buffer layer is optional. If SDM is unable to handle layers without support
-     of such a composition engine, Prepare() call will return failure.
-  */
-  kCompositionGPUTarget,    //!< This layer will hold result of composition for layers marked for
-                            //!< GPU composition.
-                            //!< If display device does not set any layer for GPU composition then
-                            //!< this layer would be ignored. Else, this layer will be composed
-                            //!< with other layers marked for SDE composition by SDE.
-                            //!< Only one layer shall be marked as target buffer by the caller.
-                            //!< GPU target layer shall be placed after all application layers
-                            //!< in the layer stack.
-
-  kCompositionBlitTarget,   //!< This layer will hold result of composition for blit rectangles
-                            //!< from the layers marked for hybrid composition. Nth blit rectangle
-                            //!< in a layer shall be composed onto Nth blit target.
-                            //!< If display device does not set any layer for hybrid composition
-                            //!< then this would be ignored.
-                            //!< Blit target layers shall be placed after GPUTarget in the layer
-                            //!< stack.
-};
-
-/*! @brief This structure defines rotation and flip values for a display layer.
-
-  @sa Layer
-*/
-struct LayerTransform {
-  float rotation = 0.0f;  //!< Left most pixel coordinate.
-  bool flip_horizontal = false;  //!< Mirror reversal of the layer across a horizontal axis.
-  bool flip_vertical = false;  //!< Mirror reversal of the layer across a vertical axis.
-
-  bool operator==(const LayerTransform& transform) const {
-    return (rotation == transform.rotation && flip_horizontal == transform.flip_horizontal &&
-            flip_vertical == transform.flip_vertical);
-  }
-
-  bool operator!=(const LayerTransform& transform) const {
-    return !operator==(transform);
-  }
-};
-
-/*! @brief This structure defines flags associated with a layer. The 1-bit flag can be set to ON(1)
-  or OFF(0).
-
-  @sa LayerBuffer
-*/
-struct LayerFlags {
-  union {
-    struct {
-      uint32_t skip : 1;      //!< This flag shall be set by client to indicate that this layer
-                              //!< will be handled by GPU. Display Device will not consider it
-                              //!< for composition.
-
-      uint32_t updating : 1;  //!< This flag shall be set by client to indicate that this is
-                              //!< updating non-updating. so strategy manager will mark them for
-                              //!< SDE/GPU composition respectively when the layer stack qualifies
-                              //!< for cache based composition.
-
-      uint32_t solid_fill : 1;
-                              //!< This flag shall be set by client to indicate that this layer
-                              //!< is for solid fill without input buffer. Display Device will
-                              //!< use SDE HW feature to achieve it.
-
-      uint32_t cursor : 1;    //!< This flag shall be set by client to indicate that this layer
-                              //!< is a cursor
-                              //!< Display Device may handle this layer using HWCursor
-
-      uint32_t single_buffer : 1;  //!< This flag shall be set by client to indicate that the layer
-                                   //!< uses only a single buffer that will not be swapped out
-    };
-
-    uint32_t flags = 0;       //!< For initialization purpose only.
-                              //!< Client shall not refer it directly.
-  };
-};
-
-/*! @brief This structure defines flags associated with the layer requests. The 1-bit flag can be
-    set to ON(1) or OFF(0).
-
-  @sa Layer
-*/
-struct LayerRequestFlags {
-  union {
-    struct {
-      uint32_t tone_map : 1;  //!< This flag will be set by SDM when the layer needs tone map
-      uint32_t secure: 1;  //!< This flag will be set by SDM when the layer must be secure
-      uint32_t flip_buffer: 1;  //!< This flag will be set by SDM when the layer needs FBT flip
-    };
-    uint32_t request_flags = 0;  //!< For initialization purpose only.
-                                 //!< Shall not be refered directly.
-  };
-};
-
-/*! @brief This structure defines LayerRequest.
-   Includes width/height/format of the LayerRequest.
-
-   SDM shall set the properties of LayerRequest to be used by the client
-
-  @sa LayerRequest
-*/
-struct LayerRequest {
-  LayerRequestFlags flags;  // Flags associated with this request
-  LayerBufferFormat format = kFormatRGBA8888;  // Requested format
-  uint32_t width = 0;  // Requested unaligned width.
-  uint32_t height = 0;  // Requested unalighed height
-};
-
-/*! @brief This structure defines flags associated with a layer stack. The 1-bit flag can be set to
-  ON(1) or OFF(0).
-
-  @sa LayerBuffer
-*/
-struct LayerStackFlags {
-  union {
-    struct {
-      uint32_t geometry_changed : 1;  //!< This flag shall be set by client to indicate that the
-                                      //!< layer set passed to Prepare() has changed by more than
-                                      //!< just the buffer handles and acquire fences.
-
-      uint32_t skip_present : 1;      //!< This flag will be set to true, if the current layer
-                                      //!< stack contains skip layers.
-
-      uint32_t video_present : 1;     //!< This flag will be set to true, if current layer stack
-                                      //!< contains video.
-
-      uint32_t secure_present : 1;    //!< This flag will be set to true, if the current layer
-                                      //!< stack contains secure layers.
-
-      uint32_t animating : 1;         //!< This flag shall be set by client to indicate that the
-                                      //!<  current frame is animating.i
-
-      uint32_t attributes_changed : 1;
-                                      //!< This flag shall be set by client to indicate that the
-                                      //!< current frame has some properties changed and
-                                      //!< needs re-config.
-
-      uint32_t cursor_present : 1;    //!< This flag will be set to true if the current layer
-                                      //!< stack contains cursor layer.
-
-      uint32_t single_buffered_layer_present : 1;    //!< Set if stack has single buffered layer
-
-      uint32_t s3d_mode_present : 1;  //!< This flag will be set to true, if the current layer
-                                      //!< stack contains s3d layer, and the layer stack can enter
-                                      //!< s3d mode.
-
-      uint32_t post_processed_output : 1;  // If output_buffer should contain post processed output
-                                           // This applies only to primary displays currently
-
-      uint32_t hdr_present : 1;  //!< Set if stack has HDR content
-    };
-
-    uint32_t flags = 0;               //!< For initialization purpose only.
-                                      //!< Client shall not refer it directly.
-  };
-};
-
-/*! @brief This structure defines a rectanglular area inside a display layer.
-
-  @sa LayerRectArray
-*/
-struct LayerRect {
-  float left   = 0.0f;   //!< Left-most pixel coordinate.
-  float top    = 0.0f;   //!< Top-most pixel coordinate.
-  float right  = 0.0f;   //!< Right-most pixel coordinate.
-  float bottom = 0.0f;   //!< Bottom-most pixel coordinate.
-
-  LayerRect() = default;
-
-  LayerRect(float l, float t, float r, float b) : left(l), top(t), right(r), bottom(b) { }
-
-  bool operator==(const LayerRect& rect) const {
-    return left == rect.left && right == rect.right && top == rect.top && bottom == rect.bottom;
-  }
-
-  bool operator!=(const LayerRect& rect) const {
-    return !operator==(rect);
-  }
-};
-
-/*! @brief This structure defines an array of display layer rectangles.
-
-  @sa LayerRect
-*/
-struct LayerRectArray {
-  LayerRect *rect = NULL;  //!< Pointer to first element of array.
-  uint32_t count = 0;      //!< Number of elements in the array.
-};
-
-/*! @brief This structure defines solidfill structure.
-
-  @sa LayerSolidFill
-*/
-struct LayerSolidFill {
-  uint32_t bit_depth = 0;  //!< Bit depth of solid fill colors
-  uint32_t red = 0;        //!< Red value
-  uint32_t green = 0;      //!< Green value
-  uint32_t blue = 0;       //!< Blue value
-  uint32_t alpha = 0;      //!< Alpha value
-};
-
-/*! @brief This structure defines display layer object which contains layer properties and a drawing
-  buffer.
-
-  @sa LayerArray
-*/
-struct Layer {
-  LayerBuffer input_buffer = {};                   //!< Buffer to be composed.
-                                                   //!< If this remains unchanged between two
-                                                   //!< consecutive Prepare() calls and
-                                                   //!< geometry_changed flag is not set for the
-                                                   //!< second call, then the display device will
-                                                   //!< assume that buffer content has not
-                                                   //!< changed.
-
-  LayerComposition composition = kCompositionGPU;  //!< Composition type which can be set by either
-                                                   //!< the client or the display device. This value
-                                                   //!< should be preserved between Prepare() and
-                                                   //!< Commit() calls.
-
-  LayerRect src_rect = {};                         //!< Rectangular area of the layer buffer to
-                                                   //!< consider for composition.
-
-  LayerRect dst_rect = {};                         //!< The target position where the frame will be
-                                                   //!< displayed. Cropping rectangle is scaled to
-                                                   //!< fit into this rectangle. The origin is the
-                                                   //!< top-left corner of the screen.
-
-  std::vector<LayerRect> visible_regions = {};     //!< Visible rectangular areas in screen space.
-                                                   //!< The visible region includes areas overlapped
-                                                   //!< by a translucent layer.
-
-  std::vector<LayerRect> dirty_regions = {};       //!< Rectangular areas in the current frames
-                                                   //!< that have changed in comparison to
-                                                   //!< previous frame.
-
-  std::vector<LayerRect> blit_regions = {};        //!< Rectangular areas of this layer which need
-                                                   //!< to be composed to blit target. Display
-                                                   //!< device will update blit rectangles if a
-                                                   //!< layer composition is set as hybrid. Nth blit
-                                                   //!< rectangle shall be composed onto Nth blit
-                                                   //!< target.
-
-  LayerBlending blending = kBlendingPremultiplied;  //!< Blending operation which need to be
-                                                    //!< applied on the layer buffer during
-                                                    //!< composition.
-
-  LayerTransform transform = {};                   //!< Rotation/Flip operations which need to be
-                                                   //!< applied to the layer buffer during
-                                                   //!< composition.
-
-  uint8_t plane_alpha = 0xff;                      //!< Alpha value applied to the whole layer.
-                                                   //!< Value of each pixel is computed as:
-                                                   //!<    if(kBlendingPremultiplied) {
-                                                   //!<      pixel.RGB = pixel.RGB * planeAlpha/255
-                                                   //!<    }
-                                                   //!<    pixel.a = pixel.a * planeAlpha
-
-  uint32_t frame_rate = 0;                         //!< Rate at which frames are being updated for
-                                                   //!< this layer.
-
-  uint32_t solid_fill_color = 0;                   //!< TODO: Remove this field when fb support
-                                                   //!  is deprecated.
-                                                   //!< Solid color used to fill the layer when
-                                                   //!< no content is associated with the layer.
-
-  LayerFlags flags;                                //!< Flags associated with this layer.
-
-  LayerRequest request = {};                       //!< o/p - request on this Layer by SDM.
-
-  Lut3d lut_3d = {};                               //!< o/p - Populated by SDM when tone mapping is
-                                                   //!< needed on this layer.
-  LayerSolidFill solid_fill_info = {};             //!< solid fill info along with depth.
-};
-
-/*! @brief This structure defines a layer stack that contains layers which need to be composed and
-  rendered onto the target.
-
-  @sa DisplayInterface::Prepare
-  @sa DisplayInterface::Commit
-*/
-
-typedef std::pair<ColorPrimaries, GammaTransfer> PrimariesTransfer;
-
-struct LayerStack {
-  std::vector<Layer *> layers = {};    //!< Vector of layer pointers.
-
-  int retire_fence_fd = -1;            //!< File descriptor referring to a sync fence object which
-                                       //!< will be signaled when this composited frame has been
-                                       //!< replaced on screen by a subsequent frame on a physical
-                                       //!< display. The fence object is created and returned during
-                                       //!< Commit(). Client shall close the returned file
-                                       //!< descriptor.
-                                       //!< NOTE: This field applies to a physical display only.
-
-  LayerBuffer *output_buffer = NULL;   //!< Pointer to the buffer where composed buffer would be
-                                       //!< rendered for virtual displays.
-                                       //!< NOTE: This field applies to a virtual display only.
-
-  LayerStackFlags flags;               //!< Flags associated with this layer set.
-
-  PrimariesTransfer blend_cs = {ColorPrimaries_BT709_5, Transfer_sRGB};
-                                       //!< o/p - Blending color space updated by SDM
-};
-
-}  // namespace sdm
-
-#endif  // __LAYER_STACK_H__
-
diff --git a/sdm/include/core/sdm_types.h b/sdm/include/core/sdm_types.h
deleted file mode 100644
index b624049..0000000
--- a/sdm/include/core/sdm_types.h
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
-* Copyright (c) 2014 - 2018, The Linux Foundation. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without
-* modification, are permitted provided that the following conditions are
-* met:
-*     * Redistributions of source code must retain the above copyright
-*       notice, this list of conditions and the following disclaimer.
-*     * Redistributions in binary form must reproduce the above
-*       copyright notice, this list of conditions and the following
-*       disclaimer in the documentation and/or other materials provided
-*       with the distribution.
-*     * Neither the name of The Linux Foundation nor the names of its
-*       contributors may be used to endorse or promote products derived
-*       from this software without specific prior written permission.
-*
-* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
-* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
-* ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
-* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
-* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-/*! @file sdm_types.h
-  @brief This file contains miscellaneous data types used across display interfaces.
-*/
-#ifndef __SDM_TYPES_H__
-#define __SDM_TYPES_H__
-
-namespace sdm {
-
-/*! @brief This enum represents different error codes that display interfaces may return.
-*/
-enum DisplayError {
-  kErrorNone,             //!< Call executed successfully.
-  kErrorUndefined,        //!< An unspecified error has occured.
-  kErrorNotSupported,     //!< Requested operation is not supported.
-  kErrorPermission,       //!< Operation is not permitted in current state.
-  kErrorVersion,          //!< Client is using advanced version of interfaces and calling into an
-                          //!< older version of display library.
-  kErrorDataAlignment,    //!< Client data structures are not aligned on naturual boundaries.
-  kErrorInstructionSet,   //!< 32-bit client is calling into 64-bit library or vice versa.
-  kErrorParameters,       //!< Invalid parameters passed to a method.
-  kErrorFileDescriptor,   //!< Invalid file descriptor.
-  kErrorMemory,           //!< System is running low on memory.
-  kErrorResources,        //!< Not enough hardware resources available to execute call.
-  kErrorHardware,         //!< A hardware error has occured.
-  kErrorTimeOut,          //!< The operation has timed out to prevent client from waiting forever.
-  kErrorShutDown,         //!< Driver is processing shutdown sequence
-  kErrorPerfValidation,   //!< Bandwidth or Clock requirement validation failure.
-  kErrorNoAppLayers,      //!< No App layer(s) in the draw cycle.
-  kErrorRotatorValidation,  //!< Rotator configuration validation failure.
-  kErrorNotValidated,     //!< Draw cycle has not been validated.
-  kErrorCriticalResource,   //!< Critical resource allocation has failed.
-};
-
-/*! @brief This structure is defined for client and library compatibility check purpose only. This
-  structure is used in SDM_VERSION_TAG definition only. Client should not refer it directly for
-  any purpose.
-*/
-struct SDMCompatibility {
-  char c1;
-  int i1;
-  char c2;
-  int i2;
-};
-
-/*! @brief This enum represents different modules/logical unit tags that a log message may
-  be associated with. Client may use this to filter messages for dynamic logging.
-
-*/
-enum DebugTag {
-  kTagNone,             //!< Debug log is not tagged. This type of logs should always be printed.
-  kTagResources,        //!< Debug log is tagged for resource management.
-  kTagStrategy,         //!< Debug log is tagged for strategy decisions.
-  kTagCompManager,      //!< Debug log is tagged for composition manager.
-  kTagDriverConfig,     //!< Debug log is tagged for driver config.
-  kTagRotator,          //!< Debug log is tagged for rotator.
-  kTagScalar,           //!< Debug log is tagged for Scalar Helper.
-  kTagQDCM,             //!< Debug log is tagged for display QDCM color managing.
-  kTagQOSClient,        //!< Debug log is tagged for Qos client.
-  kTagDisplay,          //!< Debug log is tagged for display core logs.
-  kTagClient,           //!< Debug log is tagged for SDM client.
-};
-
-}  // namespace sdm
-
-#endif  // __SDM_TYPES_H__
-
diff --git a/sdm/include/core/socket_handler.h b/sdm/include/core/socket_handler.h
deleted file mode 100644
index e7fe00e..0000000
--- a/sdm/include/core/socket_handler.h
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
-* Copyright (c) 2016, The Linux Foundation. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without
-* modification, are permitted provided that the following conditions are
-* met:
-*  * Redistributions of source code must retain the above copyright
-*    notice, this list of conditions and the following disclaimer.
-*  * Redistributions in binary form must reproduce the above
-*    copyright notice, this list of conditions and the following
-*    disclaimer in the documentation and/or other materials provided
-*    with the distribution.
-*  * Neither the name of The Linux Foundation nor the names of its
-*    contributors may be used to endorse or promote products derived
-*    from this software without specific prior written permission.
-*
-* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
-* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
-* ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
-* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
-* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-/*! @file socket_handler.h
-  @brief Interface file for platform specific Socket Handler.
-
-  @details SDM will use this interface to get the platform specific Socket fd.
-*/
-
-#ifndef __SOCKET_HANDLER_H__
-#define __SOCKET_HANDLER_H__
-
-namespace sdm {
-
-/*! @brief This enum represents Socket types, for which SDM can request the fd.
-
-*/
-enum SocketType {
-  kDpps,       //!< Socket for Dpps
-};
-
-/*! @brief Socket handler implemented by the client
-
-  @details This class declares prototype for SocketHandler methods which must be
-  implemented by client. SDM will use these methods to get the platform specific Socket fd.
-
-  @sa CoreInterface::CreateCore
-*/
-class SocketHandler {
- public:
-  /*! @brief Method to get the platform specific Socket fd for a given socket type.
-
-    @details This method returns the platform specific Socket fd for a given socket type.
-    It is the responsibility of the caller to close the file descriptor.
-
-    @param[in] socket_type
-
-    @return \link int \endlink
-  */
-
-  virtual int GetSocketFd(SocketType socket_type) = 0;
-
- protected:
-  virtual ~SocketHandler() { }
-};
-
-}  // namespace sdm
-
-#endif  // __SOCKET_HANDLER_H__
diff --git a/sdm/include/private/color_interface.h b/sdm/include/private/color_interface.h
deleted file mode 100644
index 9802e1d..0000000
--- a/sdm/include/private/color_interface.h
+++ /dev/null
@@ -1,106 +0,0 @@
-/* Copyright (c) 2015-2018, The Linux Foundataion. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without
-* modification, are permitted provided that the following conditions are
-* met:
-*     * Redistributions of source code must retain the above copyright
-*       notice, this list of conditions and the following disclaimer.
-*     * Redistributions in binary form must reproduce the above
-*       copyright notice, this list of conditions and the following
-*       disclaimer in the documentation and/or other materials provided
-*       with the distribution.
-*     * Neither the name of The Linux Foundation nor the names of its
-*       contributors may be used to endorse or promote products derived
-*       from this software without specific prior written permission.
-*
-* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
-* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
-* ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
-* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
-* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*
-*/
-
-#ifndef __COLOR_INTERFACE_H__
-#define __COLOR_INTERFACE_H__
-
-#include <string>
-#include "core/sdm_types.h"
-#include "color_params.h"
-
-namespace sdm {
-
-#define COLORMGR_LIBRARY_NAME "libsdm-color.so"
-#define CREATE_COLOR_INTERFACE_NAME "CreateColorInterface"
-#define DESTROY_COLOR_INTERFACE_NAME "DestroyColorInterface"
-#define COLOR_REVISION_MAJOR (1)
-#define COLOR_REVISION_MINOR (0)
-
-#define COLOR_VERSION_TAG ((uint16_t)((COLOR_REVISION_MAJOR << 8) | COLOR_REVISION_MINOR))
-
-class ColorInterface;
-
-typedef DisplayError (*CreateColorInterface)(uint16_t version, DisplayType type,
-                                             const PPHWAttributes &attributes,
-                                             ColorInterface **interface);
-
-typedef DisplayError (*DestroyColorInterface)(DisplayType type);
-
-class ColorModeInterface {
- public:
-  virtual DisplayError ColorIntfGetActiveColorParam(uint32_t hint, uint32_t display_id,
-                                                    void* data) = 0;
-  virtual DisplayError ColorIntfSetActiveColorParam(uint32_t hint, uint32_t display_id,
-                                                    void* data) = 0;
-  virtual DisplayError ColorIntfSetHdrInterface(void *hdr_intf) = 0;
-
- protected:
-  virtual ~ColorModeInterface() {}
-};
-
-extern "C" ColorModeInterface* GetColorModeInterface(DisplayType type);
-extern "C" void ReleaseColorModeInterface(DisplayType type);
-
-class ColorInterface {
- public:
-  virtual DisplayError ColorSVCRequestRoute(const PPDisplayAPIPayload &in_payload,
-                                            PPDisplayAPIPayload *out_payload,
-                                            PPFeaturesConfig *out_features,
-                                            PPPendingParams *pending_action) = 0;
-
-  virtual DisplayError ApplyDefaultDisplayMode(PPFeaturesConfig *out_features) = 0;
-
-  virtual DisplayError ColorIntfSetColorTransform(PPFeaturesConfig *out_features,
-                                                uint32_t disp_id, uint32_t length,
-                                                const double *trans_data) = 0;
-
-  virtual DisplayError ColorIntfSetDisplayMode(PPFeaturesConfig *out_features,
-                                             uint32_t disp_id, int32_t mode_id) = 0;
-
-  virtual DisplayError ColorIntfGetNumDisplayModes(PPFeaturesConfig *out_features,
-                                                 uint32_t disp_id, uint32_t *mode_cnt) = 0;
-
-  virtual DisplayError ColorIntfEnumerateDisplayModes(PPFeaturesConfig *out_features,
-                                                uint32_t disp_id, SDEDisplayMode *modes,
-                                                uint32_t *mode_cnt) = 0;
-  virtual DisplayError ColorIntfGetModeInfo(PPFeaturesConfig *out_features,
-                                            uint32_t disp_id, int32_t mode_id,
-                                            AttrVal *query) = 0;
-  virtual DisplayError ColorIntfGetDefaultModeID(PPFeaturesConfig *out_features,
-                                                 uint32_t disp_id, int32_t *mode_id) = 0;
-  virtual DisplayError ColorIntfGetActiveMode(PPFeaturesConfig *out_features,
-                                              int32_t disp_id, std::string *mode) = 0;
-
- protected:
-  virtual ~ColorInterface() {}
-};
-
-}  // namespace sdm
-
-#endif  // __COLOR_INTERFACE_H__
diff --git a/sdm/include/private/color_params.h b/sdm/include/private/color_params.h
deleted file mode 100644
index b71266c..0000000
--- a/sdm/include/private/color_params.h
+++ /dev/null
@@ -1,652 +0,0 @@
-/* Copyright (c) 2015-2018, The Linux Foundataion. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without
-* modification, are permitted provided that the following conditions are
-* met:
-*     * Redistributions of source code must retain the above copyright
-*       notice, this list of conditions and the following disclaimer.
-*     * Redistributions in binary form must reproduce the above
-*       copyright notice, this list of conditions and the following
-*       disclaimer in the documentation and/or other materials provided
-*       with the distribution.
-*     * Neither the name of The Linux Foundation nor the names of its
-*       contributors may be used to endorse or promote products derived
-*       from this software without specific prior written permission.
-*
-* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
-* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
-* ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
-* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
-* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*
-*/
-
-#ifndef __COLOR_PARAMS_H__
-#define __COLOR_PARAMS_H__
-
-#include <stdio.h>
-#include <string.h>
-#include <utils/locker.h>
-#include <utils/constants.h>
-#include <core/sdm_types.h>
-#include <core/display_interface.h>
-
-#include <string>
-
-#include "hw_info_types.h"
-
-namespace sdm {
-
-// Bitmap Pending action to indicate to the caller what's pending to be taken care of.
-enum PendingAction {
-  kInvalidating = BITMAP(0),
-  kApplySolidFill = BITMAP(1),
-  kDisableSolidFill = BITMAP(2),
-  kEnterQDCMMode = BITMAP(3),
-  kExitQDCMMode = BITMAP(4),
-  kSetPanelBrightness = BITMAP(5),
-  kEnableFrameCapture = BITMAP(6),
-  kDisableFrameCapture = BITMAP(7),
-  kConfigureDetailedEnhancer = BITMAP(8),
-  kModeSet = BITMAP(10),
-  kGetDetailedEnhancerData = BITMAP(21),
-  kNoAction = BITMAP(31),
-};
-
-static const uint32_t kOpsEnable = BITMAP(0);
-static const uint32_t kOpsRead = BITMAP(1);
-static const uint32_t kOpsWrite = BITMAP(2);
-static const uint32_t kOpsDisable = BITMAP(3);
-
-static const uint32_t kOpsGc8BitRoundEnable = BITMAP(4);
-
-static const uint32_t kPaHueEnable = BITMAP(4);
-static const uint32_t kPaSatEnable = BITMAP(5);
-static const uint32_t kPaValEnable = BITMAP(6);
-static const uint32_t kPaContEnable = BITMAP(7);
-
-static const uint32_t kPaSixZoneEnable = BITMAP(8);
-static const uint32_t kPaSkinEnable = BITMAP(9);
-static const uint32_t kPaSkyEnable = BITMAP(10);
-static const uint32_t kPaFoliageEnable = BITMAP(11);
-
-static const uint32_t kLeftSplitMode = BITMAP(28);   // 0x10000000
-static const uint32_t kRightSplitMode = BITMAP(29);  // 0x20000000
-
-static const int32_t kInvalidModeId = -1;
-
-static const std::string kDynamicRangeAttribute = "DynamicRange";
-static const std::string kColorGamutAttribute = "ColorGamut";
-static const std::string kPictureQualityAttribute = "PictureQuality";
-
-static const std::string kHdr = "hdr";
-static const std::string kSdr = "sdr";
-
-static const std::string kNative = "native";
-static const std::string kDcip3 = "dcip3";
-static const std::string kSrgb = "srgb";
-static const std::string kDisplayP3 = "display_p3";
-
-static const std::string kVivid = "vivid";
-static const std::string kSharp = "sharp";
-static const std::string kStandard = "standard";
-static const std::string kAmazon = "amazon";
-static const std::string kNetflix = "netflix";
-
-// Enum to identify type of dynamic range of color mode.
-enum DynamicRangeType {
-  kSdrType,
-  kHdrType,
-};
-
-// ENUM to identify different Postprocessing feature block to program.
-// Note: For each new entry added here, also need update hw_interface::GetPPFeaturesVersion<>
-// AND HWPrimary::SetPPFeatures<>.
-enum PPGlobalColorFeatureID {
-  kGlobalColorFeaturePcc,
-  kGlobalColorFeatureIgc,
-  kGlobalColorFeaturePgc,
-  kMixerColorFeatureGc,
-  kGlobalColorFeaturePaV2,
-  kGlobalColorFeatureDither,
-  kGlobalColorFeatureGamut,
-  kGlobalColorFeaturePADither,
-  kMaxNumPPFeatures,
-};
-
-struct PPPendingParams {
-  int32_t action = kNoAction;
-  void *params = NULL;
-};
-
-struct PPColorInfo {
-  uint32_t r_bitdepth = 0;
-  uint32_t r = 0;
-  uint32_t g_bitdepth = 0;
-  uint32_t g = 0;
-  uint32_t b_bitdepth = 0;
-  uint32_t b = 0;
-};
-
-struct PPColorFillParams {
-  uint32_t flags = 0;
-  struct {
-    uint32_t width = 0;
-    uint32_t height = 0;
-    int32_t x = 0;
-    int32_t y = 0;
-  } rect;
-
-  PPColorInfo color;
-};
-
-struct PPFeatureVersion {
-  // SDE ASIC versioning its PP block at each specific feature level.
-  static const uint32_t kSDEPpVersionInvalid = 0;
-  static const uint32_t kSDEIgcV17 = 1;
-  static const uint32_t kSDEPgcV17 = 5;
-  static const uint32_t kSDEDitherV17 = 7;
-  static const uint32_t kSDEGamutV17 = 9;
-  static const uint32_t kSDEPaV17 = 11;
-  static const uint32_t kSDEPccV17 = 13;
-  static const uint32_t kSDELegacyPP = 15;
-  static const uint32_t kSDEPADitherV17 = 16;
-  static const uint32_t kSDEIgcV30 = 17;
-  static const uint32_t kSDEGamutV4 = 18;
-  static const uint32_t kSDEPccV4 = 19;
-
-  uint32_t version[kMaxNumPPFeatures];
-  PPFeatureVersion() { memset(version, 0, sizeof(version)); }
-};
-
-struct PPHWAttributes : HWResourceInfo, HWPanelInfo, DisplayConfigVariableInfo {
-  char panel_name[256] = "generic_panel";
-  PPFeatureVersion version;
-  int panel_max_brightness = 0;
-
-  void Set(const HWResourceInfo &hw_res, const HWPanelInfo &panel_info,
-           const DisplayConfigVariableInfo &attr, const PPFeatureVersion &feature_ver);
-};
-
-struct PPDisplayAPIPayload {
-  bool own_payload = false;  // to indicate if *payload is owned by this or just a reference.
-  uint32_t size = 0;
-  uint8_t *payload = NULL;
-
-  PPDisplayAPIPayload() = default;
-  PPDisplayAPIPayload(uint32_t size, uint8_t *param)
-      : size(size), payload(param) {}
-
-  template <typename T>
-  DisplayError CreatePayload(T *&output) {
-    DisplayError ret = kErrorNone;
-
-    payload = new uint8_t[sizeof(T)]();
-    if (!payload) {
-      ret = kErrorMemory;
-      output = NULL;
-    } else {
-      this->size = sizeof(T);
-      output = reinterpret_cast<T *>(payload);
-      own_payload = true;
-    }
-    return ret;
-  }
-
-  DisplayError CreatePayloadBytes(uint32_t size_in_bytes, uint8_t **output) {
-    DisplayError ret = kErrorNone;
-
-    payload = new uint8_t[size_in_bytes]();
-    if (!payload) {
-      ret = kErrorMemory;
-      *output = NULL;
-    } else {
-      this->size = size_in_bytes;
-      *output = payload;
-      own_payload = true;
-    }
-    return ret;
-  }
-
-  inline void DestroyPayload() {
-    if (payload && own_payload) {
-      delete[] payload;
-      payload = NULL;
-      size = 0;
-    } else {
-      payload = NULL;
-      size = 0;
-    }
-  }
-};
-
-struct PPRectInfo {
-  uint32_t width;
-  uint32_t height;
-  int32_t x;
-  int32_t y;
-};
-
-typedef enum {
-  PP_PIXEL_FORMAT_NONE = 0,
-  PP_PIXEL_FORMAT_RGB_888,
-  PP_PIXEL_FORMAT_RGB_2101010,
-  PP_PIXEL_FORMAT_MAX,
-  PP_PIXEL_FORMAT_FORCE32BIT = 0x7FFFFFFF,
-} PPPixelFormats;
-
-struct PPFrameCaptureInputParams {
-  PPRectInfo rect;
-  PPPixelFormats out_pix_format;
-  uint32_t flags;
-};
-
-struct PPFrameCaptureData {
-  PPFrameCaptureInputParams input_params;
-  uint8_t *buffer;
-  uint32_t buffer_stride;
-  uint32_t buffer_size;
-};
-
-static const uint32_t kDeTuningFlagSharpFactor = 0x01;
-static const uint32_t kDeTuningFlagClip = 0x02;
-static const uint32_t kDeTuningFlagThrQuiet = 0x04;
-static const uint32_t kDeTuningFlagThrDieout = 0x08;
-static const uint32_t kDeTuningFlagThrLow = 0x10;
-static const uint32_t kDeTuningFlagThrHigh = 0x20;
-static const uint32_t kDeTuningFlagContentQualLevel = 0x40;
-
-typedef enum {
-  kDeContentQualUnknown,
-  kDeContentQualLow,
-  kDeContentQualMedium,
-  kDeContentQualHigh,
-  kDeContentQualMax,
-} PPDEContentQualLevel;
-
-typedef enum {
-  kDeContentTypeUnknown,
-  kDeContentTypeVideo,
-  kDeContentTypeGraphics,
-  kDeContentTypeMax,
-} PPDEContentType;
-
-struct PPDETuningCfg {
-  uint32_t flags = 0;
-  int32_t sharp_factor = 0;
-  uint16_t thr_quiet = 0;
-  uint16_t thr_dieout = 0;
-  uint16_t thr_low = 0;
-  uint16_t thr_high = 0;
-  uint16_t clip = 0;
-  PPDEContentQualLevel quality = kDeContentQualUnknown;
-  PPDEContentType content_type = kDeContentTypeUnknown;
-};
-
-struct PPDETuningCfgData {
-  uint32_t cfg_en = 0;
-  PPDETuningCfg params;
-  bool cfg_pending = false;
-};
-
-struct SDEGamutCfg {
-  static const int kGamutTableNum = 4;
-  static const int kGamutScaleoffTableNum = 3;
-  static const int kGamutTableSize = 1229;
-  static const int kGamutTableCoarse13Size = 550;
-  static const int kGamutTableCoarseSize = 32;
-  static const int kGamutScaleoffSize = 16;
-  uint32_t mode;
-  uint32_t map_en;
-  uint32_t tbl_size[kGamutTableNum];
-  uint32_t *c0_data[kGamutTableNum];
-  uint32_t *c1_c2_data[kGamutTableNum];
-  uint32_t tbl_scale_off_sz[kGamutScaleoffTableNum];
-  uint32_t *scale_off_data[kGamutScaleoffTableNum];
-};
-
-struct SDEPccCoeff {
-  uint32_t c = 0;
-  uint32_t r = 0;
-  uint32_t g = 0;
-  uint32_t b = 0;
-  uint32_t rg = 0;
-  uint32_t gb = 0;
-  uint32_t rb = 0;
-  uint32_t rgb = 0;
-};
-
-struct SDEPccCfg {
-  SDEPccCoeff red;
-  SDEPccCoeff green;
-  SDEPccCoeff blue;
-
-  static SDEPccCfg *Init(uint32_t arg __attribute__((__unused__)));
-  SDEPccCfg *GetConfig() { return this; }
-};
-
-struct SDEPccV4Coeff {
-  uint32_t c = 0;
-  uint32_t r = 0;
-  uint32_t g = 0;
-  uint32_t b = 0;
-  uint32_t rg = 0;
-  uint32_t gb = 0;
-  uint32_t rb = 0;
-  uint32_t rgb = 0;
-  uint32_t rr = 0;
-  uint32_t gg = 0;
-  uint32_t bb = 0;
-};
-
-struct SDEPccV4Cfg {
-  SDEPccV4Coeff red;
-  SDEPccV4Coeff green;
-  SDEPccV4Coeff blue;
-
-  static SDEPccV4Cfg *Init(uint32_t arg __attribute__((__unused__)));
-  SDEPccV4Cfg *GetConfig() { return this; }
-};
-
-struct SDEDitherCfg {
-  uint32_t g_y_depth;
-  uint32_t r_cr_depth;
-  uint32_t b_cb_depth;
-  uint32_t length;
-  uint32_t dither_matrix[16];
-  uint32_t temporal_en;
-
-  static SDEDitherCfg *Init(uint32_t arg __attribute__((__unused__)));
-  SDEDitherCfg *GetConfig() { return this; }
-};
-
-struct SDEPADitherData {
-  uint64_t data_flags;
-  uint32_t matrix_size;
-  uint64_t matrix_data_addr;
-  uint32_t strength;
-  uint32_t offset_en;
-};
-
-class SDEPADitherWrapper : private SDEPADitherData {
- public:
-  static SDEPADitherWrapper *Init(uint32_t arg __attribute__((__unused__)));
-  ~SDEPADitherWrapper() {
-    if (buffer_)
-      delete[] buffer_;
-  }
-  inline SDEPADitherData *GetConfig(void) { return this; }
-
- private:
-  SDEPADitherWrapper() {}
-  uint32_t *buffer_ = NULL;
-};
-
-struct SDEPaMemColorData {
-  uint32_t adjust_p0 = 0;
-  uint32_t adjust_p1 = 0;
-  uint32_t adjust_p2 = 0;
-  uint32_t blend_gain = 0;
-  uint8_t sat_hold = 0;
-  uint8_t val_hold = 0;
-  uint32_t hue_region = 0;
-  uint32_t sat_region = 0;
-  uint32_t val_region = 0;
-};
-
-struct SDEPaData {
-  static const int kSixZoneLUTSize = 384;
-  uint32_t mode = 0;
-  uint32_t hue_adj = 0;
-  uint32_t sat_adj = 0;
-  uint32_t val_adj = 0;
-  uint32_t cont_adj;
-  SDEPaMemColorData skin;
-  SDEPaMemColorData sky;
-  SDEPaMemColorData foliage;
-  uint32_t six_zone_thresh = 0;
-  uint32_t six_zone_adj_p0 = 0;
-  uint32_t six_zone_adj_p1 = 0;
-  uint8_t six_zone_sat_hold = 0;
-  uint8_t six_zone_val_hold = 0;
-  uint32_t six_zone_len = 0;
-  uint32_t *six_zone_curve_p0 = NULL;
-  uint32_t *six_zone_curve_p1 = NULL;
-};
-
-struct SDEIgcLUTData {
-  static const int kMaxIgcLUTEntries = 256;
-  uint32_t table_fmt = 0;
-  uint32_t len = 0;
-  uint32_t *c0_c1_data = NULL;
-  uint32_t *c2_data = NULL;
-};
-
-struct SDEIgcV30LUTData {
-  static const int kMaxIgcLUTEntries = 256;
-  uint32_t table_fmt = 0;
-  uint32_t len = 0;
-  uint64_t c0_c1_data = 0;
-  uint64_t c2_data = 0;
-  uint32_t strength = 0;
-};
-
-struct SDEPgcLUTData {
-  static const int kPgcLUTEntries = 1024;
-  uint32_t len = 0;
-  uint32_t *c0_data = NULL;
-  uint32_t *c1_data = NULL;
-  uint32_t *c2_data = NULL;
-};
-
-struct SDEDisplayMode {
-  static const int kMaxModeNameSize = 256;
-  int32_t id = -1;
-  uint32_t type = 0;
-  char name[kMaxModeNameSize] = {0};
-};
-
-// Wrapper on HW block config data structure to encapsulate the details of allocating
-// and destroying from the caller.
-class SDEGamutCfgWrapper : private SDEGamutCfg {
- public:
-  enum GamutMode {
-    GAMUT_FINE_MODE = 0x01,
-    GAMUT_COARSE_MODE,
-    GAMUT_COARSE_MODE_13,
-  };
-
-  // This factory method will be used by libsdm-color.so data producer to be populated with
-  // converted config values for SDE feature blocks.
-  static SDEGamutCfgWrapper *Init(uint32_t arg);
-
-  // Data consumer<Commit thread> will be responsible to destroy it once the feature is commited.
-  ~SDEGamutCfgWrapper() {
-    if (buffer_)
-      delete[] buffer_;
-  }
-
-  // Data consumer will use this method to retrieve contained feature configuration.
-  inline SDEGamutCfg *GetConfig(void) { return this; }
-
- private:
-  SDEGamutCfgWrapper() {}
-  uint32_t *buffer_ = NULL;
-};
-
-class SDEPaCfgWrapper : private SDEPaData {
- public:
-  static SDEPaCfgWrapper *Init(uint32_t arg = 0);
-  ~SDEPaCfgWrapper() {
-    if (buffer_)
-      delete[] buffer_;
-  }
-  inline SDEPaData *GetConfig(void) { return this; }
-
- private:
-  SDEPaCfgWrapper() {}
-  uint32_t *buffer_ = NULL;
-};
-
-class SDEIgcLUTWrapper : private SDEIgcLUTData {
- public:
-  static SDEIgcLUTWrapper *Init(uint32_t arg __attribute__((__unused__)));
-  ~SDEIgcLUTWrapper() {
-    if (buffer_)
-      delete[] buffer_;
-  }
-  inline SDEIgcLUTData *GetConfig(void) { return this; }
-
- private:
-  SDEIgcLUTWrapper() {}
-  uint32_t *buffer_ = NULL;
-};
-
-class SDEIgcV30LUTWrapper : private SDEIgcV30LUTData {
- public:
-  static SDEIgcV30LUTWrapper *Init(uint32_t arg __attribute__((__unused__)));
-  ~SDEIgcV30LUTWrapper() {
-    if (buffer_)
-      delete[] buffer_;
-  }
-  inline SDEIgcV30LUTData *GetConfig(void) { return this; }
-
- private:
-  SDEIgcV30LUTWrapper(const SDEIgcV30LUTWrapper& src) { /* do not create copies */ }
-  SDEIgcV30LUTWrapper& operator=(const SDEIgcV30LUTWrapper&) { return *this; }
-  SDEIgcV30LUTWrapper() {}
-  uint32_t *buffer_ = NULL;
-};
-
-class SDEPgcLUTWrapper : private SDEPgcLUTData {
- public:
-  static SDEPgcLUTWrapper *Init(uint32_t arg __attribute__((__unused__)));
-  ~SDEPgcLUTWrapper() {
-    if (buffer_)
-      delete[] buffer_;
-  }
-  inline SDEPgcLUTData *GetConfig(void) { return this; }
-
- private:
-  SDEPgcLUTWrapper() {}
-  uint32_t *buffer_ = NULL;
-};
-
-// Base Postprocessing features information.
-class PPFeatureInfo {
- public:
-  uint32_t enable_flags_ = 0;  // bitmap to indicate subset of parameters enabling or not.
-  uint32_t feature_version_ = 0;
-  uint32_t feature_id_ = 0;
-  uint32_t disp_id_ = 0;
-  uint32_t pipe_id_ = 0;
-
-  virtual ~PPFeatureInfo() {}
-  virtual void *GetConfigData(void) const = 0;
-};
-
-// Individual Postprocessing feature representing physical attributes and information
-// This template class wrapping around abstract data type representing different
-// post-processing features. It will take output from ColorManager converting from raw metadata.
-// The configuration will directly pass into HWInterface to program the hardware accordingly.
-template <typename T>
-class TPPFeatureInfo : public PPFeatureInfo {
- public:
-  virtual ~TPPFeatureInfo() {
-    if (params_)
-      delete params_;
-  }
-
-  // API for data consumer to get underlying data configs to program into pp hardware block.
-  virtual void *GetConfigData(void) const { return params_->GetConfig(); }
-
-  // API for data producer to get access to underlying data configs to populate it.
-  T *GetParamsReference(void) { return params_; }
-
-  // API for create this template object.
-  static TPPFeatureInfo *Init(uint32_t arg = 0) {
-    TPPFeatureInfo *info = new TPPFeatureInfo();
-    if (info) {
-      info->params_ = T::Init(arg);
-      if (!info->params_) {
-        delete info;
-        info = NULL;
-      }
-    }
-
-    return info;
-  }
-
- protected:
-  TPPFeatureInfo() = default;
-
- private:
-  T *params_ = NULL;
-};
-
-// This singleton class serves as data exchanging central between data producer
-// <libsdm-color.so> and data consumer<SDM and HWC.>
-// This class defines PP pending features to be programmed, which generated from
-// ColorManager. Dirty flag indicates some features are available to be programmed.
-// () Lock is needed since the object wil be accessed from 2 tasks.
-// All API exposed are not threadsafe, it's caller's responsiblity to acquire the locker.
-class PPFeaturesConfig {
- public:
-  PPFeaturesConfig() { memset(feature_, 0, sizeof(feature_)); }
-  ~PPFeaturesConfig() { Reset(); }
-
-  // ColorManager installs one TFeatureInfo<T> to take the output configs computed
-  // from ColorManager, containing all physical features to be programmed and also compute
-  // metadata/populate into T.
-  inline DisplayError AddFeature(uint32_t feature_id, PPFeatureInfo *feature) {
-    if (feature_id < kMaxNumPPFeatures) {
-      if (feature_[feature_id]) {
-        delete feature_[feature_id];
-        feature_[feature_id] = NULL;
-      }
-      feature_[feature_id] = feature;
-    }
-    return kErrorNone;
-  }
-
-  inline PPFeatureInfo* GetFeature(uint32_t feature_id) {
-    PPFeatureInfo* feature = nullptr;
-    if (feature_id < kMaxNumPPFeatures) {
-      if (feature_[feature_id]) {
-        feature = feature_[feature_id];
-      }
-    }
-    return feature;
-  }
-
-  inline Locker &GetLocker(void) { return locker_; }
-  inline PPFrameCaptureData *GetFrameCaptureData(void) { return &frame_capture_data; }
-  inline PPDETuningCfgData *GetDETuningCfgData(void) { return &de_tuning_data_; }
-  // Once all features are consumed, destroy/release all TFeatureInfo<T> on the list,
-  // then clear dirty_ flag and return the lock to the TFeatureInfo<T> producer.
-  void Reset();
-
-  // Consumer to call this to retrieve all the TFeatureInfo<T> on the list to be programmed.
-  DisplayError RetrieveNextFeature(PPFeatureInfo **feature);
-
-  inline bool IsDirty() { return dirty_; }
-  inline void MarkAsDirty() { dirty_ = true; }
-
- private:
-  bool dirty_ = 0;
-  Locker locker_;
-  PPFeatureInfo *feature_[kMaxNumPPFeatures];  // reference to TFeatureInfo<T>.
-  uint32_t next_idx_ = 0;
-  PPFrameCaptureData frame_capture_data;
-  PPDETuningCfgData de_tuning_data_;
-};
-
-}  // namespace sdm
-
-#endif  // __COLOR_PARAMS_H__
diff --git a/sdm/include/private/dpps_control_interface.h b/sdm/include/private/dpps_control_interface.h
deleted file mode 100644
index 8a44907..0000000
--- a/sdm/include/private/dpps_control_interface.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
-* Copyright (c) 2016, The Linux Foundation. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without modification, are permitted
-* provided that the following conditions are met:
-*    * Redistributions of source code must retain the above copyright notice, this list of
-*      conditions and the following disclaimer.
-*    * Redistributions in binary form must reproduce the above copyright notice, this list of
-*      conditions and the following disclaimer in the documentation and/or other materials provided
-*      with the distribution.
-*    * Neither the name of The Linux Foundation nor the names of its contributors may be used to
-*      endorse or promote products derived from this software without specific prior written
-*      permission.
-*
-* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-* NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
-* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
-* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
-* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#ifndef __DPPS_CONTROL_INTERFACE_H__
-#define __DPPS_CONTROL_INTERFACE_H__
-
-namespace sdm {
-
-class DppsControlInterface {
- public:
-  virtual ~DppsControlInterface() { }
-  virtual DisplayError On() = 0;
-  virtual DisplayError Off() = 0;
-};
-
-}  // namespace sdm
-
-#endif  // __DPPS_CONTROL_INTERFACE_H__
-
diff --git a/sdm/include/private/extension_interface.h b/sdm/include/private/extension_interface.h
deleted file mode 100644
index 2e5bd49..0000000
--- a/sdm/include/private/extension_interface.h
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
-* Copyright (c) 2015 - 2017, The Linux Foundation. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without modification, are permitted
-* provided that the following conditions are met:
-*    * Redistributions of source code must retain the above copyright notice, this list of
-*      conditions and the following disclaimer.
-*    * Redistributions in binary form must reproduce the above copyright notice, this list of
-*      conditions and the following disclaimer in the documentation and/or other materials provided
-*      with the distribution.
-*    * Neither the name of The Linux Foundation nor the names of its contributors may be used to
-*      endorse or promote products derived from this software without specific prior written
-*      permission.
-*
-* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-* NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
-* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
-* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
-* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#ifndef __EXTENSION_INTERFACE_H__
-#define __EXTENSION_INTERFACE_H__
-
-#include <core/sdm_types.h>
-#include <core/display_interface.h>
-
-#include "partial_update_interface.h"
-#include "strategy_interface.h"
-#include "resource_interface.h"
-#include "dpps_control_interface.h"
-
-namespace sdm {
-
-#define EXTENSION_LIBRARY_NAME "libsdmextension.so"
-#define CREATE_EXTENSION_INTERFACE_NAME "CreateExtensionInterface"
-#define DESTROY_EXTENSION_INTERFACE_NAME "DestroyExtensionInterface"
-
-#define EXTENSION_REVISION_MAJOR (1)
-#define EXTENSION_REVISION_MINOR (0)
-
-#define EXTENSION_VERSION_TAG ((uint16_t) ((EXTENSION_REVISION_MAJOR << 8) \
-                                          | EXTENSION_REVISION_MINOR))
-
-class ExtensionInterface;
-
-typedef DisplayError (*CreateExtensionInterface)(uint16_t version, ExtensionInterface **interface);
-typedef DisplayError (*DestroyExtensionInterface)(ExtensionInterface *interface);
-
-class ExtensionInterface {
- public:
-  virtual DisplayError CreatePartialUpdate(DisplayType type, const HWResourceInfo &hw_resource_info,
-                                           const HWPanelInfo &hw_panel_info,
-                                           const HWMixerAttributes &mixer_attributes,
-                                           const HWDisplayAttributes &display_attributes,
-                                           const DisplayConfigVariableInfo &fb_config,
-                                           PartialUpdateInterface **interface) = 0;
-  virtual DisplayError DestroyPartialUpdate(PartialUpdateInterface *interface) = 0;
-
-  virtual DisplayError CreateStrategyExtn(DisplayType type, BufferAllocator *buffer_allocator,
-                                          const HWResourceInfo &hw_resource_info,
-                                          const HWPanelInfo &hw_panel_info,
-                                          const HWMixerAttributes &mixer_attributes,
-                                          const DisplayConfigVariableInfo &fb_config,
-                                          StrategyInterface **interface) = 0;
-  virtual DisplayError DestroyStrategyExtn(StrategyInterface *interface) = 0;
-
-  virtual DisplayError CreateResourceExtn(const HWResourceInfo &hw_resource_info,
-                                          BufferAllocator *buffer_allocator,
-                                          BufferSyncHandler *buffer_sync_handler,
-                                          ResourceInterface **interface) = 0;
-  virtual DisplayError DestroyResourceExtn(ResourceInterface *interface) = 0;
-  virtual DisplayError CreateDppsControlExtn(DppsControlInterface **dpps_control_interface,
-                                             SocketHandler *socket_handler) = 0;
-  virtual DisplayError DestroyDppsControlExtn(DppsControlInterface *interface) = 0;
-
- protected:
-  virtual ~ExtensionInterface() { }
-};
-
-}  // namespace sdm
-
-#endif  // __EXTENSION_INTERFACE_H__
-
diff --git a/sdm/include/private/hw_info_types.h b/sdm/include/private/hw_info_types.h
deleted file mode 100644
index 43551de..0000000
--- a/sdm/include/private/hw_info_types.h
+++ /dev/null
@@ -1,618 +0,0 @@
-/*
-* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without modification, are permitted
-* provided that the following conditions are met:
-*    * Redistributions of source code must retain the above copyright notice, this list of
-*      conditions and the following disclaimer.
-*    * Redistributions in binary form must reproduce the above copyright notice, this list of
-*      conditions and the following disclaimer in the documentation and/or other materials provided
-*      with the distribution.
-*    * Neither the name of The Linux Foundation nor the names of its contributors may be used to
-*      endorse or promote products derived from this software without specific prior written
-*      permission.
-*
-* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-* NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
-* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
-* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
-* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#ifndef __HW_INFO_TYPES_H__
-#define __HW_INFO_TYPES_H__
-
-#include <stdint.h>
-#include <core/display_interface.h>
-#include <core/core_interface.h>
-#include <vector>
-#include <map>
-#include <string>
-#include <bitset>
-
-namespace sdm {
-using std::string;
-
-const int kMaxSDELayers = 16;   // Maximum number of layers that can be handled by MDP5 hardware
-                                // in a given layer stack.
-#define MAX_PLANES 4
-#define MAX_DETAIL_ENHANCE_CURVE 3
-#define MAJOR 28
-#define MINOR 16
-#define SDEVERSION(major, minor, hw_rev) ((major) << MAJOR) | ((minor) << MINOR) | (hw_rev)
-
-enum HWDeviceType {
-  kDevicePrimary,
-  kDeviceHDMI,
-  kDeviceVirtual,
-  kDeviceRotator,
-  kDeviceMax,
-};
-
-enum HWBlockType {
-  kHWPrimary,
-  kHWHDMI,
-  kHWWriteback0,
-  kHWWriteback1,
-  kHWWriteback2,
-  kHWBlockMax
-};
-
-enum HWDisplayMode {
-  kModeDefault,
-  kModeVideo,
-  kModeCommand,
-};
-
-enum PipeType {
-  kPipeTypeUnused,
-  kPipeTypeVIG,
-  kPipeTypeRGB,
-  kPipeTypeDMA,
-  kPipeTypeCursor,
-};
-
-enum HWSubBlockType {
-  kHWVIGPipe,
-  kHWRGBPipe,
-  kHWDMAPipe,
-  kHWCursorPipe,
-  kHWRotatorInput,
-  kHWRotatorOutput,
-  kHWWBIntfOutput,
-  kHWDestinationScalar,
-  kHWSubBlockMax,
-};
-
-enum HWAlphaInterpolation {
-  kInterpolationPixelRepeat,
-  kInterpolationBilinear,
-  kInterpolation2D,
-  kInterpolationMax,
-};
-
-enum HWBlendingFilter {
-  kBlendFilterCircular,
-  kBlendFilterSeparable,
-  kBlendFilterMax,
-};
-
-enum HWPipeFlags {
-  kIGC = 0x01,
-  kMultiRect = 0x02,
-  kMultiRectParallelMode = 0x04,
-};
-
-enum HWAVRModes {
-  kContinuousMode,  // Mode to enable AVR feature for every frame.
-  kOneShotMode,     // Mode to enable AVR feature for particular frame.
-};
-
-enum HWTopology {
-  kUnknown,
-  kSingleLM,
-  kSingleLMDSC,
-  kDualLM,
-  kDualLMDSC,
-  kDualLMMerge,
-  kDualLMMergeDSC,
-  kDualLMDSCMerge,
-  kPPSplit,
-};
-
-enum HwHdrEotf {
-  kHdrEOTFInvalid = 0,
-  kHdrEOTFSDR = 0x1,
-  kHdrEOTFHdrLumRange = 0x2,
-  kHdrEOTFHDR10 = 0x4,
-  kHdrEOTFHLG = 0x8,
-};
-
-typedef std::map<HWSubBlockType, std::vector<LayerBufferFormat>> FormatsMap;
-typedef std::map<LayerBufferFormat, float> CompRatioMap;
-
-struct HWDynBwLimitInfo {
-  uint32_t cur_mode = kBwDefault;
-  uint64_t total_bw_limit[kBwModeMax] = { 0 };
-  uint64_t pipe_bw_limit[kBwModeMax] = { 0 };
-};
-
-struct HWPipeCaps {
-  PipeType type = kPipeTypeUnused;
-  uint32_t id = 0;
-  uint32_t master_pipe_id = 0;
-  uint32_t max_rects = 1;
-};
-
-struct HWRotatorInfo {
-  enum { ROT_TYPE_MDSS, ROT_TYPE_V4L2 };
-  uint32_t type = ROT_TYPE_MDSS;
-  uint32_t num_rotator = 0;
-  bool has_downscale = false;
-  std::string device_path = "";
-  float min_downscale = 2.0f;
-  bool downscale_compression = false;
-};
-
-enum HWQseedStepVersion {
-  kQseed3v2,
-  kQseed3v3,
-  kQseed3v4,
-};
-
-struct HWDestScalarInfo {
-  uint32_t count = 0;
-  uint32_t max_input_width = 0;
-  uint32_t max_output_width = 0;
-  uint32_t max_scale_up = 1;
-  uint32_t prefill_lines = 4;
-};
-
-enum SmartDMARevision {
-  V1,
-  V2,
-};
-
-struct HWResourceInfo {
-  uint32_t hw_version = 0;
-  uint32_t hw_revision = 0;
-  uint32_t num_dma_pipe = 0;
-  uint32_t num_vig_pipe = 0;
-  uint32_t num_rgb_pipe = 0;
-  uint32_t num_cursor_pipe = 0;
-  uint32_t num_blending_stages = 0;
-  uint32_t num_solidfill_stages = 0;
-  uint32_t num_control = 0;
-  uint32_t num_mixer_to_disp = 0;
-  uint32_t smp_total = 0;
-  uint32_t smp_size = 0;
-  uint32_t num_smp_per_pipe = 0;
-  uint32_t max_scale_up = 1;
-  uint32_t max_scale_down = 1;
-  uint64_t max_bandwidth_low = 0;
-  uint64_t max_bandwidth_high = 0;
-  uint32_t max_mixer_width = 2048;
-  uint32_t max_pipe_width = 2048;
-  uint32_t max_cursor_size = 0;
-  uint64_t max_pipe_bw =  0;
-  uint32_t max_sde_clk = 0;
-  float clk_fudge_factor = 1.0f;
-  uint32_t macrotile_nv12_factor = 0;
-  uint32_t macrotile_factor = 0;
-  uint32_t linear_factor = 0;
-  uint32_t scale_factor = 0;
-  uint32_t extra_fudge_factor = 0;
-  uint32_t amortizable_threshold = 0;
-  uint32_t system_overhead_lines = 0;
-  bool has_bwc = false;
-  bool has_ubwc = false;
-  bool has_decimation = false;
-  bool has_macrotile = false;
-  bool has_non_scalar_rgb = false;
-  bool is_src_split = false;
-  bool has_dyn_bw_support = false;
-  bool separate_rotator = false;
-  bool has_qseed3 = false;
-  bool has_concurrent_writeback = false;
-  bool has_ppp = false;
-  uint32_t writeback_index = kHWBlockMax;
-  HWDynBwLimitInfo dyn_bw_info;
-  std::vector<HWPipeCaps> hw_pipes;
-  FormatsMap supported_formats_map;
-  HWRotatorInfo hw_rot_info;
-  HWDestScalarInfo hw_dest_scalar_info;
-  bool has_avr = false;
-  bool has_hdr = false;
-  SmartDMARevision smart_dma_rev = SmartDMARevision::V1;
-  float ib_fudge_factor = 1.0f;
-  uint32_t undersized_prefill_lines = 0;
-  CompRatioMap comp_ratio_rt_map;
-  CompRatioMap comp_ratio_nrt_map;
-  uint32_t cache_size = 0;  // cache size in bytes
-  HWQseedStepVersion pipe_qseed3_version = kQseed3v2;  // only valid when has_qseed3=true
-  uint32_t min_prefill_lines = 0;
-};
-
-struct HWSplitInfo {
-  uint32_t left_split = 0;
-  uint32_t right_split = 0;
-
-  bool operator !=(const HWSplitInfo &split_info) {
-    return ((left_split != split_info.left_split) || (right_split != split_info.right_split));
-  }
-
-  bool operator ==(const HWSplitInfo &split_info) {
-    return !(operator !=(split_info));
-  }
-};
-
-enum HWS3DMode {
-  kS3DModeNone,
-  kS3DModeLR,
-  kS3DModeRL,
-  kS3DModeTB,
-  kS3DModeFP,
-  kS3DModeMax,
-};
-
-struct HWColorPrimaries {
-  uint32_t white_point[2] = {};       // White point
-  uint32_t red[2] = {};               // Red color primary
-  uint32_t green[2] = {};             // Green color primary
-  uint32_t blue[2] = {};              // Blue color primary
-};
-
-struct HWPanelOrientation {
-  bool rotation = false;
-  bool flip_horizontal = false;
-  bool flip_vertical = false;
-};
-
-struct HWPanelInfo {
-  DisplayPort port = kPortDefault;    // Display port
-  HWDisplayMode mode = kModeDefault;  // Display mode
-  bool partial_update = false;        // Partial update feature
-  int left_align = 1;                 // ROI left alignment restriction
-  int width_align = 1;                // ROI width alignment restriction
-  int top_align = 1;                  // ROI top alignment restriction
-  int height_align = 1;               // ROI height alignment restriction
-  int min_roi_width = 1;              // Min width needed for ROI
-  int min_roi_height = 1;             // Min height needed for ROI
-  bool needs_roi_merge = false;       // Merge ROI's of both the DSI's
-  bool dynamic_fps = false;           // Panel Supports dynamic fps
-  bool dfps_porch_mode = false;       // dynamic fps VFP or HFP mode
-  bool ping_pong_split = false;       // Supports Ping pong split
-  uint32_t min_fps = 0;               // Min fps supported by panel
-  uint32_t max_fps = 0;               // Max fps supported by panel
-  bool is_primary_panel = false;      // Panel is primary display
-  bool is_pluggable = false;          // Panel is pluggable
-  HWSplitInfo split_info;             // Panel split configuration
-  char panel_name[256] = {0};         // Panel name
-  HWS3DMode s3d_mode = kS3DModeNone;  // Panel's current s3d mode.
-  int panel_max_brightness = 0;       // Max panel brightness
-  uint32_t left_roi_count = 1;        // Number if ROI supported on left panel
-  uint32_t right_roi_count = 1;       // Number if ROI supported on right panel
-  bool hdr_enabled = false;           // HDR feature supported
-  bool hdr_metadata_type_one = false;     // Static HDR metadata type one
-  uint32_t hdr_eotf = 0;              // Electro optical transfer function
-  uint32_t peak_luminance = 0;        // Panel's peak luminance level
-  uint32_t average_luminance = 0;     // Panel's average luminance level
-  uint32_t blackness_level = 0;       // Panel's blackness level
-  HWColorPrimaries primaries = {};    // WRGB color primaries
-  HWPanelOrientation panel_orientation = {};  // Panel Orientation
-  uint32_t transfer_time_us = 0;      // transfer time in micro seconds to panel's active region
-
-  bool operator !=(const HWPanelInfo &panel_info) {
-    return ((port != panel_info.port) || (mode != panel_info.mode) ||
-            (partial_update != panel_info.partial_update) ||
-            (left_align != panel_info.left_align) || (width_align != panel_info.width_align) ||
-            (top_align != panel_info.top_align) || (height_align != panel_info.height_align) ||
-            (min_roi_width != panel_info.min_roi_width) ||
-            (min_roi_height != panel_info.min_roi_height) ||
-            (needs_roi_merge != panel_info.needs_roi_merge) ||
-            (dynamic_fps != panel_info.dynamic_fps) || (min_fps != panel_info.min_fps) ||
-            (dfps_porch_mode != panel_info.dfps_porch_mode) ||
-            (ping_pong_split != panel_info.ping_pong_split) ||
-            (max_fps != panel_info.max_fps) || (is_primary_panel != panel_info.is_primary_panel) ||
-            (split_info != panel_info.split_info) || (s3d_mode != panel_info.s3d_mode) ||
-            (left_roi_count != panel_info.left_roi_count) ||
-            (right_roi_count != panel_info.right_roi_count) ||
-            (transfer_time_us != panel_info.transfer_time_us));
-  }
-
-  bool operator ==(const HWPanelInfo &panel_info) {
-    return !(operator !=(panel_info));
-  }
-};
-
-struct HWSessionConfig {
-  LayerRect src_rect {};
-  LayerRect dst_rect {};
-  uint32_t buffer_count = 0;
-  bool secure = false;
-  uint32_t frame_rate = 0;
-  LayerTransform transform;
-  bool secure_camera = false;
-
-  bool operator==(const HWSessionConfig& config) const {
-    return (src_rect == config.src_rect &&
-            dst_rect == config.dst_rect &&
-            buffer_count == config.buffer_count &&
-            secure == config.secure &&
-            frame_rate == config.frame_rate &&
-            transform == config.transform &&
-            secure_camera == config.secure_camera);
-  }
-
-  bool operator!=(const HWSessionConfig& config) const {
-    return !operator==(config);
-  }
-};
-
-enum HWRotatorMode {
-  kRotatorNone,
-  kRotatorOffline,
-  kRotatorInline
-};
-
-struct HWRotateInfo {
-  int pipe_id = -1;  // Not actual pipe id, but the relative DMA id
-  int writeback_id = -1;  // Writeback block id, but this is the same as DMA id
-  LayerRect src_roi {};  // Source crop of each split
-  LayerRect dst_roi {};  // Destination crop of each split
-  bool valid = false;
-  int rotate_id = -1;  // Actual rotator session id with driver
-};
-
-struct HWRotatorSession {
-  HWRotateInfo hw_rotate_info[kMaxRotatePerLayer] {};
-  uint32_t hw_block_count = 0;  // number of rotator hw blocks used by rotator session
-  int session_id = -1;  // A handle with Session Manager
-  HWSessionConfig hw_session_config {};
-  LayerBuffer input_buffer {};  // Input to rotator
-  LayerBuffer output_buffer {};  // Output of rotator, crop width and stride are same
-  float input_compression = 1.0f;
-  float output_compression = 1.0f;
-  bool is_buffer_cached = false;
-  HWRotatorMode mode = kRotatorNone;
-};
-
-struct HWScaleLutInfo {
-  uint32_t dir_lut_size = 0;
-  uint32_t cir_lut_size = 0;
-  uint32_t sep_lut_size = 0;
-  uint64_t dir_lut = 0;
-  uint64_t cir_lut = 0;
-  uint64_t sep_lut = 0;
-};
-
-struct HWDetailEnhanceData : DisplayDetailEnhancerData {
-  uint16_t prec_shift = 0;
-  int16_t adjust_a[MAX_DETAIL_ENHANCE_CURVE] = {0};
-  int16_t adjust_b[MAX_DETAIL_ENHANCE_CURVE] = {0};
-  int16_t adjust_c[MAX_DETAIL_ENHANCE_CURVE] = {0};
-};
-
-struct HWPixelExtension {
-  int32_t extension = 0;  // Number of pixels extension in left, right, top and bottom directions
-                          // for all color components. This pixel value for each color component
-                          // should be sum of fetch and repeat pixels.
-
-  int32_t overfetch = 0;  // Number of pixels need to be overfetched in left, right, top and bottom
-                          // directions from source image for scaling.
-
-  int32_t repeat = 0;     // Number of pixels need to be repeated in left, right, top and bottom
-                          // directions for scaling.
-};
-
-struct HWPlane {
-  int32_t init_phase_x = 0;
-  int32_t phase_step_x = 0;
-  int32_t init_phase_y = 0;
-  int32_t phase_step_y = 0;
-  HWPixelExtension left {};
-  HWPixelExtension top {};
-  HWPixelExtension right {};
-  HWPixelExtension bottom {};
-  uint32_t roi_width = 0;
-  int32_t preload_x = 0;
-  int32_t preload_y = 0;
-  uint32_t src_width = 0;
-  uint32_t src_height = 0;
-};
-
-struct HWScaleData {
-  struct enable {
-    uint8_t scale = 0;
-    uint8_t direction_detection = 0;
-    uint8_t detail_enhance = 0;
-  } enable;
-  uint32_t dst_width = 0;
-  uint32_t dst_height = 0;
-  HWPlane plane[MAX_PLANES] {};
-  // scale_v2_data fields
-  ScalingFilterConfig y_rgb_filter_cfg = kFilterEdgeDirected;
-  ScalingFilterConfig uv_filter_cfg = kFilterEdgeDirected;
-  HWAlphaInterpolation alpha_filter_cfg = kInterpolationPixelRepeat;
-  HWBlendingFilter blend_cfg = kBlendFilterCircular;
-
-  struct lut_flags {
-    uint8_t lut_swap = 0;
-    uint8_t lut_dir_wr = 0;
-    uint8_t lut_y_cir_wr = 0;
-    uint8_t lut_uv_cir_wr = 0;
-    uint8_t lut_y_sep_wr = 0;
-    uint8_t lut_uv_sep_wr = 0;
-  } lut_flag;
-
-  uint32_t dir_lut_idx = 0;
-  /* for Y(RGB) and UV planes*/
-  uint32_t y_rgb_cir_lut_idx = 0;
-  uint32_t uv_cir_lut_idx = 0;
-  uint32_t y_rgb_sep_lut_idx = 0;
-  uint32_t uv_sep_lut_idx = 0;
-  HWDetailEnhanceData detail_enhance {};
-};
-
-struct HWDestScaleInfo {
-  uint32_t mixer_width = 0;
-  uint32_t mixer_height = 0;
-  bool scale_update = false;
-  HWScaleData scale_data = {};
-  LayerRect panel_roi = {};
-};
-
-typedef std::map<uint32_t, HWDestScaleInfo *> DestScaleInfoMap;
-
-struct HWAVRInfo {
-  bool enable = false;                // Flag to Enable AVR feature
-  HWAVRModes mode = kContinuousMode;  // Specifies the AVR mode
-};
-
-struct HWPipeInfo {
-  HWPipeInfo *pair = NULL;
-  uint8_t rect = 255;
-  uint32_t pipe_id = 0;
-  HWSubBlockType sub_block_type = kHWSubBlockMax;
-  LayerRect src_roi {};
-  LayerRect dst_roi {};
-  uint8_t horizontal_decimation = 0;
-  uint8_t vertical_decimation = 0;
-  HWScaleData scale_data {};
-  uint32_t z_order = 0;
-  uint8_t flags = 0;
-  bool valid = false;
-  bool is_virtual = 0;
-};
-
-struct HWSolidfillStage {
-  uint32_t z_order = kMaxSDELayers;
-  uint32_t color = 0;
-  LayerRect roi = {};
-  bool is_exclusion_rect = false;
-  LayerSolidFill solid_fill_info = {};
-};
-
-struct HWLayerConfig {
-  HWPipeInfo left_pipe {};           // pipe for left side of output
-  HWPipeInfo right_pipe {};          // pipe for right side of output
-  HWRotatorSession hw_rotator_session {};
-  HWSolidfillStage hw_solidfill_stage {};
-  float compression = 1.0f;
-  bool use_solidfill_stage = false;
-};
-
-struct HWHDRLayerInfo {
-  enum HDROperation {
-    kNoOp,   // No-op.
-    kSet,    // Sets the HDR MetaData - Start of HDR
-    kReset,  // resets the previously set HDR Metadata, End of HDR
-  };
-
-  int32_t layer_index = -1;
-  HDROperation operation = kNoOp;
-};
-
-struct HWLayersInfo {
-  LayerStack *stack = NULL;        // Input layer stack. Set by the caller.
-  uint32_t app_layer_count = 0;    // Total number of app layers. Must not be 0.
-  uint32_t gpu_target_index = 0;   // GPU target layer index. 0 if not present.
-  std::vector<Layer> hw_layers = {};  // Layers which need to be programmed on the HW
-  std::vector<uint32_t> index {};   // Indexes of the layers from the layer stack which need to
-  std::vector<uint32_t> roi_index {};  // Stores the ROI index where the layers are visible.
-  int sync_handle = -1;         // Release fence id for current draw cycle.
-  int set_idle_time_ms = -1;    // Set idle time to the new specified value.
-                                //    -1 indicates no change in idle time since last set value.
-  std::vector<LayerRect> left_frame_roi = {};   // Left ROI.
-  std::vector<LayerRect> right_frame_roi = {};  // Right ROI.
-  LayerRect partial_fb_roi = {};   // Damaged area in framebuffer.
-  bool roi_split = false;          // Indicates separated left and right ROI
-  bool async_cursor_updates = false;  // Cursor layer allowed to have async updates
-  DestScaleInfoMap dest_scale_info_map = {};
-  HWHDRLayerInfo hdr_layer_info = {};
-  Handle pvt_data = NULL;   // Private data used by sdm extension only.
-};
-
-struct HWQosData {
-  uint64_t core_ab_bps = 0;
-  uint64_t core_ib_bps = 0;
-  uint64_t llcc_ab_bps = 0;
-  uint64_t llcc_ib_bps = 0;
-  uint64_t dram_ab_bps = 0;
-  uint64_t dram_ib_bps = 0;
-  uint64_t rot_prefill_bw_bps = 0;
-  uint32_t clock_hz = 0;
-  uint32_t rot_clock_hz = 0;
-};
-
-struct HWLayers {
-  HWLayersInfo info {};
-  HWLayerConfig config[kMaxSDELayers] {};
-  float output_compression = 1.0f;
-  HWQosData qos_data = {};
-  HWAVRInfo hw_avr_info = {};
-};
-
-struct HWDisplayAttributes : DisplayConfigVariableInfo {
-  bool is_device_split = false;
-  uint32_t v_front_porch = 0;  //!< Vertical front porch of panel
-  uint32_t v_back_porch = 0;   //!< Vertical back porch of panel
-  uint32_t v_pulse_width = 0;  //!< Vertical pulse width of panel
-  uint32_t h_total = 0;        //!< Total width of panel (hActive + hFP + hBP + hPulseWidth)
-  uint32_t v_total = 0;        //!< Total height of panel (vActive + vFP + vBP + vPulseWidth)
-  std::bitset<32> s3d_config {};  //!< Stores the bit mask of S3D modes
-  uint32_t clock_khz = 0;      //!< Stores the pixel clock of panel in khz
-  HWTopology topology = kUnknown;  //!< Stores the topology information.
-
-  bool operator !=(const HWDisplayAttributes &display_attributes) {
-    return ((is_device_split != display_attributes.is_device_split) ||
-            (x_pixels != display_attributes.x_pixels) ||
-            (y_pixels != display_attributes.y_pixels) ||
-            (x_dpi != display_attributes.x_dpi) ||
-            (y_dpi != display_attributes.y_dpi) ||
-            (fps != display_attributes.fps) ||
-            (vsync_period_ns != display_attributes.vsync_period_ns) ||
-            (v_front_porch != display_attributes.v_front_porch) ||
-            (v_back_porch != display_attributes.v_back_porch) ||
-            (v_pulse_width != display_attributes.v_pulse_width) ||
-            (h_total != display_attributes.h_total) ||
-            (is_yuv != display_attributes.is_yuv) ||
-            (s3d_config != display_attributes.s3d_config) ||
-            (clock_khz != display_attributes.clock_khz) ||
-            (topology != display_attributes.topology));
-  }
-
-  bool operator ==(const HWDisplayAttributes &display_attributes) {
-    return !(operator !=(display_attributes));
-  }
-};
-
-struct HWMixerAttributes {
-  uint32_t width = 0;                                  // Layer mixer width
-  uint32_t height = 0;                                 // Layer mixer height
-  uint32_t split_left = 0;
-  LayerBufferFormat output_format = kFormatRGB101010;  // Layer mixer output format
-
-  bool operator !=(const HWMixerAttributes &mixer_attributes) {
-    return ((width != mixer_attributes.width) ||
-            (height != mixer_attributes.height) ||
-            (output_format != mixer_attributes.output_format) ||
-            (split_left != mixer_attributes.split_left));
-  }
-
-  bool operator ==(const HWMixerAttributes &mixer_attributes) {
-    return !(operator !=(mixer_attributes));
-  }
-
-  bool IsValid() {
-    return (width > 0 && height > 0);
-  }
-};
-
-}  // namespace sdm
-
-#endif  // __HW_INFO_TYPES_H__
-
diff --git a/sdm/include/private/partial_update_interface.h b/sdm/include/private/partial_update_interface.h
deleted file mode 100644
index a1c2382..0000000
--- a/sdm/include/private/partial_update_interface.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
-* Copyright (c) 2015, The Linux Foundation. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without modification, are permitted
-* provided that the following conditions are met:
-*    * Redistributions of source code must retain the above copyright notice, this list of
-*      conditions and the following disclaimer.
-*    * Redistributions in binary form must reproduce the above copyright notice, this list of
-*      conditions and the following disclaimer in the documentation and/or other materials provided
-*      with the distribution.
-*    * Neither the name of The Linux Foundation nor the names of its contributors may be used to
-*      endorse or promote products derived from this software without specific prior written
-*      permission.
-*
-* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-* NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
-* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
-* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
-* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#ifndef __PARTIAL_UPDATE_INTERFACE_H__
-#define __PARTIAL_UPDATE_INTERFACE_H__
-
-#include <core/display_interface.h>
-#include <core/buffer_allocator.h>
-#include <core/buffer_sync_handler.h>
-
-#include "hw_info_types.h"
-
-namespace sdm {
-
-struct PUConstraints {
-  bool enable = true;             //!< If this is set, PU will be enabled or it will be disabled
-};
-
-class PartialUpdateInterface {
- public:
-  virtual DisplayError Start(const PUConstraints &pu_constraints) = 0;
-  virtual DisplayError GenerateROI(HWLayersInfo *hw_layers_info) = 0;
-  virtual DisplayError Stop() = 0;
-
- protected:
-  virtual ~PartialUpdateInterface() { }
-};
-
-}  // namespace sdm
-
-#endif  // __PARTIAL_UPDATE_INTERFACE_H__
-
diff --git a/sdm/include/private/resource_interface.h b/sdm/include/private/resource_interface.h
deleted file mode 100644
index 1e75298..0000000
--- a/sdm/include/private/resource_interface.h
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
-* Copyright (c) 2015 - 2017, The Linux Foundation. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without modification, are permitted
-* provided that the following conditions are met:
-*    * Redistributions of source code must retain the above copyright notice, this list of
-*      conditions and the following disclaimer.
-*    * Redistributions in binary form must reproduce the above copyright notice, this list of
-*      conditions and the following disclaimer in the documentation and/or other materials provided
-*      with the distribution.
-*    * Neither the name of The Linux Foundation nor the names of its contributors may be used to
-*      endorse or promote products derived from this software without specific prior written
-*      permission.
-*
-* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-* NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
-* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
-* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
-* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#ifndef __RESOURCE_INTERFACE_H__
-#define __RESOURCE_INTERFACE_H__
-
-#include <core/display_interface.h>
-#include "hw_info_types.h"
-
-namespace sdm {
-
-class ResourceInterface {
- public:
-  enum ResourceCmd {
-    kCmdResetScalarLUT,
-    kCmdMax,
-  };
-
-  virtual DisplayError RegisterDisplay(DisplayType type,
-                                       const HWDisplayAttributes &display_attributes,
-                                       const HWPanelInfo &hw_panel_info,
-                                       const HWMixerAttributes &mixer_attributes,
-                                       Handle *display_ctx) = 0;
-  virtual DisplayError UnregisterDisplay(Handle display_ctx) = 0;
-  virtual DisplayError ReconfigureDisplay(Handle display_ctx,
-                                          const HWDisplayAttributes &display_attributes,
-                                          const HWPanelInfo &hw_panel_info,
-                                          const HWMixerAttributes &mixer_attributes) = 0;
-  virtual DisplayError Start(Handle display_ctx) = 0;
-  virtual DisplayError Stop(Handle display_ctx, HWLayers *hw_layers) = 0;
-  virtual DisplayError Prepare(Handle display_ctx, HWLayers *hw_layers) = 0;
-  virtual DisplayError PostPrepare(Handle display_ctx, HWLayers *hw_layers) = 0;
-  virtual DisplayError Commit(Handle display_ctx, HWLayers *hw_layers) = 0;
-  virtual DisplayError PostCommit(Handle display_ctx, HWLayers *hw_layers) = 0;
-  virtual void Purge(Handle display_ctx) = 0;
-  virtual DisplayError SetMaxMixerStages(Handle display_ctx, uint32_t max_mixer_stages) = 0;
-  virtual DisplayError ValidateScaling(const LayerRect &crop, const LayerRect &dst,
-                                       bool rotate90, BufferLayout layout,
-                                       bool use_rotator_downscale) = 0;
-  virtual DisplayError ValidateAndSetCursorPosition(Handle display_ctx, HWLayers *hw_layers,
-                                                    int x, int y,
-                                                    DisplayConfigVariableInfo *fb_config) = 0;
-  virtual DisplayError SetMaxBandwidthMode(HWBwModes mode) = 0;
-  virtual DisplayError GetScaleLutConfig(HWScaleLutInfo *lut_info) = 0;
-  virtual DisplayError SetDetailEnhancerData(Handle display_ctx,
-                                             const DisplayDetailEnhancerData &de_data) = 0;
-  virtual DisplayError Perform(int cmd, ...) = 0;
-  virtual ~ResourceInterface() { }
-};
-
-}  // namespace sdm
-
-#endif  // __RESOURCE_INTERFACE_H__
-
diff --git a/sdm/include/private/strategy_interface.h b/sdm/include/private/strategy_interface.h
deleted file mode 100644
index 1174e7f..0000000
--- a/sdm/include/private/strategy_interface.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
-* Copyright (c) 2014 - 2017, The Linux Foundation. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without modification, are permitted
-* provided that the following conditions are met:
-*    * Redistributions of source code must retain the above copyright notice, this list of
-*      conditions and the following disclaimer.
-*    * Redistributions in binary form must reproduce the above copyright notice, this list of
-*      conditions and the following disclaimer in the documentation and/or other materials provided
-*      with the distribution.
-*    * Neither the name of The Linux Foundation nor the names of its contributors may be used to
-*      endorse or promote products derived from this software without specific prior written
-*      permission.
-*
-* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-* NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
-* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
-* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
-* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#ifndef __STRATEGY_INTERFACE_H__
-#define __STRATEGY_INTERFACE_H__
-
-#include <core/sdm_types.h>
-#include <core/display_interface.h>
-#include "hw_info_types.h"
-
-namespace sdm {
-
-struct StrategyConstraints {
-  bool safe_mode = false;   //!< In this mode, strategy manager chooses the composition strategy
-                            //!< that requires minimum number of pipe for the current frame. i.e.,
-                            //!< video only composition, secure only composition or GPU composition
-
-  uint32_t max_layers = kMaxSDELayers;  //!< Maximum number of layers that shall be programmed
-                                        //!< on hardware for the given layer stack.
-};
-
-class StrategyInterface {
- public:
-  virtual DisplayError Start(HWLayersInfo *hw_layers_info, uint32_t *max_attempts) = 0;
-  virtual DisplayError GetNextStrategy(StrategyConstraints *constraints) = 0;
-  virtual DisplayError Stop() = 0;
-  virtual DisplayError Reconfigure(const HWPanelInfo &hw_panel_info,
-                                   const HWResourceInfo &hw_res_info,
-                                   const HWMixerAttributes &mixer_attributes,
-                                   const DisplayConfigVariableInfo &fb_config) = 0;
-  virtual DisplayError SetCompositionState(LayerComposition composition_type, bool enable) = 0;
-  virtual DisplayError Purge() = 0;
-  virtual DisplayError SetIdleTimeoutMs(uint32_t active_ms) = 0;
-
-  virtual ~StrategyInterface() { }
-};
-
-}  // namespace sdm
-
-#endif  // __STRATEGY_INTERFACE_H__
-
diff --git a/sdm/include/utils/constants.h b/sdm/include/utils/constants.h
deleted file mode 100644
index 5efe357..0000000
--- a/sdm/include/utils/constants.h
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
-* Copyright (c) 2014 - 2017, The Linux Foundation. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without modification, are permitted
-* provided that the following conditions are met:
-*    * Redistributions of source code must retain the above copyright notice, this list of
-*      conditions and the following disclaimer.
-*    * Redistributions in binary form must reproduce the above copyright notice, this list of
-*      conditions and the following disclaimer in the documentation and/or other materials provided
-*      with the distribution.
-*    * Neither the name of The Linux Foundation nor the names of its contributors may be used to
-*      endorse or promote products derived from this software without specific prior written
-*      permission.
-*
-* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-* NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
-* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
-* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
-* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#ifndef __CONSTANTS_H__
-#define __CONSTANTS_H__
-
-#include <stdlib.h>
-#include <inttypes.h>
-
-#ifndef PRIu64
-#define PRIu64 "llu"
-#endif
-
-#define INT(exp) static_cast<int>(exp)
-#define FLOAT(exp) static_cast<float>(exp)
-#define UINT8(exp) static_cast<uint8_t>(exp)
-#define UINT16(exp) static_cast<uint16_t>(exp)
-#define UINT32(exp) static_cast<uint32_t>(exp)
-#define INT32(exp) static_cast<int32_t>(exp)
-#define UINT64(exp) static_cast<uint64_t>(exp)
-
-#define ROUND_UP(number, step) ((((number) + ((step) - 1)) / (step)) * (step))
-
-#define BITMAP(bit) (1 << (bit))
-
-#define ROUND_UP_ALIGN_DOWN(value, a) FLOAT(FloorToMultipleOf(UINT32(value + 0.5f), UINT32(a)))
-#define ROUND_UP_ALIGN_UP(value, a) FLOAT(CeilToMultipleOf(UINT32(value + 0.5f), UINT32(a)))
-
-#define IDLE_TIMEOUT_DEFAULT_MS 70
-#define IDLE_TIMEOUT_ACTIVE_MS IDLE_TIMEOUT_DEFAULT_MS
-#define IDLE_TIMEOUT_INACTIVE_MS 520
-
-#define IS_RGB_FORMAT(format) (((format) < kFormatYCbCr420Planar) ? true: false)
-
-#define BITS_PER_BYTE 8
-#define BITS_TO_BYTES(x) (((x) + (BITS_PER_BYTE - 1)) / (BITS_PER_BYTE))
-
-// factor value should be in powers of 2(eg: 1, 2, 4, 8)
-template <class T1, class T2>
-inline T1 FloorToMultipleOf(const T1 &value, const T2 &factor) {
-  return (T1)(value & (~(factor - 1)));
-}
-
-template <class T1, class T2>
-inline T1 CeilToMultipleOf(const T1 &value, const T2 &factor) {
-  return (T1)((value + (factor - 1)) & (~(factor - 1)));
-}
-
-namespace sdm {
-
-  const int kThreadPriorityUrgent = -9;
-  const int kMaxRotatePerLayer = 2;
-  const uint32_t kMaxBlitTargetLayers = 2;
-  const int kPageSize = 4096;
-  const uint32_t kGridSize = 129;  // size used for non-linear transformation before Tone-mapping
-  const uint32_t kLutDim = 17;  // Dim of the 3d LUT for tone-mapping.
-
-  typedef void * Handle;
-
-}  // namespace sdm
-
-#endif  // __CONSTANTS_H__
-
diff --git a/sdm/include/utils/debug.h b/sdm/include/utils/debug.h
deleted file mode 100644
index b4334b7..0000000
--- a/sdm/include/utils/debug.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
-* Copyright (c) 2014 - 2018, The Linux Foundation. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without
-* modification, are permitted provided that the following conditions are
-* met:
-*     * Redistributions of source code must retain the above copyright
-*       notice, this list of conditions and the following disclaimer.
-*     * Redistributions in binary form must reproduce the above
-*       copyright notice, this list of conditions and the following
-*       disclaimer in the documentation and/or other materials provided
-*       with the distribution.
-*     * Neither the name of The Linux Foundation nor the names of its
-*       contributors may be used to endorse or promote products derived
-*       from this software without specific prior written permission.
-*
-* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
-* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
-* ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
-* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
-* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#ifndef __DEBUG_H__
-#define __DEBUG_H__
-
-#include <stdint.h>
-#include <debug_handler.h>
-#include <core/sdm_types.h>
-#include <core/display_interface.h>
-#include <display_properties.h>
-
-namespace sdm {
-
-using display::DebugHandler;
-
-class Debug {
- public:
-  static inline DebugHandler* Get() { return DebugHandler::Get(); }
-  static int GetSimulationFlag();
-  static bool GetExternalResolution(char *val);
-  static void GetIdleTimeoutMs(uint32_t *active_ms, uint32_t *inactive_ms);
-  static int GetBootAnimLayerCount();
-  static bool IsRotatorDownScaleDisabled();
-  static bool IsDecimationDisabled();
-  static int GetMaxPipesPerMixer(DisplayType display_type);
-  static int GetMaxUpscale();
-  static bool IsVideoModeEnabled();
-  static bool IsRotatorUbwcDisabled();
-  static bool IsRotatorSplitDisabled();
-  static bool IsScalarDisabled();
-  static bool IsUbwcTiledFrameBuffer();
-  static bool IsAVRDisabled();
-  static bool IsExtAnimDisabled();
-  static bool IsPartialSplitDisabled();
-  static bool IsSrcSplitPreferred();
-  static DisplayError GetMixerResolution(uint32_t *width, uint32_t *height);
-  static DisplayError GetReducedConfig(uint32_t *num_vig_pipes, uint32_t *num_dma_pipes);
-  static int GetExtMaxlayers();
-  static DisplayError GetProperty(const char *property_name, char *value);
-  static DisplayError GetProperty(const char *property_name, int *value);
-};
-
-}  // namespace sdm
-
-#endif  // __DEBUG_H__
-
diff --git a/sdm/include/utils/factory.h b/sdm/include/utils/factory.h
deleted file mode 100644
index f77a299..0000000
--- a/sdm/include/utils/factory.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
-* Copyright (c) 2017, The Linux Foundation. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without
-* modification, are permitted provided that the following conditions are
-* met:
-*   * Redistributions of source code must retain the above copyright
-*     notice, this list of conditions and the following disclaimer.
-*   * Redistributions in binary form must reproduce the above
-*     copyright notice, this list of conditions and the following
-*     disclaimer in the documentation and/or other materials provided
-*     with the distribution.
-*   * Neither the name of The Linux Foundation nor the names of its
-*     contributors may be used to endorse or promote products derived
-*     from this software without specific prior written permission.
-*
-* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
-* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
-* ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
-* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
-* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#ifndef __FACTORY_H__
-#define __FACTORY_H__
-
-#include <utility>
-#include <map>
-#include <string>
-
-namespace sdm {
-
-template <class Creator>
-class Factory {
- public:
-  int Add(const std::string &name, const Creator &creator) {
-    map_.insert(std::pair<std::string, Creator>(name, creator));
-
-    return 0;
-  }
-
-  Creator Get(const std::string &name) {
-    typename std::map<std::string, Creator>::iterator it = map_.find(name);
-    if (it != map_.end()) {
-      return it->second;
-    }
-
-    return nullptr;
-  }
-
- private:
-  std::map<std::string, Creator> map_;
-};
-
-}  // namespace sdm
-
-#endif  // __FACTORY_H__
diff --git a/sdm/include/utils/formats.h b/sdm/include/utils/formats.h
deleted file mode 100644
index 2d43850..0000000
--- a/sdm/include/utils/formats.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
-* Copyright (c) 2016 - 2017, The Linux Foundation. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without
-* modification, are permitted provided that the following conditions are
-* met:
-*   * Redistributions of source code must retain the above copyright
-*     notice, this list of conditions and the following disclaimer.
-*   * Redistributions in binary form must reproduce the above
-*     copyright notice, this list of conditions and the following
-*     disclaimer in the documentation and/or other materials provided
-*     with the distribution.
-*   * Neither the name of The Linux Foundation nor the names of its
-*     contributors may be used to endorse or promote products derived
-*     from this software without specific prior written permission.
-*
-* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
-* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
-* ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
-* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
-* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#ifndef __FORMATS_H__
-#define __FORMATS_H__
-
-#include <core/layer_stack.h>
-
-namespace sdm {
-
-struct FormatTileSize {
-  /*< Tile width in pixels. For YUV formats this will give only the
-      tile width for Y plane*/
-  uint32_t tile_width = 0;
-  /*< Tile height in pixels. For YUV formats this will give only the
-      tile height for Y plane*/
-  uint32_t tile_height = 0;
-
-  /*< Tile width in pixels. Only valid for YUV formats where this will
-      give tile width for UV plane*/
-  uint32_t uv_tile_width = 0;
-  /*< Tile height in pixels. Only valid for YUV formats where this will
-       give tile height for UV plane*/
-  uint32_t uv_tile_height = 0;
-};
-
-bool IsUBWCFormat(LayerBufferFormat format);
-bool Is10BitFormat(LayerBufferFormat format);
-const char *GetFormatString(const LayerBufferFormat &format);
-BufferLayout GetBufferLayout(LayerBufferFormat format);
-DisplayError GetBufferFormatTileSize(LayerBufferFormat format, FormatTileSize *tile_size);
-float GetBufferFormatBpp(LayerBufferFormat format);
-
-}  // namespace sdm
-
-#endif  // __FORMATS_H__
-
diff --git a/sdm/include/utils/locker.h b/sdm/include/utils/locker.h
deleted file mode 100755
index e0d91cb..0000000
--- a/sdm/include/utils/locker.h
+++ /dev/null
@@ -1,171 +0,0 @@
-/*
-* Copyright (c) 2014 - 2016, 2018 The Linux Foundation. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without modification, are permitted
-* provided that the following conditions are met:
-*    * Redistributions of source code must retain the above copyright notice, this list of
-*      conditions and the following disclaimer.
-*    * Redistributions in binary form must reproduce the above copyright notice, this list of
-*      conditions and the following disclaimer in the documentation and/or other materials provided
-*      with the distribution.
-*    * Neither the name of The Linux Foundation nor the names of its contributors may be used to
-*      endorse or promote products derived from this software without specific prior written
-*      permission.
-*
-* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-* NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
-* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
-* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
-* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#ifndef __LOCKER_H__
-#define __LOCKER_H__
-
-#include <stdint.h>
-#include <errno.h>
-#include <pthread.h>
-#include <sys/time.h>
-
-#define SCOPE_LOCK(locker) Locker::ScopeLock lock(locker)
-#define SEQUENCE_ENTRY_SCOPE_LOCK(locker) Locker::SequenceEntryScopeLock lock(locker)
-#define SEQUENCE_EXIT_SCOPE_LOCK(locker) Locker::SequenceExitScopeLock lock(locker)
-#define SEQUENCE_WAIT_SCOPE_LOCK(locker) Locker::SequenceWaitScopeLock lock(locker)
-#define SEQUENCE_CANCEL_SCOPE_LOCK(locker) Locker::SequenceCancelScopeLock lock(locker)
-
-namespace sdm {
-
-class Locker {
- public:
-  class ScopeLock {
-   public:
-    explicit ScopeLock(Locker& locker) : locker_(locker) {
-      locker_.Lock();
-    }
-
-    ~ScopeLock() {
-      locker_.Unlock();
-    }
-
-   private:
-    Locker &locker_;
-  };
-
-  class SequenceEntryScopeLock {
-   public:
-    explicit SequenceEntryScopeLock(Locker& locker) : locker_(locker) {
-      locker_.Lock();
-      locker_.sequence_wait_ = 1;
-    }
-
-    ~SequenceEntryScopeLock() {
-      locker_.Unlock();
-    }
-
-   private:
-    Locker &locker_;
-  };
-
-  class SequenceExitScopeLock {
-   public:
-    explicit SequenceExitScopeLock(Locker& locker) : locker_(locker) {
-      locker_.Lock();
-      locker_.sequence_wait_ = 0;
-    }
-
-    ~SequenceExitScopeLock() {
-      locker_.Broadcast();
-      locker_.Unlock();
-    }
-
-   private:
-    Locker &locker_;
-  };
-
-  class SequenceWaitScopeLock {
-   public:
-    explicit SequenceWaitScopeLock(Locker& locker) : locker_(locker), error_(false) {
-      locker_.Lock();
-
-      while (locker_.sequence_wait_ == 1) {
-        locker_.Wait();
-        error_ = (locker_.sequence_wait_ == -1);
-      }
-    }
-
-    ~SequenceWaitScopeLock() {
-      locker_.Unlock();
-    }
-
-    bool IsError() {
-      return error_;
-    }
-
-   private:
-    Locker &locker_;
-    bool error_;
-  };
-
-  class SequenceCancelScopeLock {
-   public:
-    explicit SequenceCancelScopeLock(Locker& locker) : locker_(locker) {
-      locker_.Lock();
-      locker_.sequence_wait_ = -1;
-    }
-
-    ~SequenceCancelScopeLock() {
-      locker_.Broadcast();
-      locker_.Unlock();
-    }
-
-   private:
-    Locker &locker_;
-  };
-
-  Locker() : sequence_wait_(0) {
-    pthread_mutex_init(&mutex_, 0);
-    pthread_condattr_init(&cond_attr_);
-    pthread_condattr_setclock(&cond_attr_, CLOCK_MONOTONIC);
-    pthread_cond_init(&condition_, &cond_attr_);
-  }
-
-  ~Locker() {
-    pthread_mutex_destroy(&mutex_);
-    pthread_cond_destroy(&condition_);
-    pthread_condattr_destroy(&cond_attr_);
-  }
-
-  void Lock() { pthread_mutex_lock(&mutex_); }
-  void Unlock() { pthread_mutex_unlock(&mutex_); }
-  void Signal() { pthread_cond_signal(&condition_); }
-  void Broadcast() { pthread_cond_broadcast(&condition_); }
-  void Wait() { pthread_cond_wait(&condition_, &mutex_); }
-  int WaitFinite(uint32_t ms) {
-    struct timespec ts;
-    if (clock_gettime(CLOCK_MONOTONIC, &ts)) {
-       return EINVAL;
-    }
-    uint64_t ns = (uint64_t)ts.tv_nsec + (ms * 1000000L);
-    ts.tv_sec   = ts.tv_sec + (time_t)(ns / 1000000000L);
-    ts.tv_nsec  = ns % 1000000000L;
-    return pthread_cond_timedwait(&condition_, &mutex_, &ts);
-  }
-
- private:
-  pthread_mutex_t mutex_;
-  pthread_cond_t condition_;
-  pthread_condattr_t cond_attr_;
-  int sequence_wait_;   // This flag is set to 1 on sequence entry, 0 on exit, and -1 on cancel.
-                        // Some routines will wait for sequence of function calls to finish
-                        // so that capturing a transitionary snapshot of context is prevented.
-                        // If flag is set to -1, these routines will exit without doing any
-                        // further processing.
-};
-
-}  // namespace sdm
-
-#endif  // __LOCKER_H__
-
diff --git a/sdm/include/utils/rect.h b/sdm/include/utils/rect.h
deleted file mode 100644
index b25f76e..0000000
--- a/sdm/include/utils/rect.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
-* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without
-* modification, are permitted provided that the following conditions are
-* met:
-*   * Redistributions of source code must retain the above copyright
-*     notice, this list of conditions and the following disclaimer.
-*   * Redistributions in binary form must reproduce the above
-*     copyright notice, this list of conditions and the following
-*     disclaimer in the documentation and/or other materials provided
-*     with the distribution.
-*   * Neither the name of The Linux Foundation nor the names of its
-*     contributors may be used to endorse or promote products derived
-*     from this software without specific prior written permission.
-*
-* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
-* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
-* ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
-* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
-* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#ifndef __RECT_H__
-#define __RECT_H__
-
-#include <stdint.h>
-#include <core/sdm_types.h>
-#include <core/layer_stack.h>
-#include <utils/debug.h>
-
-namespace sdm {
-
-  enum RectOrientation {
-    kOrientationPortrait,
-    kOrientationLandscape,
-    kOrientationUnknown,
-  };
-
-  bool IsValid(const LayerRect &rect);
-  bool IsCongruent(const LayerRect &rect1, const LayerRect &rect2);
-  void LogI(DebugTag debug_tag, const char *prefix, const LayerRect &roi);
-  void Log(DebugTag debug_tag, const char *prefix, const LayerRect &roi);
-  void Normalize(const uint32_t &align_x, const uint32_t &align_y, LayerRect *rect);
-  LayerRect Union(const LayerRect &rect1, const LayerRect &rect2);
-  LayerRect Intersection(const LayerRect &rect1, const LayerRect &rect2);
-  LayerRect Subtract(const LayerRect &rect1, const LayerRect &rect2);
-  LayerRect Reposition(const LayerRect &rect1, const int &x_offset, const int &y_offset);
-  void SplitLeftRight(const LayerRect &in_rect, uint32_t split_count, uint32_t align_x,
-                      bool flip_horizontal, LayerRect *out_rects);
-  void SplitTopBottom(const LayerRect &in_rect, uint32_t split_count, uint32_t align_y,
-                      bool flip_horizontal, LayerRect *out_rects);
-  void MapRect(const LayerRect &src_domain, const LayerRect &dst_domain, const LayerRect &in_rect,
-               LayerRect *out_rect);
-  void TransformHV(const LayerRect &src_domain, const LayerRect &in_rect,
-                   const LayerTransform &transform, LayerRect *out_rect);
-  RectOrientation GetOrientation(const LayerRect &in_rect);
-  DisplayError GetCropAndDestination(const LayerRect &crop, const LayerRect &dst,
-                                     bool rotate90, float *crop_width, float *crop_height,
-                                     float *dst_width, float *dst_height);
-  DisplayError GetScaleFactor(const LayerRect &crop, const LayerRect &dst, bool rotate90,
-                              float *scale_x, float *scale_y);
-}  // namespace sdm
-
-#endif  // __RECT_H__
-
diff --git a/sdm/include/utils/sync_task.h b/sdm/include/utils/sync_task.h
deleted file mode 100644
index 725460a..0000000
--- a/sdm/include/utils/sync_task.h
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
-* Copyright (c) 2017, The Linux Foundation. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without
-* modification, are permitted provided that the following conditions are
-* met:
-*  * Redistributions of source code must retain the above copyright
-*    notice, this list of conditions and the following disclaimer.
-*  * Redistributions in binary form must reproduce the above
-*    copyright notice, this list of conditions and the following
-*    disclaimer in the documentation and/or other materials provided
-*    with the distribution.
-*  * Neither the name of The Linux Foundation nor the names of its
-*    contributors may be used to endorse or promote products derived
-*    from this software without specific prior written permission.
-*
-* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
-* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
-* ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
-* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
-* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#ifndef __SYNC_TASK_H__
-#define __SYNC_TASK_H__
-
-#include <thread>
-#include <mutex>
-#include <condition_variable>   // NOLINT
-
-namespace sdm {
-
-template <class TaskCode>
-class SyncTask {
- public:
-  // This class need to be overridden by caller to pass on a task context.
-  class TaskContext {
-   public:
-    virtual ~TaskContext() { }
-  };
-
-  // Methods to callback into caller for command codes executions in worker thread.
-  class TaskHandler {
-   public:
-    virtual ~TaskHandler() { }
-    virtual void OnTask(const TaskCode &task_code, TaskContext *task_context) = 0;
-  };
-
-  explicit SyncTask(TaskHandler &task_handler) : task_handler_(task_handler) {
-    // Block caller thread until worker thread has started and ready to listen to task commands.
-    // Worker thread will signal as soon as callback is received in the new thread.
-    std::unique_lock<std::mutex> caller_lock(caller_mutex_);
-    std::thread worker_thread(SyncTaskThread, this);
-    worker_thread_.swap(worker_thread);
-    caller_cv_.wait(caller_lock);
-  }
-
-  ~SyncTask() {
-    // Task code does not matter here.
-    PerformTask(task_code_, nullptr, true);
-    worker_thread_.join();
-  }
-
-  void PerformTask(const TaskCode &task_code, TaskContext *task_context) {
-    PerformTask(task_code, task_context, false);
-  }
-
- private:
-  void PerformTask(const TaskCode &task_code, TaskContext *task_context, bool terminate) {
-    std::unique_lock<std::mutex> caller_lock(caller_mutex_);
-
-    // New scope to limit scope of worker lock to this block.
-    {
-      // Set task command code and notify worker thread.
-      std::unique_lock<std::mutex> worker_lock(worker_mutex_);
-      task_code_ = task_code;
-      task_context_ = task_context;
-      worker_thread_exit_ = terminate;
-      pending_code_ = true;
-      worker_cv_.notify_one();
-    }
-
-    // Wait for worker thread to finish and signal.
-    caller_cv_.wait(caller_lock);
-  }
-
-  static void SyncTaskThread(SyncTask *sync_task) {
-    if (sync_task) {
-      sync_task->OnThreadCallback();
-    }
-  }
-
-  void OnThreadCallback() {
-    // Acquire worker lock and start waiting for events.
-    // Wait must start before caller thread can post events, otherwise posted events will be lost.
-    // Caller thread will be blocked until worker thread signals readiness.
-    std::unique_lock<std::mutex> worker_lock(worker_mutex_);
-
-    // New scope to limit scope of caller lock to this block.
-    {
-      // Signal caller thread that worker thread is ready to listen to events.
-      std::unique_lock<std::mutex> caller_lock(caller_mutex_);
-      caller_cv_.notify_one();
-    }
-
-    while (!worker_thread_exit_) {
-      // Add predicate to handle spurious interrupts.
-      // Wait for caller thread to signal new command codes.
-      worker_cv_.wait(worker_lock, [this] { return pending_code_; });
-
-      // Call task handler which is implemented by the caller.
-      if (!worker_thread_exit_) {
-        task_handler_.OnTask(task_code_, task_context_);
-      }
-
-      pending_code_ = false;
-      // Notify completion of current task to the caller thread which is blocked.
-      std::unique_lock<std::mutex> caller_lock(caller_mutex_);
-      caller_cv_.notify_one();
-    }
-  }
-
-  TaskHandler &task_handler_;
-  TaskCode task_code_;
-  TaskContext *task_context_ = nullptr;
-  std::thread worker_thread_;
-  std::mutex caller_mutex_;
-  std::mutex worker_mutex_;
-  std::condition_variable caller_cv_;
-  std::condition_variable worker_cv_;
-  bool worker_thread_exit_ = false;
-  bool pending_code_ = false;
-};
-
-}  // namespace sdm
-
-#endif  // __SYNC_TASK_H__
diff --git a/sdm/include/utils/sys.h b/sdm/include/utils/sys.h
deleted file mode 100644
index 6b40df4..0000000
--- a/sdm/include/utils/sys.h
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
-* Copyright (c) 2015, The Linux Foundation. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without modification, are permitted
-* provided that the following conditions are met:
-*    * Redistributions of source code must retain the above copyright notice, this list of
-*      conditions and the following disclaimer.
-*    * Redistributions in binary form must reproduce the above copyright notice, this list of
-*      conditions and the following disclaimer in the documentation and/or other materials provided
-*      with the distribution.
-*    * Neither the name of The Linux Foundation nor the names of its contributors may be used to
-*      endorse or promote products derived from this software without specific prior written
-*      permission.
-*
-* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-* NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
-* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
-* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
-* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#ifndef __SYS_H__
-#define __SYS_H__
-
-#include <sys/eventfd.h>
-#include <dlfcn.h>
-#include <unistd.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <poll.h>
-#include <pthread.h>
-#include <fstream>
-
-#ifdef SDM_VIRTUAL_DRIVER
-#include <virtual_driver.h>
-#endif
-
-namespace sdm {
-
-class Sys {
- public:
-#ifndef SDM_VIRTUAL_DRIVER
-  typedef std::fstream fstream;
-#else
-  typedef VirtualFStream fstream;
-#endif
-
-  // Pointers to system calls which are either mapped to actual system call or virtual driver.
-#ifdef TARGET_HEADLESS
-  typedef int (*ioctl)(int, unsigned long int, ...);  // NOLINT
-#else
-  typedef int (*ioctl)(int, int, ...);
-#endif
-  typedef int (*access)(const char *, int);
-  typedef int (*open)(const char *, int, ...);
-  typedef int (*close)(int);
-  typedef int (*poll)(struct pollfd *, nfds_t, int);
-  typedef ssize_t (*pread)(int, void *, size_t, off_t);
-  typedef ssize_t (*pwrite)(int, const void *, size_t, off_t);
-  typedef int (*pthread_cancel)(pthread_t thread);
-  typedef int (*dup)(int fd);
-  typedef ssize_t (*read)(int, void *, size_t);
-  typedef ssize_t (*write)(int, const void *, size_t);
-  typedef int (*eventfd)(unsigned int, int);
-
-  static bool getline_(fstream &fs, std::string &line);  // NOLINT
-
-  static ioctl ioctl_;
-  static access access_;
-  static open open_;
-  static close close_;
-  static poll poll_;
-  static pread pread_;
-  static pwrite pwrite_;
-  static pthread_cancel pthread_cancel_;
-  static dup dup_;
-  static read read_;
-  static write write_;
-  static eventfd eventfd_;
-};
-
-class DynLib {
- public:
-  ~DynLib();
-  bool Open(const char *lib_name);
-  bool Sym(const char *func_name, void **func_ptr);
-  const char * Error() { return ::dlerror(); }
-  operator bool() const { return lib_ != NULL; }
-
- private:
-  void Close();
-
-  void *lib_ = NULL;
-};
-
-}  // namespace sdm
-
-#endif  // __SYS_H__
diff --git a/sdm/include/utils/utils.h b/sdm/include/utils/utils.h
deleted file mode 100644
index b1c55c4..0000000
--- a/sdm/include/utils/utils.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
-* Copyright (c) 2016 - 2017, The Linux Foundation. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without
-* modification, are permitted provided that the following conditions are
-* met:
-*   * Redistributions of source code must retain the above copyright
-*     notice, this list of conditions and the following disclaimer.
-*   * Redistributions in binary form must reproduce the above
-*     copyright notice, this list of conditions and the following
-*     disclaimer in the documentation and/or other materials provided
-*     with the distribution.
-*   * Neither the name of The Linux Foundation nor the names of its
-*     contributors may be used to endorse or promote products derived
-*     from this software without specific prior written permission.
-*
-* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
-* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
-* ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
-* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
-* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#ifndef __UTILS_H__
-#define __UTILS_H__
-
-namespace sdm {
-
-float gcd(float a, float b);
-float lcm(float a, float b);
-void CloseFd(int *fd);
-
-enum class DriverType {
-    FB = 0,
-    DRM,
-};
-
-DriverType GetDriverType();
-
-}  // namespace sdm
-
-#endif  // __UTILS_H__
-
diff --git a/sdm/libs/core/Android.mk b/sdm/libs/core/Android.mk
deleted file mode 100644
index d4aa933..0000000
--- a/sdm/libs/core/Android.mk
+++ /dev/null
@@ -1,86 +0,0 @@
-LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-include $(LOCAL_PATH)/../../../common.mk
-
-LOCAL_MODULE                  := libsdmcore
-LOCAL_VENDOR_MODULE           := true
-LOCAL_MODULE_TAGS             := optional
-LOCAL_C_INCLUDES              := $(common_includes) $(kernel_includes)
-LOCAL_HEADER_LIBRARIES        := display_headers
-LOCAL_CFLAGS                  := -fno-operator-names -Wno-unused-parameter -DLOG_TAG=\"SDM\" \
-                                 $(common_flags)
-LOCAL_HW_INTF_PATH_1          := fb
-LOCAL_SHARED_LIBRARIES        := libdl libdisplaydebug libsdmutils
-
-ifneq ($(TARGET_IS_HEADLESS), true)
-    LOCAL_CFLAGS              += -isystem external/libdrm
-    LOCAL_SHARED_LIBRARIES    += libdrm libdrmutils
-    LOCAL_HW_INTF_PATH_2      := drm
-endif
-
-ifeq ($(TARGET_USES_DRM_PP),true)
-    LOCAL_CFLAGS              += -DPP_DRM_ENABLE
-endif
-
-LOCAL_ADDITIONAL_DEPENDENCIES := $(common_deps) $(kernel_deps)
-LOCAL_SRC_FILES               := core_interface.cpp \
-                                 core_impl.cpp \
-                                 display_base.cpp \
-                                 display_primary.cpp \
-                                 display_hdmi.cpp \
-                                 display_virtual.cpp \
-                                 comp_manager.cpp \
-                                 strategy.cpp \
-                                 resource_default.cpp \
-                                 color_manager.cpp \
-                                 hw_events_interface.cpp \
-                                 hw_info_interface.cpp \
-                                 hw_interface.cpp \
-                                 $(LOCAL_HW_INTF_PATH_1)/hw_info.cpp \
-                                 $(LOCAL_HW_INTF_PATH_1)/hw_device.cpp \
-                                 $(LOCAL_HW_INTF_PATH_1)/hw_primary.cpp \
-                                 $(LOCAL_HW_INTF_PATH_1)/hw_hdmi.cpp \
-                                 $(LOCAL_HW_INTF_PATH_1)/hw_virtual.cpp \
-                                 $(LOCAL_HW_INTF_PATH_1)/hw_color_manager.cpp \
-                                 $(LOCAL_HW_INTF_PATH_1)/hw_scale.cpp \
-                                 $(LOCAL_HW_INTF_PATH_1)/hw_events.cpp
-
-ifneq ($(TARGET_IS_HEADLESS), true)
-    LOCAL_SRC_FILES           += $(LOCAL_HW_INTF_PATH_2)/hw_info_drm.cpp \
-                                 $(LOCAL_HW_INTF_PATH_2)/hw_device_drm.cpp \
-                                 $(LOCAL_HW_INTF_PATH_2)/hw_peripheral_drm.cpp \
-                                 $(LOCAL_HW_INTF_PATH_2)/hw_tv_drm.cpp \
-                                 $(LOCAL_HW_INTF_PATH_2)/hw_events_drm.cpp \
-                                 $(LOCAL_HW_INTF_PATH_2)/hw_scale_drm.cpp \
-                                 $(LOCAL_HW_INTF_PATH_2)/hw_virtual_drm.cpp \
-                                 $(LOCAL_HW_INTF_PATH_2)/hw_color_manager_drm.cpp
-endif
-
-include $(BUILD_SHARED_LIBRARY)
-
-SDM_HEADER_PATH := ../../include
-include $(CLEAR_VARS)
-LOCAL_VENDOR_MODULE           := true
-LOCAL_COPY_HEADERS_TO         := $(common_header_export_path)/sdm/core
-LOCAL_COPY_HEADERS             = $(SDM_HEADER_PATH)/core/buffer_allocator.h \
-                                 $(SDM_HEADER_PATH)/core/buffer_sync_handler.h \
-                                 $(SDM_HEADER_PATH)/core/core_interface.h \
-                                 $(SDM_HEADER_PATH)/core/display_interface.h \
-                                 $(SDM_HEADER_PATH)/core/layer_buffer.h \
-                                 $(SDM_HEADER_PATH)/core/layer_stack.h \
-                                 $(SDM_HEADER_PATH)/core/sdm_types.h \
-                                 $(SDM_HEADER_PATH)/core/socket_handler.h
-include $(BUILD_COPY_HEADERS)
-
-include $(CLEAR_VARS)
-LOCAL_VENDOR_MODULE           := true
-LOCAL_COPY_HEADERS_TO         := $(common_header_export_path)/sdm/private
-LOCAL_COPY_HEADERS             = $(SDM_HEADER_PATH)/private/color_interface.h \
-                                 $(SDM_HEADER_PATH)/private/color_params.h \
-                                 $(SDM_HEADER_PATH)/private/extension_interface.h \
-                                 $(SDM_HEADER_PATH)/private/hw_info_types.h \
-                                 $(SDM_HEADER_PATH)/private/partial_update_interface.h \
-                                 $(SDM_HEADER_PATH)/private/resource_interface.h \
-                                 $(SDM_HEADER_PATH)/private/strategy_interface.h \
-                                 $(SDM_HEADER_PATH)/private/dpps_control_interface.h
-include $(BUILD_COPY_HEADERS)
diff --git a/sdm/libs/core/Makefile.am b/sdm/libs/core/Makefile.am
deleted file mode 100644
index 2b45d8e..0000000
--- a/sdm/libs/core/Makefile.am
+++ /dev/null
@@ -1,47 +0,0 @@
-HEADER_PATH := ${WORKSPACE}/display/display-hal/sdm/include
-
-c_sources = core_interface.cpp \
-            core_impl.cpp \
-            display_base.cpp \
-            display_primary.cpp \
-            display_hdmi.cpp \
-            display_virtual.cpp \
-            comp_manager.cpp \
-            strategy.cpp \
-            resource_default.cpp \
-            dump_impl.cpp \
-            color_manager.cpp \
-            hw_interface.cpp \
-            hw_info_interface.cpp \
-            hw_events_interface.cpp \
-            fb/hw_info.cpp \
-            fb/hw_device.cpp \
-            fb/hw_primary.cpp \
-            fb/hw_hdmi.cpp \
-            fb/hw_virtual.cpp \
-            fb/hw_color_manager.cpp \
-            fb/hw_scale.cpp \
-            fb/hw_events.cpp
-
-core_h_sources = $(HEADER_PATH)/core/*.h
-
-core_includedir = $(includedir)/sdm/core
-core_include_HEADERS = $(core_h_sources)
-
-private_h_sources = $(HEADER_PATH)/private/*.h
-
-private_includedir = $(includedir)/sdm/private
-private_include_HEADERS = $(private_h_sources)
-
-utils_h_sources = $(HEADER_PATH)/utils/*.h
-
-utils_includedir = $(includedir)/sdm/utils
-utils_include_HEADERS = $(utils_h_sources)
-
-lib_LTLIBRARIES = libsdmcore.la
-libsdmcore_la_CC = @CC@
-libsdmcore_la_SOURCES = $(c_sources)
-libsdmcore_la_CFLAGS = $(COMMON_CFLAGS) -DLOG_TAG=\"SDM\"
-libsdmcore_la_CPPFLAGS = $(AM_CPPFLAGS)
-libsdmcore_la_LIBADD = ../utils/libsdmutils.la
-libsdmcore_la_LDFLAGS = -shared -avoid-version
diff --git a/sdm/libs/core/color_manager.cpp b/sdm/libs/core/color_manager.cpp
deleted file mode 100644
index 04af820..0000000
--- a/sdm/libs/core/color_manager.cpp
+++ /dev/null
@@ -1,254 +0,0 @@
-/* Copyright (c) 2015 - 2018, The Linux Foundataion. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without
-* modification, are permitted provided that the following conditions are
-* met:
-*     * Redistributions of source code must retain the above copyright
-*       notice, this list of conditions and the following disclaimer.
-*     * Redistributions in binary form must reproduce the above
-*       copyright notice, this list of conditions and the following
-*       disclaimer in the documentation and/or other materials provided
-*       with the distribution.
-*     * Neither the name of The Linux Foundation nor the names of its
-*       contributors may be used to endorse or promote products derived
-*       from this software without specific prior written permission.
-*
-* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
-* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
-* ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
-* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
-* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*
-*/
-
-#include <dlfcn.h>
-#include <private/color_interface.h>
-#include <utils/constants.h>
-#include <utils/debug.h>
-#include <string>
-#include "color_manager.h"
-
-#define __CLASS__ "ColorManager"
-
-namespace sdm {
-
-DynLib ColorManagerProxy::color_lib_;
-CreateColorInterface ColorManagerProxy::create_intf_ = NULL;
-DestroyColorInterface ColorManagerProxy::destroy_intf_ = NULL;
-HWResourceInfo ColorManagerProxy::hw_res_info_;
-
-// Below two functions are part of concrete implementation for SDM core private
-// color_params.h
-void PPFeaturesConfig::Reset() {
-  for (int i = 0; i < kMaxNumPPFeatures; i++) {
-    if (feature_[i]) {
-      delete feature_[i];
-      feature_[i] = NULL;
-    }
-  }
-  dirty_ = false;
-  next_idx_ = 0;
-}
-
-DisplayError PPFeaturesConfig::RetrieveNextFeature(PPFeatureInfo **feature) {
-  DisplayError ret = kErrorNone;
-  uint32_t i(0);
-
-  for (i = next_idx_; i < kMaxNumPPFeatures; i++) {
-    if (feature_[i]) {
-      *feature = feature_[i];
-      next_idx_ = i + 1;
-      break;
-    }
-  }
-
-  if (i == kMaxNumPPFeatures) {
-    ret = kErrorParameters;
-    next_idx_ = 0;
-  }
-
-  return ret;
-}
-
-DisplayError ColorManagerProxy::Init(const HWResourceInfo &hw_res_info) {
-  DisplayError error = kErrorNone;
-
-  // Load color service library and retrieve its entry points.
-  if (color_lib_.Open(COLORMGR_LIBRARY_NAME)) {
-    if (!color_lib_.Sym(CREATE_COLOR_INTERFACE_NAME, reinterpret_cast<void **>(&create_intf_)) ||
-        !color_lib_.Sym(DESTROY_COLOR_INTERFACE_NAME, reinterpret_cast<void **>(&destroy_intf_))) {
-      DLOGW("Fail to retrieve = %s from %s", CREATE_COLOR_INTERFACE_NAME, COLORMGR_LIBRARY_NAME);
-      error = kErrorResources;
-    }
-  } else {
-    DLOGW("Fail to load = %s", COLORMGR_LIBRARY_NAME);
-    error = kErrorResources;
-  }
-
-  hw_res_info_ = hw_res_info;
-
-  return error;
-}
-
-void ColorManagerProxy::Deinit() {
-  color_lib_.~DynLib();
-}
-
-ColorManagerProxy::ColorManagerProxy(DisplayType type, HWInterface *intf,
-                                     const HWDisplayAttributes &attr,
-                                     const HWPanelInfo &info)
-    : device_type_(type), pp_hw_attributes_(), hw_intf_(intf), color_intf_(NULL), pp_features_() {}
-
-ColorManagerProxy *ColorManagerProxy::CreateColorManagerProxy(DisplayType type,
-                                                              HWInterface *hw_intf,
-                                                              const HWDisplayAttributes &attribute,
-                                                              const HWPanelInfo &panel_info) {
-  DisplayError error = kErrorNone;
-  PPFeatureVersion versions;
-
-  // check if all resources are available before invoking factory method from libsdm-color.so.
-  if (!color_lib_ || !create_intf_ || !destroy_intf_) {
-    DLOGW("Information for %s isn't available!", COLORMGR_LIBRARY_NAME);
-    return NULL;
-  }
-
-  ColorManagerProxy *color_manager_proxy =
-      new ColorManagerProxy(type, hw_intf, attribute, panel_info);
-  if (color_manager_proxy) {
-    // 1. need query post-processing feature version from HWInterface.
-    error = color_manager_proxy->hw_intf_->GetPPFeaturesVersion(&versions);
-    PPHWAttributes &hw_attr = color_manager_proxy->pp_hw_attributes_;
-    if (error != kErrorNone) {
-      DLOGW("Fail to get DSPP feature versions");
-    } else {
-      hw_attr.Set(hw_res_info_, panel_info, attribute, versions);
-      DLOGI("PAV2 version is versions = %d, version = %d ",
-            hw_attr.version.version[kGlobalColorFeaturePaV2],
-            versions.version[kGlobalColorFeaturePaV2]);
-    }
-
-    // 2. instantiate concrete ColorInterface from libsdm-color.so, pass all hardware info in.
-    error = create_intf_(COLOR_VERSION_TAG, color_manager_proxy->device_type_, hw_attr,
-                         &color_manager_proxy->color_intf_);
-    if (error != kErrorNone) {
-      DLOGW("Unable to instantiate concrete ColorInterface from %s", COLORMGR_LIBRARY_NAME);
-      delete color_manager_proxy;
-      color_manager_proxy = NULL;
-    }
-  }
-
-  return color_manager_proxy;
-}
-
-ColorManagerProxy::~ColorManagerProxy() {
-  if (destroy_intf_)
-    destroy_intf_(device_type_);
-  color_intf_ = NULL;
-}
-
-DisplayError ColorManagerProxy::ColorSVCRequestRoute(const PPDisplayAPIPayload &in_payload,
-                                                     PPDisplayAPIPayload *out_payload,
-                                                     PPPendingParams *pending_action) {
-  DisplayError ret = kErrorNone;
-
-  // On completion, dspp_features_ will be populated and mark dirty with all resolved dspp
-  // feature list with paramaters being transformed into target requirement.
-  ret = color_intf_->ColorSVCRequestRoute(in_payload, out_payload, &pp_features_, pending_action);
-
-  return ret;
-}
-
-DisplayError ColorManagerProxy::ApplyDefaultDisplayMode(void) {
-  DisplayError ret = kErrorNone;
-
-  // On POR, will be invoked from prepare<> request once bootanimation is done.
-  ret = color_intf_->ApplyDefaultDisplayMode(&pp_features_);
-
-  return ret;
-}
-
-bool ColorManagerProxy::NeedsPartialUpdateDisable() {
-  Locker &locker(pp_features_.GetLocker());
-  SCOPE_LOCK(locker);
-
-  return pp_features_.IsDirty();
-}
-
-DisplayError ColorManagerProxy::Commit() {
-  static bool first_cycle = true;
-  if (first_cycle) {
-    first_cycle = false;
-    return kErrorNone;
-  }
-
-  Locker &locker(pp_features_.GetLocker());
-  SCOPE_LOCK(locker);
-
-  DisplayError ret = kErrorNone;
-  if (pp_features_.IsDirty()) {
-    ret = hw_intf_->SetPPFeatures(&pp_features_);
-  }
-
-  return ret;
-}
-
-void PPHWAttributes::Set(const HWResourceInfo &hw_res,
-                         const HWPanelInfo &panel_info,
-                         const DisplayConfigVariableInfo &attr,
-                         const PPFeatureVersion &feature_ver) {
-  HWResourceInfo &res = *this;
-  res = hw_res;
-  HWPanelInfo &panel = *this;
-  panel = panel_info;
-  DisplayConfigVariableInfo &attributes = *this;
-  attributes = attr;
-  version = feature_ver;
-  panel_max_brightness = panel_info.panel_max_brightness;
-
-  if (strlen(panel_info.panel_name)) {
-    snprintf(&panel_name[0], sizeof(panel_name), "%s", &panel_info.panel_name[0]);
-    char *tmp = panel_name;
-    while ((tmp = strstr(tmp, " ")) != NULL)
-      *tmp = '_';
-    if ((tmp = strstr(panel_name, "\n")) != NULL)
-      *tmp = '\0';
-  }
-}
-
-DisplayError ColorManagerProxy::ColorMgrGetNumOfModes(uint32_t *mode_cnt) {
-  return color_intf_->ColorIntfGetNumDisplayModes(&pp_features_, 0, mode_cnt);
-}
-
-DisplayError ColorManagerProxy::ColorMgrGetModes(uint32_t *mode_cnt,
-                                                 SDEDisplayMode *modes) {
-  return color_intf_->ColorIntfEnumerateDisplayModes(&pp_features_, 0, modes, mode_cnt);
-}
-
-DisplayError ColorManagerProxy::ColorMgrSetMode(int32_t color_mode_id) {
-  return color_intf_->ColorIntfSetDisplayMode(&pp_features_, 0, color_mode_id);
-}
-
-DisplayError ColorManagerProxy::ColorMgrGetModeInfo(int32_t mode_id, AttrVal *query) {
-  return color_intf_->ColorIntfGetModeInfo(&pp_features_, 0, mode_id, query);
-}
-
-DisplayError ColorManagerProxy::ColorMgrSetColorTransform(uint32_t length,
-                                                          const double *trans_data) {
-  return color_intf_->ColorIntfSetColorTransform(&pp_features_, 0, length, trans_data);
-}
-
-DisplayError ColorManagerProxy::ColorMgrGetDefaultModeID(int32_t *mode_id) {
-  return color_intf_->ColorIntfGetDefaultModeID(&pp_features_, 0, mode_id);
-}
-
-DisplayError ColorManagerProxy::ColorMgrGetActiveMode(std::string *mode) {
-  return color_intf_->ColorIntfGetActiveMode(&pp_features_, 0, mode);
-}
-
-}  // namespace sdm
diff --git a/sdm/libs/core/color_manager.h b/sdm/libs/core/color_manager.h
deleted file mode 100644
index d29422e..0000000
--- a/sdm/libs/core/color_manager.h
+++ /dev/null
@@ -1,100 +0,0 @@
-/* Copyright (c) 2015-2018, The Linux Foundataion. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without
-* modification, are permitted provided that the following conditions are
-* met:
-*     * Redistributions of source code must retain the above copyright
-*       notice, this list of conditions and the following disclaimer.
-*     * Redistributions in binary form must reproduce the above
-*       copyright notice, this list of conditions and the following
-*       disclaimer in the documentation and/or other materials provided
-*       with the distribution.
-*     * Neither the name of The Linux Foundation nor the names of its
-*       contributors may be used to endorse or promote products derived
-*       from this software without specific prior written permission.
-*
-* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
-* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
-* ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
-* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
-* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*
-*/
-
-#ifndef __COLOR_MANAGER_H__
-#define __COLOR_MANAGER_H__
-
-#include <stdlib.h>
-#include <core/sdm_types.h>
-#include <utils/locker.h>
-#include <private/color_interface.h>
-#include <utils/sys.h>
-#include <utils/debug.h>
-#include <string>
-#include "hw_interface.h"
-
-namespace sdm {
-
-/*
- * ColorManager proxy to maintain necessary information to interact with underlying color service.
- * Each display object has its own proxy.
- */
-class ColorManagerProxy {
- public:
-  static DisplayError Init(const HWResourceInfo &hw_res_info);
-  static void Deinit();
-
-  /* Create ColorManagerProxy for this display object, following things need to be happening
-   * 1. Instantiates concrete ColorInerface implementation.
-   * 2. Pass all display object specific informations into it.
-   * 3. Populate necessary resources.
-   * 4. Need get panel name for hw_panel_info_.
-   */
-  static ColorManagerProxy *CreateColorManagerProxy(DisplayType type, HWInterface *hw_intf,
-                                                    const HWDisplayAttributes &attribute,
-                                                    const HWPanelInfo &panel_info);
-
-  /* need reverse the effect of CreateColorManagerProxy. */
-  ~ColorManagerProxy();
-
-  DisplayError ColorSVCRequestRoute(const PPDisplayAPIPayload &in_payload,
-                                    PPDisplayAPIPayload *out_payload,
-                                    PPPendingParams *pending_action);
-  DisplayError ApplyDefaultDisplayMode();
-  DisplayError ColorMgrGetNumOfModes(uint32_t *mode_cnt);
-  DisplayError ColorMgrGetModes(uint32_t *mode_cnt, SDEDisplayMode *modes);
-  DisplayError ColorMgrSetMode(int32_t color_mode_id);
-  DisplayError ColorMgrGetModeInfo(int32_t mode_id, AttrVal *query);
-  DisplayError ColorMgrSetColorTransform(uint32_t length, const double *trans_data);
-  DisplayError ColorMgrGetDefaultModeID(int32_t *mode_id);
-  DisplayError ColorMgrGetActiveMode(std::string *mode);
-  bool NeedsPartialUpdateDisable();
-  DisplayError Commit();
-
- protected:
-  ColorManagerProxy() {}
-  ColorManagerProxy(DisplayType type, HWInterface *intf, const HWDisplayAttributes &attr,
-                    const HWPanelInfo &info);
-
- private:
-  static DynLib color_lib_;
-  static CreateColorInterface create_intf_;
-  static DestroyColorInterface destroy_intf_;
-  static HWResourceInfo hw_res_info_;
-
-  DisplayType device_type_;
-  PPHWAttributes pp_hw_attributes_;
-  HWInterface *hw_intf_;
-  ColorInterface *color_intf_;
-  PPFeaturesConfig pp_features_;
-};
-
-}  // namespace sdm
-
-#endif  // __COLOR_MANAGER_H__
diff --git a/sdm/libs/core/comp_manager.cpp b/sdm/libs/core/comp_manager.cpp
deleted file mode 100644
index 3acdcf0..0000000
--- a/sdm/libs/core/comp_manager.cpp
+++ /dev/null
@@ -1,540 +0,0 @@
-/*
-* Copyright (c) 2014 - 2017, The Linux Foundation. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without modification, are permitted
-* provided that the following conditions are met:
-*    * Redistributions of source code must retain the above copyright notice, this list of
-*      conditions and the following disclaimer.
-*    * Redistributions in binary form must reproduce the above copyright notice, this list of
-*      conditions and the following disclaimer in the documentation and/or other materials provided
-*      with the distribution.
-*    * Neither the name of The Linux Foundation nor the names of its contributors may be used to
-*      endorse or promote products derived from this software without specific prior written
-*      permission.
-*
-* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-* NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
-* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
-* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
-* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#include <utils/constants.h>
-#include <utils/debug.h>
-#include <core/buffer_allocator.h>
-
-#include "comp_manager.h"
-#include "strategy.h"
-
-#define __CLASS__ "CompManager"
-
-namespace sdm {
-
-DisplayError CompManager::Init(const HWResourceInfo &hw_res_info,
-                               ExtensionInterface *extension_intf,
-                               BufferAllocator *buffer_allocator,
-                               BufferSyncHandler *buffer_sync_handler,
-                               SocketHandler *socket_handler) {
-  SCOPE_LOCK(locker_);
-
-  DisplayError error = kErrorNone;
-
-  if (extension_intf) {
-    error = extension_intf->CreateResourceExtn(hw_res_info, buffer_allocator, buffer_sync_handler,
-                                               &resource_intf_);
-    extension_intf->CreateDppsControlExtn(&dpps_ctrl_intf_, socket_handler);
-  } else {
-    error = ResourceDefault::CreateResourceDefault(hw_res_info, &resource_intf_);
-  }
-
-  if (error != kErrorNone) {
-    if (extension_intf) {
-      extension_intf->DestroyDppsControlExtn(dpps_ctrl_intf_);
-    }
-    return error;
-  }
-
-  hw_res_info_ = hw_res_info;
-  buffer_allocator_ = buffer_allocator;
-  extension_intf_ = extension_intf;
-
-  return error;
-}
-
-DisplayError CompManager::Deinit() {
-  SCOPE_LOCK(locker_);
-
-  if (extension_intf_) {
-    extension_intf_->DestroyResourceExtn(resource_intf_);
-    extension_intf_->DestroyDppsControlExtn(dpps_ctrl_intf_);
-  } else {
-    ResourceDefault::DestroyResourceDefault(resource_intf_);
-  }
-
-  return kErrorNone;
-}
-
-DisplayError CompManager::RegisterDisplay(DisplayType type,
-                                          const HWDisplayAttributes &display_attributes,
-                                          const HWPanelInfo &hw_panel_info,
-                                          const HWMixerAttributes &mixer_attributes,
-                                          const DisplayConfigVariableInfo &fb_config,
-                                          Handle *display_ctx) {
-  SCOPE_LOCK(locker_);
-
-  DisplayError error = kErrorNone;
-
-  DisplayCompositionContext *display_comp_ctx = new DisplayCompositionContext();
-  if (!display_comp_ctx) {
-    return kErrorMemory;
-  }
-
-  Strategy *&strategy = display_comp_ctx->strategy;
-  strategy = new Strategy(extension_intf_, buffer_allocator_, type, hw_res_info_, hw_panel_info,
-                          mixer_attributes, display_attributes, fb_config);
-  if (!strategy) {
-    DLOGE("Unable to create strategy");
-    delete display_comp_ctx;
-    return kErrorMemory;
-  }
-
-  error = strategy->Init();
-  if (error != kErrorNone) {
-    delete strategy;
-    delete display_comp_ctx;
-    return error;
-  }
-
-  error = resource_intf_->RegisterDisplay(type, display_attributes, hw_panel_info, mixer_attributes,
-                                          &display_comp_ctx->display_resource_ctx);
-  if (error != kErrorNone) {
-    strategy->Deinit();
-    delete strategy;
-    delete display_comp_ctx;
-    display_comp_ctx = NULL;
-    return error;
-  }
-
-  registered_displays_[type] = 1;
-  display_comp_ctx->is_primary_panel = hw_panel_info.is_primary_panel;
-  display_comp_ctx->display_type = type;
-  display_comp_ctx->fb_config = fb_config;
-  *display_ctx = display_comp_ctx;
-  // New non-primary display device has been added, so move the composition mode to safe mode until
-  // resources for the added display is configured properly.
-  if (!display_comp_ctx->is_primary_panel) {
-    safe_mode_ = true;
-    max_sde_ext_layers_ = UINT32(Debug::GetExtMaxlayers());
-  }
-
-  DLOGV_IF(kTagCompManager, "registered display bit mask 0x%x, configured display bit mask 0x%x, " \
-           "display type %d", registered_displays_.to_ulong(), configured_displays_.to_ulong(),
-           display_comp_ctx->display_type);
-
-  return kErrorNone;
-}
-
-DisplayError CompManager::UnregisterDisplay(Handle display_ctx) {
-  SCOPE_LOCK(locker_);
-
-  DisplayCompositionContext *display_comp_ctx =
-                             reinterpret_cast<DisplayCompositionContext *>(display_ctx);
-
-  if (!display_comp_ctx) {
-    return kErrorParameters;
-  }
-
-  resource_intf_->UnregisterDisplay(display_comp_ctx->display_resource_ctx);
-
-  Strategy *&strategy = display_comp_ctx->strategy;
-  strategy->Deinit();
-  delete strategy;
-
-  registered_displays_[display_comp_ctx->display_type] = 0;
-  configured_displays_[display_comp_ctx->display_type] = 0;
-
-  if (display_comp_ctx->display_type == kHDMI) {
-    max_layers_ = kMaxSDELayers;
-  }
-
-  DLOGV_IF(kTagCompManager, "registered display bit mask 0x%x, configured display bit mask 0x%x, " \
-           "display type %d", registered_displays_.to_ulong(), configured_displays_.to_ulong(),
-           display_comp_ctx->display_type);
-
-  delete display_comp_ctx;
-  display_comp_ctx = NULL;
-  return kErrorNone;
-}
-
-DisplayError CompManager::ReconfigureDisplay(Handle comp_handle,
-                                             const HWDisplayAttributes &display_attributes,
-                                             const HWPanelInfo &hw_panel_info,
-                                             const HWMixerAttributes &mixer_attributes,
-                                             const DisplayConfigVariableInfo &fb_config) {
-  SCOPE_LOCK(locker_);
-
-  DisplayError error = kErrorNone;
-  DisplayCompositionContext *display_comp_ctx =
-                             reinterpret_cast<DisplayCompositionContext *>(comp_handle);
-
-  error = resource_intf_->ReconfigureDisplay(display_comp_ctx->display_resource_ctx,
-                                             display_attributes, hw_panel_info, mixer_attributes);
-  if (error != kErrorNone) {
-    return error;
-  }
-
-  if (display_comp_ctx->strategy) {
-    error = display_comp_ctx->strategy->Reconfigure(hw_panel_info, display_attributes,
-                                                    mixer_attributes, fb_config);
-    if (error != kErrorNone) {
-      DLOGE("Unable to Reconfigure strategy.");
-      display_comp_ctx->strategy->Deinit();
-      delete display_comp_ctx->strategy;
-      display_comp_ctx->strategy = NULL;
-      return error;
-    }
-  }
-
-  // For HDMI S3D mode, set max_layers_ to 0 so that primary display would fall back
-  // to GPU composition to release pipes for HDMI.
-  if (display_comp_ctx->display_type == kHDMI) {
-    if (hw_panel_info.s3d_mode != kS3DModeNone) {
-      max_layers_ = 0;
-    } else {
-      max_layers_ = kMaxSDELayers;
-    }
-  }
-
-  // Update new resolution.
-  display_comp_ctx->fb_config = fb_config;
-  return error;
-}
-
-void CompManager::PrepareStrategyConstraints(Handle comp_handle, HWLayers *hw_layers) {
-  DisplayCompositionContext *display_comp_ctx =
-                             reinterpret_cast<DisplayCompositionContext *>(comp_handle);
-  StrategyConstraints *constraints = &display_comp_ctx->constraints;
-
-  constraints->safe_mode = safe_mode_;
-  constraints->max_layers = max_layers_;
-
-  // Limit 2 layer SDE Comp if its not a Primary Display.
-  // Safe mode is the policy for External display on a low end device.
-  if (!display_comp_ctx->is_primary_panel) {
-    bool low_end_hw = ((hw_res_info_.num_vig_pipe + hw_res_info_.num_rgb_pipe +
-                        hw_res_info_.num_dma_pipe) <= kSafeModeThreshold);
-    constraints->max_layers = max_sde_ext_layers_;
-    constraints->safe_mode = (low_end_hw && !hw_res_info_.separate_rotator) ? true : safe_mode_;
-  }
-
-  // If a strategy fails after successfully allocating resources, then set safe mode
-  if (display_comp_ctx->remaining_strategies != display_comp_ctx->max_strategies) {
-    constraints->safe_mode = true;
-  }
-
-  // TODO(user): App layer count will change for hybrid composition
-  uint32_t app_layer_count = UINT32(hw_layers->info.stack->layers.size()) - 1;
-  if (display_comp_ctx->idle_fallback || display_comp_ctx->thermal_fallback_) {
-    // Handle the idle timeout by falling back
-    constraints->safe_mode = true;
-  }
-
-  // Avoid safe mode, if there is only one app layer.
-  if (app_layer_count == 1) {
-     constraints->safe_mode = false;
-  }
-}
-
-void CompManager::PrePrepare(Handle display_ctx, HWLayers *hw_layers) {
-  SCOPE_LOCK(locker_);
-  DisplayCompositionContext *display_comp_ctx =
-                             reinterpret_cast<DisplayCompositionContext *>(display_ctx);
-  display_comp_ctx->strategy->Start(&hw_layers->info, &display_comp_ctx->max_strategies,
-                                    display_comp_ctx->pu_constraints);
-  display_comp_ctx->remaining_strategies = display_comp_ctx->max_strategies;
-}
-
-DisplayError CompManager::Prepare(Handle display_ctx, HWLayers *hw_layers) {
-  SCOPE_LOCK(locker_);
-
-  DisplayCompositionContext *display_comp_ctx =
-                             reinterpret_cast<DisplayCompositionContext *>(display_ctx);
-  Handle &display_resource_ctx = display_comp_ctx->display_resource_ctx;
-
-  DisplayError error = kErrorUndefined;
-
-  PrepareStrategyConstraints(display_ctx, hw_layers);
-
-  // Select a composition strategy, and try to allocate resources for it.
-  resource_intf_->Start(display_resource_ctx);
-
-  bool exit = false;
-  uint32_t &count = display_comp_ctx->remaining_strategies;
-  for (; !exit && count > 0; count--) {
-    error = display_comp_ctx->strategy->GetNextStrategy(&display_comp_ctx->constraints);
-    if (error != kErrorNone) {
-      // Composition strategies exhausted. Resource Manager could not allocate resources even for
-      // GPU composition. This will never happen.
-      exit = true;
-    }
-
-    if (!exit) {
-      error = resource_intf_->Prepare(display_resource_ctx, hw_layers);
-      // Exit if successfully prepared resource, else try next strategy.
-      exit = (error == kErrorNone);
-    }
-  }
-
-  if (error != kErrorNone) {
-    resource_intf_->Stop(display_resource_ctx, hw_layers);
-    DLOGE("Composition strategies exhausted for display = %d", display_comp_ctx->display_type);
-    return error;
-  }
-
-  error = resource_intf_->Stop(display_resource_ctx, hw_layers);
-
-  return error;
-}
-
-DisplayError CompManager::PostPrepare(Handle display_ctx, HWLayers *hw_layers) {
-  SCOPE_LOCK(locker_);
-  DisplayCompositionContext *display_comp_ctx =
-                             reinterpret_cast<DisplayCompositionContext *>(display_ctx);
-  Handle &display_resource_ctx = display_comp_ctx->display_resource_ctx;
-
-  DisplayError error = kErrorNone;
-  error = resource_intf_->PostPrepare(display_resource_ctx, hw_layers);
-  if (error != kErrorNone) {
-    return error;
-  }
-
-  display_comp_ctx->strategy->Stop();
-
-  return kErrorNone;
-}
-
-DisplayError CompManager::Commit(Handle display_ctx, HWLayers *hw_layers) {
-  SCOPE_LOCK(locker_);
-
-  DisplayCompositionContext *display_comp_ctx =
-                             reinterpret_cast<DisplayCompositionContext *>(display_ctx);
-
-  return resource_intf_->Commit(display_comp_ctx->display_resource_ctx, hw_layers);
-}
-
-DisplayError CompManager::ReConfigure(Handle display_ctx, HWLayers *hw_layers) {
-  SCOPE_LOCK(locker_);
-
-  DisplayCompositionContext *display_comp_ctx =
-                             reinterpret_cast<DisplayCompositionContext *>(display_ctx);
-  Handle &display_resource_ctx = display_comp_ctx->display_resource_ctx;
-
-  DisplayError error = kErrorUndefined;
-  resource_intf_->Start(display_resource_ctx);
-  error = resource_intf_->Prepare(display_resource_ctx, hw_layers);
-
-  if (error != kErrorNone) {
-    DLOGE("Reconfigure failed for display = %d", display_comp_ctx->display_type);
-  }
-
-  resource_intf_->Stop(display_resource_ctx, hw_layers);
-  if (error != kErrorNone) {
-      error = resource_intf_->PostPrepare(display_resource_ctx, hw_layers);
-  }
-
-  return error;
-}
-
-DisplayError CompManager::PostCommit(Handle display_ctx, HWLayers *hw_layers) {
-  SCOPE_LOCK(locker_);
-
-  DisplayError error = kErrorNone;
-  DisplayCompositionContext *display_comp_ctx =
-                             reinterpret_cast<DisplayCompositionContext *>(display_ctx);
-  configured_displays_[display_comp_ctx->display_type] = 1;
-  if (configured_displays_ == registered_displays_) {
-    safe_mode_ = false;
-  }
-
-  error = resource_intf_->PostCommit(display_comp_ctx->display_resource_ctx, hw_layers);
-  if (error != kErrorNone) {
-    return error;
-  }
-
-  display_comp_ctx->idle_fallback = false;
-
-  DLOGV_IF(kTagCompManager, "registered display bit mask 0x%x, configured display bit mask 0x%x, " \
-           "display type %d", registered_displays_, configured_displays_,
-           display_comp_ctx->display_type);
-
-  return kErrorNone;
-}
-
-void CompManager::Purge(Handle display_ctx) {
-  SCOPE_LOCK(locker_);
-
-  DisplayCompositionContext *display_comp_ctx =
-                             reinterpret_cast<DisplayCompositionContext *>(display_ctx);
-
-  resource_intf_->Purge(display_comp_ctx->display_resource_ctx);
-
-  display_comp_ctx->strategy->Purge();
-}
-
-DisplayError CompManager::SetIdleTimeoutMs(Handle display_ctx, uint32_t active_ms) {
-  SCOPE_LOCK(locker_);
-
-  DisplayCompositionContext *display_comp_ctx =
-                             reinterpret_cast<DisplayCompositionContext *>(display_ctx);
-
-  return display_comp_ctx->strategy->SetIdleTimeoutMs(active_ms);
-}
-
-void CompManager::ProcessIdleTimeout(Handle display_ctx) {
-  SCOPE_LOCK(locker_);
-
-  DisplayCompositionContext *display_comp_ctx =
-                             reinterpret_cast<DisplayCompositionContext *>(display_ctx);
-
-  if (!display_comp_ctx) {
-    return;
-  }
-
-  display_comp_ctx->idle_fallback = true;
-}
-
-void CompManager::ProcessThermalEvent(Handle display_ctx, int64_t thermal_level) {
-  SCOPE_LOCK(locker_);
-
-  DisplayCompositionContext *display_comp_ctx =
-          reinterpret_cast<DisplayCompositionContext *>(display_ctx);
-
-  if (thermal_level >= kMaxThermalLevel) {
-    display_comp_ctx->thermal_fallback_ = true;
-  } else {
-    display_comp_ctx->thermal_fallback_ = false;
-  }
-}
-
-void CompManager::ProcessIdlePowerCollapse(Handle display_ctx) {
-  SCOPE_LOCK(locker_);
-
-  DisplayCompositionContext *display_comp_ctx =
-          reinterpret_cast<DisplayCompositionContext *>(display_ctx);
-
-  if (display_comp_ctx) {
-    resource_intf_->Perform(ResourceInterface::kCmdResetScalarLUT,
-                            display_comp_ctx->display_resource_ctx);
-  }
-}
-
-DisplayError CompManager::SetMaxMixerStages(Handle display_ctx, uint32_t max_mixer_stages) {
-  SCOPE_LOCK(locker_);
-
-  DisplayError error = kErrorNone;
-  DisplayCompositionContext *display_comp_ctx =
-                             reinterpret_cast<DisplayCompositionContext *>(display_ctx);
-
-  if (display_comp_ctx) {
-    error = resource_intf_->SetMaxMixerStages(display_comp_ctx->display_resource_ctx,
-                                              max_mixer_stages);
-  }
-
-  return error;
-}
-
-void CompManager::ControlPartialUpdate(Handle display_ctx, bool enable) {
-  SCOPE_LOCK(locker_);
-
-  DisplayCompositionContext *display_comp_ctx =
-                             reinterpret_cast<DisplayCompositionContext *>(display_ctx);
-  display_comp_ctx->pu_constraints.enable = enable;
-}
-
-DisplayError CompManager::ValidateScaling(const LayerRect &crop, const LayerRect &dst,
-                                          bool rotate90) {
-  BufferLayout layout = Debug::IsUbwcTiledFrameBuffer() ? kUBWC : kLinear;
-  return resource_intf_->ValidateScaling(crop, dst, rotate90, layout, true);
-}
-
-DisplayError CompManager::ValidateAndSetCursorPosition(Handle display_ctx, HWLayers *hw_layers,
-                                                 int x, int y) {
-  DisplayCompositionContext *display_comp_ctx =
-                             reinterpret_cast<DisplayCompositionContext *>(display_ctx);
-  Handle &display_resource_ctx = display_comp_ctx->display_resource_ctx;
-  return resource_intf_->ValidateAndSetCursorPosition(display_resource_ctx, hw_layers, x, y,
-                                                      &display_comp_ctx->fb_config);
-}
-
-DisplayError CompManager::SetMaxBandwidthMode(HWBwModes mode) {
-  if ((hw_res_info_.has_dyn_bw_support == false) || (mode >= kBwModeMax)) {
-    return kErrorNotSupported;
-  }
-
-  return resource_intf_->SetMaxBandwidthMode(mode);
-}
-
-DisplayError CompManager::GetScaleLutConfig(HWScaleLutInfo *lut_info) {
-  return resource_intf_->GetScaleLutConfig(lut_info);
-}
-
-DisplayError CompManager::SetDetailEnhancerData(Handle display_ctx,
-                                                const DisplayDetailEnhancerData &de_data) {
-  SCOPE_LOCK(locker_);
-  if (!hw_res_info_.hw_dest_scalar_info.count) {
-    return kErrorResources;
-  }
-
-  DisplayCompositionContext *display_comp_ctx =
-                             reinterpret_cast<DisplayCompositionContext *>(display_ctx);
-
-  return resource_intf_->SetDetailEnhancerData(display_comp_ctx->display_resource_ctx, de_data);
-}
-
-DisplayError CompManager::SetCompositionState(Handle display_ctx,
-                                              LayerComposition composition_type, bool enable) {
-  SCOPE_LOCK(locker_);
-
-  DisplayCompositionContext *display_comp_ctx =
-                             reinterpret_cast<DisplayCompositionContext *>(display_ctx);
-
-  return display_comp_ctx->strategy->SetCompositionState(composition_type, enable);
-}
-
-DisplayError CompManager::ControlDpps(bool enable) {
-  if (dpps_ctrl_intf_) {
-    return enable ? dpps_ctrl_intf_->On() : dpps_ctrl_intf_->Off();
-  }
-
-  return kErrorNone;
-}
-
-bool CompManager::SetDisplayState(Handle display_ctx,
-                                  DisplayState state, DisplayType display_type) {
-  display_state_[display_type] = state;
-
-  switch (state) {
-  case kStateOff:
-    Purge(display_ctx);
-    configured_displays_.reset(display_type);
-    DLOGV_IF(kTagCompManager, "configured_displays_ = 0x%x", configured_displays_);
-    break;
-
-  case kStateOn:
-    if (registered_displays_.count() > 1) {
-      safe_mode_ = true;
-      DLOGV_IF(kTagCompManager, "safe_mode = %d", safe_mode_);
-    }
-    break;
-
-  default:
-    break;
-  }
-
-  return true;
-}
-
-}  // namespace sdm
diff --git a/sdm/libs/core/comp_manager.h b/sdm/libs/core/comp_manager.h
deleted file mode 100644
index 7fe4482..0000000
--- a/sdm/libs/core/comp_manager.h
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
-* Copyright (c) 2014 - 2017, The Linux Foundation. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without modification, are permitted
-* provided that the following conditions are met:
-*    * Redistributions of source code must retain the above copyright notice, this list of
-*      conditions and the following disclaimer.
-*    * Redistributions in binary form must reproduce the above copyright notice, this list of
-*      conditions and the following disclaimer in the documentation and/or other materials provided
-*      with the distribution.
-*    * Neither the name of The Linux Foundation nor the names of its contributors may be used to
-*      endorse or promote products derived from this software without specific prior written
-*      permission.
-*
-* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-* NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
-* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
-* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
-* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#ifndef __COMP_MANAGER_H__
-#define __COMP_MANAGER_H__
-
-#include <core/display_interface.h>
-#include <private/extension_interface.h>
-#include <utils/locker.h>
-#include <bitset>
-
-#include "strategy.h"
-#include "resource_default.h"
-#include "hw_interface.h"
-
-namespace sdm {
-
-class CompManager {
- public:
-  DisplayError Init(const HWResourceInfo &hw_res_info_, ExtensionInterface *extension_intf,
-                    BufferAllocator *buffer_allocator, BufferSyncHandler *buffer_sync_handler,
-                    SocketHandler *socket_handler);
-  DisplayError Deinit();
-  DisplayError RegisterDisplay(DisplayType type, const HWDisplayAttributes &display_attributes,
-                               const HWPanelInfo &hw_panel_info,
-                               const HWMixerAttributes &mixer_attributes,
-                               const DisplayConfigVariableInfo &fb_config, Handle *display_ctx);
-  DisplayError UnregisterDisplay(Handle display_ctx);
-  DisplayError ReconfigureDisplay(Handle display_ctx, const HWDisplayAttributes &display_attributes,
-                                  const HWPanelInfo &hw_panel_info,
-                                  const HWMixerAttributes &mixer_attributes,
-                                  const DisplayConfigVariableInfo &fb_config);
-  void PrePrepare(Handle display_ctx, HWLayers *hw_layers);
-  DisplayError Prepare(Handle display_ctx, HWLayers *hw_layers);
-  DisplayError Commit(Handle display_ctx, HWLayers *hw_layers);
-  DisplayError PostPrepare(Handle display_ctx, HWLayers *hw_layers);
-  DisplayError ReConfigure(Handle display_ctx, HWLayers *hw_layers);
-  DisplayError PostCommit(Handle display_ctx, HWLayers *hw_layers);
-  void Purge(Handle display_ctx);
-  DisplayError SetIdleTimeoutMs(Handle display_ctx, uint32_t active_ms);
-  void ProcessIdleTimeout(Handle display_ctx);
-  void ProcessThermalEvent(Handle display_ctx, int64_t thermal_level);
-  void ProcessIdlePowerCollapse(Handle display_ctx);
-  DisplayError SetMaxMixerStages(Handle display_ctx, uint32_t max_mixer_stages);
-  void ControlPartialUpdate(Handle display_ctx, bool enable);
-  DisplayError ValidateScaling(const LayerRect &crop, const LayerRect &dst, bool rotate90);
-  DisplayError ValidateAndSetCursorPosition(Handle display_ctx, HWLayers *hw_layers, int x, int y);
-  bool SetDisplayState(Handle display_ctx, DisplayState state, DisplayType display_type);
-  DisplayError SetMaxBandwidthMode(HWBwModes mode);
-  DisplayError GetScaleLutConfig(HWScaleLutInfo *lut_info);
-  DisplayError SetDetailEnhancerData(Handle display_ctx, const DisplayDetailEnhancerData &de_data);
-  DisplayError SetCompositionState(Handle display_ctx, LayerComposition composition_type,
-                                   bool enable);
-  DisplayError ControlDpps(bool enable);
-
- private:
-  static const int kMaxThermalLevel = 3;
-  static const int kSafeModeThreshold = 4;
-
-  void PrepareStrategyConstraints(Handle display_ctx, HWLayers *hw_layers);
-
-  struct DisplayCompositionContext {
-    Strategy *strategy = NULL;
-    StrategyConstraints constraints;
-    Handle display_resource_ctx = NULL;
-    DisplayType display_type = kPrimary;
-    uint32_t max_strategies = 0;
-    uint32_t remaining_strategies = 0;
-    bool idle_fallback = false;
-    bool thermal_fallback_ = false;
-    // Using primary panel flag of hw panel to configure Constraints. We do not need other hw
-    // panel parameters for now.
-    bool is_primary_panel = false;
-    PUConstraints pu_constraints = {};
-    DisplayConfigVariableInfo fb_config = {};
-  };
-
-  Locker locker_;
-  ResourceInterface *resource_intf_ = NULL;
-  std::bitset<kDisplayMax> registered_displays_;  // Bit mask of registered displays
-  std::bitset<kDisplayMax> configured_displays_;  // Bit mask of sucessfully configured displays
-  uint32_t display_state_[kDisplayMax] = {};
-  bool safe_mode_ = false;              // Flag to notify all displays to be in resource crunch
-                                        // mode, where strategy manager chooses the best strategy
-                                        // that uses optimal number of pipes for each display
-  HWResourceInfo hw_res_info_;
-  BufferAllocator *buffer_allocator_ = NULL;
-  ExtensionInterface *extension_intf_ = NULL;
-  uint32_t max_layers_ = kMaxSDELayers;
-  uint32_t max_sde_ext_layers_ = 0;
-  DppsControlInterface *dpps_ctrl_intf_ = NULL;
-};
-
-}  // namespace sdm
-
-#endif  // __COMP_MANAGER_H__
-
diff --git a/sdm/libs/core/core_impl.cpp b/sdm/libs/core/core_impl.cpp
deleted file mode 100644
index 5532858..0000000
--- a/sdm/libs/core/core_impl.cpp
+++ /dev/null
@@ -1,184 +0,0 @@
-/*
-* Copyright (c) 2014 - 2016, The Linux Foundation. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without modification, are permitted
-* provided that the following conditions are met:
-*    * Redistributions of source code must retain the above copyright notice, this list of
-*      conditions and the following disclaimer.
-*    * Redistributions in binary form must reproduce the above copyright notice, this list of
-*      conditions and the following disclaimer in the documentation and/or other materials provided
-*      with the distribution.
-*    * Neither the name of The Linux Foundation nor the names of its contributors may be used to
-*      endorse or promote products derived from this software without specific prior written
-*      permission.
-*
-* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-* NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
-* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
-* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
-* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#include <dlfcn.h>
-#include <signal.h>
-#include <utils/locker.h>
-#include <utils/constants.h>
-#include <utils/debug.h>
-
-#include "core_impl.h"
-#include "display_primary.h"
-#include "display_hdmi.h"
-#include "display_virtual.h"
-#include "hw_info_interface.h"
-#include "color_manager.h"
-
-#define __CLASS__ "CoreImpl"
-
-namespace sdm {
-
-CoreImpl::CoreImpl(BufferAllocator *buffer_allocator,
-                   BufferSyncHandler *buffer_sync_handler,
-                   SocketHandler *socket_handler)
-  : buffer_allocator_(buffer_allocator), buffer_sync_handler_(buffer_sync_handler),
-    socket_handler_(socket_handler) {
-}
-
-DisplayError CoreImpl::Init() {
-  SCOPE_LOCK(locker_);
-  DisplayError error = kErrorNone;
-
-  // Try to load extension library & get handle to its interface.
-  if (extension_lib_.Open(EXTENSION_LIBRARY_NAME)) {
-    if (!extension_lib_.Sym(CREATE_EXTENSION_INTERFACE_NAME,
-                            reinterpret_cast<void **>(&create_extension_intf_)) ||
-        !extension_lib_.Sym(DESTROY_EXTENSION_INTERFACE_NAME,
-                            reinterpret_cast<void **>(&destroy_extension_intf_))) {
-      DLOGE("Unable to load symbols, error = %s", extension_lib_.Error());
-      return kErrorUndefined;
-    }
-
-    error = create_extension_intf_(EXTENSION_VERSION_TAG, &extension_intf_);
-    if (error != kErrorNone) {
-      DLOGE("Unable to create interface");
-      return error;
-    }
-  } else {
-    DLOGW("Unable to load = %s, error = %s", EXTENSION_LIBRARY_NAME, extension_lib_.Error());
-  }
-
-  error = HWInfoInterface::Create(&hw_info_intf_);
-  if (error != kErrorNone) {
-    goto CleanupOnError;
-  }
-
-  error = hw_info_intf_->GetHWResourceInfo(&hw_resource_);
-  if (error != kErrorNone) {
-    goto CleanupOnError;
-  }
-
-  error = comp_mgr_.Init(hw_resource_, extension_intf_, buffer_allocator_,
-                         buffer_sync_handler_, socket_handler_);
-
-  if (error != kErrorNone) {
-    goto CleanupOnError;
-  }
-
-  error = ColorManagerProxy::Init(hw_resource_);
-  // if failed, doesn't affect display core functionalities.
-  if (error != kErrorNone) {
-    DLOGW("Unable creating color manager and continue without it.");
-  }
-
-  signal(SIGPIPE, SIG_IGN);
-  return kErrorNone;
-
-CleanupOnError:
-  if (hw_info_intf_) {
-    HWInfoInterface::Destroy(hw_info_intf_);
-  }
-
-  return error;
-}
-
-DisplayError CoreImpl::Deinit() {
-  SCOPE_LOCK(locker_);
-
-  ColorManagerProxy::Deinit();
-
-  comp_mgr_.Deinit();
-  HWInfoInterface::Destroy(hw_info_intf_);
-
-  return kErrorNone;
-}
-
-DisplayError CoreImpl::CreateDisplay(DisplayType type, DisplayEventHandler *event_handler,
-                                     DisplayInterface **intf) {
-  SCOPE_LOCK(locker_);
-
-  if (!event_handler || !intf) {
-    return kErrorParameters;
-  }
-
-  DisplayBase *display_base = NULL;
-
-  switch (type) {
-  case kPrimary:
-    display_base = new DisplayPrimary(event_handler, hw_info_intf_, buffer_sync_handler_,
-                                      buffer_allocator_, &comp_mgr_);
-    break;
-  case kHDMI:
-    display_base = new DisplayHDMI(event_handler, hw_info_intf_, buffer_sync_handler_,
-                                   buffer_allocator_, &comp_mgr_);
-    break;
-  case kVirtual:
-    display_base = new DisplayVirtual(event_handler, hw_info_intf_, buffer_sync_handler_,
-                                      buffer_allocator_, &comp_mgr_);
-    break;
-  default:
-    DLOGE("Spurious display type %d", type);
-    return kErrorParameters;
-  }
-
-  if (!display_base) {
-    return kErrorMemory;
-  }
-
-  DisplayError error = display_base->Init();
-  if (error != kErrorNone) {
-    delete display_base;
-    return error;
-  }
-
-  *intf = display_base;
-  return kErrorNone;
-}
-
-DisplayError CoreImpl::DestroyDisplay(DisplayInterface *intf) {
-  SCOPE_LOCK(locker_);
-
-  if (!intf) {
-    return kErrorParameters;
-  }
-
-  DisplayBase *display_base = static_cast<DisplayBase *>(intf);
-  display_base->Deinit();
-  delete display_base;
-
-  return kErrorNone;
-}
-
-DisplayError CoreImpl::SetMaxBandwidthMode(HWBwModes mode) {
-  SCOPE_LOCK(locker_);
-
-  return comp_mgr_.SetMaxBandwidthMode(mode);
-}
-
-DisplayError CoreImpl::GetFirstDisplayInterfaceType(HWDisplayInterfaceInfo *hw_disp_info) {
-  return hw_info_intf_->GetFirstDisplayInterfaceType(hw_disp_info);
-}
-
-}  // namespace sdm
-
diff --git a/sdm/libs/core/core_impl.h b/sdm/libs/core/core_impl.h
deleted file mode 100644
index 2647c78..0000000
--- a/sdm/libs/core/core_impl.h
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
-* Copyright (c) 2014 - 2016, The Linux Foundation. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without modification, are permitted
-* provided that the following conditions are met:
-*    * Redistributions of source code must retain the above copyright notice, this list of
-*      conditions and the following disclaimer.
-*    * Redistributions in binary form must reproduce the above copyright notice, this list of
-*      conditions and the following disclaimer in the documentation and/or other materials provided
-*      with the distribution.
-*    * Neither the name of The Linux Foundation nor the names of its contributors may be used to
-*      endorse or promote products derived from this software without specific prior written
-*      permission.
-*
-* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-* NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
-* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
-* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
-* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#ifndef __CORE_IMPL_H__
-#define __CORE_IMPL_H__
-
-#include <core/core_interface.h>
-#include <private/extension_interface.h>
-#include <private/color_interface.h>
-#include <utils/locker.h>
-#include <utils/sys.h>
-
-#include "hw_interface.h"
-#include "comp_manager.h"
-
-#define SET_REVISION(major, minor) ((major << 8) | minor)
-
-namespace sdm {
-
-class CoreImpl : public CoreInterface {
- public:
-  // This class implements display core interface revision 1.0.
-  static const uint16_t kRevision = SET_REVISION(1, 0);
-  CoreImpl(BufferAllocator *buffer_allocator, BufferSyncHandler *buffer_sync_handler,
-           SocketHandler *socket_handler);
-  virtual ~CoreImpl() { }
-
-  // This method returns the interface revision for the current display core object.
-  // Future revisions will override this method and return the appropriate revision upon query.
-  virtual uint16_t GetRevision() { return kRevision; }
-  virtual DisplayError Init();
-  virtual DisplayError Deinit();
-
-  // Methods from core interface
-  virtual DisplayError CreateDisplay(DisplayType type, DisplayEventHandler *event_handler,
-                                     DisplayInterface **intf);
-  virtual DisplayError DestroyDisplay(DisplayInterface *intf);
-  virtual DisplayError SetMaxBandwidthMode(HWBwModes mode);
-  virtual DisplayError GetFirstDisplayInterfaceType(HWDisplayInterfaceInfo *hw_disp_info);
-
- protected:
-  Locker locker_;
-  BufferAllocator *buffer_allocator_ = NULL;
-  BufferSyncHandler *buffer_sync_handler_ = NULL;
-  HWResourceInfo hw_resource_;
-  CompManager comp_mgr_;
-  HWInfoInterface *hw_info_intf_ = NULL;
-  DynLib extension_lib_;
-  ExtensionInterface *extension_intf_ = NULL;
-  CreateExtensionInterface create_extension_intf_ = NULL;
-  DestroyExtensionInterface destroy_extension_intf_ = NULL;
-  SocketHandler *socket_handler_ = NULL;
-};
-
-}  // namespace sdm
-
-#endif  // __CORE_IMPL_H__
-
diff --git a/sdm/libs/core/core_interface.cpp b/sdm/libs/core/core_interface.cpp
deleted file mode 100644
index b880298..0000000
--- a/sdm/libs/core/core_interface.cpp
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
-* Copyright (c) 2014 - 2015, 2018 The Linux Foundation. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without
-* modification, are permitted provided that the following conditions are
-* met:
-*     * Redistributions of source code must retain the above copyright
-*       notice, this list of conditions and the following disclaimer.
-*     * Redistributions in binary form must reproduce the above
-*       copyright notice, this list of conditions and the following
-*       disclaimer in the documentation and/or other materials provided
-*       with the distribution.
-*     * Neither the name of The Linux Foundation nor the names of its
-*       contributors may be used to endorse or promote products derived
-*       from this software without specific prior written permission.
-*
-* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
-* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
-* ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
-* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
-* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#include <utils/locker.h>
-#include <utils/constants.h>
-#include <utils/debug.h>
-#include <core/buffer_sync_handler.h>
-
-#include "core_impl.h"
-
-#define __CLASS__ "CoreInterface"
-
-#define GET_REVISION(version) (version >> 16)
-#define GET_DATA_ALIGNMENT(version) ((version >> 8) & 0xFF)
-#define GET_INSTRUCTION_SET(version) (version & 0xFF)
-
-namespace sdm {
-
-// Currently, we support only one client and one session for display core. So, create a global
-// singleton core object.
-struct CoreSingleton {
-  CoreSingleton() : core_impl(NULL) { }
-
-  CoreImpl *core_impl;
-  Locker locker;
-} g_core;
-
-DisplayError CoreInterface::CreateCore(BufferAllocator *buffer_allocator,
-                                       BufferSyncHandler *buffer_sync_handler,
-                                       SocketHandler *socket_handler,
-                                       CoreInterface **interface, uint32_t client_version) {
-  SCOPE_LOCK(g_core.locker);
-
-  if (!buffer_allocator || !buffer_sync_handler || !interface) {
-    return kErrorParameters;
-  }
-
-  // Check compatibility of client and core.
-  uint32_t lib_version = SDM_VERSION_TAG;
-  if (GET_REVISION(client_version) > GET_REVISION(lib_version)) {
-    return kErrorVersion;
-  } else if (GET_DATA_ALIGNMENT(client_version) != GET_DATA_ALIGNMENT(lib_version)) {
-    return kErrorDataAlignment;
-  } else if (GET_INSTRUCTION_SET(client_version) != GET_INSTRUCTION_SET(lib_version)) {
-    return kErrorInstructionSet;
-  }
-
-  CoreImpl *&core_impl = g_core.core_impl;
-  if (core_impl) {
-    return kErrorUndefined;
-  }
-
-  // Create appropriate CoreImpl object based on client version.
-  if (GET_REVISION(client_version) == CoreImpl::kRevision) {
-    core_impl = new CoreImpl(buffer_allocator, buffer_sync_handler, socket_handler);
-  } else {
-    return kErrorNotSupported;
-  }
-
-  if (!core_impl) {
-    return kErrorMemory;
-  }
-
-  DisplayError error = core_impl->Init();
-  if (error != kErrorNone) {
-    delete core_impl;
-    core_impl = NULL;
-    return error;
-  }
-
-  *interface = core_impl;
-  DLOGI("Open interface handle = %p", *interface);
-
-  return kErrorNone;
-}
-
-DisplayError CoreInterface::DestroyCore() {
-  SCOPE_LOCK(g_core.locker);
-
-  DLOGI("Close handle");
-
-  CoreImpl *&core_impl = g_core.core_impl;
-  if (!core_impl) {
-    return kErrorUndefined;
-  }
-
-  core_impl->Deinit();
-  delete core_impl;
-  core_impl = NULL;
-
-  return kErrorNone;
-}
-
-}  // namespace sdm
-
diff --git a/sdm/libs/core/display_base.cpp b/sdm/libs/core/display_base.cpp
deleted file mode 100644
index 5ae6c18..0000000
--- a/sdm/libs/core/display_base.cpp
+++ /dev/null
@@ -1,1688 +0,0 @@
-/*
-* Copyright (c) 2014 - 2018, The Linux Foundation. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without modification, are permitted
-* provided that the following conditions are met:
-*    * Redistributions of source code must retain the above copyright notice, this list of
-*      conditions and the following disclaimer.
-*    * Redistributions in binary form must reproduce the above copyright notice, this list of
-*      conditions and the following disclaimer in the documentation and/or other materials provided
-*      with the distribution.
-*    * Neither the name of The Linux Foundation nor the names of its contributors may be used to
-*      endorse or promote products derived from this software without specific prior written
-*      permission.
-*
-* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-* NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
-* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
-* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
-* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#include <stdio.h>
-#include <utils/constants.h>
-#include <utils/debug.h>
-#include <utils/formats.h>
-#include <utils/rect.h>
-#include <utils/utils.h>
-
-#include <iomanip>
-#include <map>
-#include <sstream>
-#include <string>
-#include <vector>
-#include <algorithm>
-
-#include "display_base.h"
-#include "hw_info_interface.h"
-
-#define __CLASS__ "DisplayBase"
-
-namespace sdm {
-
-// TODO(user): Have a single structure handle carries all the interface pointers and variables.
-DisplayBase::DisplayBase(DisplayType display_type, DisplayEventHandler *event_handler,
-                         HWDeviceType hw_device_type, BufferSyncHandler *buffer_sync_handler,
-                         BufferAllocator *buffer_allocator, CompManager *comp_manager,
-                         HWInfoInterface *hw_info_intf)
-  : display_type_(display_type), event_handler_(event_handler), hw_device_type_(hw_device_type),
-    buffer_sync_handler_(buffer_sync_handler), buffer_allocator_(buffer_allocator),
-    comp_manager_(comp_manager), hw_info_intf_(hw_info_intf) {
-}
-
-DisplayError DisplayBase::Init() {
-  lock_guard<recursive_mutex> obj(recursive_mutex_);
-  DisplayError error = kErrorNone;
-  hw_panel_info_ = HWPanelInfo();
-  hw_intf_->GetHWPanelInfo(&hw_panel_info_);
-
-  uint32_t active_index = 0;
-  int drop_vsync = 0;
-  hw_intf_->GetActiveConfig(&active_index);
-  hw_intf_->GetDisplayAttributes(active_index, &display_attributes_);
-  fb_config_ = display_attributes_;
-
-  error = Debug::GetMixerResolution(&mixer_attributes_.width, &mixer_attributes_.height);
-  if (error == kErrorNone) {
-    hw_intf_->SetMixerAttributes(mixer_attributes_);
-  }
-
-  error = hw_intf_->GetMixerAttributes(&mixer_attributes_);
-  if (error != kErrorNone) {
-    return error;
-  }
-
-  // Override x_pixels and y_pixels of frame buffer with mixer width and height
-  fb_config_.x_pixels = mixer_attributes_.width;
-  fb_config_.y_pixels = mixer_attributes_.height;
-
-  HWScaleLutInfo lut_info = {};
-  error = comp_manager_->GetScaleLutConfig(&lut_info);
-  if (error == kErrorNone) {
-    error = hw_intf_->SetScaleLutConfig(&lut_info);
-    if (error != kErrorNone) {
-      goto CleanupOnError;
-    }
-  }
-
-  color_mgr_ = ColorManagerProxy::CreateColorManagerProxy(display_type_, hw_intf_,
-                                                          display_attributes_, hw_panel_info_);
-
-  if (!color_mgr_) {
-    DLOGW("Unable to create ColorManagerProxy for display = %d", display_type_);
-  } else if (InitializeColorModes() != kErrorNone) {
-    DLOGW("InitColorModes failed for display = %d", display_type_);
-  }
-
-  error = comp_manager_->RegisterDisplay(display_type_, display_attributes_, hw_panel_info_,
-                                         mixer_attributes_, fb_config_, &display_comp_ctx_);
-  if (error != kErrorNone) {
-    goto CleanupOnError;
-  }
-
-  if (hw_info_intf_) {
-    HWResourceInfo hw_resource_info = HWResourceInfo();
-    hw_info_intf_->GetHWResourceInfo(&hw_resource_info);
-    auto max_mixer_stages = hw_resource_info.num_blending_stages;
-    int property_value = Debug::GetMaxPipesPerMixer(display_type_);
-    if (property_value >= 0) {
-      max_mixer_stages = std::min(UINT32(property_value), hw_resource_info.num_blending_stages);
-    }
-    DisplayBase::SetMaxMixerStages(max_mixer_stages);
-  }
-
-  Debug::GetProperty(DISABLE_HDR_LUT_GEN, &disable_hdr_lut_gen_);
-  // TODO(user): Temporary changes, to be removed when DRM driver supports
-  // Partial update with Destination scaler enabled.
-  SetPUonDestScaler();
-  Debug::Get()->GetProperty("sdm.drop_skewed_vsync", &drop_vsync);
-  drop_skewed_vsync_ = (drop_vsync == 1);
-  return kErrorNone;
-
-CleanupOnError:
-  ClearColorInfo();
-  if (display_comp_ctx_) {
-    comp_manager_->UnregisterDisplay(display_comp_ctx_);
-  }
-
-  return error;
-}
-
-DisplayError DisplayBase::Deinit() {
-  {  // Scope for lock
-    lock_guard<recursive_mutex> obj(recursive_mutex_);
-    ClearColorInfo();
-    comp_manager_->UnregisterDisplay(display_comp_ctx_);
-  }
-  HWEventsInterface::Destroy(hw_events_intf_);
-  HWInterface::Destroy(hw_intf_);
-
-  return kErrorNone;
-}
-
-DisplayError DisplayBase::BuildLayerStackStats(LayerStack *layer_stack) {
-  std::vector<Layer *> &layers = layer_stack->layers;
-  HWLayersInfo &hw_layers_info = hw_layers_.info;
-
-  hw_layers_info.stack = layer_stack;
-
-  for (auto &layer : layers) {
-    if (layer->composition == kCompositionGPUTarget) {
-      hw_layers_info.gpu_target_index = hw_layers_info.app_layer_count;
-      break;
-    }
-    hw_layers_info.app_layer_count++;
-  }
-
-  DLOGD_IF(kTagDisplay, "LayerStack layer_count: %d, app_layer_count: %d, gpu_target_index: %d, "
-           "display type: %d", layers.size(), hw_layers_info.app_layer_count,
-           hw_layers_info.gpu_target_index, display_type_);
-
-  if (!hw_layers_info.app_layer_count) {
-    DLOGW("Layer count is zero");
-    return kErrorNoAppLayers;
-  }
-
-  if (hw_layers_info.gpu_target_index) {
-    return ValidateGPUTargetParams();
-  }
-
-  return kErrorNone;
-}
-
-DisplayError DisplayBase::ValidateGPUTargetParams() {
-  HWLayersInfo &hw_layers_info = hw_layers_.info;
-  Layer *gpu_target_layer = hw_layers_info.stack->layers.at(hw_layers_info.gpu_target_index);
-
-  if (!IsValid(gpu_target_layer->src_rect)) {
-    DLOGE("Invalid src rect for GPU target layer");
-    return kErrorParameters;
-  }
-
-  if (!IsValid(gpu_target_layer->dst_rect)) {
-    DLOGE("Invalid dst rect for GPU target layer");
-    return kErrorParameters;
-  }
-
-  float layer_mixer_width = FLOAT(mixer_attributes_.width);
-  float layer_mixer_height = FLOAT(mixer_attributes_.height);
-  float fb_width = FLOAT(fb_config_.x_pixels);
-  float fb_height = FLOAT(fb_config_.y_pixels);
-  LayerRect src_domain = (LayerRect){0.0f, 0.0f, fb_width, fb_height};
-  LayerRect dst_domain = (LayerRect){0.0f, 0.0f, layer_mixer_width, layer_mixer_height};
-  LayerRect out_rect = gpu_target_layer->dst_rect;
-
-  MapRect(src_domain, dst_domain, gpu_target_layer->dst_rect, &out_rect);
-  Normalize(1, 1, &out_rect);
-
-  auto gpu_target_layer_dst_xpixels = out_rect.right - out_rect.left;
-  auto gpu_target_layer_dst_ypixels = out_rect.bottom - out_rect.top;
-
-  if (gpu_target_layer_dst_xpixels > mixer_attributes_.width ||
-    gpu_target_layer_dst_ypixels > mixer_attributes_.height) {
-    DLOGE("GPU target layer dst rect is not with in limits gpu wxh %fx%f, mixer wxh %dx%d",
-                  gpu_target_layer_dst_xpixels, gpu_target_layer_dst_ypixels,
-                  mixer_attributes_.width, mixer_attributes_.height);
-    return kErrorParameters;
-  }
-
-  return kErrorNone;
-}
-
-DisplayError DisplayBase::Prepare(LayerStack *layer_stack) {
-  lock_guard<recursive_mutex> obj(recursive_mutex_);
-  DisplayError error = kErrorNone;
-  needs_validate_ = true;
-
-  if (!active_) {
-    return kErrorPermission;
-  }
-
-  if (!layer_stack) {
-    return kErrorParameters;
-  }
-
-  DLOGI_IF(kTagDisplay, "Entering Prepare for display type : %d", display_type_);
-  error = BuildLayerStackStats(layer_stack);
-  if (error != kErrorNone) {
-    return error;
-  }
-
-  error = HandleHDR(layer_stack);
-  if (error != kErrorNone) {
-    DLOGW("HandleHDR failed");
-    return error;
-  }
-
-  if (color_mgr_ && color_mgr_->NeedsPartialUpdateDisable()) {
-    DisablePartialUpdateOneFrame();
-  }
-  // TODO(user): Temporary changes, to be removed when DRM driver supports
-  // Partial update with Destination scaler enabled.
-  if (partial_update_control_ == false || disable_pu_one_frame_ ||
-      disable_pu_on_dest_scaler_) {
-    comp_manager_->ControlPartialUpdate(display_comp_ctx_, false /* enable */);
-    disable_pu_one_frame_ = false;
-  }
-
-  comp_manager_->PrePrepare(display_comp_ctx_, &hw_layers_);
-  while (true) {
-    error = comp_manager_->Prepare(display_comp_ctx_, &hw_layers_);
-    if (error != kErrorNone) {
-      break;
-    }
-
-    error = hw_intf_->Validate(&hw_layers_);
-    if (error == kErrorNone) {
-      // Strategy is successful now, wait for Commit().
-      needs_validate_ = false;
-      break;
-    }
-    if (error == kErrorShutDown) {
-      comp_manager_->PostPrepare(display_comp_ctx_, &hw_layers_);
-      return error;
-    }
-  }
-
-  comp_manager_->PostPrepare(display_comp_ctx_, &hw_layers_);
-
-  if (error != kErrorNone) {
-    return error;
-  }
-
-  error = ValidateHDR(layer_stack);
-  if (error != kErrorNone) {
-    DLOGW("ValidateHDR failed");
-  }
-
-  DLOGI_IF(kTagDisplay, "Exiting Prepare for display type : %d", display_type_);
-  return error;
-}
-
-DisplayError DisplayBase::Commit(LayerStack *layer_stack) {
-  lock_guard<recursive_mutex> obj(recursive_mutex_);
-  DisplayError error = kErrorNone;
-
-  if (!active_) {
-    needs_validate_ = true;
-    return kErrorPermission;
-  }
-
-  if (!layer_stack) {
-    return kErrorParameters;
-  }
-
-  if (needs_validate_) {
-    DLOGE("Commit: Corresponding Prepare() is not called for display = %d", display_type_);
-    return kErrorNotValidated;
-  }
-
-  // Layer stack attributes has changed, need to Reconfigure, currently in use for Hybrid Comp
-  if (layer_stack->flags.attributes_changed) {
-    error = comp_manager_->ReConfigure(display_comp_ctx_, &hw_layers_);
-    if (error != kErrorNone) {
-      return error;
-    }
-
-    error = hw_intf_->Validate(&hw_layers_);
-    if (error != kErrorNone) {
-        return error;
-    }
-  }
-
-  DLOGI_IF(kTagDisplay, "Entering commit for display type : %d", display_type_);
-  CommitLayerParams(layer_stack);
-
-  error = comp_manager_->Commit(display_comp_ctx_, &hw_layers_);
-  if (error != kErrorNone) {
-    return error;
-  }
-
-  // check if feature list cache is dirty and pending.
-  // If dirty, need program to hardware blocks.
-  if (color_mgr_)
-    error = color_mgr_->Commit();
-  if (error != kErrorNone) {  // won't affect this execution path.
-    DLOGW("ColorManager::Commit(...) isn't working");
-  }
-
-  error = hw_intf_->Commit(&hw_layers_);
-  if (error != kErrorNone) {
-    return error;
-  }
-
-  PostCommitLayerParams(layer_stack);
-
-  if (partial_update_control_) {
-    comp_manager_->ControlPartialUpdate(display_comp_ctx_, true /* enable */);
-  }
-
-  error = comp_manager_->PostCommit(display_comp_ctx_, &hw_layers_);
-  if (error != kErrorNone) {
-    return error;
-  }
-  // Stop dropping vsync when first commit is received after idle fallback.
-  drop_hw_vsync_ = false;
-  DLOGI_IF(kTagDisplay, "Exiting commit for display type : %d", display_type_);
-  return kErrorNone;
-}
-
-DisplayError DisplayBase::Flush() {
-  lock_guard<recursive_mutex> obj(recursive_mutex_);
-  DisplayError error = kErrorNone;
-
-  if (!active_) {
-    return kErrorPermission;
-  }
-  hw_layers_.info.hw_layers.clear();
-  error = hw_intf_->Flush();
-  if (error == kErrorNone) {
-    comp_manager_->Purge(display_comp_ctx_);
-    needs_validate_ = true;
-  } else {
-    DLOGW("Unable to flush display = %d", display_type_);
-  }
-
-  return error;
-}
-
-DisplayError DisplayBase::GetDisplayState(DisplayState *state) {
-  lock_guard<recursive_mutex> obj(recursive_mutex_);
-  if (!state) {
-    return kErrorParameters;
-  }
-
-  *state = state_;
-  return kErrorNone;
-}
-
-DisplayError DisplayBase::GetNumVariableInfoConfigs(uint32_t *count) {
-  lock_guard<recursive_mutex> obj(recursive_mutex_);
-  return hw_intf_->GetNumDisplayAttributes(count);
-}
-
-DisplayError DisplayBase::GetConfig(uint32_t index, DisplayConfigVariableInfo *variable_info) {
-  lock_guard<recursive_mutex> obj(recursive_mutex_);
-  HWDisplayAttributes attrib;
-  if (hw_intf_->GetDisplayAttributes(index, &attrib) == kErrorNone) {
-    *variable_info = attrib;
-    return kErrorNone;
-  }
-
-  return kErrorNotSupported;
-}
-
-DisplayError DisplayBase::GetConfig(DisplayConfigFixedInfo *fixed_info) {
-  lock_guard<recursive_mutex> obj(recursive_mutex_);
-  fixed_info->is_cmdmode = (hw_panel_info_.mode == kModeCommand);
-
-  HWResourceInfo hw_resource_info = HWResourceInfo();
-  hw_info_intf_->GetHWResourceInfo(&hw_resource_info);
-  bool hdr_supported = hw_resource_info.has_hdr;
-  HWDisplayInterfaceInfo hw_disp_info = {};
-  hw_info_intf_->GetFirstDisplayInterfaceType(&hw_disp_info);
-  if (hw_disp_info.type == kHDMI) {
-    hdr_supported = (hdr_supported && hw_panel_info_.hdr_enabled);
-  }
-
-  fixed_info->hdr_supported = hdr_supported;
-  // Populate luminance values only if hdr will be supported on that display
-  fixed_info->max_luminance = fixed_info->hdr_supported ? hw_panel_info_.peak_luminance: 0;
-  fixed_info->average_luminance = fixed_info->hdr_supported ? hw_panel_info_.average_luminance : 0;
-  fixed_info->min_luminance = fixed_info->hdr_supported ?  hw_panel_info_.blackness_level: 0;
-  fixed_info->hdr_eotf = hw_panel_info_.hdr_eotf;
-  fixed_info->hdr_metadata_type_one = hw_panel_info_.hdr_metadata_type_one;
-
-  return kErrorNone;
-}
-
-DisplayError DisplayBase::GetActiveConfig(uint32_t *index) {
-  lock_guard<recursive_mutex> obj(recursive_mutex_);
-  return hw_intf_->GetActiveConfig(index);
-}
-
-DisplayError DisplayBase::GetVSyncState(bool *enabled) {
-  lock_guard<recursive_mutex> obj(recursive_mutex_);
-  if (!enabled) {
-    return kErrorParameters;
-  }
-
-  *enabled = vsync_enable_;
-
-  return kErrorNone;
-}
-
-DisplayState DisplayBase::GetLastPowerMode() {
-  return last_power_mode_;
-}
-
-DisplayError DisplayBase::SetDisplayState(DisplayState state, int *release_fence) {
-  lock_guard<recursive_mutex> obj(recursive_mutex_);
-  DisplayError error = kErrorNone;
-  bool active = false;
-
-  DLOGI("Set state = %d, display %d", state, display_type_);
-
-  if (state == state_) {
-    DLOGI("Same state transition is requested.");
-    return kErrorNone;
-  }
-
-  switch (state) {
-  case kStateOff:
-    hw_layers_.info.hw_layers.clear();
-    error = hw_intf_->Flush();
-    if (error == kErrorNone) {
-      error = hw_intf_->PowerOff();
-    }
-    break;
-
-  case kStateOn:
-    error = hw_intf_->PowerOn(release_fence);
-    if (error != kErrorNone) {
-      return error;
-    }
-
-    error = comp_manager_->ReconfigureDisplay(display_comp_ctx_, display_attributes_,
-                                              hw_panel_info_, mixer_attributes_, fb_config_);
-    if (error != kErrorNone) {
-      return error;
-    }
-
-    active = true;
-    last_power_mode_ = kStateOn;
-    break;
-
-  case kStateDoze:
-    error = hw_intf_->Doze(release_fence);
-    active = true;
-    last_power_mode_ = kStateDoze;
-    break;
-
-  case kStateDozeSuspend:
-    error = hw_intf_->DozeSuspend(release_fence);
-    if (display_type_ != kPrimary) {
-      active = true;
-    }
-    last_power_mode_ = kStateDozeSuspend;
-    break;
-
-  case kStateStandby:
-    error = hw_intf_->Standby();
-    last_power_mode_ = kStateStandby;
-    break;
-
-  default:
-    DLOGE("Spurious state = %d transition requested.", state);
-    return kErrorParameters;
-  }
-
-  DisablePartialUpdateOneFrame();
-
-  if (error == kErrorNone) {
-    active_ = active;
-    state_ = state;
-    comp_manager_->SetDisplayState(display_comp_ctx_, state, display_type_);
-  }
-
-  return error;
-}
-
-DisplayError DisplayBase::SetActiveConfig(uint32_t index) {
-  lock_guard<recursive_mutex> obj(recursive_mutex_);
-  DisplayError error = kErrorNone;
-  uint32_t active_index = 0;
-
-  hw_intf_->GetActiveConfig(&active_index);
-
-  if (active_index == index) {
-    return kErrorNone;
-  }
-
-  error = hw_intf_->SetDisplayAttributes(index);
-  if (error != kErrorNone) {
-    return error;
-  }
-
-  return ReconfigureDisplay();
-}
-
-DisplayError DisplayBase::SetMaxMixerStages(uint32_t max_mixer_stages) {
-  lock_guard<recursive_mutex> obj(recursive_mutex_);
-  DisplayError error = kErrorNone;
-
-  error = comp_manager_->SetMaxMixerStages(display_comp_ctx_, max_mixer_stages);
-
-  if (error == kErrorNone) {
-    max_mixer_stages_ = max_mixer_stages;
-  }
-
-  return error;
-}
-
-std::string DisplayBase::Dump() {
-  lock_guard<recursive_mutex> obj(recursive_mutex_);
-  HWDisplayAttributes attrib;
-  uint32_t active_index = 0;
-  uint32_t num_modes = 0;
-  std::ostringstream os;
-
-  hw_intf_->GetNumDisplayAttributes(&num_modes);
-  hw_intf_->GetActiveConfig(&active_index);
-  hw_intf_->GetDisplayAttributes(active_index, &attrib);
-
-  os << "device type:" << display_type_;
-  os << "\nstate: " << state_ << " vsync on: " << vsync_enable_ << " max. mixer stages: "
-    << max_mixer_stages_;
-  os << "\nnum configs: " << num_modes << " active config index: " << active_index;
-
-  DisplayConfigVariableInfo &info = attrib;
-
-  uint32_t num_hw_layers = 0;
-  if (hw_layers_.info.stack) {
-    num_hw_layers = UINT32(hw_layers_.info.hw_layers.size());
-  }
-
-  if (num_hw_layers == 0) {
-    os << "\nNo hardware layers programmed";
-    return os.str();
-  }
-
-  LayerBuffer *out_buffer = hw_layers_.info.stack->output_buffer;
-  if (out_buffer) {
-    os << "\nres: " << out_buffer->width << "x" << out_buffer->height << " format: "
-      << GetFormatString(out_buffer->format);
-  } else {
-    os.precision(2);
-    os << "\nres: " << info.x_pixels << "x" << info.y_pixels << " dpi: " << std::fixed <<
-      info.x_dpi << "x" << std::fixed << info.y_dpi << " fps: " << info.fps <<
-      " vsync period: " << info.vsync_period_ns;
-  }
-
-  HWLayersInfo &layer_info = hw_layers_.info;
-  for (uint32_t i = 0; i < layer_info.left_frame_roi.size(); i++) {
-    LayerRect &l_roi = layer_info.left_frame_roi.at(i);
-    LayerRect &r_roi = layer_info.right_frame_roi.at(i);
-
-    os << "\nROI(LTRB)#" << i << " LEFT(" << INT(l_roi.left) << " " << INT(l_roi.top) << " " <<
-      INT(l_roi.right) << " " << INT(l_roi.bottom) << ")";
-    if (IsValid(r_roi)) {
-    os << " RIGHT(" << INT(r_roi.left) << " " << INT(r_roi.top) << " " << INT(r_roi.right) << " "
-      << INT(r_roi.bottom) << ")";
-    }
-  }
-
-  LayerRect &fb_roi = layer_info.partial_fb_roi;
-  if (IsValid(fb_roi)) {
-    os << "\nPartial FB ROI(LTRB):(" << INT(fb_roi.left) << " " << INT(fb_roi.top) << " " <<
-      INT(fb_roi.right) << " " << INT(fb_roi.bottom) << ")";
-  }
-
-  const char *header  = "\n| Idx |  Comp Type |   Split   | Pipe |    W x H    |          Format          |  Src Rect (L T R B) |  Dst Rect (L T R B) |  Z |    Flags   | Deci(HxV) | CS | Rng |";  //NOLINT
-  const char *newline = "\n|-----|------------|-----------|------|-------------|--------------------------|---------------------|---------------------|----|------------|-----------|----|-----|";  //NOLINT
-  const char *format  = "\n| %3s | %10s | %9s | %4d | %4d x %4d | %24s | %4d %4d %4d %4d | %4d %4d %4d %4d | %2s | %10s | %9s | %2s | %3s |";  //NOLINT
-
-  os << "\n";
-  os << newline;
-  os << header;
-  os << newline;
-
-  for (uint32_t i = 0; i < num_hw_layers; i++) {
-    uint32_t layer_index = hw_layers_.info.index.at(i);
-    // sdm-layer from client layer stack
-    Layer *sdm_layer = hw_layers_.info.stack->layers.at(layer_index);
-    // hw-layer from hw layers info
-    Layer &hw_layer = hw_layers_.info.hw_layers.at(i);
-    LayerBuffer *input_buffer = &hw_layer.input_buffer;
-    HWLayerConfig &layer_config = hw_layers_.config[i];
-    HWRotatorSession &hw_rotator_session = layer_config.hw_rotator_session;
-
-    const char *comp_type = GetName(sdm_layer->composition);
-    const char *buffer_format = GetFormatString(input_buffer->format);
-    const char *pipe_split[2] = { "Pipe-1", "Pipe-2" };
-    char idx[8];
-
-    snprintf(idx, sizeof(idx), "%d", layer_index);
-
-    for (uint32_t count = 0; count < hw_rotator_session.hw_block_count; count++) {
-      char row[1024];
-      HWRotateInfo &rotate = hw_rotator_session.hw_rotate_info[count];
-      LayerRect &src_roi = rotate.src_roi;
-      LayerRect &dst_roi = rotate.dst_roi;
-      char rot[12] = { 0 };
-
-      snprintf(rot, sizeof(rot), "Rot-%s-%d", hw_rotator_session.mode == kRotatorInline ?
-               "inl" : "off", count + 1);
-
-      snprintf(row, sizeof(row), format, idx, comp_type, rot,
-               0, input_buffer->width, input_buffer->height, buffer_format,
-               INT(src_roi.left), INT(src_roi.top), INT(src_roi.right), INT(src_roi.bottom),
-               INT(dst_roi.left), INT(dst_roi.top), INT(dst_roi.right), INT(dst_roi.bottom),
-               "-", "-    ", "-    ", "-", "-");
-      os << row;
-      // print the below only once per layer block, fill with spaces for rest.
-      idx[0] = 0;
-      comp_type = "";
-    }
-
-    if (hw_rotator_session.hw_block_count > 0) {
-      input_buffer = &hw_rotator_session.output_buffer;
-      buffer_format = GetFormatString(input_buffer->format);
-    }
-
-    if (layer_config.use_solidfill_stage) {
-      LayerRect src_roi = layer_config.hw_solidfill_stage.roi;
-      const char *decimation = "";
-      char flags[16] = { 0 };
-      char z_order[8] = { 0 };
-      const char *color_primary = "";
-      const char *range = "";
-      char row[1024] = { 0 };
-
-      snprintf(z_order, sizeof(z_order), "%d", layer_config.hw_solidfill_stage.z_order);
-      snprintf(flags, sizeof(flags), "0x%08x", hw_layer.flags.flags);
-      snprintf(row, sizeof(row), format, idx, comp_type, pipe_split[0],
-               0, INT(src_roi.right), INT(src_roi.bottom),
-               buffer_format, INT(src_roi.left), INT(src_roi.top),
-               INT(src_roi.right), INT(src_roi.bottom), INT(src_roi.left),
-               INT(src_roi.top), INT(src_roi.right), INT(src_roi.bottom),
-               z_order, flags, decimation, color_primary, range);
-      os << row;
-      continue;
-    }
-
-    for (uint32_t count = 0; count < 2; count++) {
-      char decimation[16] = { 0 };
-      char flags[16] = { 0 };
-      char z_order[8] = { 0 };
-      char color_primary[8] = { 0 };
-      char range[8] = { 0 };
-
-      HWPipeInfo &pipe = (count == 0) ? layer_config.left_pipe : layer_config.right_pipe;
-
-      if (!pipe.valid) {
-        continue;
-      }
-
-      LayerRect src_roi = pipe.src_roi;
-      LayerRect &dst_roi = pipe.dst_roi;
-      if (hw_rotator_session.mode == kRotatorInline) {
-        src_roi = hw_rotator_session.hw_rotate_info[count].dst_roi;
-      }
-
-      snprintf(z_order, sizeof(z_order), "%d", pipe.z_order);
-      snprintf(flags, sizeof(flags), "0x%08x", hw_layer.flags.flags);
-      snprintf(decimation, sizeof(decimation), "%3d x %3d", pipe.horizontal_decimation,
-               pipe.vertical_decimation);
-      ColorMetaData &color_metadata = hw_layer.input_buffer.color_metadata;
-      snprintf(color_primary, sizeof(color_primary), "%d", color_metadata.colorPrimaries);
-      snprintf(range, sizeof(range), "%d", color_metadata.range);
-
-      char row[1024];
-      snprintf(row, sizeof(row), format, idx, comp_type, pipe_split[count],
-               pipe.pipe_id, input_buffer->width, input_buffer->height,
-               buffer_format, INT(src_roi.left), INT(src_roi.top),
-               INT(src_roi.right), INT(src_roi.bottom), INT(dst_roi.left),
-               INT(dst_roi.top), INT(dst_roi.right), INT(dst_roi.bottom),
-               z_order, flags, decimation, color_primary, range);
-
-      os << row;
-      // print the below only once per layer block, fill with spaces for rest.
-      idx[0] = 0;
-      comp_type = "";
-    }
-  }
-
-  os << newline << "\n";
-
-  return os.str();
-}
-
-const char * DisplayBase::GetName(const LayerComposition &composition) {
-  switch (composition) {
-  case kCompositionGPU:         return "GPU";
-  case kCompositionSDE:         return "SDE";
-  case kCompositionCursor:      return "CURSOR";
-  case kCompositionHybrid:      return "HYBRID";
-  case kCompositionBlit:        return "BLIT";
-  case kCompositionGPUTarget:   return "GPU_TARGET";
-  case kCompositionBlitTarget:  return "BLIT_TARGET";
-  default:                      return "UNKNOWN";
-  }
-}
-
-DisplayError DisplayBase::ColorSVCRequestRoute(const PPDisplayAPIPayload &in_payload,
-                                               PPDisplayAPIPayload *out_payload,
-                                               PPPendingParams *pending_action) {
-  lock_guard<recursive_mutex> obj(recursive_mutex_);
-  if (color_mgr_)
-    return color_mgr_->ColorSVCRequestRoute(in_payload, out_payload, pending_action);
-  else
-    return kErrorParameters;
-}
-
-DisplayError DisplayBase::GetColorModeCount(uint32_t *mode_count) {
-  lock_guard<recursive_mutex> obj(recursive_mutex_);
-  if (!mode_count) {
-    return kErrorParameters;
-  }
-
-  if (!color_mgr_) {
-    return kErrorNotSupported;
-  }
-
-  DLOGV_IF(kTagQDCM, "Number of modes from color manager = %d", num_color_modes_);
-  *mode_count = num_color_modes_;
-
-  return kErrorNone;
-}
-
-DisplayError DisplayBase::GetColorModes(uint32_t *mode_count,
-                                        std::vector<std::string> *color_modes) {
-  lock_guard<recursive_mutex> obj(recursive_mutex_);
-  if (!mode_count || !color_modes) {
-    return kErrorParameters;
-  }
-
-  if (!color_mgr_) {
-    return kErrorNotSupported;
-  }
-
-  for (uint32_t i = 0; i < num_color_modes_; i++) {
-    DLOGV_IF(kTagQDCM, "Color Mode[%d]: Name = %s mode_id = %d", i, color_modes_[i].name,
-             color_modes_[i].id);
-    color_modes->at(i) = color_modes_[i].name;
-  }
-
-  return kErrorNone;
-}
-
-DisplayError DisplayBase::GetColorModeAttr(const std::string &color_mode, AttrVal *attr) {
-  lock_guard<recursive_mutex> obj(recursive_mutex_);
-  if (!attr) {
-    return kErrorParameters;
-  }
-
-  if (!color_mgr_) {
-    return kErrorNotSupported;
-  }
-
-  auto it = color_mode_attr_map_.find(color_mode);
-  if (it == color_mode_attr_map_.end()) {
-    DLOGI("Mode %s has no attribute", color_mode.c_str());
-    return kErrorNotSupported;
-  }
-  *attr = it->second;
-
-  return kErrorNone;
-}
-
-DisplayError DisplayBase::SetColorMode(const std::string &color_mode) {
-  lock_guard<recursive_mutex> obj(recursive_mutex_);
-  if (!color_mgr_) {
-    return kErrorNotSupported;
-  }
-
-  DynamicRangeType dynamic_range_type;
-  if (IsSupportColorModeAttribute(color_mode)) {
-    auto it_mode = color_mode_attr_map_.find(color_mode);
-    std::string dynamic_range;
-    GetValueOfModeAttribute(it_mode->second, kDynamicRangeAttribute, &dynamic_range);
-    if (dynamic_range == kHdr) {
-      dynamic_range_type = kHdrType;
-    } else {
-      dynamic_range_type = kSdrType;
-    }
-  } else {
-    if (color_mode.find("hal_hdr") != std::string::npos) {
-      dynamic_range_type = kHdrType;
-    } else {
-      dynamic_range_type = kSdrType;
-    }
-  }
-
-  DisplayError error = kErrorNone;
-  if (disable_hdr_lut_gen_) {
-    error = SetColorModeInternal(color_mode);
-    if (error != kErrorNone) {
-      return error;
-    }
-    // Store the new SDR color mode request by client
-    if (dynamic_range_type == kSdrType) {
-      current_color_mode_ = color_mode;
-    }
-    return error;
-  }
-
-  if (hdr_playback_) {
-    // HDR playback on, If incoming mode is SDR mode,
-    // cache the mode and apply it after HDR playback stop.
-    if (dynamic_range_type == kHdrType) {
-      error = SetColorModeInternal(color_mode);
-      if (error != kErrorNone) {
-        return error;
-      }
-    } else if (dynamic_range_type == kSdrType) {
-      current_color_mode_ = color_mode;
-    }
-  } else {
-    // HDR playback off, do not apply HDR mode
-    if (dynamic_range_type == kHdrType) {
-      DLOGE("Failed: Forbid setting HDR Mode : %s when HDR playback off", color_mode.c_str());
-      return kErrorNotSupported;
-    }
-    error = SetColorModeInternal(color_mode);
-    if (error != kErrorNone) {
-      return error;
-    }
-    current_color_mode_ = color_mode;
-  }
-
-  return error;
-}
-
-DisplayError DisplayBase::SetColorModeById(int32_t color_mode_id) {
-  return color_mgr_->ColorMgrSetMode(color_mode_id);
-}
-
-DisplayError DisplayBase::SetColorModeInternal(const std::string &color_mode) {
-  DLOGV_IF(kTagQDCM, "Color Mode = %s", color_mode.c_str());
-
-  ColorModeMap::iterator it = color_mode_map_.find(color_mode);
-  if (it == color_mode_map_.end()) {
-    DLOGE("Failed: Unknown Mode : %s", color_mode.c_str());
-    return kErrorNotSupported;
-  }
-
-  SDEDisplayMode *sde_display_mode = it->second;
-
-  DLOGV_IF(kTagQDCM, "Color Mode Name = %s corresponding mode_id = %d", sde_display_mode->name,
-           sde_display_mode->id);
-  DisplayError error = kErrorNone;
-  error = color_mgr_->ColorMgrSetMode(sde_display_mode->id);
-  if (error != kErrorNone) {
-    DLOGE("Failed for mode id = %d", sde_display_mode->id);
-    return error;
-  }
-
-  return error;
-}
-
-DisplayError DisplayBase::GetValueOfModeAttribute(const AttrVal &attr, const std::string &type,
-                                                  std::string *value) {
-  if (!value) {
-    return kErrorParameters;
-  }
-  for (auto &it : attr) {
-    if (it.first.find(type) != std::string::npos) {
-      *value = it.second;
-    }
-  }
-
-  return kErrorNone;
-}
-
-bool DisplayBase::IsSupportColorModeAttribute(const std::string &color_mode) {
-  auto it = color_mode_attr_map_.find(color_mode);
-  if (it == color_mode_attr_map_.end()) {
-    return false;
-  }
-  return true;
-}
-
-DisplayError DisplayBase::GetHdrColorMode(std::string *color_mode, bool *found_hdr) {
-  if (!found_hdr || !color_mode) {
-    return kErrorParameters;
-  }
-  *found_hdr = false;
-  // get the default HDR mode which is value of picture quality equal to "standard"
-  for (auto &it_hdr : color_mode_attr_map_) {
-    std::string dynamic_range, pic_quality;
-    GetValueOfModeAttribute(it_hdr.second, kDynamicRangeAttribute, &dynamic_range);
-    GetValueOfModeAttribute(it_hdr.second, kPictureQualityAttribute, &pic_quality);
-    if (dynamic_range == kHdr && pic_quality == kStandard) {
-      *color_mode = it_hdr.first;
-      *found_hdr = true;
-    }
-  }
-
-  return kErrorNone;
-}
-
-DisplayError DisplayBase::SetColorTransform(const uint32_t length, const double *color_transform) {
-  lock_guard<recursive_mutex> obj(recursive_mutex_);
-  DisplayError ret = kErrorNone;
-  if (!color_mgr_) {
-    return kErrorNotSupported;
-  }
-
-  if (!color_transform) {
-    return kErrorParameters;
-  }
-
-  color_transform_active_ = false;
-  ret = color_mgr_->ColorMgrSetColorTransform(length, color_transform);
-  if (!ret) {
-    CopyColorTransformMatrix(color_transform);
-  }
-  return ret;
-}
-
-DisplayError DisplayBase::GetDefaultColorMode(std::string *color_mode) {
-  lock_guard<recursive_mutex> obj(recursive_mutex_);
-  if (!color_mode) {
-    return kErrorParameters;
-  }
-
-  if (!color_mgr_) {
-    return kErrorNotSupported;
-  }
-
-  int32_t default_id = kInvalidModeId;
-  DisplayError error = color_mgr_->ColorMgrGetDefaultModeID(&default_id);
-  if (error != kErrorNone) {
-    DLOGE("Failed for get default color mode id");
-    return error;
-  }
-
-  for (uint32_t i = 0; i < num_color_modes_; i++) {
-    if (color_modes_[i].id == default_id) {
-      *color_mode = color_modes_[i].name;
-      return kErrorNone;
-    }
-  }
-
-  return kErrorNotSupported;
-}
-
-DisplayError DisplayBase::ApplyDefaultDisplayMode() {
-  lock_guard<recursive_mutex> obj(recursive_mutex_);
-  DisplayError error = kErrorNone;
-  if (color_mgr_) {
-    error = color_mgr_->ApplyDefaultDisplayMode();
-    // Apply default mode failed
-    if (error != kErrorNone) {
-      DLOGI("default mode not found");
-      return error;
-    }
-    DeInitializeColorModes();
-    // Default mode apply is called during first frame, if file system
-    // where mode files is present, ColorManager will not find any modes.
-    // Once boot animation is complete we re-try to apply the modes, since
-    // file system should be mounted. InitColorModes needs to called again
-    error = InitializeColorModes();
-    if (error != kErrorNone) {
-      DLOGE("failed to initial modes\n");
-      return error;
-    }
-  } else {
-    return kErrorParameters;
-  }
-  return kErrorNone;
-}
-
-DisplayError DisplayBase::SetCursorPosition(int x, int y) {
-  lock_guard<recursive_mutex> obj(recursive_mutex_);
-  if (state_ != kStateOn) {
-    return kErrorNotSupported;
-  }
-
-  DisplayError error = comp_manager_->ValidateAndSetCursorPosition(display_comp_ctx_, &hw_layers_,
-                                                                   x, y);
-  if (error == kErrorNone) {
-    return hw_intf_->SetCursorPosition(&hw_layers_, x, y);
-  }
-
-  return kErrorNone;
-}
-
-DisplayError DisplayBase::GetRefreshRateRange(uint32_t *min_refresh_rate,
-                                              uint32_t *max_refresh_rate) {
-  lock_guard<recursive_mutex> obj(recursive_mutex_);
-  // The min and max refresh rates will be same when the HWPanelInfo does not contain valid rates.
-  // Usually for secondary displays, command mode panels
-  HWDisplayAttributes display_attributes;
-  uint32_t active_index = 0;
-  hw_intf_->GetActiveConfig(&active_index);
-  DisplayError error = hw_intf_->GetDisplayAttributes(active_index, &display_attributes);
-  if (error) {
-    return error;
-  }
-
-  *min_refresh_rate = display_attributes.fps;
-  *max_refresh_rate = display_attributes.fps;
-
-  return error;
-}
-
-DisplayError DisplayBase::SetVSyncState(bool enable) {
-  lock_guard<recursive_mutex> obj(recursive_mutex_);
-  DisplayError error = kErrorNone;
-  if (vsync_enable_ != enable) {
-    error = hw_intf_->SetVSyncState(enable);
-    if (error == kErrorNotSupported) {
-      if (drop_skewed_vsync_ && (hw_panel_info_.mode == kModeVideo) &&
-        enable && (current_refresh_rate_ == hw_panel_info_.min_fps)) {
-        drop_hw_vsync_ = true;
-      }
-      error = hw_events_intf_->SetEventState(HWEvent::VSYNC, enable);
-    }
-    if (error == kErrorNone) {
-      vsync_enable_ = enable;
-    }
-  }
-
-  return error;
-}
-
-DisplayError DisplayBase::ReconfigureDisplay() {
-  lock_guard<recursive_mutex> obj(recursive_mutex_);
-  DisplayError error = kErrorNone;
-  HWDisplayAttributes display_attributes;
-  HWMixerAttributes mixer_attributes;
-  HWPanelInfo hw_panel_info;
-  uint32_t active_index = 0;
-
-  error = hw_intf_->GetActiveConfig(&active_index);
-  if (error != kErrorNone) {
-    return error;
-  }
-
-  error = hw_intf_->GetDisplayAttributes(active_index, &display_attributes);
-  if (error != kErrorNone) {
-    return error;
-  }
-
-  error = hw_intf_->GetMixerAttributes(&mixer_attributes);
-  if (error != kErrorNone) {
-    return error;
-  }
-
-  error = hw_intf_->GetHWPanelInfo(&hw_panel_info);
-  if (error != kErrorNone) {
-    return error;
-  }
-
-  if (display_attributes == display_attributes_ && mixer_attributes == mixer_attributes_ &&
-      hw_panel_info == hw_panel_info_) {
-    return kErrorNone;
-  }
-
-  error = comp_manager_->ReconfigureDisplay(display_comp_ctx_, display_attributes, hw_panel_info,
-                                            mixer_attributes, fb_config_);
-  if (error != kErrorNone) {
-    return error;
-  }
-
-  // Disable partial update for one frame on any display changes
-  DisablePartialUpdateOneFrame();
-
-  display_attributes_ = display_attributes;
-  mixer_attributes_ = mixer_attributes;
-  hw_panel_info_ = hw_panel_info;
-  // TODO(user): Temporary changes, to be removed when DRM driver supports
-  // Partial update with Destination scaler enabled.
-  SetPUonDestScaler();
-
-  return kErrorNone;
-}
-
-DisplayError DisplayBase::SetMixerResolution(uint32_t width, uint32_t height) {
-  lock_guard<recursive_mutex> obj(recursive_mutex_);
-
-  DisplayError error = ReconfigureMixer(width, height);
-  if (error != kErrorNone) {
-    return error;
-  }
-
-  req_mixer_width_ = width;
-  req_mixer_height_ = height;
-
-  return kErrorNone;
-}
-
-DisplayError DisplayBase::GetMixerResolution(uint32_t *width, uint32_t *height) {
-  lock_guard<recursive_mutex> obj(recursive_mutex_);
-  if (!width || !height) {
-    return kErrorParameters;
-  }
-
-  *width = mixer_attributes_.width;
-  *height = mixer_attributes_.height;
-
-  return kErrorNone;
-}
-
-DisplayError DisplayBase::ReconfigureMixer(uint32_t width, uint32_t height) {
-  lock_guard<recursive_mutex> obj(recursive_mutex_);
-  DisplayError error = kErrorNone;
-
-  if (!width || !height) {
-    return kErrorParameters;
-  }
-
-  DLOGD_IF(kTagQDCM, "Reconfiguring mixer with width : %d, height : %d", width, height);
-  HWMixerAttributes mixer_attributes;
-  mixer_attributes.width = width;
-  mixer_attributes.height = height;
-
-  error = hw_intf_->SetMixerAttributes(mixer_attributes);
-  if (error != kErrorNone) {
-    return error;
-  }
-
-  return ReconfigureDisplay();
-}
-
-bool DisplayBase::NeedsDownScale(const LayerRect &src_rect, const LayerRect &dst_rect,
-                                 bool needs_rotation) {
-  float src_width = FLOAT(src_rect.right - src_rect.left);
-  float src_height = FLOAT(src_rect.bottom - src_rect.top);
-  float dst_width = FLOAT(dst_rect.right - dst_rect.left);
-  float dst_height = FLOAT(dst_rect.bottom - dst_rect.top);
-
-  if (needs_rotation) {
-    std::swap(src_width, src_height);
-  }
-
-  if ((src_width > dst_width) || (src_height > dst_height)) {
-    return true;
-  }
-
-  return false;
-}
-
-bool DisplayBase::NeedsMixerReconfiguration(LayerStack *layer_stack, uint32_t *new_mixer_width,
-                                            uint32_t *new_mixer_height) {
-  lock_guard<recursive_mutex> obj(recursive_mutex_);
-  uint32_t layer_count = UINT32(layer_stack->layers.size());
-
-  uint32_t fb_width  = fb_config_.x_pixels;
-  uint32_t fb_height  = fb_config_.y_pixels;
-  uint32_t fb_area = fb_width * fb_height;
-  LayerRect fb_rect = (LayerRect) {0.0f, 0.0f, FLOAT(fb_width), FLOAT(fb_height)};
-  uint32_t mixer_width = mixer_attributes_.width;
-  uint32_t mixer_height = mixer_attributes_.height;
-  uint32_t display_width = display_attributes_.x_pixels;
-  uint32_t display_height = display_attributes_.y_pixels;
-
-  RectOrientation fb_orientation = GetOrientation(fb_rect);
-  uint32_t max_layer_area = 0;
-  uint32_t max_area_layer_index = 0;
-  std::vector<Layer *> layers = layer_stack->layers;
-  uint32_t align_x = display_attributes_.is_device_split ? 4 : 2;
-  uint32_t align_y = 2;
-
-  if (req_mixer_width_ && req_mixer_height_) {
-    DLOGD_IF(kTagDisplay, "Required mixer width : %d, height : %d",
-             req_mixer_width_, req_mixer_height_);
-    *new_mixer_width = req_mixer_width_;
-    *new_mixer_height = req_mixer_height_;
-    return (req_mixer_width_ != mixer_width || req_mixer_height_ != mixer_height);
-  }
-
-  for (uint32_t i = 0; i < layer_count; i++) {
-    Layer *layer = layers.at(i);
-
-    uint32_t layer_width = UINT32(layer->src_rect.right - layer->src_rect.left);
-    uint32_t layer_height = UINT32(layer->src_rect.bottom - layer->src_rect.top);
-    uint32_t layer_area = layer_width * layer_height;
-
-    if (layer_area > max_layer_area) {
-      max_layer_area = layer_area;
-      max_area_layer_index = i;
-    }
-  }
-  DLOGV_IF(kTagDisplay, "Max area layer at index : %d", max_area_layer_index);
-
-  // TODO(user): Mark layer which needs downscaling on GPU fallback as priority layer and use MDP
-  // for composition to avoid quality mismatch between GPU and MDP switch(idle timeout usecase).
-  if (max_layer_area >= fb_area) {
-    Layer *layer = layers.at(max_area_layer_index);
-    bool needs_rotation = (layer->transform.rotation == 90.0f);
-
-    uint32_t layer_width = UINT32(layer->src_rect.right - layer->src_rect.left);
-    uint32_t layer_height = UINT32(layer->src_rect.bottom - layer->src_rect.top);
-    LayerRect layer_dst_rect = {};
-
-    RectOrientation layer_orientation = GetOrientation(layer->src_rect);
-    if (layer_orientation != kOrientationUnknown &&
-        fb_orientation != kOrientationUnknown) {
-      if (layer_orientation != fb_orientation) {
-        std::swap(layer_width, layer_height);
-      }
-    }
-
-    // Align the width and height according to fb's aspect ratio
-    *new_mixer_width = FloorToMultipleOf(UINT32((FLOAT(fb_width) / FLOAT(fb_height)) *
-                                         layer_height), align_x);
-    *new_mixer_height = FloorToMultipleOf(layer_height, align_y);
-
-    LayerRect dst_domain = {0.0f, 0.0f, FLOAT(*new_mixer_width), FLOAT(*new_mixer_height)};
-
-    MapRect(fb_rect, dst_domain, layer->dst_rect, &layer_dst_rect);
-    if (NeedsDownScale(layer->src_rect, layer_dst_rect, needs_rotation)) {
-      *new_mixer_width = display_width;
-      *new_mixer_height = display_height;
-    }
-    if (*new_mixer_width > display_width || *new_mixer_height > display_height) {
-      *new_mixer_width = display_width;
-      *new_mixer_height = display_height;
-    }
-    return true;
-  }
-
-  return false;
-}
-
-DisplayError DisplayBase::SetFrameBufferConfig(const DisplayConfigVariableInfo &variable_info) {
-  lock_guard<recursive_mutex> obj(recursive_mutex_);
-  uint32_t width = variable_info.x_pixels;
-  uint32_t height = variable_info.y_pixels;
-
-  if (width == 0 || height == 0) {
-    DLOGE("Unsupported resolution: (%dx%d)", width, height);
-    return kErrorParameters;
-  }
-
-  // Create rects to represent the new source and destination crops
-  LayerRect crop = LayerRect(0, 0, FLOAT(width), FLOAT(height));
-  LayerRect dst = LayerRect(0, 0, FLOAT(mixer_attributes_.width), FLOAT(mixer_attributes_.height));
-  // Set rotate90 to false since this is taken care of during regular composition.
-  bool rotate90 = false;
-
-  DisplayError error = comp_manager_->ValidateScaling(crop, dst, rotate90);
-  if (error != kErrorNone) {
-    DLOGE("Unsupported resolution: (%dx%d)", width, height);
-    return kErrorParameters;
-  }
-
-  error =  comp_manager_->ReconfigureDisplay(display_comp_ctx_, display_attributes_, hw_panel_info_,
-                                             mixer_attributes_, variable_info);
-  if (error != kErrorNone) {
-    return error;
-  }
-
-  fb_config_.x_pixels = width;
-  fb_config_.y_pixels = height;
-
-  DLOGI("New framebuffer resolution (%dx%d)", fb_config_.x_pixels, fb_config_.y_pixels);
-
-  return kErrorNone;
-}
-
-DisplayError DisplayBase::GetFrameBufferConfig(DisplayConfigVariableInfo *variable_info) {
-  lock_guard<recursive_mutex> obj(recursive_mutex_);
-  if (!variable_info) {
-    return kErrorParameters;
-  }
-
-  *variable_info = fb_config_;
-
-  return kErrorNone;
-}
-
-DisplayError DisplayBase::SetDetailEnhancerData(const DisplayDetailEnhancerData &de_data) {
-  lock_guard<recursive_mutex> obj(recursive_mutex_);
-  DisplayError error = comp_manager_->SetDetailEnhancerData(display_comp_ctx_, de_data);
-  if (error != kErrorNone) {
-    return error;
-  }
-  // TODO(user): Temporary changes, to be removed when DRM driver supports
-  // Partial update with Destination scaler enabled.
-  if (GetDriverType() == DriverType::DRM) {
-    if (de_data.enable) {
-      disable_pu_on_dest_scaler_ = true;
-    } else {
-      SetPUonDestScaler();
-    }
-  } else {
-    DisablePartialUpdateOneFrame();
-  }
-
-  return kErrorNone;
-}
-
-DisplayError DisplayBase::GetDisplayPort(DisplayPort *port) {
-  lock_guard<recursive_mutex> obj(recursive_mutex_);
-
-  if (!port) {
-    return kErrorParameters;
-  }
-
-  *port = hw_panel_info_.port;
-
-  return kErrorNone;
-}
-
-bool DisplayBase::IsPrimaryDisplay() {
-  lock_guard<recursive_mutex> obj(recursive_mutex_);
-
-  return hw_panel_info_.is_primary_panel;
-}
-
-DisplayError DisplayBase::SetCompositionState(LayerComposition composition_type, bool enable) {
-  lock_guard<recursive_mutex> obj(recursive_mutex_);
-
-  return comp_manager_->SetCompositionState(display_comp_ctx_, composition_type, enable);
-}
-
-void DisplayBase::CommitLayerParams(LayerStack *layer_stack) {
-  // Copy the acquire fence from clients layers  to HWLayers
-  uint32_t hw_layers_count = UINT32(hw_layers_.info.hw_layers.size());
-
-  for (uint32_t i = 0; i < hw_layers_count; i++) {
-    Layer *sdm_layer = layer_stack->layers.at(hw_layers_.info.index.at(i));
-    Layer &hw_layer = hw_layers_.info.hw_layers.at(i);
-
-    hw_layer.input_buffer.planes[0].fd = sdm_layer->input_buffer.planes[0].fd;
-    hw_layer.input_buffer.planes[0].offset = sdm_layer->input_buffer.planes[0].offset;
-    hw_layer.input_buffer.planes[0].stride = sdm_layer->input_buffer.planes[0].stride;
-    hw_layer.input_buffer.size = sdm_layer->input_buffer.size;
-    hw_layer.input_buffer.acquire_fence_fd = sdm_layer->input_buffer.acquire_fence_fd;
-  }
-
-  return;
-}
-
-void DisplayBase::PostCommitLayerParams(LayerStack *layer_stack) {
-  // Copy the release fence from HWLayers to clients layers
-    uint32_t hw_layers_count = UINT32(hw_layers_.info.hw_layers.size());
-
-  std::vector<uint32_t> fence_dup_flag;
-
-  for (uint32_t i = 0; i < hw_layers_count; i++) {
-    uint32_t sdm_layer_index = hw_layers_.info.index.at(i);
-    Layer *sdm_layer = layer_stack->layers.at(sdm_layer_index);
-    Layer &hw_layer = hw_layers_.info.hw_layers.at(i);
-
-    // Copy the release fence only once for a SDM Layer.
-    // In S3D use case, two hw layers can share the same input buffer, So make sure to merge the
-    // output fence fd and assign it to layer's input buffer release fence fd.
-    if (std::find(fence_dup_flag.begin(), fence_dup_flag.end(), sdm_layer_index) ==
-        fence_dup_flag.end()) {
-      sdm_layer->input_buffer.release_fence_fd = hw_layer.input_buffer.release_fence_fd;
-      fence_dup_flag.push_back(sdm_layer_index);
-    } else {
-      int temp = -1;
-      buffer_sync_handler_->SyncMerge(hw_layer.input_buffer.release_fence_fd,
-                                      sdm_layer->input_buffer.release_fence_fd, &temp);
-
-      if (hw_layer.input_buffer.release_fence_fd >= 0) {
-        Sys::close_(hw_layer.input_buffer.release_fence_fd);
-        hw_layer.input_buffer.release_fence_fd = -1;
-      }
-
-      if (sdm_layer->input_buffer.release_fence_fd >= 0) {
-        Sys::close_(sdm_layer->input_buffer.release_fence_fd);
-        sdm_layer->input_buffer.release_fence_fd = -1;
-      }
-
-      sdm_layer->input_buffer.release_fence_fd = temp;
-    }
-  }
-
-  return;
-}
-
-DisplayError DisplayBase::InitializeColorModes() {
-  if (!color_mgr_) {
-    return kErrorNotSupported;
-  }
-
-  DisplayError error = color_mgr_->ColorMgrGetNumOfModes(&num_color_modes_);
-  if (error != kErrorNone || !num_color_modes_) {
-    DLOGV_IF(kTagQDCM, "GetNumModes failed = %d count = %d", error, num_color_modes_);
-    return kErrorNotSupported;
-  }
-  DLOGI("Number of Color Modes = %d", num_color_modes_);
-
-  if (!color_modes_.size()) {
-    color_modes_.resize(num_color_modes_);
-
-    DisplayError error = color_mgr_->ColorMgrGetModes(&num_color_modes_, color_modes_.data());
-    if (error != kErrorNone) {
-      color_modes_.clear();
-      DLOGE("Failed");
-      return error;
-    }
-    int32_t default_id = kInvalidModeId;
-    error = color_mgr_->ColorMgrGetDefaultModeID(&default_id);
-
-    AttrVal var;
-    for (uint32_t i = 0; i < num_color_modes_; i++) {
-      DLOGV_IF(kTagQDCM, "Color Mode[%d]: Name = %s mode_id = %d", i, color_modes_[i].name,
-               color_modes_[i].id);
-      // get the name of default color mode
-      if (color_modes_[i].id == default_id) {
-        current_color_mode_ = color_modes_[i].name;
-      }
-      auto it = color_mode_map_.find(color_modes_[i].name);
-      if (it != color_mode_map_.end()) {
-        if (it->second->id < color_modes_[i].id) {
-          color_mode_map_.erase(it);
-          color_mode_map_.insert(std::make_pair(color_modes_[i].name, &color_modes_[i]));
-        }
-      } else {
-        color_mode_map_.insert(std::make_pair(color_modes_[i].name, &color_modes_[i]));
-      }
-
-      var.clear();
-      error = color_mgr_->ColorMgrGetModeInfo(color_modes_[i].id, &var);
-      if (error != kErrorNone) {
-        DLOGE("Failed for get attributes of mode_id = %d", color_modes_[i].id);
-        continue;
-      }
-      if (!var.empty()) {
-        auto it = color_mode_attr_map_.find(color_modes_[i].name);
-        if (it == color_mode_attr_map_.end()) {
-          color_mode_attr_map_.insert(std::make_pair(color_modes_[i].name, var));
-        }
-      }
-    }
-  }
-
-  return kErrorNone;
-}
-
-DisplayError DisplayBase::SetHDRMode(bool set) {
-  DisplayError error = kErrorNone;
-  std::string color_mode = "";
-
-  if (color_mgr_ && !disable_hdr_lut_gen_) {
-    // Do not apply HDR Mode when hdr lut generation is disabled
-    if (set) {
-      color_mode = "hal_hdr";
-      error = color_mgr_->ColorMgrGetActiveMode(&current_color_mode_);
-      if (error != kErrorNone) {
-        DLOGW("Failed to get active color mode");
-      }
-      if (IsSupportColorModeAttribute(current_color_mode_)) {
-        bool found_hdr = false;
-        error = GetHdrColorMode(&color_mode, &found_hdr);
-        if (!found_hdr) {
-          color_mode = "hal_hdr";
-        }
-      }
-    } else {
-      // HDR playback off - set prev mode
-      color_mode = current_color_mode_;
-    }
-    DLOGI("Setting color mode = %s", color_mode.c_str());
-    error = SetColorModeInternal(color_mode);
-    if (color_transform_active_) {
-      color_mgr_->ColorMgrSetColorTransform(kColorTransformlength_, color_transform_);
-    }
-  }
-
-  // DPPS and HDR features are mutually exclusive
-  comp_manager_->ControlDpps(!set);
-  hdr_mode_ = set;
-
-  return error;
-}
-
-DisplayError DisplayBase::HandleHDR(LayerStack *layer_stack) {
-  DisplayError error = kErrorNone;
-
-  if (display_type_ != kPrimary) {
-    // Handling is needed for only primary displays
-    return kErrorNone;
-  }
-
-  if (!layer_stack->flags.hdr_present) {
-    //  HDR playback off - set prev mode
-    if (hdr_playback_) {
-      hdr_playback_ = false;
-      if (hdr_mode_) {
-        error = SetHDRMode(false);
-      }
-    }
-  } else {
-    // hdr is present
-    if (!hdr_playback_ && !layer_stack->flags.animating) {
-      // hdr is starting
-      hdr_playback_ = true;
-      error = SetHDRMode(true);
-      if (error != kErrorNone) {
-        DLOGW("Failed to set HDR mode");
-      }
-    } else if (hdr_playback_ && !hdr_mode_) {
-      error = SetHDRMode(true);
-      if (error != kErrorNone) {
-        DLOGW("Failed to set HDR mode");
-      }
-    }
-  }
-
-  return error;
-}
-
-DisplayError DisplayBase::ValidateHDR(LayerStack *layer_stack) {
-  DisplayError error = kErrorNone;
-
-  if (display_type_ != kPrimary) {
-    // Handling is needed for only primary displays
-    return kErrorNone;
-  }
-
-  if (hdr_playback_) {
-    // HDR color mode is set when hdr layer is present in layer_stack.
-    // If client flags HDR layer as skipped, then blending happens
-    // in SDR color space. Hence, need to restore the SDR color mode.
-    if (layer_stack->blend_cs.first != ColorPrimaries_BT2020) {
-      error = SetHDRMode(false);
-      if (error != kErrorNone) {
-        DLOGW("Failed to restore SDR mode");
-      }
-    }
-  }
-
-  return kErrorNone;
-}
-
-DisplayError DisplayBase::GetClientTargetSupport(uint32_t width, uint32_t height,
-                                                 LayerBufferFormat format,
-                                                 const ColorMetaData &color_metadata) {
-  if (format != kFormatRGBA8888 && format != kFormatRGBA1010102) {
-    DLOGW("Unsupported format = %d", format);
-    return kErrorNotSupported;
-  } else if (ValidateScaling(width, height) != kErrorNone) {
-    DLOGW("Unsupported width = %d height = %d", width, height);
-    return kErrorNotSupported;
-  } else if (color_metadata.transfer && color_metadata.colorPrimaries) {
-    DisplayError error = ValidateDataspace(color_metadata);
-    if (error != kErrorNone) {
-      DLOGW("Unsupported Transfer Request = %d Color Primary = %d",
-             color_metadata.transfer, color_metadata.colorPrimaries);
-      return error;
-    }
-
-    // Check for BT2020 support
-    if (color_metadata.colorPrimaries == ColorPrimaries_BT2020) {
-      DLOGW("Unsupported Color Primary = %d", color_metadata.colorPrimaries);
-      return kErrorNotSupported;
-    }
-  }
-
-  return kErrorNone;
-}
-
-DisplayError DisplayBase::ValidateScaling(uint32_t width, uint32_t height) {
-  uint32_t display_width = display_attributes_.x_pixels;
-  uint32_t display_height = display_attributes_.y_pixels;
-
-  HWResourceInfo hw_resource_info = HWResourceInfo();
-  hw_info_intf_->GetHWResourceInfo(&hw_resource_info);
-  float max_scale_down = FLOAT(hw_resource_info.max_scale_down);
-  float max_scale_up = FLOAT(hw_resource_info.max_scale_up);
-
-  float scale_x = FLOAT(width / display_width);
-  float scale_y = FLOAT(height / display_height);
-
-  if (scale_x > max_scale_down || scale_y > max_scale_down) {
-    return kErrorNotSupported;
-  }
-
-  if (UINT32(scale_x) < 1 && scale_x > 0.0f) {
-    if ((1.0f / scale_x) > max_scale_up) {
-      return kErrorNotSupported;
-    }
-  }
-
-  if (UINT32(scale_y) < 1 && scale_y > 0.0f) {
-    if ((1.0f / scale_y) > max_scale_up) {
-      return kErrorNotSupported;
-    }
-  }
-
-  return kErrorNone;
-}
-
-DisplayError DisplayBase::ValidateDataspace(const ColorMetaData &color_metadata) {
-  // Handle transfer
-  switch (color_metadata.transfer) {
-    case Transfer_sRGB:
-    case Transfer_SMPTE_170M:
-    case Transfer_SMPTE_ST2084:
-    case Transfer_HLG:
-    case Transfer_Linear:
-    case Transfer_Gamma2_2:
-      break;
-    default:
-      DLOGW("Unsupported Transfer Request = %d", color_metadata.transfer);
-      return kErrorNotSupported;
-  }
-
-  // Handle colorPrimaries
-  switch (color_metadata.colorPrimaries) {
-    case ColorPrimaries_BT709_5:
-    case ColorPrimaries_BT601_6_525:
-    case ColorPrimaries_BT601_6_625:
-    case ColorPrimaries_DCIP3:
-    case ColorPrimaries_BT2020:
-      break;
-    default:
-      DLOGW("Unsupported Color Primary = %d", color_metadata.colorPrimaries);
-      return kErrorNotSupported;
-  }
-
-  return kErrorNone;
-}
-
-// TODO(user): Temporary changes, to be removed when DRM driver supports
-// Partial update with Destination scaler enabled.
-void DisplayBase::SetPUonDestScaler() {
-  if (GetDriverType() == DriverType::FB) {
-    return;
-  }
-  uint32_t mixer_width = mixer_attributes_.width;
-  uint32_t mixer_height = mixer_attributes_.height;
-  uint32_t display_width = display_attributes_.x_pixels;
-  uint32_t display_height = display_attributes_.y_pixels;
-
-  disable_pu_on_dest_scaler_ = (mixer_width != display_width ||
-                                mixer_height != display_height);
-}
-
-void DisplayBase::ClearColorInfo() {
-  color_modes_.clear();
-  color_mode_map_.clear();
-  color_mode_attr_map_.clear();
-
-  if (color_mgr_) {
-    delete color_mgr_;
-    color_mgr_ = NULL;
-  }
-}
-
-void DisplayBase::DeInitializeColorModes() {
-    color_mode_map_.clear();
-    color_modes_.clear();
-    color_mode_attr_map_.clear();
-    num_color_modes_ = 0;
-}
-}  // namespace sdm
diff --git a/sdm/libs/core/display_base.h b/sdm/libs/core/display_base.h
deleted file mode 100644
index 9252c00..0000000
--- a/sdm/libs/core/display_base.h
+++ /dev/null
@@ -1,205 +0,0 @@
-/*
-* Copyright (c) 2014-2018, The Linux Foundation. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without modification, are permitted
-* provided that the following conditions are met:
-*    * Redistributions of source code must retain the above copyright notice, this list of
-*      conditions and the following disclaimer.
-*    * Redistributions in binary form must reproduce the above copyright notice, this list of
-*      conditions and the following disclaimer in the documentation and/or other materials provided
-*      with the distribution.
-*    * Neither the name of The Linux Foundation nor the names of its contributors may be used to
-*      endorse or promote products derived from this software without specific prior written
-*      permission.
-*
-* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-* NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
-* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
-* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
-* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#ifndef __DISPLAY_BASE_H__
-#define __DISPLAY_BASE_H__
-
-#include <core/display_interface.h>
-#include <private/strategy_interface.h>
-#include <private/color_interface.h>
-
-#include <map>
-#include <mutex>
-#include <string>
-#include <vector>
-
-#include "hw_interface.h"
-#include "comp_manager.h"
-#include "color_manager.h"
-#include "hw_events_interface.h"
-
-namespace sdm {
-
-using std::recursive_mutex;
-using std::lock_guard;
-
-class DisplayBase : public DisplayInterface {
- public:
-  DisplayBase(DisplayType display_type, DisplayEventHandler *event_handler,
-              HWDeviceType hw_device_type, BufferSyncHandler *buffer_sync_handler,
-              BufferAllocator *buffer_allocator, CompManager *comp_manager,
-              HWInfoInterface *hw_info_intf);
-  virtual ~DisplayBase() { }
-  virtual DisplayError Init();
-  virtual DisplayError Deinit();
-  DisplayError Prepare(LayerStack *layer_stack);
-  DisplayError Commit(LayerStack *layer_stack);
-  virtual DisplayError Flush();
-  virtual DisplayError GetDisplayState(DisplayState *state);
-  virtual DisplayError GetNumVariableInfoConfigs(uint32_t *count);
-  virtual DisplayError GetConfig(uint32_t index, DisplayConfigVariableInfo *variable_info);
-  virtual DisplayError GetConfig(DisplayConfigFixedInfo *variable_info);
-  virtual DisplayError GetActiveConfig(uint32_t *index);
-  virtual DisplayError GetVSyncState(bool *enabled);
-  virtual DisplayError SetDisplayState(DisplayState state, int *release_fence);
-  virtual DisplayError SetActiveConfig(uint32_t index);
-  virtual DisplayError SetActiveConfig(DisplayConfigVariableInfo *variable_info) {
-    return kErrorNotSupported;
-  }
-  virtual DisplayError SetMaxMixerStages(uint32_t max_mixer_stages);
-  virtual DisplayError ControlPartialUpdate(bool enable, uint32_t *pending) {
-    return kErrorNotSupported;
-  }
-  virtual DisplayError DisablePartialUpdateOneFrame() {
-    return kErrorNotSupported;
-  }
-  virtual DisplayError SetDisplayMode(uint32_t mode) {
-    return kErrorNotSupported;
-  }
-  virtual bool IsUnderscanSupported() {
-    return false;
-  }
-  virtual DisplayError SetPanelBrightness(int level) {
-    return kErrorNotSupported;
-  }
-  virtual DisplayError OnMinHdcpEncryptionLevelChange(uint32_t min_enc_level) {
-    return kErrorNotSupported;
-  }
-  virtual DisplayError ColorSVCRequestRoute(const PPDisplayAPIPayload &in_payload,
-                                            PPDisplayAPIPayload *out_payload,
-                                            PPPendingParams *pending_action);
-  virtual DisplayError GetColorModeCount(uint32_t *mode_count);
-  virtual DisplayError GetColorModes(uint32_t *mode_count, std::vector<std::string> *color_modes);
-  virtual DisplayError GetColorModeAttr(const std::string &color_mode, AttrVal *attr);
-  virtual DisplayError SetColorMode(const std::string &color_mode);
-  virtual DisplayError SetColorModeById(int32_t color_mode_id);
-  virtual DisplayError SetColorTransform(const uint32_t length, const double *color_transform);
-  virtual DisplayError GetDefaultColorMode(std::string *color_mode);
-  virtual DisplayError ApplyDefaultDisplayMode(void);
-  virtual DisplayError SetCursorPosition(int x, int y);
-  virtual DisplayError GetRefreshRateRange(uint32_t *min_refresh_rate, uint32_t *max_refresh_rate);
-  virtual DisplayError GetPanelBrightness(int *level) {
-    return kErrorNotSupported;
-  }
-  virtual DisplayError SetVSyncState(bool enable);
-  virtual void SetIdleTimeoutMs(uint32_t active_ms) {}
-  virtual DisplayError SetMixerResolution(uint32_t width, uint32_t height);
-  virtual DisplayError GetMixerResolution(uint32_t *width, uint32_t *height);
-  virtual DisplayError SetFrameBufferConfig(const DisplayConfigVariableInfo &variable_info);
-  virtual DisplayError GetFrameBufferConfig(DisplayConfigVariableInfo *variable_info);
-  virtual DisplayError SetDetailEnhancerData(const DisplayDetailEnhancerData &de_data);
-  virtual DisplayError GetDisplayPort(DisplayPort *port);
-  virtual bool IsPrimaryDisplay();
-  virtual DisplayError SetCompositionState(LayerComposition composition_type, bool enable);
-  virtual DisplayError GetClientTargetSupport(uint32_t width, uint32_t height,
-                                              LayerBufferFormat format,
-                                              const ColorMetaData &color_metadata);
-  virtual std::string Dump();
-
- protected:
-  DisplayError BuildLayerStackStats(LayerStack *layer_stack);
-  virtual DisplayError ValidateGPUTargetParams();
-  void CommitLayerParams(LayerStack *layer_stack);
-  void PostCommitLayerParams(LayerStack *layer_stack);
-  DisplayError HandleHDR(LayerStack *layer_stack);
-  DisplayError ValidateHDR(LayerStack *layer_stack);
-  DisplayError SetHDRMode(bool set);
-  DisplayError ValidateScaling(uint32_t width, uint32_t height);
-  DisplayError ValidateDataspace(const ColorMetaData &color_metadata);
-
-  const char *GetName(const LayerComposition &composition);
-  DisplayError ReconfigureDisplay();
-  bool NeedsMixerReconfiguration(LayerStack *layer_stack, uint32_t *new_mixer_width,
-                                 uint32_t *new_mixer_height);
-  DisplayError ReconfigureMixer(uint32_t width, uint32_t height);
-  bool NeedsDownScale(const LayerRect &src_rect, const LayerRect &dst_rect, bool needs_rotation);
-  DisplayError InitializeColorModes();
-  void DeInitializeColorModes();
-  DisplayError SetColorModeInternal(const std::string &color_mode);
-  DisplayError GetValueOfModeAttribute(const AttrVal &attr, const std::string &type,
-                                       std::string *value);
-  DisplayError GetHdrColorMode(std::string *color_mode, bool *found_hdr);
-  bool IsSupportColorModeAttribute(const std::string &color_mode);
-  DisplayState GetLastPowerMode();
-  void SetPUonDestScaler();
-  void ClearColorInfo();
-  void CopyColorTransformMatrix(const double *input_matrix) {
-    for (uint32_t i = 0; i < kColorTransformlength_; i++) {
-      color_transform_[i] = input_matrix[i];
-    }
-    color_transform_active_ = true;
-  }
-
-  recursive_mutex recursive_mutex_;
-  DisplayType display_type_;
-  DisplayEventHandler *event_handler_ = NULL;
-  HWDeviceType hw_device_type_;
-  HWInterface *hw_intf_ = NULL;
-  HWPanelInfo hw_panel_info_;
-  BufferSyncHandler *buffer_sync_handler_ = NULL;
-  BufferAllocator *buffer_allocator_ {};
-  CompManager *comp_manager_ = NULL;
-  DisplayState state_ = kStateOff;
-  bool active_ = false;
-  Handle hw_device_ = 0;
-  Handle display_comp_ctx_ = 0;
-  HWLayers hw_layers_;
-  bool needs_validate_ = true;
-  bool vsync_enable_ = false;
-  uint32_t max_mixer_stages_ = 0;
-  HWInfoInterface *hw_info_intf_ = NULL;
-  ColorManagerProxy *color_mgr_ = NULL;  // each display object owns its ColorManagerProxy
-  bool partial_update_control_ = true;
-  HWEventsInterface *hw_events_intf_ = NULL;
-  bool disable_pu_one_frame_ = false;
-  // TODO(user): Temporary changes, to be removed when DRM driver supports
-  // Partial update with Destination scaler enabled.
-  bool disable_pu_on_dest_scaler_ = false;
-  uint32_t num_color_modes_ = 0;
-  std::vector<SDEDisplayMode> color_modes_;
-  typedef std::map<std::string, SDEDisplayMode *> ColorModeMap;
-  ColorModeMap color_mode_map_ = {};
-  typedef std::map<std::string, AttrVal> ColorModeAttrMap;
-  ColorModeAttrMap color_mode_attr_map_ = {};
-  HWDisplayAttributes display_attributes_ = {};
-  HWMixerAttributes mixer_attributes_ = {};
-  DisplayConfigVariableInfo fb_config_ = {};
-  uint32_t req_mixer_width_ = 0;
-  uint32_t req_mixer_height_ = 0;
-  std::string current_color_mode_ = "hal_native";
-  bool hdr_playback_ = false;
-  bool hdr_mode_ = false;
-  int disable_hdr_lut_gen_ = 0;
-  DisplayState last_power_mode_ = kStateOff;
-  bool drop_hw_vsync_ = false;
-  uint32_t current_refresh_rate_ = 0;
-  bool drop_skewed_vsync_ = false;
-  static const uint32_t kColorTransformlength_ = 16;
-  double color_transform_[kColorTransformlength_] = {0};
-  bool color_transform_active_ = false;
-};
-
-}  // namespace sdm
-
-#endif  // __DISPLAY_BASE_H__
diff --git a/sdm/libs/core/display_hdmi.cpp b/sdm/libs/core/display_hdmi.cpp
deleted file mode 100644
index ed9a739..0000000
--- a/sdm/libs/core/display_hdmi.cpp
+++ /dev/null
@@ -1,310 +0,0 @@
-/*
-* Copyright (c) 2014 - 2018, The Linux Foundation. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without modification, are permitted
-* provided that the following conditions are met:
-*    * Redistributions of source code must retain the above copyright notice, this list of
-*      conditions and the following disclaimer.
-*    * Redistributions in binary form must reproduce the above copyright notice, this list of
-*      conditions and the following disclaimer in the documentation and/or other materials provided
-*      with the distribution.
-*    * Neither the name of The Linux Foundation nor the names of its contributors may be used to
-*      endorse or promote products derived from this software without specific prior written
-*      permission.
-*
-* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-* NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
-* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
-* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
-* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#include <utils/constants.h>
-#include <utils/debug.h>
-#include <map>
-#include <utility>
-#include <vector>
-
-#include "display_hdmi.h"
-#include "hw_interface.h"
-#include "hw_info_interface.h"
-
-#define __CLASS__ "DisplayHDMI"
-
-namespace sdm {
-
-DisplayHDMI::DisplayHDMI(DisplayEventHandler *event_handler, HWInfoInterface *hw_info_intf,
-                         BufferSyncHandler *buffer_sync_handler, BufferAllocator *buffer_allocator,
-                         CompManager *comp_manager)
-  : DisplayBase(kHDMI, event_handler, kDeviceHDMI, buffer_sync_handler, buffer_allocator,
-                comp_manager, hw_info_intf) {
-}
-
-DisplayError DisplayHDMI::Init() {
-  lock_guard<recursive_mutex> obj(recursive_mutex_);
-
-  DisplayError error = HWInterface::Create(kHDMI, hw_info_intf_, buffer_sync_handler_,
-                                           buffer_allocator_, &hw_intf_);
-  if (error != kErrorNone) {
-    return error;
-  }
-
-  uint32_t active_mode_index;
-  char value[64] = "0";
-  Debug::GetProperty(HDMI_S3D_MODE_PROP, value);
-  HWS3DMode mode = (HWS3DMode)atoi(value);
-  if (mode > kS3DModeNone && mode < kS3DModeMax) {
-    active_mode_index = GetBestConfig(mode);
-  } else {
-    active_mode_index = GetBestConfig(kS3DModeNone);
-  }
-
-  error = hw_intf_->SetDisplayAttributes(active_mode_index);
-  if (error != kErrorNone) {
-    HWInterface::Destroy(hw_intf_);
-    return error;
-  }
-
-  error = DisplayBase::Init();
-  if (error != kErrorNone) {
-    HWInterface::Destroy(hw_intf_);
-    return error;
-  }
-
-  GetScanSupport();
-  underscan_supported_ = (scan_support_ == kScanAlwaysUnderscanned) || (scan_support_ == kScanBoth);
-
-  s3d_format_to_mode_.insert(std::pair<LayerBufferS3DFormat, HWS3DMode>
-                            (kS3dFormatNone, kS3DModeNone));
-  s3d_format_to_mode_.insert(std::pair<LayerBufferS3DFormat, HWS3DMode>
-                            (kS3dFormatLeftRight, kS3DModeLR));
-  s3d_format_to_mode_.insert(std::pair<LayerBufferS3DFormat, HWS3DMode>
-                            (kS3dFormatRightLeft, kS3DModeRL));
-  s3d_format_to_mode_.insert(std::pair<LayerBufferS3DFormat, HWS3DMode>
-                            (kS3dFormatTopBottom, kS3DModeTB));
-  s3d_format_to_mode_.insert(std::pair<LayerBufferS3DFormat, HWS3DMode>
-                            (kS3dFormatFramePacking, kS3DModeFP));
-
-  error = HWEventsInterface::Create(INT(display_type_), this, event_list_, hw_intf_,
-                                    &hw_events_intf_);
-  if (error != kErrorNone) {
-    DisplayBase::Deinit();
-    HWInterface::Destroy(hw_intf_);
-    DLOGE("Failed to create hardware events interface. Error = %d", error);
-  }
-
-  current_refresh_rate_ = hw_panel_info_.max_fps;
-
-  return error;
-}
-
-DisplayError DisplayHDMI::Prepare(LayerStack *layer_stack) {
-  lock_guard<recursive_mutex> obj(recursive_mutex_);
-  DisplayError error = kErrorNone;
-  uint32_t new_mixer_width = 0;
-  uint32_t new_mixer_height = 0;
-  uint32_t display_width = display_attributes_.x_pixels;
-  uint32_t display_height = display_attributes_.y_pixels;
-
-  if (NeedsMixerReconfiguration(layer_stack, &new_mixer_width, &new_mixer_height)) {
-    error = ReconfigureMixer(new_mixer_width, new_mixer_height);
-    if (error != kErrorNone) {
-      ReconfigureMixer(display_width, display_height);
-    }
-  }
-
-  SetS3DMode(layer_stack);
-
-  // Clean hw layers for reuse.
-  hw_layers_ = HWLayers();
-
-  return DisplayBase::Prepare(layer_stack);
-}
-
-DisplayError DisplayHDMI::GetRefreshRateRange(uint32_t *min_refresh_rate,
-                                              uint32_t *max_refresh_rate) {
-  lock_guard<recursive_mutex> obj(recursive_mutex_);
-  DisplayError error = kErrorNone;
-
-  if (hw_panel_info_.min_fps && hw_panel_info_.max_fps) {
-    *min_refresh_rate = hw_panel_info_.min_fps;
-    *max_refresh_rate = hw_panel_info_.max_fps;
-  } else {
-    error = DisplayBase::GetRefreshRateRange(min_refresh_rate, max_refresh_rate);
-  }
-
-  return error;
-}
-
-DisplayError DisplayHDMI::SetRefreshRate(uint32_t refresh_rate, bool final_rate) {
-  lock_guard<recursive_mutex> obj(recursive_mutex_);
-
-  if (!active_) {
-    return kErrorPermission;
-  }
-
-  if (current_refresh_rate_ != refresh_rate) {
-    DisplayError error = hw_intf_->SetRefreshRate(refresh_rate);
-    if (error != kErrorNone) {
-      return error;
-    }
-  }
-
-  current_refresh_rate_ = refresh_rate;
-  return DisplayBase::ReconfigureDisplay();
-}
-
-bool DisplayHDMI::IsUnderscanSupported() {
-  lock_guard<recursive_mutex> obj(recursive_mutex_);
-  return underscan_supported_;
-}
-
-DisplayError DisplayHDMI::OnMinHdcpEncryptionLevelChange(uint32_t min_enc_level) {
-  lock_guard<recursive_mutex> obj(recursive_mutex_);
-  return hw_intf_->OnMinHdcpEncryptionLevelChange(min_enc_level);
-}
-
-uint32_t DisplayHDMI::GetBestConfig(HWS3DMode s3d_mode) {
-  uint32_t best_index = 0, index;
-  uint32_t num_modes = 0;
-
-  hw_intf_->GetNumDisplayAttributes(&num_modes);
-
-  // Get display attribute for each mode
-  std::vector<HWDisplayAttributes> attrib(num_modes);
-  for (index = 0; index < num_modes; index++) {
-    hw_intf_->GetDisplayAttributes(index, &attrib[index]);
-  }
-
-  // Select best config for s3d_mode. If s3d is not enabled, s3d_mode is kS3DModeNone
-  for (index = 0; index < num_modes; index ++) {
-    if (attrib[index].s3d_config[s3d_mode]) {
-      break;
-    }
-  }
-
-  index = 0;
-  best_index = UINT32(index);
-  for (size_t index = best_index + 1; index < num_modes; index ++) {
-    // TODO(user): Need to add support to S3D modes
-    // From the available configs, select the best
-    // Ex: 1920x1080@60Hz is better than 1920x1080@30 and 1920x1080@30 is better than 1280x720@60
-    if (attrib[index].x_pixels > attrib[best_index].x_pixels) {
-      best_index = UINT32(index);
-    } else if (attrib[index].x_pixels == attrib[best_index].x_pixels) {
-      if (attrib[index].y_pixels > attrib[best_index].y_pixels) {
-        best_index = UINT32(index);
-      } else if (attrib[index].y_pixels == attrib[best_index].y_pixels) {
-        if (attrib[index].vsync_period_ns < attrib[best_index].vsync_period_ns) {
-          best_index = UINT32(index);
-        }
-      }
-    }
-  }
-  char val[kPropertyMax]={};
-  // Used for changing HDMI Resolution - override the best with user set config
-  bool user_config = (Debug::GetExternalResolution(val));
-
-  if (user_config) {
-    uint32_t config_index = 0;
-    // For the config, get the corresponding index
-    DisplayError error = hw_intf_->GetConfigIndex(val, &config_index);
-    if (error == kErrorNone)
-      return config_index;
-  }
-
-  return best_index;
-}
-
-void DisplayHDMI::GetScanSupport() {
-  DisplayError error = kErrorNone;
-  uint32_t video_format = 0;
-  uint32_t max_cea_format = 0;
-  HWScanInfo scan_info = HWScanInfo();
-  hw_intf_->GetHWScanInfo(&scan_info);
-
-  uint32_t active_mode_index = 0;
-  hw_intf_->GetActiveConfig(&active_mode_index);
-
-  error = hw_intf_->GetVideoFormat(active_mode_index, &video_format);
-  if (error != kErrorNone) {
-    return;
-  }
-
-  error = hw_intf_->GetMaxCEAFormat(&max_cea_format);
-  if (error != kErrorNone) {
-    return;
-  }
-
-  // The scan support for a given HDMI TV must be read from scan info corresponding to
-  // Preferred Timing if the preferred timing of the display is currently active, and if it is
-  // valid. In all other cases, we must read the scan support from CEA scan info if
-  // the resolution is a CEA resolution, or from IT scan info for all other resolutions.
-  if (active_mode_index == 0 && scan_info.pt_scan_support != kScanNotSupported) {
-    scan_support_ = scan_info.pt_scan_support;
-  } else if (video_format < max_cea_format) {
-    scan_support_ = scan_info.cea_scan_support;
-  } else {
-    scan_support_ = scan_info.it_scan_support;
-  }
-}
-
-void DisplayHDMI::SetS3DMode(LayerStack *layer_stack) {
-  uint32_t s3d_layer_count = 0;
-  HWS3DMode s3d_mode = kS3DModeNone;
-  uint32_t layer_count = UINT32(layer_stack->layers.size());
-
-  // S3D mode is supported for the following scenarios:
-  // 1. Layer stack containing only one s3d layer which is not skip
-  // 2. Layer stack containing only one secure layer along with one s3d layer
-  for (uint32_t i = 0; i < layer_count; i++) {
-    Layer *layer = layer_stack->layers.at(i);
-    LayerBuffer &layer_buffer = layer->input_buffer;
-
-    if (layer_buffer.s3d_format != kS3dFormatNone) {
-      s3d_layer_count++;
-      if (s3d_layer_count > 1 || layer->flags.skip) {
-        s3d_mode = kS3DModeNone;
-        break;
-      }
-
-      std::map<LayerBufferS3DFormat, HWS3DMode>::iterator it =
-                s3d_format_to_mode_.find(layer_buffer.s3d_format);
-      if (it != s3d_format_to_mode_.end()) {
-        s3d_mode = it->second;
-      }
-    } else if (layer_buffer.flags.secure && layer_count > 2) {
-        s3d_mode = kS3DModeNone;
-        break;
-    }
-  }
-
-  if (hw_intf_->SetS3DMode(s3d_mode) != kErrorNone) {
-    hw_intf_->SetS3DMode(kS3DModeNone);
-    layer_stack->flags.s3d_mode_present = false;
-  } else if (s3d_mode != kS3DModeNone) {
-    layer_stack->flags.s3d_mode_present = true;
-  }
-
-  DisplayBase::ReconfigureDisplay();
-}
-
-void DisplayHDMI::CECMessage(char *message) {
-  event_handler_->CECMessage(message);
-}
-
-DisplayError DisplayHDMI::VSync(int64_t timestamp) {
-  if (vsync_enable_) {
-    DisplayEventVSync vsync;
-    vsync.timestamp = timestamp;
-    event_handler_->VSync(vsync);
-  }
-
-  return kErrorNone;
-}
-
-}  // namespace sdm
-
diff --git a/sdm/libs/core/display_hdmi.h b/sdm/libs/core/display_hdmi.h
deleted file mode 100644
index 64aa6c7..0000000
--- a/sdm/libs/core/display_hdmi.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
-* Copyright (c) 2014 - 2017, The Linux Foundation. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without modification, are permitted
-* provided that the following conditions are met:
-*    * Redistributions of source code must retain the above copyright notice, this list of
-*      conditions and the following disclaimer.
-*    * Redistributions in binary form must reproduce the above copyright notice, this list of
-*      conditions and the following disclaimer in the documentation and/or other materials provided
-*      with the distribution.
-*    * Neither the name of The Linux Foundation nor the names of its contributors may be used to
-*      endorse or promote products derived from this software without specific prior written
-*      permission.
-*
-* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-* NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
-* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
-* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
-* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#ifndef __DISPLAY_HDMI_H__
-#define __DISPLAY_HDMI_H__
-
-#include <vector>
-#include <map>
-
-#include "display_base.h"
-#include "hw_events_interface.h"
-
-namespace sdm {
-
-class HWHDMIInterface;
-
-class DisplayHDMI : public DisplayBase, HWEventHandler {
- public:
-  DisplayHDMI(DisplayEventHandler *event_handler, HWInfoInterface *hw_info_intf,
-              BufferSyncHandler *buffer_sync_handler, BufferAllocator *buffer_allocator,
-              CompManager *comp_manager);
-  virtual DisplayError Init();
-  virtual DisplayError Prepare(LayerStack *layer_stack);
-  virtual DisplayError GetRefreshRateRange(uint32_t *min_refresh_rate, uint32_t *max_refresh_rate);
-  virtual DisplayError SetRefreshRate(uint32_t refresh_rate, bool final_rate);
-  virtual bool IsUnderscanSupported();
-  virtual DisplayError OnMinHdcpEncryptionLevelChange(uint32_t min_enc_level);
-
-  // Implement the HWEventHandlers
-  virtual DisplayError VSync(int64_t timestamp);
-  virtual DisplayError Blank(bool blank) { return kErrorNone; }
-  virtual void IdleTimeout() { }
-  virtual void ThermalEvent(int64_t thermal_level) { }
-  virtual void CECMessage(char *message);
-  virtual void IdlePowerCollapse() { }
-  virtual void PingPongTimeout() { }
-  virtual void PanelDead() { }
-
- private:
-  uint32_t GetBestConfig(HWS3DMode s3d_mode);
-  void GetScanSupport();
-  void SetS3DMode(LayerStack *layer_stack);
-  static const int kPropertyMax = 256;
-
-  bool underscan_supported_ = false;
-  HWScanSupport scan_support_;
-  std::map<LayerBufferS3DFormat, HWS3DMode> s3d_format_to_mode_;
-  std::vector<HWEvent> event_list_ = { HWEvent::VSYNC, HWEvent::IDLE_NOTIFY, HWEvent::EXIT,
-    HWEvent::CEC_READ_MESSAGE };
-  uint32_t current_refresh_rate_ = 0;
-};
-
-}  // namespace sdm
-
-#endif  // __DISPLAY_HDMI_H__
diff --git a/sdm/libs/core/display_primary.cpp b/sdm/libs/core/display_primary.cpp
deleted file mode 100644
index ba83d05..0000000
--- a/sdm/libs/core/display_primary.cpp
+++ /dev/null
@@ -1,420 +0,0 @@
-/*
-* Copyright (c) 2014 - 2018, The Linux Foundation. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without modification, are permitted
-* provided that the following conditions are met:
-*    * Redistributions of source code must retain the above copyright notice, this list of
-*      conditions and the following disclaimer.
-*    * Redistributions in binary form must reproduce the above copyright notice, this list of
-*      conditions and the following disclaimer in the documentation and/or other materials provided
-*      with the distribution.
-*    * Neither the name of The Linux Foundation nor the names of its contributors may be used to
-*      endorse or promote products derived from this software without specific prior written
-*      permission.
-*
-* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-* NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
-* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
-* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
-* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#include <utils/constants.h>
-#include <utils/debug.h>
-#include <utils/rect.h>
-#include <map>
-#include <algorithm>
-#include <functional>
-#include <vector>
-
-#include "display_primary.h"
-#include "hw_interface.h"
-#include "hw_info_interface.h"
-
-#define __CLASS__ "DisplayPrimary"
-
-namespace sdm {
-
-DisplayPrimary::DisplayPrimary(DisplayEventHandler *event_handler, HWInfoInterface *hw_info_intf,
-                               BufferSyncHandler *buffer_sync_handler,
-                               BufferAllocator *buffer_allocator, CompManager *comp_manager)
-  : DisplayBase(kPrimary, event_handler, kDevicePrimary, buffer_sync_handler, buffer_allocator,
-                comp_manager, hw_info_intf) {
-}
-
-DisplayError DisplayPrimary::Init() {
-  lock_guard<recursive_mutex> obj(recursive_mutex_);
-
-  DisplayError error = HWInterface::Create(kPrimary, hw_info_intf_, buffer_sync_handler_,
-                                           buffer_allocator_, &hw_intf_);
-  if (error != kErrorNone) {
-    return error;
-  }
-
-  error = DisplayBase::Init();
-  if (error != kErrorNone) {
-    HWInterface::Destroy(hw_intf_);
-    return error;
-  }
-
-  if (hw_panel_info_.mode == kModeCommand && Debug::IsVideoModeEnabled()) {
-    error = hw_intf_->SetDisplayMode(kModeVideo);
-    if (error != kErrorNone) {
-      DLOGW("Retaining current display mode. Current = %d, Requested = %d", hw_panel_info_.mode,
-            kModeVideo);
-    }
-  }
-
-  if (hw_panel_info_.mode == kModeCommand) {
-    event_list_ = { HWEvent::VSYNC,
-                    HWEvent::EXIT,
-                    HWEvent::SHOW_BLANK_EVENT,
-                    HWEvent::THERMAL_LEVEL,
-                    HWEvent::IDLE_POWER_COLLAPSE,
-                    HWEvent::PINGPONG_TIMEOUT,
-                    HWEvent::PANEL_DEAD };
-  } else {
-    event_list_ = { HWEvent::VSYNC,
-                    HWEvent::EXIT,
-                    HWEvent::IDLE_NOTIFY,
-                    HWEvent::SHOW_BLANK_EVENT,
-                    HWEvent::THERMAL_LEVEL,
-                    HWEvent::PINGPONG_TIMEOUT,
-                    HWEvent::PANEL_DEAD };
-  }
-
-  avr_prop_disabled_ = Debug::IsAVRDisabled();
-
-  error = HWEventsInterface::Create(INT(display_type_), this, event_list_, hw_intf_,
-                                    &hw_events_intf_);
-  if (error != kErrorNone) {
-    DLOGE("Failed to create hardware events interface. Error = %d", error);
-    DisplayBase::Deinit();
-    HWInterface::Destroy(hw_intf_);
-  }
-
-  current_refresh_rate_ = hw_panel_info_.max_fps;
-
-  return error;
-}
-
-DisplayError DisplayPrimary::Prepare(LayerStack *layer_stack) {
-  lock_guard<recursive_mutex> obj(recursive_mutex_);
-  DisplayError error = kErrorNone;
-  uint32_t new_mixer_width = 0;
-  uint32_t new_mixer_height = 0;
-  uint32_t display_width = display_attributes_.x_pixels;
-  uint32_t display_height = display_attributes_.y_pixels;
-
-  if (reset_panel_) {
-    DLOGW("panel is in bad state, resetting the panel");
-    ResetPanel();
-    reset_panel_ = false;
-  }
-
-  if (NeedsMixerReconfiguration(layer_stack, &new_mixer_width, &new_mixer_height)) {
-    error = ReconfigureMixer(new_mixer_width, new_mixer_height);
-    if (error != kErrorNone) {
-      ReconfigureMixer(display_width, display_height);
-    }
-  }
-
-  // Clean hw layers for reuse.
-  hw_layers_ = HWLayers();
-  hw_layers_.hw_avr_info.enable = NeedsAVREnable();
-
-  return DisplayBase::Prepare(layer_stack);
-}
-
-DisplayError DisplayPrimary::Commit(LayerStack *layer_stack) {
-  lock_guard<recursive_mutex> obj(recursive_mutex_);
-  DisplayError error = kErrorNone;
-  uint32_t app_layer_count = hw_layers_.info.app_layer_count;
-
-  // Enabling auto refresh is async and needs to happen before commit ioctl
-  if (hw_panel_info_.mode == kModeCommand) {
-    bool enable = (app_layer_count == 1) && layer_stack->flags.single_buffered_layer_present;
-    bool need_refresh = layer_stack->flags.single_buffered_layer_present && (app_layer_count > 1);
-
-    hw_intf_->SetAutoRefresh(enable);
-    if (need_refresh) {
-      event_handler_->Refresh();
-    }
-  }
-
-  error = DisplayBase::Commit(layer_stack);
-  if (error != kErrorNone) {
-    return error;
-  }
-
-  DisplayBase::ReconfigureDisplay();
-
-  int idle_time_ms = hw_layers_.info.set_idle_time_ms;
-  if (idle_time_ms >= 0) {
-    hw_intf_->SetIdleTimeoutMs(UINT32(idle_time_ms));
-  }
-
-  if (switch_to_cmd_) {
-    uint32_t pending;
-    switch_to_cmd_ = false;
-    ControlPartialUpdate(true /* enable */, &pending);
-  }
-
-  return error;
-}
-
-DisplayError DisplayPrimary::SetDisplayState(DisplayState state, int *release_fence) {
-  lock_guard<recursive_mutex> obj(recursive_mutex_);
-  DisplayError error = kErrorNone;
-  error = DisplayBase::SetDisplayState(state, release_fence);
-  if (error != kErrorNone) {
-    return error;
-  }
-
-  // Set vsync enable state to false, as driver disables vsync during display power off.
-  if (state == kStateOff) {
-    vsync_enable_ = false;
-  }
-
-  return kErrorNone;
-}
-
-void DisplayPrimary::SetIdleTimeoutMs(uint32_t active_ms) {
-  lock_guard<recursive_mutex> obj(recursive_mutex_);
-  comp_manager_->SetIdleTimeoutMs(display_comp_ctx_, active_ms);
-}
-
-DisplayError DisplayPrimary::SetDisplayMode(uint32_t mode) {
-  DisplayError error = kErrorNone;
-
-  // Limit scope of mutex to this block
-  {
-    lock_guard<recursive_mutex> obj(recursive_mutex_);
-    HWDisplayMode hw_display_mode = static_cast<HWDisplayMode>(mode);
-    uint32_t pending = 0;
-
-    if (!active_) {
-      DLOGW("Invalid display state = %d. Panel must be on.", state_);
-      return kErrorNotSupported;
-    }
-
-    if (hw_display_mode != kModeCommand && hw_display_mode != kModeVideo) {
-      DLOGW("Invalid panel mode parameters. Requested = %d", hw_display_mode);
-      return kErrorParameters;
-    }
-
-    if (hw_display_mode == hw_panel_info_.mode) {
-      DLOGW("Same display mode requested. Current = %d, Requested = %d", hw_panel_info_.mode,
-            hw_display_mode);
-      return kErrorNone;
-    }
-
-    error = hw_intf_->SetDisplayMode(hw_display_mode);
-    if (error != kErrorNone) {
-      DLOGW("Retaining current display mode. Current = %d, Requested = %d", hw_panel_info_.mode,
-            hw_display_mode);
-      return error;
-    }
-
-    if (mode == kModeVideo) {
-      ControlPartialUpdate(false /* enable */, &pending);
-    } else if (mode == kModeCommand) {
-      // Flush idle timeout value currently set.
-      comp_manager_->SetIdleTimeoutMs(display_comp_ctx_, 0);
-      switch_to_cmd_ = true;
-    }
-  }
-
-  // Request for a new draw cycle. New display mode will get applied on next draw cycle.
-  // New idle time will get configured as part of this.
-  event_handler_->Refresh();
-
-  return error;
-}
-
-DisplayError DisplayPrimary::SetPanelBrightness(int level) {
-  lock_guard<recursive_mutex> obj(recursive_mutex_);
-  return hw_intf_->SetPanelBrightness(level);
-}
-
-DisplayError DisplayPrimary::GetRefreshRateRange(uint32_t *min_refresh_rate,
-                                                 uint32_t *max_refresh_rate) {
-  lock_guard<recursive_mutex> obj(recursive_mutex_);
-  DisplayError error = kErrorNone;
-
-  if (hw_panel_info_.min_fps && hw_panel_info_.max_fps) {
-    *min_refresh_rate = hw_panel_info_.min_fps;
-    *max_refresh_rate = hw_panel_info_.max_fps;
-  } else {
-    error = DisplayBase::GetRefreshRateRange(min_refresh_rate, max_refresh_rate);
-  }
-
-  return error;
-}
-
-DisplayError DisplayPrimary::SetRefreshRate(uint32_t refresh_rate, bool final_rate) {
-  lock_guard<recursive_mutex> obj(recursive_mutex_);
-
-  if (!active_ || !hw_panel_info_.dynamic_fps) {
-    return kErrorNotSupported;
-  }
-
-  if (refresh_rate < hw_panel_info_.min_fps || refresh_rate > hw_panel_info_.max_fps) {
-    DLOGE("Invalid Fps = %d request", refresh_rate);
-    return kErrorParameters;
-  }
-
-  if (handle_idle_timeout_ && !final_rate) {
-    refresh_rate = hw_panel_info_.min_fps;
-  }
-
-  if ((current_refresh_rate_ != refresh_rate) || handle_idle_timeout_) {
-    DisplayError error = hw_intf_->SetRefreshRate(refresh_rate);
-    if (error != kErrorNone) {
-      return error;
-    }
-  }
-
-  // On success, set current refresh rate to new refresh rate
-  current_refresh_rate_ = refresh_rate;
-  handle_idle_timeout_ = false;
-
-  return DisplayBase::ReconfigureDisplay();
-}
-
-DisplayError DisplayPrimary::VSync(int64_t timestamp) {
-  if (vsync_enable_ && !drop_hw_vsync_) {
-    DisplayEventVSync vsync;
-    vsync.timestamp = timestamp;
-    event_handler_->VSync(vsync);
-  }
-
-  return kErrorNone;
-}
-
-void DisplayPrimary::IdleTimeout() {
-  if (hw_panel_info_.mode == kModeVideo) {
-    if (event_handler_->HandleEvent(kIdleTimeout) != kErrorNone) {
-      return;
-    }
-    handle_idle_timeout_ = true;
-    event_handler_->Refresh();
-    lock_guard<recursive_mutex> obj(recursive_mutex_);
-    comp_manager_->ProcessIdleTimeout(display_comp_ctx_);
-  }
-}
-
-void DisplayPrimary::PingPongTimeout() {
-  lock_guard<recursive_mutex> obj(recursive_mutex_);
-  hw_intf_->DumpDebugData();
-}
-
-void DisplayPrimary::ThermalEvent(int64_t thermal_level) {
-  event_handler_->HandleEvent(kThermalEvent);
-  lock_guard<recursive_mutex> obj(recursive_mutex_);
-  comp_manager_->ProcessThermalEvent(display_comp_ctx_, thermal_level);
-}
-
-void DisplayPrimary::IdlePowerCollapse() {
-  if (hw_panel_info_.mode == kModeCommand) {
-    event_handler_->HandleEvent(kIdlePowerCollapse);
-    lock_guard<recursive_mutex> obj(recursive_mutex_);
-    comp_manager_->ProcessIdlePowerCollapse(display_comp_ctx_);
-  }
-}
-
-void DisplayPrimary::PanelDead() {
-  event_handler_->HandleEvent(kPanelDeadEvent);
-  event_handler_->Refresh();
-  {
-    lock_guard<recursive_mutex> obj(recursive_mutex_);
-    reset_panel_ = true;
-  }
-}
-
-DisplayError DisplayPrimary::GetPanelBrightness(int *level) {
-  lock_guard<recursive_mutex> obj(recursive_mutex_);
-  return hw_intf_->GetPanelBrightness(level);
-}
-
-DisplayError DisplayPrimary::ControlPartialUpdate(bool enable, uint32_t *pending) {
-  lock_guard<recursive_mutex> obj(recursive_mutex_);
-  if (!pending) {
-    return kErrorParameters;
-  }
-
-  if (!hw_panel_info_.partial_update) {
-    // Nothing to be done.
-    DLOGI("partial update is not applicable for display=%d", display_type_);
-    return kErrorNotSupported;
-  }
-
-  *pending = 0;
-  if (enable == partial_update_control_) {
-    DLOGI("Same state transition is requested.");
-    return kErrorNone;
-  }
-
-  partial_update_control_ = enable;
-
-  if (!enable) {
-    // If the request is to turn off feature, new draw call is required to have
-    // the new setting into effect.
-    *pending = 1;
-  }
-
-  return kErrorNone;
-}
-
-DisplayError DisplayPrimary::DisablePartialUpdateOneFrame() {
-  lock_guard<recursive_mutex> obj(recursive_mutex_);
-  disable_pu_one_frame_ = true;
-
-  return kErrorNone;
-}
-
-bool DisplayPrimary::NeedsAVREnable() {
-  if (avr_prop_disabled_) {
-    return false;
-  }
-
-  return (hw_panel_info_.mode == kModeVideo && ((hw_panel_info_.dynamic_fps &&
-          hw_panel_info_.dfps_porch_mode) || (!hw_panel_info_.dynamic_fps &&
-          hw_panel_info_.min_fps != hw_panel_info_.max_fps)));
-}
-
-void DisplayPrimary::ResetPanel() {
-  DisplayError status = kErrorNone;
-  int release_fence = -1;
-
-  DLOGI("Powering off primary");
-  status = SetDisplayState(kStateOff, &release_fence);
-  if (status != kErrorNone) {
-    DLOGE("power-off on primary failed with error = %d", status);
-  }
-  if (release_fence >= 0) {
-    ::close(release_fence);
-  }
-
-  DLOGI("Restoring power mode on primary");
-  DisplayState mode = GetLastPowerMode();
-  status = SetDisplayState(mode, &release_fence);
-  if (status != kErrorNone) {
-    DLOGE("Setting power mode = %d on primary failed with error = %d", mode, status);
-  }
-  if (release_fence >= 0) {
-    ::close(release_fence);
-  }
-
-  DLOGI("Enabling HWVsync");
-  status = SetVSyncState(true);
-  if (status != kErrorNone) {
-    DLOGE("enabling vsync failed for primary with error = %d", status);
-  }
-}
-
-}  // namespace sdm
-
diff --git a/sdm/libs/core/display_primary.h b/sdm/libs/core/display_primary.h
deleted file mode 100644
index a5a3ae0..0000000
--- a/sdm/libs/core/display_primary.h
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
-* Copyright (c) 2014 - 2018, The Linux Foundation. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without modification, are permitted
-* provided that the following conditions are met:
-*    * Redistributions of source code must retain the above copyright notice, this list of
-*      conditions and the following disclaimer.
-*    * Redistributions in binary form must reproduce the above copyright notice, this list of
-*      conditions and the following disclaimer in the documentation and/or other materials provided
-*      with the distribution.
-*    * Neither the name of The Linux Foundation nor the names of its contributors may be used to
-*      endorse or promote products derived from this software without specific prior written
-*      permission.
-*
-* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-* NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
-* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
-* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
-* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#ifndef __DISPLAY_PRIMARY_H__
-#define __DISPLAY_PRIMARY_H__
-
-#include <vector>
-
-#include "display_base.h"
-#include "hw_events_interface.h"
-
-namespace sdm {
-
-class HWPrimaryInterface;
-
-class DisplayPrimary : public DisplayBase, HWEventHandler {
- public:
-  DisplayPrimary(DisplayEventHandler *event_handler, HWInfoInterface *hw_info_intf,
-                 BufferSyncHandler *buffer_sync_handler, BufferAllocator *buffer_allocator,
-                 CompManager *comp_manager);
-  virtual DisplayError Init();
-  virtual DisplayError Prepare(LayerStack *layer_stack);
-  virtual DisplayError Commit(LayerStack *layer_stack);
-  virtual DisplayError ControlPartialUpdate(bool enable, uint32_t *pending);
-  virtual DisplayError DisablePartialUpdateOneFrame();
-  virtual DisplayError SetDisplayState(DisplayState state, int *release_fence);
-  virtual void SetIdleTimeoutMs(uint32_t active_ms);
-  virtual DisplayError SetDisplayMode(uint32_t mode);
-  virtual DisplayError GetRefreshRateRange(uint32_t *min_refresh_rate, uint32_t *max_refresh_rate);
-  virtual DisplayError SetRefreshRate(uint32_t refresh_rate, bool final_rate);
-  virtual DisplayError SetPanelBrightness(int level);
-  virtual DisplayError GetPanelBrightness(int *level);
-
-  // Implement the HWEventHandlers
-  virtual DisplayError VSync(int64_t timestamp);
-  virtual DisplayError Blank(bool blank) { return kErrorNone; }
-  virtual void IdleTimeout();
-  virtual void ThermalEvent(int64_t thermal_level);
-  virtual void CECMessage(char *message) { }
-  virtual void IdlePowerCollapse();
-  virtual void PingPongTimeout();
-  virtual void PanelDead();
-
- private:
-  bool NeedsAVREnable();
-  void ResetPanel();
-
-  std::vector<HWEvent> event_list_;
-  bool avr_prop_disabled_ = false;
-  bool switch_to_cmd_ = false;
-  bool handle_idle_timeout_ = false;
-  bool reset_panel_ = false;
-};
-
-}  // namespace sdm
-
-#endif  // __DISPLAY_PRIMARY_H__
-
diff --git a/sdm/libs/core/display_virtual.cpp b/sdm/libs/core/display_virtual.cpp
deleted file mode 100644
index d46c8c0..0000000
--- a/sdm/libs/core/display_virtual.cpp
+++ /dev/null
@@ -1,174 +0,0 @@
-/*
-* Copyright (c) 2014 - 2018, The Linux Foundation. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without modification, are permitted
-* provided that the following conditions are met:
-*    * Redistributions of source code must retain the above copyright notice, this list of
-*      conditions and the following disclaimer.
-*    * Redistributions in binary form must reproduce the above copyright notice, this list of
-*      conditions and the following disclaimer in the documentation and/or other materials provided
-*      with the distribution.
-*    * Neither the name of The Linux Foundation nor the names of its contributors may be used to
-*      endorse or promote products derived from this software without specific prior written
-*      permission.
-*
-* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-* NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
-* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
-* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
-* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#include <utils/constants.h>
-#include <utils/debug.h>
-#include <algorithm>
-#include "display_virtual.h"
-#include "hw_interface.h"
-#include "hw_info_interface.h"
-
-#define __CLASS__ "DisplayVirtual"
-
-namespace sdm {
-
-DisplayVirtual::DisplayVirtual(DisplayEventHandler *event_handler, HWInfoInterface *hw_info_intf,
-                               BufferSyncHandler *buffer_sync_handler,
-                               BufferAllocator *buffer_allocator, CompManager *comp_manager)
-  : DisplayBase(kVirtual, event_handler, kDeviceVirtual, buffer_sync_handler, buffer_allocator,
-                comp_manager, hw_info_intf) {
-}
-
-DisplayError DisplayVirtual::Init() {
-  lock_guard<recursive_mutex> obj(recursive_mutex_);
-
-  DisplayError error = HWInterface::Create(kVirtual, hw_info_intf_, buffer_sync_handler_,
-                                           buffer_allocator_, &hw_intf_);
-  if (error != kErrorNone) {
-    return error;
-  }
-
-  HWScaleLutInfo lut_info = {};
-  error = comp_manager_->GetScaleLutConfig(&lut_info);
-  if (error == kErrorNone) {
-    error = hw_intf_->SetScaleLutConfig(&lut_info);
-    if (error != kErrorNone) {
-      HWInterface::Destroy(hw_intf_);
-      return error;
-    }
-  }
-
-  if (hw_info_intf_) {
-    HWResourceInfo hw_resource_info = HWResourceInfo();
-    hw_info_intf_->GetHWResourceInfo(&hw_resource_info);
-    auto max_mixer_stages = hw_resource_info.num_blending_stages;
-    int property_value = Debug::GetMaxPipesPerMixer(display_type_);
-    if (property_value >= 0) {
-      max_mixer_stages = std::min(UINT32(property_value), hw_resource_info.num_blending_stages);
-    }
-    DisplayBase::SetMaxMixerStages(max_mixer_stages);
-  }
-
-  return error;
-}
-
-DisplayError DisplayVirtual::GetNumVariableInfoConfigs(uint32_t *count) {
-  lock_guard<recursive_mutex> obj(recursive_mutex_);
-  *count = 1;
-  return kErrorNone;
-}
-
-DisplayError DisplayVirtual::GetConfig(uint32_t index, DisplayConfigVariableInfo *variable_info) {
-  lock_guard<recursive_mutex> obj(recursive_mutex_);
-  *variable_info = display_attributes_;
-  return kErrorNone;
-}
-
-DisplayError DisplayVirtual::GetActiveConfig(uint32_t *index) {
-  lock_guard<recursive_mutex> obj(recursive_mutex_);
-  *index = 0;
-  return kErrorNone;
-}
-
-DisplayError DisplayVirtual::SetActiveConfig(DisplayConfigVariableInfo *variable_info) {
-  lock_guard<recursive_mutex> obj(recursive_mutex_);
-
-  if (!variable_info) {
-    return kErrorParameters;
-  }
-
-  DisplayError error = kErrorNone;
-  HWDisplayAttributes display_attributes;
-  HWMixerAttributes mixer_attributes;
-  HWPanelInfo hw_panel_info = {};
-  DisplayConfigVariableInfo fb_config = fb_config_;
-
-  display_attributes.x_pixels = variable_info->x_pixels;
-  display_attributes.y_pixels = variable_info->y_pixels;
-  display_attributes.fps = variable_info->fps;
-
-  if (display_attributes == display_attributes_) {
-    return kErrorNone;
-  }
-
-  error = hw_intf_->SetDisplayAttributes(display_attributes);
-  if (error != kErrorNone) {
-    return error;
-  }
-
-  hw_intf_->GetHWPanelInfo(&hw_panel_info);
-
-  error = hw_intf_->GetMixerAttributes(&mixer_attributes);
-  if (error != kErrorNone) {
-    return error;
-  }
-
-  // fb_config will be updated only once after creation of virtual display
-  if (fb_config.x_pixels == 0 || fb_config.y_pixels == 0) {
-    fb_config = display_attributes;
-  }
-
-  // if display is already connected, unregister display from composition manager and register
-  // the display with new configuration.
-  if (display_comp_ctx_) {
-    comp_manager_->UnregisterDisplay(display_comp_ctx_);
-  }
-
-  error = comp_manager_->RegisterDisplay(display_type_, display_attributes, hw_panel_info,
-                                         mixer_attributes, fb_config, &display_comp_ctx_);
-  if (error != kErrorNone) {
-    return error;
-  }
-
-  display_attributes_ = display_attributes;
-  mixer_attributes_ = mixer_attributes;
-  hw_panel_info_ = hw_panel_info;
-  fb_config_ = fb_config;
-
-  DLOGI("Virtual display resolution changed to[%dx%d]", display_attributes_.x_pixels,
-        display_attributes_.y_pixels);
-
-  return kErrorNone;
-}
-
-DisplayError DisplayVirtual::Prepare(LayerStack *layer_stack) {
-  lock_guard<recursive_mutex> obj(recursive_mutex_);
-
-  // Clean hw layers for reuse.
-  hw_layers_ = HWLayers();
-
-  return DisplayBase::Prepare(layer_stack);
-}
-
-DisplayError DisplayVirtual::GetColorModeCount(uint32_t *mode_count) {
-  lock_guard<recursive_mutex> obj(recursive_mutex_);
-
-  // Color Manager isn't supported for virtual displays.
-  *mode_count = 1;
-
-  return kErrorNone;
-}
-
-}  // namespace sdm
-
diff --git a/sdm/libs/core/display_virtual.h b/sdm/libs/core/display_virtual.h
deleted file mode 100644
index ca154c4..0000000
--- a/sdm/libs/core/display_virtual.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
-* Copyright (c) 2014 - 2018, The Linux Foundation. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without modification, are permitted
-* provided that the following conditions are met:
-*    * Redistributions of source code must retain the above copyright notice, this list of
-*      conditions and the following disclaimer.
-*    * Redistributions in binary form must reproduce the above copyright notice, this list of
-*      conditions and the following disclaimer in the documentation and/or other materials provided
-*      with the distribution.
-*    * Neither the name of The Linux Foundation nor the names of its contributors may be used to
-*      endorse or promote products derived from this software without specific prior written
-*      permission.
-*
-* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-* NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
-* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
-* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
-* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#ifndef __DISPLAY_VIRTUAL_H__
-#define __DISPLAY_VIRTUAL_H__
-
-#include <private/hw_info_types.h>
-#include "display_base.h"
-
-namespace sdm {
-
-class HWVirtualInterface;
-
-class DisplayVirtual : public DisplayBase {
- public:
-  DisplayVirtual(DisplayEventHandler *event_handler, HWInfoInterface *hw_info_intf,
-                 BufferSyncHandler *buffer_sync_handler, BufferAllocator *buffer_allocator,
-                 CompManager *comp_manager);
-  virtual DisplayError Init();
-  virtual DisplayError Prepare(LayerStack *layer_stack);
-  virtual DisplayError GetNumVariableInfoConfigs(uint32_t *count);
-  virtual DisplayError GetConfig(uint32_t index, DisplayConfigVariableInfo *variable_info);
-  virtual DisplayError GetActiveConfig(uint32_t *index);
-  virtual DisplayError SetActiveConfig(uint32_t index) {
-    return kErrorNotSupported;
-  }
-  virtual DisplayError SetActiveConfig(DisplayConfigVariableInfo *variable_info);
-  virtual DisplayError SetMixerResolution(uint32_t width, uint32_t height) {
-    return kErrorNotSupported;
-  }
-  virtual DisplayError SetVSyncState(bool enable) {
-    return kErrorNotSupported;
-  }
-  virtual DisplayError SetRefreshRate(uint32_t refresh_rate, bool final_rate) {
-    return kErrorNotSupported;
-  }
-  virtual DisplayError SetDetailEnhancerData(const DisplayDetailEnhancerData &de_data) {
-    return kErrorNotSupported;
-  }
-  virtual DisplayError ValidateGPUTargetParams() {
-    // TODO(user): Validate GPU target for virtual display when query display attributes
-    // on virtual display is functional.
-    return kErrorNone;
-  }
-  virtual DisplayError GetColorModeCount(uint32_t *mode_count);
-};
-
-}  // namespace sdm
-
-#endif  // __DISPLAY_VIRTUAL_H__
-
diff --git a/sdm/libs/core/drm/hw_color_manager_drm.cpp b/sdm/libs/core/drm/hw_color_manager_drm.cpp
deleted file mode 100644
index 85e9574..0000000
--- a/sdm/libs/core/drm/hw_color_manager_drm.cpp
+++ /dev/null
@@ -1,967 +0,0 @@
-/*
-* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without
-* modification, are permitted provided that the following conditions are
-* met:
-*     * Redistributions of source code must retain the above copyright
-*       notice, this list of conditions and the following disclaimer.
-*     * Redistributions in binary form must reproduce the above
-*       copyright notice, this list of conditions and the following
-*       disclaimer in the documentation and/or other materials provided
-*       with the distribution.
-*     * Neither the name of The Linux Foundation nor the names of its
-*       contributors may be used to endorse or promote products derived
-*       from this software without specific prior written permission.
-*
-* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
-* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
-* ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
-* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
-* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#define __CLASS__ "HWColorManagerDRM"
-
-#ifdef PP_DRM_ENABLE
-#include <drm/msm_drm_pp.h>
-#endif
-#include <utils/debug.h>
-#include "hw_color_manager_drm.h"
-
-#ifdef PP_DRM_ENABLE
-static const uint32_t kPgcDataMask = 0x3FF;
-static const uint32_t kPgcShift = 16;
-
-static const uint32_t kIgcDataMask = 0xFFF;
-static const uint32_t kIgcShift = 16;
-
-#ifdef DRM_MSM_PA_HSIC
-static const uint32_t kPAHueMask = (1 << 12);
-static const uint32_t kPASatMask = (1 << 13);
-static const uint32_t kPAValMask = (1 << 14);
-static const uint32_t kPAContrastMask = (1 << 15);
-#endif
-
-#ifdef DRM_MSM_SIXZONE
-static const uint32_t kSixZoneP0Mask = 0x0FFF;
-static const uint32_t kSixZoneP1Mask = 0x0FFF0FFF;
-static const uint32_t kSixZoneHueMask = (1 << 16);
-static const uint32_t kSixZoneSatMask = (1 << 17);
-static const uint32_t kSixZoneValMask = (1 << 18);
-#endif
-
-#ifdef DRM_MSM_MEMCOL
-static const uint32_t kMemColorProtHueMask = (1 << 0);
-static const uint32_t kMemColorProtSatMask = (1 << 1);
-static const uint32_t kMemColorProtValMask = (1 << 2);
-static const uint32_t kMemColorProtContMask = (1 << 3);
-static const uint32_t kMemColorProtSixZoneMask = (1 << 4);
-static const uint32_t kMemColorProtBlendMask = (1 << 5);
-
-static const uint32_t kMemColorProtMask = \
-  (kMemColorProtHueMask | kMemColorProtSatMask | kMemColorProtValMask | \
-    kMemColorProtContMask | kMemColorProtSixZoneMask | kMemColorProtBlendMask);
-
-static const uint32_t kMemColorSkinMask = (1 << 19);
-static const uint32_t kMemColorSkyMask = (1 << 20);
-static const uint32_t kMemColorFolMask = (1 << 21);
-#endif
-#endif
-
-namespace sdm {
-
-DisplayError (*HWColorManagerDrm::GetDrmFeature[])(const PPFeatureInfo &, DRMPPFeatureInfo *) = {
-        [kFeaturePcc] = &HWColorManagerDrm::GetDrmPCC,
-        [kFeatureIgc] = &HWColorManagerDrm::GetDrmIGC,
-        [kFeaturePgc] = &HWColorManagerDrm::GetDrmPGC,
-        [kFeatureMixerGc] = &HWColorManagerDrm::GetDrmMixerGC,
-        [kFeaturePaV2] = NULL,
-        [kFeatureDither] = &HWColorManagerDrm::GetDrmDither,
-        [kFeatureGamut] = &HWColorManagerDrm::GetDrmGamut,
-        [kFeaturePADither] = &HWColorManagerDrm::GetDrmPADither,
-        [kFeaturePAHsic] = &HWColorManagerDrm::GetDrmPAHsic,
-        [kFeaturePASixZone] = &HWColorManagerDrm::GetDrmPASixZone,
-        [kFeaturePAMemColSkin] = &HWColorManagerDrm::GetDrmPAMemColSkin,
-        [kFeaturePAMemColSky] = &HWColorManagerDrm::GetDrmPAMemColSky,
-        [kFeaturePAMemColFoliage] = &HWColorManagerDrm::GetDrmPAMemColFoliage,
-        [kFeaturePAMemColProt] = &HWColorManagerDrm::GetDrmPAMemColProt,
-};
-
-void HWColorManagerDrm::FreeDrmFeatureData(DRMPPFeatureInfo *feature) {
-  if (feature->payload)
-    free(feature->payload);
-  feature->payload = NULL;
-}
-
-uint32_t HWColorManagerDrm::GetFeatureVersion(const DRMPPFeatureInfo &feature) {
-  uint32_t version = PPFeatureVersion::kSDEPpVersionInvalid;
-
-  switch (feature.id) {
-    case kFeaturePcc:
-      if (feature.version == 1) {
-        version = PPFeatureVersion::kSDEPccV17;
-      } else if (feature.version == 4) {
-        version = PPFeatureVersion::kSDEPccV4;
-      }
-      break;
-    case kFeatureIgc:
-      if (feature.version == 3)
-        version = PPFeatureVersion::kSDEIgcV30;
-      break;
-    case kFeaturePgc:
-      if (feature.version == 1)
-        version = PPFeatureVersion::kSDEPgcV17;
-      break;
-    case kFeatureMixerGc:
-        version = PPFeatureVersion::kSDEPgcV17;
-      break;
-    case kFeaturePAHsic:
-    case kFeaturePASixZone:
-    case kFeaturePAMemColSkin:
-    case kFeaturePAMemColSky:
-    case kFeaturePAMemColFoliage:
-    case kFeaturePAMemColProt:
-      if (feature.version == 1)
-        version = PPFeatureVersion::kSDEPaV17;
-      break;
-    case kFeatureDither:
-        version = PPFeatureVersion::kSDEDitherV17;
-      break;
-    case kFeatureGamut:
-      if (feature.version == 1)
-        version = PPFeatureVersion::kSDEGamutV17;
-      else if (feature.version == 4)
-        version = PPFeatureVersion::kSDEGamutV4;
-      break;
-    case kFeaturePADither:
-        version = PPFeatureVersion::kSDEPADitherV17;
-      break;
-    default:
-      break;
-  }
-  return version;
-}
-
-DRMPPFeatureID HWColorManagerDrm::ToDrmFeatureId(uint32_t id) {
-  DRMPPFeatureID ret = kPPFeaturesMax;
-
-  switch (id) {
-    case kGlobalColorFeaturePcc:
-      ret = kFeaturePcc;
-      break;
-    case kGlobalColorFeatureIgc:
-      ret = kFeatureIgc;
-      break;
-    case kGlobalColorFeaturePgc:
-      ret = kFeaturePgc;
-      break;
-    case kMixerColorFeatureGc:
-      ret = kFeatureMixerGc;
-      break;
-    case kGlobalColorFeaturePaV2:
-      ret = kFeaturePAHsic;
-      break;
-    case kGlobalColorFeatureDither:
-      ret = kFeatureDither;
-      break;
-    case kGlobalColorFeatureGamut:
-      ret = kFeatureGamut;
-      break;
-    case kGlobalColorFeaturePADither:
-      ret = kFeaturePADither;
-      break;
-    default:
-      break;
-  }
-  return ret;
-}
-
-DisplayError HWColorManagerDrm::GetDrmPCC(const PPFeatureInfo &in_data,
-                                          DRMPPFeatureInfo *out_data) {
-  DisplayError ret = kErrorNone;
-#ifdef PP_DRM_ENABLE
-  struct SDEPccV4Cfg *sde_pcc = NULL;
-  struct SDEPccV4Coeff *sde_pcc_coeffs = NULL;
-  struct drm_msm_pcc *mdp_pcc = NULL;
-  struct drm_msm_pcc_coeff *mdp_pcc_coeffs = NULL;
-  uint32_t i = 0;
-
-  if (!out_data) {
-    DLOGE("Invalid input parameter for pcc");
-    return kErrorParameters;
-  }
-
-  switch (in_data.feature_version_) {
-  case PPFeatureVersion::kSDEPccV4:
-    sde_pcc = (struct SDEPccV4Cfg *) in_data.GetConfigData();
-    break;
-  default:
-    DLOGE("Unsupported pcc feature version: %d", in_data.feature_version_);
-    return kErrorParameters;
-  }
-
-  out_data->id = kFeaturePcc;
-  out_data->type = sde_drm::kPropBlob;
-  out_data->version = in_data.feature_version_;
-  out_data->payload_size = sizeof(struct drm_msm_pcc);
-
-  if (in_data.enable_flags_ & kOpsDisable) {
-    /* feature disable case */
-    out_data->payload = NULL;
-    return ret;
-  } else if (!(in_data.enable_flags_ & kOpsEnable)) {
-    out_data->payload = NULL;
-    return kErrorParameters;
-  }
-
-  mdp_pcc = new drm_msm_pcc();
-  if (!mdp_pcc) {
-    DLOGE("Failed to allocate memory for pcc");
-    return kErrorMemory;
-  }
-
-  mdp_pcc->flags = 0;
-
-  for (i = 0; i < kMaxPCCChanel; i++) {
-    switch (i) {
-    case 0:
-      sde_pcc_coeffs = &sde_pcc->red;
-      mdp_pcc_coeffs = &mdp_pcc->r;
-      mdp_pcc->r_rr = sde_pcc_coeffs->rr;
-      mdp_pcc->r_gg = sde_pcc_coeffs->gg;
-      mdp_pcc->r_bb = sde_pcc_coeffs->bb;
-      break;
-    case 1:
-        sde_pcc_coeffs = &sde_pcc->green;
-        mdp_pcc_coeffs = &mdp_pcc->g;
-        mdp_pcc->g_rr = sde_pcc_coeffs->rr;
-        mdp_pcc->g_gg = sde_pcc_coeffs->gg;
-        mdp_pcc->g_bb = sde_pcc_coeffs->bb;
-      break;
-    case 2:
-        sde_pcc_coeffs = &sde_pcc->blue;
-        mdp_pcc_coeffs = &mdp_pcc->b;
-        mdp_pcc->b_rr = sde_pcc_coeffs->rr;
-        mdp_pcc->b_gg = sde_pcc_coeffs->gg;
-        mdp_pcc->b_bb = sde_pcc_coeffs->bb;
-      break;
-    }
-    mdp_pcc_coeffs->c = sde_pcc_coeffs->c;
-    mdp_pcc_coeffs->r = sde_pcc_coeffs->r;
-    mdp_pcc_coeffs->g = sde_pcc_coeffs->g;
-    mdp_pcc_coeffs->b = sde_pcc_coeffs->b;
-    mdp_pcc_coeffs->rg = sde_pcc_coeffs->rg;
-    mdp_pcc_coeffs->gb = sde_pcc_coeffs->gb;
-    mdp_pcc_coeffs->rb = sde_pcc_coeffs->rb;
-    mdp_pcc_coeffs->rgb = sde_pcc_coeffs->rgb;
-  }
-  out_data->payload = mdp_pcc;
-#endif
-  return ret;
-}
-
-DisplayError HWColorManagerDrm::GetDrmIGC(const PPFeatureInfo &in_data,
-                                          DRMPPFeatureInfo *out_data) {
-  DisplayError ret = kErrorNone;
-#ifdef PP_DRM_ENABLE
-  struct SDEIgcV30LUTData *sde_igc;
-  struct drm_msm_igc_lut *mdp_igc;
-  uint32_t *c0_c1_data_ptr = NULL;
-  uint32_t *c2_data_ptr = NULL;
-
-
-  if (!out_data) {
-    DLOGE("Invalid input parameter for igc");
-    return kErrorParameters;
-  }
-
-  switch (in_data.feature_version_) {
-  case PPFeatureVersion::kSDEIgcV30:
-    sde_igc = (struct SDEIgcV30LUTData *) in_data.GetConfigData();
-    break;
-  default:
-    DLOGE("Unsupported igc feature version: %d", in_data.feature_version_);
-    return kErrorParameters;
-  }
-
-  out_data->id = kFeatureIgc;
-  out_data->type = sde_drm::kPropBlob;
-  out_data->version = in_data.feature_version_;
-  out_data->payload_size = sizeof(struct drm_msm_igc_lut);
-
-  if (in_data.enable_flags_ & kOpsDisable) {
-    /* feature disable case */
-    out_data->payload = NULL;
-    return ret;
-  } else if (!(in_data.enable_flags_ & kOpsEnable)) {
-    out_data->payload = NULL;
-    return kErrorParameters;
-  }
-
-  mdp_igc = new drm_msm_igc_lut();
-  if (!mdp_igc) {
-    DLOGE("Failed to allocate memory for igc");
-    return kErrorMemory;
-  }
-
-  mdp_igc->flags = IGC_DITHER_ENABLE;
-  mdp_igc->strength = sde_igc->strength;
-
-  c0_c1_data_ptr = reinterpret_cast<uint32_t*>(sde_igc->c0_c1_data);
-  c2_data_ptr = reinterpret_cast<uint32_t*>(sde_igc->c2_data);
-
-  if (!c0_c1_data_ptr || !c2_data_ptr) {
-    DLOGE("Invaid igc data pointer");
-    delete mdp_igc;
-    out_data->payload = NULL;
-    return kErrorParameters;
-  }
-
-  for (int i = 0; i < IGC_TBL_LEN; i++) {
-    mdp_igc->c0[i] = c0_c1_data_ptr[i] & kIgcDataMask;
-    mdp_igc->c1[i] = (c0_c1_data_ptr[i] >> kIgcShift) & kIgcDataMask;
-    mdp_igc->c2[i] = c2_data_ptr[i] & kIgcDataMask;
-  }
-  out_data->payload = mdp_igc;
-#endif
-  return ret;
-}
-
-DisplayError HWColorManagerDrm::GetDrmPGC(const PPFeatureInfo &in_data,
-                                          DRMPPFeatureInfo *out_data) {
-  DisplayError ret = kErrorNone;
-#ifdef PP_DRM_ENABLE
-  struct SDEPgcLUTData *sde_pgc;
-  struct drm_msm_pgc_lut *mdp_pgc;
-
-  if (!out_data) {
-    DLOGE("Invalid input parameter for gamut");
-    return kErrorParameters;
-  }
-  sde_pgc = (struct SDEPgcLUTData *)in_data.GetConfigData();
-  out_data->id = kFeaturePgc;
-  out_data->type = sde_drm::kPropBlob;
-  out_data->version = in_data.feature_version_;
-  out_data->payload_size = sizeof(struct drm_msm_pgc_lut);
-
-  if (in_data.enable_flags_ & kOpsDisable) {
-    /* feature disable case */
-    out_data->payload = NULL;
-    return ret;
-  } else if (!(in_data.enable_flags_ & kOpsEnable)) {
-    out_data->payload = NULL;
-    return kErrorParameters;
-  }
-
-  mdp_pgc = new drm_msm_pgc_lut();
-  if (!mdp_pgc) {
-    DLOGE("Failed to allocate memory for pgc");
-    return kErrorMemory;
-  }
-
-  if (in_data.enable_flags_ & kOpsEnable)
-    mdp_pgc->flags = PGC_8B_ROUND;
-  else
-    mdp_pgc->flags = 0;
-
-  for (int i = 0, j = 0; i < PGC_TBL_LEN; i++, j += 2) {
-    mdp_pgc->c0[i] = (sde_pgc->c0_data[j] & kPgcDataMask) |
-        (sde_pgc->c0_data[j + 1] & kPgcDataMask) << kPgcShift;
-    mdp_pgc->c1[i] = (sde_pgc->c1_data[j] & kPgcDataMask) |
-        (sde_pgc->c1_data[j + 1] & kPgcDataMask) << kPgcShift;
-    mdp_pgc->c2[i] = (sde_pgc->c2_data[j] & kPgcDataMask) |
-        (sde_pgc->c2_data[j + 1] & kPgcDataMask) << kPgcShift;
-  }
-  out_data->payload = mdp_pgc;
-#endif
-  return ret;
-}
-
-DisplayError HWColorManagerDrm::GetDrmMixerGC(const PPFeatureInfo &in_data,
-                                              DRMPPFeatureInfo *out_data) {
-  DisplayError ret = kErrorNone;
-#ifdef PP_DRM_ENABLE
-  if (!out_data) {
-    DLOGE("Invalid input parameter for Mixer GC");
-    return kErrorParameters;
-  }
-
-  out_data->id = kPPFeaturesMax;
-  out_data->type = sde_drm::kPropBlob;
-  out_data->version = in_data.feature_version_;
-#endif
-  return ret;
-}
-
-DisplayError HWColorManagerDrm::GetDrmPAHsic(const PPFeatureInfo &in_data,
-                                           DRMPPFeatureInfo *out_data) {
-  DisplayError ret = kErrorNone;
-#if defined(PP_DRM_ENABLE) && defined(DRM_MSM_PA_HSIC)
-  struct SDEPaData *sde_pa;
-  struct drm_msm_pa_hsic *mdp_hsic;
-
-  if (!out_data) {
-    DLOGE("Invalid input parameter for pa hsic");
-    return kErrorParameters;
-  }
-
-  sde_pa = (struct SDEPaData *) in_data.GetConfigData();
-
-  out_data->id = kFeaturePAHsic;
-  out_data->type = sde_drm::kPropBlob;
-  out_data->version = in_data.feature_version_;
-  out_data->payload_size = 0;
-  out_data->payload = NULL;
-
-  if (in_data.enable_flags_ & kOpsDisable) {
-    /* Complete PA features disable case */
-    return ret;
-  } else if (!(in_data.enable_flags_ & kOpsEnable)) {
-    DLOGE("Invalid ops for pa hsic");
-    return kErrorParameters;
-  }
-
-  if (!(sde_pa->mode & (kPAHueMask | kPASatMask |
-                        kPAValMask | kPAContrastMask))) {
-    /* PA HSIC feature disable case, but other PA features active */
-    return ret;
-  }
-
-  mdp_hsic = new drm_msm_pa_hsic();
-  if (!mdp_hsic) {
-    DLOGE("Failed to allocate memory for pa hsic");
-    return kErrorMemory;
-  }
-
-  mdp_hsic->flags = 0;
-
-  if (in_data.enable_flags_ & kPaHueEnable) {
-    mdp_hsic->flags |= PA_HSIC_HUE_ENABLE;
-    mdp_hsic->hue = sde_pa->hue_adj;
-  }
-  if (in_data.enable_flags_ & kPaSatEnable) {
-    mdp_hsic->flags |= PA_HSIC_SAT_ENABLE;
-    mdp_hsic->saturation = sde_pa->sat_adj;
-  }
-  if (in_data.enable_flags_ & kPaValEnable) {
-    mdp_hsic->flags |= PA_HSIC_VAL_ENABLE;
-    mdp_hsic->value = sde_pa->val_adj;
-  }
-  if (in_data.enable_flags_ & kPaContEnable) {
-    mdp_hsic->flags |= PA_HSIC_CONT_ENABLE;
-    mdp_hsic->contrast = sde_pa->cont_adj;
-  }
-
-  if (mdp_hsic->flags) {
-    out_data->payload = mdp_hsic;
-    out_data->payload_size = sizeof(struct drm_msm_pa_hsic);
-  } else {
-    /* PA HSIC configuration unchanged, no better return code available */
-    delete mdp_hsic;
-    ret = kErrorPermission;
-  }
-#endif
-  return ret;
-}
-
-DisplayError HWColorManagerDrm::GetDrmPASixZone(const PPFeatureInfo &in_data,
-                                                DRMPPFeatureInfo *out_data) {
-  DisplayError ret = kErrorNone;
-#if defined(PP_DRM_ENABLE) && defined(DRM_MSM_SIXZONE)
-  struct SDEPaData *sde_pa;
-
-  if (!out_data) {
-    DLOGE("Invalid input parameter for six zone");
-    return kErrorParameters;
-  }
-
-  sde_pa = (struct SDEPaData *) in_data.GetConfigData();
-
-  out_data->id = kFeaturePASixZone;
-  out_data->type = sde_drm::kPropBlob;
-  out_data->version = in_data.feature_version_;
-  out_data->payload_size = 0;
-  out_data->payload = NULL;
-
-  if (in_data.enable_flags_ & kOpsDisable) {
-    /* Complete PA features disable case */
-    return ret;
-  } else if (!(in_data.enable_flags_ & kOpsEnable)) {
-    DLOGE("Invalid ops for six zone");
-    return kErrorParameters;
-  }
-
-  if (!(sde_pa->mode & (kSixZoneHueMask | kSixZoneSatMask |
-                        kSixZoneValMask))) {
-    /* PA SixZone feature disable case, but other PA features active */
-    return ret;
-  }
-
-  if (in_data.enable_flags_ & kPaSixZoneEnable) {
-    struct drm_msm_sixzone *mdp_sixzone = NULL;
-
-    if ((!sde_pa->six_zone_curve_p0 || !sde_pa->six_zone_curve_p1) ||
-        (sde_pa->six_zone_len != SIXZONE_LUT_SIZE)) {
-        DLOGE("Invaid sixzone curve");
-        return kErrorParameters;
-    }
-
-    mdp_sixzone = new drm_msm_sixzone();
-    if (!mdp_sixzone) {
-      DLOGE("Failed to allocate memory for six zone");
-      return kErrorMemory;
-    }
-
-    mdp_sixzone->flags = 0;
-
-    if (sde_pa->mode & kSixZoneHueMask) {
-      mdp_sixzone->flags |= SIXZONE_HUE_ENABLE;
-    }
-    if (sde_pa->mode & kSixZoneSatMask) {
-      mdp_sixzone->flags |= SIXZONE_SAT_ENABLE;
-    }
-    if (sde_pa->mode & kSixZoneValMask) {
-      mdp_sixzone->flags |= SIXZONE_VAL_ENABLE;
-    }
-
-    mdp_sixzone->threshold = sde_pa->six_zone_thresh;
-    mdp_sixzone->adjust_p0 = sde_pa->six_zone_adj_p0;
-    mdp_sixzone->adjust_p1 = sde_pa->six_zone_adj_p1;
-    mdp_sixzone->sat_hold = sde_pa->six_zone_sat_hold;
-    mdp_sixzone->val_hold = sde_pa->six_zone_val_hold;
-
-    for (int i = 0; i < SIXZONE_LUT_SIZE; i++) {
-      mdp_sixzone->curve[i].p0 = sde_pa->six_zone_curve_p0[i] & kSixZoneP0Mask;
-      mdp_sixzone->curve[i].p1 = sde_pa->six_zone_curve_p1[i] & kSixZoneP1Mask;
-    }
-    out_data->payload = mdp_sixzone;
-    out_data->payload_size = sizeof(struct drm_msm_sixzone);
-  } else {
-    /* PA SixZone configuration unchanged, no better return code available */
-    ret = kErrorPermission;
-  }
-
-#endif
-  return ret;
-}
-
-DisplayError HWColorManagerDrm::GetDrmPAMemColSkin(const PPFeatureInfo &in_data,
-                                                   DRMPPFeatureInfo *out_data) {
-  DisplayError ret = kErrorNone;
-#if defined(PP_DRM_ENABLE) && defined(DRM_MSM_MEMCOL)
-  struct SDEPaData *sde_pa;
-
-  if (!out_data) {
-    DLOGE("Invalid input parameter for memory color skin");
-    return kErrorParameters;
-  }
-
-  sde_pa = (struct SDEPaData *) in_data.GetConfigData();
-
-  out_data->id = kFeaturePAMemColSkin;
-  out_data->type = sde_drm::kPropBlob;
-  out_data->version = in_data.feature_version_;
-  out_data->payload_size = 0;
-  out_data->payload = NULL;
-
-  if (in_data.enable_flags_ & kOpsDisable) {
-    /* Complete PA features disable case */
-    return ret;
-  } else if (!(in_data.enable_flags_ & kOpsEnable)) {
-    DLOGE("Invalid ops for memory color skin");
-    return kErrorParameters;
-  }
-
-  if (!(sde_pa->mode & kMemColorSkinMask)) {
-    /* PA MemColSkin feature disable case, but other PA features active */
-    return ret;
-  }
-
-  if (in_data.enable_flags_ & kPaSkinEnable) {
-    struct drm_msm_memcol *mdp_memcol = NULL;
-    struct SDEPaMemColorData *pa_memcol = &sde_pa->skin;
-
-    mdp_memcol = new drm_msm_memcol();
-    if (!mdp_memcol) {
-      DLOGE("Failed to allocate memory for memory color skin");
-      return kErrorMemory;
-    }
-
-    mdp_memcol->prot_flags = 0;
-    mdp_memcol->color_adjust_p0 = pa_memcol->adjust_p0;
-    mdp_memcol->color_adjust_p1 = pa_memcol->adjust_p1;
-    mdp_memcol->color_adjust_p2 = pa_memcol->adjust_p2;
-    mdp_memcol->blend_gain = pa_memcol->blend_gain;
-    mdp_memcol->sat_hold = pa_memcol->sat_hold;
-    mdp_memcol->val_hold = pa_memcol->val_hold;
-    mdp_memcol->hue_region = pa_memcol->hue_region;
-    mdp_memcol->sat_region = pa_memcol->sat_region;
-    mdp_memcol->val_region = pa_memcol->val_region;
-
-    out_data->payload = mdp_memcol;
-    out_data->payload_size = sizeof(struct drm_msm_memcol);
-  } else {
-    /* PA MemColSkin configuration unchanged, no better return code available */
-    ret = kErrorPermission;
-  }
-#endif
-  return ret;
-}
-
-DisplayError HWColorManagerDrm::GetDrmPAMemColSky(const PPFeatureInfo &in_data,
-                                                  DRMPPFeatureInfo *out_data) {
-  DisplayError ret = kErrorNone;
-#if defined(PP_DRM_ENABLE) && defined(DRM_MSM_MEMCOL)
-  struct SDEPaData *sde_pa;
-
-  if (!out_data) {
-    DLOGE("Invalid input parameter for memory color sky");
-    return kErrorParameters;
-  }
-
-  sde_pa = (struct SDEPaData *) in_data.GetConfigData();
-
-  out_data->id = kFeaturePAMemColSky;
-  out_data->type = sde_drm::kPropBlob;
-  out_data->version = in_data.feature_version_;
-  out_data->payload_size = 0;
-  out_data->payload = NULL;
-
-  if (in_data.enable_flags_ & kOpsDisable) {
-    /* Complete PA features disable case */
-    return ret;
-  } else if (!(in_data.enable_flags_ & kOpsEnable)) {
-    DLOGE("Invalid ops for memory color sky");
-    return kErrorParameters;
-  }
-
-  if (!(sde_pa->mode & kMemColorSkyMask)) {
-    /* PA MemColSky feature disable case, but other PA features active */
-    return ret;
-  }
-
-  if (in_data.enable_flags_ & kPaSkyEnable) {
-    struct drm_msm_memcol *mdp_memcol = NULL;
-    struct SDEPaMemColorData *pa_memcol = &sde_pa->sky;
-
-    mdp_memcol = new drm_msm_memcol();
-    if (!mdp_memcol) {
-      DLOGE("Failed to allocate memory for memory color sky");
-      return kErrorMemory;
-    }
-
-    mdp_memcol->prot_flags = 0;
-    mdp_memcol->color_adjust_p0 = pa_memcol->adjust_p0;
-    mdp_memcol->color_adjust_p1 = pa_memcol->adjust_p1;
-    mdp_memcol->color_adjust_p2 = pa_memcol->adjust_p2;
-    mdp_memcol->blend_gain = pa_memcol->blend_gain;
-    mdp_memcol->sat_hold = pa_memcol->sat_hold;
-    mdp_memcol->val_hold = pa_memcol->val_hold;
-    mdp_memcol->hue_region = pa_memcol->hue_region;
-    mdp_memcol->sat_region = pa_memcol->sat_region;
-    mdp_memcol->val_region = pa_memcol->val_region;
-
-    out_data->payload = mdp_memcol;
-    out_data->payload_size = sizeof(struct drm_msm_memcol);
-  } else {
-    /* PA MemColSky configuration unchanged, no better return code available */
-    ret = kErrorPermission;
-  }
-#endif
-  return ret;
-}
-
-DisplayError HWColorManagerDrm::GetDrmPAMemColFoliage(const PPFeatureInfo &in_data,
-                                                      DRMPPFeatureInfo *out_data) {
-  DisplayError ret = kErrorNone;
-#if defined(PP_DRM_ENABLE) && defined(DRM_MSM_MEMCOL)
-  struct SDEPaData *sde_pa;
-
-  if (!out_data) {
-    DLOGE("Invalid input parameter for memory color foliage");
-    return kErrorParameters;
-  }
-
-  sde_pa = (struct SDEPaData *) in_data.GetConfigData();
-
-  out_data->id = kFeaturePAMemColFoliage;
-  out_data->type = sde_drm::kPropBlob;
-  out_data->version = in_data.feature_version_;
-  out_data->payload_size = 0;
-  out_data->payload = NULL;
-
-  if (in_data.enable_flags_ & kOpsDisable) {
-    /* Complete PA features disable case */
-    return ret;
-  } else if (!(in_data.enable_flags_ & kOpsEnable)) {
-    DLOGE("Invalid ops for memory color foliage");
-    return kErrorParameters;
-  }
-
-  if (!(sde_pa->mode & kMemColorFolMask)) {
-    /* PA MemColFoliage feature disable case, but other PA features active */
-    return ret;
-  }
-
-  if (in_data.enable_flags_ & kPaFoliageEnable) {
-    struct drm_msm_memcol *mdp_memcol = NULL;
-    struct SDEPaMemColorData *pa_memcol = &sde_pa->foliage;
-
-    mdp_memcol = new drm_msm_memcol();
-    if (!mdp_memcol) {
-      DLOGE("Failed to allocate memory for memory color foliage");
-      return kErrorMemory;
-    }
-
-    mdp_memcol->prot_flags = 0;
-    mdp_memcol->color_adjust_p0 = pa_memcol->adjust_p0;
-    mdp_memcol->color_adjust_p1 = pa_memcol->adjust_p1;
-    mdp_memcol->color_adjust_p2 = pa_memcol->adjust_p2;
-    mdp_memcol->blend_gain = pa_memcol->blend_gain;
-    mdp_memcol->sat_hold = pa_memcol->sat_hold;
-    mdp_memcol->val_hold = pa_memcol->val_hold;
-    mdp_memcol->hue_region = pa_memcol->hue_region;
-    mdp_memcol->sat_region = pa_memcol->sat_region;
-    mdp_memcol->val_region = pa_memcol->val_region;
-
-    out_data->payload = mdp_memcol;
-    out_data->payload_size = sizeof(struct drm_msm_memcol);
-  } else {
-    /* PA MemColFoliage configuration unchanged, no better return code available */
-    ret = kErrorPermission;
-  }
-#endif
-  return ret;
-}
-
-DisplayError HWColorManagerDrm::GetDrmPAMemColProt(const PPFeatureInfo &in_data,
-                                                   DRMPPFeatureInfo *out_data) {
-  DisplayError ret = kErrorNone;
-#if defined(PP_DRM_ENABLE) && defined(DRM_MSM_MEMCOL)
-  struct SDEPaData *sde_pa;
-  struct drm_msm_memcol *mdp_memcol;
-
-  if (!out_data) {
-    DLOGE("Invalid input parameter for memory color prot");
-    return kErrorParameters;
-  }
-
-  sde_pa = (struct SDEPaData *) in_data.GetConfigData();
-
-  out_data->id = kFeaturePAMemColProt;
-  out_data->type = sde_drm::kPropBlob;
-  out_data->version = in_data.feature_version_;
-  out_data->payload_size = sizeof(struct drm_msm_memcol);
-
-  if (in_data.enable_flags_ & kOpsDisable) {
-    /* Complete PA features disable case */
-    out_data->payload = NULL;
-    return ret;
-  } else if (!(in_data.enable_flags_ & kOpsEnable)) {
-    out_data->payload = NULL;
-    return kErrorParameters;
-  }
-
-  out_data->payload = NULL;
-  if (!(sde_pa->mode & kMemColorProtMask)) {
-    /* PA MemColProt feature disable case, but other PA features active */
-    return ret;
-  }
-
-  mdp_memcol = new drm_msm_memcol();
-  if (!mdp_memcol) {
-    DLOGE("Failed to allocate memory for memory color prot");
-    return kErrorMemory;
-  }
-
-  mdp_memcol->prot_flags = 0;
-
-  if (sde_pa->mode & kMemColorProtMask) {
-    mdp_memcol->prot_flags |= (sde_pa->mode & kMemColorProtMask);
-  }
-
-  out_data->payload = mdp_memcol;
-
-#endif
-  return ret;
-}
-
-DisplayError HWColorManagerDrm::GetDrmDither(const PPFeatureInfo &in_data,
-                                             DRMPPFeatureInfo *out_data) {
-  DisplayError ret = kErrorNone;
-#ifdef PP_DRM_ENABLE
-  struct SDEDitherCfg *sde_dither = NULL;
-  struct drm_msm_dither *mdp_dither = NULL;
-
-  if (!out_data) {
-    DLOGE("Invalid input parameter for dither");
-    return kErrorParameters;
-  }
-
-  sde_dither = (struct SDEDitherCfg *)in_data.GetConfigData();
-  out_data->id = kFeatureDither;
-  out_data->type = sde_drm::kPropBlob;
-  out_data->version = in_data.feature_version_;
-  out_data->payload_size = sizeof(struct drm_msm_dither);
-
-  if (in_data.enable_flags_ & kOpsDisable) {
-    out_data->payload = NULL;
-    return ret;
-  } else if (!(in_data.enable_flags_ & kOpsEnable)) {
-    out_data->payload = NULL;
-    return kErrorParameters;
-  }
-
-  mdp_dither = new drm_msm_dither();
-  if (!mdp_dither) {
-    DLOGE("Failed to allocate memory for dither");
-    return kErrorMemory;
-  }
-
-  mdp_dither->flags = 0;
-  std::memcpy(mdp_dither->matrix, sde_dither->dither_matrix,
-                sizeof(sde_dither->dither_matrix));
-  mdp_dither->temporal_en = sde_dither->temporal_en;
-  mdp_dither->c0_bitdepth = sde_dither->g_y_depth;
-  mdp_dither->c1_bitdepth = sde_dither->b_cb_depth;
-  mdp_dither->c2_bitdepth = sde_dither->r_cr_depth;
-  mdp_dither->c3_bitdepth = 0;
-  out_data->payload = mdp_dither;
-#endif
-  return ret;
-}
-
-DisplayError HWColorManagerDrm::GetDrmGamut(const PPFeatureInfo &in_data,
-                                            DRMPPFeatureInfo *out_data) {
-  DisplayError ret = kErrorNone;
-#ifdef PP_DRM_ENABLE
-  struct SDEGamutCfg *sde_gamut = NULL;
-  struct drm_msm_3d_gamut *mdp_gamut = NULL;
-  uint32_t size = 0;
-
-  if (!out_data) {
-    DLOGE("Invalid input parameter for gamut");
-    return kErrorParameters;
-  }
-  sde_gamut = (struct SDEGamutCfg *)in_data.GetConfigData();
-  out_data->id = kFeatureGamut;
-  out_data->type = sde_drm::kPropBlob;
-  out_data->version = in_data.feature_version_;
-  out_data->payload_size = sizeof(struct drm_msm_3d_gamut);
-  if (in_data.enable_flags_ & kOpsDisable) {
-    /* feature disable case */
-    out_data->payload = NULL;
-    return ret;
-  } else if (!(in_data.enable_flags_ & kOpsEnable)) {
-    out_data->payload = NULL;
-    return kErrorParameters;
-  }
-
-  mdp_gamut = new drm_msm_3d_gamut();
-  if (!mdp_gamut) {
-    DLOGE("Failed to allocate memory for gamut");
-    return kErrorMemory;
-  }
-
-  if (sde_gamut->map_en)
-    mdp_gamut->flags = GAMUT_3D_MAP_EN;
-  else
-    mdp_gamut->flags = 0;
-
-  switch (sde_gamut->mode) {
-    case SDEGamutCfgWrapper::GAMUT_FINE_MODE:
-      mdp_gamut->mode = GAMUT_3D_MODE_17;
-      size = GAMUT_3D_MODE17_TBL_SZ;
-      break;
-    case SDEGamutCfgWrapper::GAMUT_COARSE_MODE:
-      mdp_gamut->mode = GAMUT_3D_MODE_5;
-      size = GAMUT_3D_MODE5_TBL_SZ;
-      break;
-    case SDEGamutCfgWrapper::GAMUT_COARSE_MODE_13:
-      mdp_gamut->mode = GAMUT_3D_MODE_13;
-      size = GAMUT_3D_MODE13_TBL_SZ;
-      break;
-    default:
-      DLOGE("Invalid gamut mode %d", sde_gamut->mode);
-      delete mdp_gamut;
-      return kErrorParameters;
-  }
-
-  if (sde_gamut->map_en) {
-    std::memcpy(&mdp_gamut->scale_off[0][0], sde_gamut->scale_off_data[0],
-                sizeof(uint32_t) * GAMUT_3D_SCALE_OFF_SZ);
-    std::memcpy(&mdp_gamut->scale_off[1][0], sde_gamut->scale_off_data[1],
-                sizeof(uint32_t) * GAMUT_3D_SCALE_OFF_SZ);
-    std::memcpy(&mdp_gamut->scale_off[2][0], sde_gamut->scale_off_data[2],
-                sizeof(uint32_t) * GAMUT_3D_SCALE_OFF_SZ);
-  }
-
-  for (uint32_t row = 0; row < GAMUT_3D_TBL_NUM; row++) {
-    for (uint32_t col = 0; col < size; col++) {
-      mdp_gamut->col[row][col].c0 = sde_gamut->c0_data[row][col];
-      mdp_gamut->col[row][col].c2_c1 = sde_gamut->c1_c2_data[row][col];
-    }
-  }
-  out_data->payload = mdp_gamut;
-#endif
-  return ret;
-}
-
-DisplayError HWColorManagerDrm::GetDrmPADither(const PPFeatureInfo &in_data,
-                                               DRMPPFeatureInfo *out_data) {
-  DisplayError ret = kErrorNone;
-#if defined(PP_DRM_ENABLE) && defined(DRM_MSM_PA_DITHER)
-  struct SDEPADitherData* sde_dither;
-  struct drm_msm_pa_dither* mdp_dither;
-
-  if (!out_data) {
-    DLOGE("Invalid input parameter for PA dither");
-    return kErrorParameters;
-  }
-
-  out_data->id = kFeaturePADither;
-  out_data->type = sde_drm::kPropBlob;
-  out_data->version = in_data.feature_version_;
-
-  out_data->payload_size = sizeof(struct drm_msm_pa_dither);
-  if (in_data.enable_flags_ & kOpsDisable) {
-    /* feature disable case */
-    out_data->payload = NULL;
-    return ret;
-  } else if (!(in_data.enable_flags_ & kOpsEnable)) {
-    out_data->payload = NULL;
-    return kErrorParameters;
-  }
-
-  sde_dither = (struct SDEPADitherData *)in_data.GetConfigData();
-  if (sde_dither->matrix_size != DITHER_MATRIX_SZ) {
-    DLOGE("Invalid dither matrix size %d, exp sz %d",
-          sde_dither->matrix_size, DITHER_MATRIX_SZ);
-    return kErrorParameters;
-  }
-
-  mdp_dither = new drm_msm_pa_dither();
-  if (!mdp_dither) {
-    DLOGE("Failed to allocate memory for dither");
-    return kErrorMemory;
-  }
-
-  mdp_dither->flags = 0;
-  mdp_dither->strength = sde_dither->strength;
-  mdp_dither->offset_en = sde_dither->offset_en;
-  std::memcpy(&mdp_dither->matrix[0],
-              reinterpret_cast<void*>(sde_dither->matrix_data_addr),
-              sizeof(uint32_t) * DITHER_MATRIX_SZ);
-  out_data->payload = mdp_dither;
-#endif
-  return ret;
-}
-
-}  // namespace sdm
diff --git a/sdm/libs/core/drm/hw_color_manager_drm.h b/sdm/libs/core/drm/hw_color_manager_drm.h
deleted file mode 100644
index 1e77f6c..0000000
--- a/sdm/libs/core/drm/hw_color_manager_drm.h
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
-* Copyright (c) 2017, The Linux Foundation. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without
-* modification, are permitted provided that the following conditions are
-* met:
-*     * Redistributions of source code must retain the above copyright
-*       notice, this list of conditions and the following disclaimer.
-*     * Redistributions in binary form must reproduce the above
-*       copyright notice, this list of conditions and the following
-*       disclaimer in the documentation and/or other materials provided
-*       with the distribution.
-*     * Neither the name of The Linux Foundation nor the names of its
-*       contributors may be used to endorse or promote products derived
-*       from this software without specific prior written permission.
-*
-* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
-* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
-* ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
-* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
-* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#ifndef __HW_COLOR_MANAGER_DRM_H__
-#define __HW_COLOR_MANAGER_DRM_H__
-
-#include <drm_interface.h>
-#include <private/color_params.h>
-#include <vector>
-#include <map>
-
-using sde_drm::DRMPPFeatureID;
-using sde_drm::DRMPPFeatureInfo;
-
-using sde_drm::kFeaturePcc;
-using sde_drm::kFeatureIgc;
-using sde_drm::kFeaturePgc;
-using sde_drm::kFeatureMixerGc;
-using sde_drm::kFeaturePaV2;
-using sde_drm::kFeatureDither;
-using sde_drm::kFeatureGamut;
-using sde_drm::kFeaturePADither;
-using sde_drm::kFeaturePAHsic;
-using sde_drm::kFeaturePASixZone;
-using sde_drm::kFeaturePAMemColSkin;
-using sde_drm::kFeaturePAMemColSky;
-using sde_drm::kFeaturePAMemColFoliage;
-using sde_drm::kFeaturePAMemColProt;
-using sde_drm::kPPFeaturesMax;
-
-namespace sdm {
-
-typedef std::map<uint32_t, std::vector<uint32_t>> DrmPPFeatureMap;
-
-static const DrmPPFeatureMap DrmPPfeatureMap_ = \
-  {{kGlobalColorFeaturePcc, {kFeaturePcc}},
-    {kGlobalColorFeatureIgc, {kFeatureIgc}},
-    {kGlobalColorFeaturePgc, {kFeaturePgc}},
-    {kMixerColorFeatureGc, {kMixerColorFeatureGc}},
-    {kGlobalColorFeaturePaV2, {kFeaturePAHsic, kFeaturePASixZone,
-                               kFeaturePAMemColSkin, kFeaturePAMemColSky,
-                               kFeaturePAMemColFoliage, kFeaturePAMemColProt}},
-    {kGlobalColorFeatureDither, {kFeatureDither}},
-    {kGlobalColorFeatureGamut, {kFeatureGamut}},
-    {kGlobalColorFeaturePADither, {kFeaturePADither}},
-};
-
-static const uint32_t kMaxPCCChanel = 3;
-
-class HWColorManagerDrm {
- public:
-  static DisplayError (*GetDrmFeature[kPPFeaturesMax])(const PPFeatureInfo &in_data,
-                                                          DRMPPFeatureInfo *out_data);
-  static void FreeDrmFeatureData(DRMPPFeatureInfo *feature);
-  static uint32_t GetFeatureVersion(const DRMPPFeatureInfo &feature);
-  static DRMPPFeatureID ToDrmFeatureId(uint32_t id);
-
- protected:
-  HWColorManagerDrm() {}
-
- private:
-  static DisplayError GetDrmPCC(const PPFeatureInfo &in_data, DRMPPFeatureInfo *out_data);
-  static DisplayError GetDrmIGC(const PPFeatureInfo &in_data, DRMPPFeatureInfo *out_data);
-  static DisplayError GetDrmPGC(const PPFeatureInfo &in_data, DRMPPFeatureInfo *out_data);
-  static DisplayError GetDrmMixerGC(const PPFeatureInfo &in_data, DRMPPFeatureInfo *out_data);
-  static DisplayError GetDrmDither(const PPFeatureInfo &in_data, DRMPPFeatureInfo *out_data);
-  static DisplayError GetDrmGamut(const PPFeatureInfo &in_data, DRMPPFeatureInfo *out_data);
-  static DisplayError GetDrmPADither(const PPFeatureInfo &in_data, DRMPPFeatureInfo *out_data);
-  static DisplayError GetDrmPAHsic(const PPFeatureInfo &in_data, DRMPPFeatureInfo *out_data);
-  static DisplayError GetDrmPASixZone(const PPFeatureInfo &in_data, DRMPPFeatureInfo *out_data);
-  static DisplayError GetDrmPAMemColSkin(const PPFeatureInfo &in_data, DRMPPFeatureInfo *out_data);
-  static DisplayError GetDrmPAMemColSky(const PPFeatureInfo &in_data, DRMPPFeatureInfo *out_data);
-  static DisplayError GetDrmPAMemColFoliage(const PPFeatureInfo &in_data,
-                                            DRMPPFeatureInfo *out_data);
-  static DisplayError GetDrmPAMemColProt(const PPFeatureInfo &in_data, DRMPPFeatureInfo *out_data);
-};
-
-}  // namespace sdm
-
-#endif  // __HW_COLOR_MANAGER_DRM_H__
diff --git a/sdm/libs/core/drm/hw_device_drm.cpp b/sdm/libs/core/drm/hw_device_drm.cpp
deleted file mode 100644
index ef8deeb..0000000
--- a/sdm/libs/core/drm/hw_device_drm.cpp
+++ /dev/null
@@ -1,1579 +0,0 @@
-/*
-* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without
-* modification, are permitted provided that the following conditions are
-* met:
-*     * Redistributions of source code must retain the above copyright
-*       notice, this list of conditions and the following disclaimer.
-*     * Redistributions in binary form must reproduce the above
-*       copyright notice, this list of conditions and the following
-*       disclaimer in the documentation and/or other materials provided
-*       with the distribution.
-*     * Neither the name of The Linux Foundation nor the names of its
-*       contributors may be used to endorse or promote products derived
-*       from this software without specific prior written permission.
-*
-* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
-* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
-* ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
-* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
-* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#define __STDC_FORMAT_MACROS
-
-#include <ctype.h>
-#include <drm/drm_fourcc.h>
-#include <drm_lib_loader.h>
-#include <drm_master.h>
-#include <drm_res_mgr.h>
-#include <fcntl.h>
-#include <inttypes.h>
-#include <linux/fb.h>
-#include <math.h>
-#include <stdio.h>
-#include <string.h>
-#include <sys/ioctl.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <unistd.h>
-#include <utils/constants.h>
-#include <utils/debug.h>
-#include <utils/formats.h>
-#include <utils/sys.h>
-#include <drm/sde_drm.h>
-#include <private/color_params.h>
-#include <utils/rect.h>
-
-#include <algorithm>
-#include <string>
-#include <unordered_map>
-#include <utility>
-#include <vector>
-#include <limits>
-
-#include "hw_device_drm.h"
-#include "hw_info_interface.h"
-#include "hw_color_manager_drm.h"
-
-#define __CLASS__ "HWDeviceDRM"
-
-#ifndef DRM_FORMAT_MOD_QCOM_COMPRESSED
-#define DRM_FORMAT_MOD_QCOM_COMPRESSED fourcc_mod_code(QCOM, 1)
-#endif
-#ifndef DRM_FORMAT_MOD_QCOM_DX
-#define DRM_FORMAT_MOD_QCOM_DX fourcc_mod_code(QCOM, 0x2)
-#endif
-#ifndef DRM_FORMAT_MOD_QCOM_TIGHT
-#define DRM_FORMAT_MOD_QCOM_TIGHT fourcc_mod_code(QCOM, 0x4)
-#endif
-
-using std::string;
-using std::to_string;
-using std::fstream;
-using std::unordered_map;
-using drm_utils::DRMMaster;
-using drm_utils::DRMResMgr;
-using drm_utils::DRMLibLoader;
-using drm_utils::DRMBuffer;
-using sde_drm::GetDRMManager;
-using sde_drm::DestroyDRMManager;
-using sde_drm::DRMDisplayType;
-using sde_drm::DRMDisplayToken;
-using sde_drm::DRMConnectorInfo;
-using sde_drm::DRMPPFeatureInfo;
-using sde_drm::DRMRect;
-using sde_drm::DRMRotation;
-using sde_drm::DRMBlendType;
-using sde_drm::DRMSrcConfig;
-using sde_drm::DRMOps;
-using sde_drm::DRMTopology;
-using sde_drm::DRMPowerMode;
-using sde_drm::DRMSecureMode;
-using sde_drm::DRMSecurityLevel;
-using sde_drm::DRMCscType;
-using sde_drm::DRMMultiRectMode;
-
-namespace sdm {
-
-static void GetDRMFormat(LayerBufferFormat format, uint32_t *drm_format,
-                         uint64_t *drm_format_modifier) {
-  switch (format) {
-    case kFormatRGBA8888:
-      *drm_format = DRM_FORMAT_ABGR8888;
-      break;
-    case kFormatRGBA8888Ubwc:
-      *drm_format = DRM_FORMAT_ABGR8888;
-      *drm_format_modifier = DRM_FORMAT_MOD_QCOM_COMPRESSED;
-      break;
-    case kFormatRGBA5551:
-      *drm_format = DRM_FORMAT_ABGR1555;
-      break;
-    case kFormatRGBA4444:
-      *drm_format = DRM_FORMAT_ABGR4444;
-      break;
-    case kFormatBGRA8888:
-      *drm_format = DRM_FORMAT_ARGB8888;
-      break;
-    case kFormatRGBX8888:
-      *drm_format = DRM_FORMAT_XBGR8888;
-      break;
-    case kFormatRGBX8888Ubwc:
-      *drm_format = DRM_FORMAT_XBGR8888;
-      *drm_format_modifier = DRM_FORMAT_MOD_QCOM_COMPRESSED;
-      break;
-    case kFormatBGRX8888:
-      *drm_format = DRM_FORMAT_XRGB8888;
-      break;
-    case kFormatRGB888:
-      *drm_format = DRM_FORMAT_BGR888;
-      break;
-    case kFormatRGB565:
-      *drm_format = DRM_FORMAT_BGR565;
-      break;
-    case kFormatBGR565:
-      *drm_format = DRM_FORMAT_RGB565;
-      break;
-    case kFormatBGR565Ubwc:
-      *drm_format = DRM_FORMAT_BGR565;
-      *drm_format_modifier = DRM_FORMAT_MOD_QCOM_COMPRESSED;
-      break;
-    case kFormatRGBA1010102:
-      *drm_format = DRM_FORMAT_ABGR2101010;
-      break;
-    case kFormatRGBA1010102Ubwc:
-      *drm_format = DRM_FORMAT_ABGR2101010;
-      *drm_format_modifier = DRM_FORMAT_MOD_QCOM_COMPRESSED;
-      break;
-    case kFormatARGB2101010:
-      *drm_format = DRM_FORMAT_BGRA1010102;
-      break;
-    case kFormatRGBX1010102:
-      *drm_format = DRM_FORMAT_XBGR2101010;
-      break;
-    case kFormatRGBX1010102Ubwc:
-      *drm_format = DRM_FORMAT_XBGR2101010;
-      *drm_format_modifier = DRM_FORMAT_MOD_QCOM_COMPRESSED;
-      break;
-    case kFormatXRGB2101010:
-      *drm_format = DRM_FORMAT_BGRX1010102;
-      break;
-    case kFormatBGRA1010102:
-      *drm_format = DRM_FORMAT_ARGB2101010;
-      break;
-    case kFormatABGR2101010:
-      *drm_format = DRM_FORMAT_RGBA1010102;
-      break;
-    case kFormatBGRX1010102:
-      *drm_format = DRM_FORMAT_XRGB2101010;
-      break;
-    case kFormatXBGR2101010:
-      *drm_format = DRM_FORMAT_RGBX1010102;
-      break;
-    case kFormatYCbCr420SemiPlanar:
-      *drm_format = DRM_FORMAT_NV12;
-      break;
-    case kFormatYCbCr420SemiPlanarVenus:
-      *drm_format = DRM_FORMAT_NV12;
-      break;
-    case kFormatYCbCr420SPVenusUbwc:
-      *drm_format = DRM_FORMAT_NV12;
-      *drm_format_modifier = DRM_FORMAT_MOD_QCOM_COMPRESSED;
-      break;
-    case kFormatYCrCb420SemiPlanar:
-      *drm_format = DRM_FORMAT_NV21;
-      break;
-    case kFormatYCrCb420SemiPlanarVenus:
-      *drm_format = DRM_FORMAT_NV21;
-      break;
-    case kFormatYCbCr420P010:
-    case kFormatYCbCr420P010Venus:
-      *drm_format = DRM_FORMAT_NV12;
-      *drm_format_modifier = DRM_FORMAT_MOD_QCOM_DX;
-      break;
-    case kFormatYCbCr420P010Ubwc:
-      *drm_format = DRM_FORMAT_NV12;
-      *drm_format_modifier = DRM_FORMAT_MOD_QCOM_COMPRESSED |
-        DRM_FORMAT_MOD_QCOM_DX;
-      break;
-    case kFormatYCbCr420TP10Ubwc:
-      *drm_format = DRM_FORMAT_NV12;
-      *drm_format_modifier = DRM_FORMAT_MOD_QCOM_COMPRESSED |
-        DRM_FORMAT_MOD_QCOM_DX | DRM_FORMAT_MOD_QCOM_TIGHT;
-      break;
-    case kFormatYCbCr422H2V1SemiPlanar:
-      *drm_format = DRM_FORMAT_NV16;
-      break;
-    case kFormatYCrCb422H2V1SemiPlanar:
-      *drm_format = DRM_FORMAT_NV61;
-      break;
-    case kFormatYCrCb420PlanarStride16:
-      *drm_format = DRM_FORMAT_YVU420;
-      break;
-    default:
-      DLOGW("Unsupported format %s", GetFormatString(format));
-  }
-}
-
-HWDeviceDRM::Registry::Registry(BufferAllocator *buffer_allocator) :
-  buffer_allocator_(buffer_allocator) {
-  DRMMaster *master = nullptr;
-  DRMMaster::GetInstance(&master);
-
-  if (!master) {
-    DLOGE("Failed to acquire DRM Master instance");
-    return;
-  }
-
-  // If RMFB is ref-counted, we should immediately make a call to clean up fb_id after commit.
-  // Driver will release fb_id after its usage. Otherwise speculatively free up fb_id after 3
-  // cycles assuming driver is done with it.
-  rmfb_delay_ = master->IsRmFbRefCounted() ? 1 : 3;
-  hashmap_ = new std::unordered_map<int, uint32_t>[rmfb_delay_];
-}
-
-HWDeviceDRM::Registry::~Registry() {
-  delete [] hashmap_;
-}
-
-void HWDeviceDRM::Registry::Register(HWLayers *hw_layers) {
-  HWLayersInfo &hw_layer_info = hw_layers->info;
-  uint32_t hw_layer_count = UINT32(hw_layer_info.hw_layers.size());
-
-  for (uint32_t i = 0; i < hw_layer_count; i++) {
-    Layer &layer = hw_layer_info.hw_layers.at(i);
-    LayerBuffer *input_buffer = &layer.input_buffer;
-    HWRotatorSession *hw_rotator_session = &hw_layers->config[i].hw_rotator_session;
-    HWRotateInfo *hw_rotate_info = &hw_rotator_session->hw_rotate_info[0];
-
-    if (hw_rotator_session->mode == kRotatorOffline && hw_rotate_info->valid) {
-      input_buffer = &hw_rotator_session->output_buffer;
-    }
-
-    MapBufferToFbId(input_buffer);
-  }
-}
-
-void HWDeviceDRM::Registry::MapBufferToFbId(LayerBuffer* buffer) {
-  int fd = buffer->planes[0].fd;
-  DRMMaster *master = nullptr;
-  DRMMaster::GetInstance(&master);
-
-  if (!master) {
-    DLOGE("Failed to acquire DRM Master instance");
-    return;
-  }
-
-  if (fd >= 0 && hashmap_[current_index_].find(fd) == hashmap_[current_index_].end()) {
-    AllocatedBufferInfo buf_info{};
-    DRMBuffer layout{};
-    buf_info.fd = layout.fd = fd;
-    buf_info.aligned_width = layout.width = buffer->width;
-    buf_info.aligned_height = layout.height = buffer->height;
-    buf_info.format = buffer->format;
-    GetDRMFormat(buf_info.format, &layout.drm_format, &layout.drm_format_modifier);
-    buffer_allocator_->GetBufferLayout(buf_info, layout.stride, layout.offset,
-        &layout.num_planes);
-    uint32_t fb_id = 0;
-    int ret = master->CreateFbId(layout, &fb_id);
-    if (ret < 0) {
-      DLOGW("CreateFbId failed. width %d, height %d, format: %s, stride %u, error %d",
-          layout.width, layout.height, GetFormatString(buf_info.format), layout.stride[0],
-          errno);
-    } else {
-      hashmap_[current_index_][fd] = fb_id;
-    }
-  }
-  return;
-}
-
-void HWDeviceDRM::Registry::Next() {
-  current_index_ = (current_index_ + 1) % rmfb_delay_;
-}
-
-void HWDeviceDRM::Registry::Unregister() {
-  DRMMaster *master = nullptr;
-  DRMMaster::GetInstance(&master);
-
-  if (!master) {
-    DLOGE("Failed to acquire DRM Master instance");
-    return;
-  }
-
-  auto &curr_map = hashmap_[current_index_];
-  for (auto &pair : curr_map) {
-    uint32_t fb_id = pair.second;
-    int ret = master->RemoveFbId(fb_id);
-    if (ret < 0) {
-      DLOGE("Removing fb_id %d failed with error %d", fb_id, errno);
-    }
-  }
-
-  curr_map.clear();
-}
-
-void HWDeviceDRM::Registry::Clear() {
-  for (int i = 0; i < rmfb_delay_; i++) {
-    Unregister();
-    Next();
-  }
-  current_index_ = 0;
-}
-
-uint32_t HWDeviceDRM::Registry::GetFbId(int fd) {
-  auto it = hashmap_[current_index_].find(fd);
-  return (it == hashmap_[current_index_].end()) ? 0 : it->second;
-}
-
-HWDeviceDRM::HWDeviceDRM(BufferSyncHandler *buffer_sync_handler, BufferAllocator *buffer_allocator,
-                         HWInfoInterface *hw_info_intf)
-    : hw_info_intf_(hw_info_intf), buffer_sync_handler_(buffer_sync_handler),
-      registry_(buffer_allocator) {
-  hw_info_intf_ = hw_info_intf;
-}
-
-DisplayError HWDeviceDRM::Init() {
-  DRMMaster *drm_master = {};
-  DRMMaster::GetInstance(&drm_master);
-  drm_master->GetHandle(&dev_fd_);
-  DRMLibLoader::GetInstance()->FuncGetDRMManager()(dev_fd_, &drm_mgr_intf_);
-
-  if (drm_mgr_intf_->RegisterDisplay(disp_type_, &token_)) {
-    DLOGE("RegisterDisplay failed for %s", device_name_);
-    return kErrorResources;
-  }
-
-  drm_mgr_intf_->CreateAtomicReq(token_, &drm_atomic_intf_);
-  drm_mgr_intf_->GetConnectorInfo(token_.conn_id, &connector_info_);
-  hw_info_intf_->GetHWResourceInfo(&hw_resource_);
-
-  InitializeConfigs();
-  PopulateHWPanelInfo();
-  UpdateMixerAttributes();
-
-  // TODO(user): In future, remove has_qseed3 member, add version and pass version to constructor
-  if (hw_resource_.has_qseed3) {
-    hw_scale_ = new HWScaleDRM(HWScaleDRM::Version::V2);
-  }
-
-  return kErrorNone;
-}
-
-DisplayError HWDeviceDRM::Deinit() {
-  DisplayError err = kErrorNone;
-  drm_atomic_intf_->Perform(DRMOps::CONNECTOR_SET_CRTC, token_.conn_id, 0);
-  drm_atomic_intf_->Perform(DRMOps::CONNECTOR_SET_POWER_MODE, token_.conn_id, DRMPowerMode::OFF);
-  drm_atomic_intf_->Perform(DRMOps::CRTC_SET_MODE, token_.crtc_id, nullptr);
-  drm_atomic_intf_->Perform(DRMOps::CRTC_SET_ACTIVE, token_.crtc_id, 0);
-  int ret = drm_atomic_intf_->Commit(true /* synchronous */, false /* retain_planes */);
-  if (ret) {
-    DLOGE("Commit failed with error: %d", ret);
-    err = kErrorHardware;
-  }
-
-  delete hw_scale_;
-  registry_.Clear();
-  display_attributes_ = {};
-  drm_mgr_intf_->DestroyAtomicReq(drm_atomic_intf_);
-  drm_atomic_intf_ = {};
-  drm_mgr_intf_->UnregisterDisplay(token_);
-  return err;
-}
-
-void HWDeviceDRM::InitializeConfigs() {
-  current_mode_index_ = 0;
-  // Update current mode with preferred mode
-  for (uint32_t mode_index = 0; mode_index < connector_info_.modes.size(); mode_index++) {
-      if (connector_info_.modes[mode_index].mode.type & DRM_MODE_TYPE_PREFERRED) {
-        current_mode_index_ = mode_index;
-        break;
-      }
-  }
-
-  display_attributes_.resize(connector_info_.modes.size());
-
-  uint32_t width = connector_info_.modes[current_mode_index_].mode.hdisplay;
-  uint32_t height = connector_info_.modes[current_mode_index_].mode.vdisplay;
-  for (uint32_t i = 0; i < connector_info_.modes.size(); i++) {
-    auto &mode = connector_info_.modes[i].mode;
-    if (mode.hdisplay != width || mode.vdisplay != height) {
-      resolution_switch_enabled_ = true;
-    }
-    PopulateDisplayAttributes(i);
-  }
-}
-
-DisplayError HWDeviceDRM::PopulateDisplayAttributes(uint32_t index) {
-  drmModeModeInfo mode = {};
-  uint32_t mm_width = 0;
-  uint32_t mm_height = 0;
-  DRMTopology topology = DRMTopology::SINGLE_LM;
-
-  if (default_mode_) {
-    DRMResMgr *res_mgr = nullptr;
-    int ret = DRMResMgr::GetInstance(&res_mgr);
-    if (ret < 0) {
-      DLOGE("Failed to acquire DRMResMgr instance");
-      return kErrorResources;
-    }
-
-    res_mgr->GetMode(&mode);
-    res_mgr->GetDisplayDimInMM(&mm_width, &mm_height);
-  } else {
-    mode = connector_info_.modes[index].mode;
-    mm_width = connector_info_.mmWidth;
-    mm_height = connector_info_.mmHeight;
-    topology = connector_info_.modes[index].topology;
-  }
-
-  display_attributes_[index].x_pixels = mode.hdisplay;
-  display_attributes_[index].y_pixels = mode.vdisplay;
-  display_attributes_[index].fps = mode.vrefresh;
-  display_attributes_[index].vsync_period_ns =
-    UINT32(1000000000L / display_attributes_[index].fps);
-
-  /*
-              Active                 Front           Sync           Back
-              Region                 Porch                          Porch
-     <-----------------------><----------------><-------------><-------------->
-     <----- [hv]display ----->
-     <------------- [hv]sync_start ------------>
-     <--------------------- [hv]sync_end --------------------->
-     <-------------------------------- [hv]total ----------------------------->
-   */
-
-  display_attributes_[index].v_front_porch = mode.vsync_start - mode.vdisplay;
-  display_attributes_[index].v_pulse_width = mode.vsync_end - mode.vsync_start;
-  display_attributes_[index].v_back_porch = mode.vtotal - mode.vsync_end;
-  display_attributes_[index].v_total = mode.vtotal;
-  display_attributes_[index].h_total = mode.htotal;
-  display_attributes_[index].is_device_split =
-      (topology == DRMTopology::DUAL_LM || topology == DRMTopology::DUAL_LM_MERGE ||
-       topology == DRMTopology::DUAL_LM_MERGE_DSC || topology == DRMTopology::DUAL_LM_DSC ||
-       topology == DRMTopology::DUAL_LM_DSCMERGE);
-  display_attributes_[index].clock_khz = mode.clock;
-
-  // If driver doesn't return panel width/height information, default to 320 dpi
-  if (INT(mm_width) <= 0 || INT(mm_height) <= 0) {
-    mm_width  = UINT32(((FLOAT(mode.hdisplay) * 25.4f) / 320.0f) + 0.5f);
-    mm_height = UINT32(((FLOAT(mode.vdisplay) * 25.4f) / 320.0f) + 0.5f);
-    DLOGW("Driver doesn't report panel physical width and height - defaulting to 320dpi");
-  }
-
-  display_attributes_[index].x_dpi = (FLOAT(mode.hdisplay) * 25.4f) / FLOAT(mm_width);
-  display_attributes_[index].y_dpi = (FLOAT(mode.vdisplay) * 25.4f) / FLOAT(mm_height);
-  SetTopology(topology, &display_attributes_[index].topology);
-
-  DLOGI("Display attributes[%d]: WxH: %dx%d, DPI: %fx%f, FPS: %d, LM_SPLIT: %d, V_BACK_PORCH: %d," \
-        " V_FRONT_PORCH: %d, V_PULSE_WIDTH: %d, V_TOTAL: %d, H_TOTAL: %d, CLK: %dKHZ, TOPOLOGY: %d",
-        index, display_attributes_[index].x_pixels, display_attributes_[index].y_pixels,
-        display_attributes_[index].x_dpi, display_attributes_[index].y_dpi,
-        display_attributes_[index].fps, display_attributes_[index].is_device_split,
-        display_attributes_[index].v_back_porch, display_attributes_[index].v_front_porch,
-        display_attributes_[index].v_pulse_width, display_attributes_[index].v_total,
-        display_attributes_[index].h_total, display_attributes_[index].clock_khz,
-        display_attributes_[index].topology);
-
-  return kErrorNone;
-}
-
-void HWDeviceDRM::PopulateHWPanelInfo() {
-  hw_panel_info_ = {};
-
-  snprintf(hw_panel_info_.panel_name, sizeof(hw_panel_info_.panel_name), "%s",
-           connector_info_.panel_name.c_str());
-
-  uint32_t index = current_mode_index_;
-  hw_panel_info_.split_info.left_split = display_attributes_[index].x_pixels;
-  if (display_attributes_[index].is_device_split) {
-    hw_panel_info_.split_info.left_split = hw_panel_info_.split_info.right_split =
-        display_attributes_[index].x_pixels / 2;
-  }
-
-  hw_panel_info_.partial_update = connector_info_.modes[index].num_roi;
-  hw_panel_info_.left_roi_count = UINT32(connector_info_.modes[index].num_roi);
-  hw_panel_info_.right_roi_count = UINT32(connector_info_.modes[index].num_roi);
-  hw_panel_info_.left_align = connector_info_.modes[index].xstart;
-  hw_panel_info_.top_align = connector_info_.modes[index].ystart;
-  hw_panel_info_.width_align = connector_info_.modes[index].walign;
-  hw_panel_info_.height_align = connector_info_.modes[index].halign;
-  hw_panel_info_.min_roi_width = connector_info_.modes[index].wmin;
-  hw_panel_info_.min_roi_height = connector_info_.modes[index].hmin;
-  hw_panel_info_.needs_roi_merge = connector_info_.modes[index].roi_merge;
-  hw_panel_info_.dynamic_fps = connector_info_.dynamic_fps;
-  drmModeModeInfo current_mode = connector_info_.modes[current_mode_index_].mode;
-  if (hw_panel_info_.dynamic_fps) {
-    uint32_t min_fps = current_mode.vrefresh;
-    uint32_t max_fps = current_mode.vrefresh;
-    for (uint32_t mode_index = 0; mode_index < connector_info_.modes.size(); mode_index++) {
-      if ((current_mode.vdisplay == connector_info_.modes[mode_index].mode.vdisplay) &&
-          (current_mode.hdisplay == connector_info_.modes[mode_index].mode.hdisplay)) {
-        if (min_fps > connector_info_.modes[mode_index].mode.vrefresh)  {
-          min_fps = connector_info_.modes[mode_index].mode.vrefresh;
-        }
-        if (max_fps < connector_info_.modes[mode_index].mode.vrefresh)  {
-          max_fps = connector_info_.modes[mode_index].mode.vrefresh;
-        }
-      }
-    }
-    hw_panel_info_.min_fps = min_fps;
-    hw_panel_info_.max_fps = max_fps;
-  } else {
-    hw_panel_info_.min_fps = current_mode.vrefresh;
-    hw_panel_info_.max_fps = current_mode.vrefresh;
-  }
-
-  hw_panel_info_.is_primary_panel = connector_info_.is_primary;
-  hw_panel_info_.is_pluggable = 0;
-  hw_panel_info_.hdr_enabled = connector_info_.panel_hdr_prop.hdr_enabled;
-  hw_panel_info_.peak_luminance = connector_info_.panel_hdr_prop.peak_brightness;
-  hw_panel_info_.blackness_level = connector_info_.panel_hdr_prop.blackness_level;
-  hw_panel_info_.primaries.white_point[0] = connector_info_.panel_hdr_prop.display_primaries[0];
-  hw_panel_info_.primaries.white_point[1] = connector_info_.panel_hdr_prop.display_primaries[1];
-  hw_panel_info_.primaries.red[0] = connector_info_.panel_hdr_prop.display_primaries[2];
-  hw_panel_info_.primaries.red[1] = connector_info_.panel_hdr_prop.display_primaries[3];
-  hw_panel_info_.primaries.green[0] = connector_info_.panel_hdr_prop.display_primaries[4];
-  hw_panel_info_.primaries.green[1] = connector_info_.panel_hdr_prop.display_primaries[5];
-  hw_panel_info_.primaries.blue[0] = connector_info_.panel_hdr_prop.display_primaries[6];
-  hw_panel_info_.primaries.blue[1] = connector_info_.panel_hdr_prop.display_primaries[7];
-  hw_panel_info_.transfer_time_us = connector_info_.transfer_time_us;
-
-  // no supprt for 90 rotation only flips or 180 supported
-  hw_panel_info_.panel_orientation.rotation = 0;
-  hw_panel_info_.panel_orientation.flip_horizontal =
-    (connector_info_.panel_orientation == DRMRotation::FLIP_H) ||
-    (connector_info_.panel_orientation == DRMRotation::ROT_180);
-  hw_panel_info_.panel_orientation.flip_vertical =
-    (connector_info_.panel_orientation == DRMRotation::FLIP_V) ||
-    (connector_info_.panel_orientation == DRMRotation::ROT_180);
-
-  GetHWDisplayPortAndMode();
-  GetHWPanelMaxBrightness();
-
-  DLOGI("%s, Panel Interface = %s, Panel Mode = %s, Is Primary = %d", device_name_,
-        interface_str_.c_str(), hw_panel_info_.mode == kModeVideo ? "Video" : "Command",
-        hw_panel_info_.is_primary_panel);
-  DLOGI("Partial Update = %d, Dynamic FPS = %d, HDR Panel = %d", hw_panel_info_.partial_update,
-        hw_panel_info_.dynamic_fps, hw_panel_info_.hdr_enabled);
-  DLOGI("Align: left = %d, width = %d, top = %d, height = %d", hw_panel_info_.left_align,
-        hw_panel_info_.width_align, hw_panel_info_.top_align, hw_panel_info_.height_align);
-  DLOGI("ROI: min_width = %d, min_height = %d, need_merge = %d", hw_panel_info_.min_roi_width,
-        hw_panel_info_.min_roi_height, hw_panel_info_.needs_roi_merge);
-  DLOGI("FPS: min = %d, max = %d", hw_panel_info_.min_fps, hw_panel_info_.max_fps);
-  DLOGI("Left Split = %d, Right Split = %d", hw_panel_info_.split_info.left_split,
-        hw_panel_info_.split_info.right_split);
-  DLOGI("Panel Transfer time = %d us", hw_panel_info_.transfer_time_us);
-}
-
-void HWDeviceDRM::GetHWDisplayPortAndMode() {
-  hw_panel_info_.port = kPortDefault;
-  hw_panel_info_.mode =
-      (connector_info_.panel_mode == sde_drm::DRMPanelMode::VIDEO) ? kModeVideo : kModeCommand;
-
-  if (default_mode_) {
-    return;
-  }
-
-  switch (connector_info_.type) {
-    case DRM_MODE_CONNECTOR_DSI:
-      hw_panel_info_.port = kPortDSI;
-      interface_str_ = "DSI";
-      break;
-    case DRM_MODE_CONNECTOR_LVDS:
-      hw_panel_info_.port = kPortLVDS;
-      interface_str_ = "LVDS";
-      break;
-    case DRM_MODE_CONNECTOR_eDP:
-      hw_panel_info_.port = kPortEDP;
-      interface_str_ = "EDP";
-      break;
-    case DRM_MODE_CONNECTOR_TV:
-    case DRM_MODE_CONNECTOR_HDMIA:
-    case DRM_MODE_CONNECTOR_HDMIB:
-      hw_panel_info_.port = kPortDTV;
-      interface_str_ = "HDMI";
-      break;
-    case DRM_MODE_CONNECTOR_VIRTUAL:
-      hw_panel_info_.port = kPortWriteBack;
-      interface_str_ = "Virtual";
-      break;
-    case DRM_MODE_CONNECTOR_DisplayPort:
-      // TODO(user): Add when available
-      interface_str_ = "DisplayPort";
-      break;
-  }
-
-  return;
-}
-
-void HWDeviceDRM::GetHWPanelMaxBrightness() {
-  char brightness[kMaxStringLength] = {0};
-  string kMaxBrightnessNode = "/sys/class/backlight/panel0-backlight/max_brightness";
-
-  hw_panel_info_.panel_max_brightness = 255;
-  int fd = Sys::open_(kMaxBrightnessNode.c_str(), O_RDONLY);
-  if (fd < 0) {
-    DLOGW("Failed to open max brightness node = %s, error = %s", kMaxBrightnessNode.c_str(),
-          strerror(errno));
-    return;
-  }
-
-  if (Sys::pread_(fd, brightness, sizeof(brightness), 0) > 0) {
-    hw_panel_info_.panel_max_brightness = atoi(brightness);
-    DLOGI("Max brightness level = %d", hw_panel_info_.panel_max_brightness);
-  } else {
-    DLOGW("Failed to read max brightness level. error = %s", strerror(errno));
-  }
-
-  Sys::close_(fd);
-}
-
-DisplayError HWDeviceDRM::GetActiveConfig(uint32_t *active_config) {
-  if (IsResolutionSwitchEnabled()) {
-    *active_config = current_mode_index_;
-  } else {
-    *active_config = 0;
-  }
-  return kErrorNone;
-}
-
-DisplayError HWDeviceDRM::GetNumDisplayAttributes(uint32_t *count) {
-  if (IsResolutionSwitchEnabled()) {
-    *count = UINT32(display_attributes_.size());
-    if (*count <= 0) {
-       return kErrorHardware;
-    }
-  } else {
-    *count = 1;
-  }
-  return kErrorNone;
-}
-
-DisplayError HWDeviceDRM::GetDisplayAttributes(uint32_t index,
-                                               HWDisplayAttributes *display_attributes) {
-  if (index >= display_attributes_.size()) {
-    return kErrorParameters;
-  }
-  if (IsResolutionSwitchEnabled()) {
-    *display_attributes = display_attributes_[index];
-  } else {
-    *display_attributes = display_attributes_[current_mode_index_];
-  }
-  return kErrorNone;
-}
-
-DisplayError HWDeviceDRM::GetHWPanelInfo(HWPanelInfo *panel_info) {
-  *panel_info = hw_panel_info_;
-  return kErrorNone;
-}
-
-DisplayError HWDeviceDRM::SetDisplayAttributes(uint32_t index) {
-  if (!IsResolutionSwitchEnabled()) {
-    return kErrorNotSupported;
-  }
-
-  if (index >= display_attributes_.size()) {
-    DLOGE("Invalid mode index %d mode size %d", index, UINT32(display_attributes_.size()));
-    return kErrorParameters;
-  }
-
-  current_mode_index_ = index;
-  PopulateHWPanelInfo();
-  UpdateMixerAttributes();
-
-  DLOGI("Display attributes[%d]: WxH: %dx%d, DPI: %fx%f, FPS: %d, LM_SPLIT: %d, V_BACK_PORCH: %d," \
-        " V_FRONT_PORCH: %d, V_PULSE_WIDTH: %d, V_TOTAL: %d, H_TOTAL: %d, CLK: %dKHZ, TOPOLOGY: %d",
-        index, display_attributes_[index].x_pixels, display_attributes_[index].y_pixels,
-        display_attributes_[index].x_dpi, display_attributes_[index].y_dpi,
-        display_attributes_[index].fps, display_attributes_[index].is_device_split,
-        display_attributes_[index].v_back_porch, display_attributes_[index].v_front_porch,
-        display_attributes_[index].v_pulse_width, display_attributes_[index].v_total,
-        display_attributes_[index].h_total, display_attributes_[index].clock_khz,
-        display_attributes_[index].topology);
-
-  return kErrorNone;
-}
-
-DisplayError HWDeviceDRM::SetDisplayAttributes(const HWDisplayAttributes &display_attributes) {
-  return kErrorNotSupported;
-}
-
-DisplayError HWDeviceDRM::GetConfigIndex(char *mode, uint32_t *index) {
-  return kErrorNone;
-}
-
-DisplayError HWDeviceDRM::PowerOn(int *release_fence) {
-  DTRACE_SCOPED();
-  if (!drm_atomic_intf_) {
-    DLOGE("DRM Atomic Interface is null!");
-    return kErrorUndefined;
-  }
-
-  if (first_cycle_) {
-    return kErrorNone;
-  }
-
-  drm_atomic_intf_->Perform(DRMOps::CRTC_SET_ACTIVE, token_.crtc_id, 1);
-  drm_atomic_intf_->Perform(DRMOps::CONNECTOR_SET_POWER_MODE, token_.conn_id, DRMPowerMode::ON);
-  int ret = drm_atomic_intf_->Commit(true /* synchronous */, true /* retain_planes */);
-  if (ret) {
-    DLOGE("Failed with error: %d", ret);
-    return kErrorHardware;
-  }
-  drm_atomic_intf_->Perform(DRMOps::CRTC_GET_RELEASE_FENCE, token_.crtc_id, release_fence);
-
-  return kErrorNone;
-}
-
-DisplayError HWDeviceDRM::PowerOff() {
-  DTRACE_SCOPED();
-  if (!drm_atomic_intf_) {
-    DLOGE("DRM Atomic Interface is null!");
-    return kErrorUndefined;
-  }
-
-  SetFullROI();
-  drmModeModeInfo current_mode = connector_info_.modes[current_mode_index_].mode;
-  drm_atomic_intf_->Perform(DRMOps::CRTC_SET_MODE, token_.crtc_id, &current_mode);
-  drm_atomic_intf_->Perform(DRMOps::CONNECTOR_SET_POWER_MODE, token_.conn_id, DRMPowerMode::OFF);
-  drm_atomic_intf_->Perform(DRMOps::CRTC_SET_ACTIVE, token_.crtc_id, 0);
-  int ret = drm_atomic_intf_->Commit(true /* synchronous */, false /* retain_planes */);
-  if (ret) {
-    DLOGE("Failed with error: %d", ret);
-    return kErrorHardware;
-  }
-
-  return kErrorNone;
-}
-
-DisplayError HWDeviceDRM::Doze(int *release_fence) {
-  DTRACE_SCOPED();
-  drm_atomic_intf_->Perform(DRMOps::CRTC_SET_ACTIVE, token_.crtc_id, 1);
-  drm_atomic_intf_->Perform(DRMOps::CONNECTOR_SET_POWER_MODE, token_.conn_id, DRMPowerMode::DOZE);
-  int ret = drm_atomic_intf_->Commit(true /* synchronous */, true /* retain_planes */);
-  if (ret) {
-    DLOGE("Failed with error: %d", ret);
-    return kErrorHardware;
-  }
-
-  drm_atomic_intf_->Perform(DRMOps::CRTC_GET_RELEASE_FENCE, token_.crtc_id, release_fence);
-
-  return kErrorNone;
-}
-
-DisplayError HWDeviceDRM::DozeSuspend(int *release_fence) {
-  DTRACE_SCOPED();
-  drm_atomic_intf_->Perform(DRMOps::CRTC_SET_ACTIVE, token_.crtc_id, 1);
-  drm_atomic_intf_->Perform(DRMOps::CONNECTOR_SET_POWER_MODE, token_.conn_id,
-                            DRMPowerMode::DOZE_SUSPEND);
-  int ret = drm_atomic_intf_->Commit(true /* synchronous */, true /* retain_planes */);
-  if (ret) {
-    DLOGE("Failed with error: %d", ret);
-    return kErrorHardware;
-  }
-
-  drm_atomic_intf_->Perform(DRMOps::CRTC_GET_RELEASE_FENCE, token_.crtc_id, release_fence);
-
-  return kErrorNone;
-}
-
-DisplayError HWDeviceDRM::Standby() {
-  return kErrorNone;
-}
-
-void HWDeviceDRM::SetupAtomic(HWLayers *hw_layers, bool validate) {
-  if (default_mode_) {
-    return;
-  }
-
-  HWLayersInfo &hw_layer_info = hw_layers->info;
-  uint32_t hw_layer_count = UINT32(hw_layer_info.hw_layers.size());
-  HWQosData &qos_data = hw_layers->qos_data;
-  DRMSecurityLevel crtc_security_level = DRMSecurityLevel::SECURE_NON_SECURE;
-  uint32_t index = current_mode_index_;
-  drmModeModeInfo current_mode = connector_info_.modes[index].mode;
-
-  solid_fills_.clear();
-
-  // TODO(user): Once destination scalar is enabled we can always send ROIs if driver allows
-  if (hw_panel_info_.partial_update) {
-    const int kNumMaxROIs = 4;
-    DRMRect crtc_rects[kNumMaxROIs] = {{0, 0, mixer_attributes_.width, mixer_attributes_.height}};
-    DRMRect conn_rects[kNumMaxROIs] = {{0, 0, display_attributes_[index].x_pixels,
-                                        display_attributes_[index].y_pixels}};
-
-    for (uint32_t i = 0; i < hw_layer_info.left_frame_roi.size(); i++) {
-      auto &roi = hw_layer_info.left_frame_roi.at(i);
-      // TODO(user): In multi PU, stitch ROIs vertically adjacent and upate plane destination
-      crtc_rects[i].left = UINT32(roi.left);
-      crtc_rects[i].right = UINT32(roi.right);
-      crtc_rects[i].top = UINT32(roi.top);
-      crtc_rects[i].bottom = UINT32(roi.bottom);
-      // TODO(user): In Dest scaler + PU, populate from HWDestScaleInfo->panel_roi
-      // TODO(user): panel_roi need to be made as a vector in HWLayersInfo and
-      // needs to be removed from  HWDestScaleInfo.
-      conn_rects[i].left = UINT32(roi.left);
-      conn_rects[i].right = UINT32(roi.right);
-      conn_rects[i].top = UINT32(roi.top);
-      conn_rects[i].bottom = UINT32(roi.bottom);
-    }
-
-    uint32_t num_rects = std::max(1u, static_cast<uint32_t>(hw_layer_info.left_frame_roi.size()));
-    drm_atomic_intf_->Perform(DRMOps::CRTC_SET_ROI, token_.crtc_id,
-                              num_rects, crtc_rects);
-    drm_atomic_intf_->Perform(DRMOps::CONNECTOR_SET_ROI, token_.conn_id,
-                              num_rects, conn_rects);
-  }
-
-  for (uint32_t i = 0; i < hw_layer_count; i++) {
-    Layer &layer = hw_layer_info.hw_layers.at(i);
-    LayerBuffer *input_buffer = &layer.input_buffer;
-    HWPipeInfo *left_pipe = &hw_layers->config[i].left_pipe;
-    HWPipeInfo *right_pipe = &hw_layers->config[i].right_pipe;
-    HWRotatorSession *hw_rotator_session = &hw_layers->config[i].hw_rotator_session;
-
-    if (hw_layers->config[i].use_solidfill_stage) {
-      hw_layers->config[i].hw_solidfill_stage.solid_fill_info = layer.solid_fill_info;
-      AddSolidfillStage(hw_layers->config[i].hw_solidfill_stage, layer.plane_alpha);
-      continue;
-    }
-
-    for (uint32_t count = 0; count < 2; count++) {
-      HWPipeInfo *pipe_info = (count == 0) ? left_pipe : right_pipe;
-      HWRotateInfo *hw_rotate_info = &hw_rotator_session->hw_rotate_info[count];
-
-      if (hw_rotator_session->mode == kRotatorOffline && hw_rotate_info->valid) {
-        input_buffer = &hw_rotator_session->output_buffer;
-      }
-
-      uint32_t fb_id = registry_.GetFbId(input_buffer->planes[0].fd);
-      if (pipe_info->valid && fb_id) {
-        uint32_t pipe_id = pipe_info->pipe_id;
-        drm_atomic_intf_->Perform(DRMOps::PLANE_SET_ALPHA, pipe_id, layer.plane_alpha);
-        drm_atomic_intf_->Perform(DRMOps::PLANE_SET_ZORDER, pipe_id, pipe_info->z_order);
-        DRMBlendType blending = {};
-        SetBlending(layer.blending, &blending);
-        drm_atomic_intf_->Perform(DRMOps::PLANE_SET_BLEND_TYPE, pipe_id, blending);
-        DRMRect src = {};
-        SetRect(pipe_info->src_roi, &src);
-        drm_atomic_intf_->Perform(DRMOps::PLANE_SET_SRC_RECT, pipe_id, src);
-        DRMRect rot_dst = {0, 0, 0, 0};
-        if (hw_rotator_session->mode == kRotatorInline && hw_rotate_info->valid) {
-          SetRect(hw_rotate_info->dst_roi, &rot_dst);
-          drm_atomic_intf_->Perform(DRMOps::PLANE_SET_ROTATION_DST_RECT, pipe_id, rot_dst);
-        }
-        DRMRect dst = {};
-        SetRect(pipe_info->dst_roi, &dst);
-        drm_atomic_intf_->Perform(DRMOps::PLANE_SET_DST_RECT, pipe_id, dst);
-
-        uint32_t rot_bit_mask = 0;
-        SetRotation(layer.transform, hw_rotator_session->mode, &rot_bit_mask);
-        drm_atomic_intf_->Perform(DRMOps::PLANE_SET_ROTATION, pipe_id, rot_bit_mask);
-        drm_atomic_intf_->Perform(DRMOps::PLANE_SET_H_DECIMATION, pipe_id,
-                                  pipe_info->horizontal_decimation);
-        drm_atomic_intf_->Perform(DRMOps::PLANE_SET_V_DECIMATION, pipe_id,
-                                  pipe_info->vertical_decimation);
-
-        DRMSecureMode fb_secure_mode;
-        DRMSecurityLevel security_level;
-        SetSecureConfig(layer.input_buffer, &fb_secure_mode, &security_level);
-        drm_atomic_intf_->Perform(DRMOps::PLANE_SET_FB_SECURE_MODE, pipe_id, fb_secure_mode);
-        if (security_level > crtc_security_level) {
-          crtc_security_level = security_level;
-        }
-
-        uint32_t config = 0;
-        SetSrcConfig(layer.input_buffer, hw_rotator_session->mode, &config);
-        drm_atomic_intf_->Perform(DRMOps::PLANE_SET_SRC_CONFIG, pipe_id, config);;
-        drm_atomic_intf_->Perform(DRMOps::PLANE_SET_FB_ID, pipe_id, fb_id);
-        drm_atomic_intf_->Perform(DRMOps::PLANE_SET_CRTC, pipe_id, token_.crtc_id);
-        if (!validate && input_buffer->acquire_fence_fd >= 0) {
-          drm_atomic_intf_->Perform(DRMOps::PLANE_SET_INPUT_FENCE, pipe_id,
-                                    input_buffer->acquire_fence_fd);
-        }
-        if (hw_scale_) {
-          SDEScaler scaler_output = {};
-          hw_scale_->SetScaler(pipe_info->scale_data, &scaler_output);
-          // TODO(user): Remove qseed3 and add version check, then send appropriate scaler object
-          if (hw_resource_.has_qseed3) {
-            drm_atomic_intf_->Perform(DRMOps::PLANE_SET_SCALER_CONFIG, pipe_id,
-                                      reinterpret_cast<uint64_t>(&scaler_output.scaler_v2));
-          }
-        }
-
-        DRMCscType csc_type = DRMCscType::kCscTypeMax;
-        SelectCscType(layer.input_buffer, &csc_type);
-        drm_atomic_intf_->Perform(DRMOps::PLANE_SET_CSC_CONFIG, pipe_id, &csc_type);
-
-        DRMMultiRectMode multirect_mode;
-        SetMultiRectMode(pipe_info->flags, &multirect_mode);
-        drm_atomic_intf_->Perform(DRMOps::PLANE_SET_MULTIRECT_MODE, pipe_id, multirect_mode);
-      }
-    }
-  }
-
-  SetSolidfillStages();
-  drm_atomic_intf_->Perform(DRMOps::CRTC_SET_CORE_CLK, token_.crtc_id, qos_data.clock_hz);
-  drm_atomic_intf_->Perform(DRMOps::CRTC_SET_CORE_AB, token_.crtc_id, qos_data.core_ab_bps);
-  drm_atomic_intf_->Perform(DRMOps::CRTC_SET_CORE_IB, token_.crtc_id, qos_data.core_ib_bps);
-  drm_atomic_intf_->Perform(DRMOps::CRTC_SET_LLCC_AB, token_.crtc_id, qos_data.llcc_ab_bps);
-  drm_atomic_intf_->Perform(DRMOps::CRTC_SET_LLCC_IB, token_.crtc_id, qos_data.llcc_ib_bps);
-  drm_atomic_intf_->Perform(DRMOps::CRTC_SET_DRAM_AB, token_.crtc_id, qos_data.dram_ab_bps);
-  drm_atomic_intf_->Perform(DRMOps::CRTC_SET_DRAM_IB, token_.crtc_id, qos_data.dram_ib_bps);
-  drm_atomic_intf_->Perform(DRMOps::CRTC_SET_ROT_PREFILL_BW, token_.crtc_id,
-                            qos_data.rot_prefill_bw_bps);
-  drm_atomic_intf_->Perform(DRMOps::CRTC_SET_ROT_CLK, token_.crtc_id, qos_data.rot_clock_hz);
-  drm_atomic_intf_->Perform(DRMOps::CRTC_SET_SECURITY_LEVEL, token_.crtc_id, crtc_security_level);
-
-  DLOGI_IF(kTagDriverConfig, "%s::%s System Clock=%d Hz, Core: AB=%llu Bps, IB=%llu Bps, " \
-           "LLCC: AB=%llu Bps, IB=%llu Bps, DRAM AB=%llu Bps, IB=%llu Bps, "\
-           "Rot: Bw=%llu Bps, Clock=%d Hz", validate ? "Validate" : "Commit", device_name_,
-           qos_data.clock_hz, qos_data.core_ab_bps, qos_data.core_ib_bps, qos_data.llcc_ab_bps,
-           qos_data.llcc_ib_bps, qos_data.dram_ab_bps, qos_data.dram_ib_bps,
-           qos_data.rot_prefill_bw_bps, qos_data.rot_clock_hz);
-
-  // Set refresh rate
-  if (vrefresh_) {
-    for (uint32_t mode_index = 0; mode_index < connector_info_.modes.size(); mode_index++) {
-      if ((current_mode.vdisplay == connector_info_.modes[mode_index].mode.vdisplay) &&
-          (current_mode.hdisplay == connector_info_.modes[mode_index].mode.hdisplay) &&
-          (vrefresh_ == connector_info_.modes[mode_index].mode.vrefresh)) {
-        current_mode = connector_info_.modes[mode_index].mode;
-        break;
-      }
-    }
-  }
-
-  if (first_cycle_) {
-    drm_atomic_intf_->Perform(DRMOps::CONNECTOR_SET_CRTC, token_.conn_id, token_.crtc_id);
-    drm_atomic_intf_->Perform(DRMOps::CONNECTOR_SET_POWER_MODE, token_.conn_id, DRMPowerMode::ON);
-  }
-
-  drm_atomic_intf_->Perform(DRMOps::CRTC_SET_MODE, token_.crtc_id, &current_mode);
-  drm_atomic_intf_->Perform(DRMOps::CRTC_SET_ACTIVE, token_.crtc_id, 1);
-
-  if (!validate && (hw_layer_info.set_idle_time_ms >= 0)) {
-    DLOGI_IF(kTagDriverConfig, "Setting idle timeout to = %d ms",
-             hw_layer_info.set_idle_time_ms);
-    drm_atomic_intf_->Perform(DRMOps::CRTC_SET_IDLE_TIMEOUT, token_.crtc_id,
-                              hw_layer_info.set_idle_time_ms);
-  }
-
-  if (hw_panel_info_.mode == kModeCommand) {
-    drm_atomic_intf_->Perform(DRMOps::CONNECTOR_SET_AUTOREFRESH, token_.conn_id, autorefresh_);
-  }
-}
-
-void HWDeviceDRM::AddSolidfillStage(const HWSolidfillStage &sf, uint32_t plane_alpha) {
-  sde_drm::DRMSolidfillStage solidfill;
-  solidfill.bounding_rect.left = UINT32(sf.roi.left);
-  solidfill.bounding_rect.top = UINT32(sf.roi.top);
-  solidfill.bounding_rect.right = UINT32(sf.roi.right);
-  solidfill.bounding_rect.bottom = UINT32(sf.roi.bottom);
-  solidfill.is_exclusion_rect  = sf.is_exclusion_rect;
-  solidfill.plane_alpha = plane_alpha;
-  solidfill.z_order = sf.z_order;
-  if (!sf.solid_fill_info.bit_depth) {
-    solidfill.color_bit_depth = 8;
-    solidfill.alpha = (0xff000000 & sf.color) >> 24;
-    solidfill.red = (0xff0000 & sf.color) >> 16;
-    solidfill.green = (0xff00 & sf.color) >> 8;
-    solidfill.blue = 0xff & sf.color;
-  } else {
-    solidfill.color_bit_depth = sf.solid_fill_info.bit_depth;
-    solidfill.alpha = sf.solid_fill_info.alpha;
-    solidfill.red = sf.solid_fill_info.red;
-    solidfill.green = sf.solid_fill_info.green;
-    solidfill.blue = sf.solid_fill_info.blue;
-  }
-  solid_fills_.push_back(solidfill);
-  DLOGI_IF(kTagDriverConfig, "Add a solidfill stage at z_order:%d argb_color:%x plane_alpha:%x",
-           solidfill.z_order, solidfill.color, solidfill.plane_alpha);
-}
-
-void HWDeviceDRM::SetSolidfillStages() {
-  if (hw_resource_.num_solidfill_stages) {
-    drm_atomic_intf_->Perform(DRMOps::CRTC_SET_SOLIDFILL_STAGES, token_.crtc_id,
-                              reinterpret_cast<uint64_t> (&solid_fills_));
-  }
-}
-
-DisplayError HWDeviceDRM::Validate(HWLayers *hw_layers) {
-  DTRACE_SCOPED();
-
-  DisplayError err = kErrorNone;
-  registry_.Register(hw_layers);
-  SetupAtomic(hw_layers, true /* validate */);
-
-  int ret = drm_atomic_intf_->Validate();
-  if (ret) {
-    DLOGE("failed with error %d for %s", ret, device_name_);
-    vrefresh_ = 0;
-    err = kErrorHardware;
-  }
-
-  registry_.Unregister();
-  return err;
-}
-
-DisplayError HWDeviceDRM::Commit(HWLayers *hw_layers) {
-  DTRACE_SCOPED();
-
-  DisplayError err = kErrorNone;
-  registry_.Register(hw_layers);
-
-  if (default_mode_) {
-    err = DefaultCommit(hw_layers);
-  } else {
-    err = AtomicCommit(hw_layers);
-  }
-
-  registry_.Next();
-  registry_.Unregister();
-
-  return err;
-}
-
-DisplayError HWDeviceDRM::DefaultCommit(HWLayers *hw_layers) {
-  DTRACE_SCOPED();
-
-  HWLayersInfo &hw_layer_info = hw_layers->info;
-  LayerStack *stack = hw_layer_info.stack;
-
-  stack->retire_fence_fd = -1;
-  for (Layer &layer : hw_layer_info.hw_layers) {
-    layer.input_buffer.release_fence_fd = -1;
-  }
-
-  DRMMaster *master = nullptr;
-  int ret = DRMMaster::GetInstance(&master);
-  if (ret < 0) {
-    DLOGE("Failed to acquire DRMMaster instance");
-    return kErrorResources;
-  }
-
-  DRMResMgr *res_mgr = nullptr;
-  ret = DRMResMgr::GetInstance(&res_mgr);
-  if (ret < 0) {
-    DLOGE("Failed to acquire DRMResMgr instance");
-    return kErrorResources;
-  }
-
-  int dev_fd = -1;
-  master->GetHandle(&dev_fd);
-
-  uint32_t connector_id = 0;
-  res_mgr->GetConnectorId(&connector_id);
-
-  uint32_t crtc_id = 0;
-  res_mgr->GetCrtcId(&crtc_id);
-
-  drmModeModeInfo mode;
-  res_mgr->GetMode(&mode);
-
-  uint32_t fb_id = registry_.GetFbId(hw_layer_info.hw_layers.at(0).input_buffer.planes[0].fd);
-  ret = drmModeSetCrtc(dev_fd, crtc_id, fb_id, 0 /* x */, 0 /* y */, &connector_id,
-                       1 /* num_connectors */, &mode);
-  if (ret < 0) {
-    DLOGE("drmModeSetCrtc failed dev fd %d, fb_id %d, crtc id %d, connector id %d, %s", dev_fd,
-          fb_id, crtc_id, connector_id, strerror(errno));
-    return kErrorHardware;
-  }
-
-  return kErrorNone;
-}
-
-DisplayError HWDeviceDRM::AtomicCommit(HWLayers *hw_layers) {
-  DTRACE_SCOPED();
-  SetupAtomic(hw_layers, false /* validate */);
-
-  int ret = drm_atomic_intf_->Commit(false /* synchronous */, false /* retain_planes*/);
-  if (ret) {
-    DLOGE("%s failed with error %d crtc %d", __FUNCTION__, ret, token_.crtc_id);
-    vrefresh_ = 0;
-    return kErrorHardware;
-  }
-
-  int release_fence = -1;
-  int retire_fence = -1;
-
-  drm_atomic_intf_->Perform(DRMOps::CRTC_GET_RELEASE_FENCE, token_.crtc_id, &release_fence);
-  drm_atomic_intf_->Perform(DRMOps::CONNECTOR_GET_RETIRE_FENCE, token_.conn_id, &retire_fence);
-
-  HWLayersInfo &hw_layer_info = hw_layers->info;
-  LayerStack *stack = hw_layer_info.stack;
-  stack->retire_fence_fd = retire_fence;
-
-  for (uint32_t i = 0; i < hw_layer_info.hw_layers.size(); i++) {
-    Layer &layer = hw_layer_info.hw_layers.at(i);
-    HWRotatorSession *hw_rotator_session = &hw_layers->config[i].hw_rotator_session;
-    if (hw_rotator_session->mode == kRotatorOffline) {
-      hw_rotator_session->output_buffer.release_fence_fd = Sys::dup_(release_fence);
-    } else {
-      layer.input_buffer.release_fence_fd = Sys::dup_(release_fence);
-    }
-  }
-
-  hw_layer_info.sync_handle = release_fence;
-
-  if (vrefresh_) {
-    // Update current mode index if refresh rate is changed
-    drmModeModeInfo current_mode = connector_info_.modes[current_mode_index_].mode;
-    for (uint32_t mode_index = 0; mode_index < connector_info_.modes.size(); mode_index++) {
-      if ((current_mode.vdisplay == connector_info_.modes[mode_index].mode.vdisplay) &&
-          (current_mode.hdisplay == connector_info_.modes[mode_index].mode.hdisplay) &&
-          (vrefresh_ == connector_info_.modes[mode_index].mode.vrefresh)) {
-        current_mode_index_ = mode_index;
-        break;
-      }
-    }
-    vrefresh_ = 0;
-  }
-
-  first_cycle_ = false;
-
-  return kErrorNone;
-}
-
-DisplayError HWDeviceDRM::Flush() {
-  DTRACE_SCOPED();
-  int ret = drm_atomic_intf_->Commit(false /* synchronous */, false /* retain_planes*/);
-  if (ret) {
-    DLOGE("failed with error %d", ret);
-    return kErrorHardware;
-  }
-
-  return kErrorNone;
-}
-
-void HWDeviceDRM::SetBlending(const LayerBlending &source, DRMBlendType *target) {
-  switch (source) {
-    case kBlendingPremultiplied:
-      *target = DRMBlendType::PREMULTIPLIED;
-      break;
-    case kBlendingOpaque:
-      *target = DRMBlendType::OPAQUE;
-      break;
-    case kBlendingCoverage:
-      *target = DRMBlendType::COVERAGE;
-      break;
-    default:
-      *target = DRMBlendType::UNDEFINED;
-  }
-}
-
-void HWDeviceDRM::SetSrcConfig(const LayerBuffer &input_buffer, const HWRotatorMode &mode,
-                               uint32_t *config) {
-  // In offline rotation case, rotator will handle deinterlacing.
-  if (mode != kRotatorOffline) {
-    if (input_buffer.flags.interlace) {
-      *config |= (0x01 << UINT32(DRMSrcConfig::DEINTERLACE));
-    }
-  }
-}
-
-void HWDeviceDRM::SelectCscType(const LayerBuffer &input_buffer, DRMCscType *type) {
-  if (type == NULL) {
-    return;
-  }
-
-  *type = DRMCscType::kCscTypeMax;
-  if (input_buffer.format < kFormatYCbCr420Planar) {
-    return;
-  }
-
-  switch (input_buffer.color_metadata.colorPrimaries) {
-    case ColorPrimaries_BT601_6_525:
-    case ColorPrimaries_BT601_6_625:
-      *type = ((input_buffer.color_metadata.range == Range_Full) ?
-               DRMCscType::kCscYuv2Rgb601FR : DRMCscType::kCscYuv2Rgb601L);
-      break;
-    case ColorPrimaries_BT709_5:
-      *type = DRMCscType::kCscYuv2Rgb709L;
-      break;
-    case ColorPrimaries_BT2020:
-      *type = ((input_buffer.color_metadata.range == Range_Full) ?
-                DRMCscType::kCscYuv2Rgb2020FR : DRMCscType::kCscYuv2Rgb2020L);
-      break;
-    default:
-      break;
-  }
-}
-
-void HWDeviceDRM::SetRect(const LayerRect &source, DRMRect *target) {
-  target->left = UINT32(source.left);
-  target->top = UINT32(source.top);
-  target->right = UINT32(source.right);
-  target->bottom = UINT32(source.bottom);
-}
-
-void HWDeviceDRM::SetRotation(LayerTransform transform, const HWRotatorMode &mode,
-                              uint32_t* rot_bit_mask) {
-  // In offline rotation case, rotator will handle flips set via offline rotator interface.
-  if (mode == kRotatorOffline) {
-    *rot_bit_mask = 0;
-    return;
-  }
-
-  // In no rotation case or inline rotation case, plane will handle flips
-  // In DRM framework rotation is applied in counter-clockwise direction.
-  if (mode == kRotatorInline && transform.rotation == 90) {
-    // a) rotate 90 clockwise = rotate 270 counter-clockwise in DRM
-    // rotate 270 is translated as hflip + vflip + rotate90
-    // b) rotate 270 clockwise = rotate 90 counter-clockwise in DRM
-    // c) hflip + rotate 90 clockwise = vflip + rotate 90 counter-clockwise in DRM
-    // d) vflip + rotate 90 clockwise = hflip + rotate 90 counter-clockwise in DRM
-    *rot_bit_mask = UINT32(DRMRotation::ROT_90);
-    transform.flip_horizontal = !transform.flip_horizontal;
-    transform.flip_vertical = !transform.flip_vertical;
-  }
-
-  if (transform.flip_horizontal) {
-    *rot_bit_mask |= UINT32(DRMRotation::FLIP_H);
-  }
-
-  if (transform.flip_vertical) {
-    *rot_bit_mask |= UINT32(DRMRotation::FLIP_V);
-  }
-}
-
-bool HWDeviceDRM::EnableHotPlugDetection(int enable) {
-  return true;
-}
-
-DisplayError HWDeviceDRM::SetCursorPosition(HWLayers *hw_layers, int x, int y) {
-  DTRACE_SCOPED();
-  return kErrorNone;
-}
-
-DisplayError HWDeviceDRM::GetPPFeaturesVersion(PPFeatureVersion *vers) {
-  struct DRMPPFeatureInfo info = {};
-  for (uint32_t i = 0; i < kMaxNumPPFeatures; i++) {
-    memset(&info, 0, sizeof(struct DRMPPFeatureInfo));
-    info.id = HWColorManagerDrm::ToDrmFeatureId(i);
-    if (info.id >= sde_drm::kPPFeaturesMax)
-      continue;
-    // use crtc_id_ = 0 since PP features are same across all CRTCs
-    drm_mgr_intf_->GetCrtcPPInfo(0, &info);
-    vers->version[i] = HWColorManagerDrm::GetFeatureVersion(info);
-  }
-  return kErrorNone;
-}
-
-DisplayError HWDeviceDRM::SetPPFeatures(PPFeaturesConfig *feature_list) {
-  int ret = 0;
-  PPFeatureInfo *feature = NULL;
-  DRMPPFeatureInfo kernel_params = {};
-  bool crtc_feature = true;
-
-  while (true) {
-    crtc_feature = true;
-    ret = feature_list->RetrieveNextFeature(&feature);
-    if (ret)
-      break;
-    kernel_params.id = HWColorManagerDrm::ToDrmFeatureId(feature->feature_id_);
-    drm_mgr_intf_->GetCrtcPPInfo(0, &kernel_params);
-    if (kernel_params.version == std::numeric_limits<uint32_t>::max())
-        crtc_feature = false;
-    if (feature) {
-      DLOGV_IF(kTagDriverConfig, "feature_id = %d", feature->feature_id_);
-      auto drm_features = DrmPPfeatureMap_.find(feature->feature_id_);
-      if (drm_features == DrmPPfeatureMap_.end()) {
-        DLOGE("DrmFeatures not valid for feature %d", feature->feature_id_);
-        continue;
-      }
-
-      for (uint32_t drm_feature : drm_features->second) {
-        if (!HWColorManagerDrm::GetDrmFeature[drm_feature]) {
-          DLOGE("GetDrmFeature is not valid for DRM feature %d", drm_feature);
-          continue;
-        }
-        ret = HWColorManagerDrm::GetDrmFeature[drm_feature](*feature, &kernel_params);
-      if (!ret && crtc_feature)
-        drm_atomic_intf_->Perform(DRMOps::CRTC_SET_POST_PROC, token_.crtc_id, &kernel_params);
-      else if (!ret && !crtc_feature)
-        drm_atomic_intf_->Perform(DRMOps::CONNECTOR_SET_POST_PROC, token_.conn_id, &kernel_params);
-      HWColorManagerDrm::FreeDrmFeatureData(&kernel_params);
-      }
-    }
-  }
-
-  // Once all features were consumed, then destroy all feature instance from feature_list,
-  feature_list->Reset();
-
-  return kErrorNone;
-}
-
-DisplayError HWDeviceDRM::SetVSyncState(bool enable) {
-  return kErrorNotSupported;
-}
-
-void HWDeviceDRM::SetIdleTimeoutMs(uint32_t timeout_ms) {
-  // TODO(user): This function can be removed after fb is deprecated
-}
-
-DisplayError HWDeviceDRM::SetDisplayMode(const HWDisplayMode hw_display_mode) {
-  return kErrorNotSupported;
-}
-
-DisplayError HWDeviceDRM::SetRefreshRate(uint32_t refresh_rate) {
-  // Check if requested refresh rate is valid
-  drmModeModeInfo current_mode = connector_info_.modes[current_mode_index_].mode;
-  for (uint32_t mode_index = 0; mode_index < connector_info_.modes.size(); mode_index++) {
-    if ((current_mode.vdisplay == connector_info_.modes[mode_index].mode.vdisplay) &&
-        (current_mode.hdisplay == connector_info_.modes[mode_index].mode.hdisplay) &&
-        (refresh_rate == connector_info_.modes[mode_index].mode.vrefresh)) {
-      vrefresh_ = refresh_rate;
-      DLOGV_IF(kTagDriverConfig, "Set refresh rate to %d", refresh_rate);
-      return kErrorNone;
-    }
-  }
-  return kErrorNotSupported;
-}
-
-DisplayError HWDeviceDRM::SetPanelBrightness(int level) {
-  DisplayError err = kErrorNone;
-  char buffer[kMaxSysfsCommandLength] = {0};
-
-  DLOGV_IF(kTagDriverConfig, "Set brightness level to %d", level);
-  int fd = Sys::open_(kBrightnessNode, O_RDWR);
-  if (fd < 0) {
-    DLOGV_IF(kTagDriverConfig, "Failed to open node = %s, error = %s ", kBrightnessNode,
-             strerror(errno));
-    return kErrorFileDescriptor;
-  }
-
-  int32_t bytes = snprintf(buffer, kMaxSysfsCommandLength, "%d\n", level);
-  ssize_t ret = Sys::pwrite_(fd, buffer, static_cast<size_t>(bytes), 0);
-  if (ret <= 0) {
-    DLOGV_IF(kTagDriverConfig, "Failed to write to node = %s, error = %s ", kBrightnessNode,
-             strerror(errno));
-    err = kErrorHardware;
-  }
-
-  Sys::close_(fd);
-
-  return err;
-}
-
-DisplayError HWDeviceDRM::GetPanelBrightness(int *level) {
-  DisplayError err = kErrorNone;
-  char brightness[kMaxStringLength] = {0};
-
-  if (!level) {
-    DLOGV_IF(kTagDriverConfig, "Invalid input, null pointer.");
-    return kErrorParameters;
-  }
-
-  int fd = Sys::open_(kBrightnessNode, O_RDWR);
-  if (fd < 0) {
-    DLOGV_IF(kTagDriverConfig, "Failed to open brightness node = %s, error = %s", kBrightnessNode,
-             strerror(errno));
-    return kErrorFileDescriptor;
-  }
-
-  if (Sys::pread_(fd, brightness, sizeof(brightness), 0) > 0) {
-    *level = atoi(brightness);
-    DLOGV_IF(kTagDriverConfig, "Brightness level = %d", *level);
-  } else {
-    DLOGV_IF(kTagDriverConfig, "Failed to read panel brightness");
-    err = kErrorHardware;
-  }
-
-  Sys::close_(fd);
-
-  return err;
-}
-
-DisplayError HWDeviceDRM::GetHWScanInfo(HWScanInfo *scan_info) {
-  return kErrorNotSupported;
-}
-
-DisplayError HWDeviceDRM::GetVideoFormat(uint32_t config_index, uint32_t *video_format) {
-  return kErrorNotSupported;
-}
-
-DisplayError HWDeviceDRM::GetMaxCEAFormat(uint32_t *max_cea_format) {
-  return kErrorNotSupported;
-}
-
-DisplayError HWDeviceDRM::OnMinHdcpEncryptionLevelChange(uint32_t min_enc_level) {
-  return kErrorNotSupported;
-}
-
-DisplayError HWDeviceDRM::SetS3DMode(HWS3DMode s3d_mode) {
-  return kErrorNotSupported;
-}
-
-DisplayError HWDeviceDRM::SetScaleLutConfig(HWScaleLutInfo *lut_info) {
-  sde_drm::DRMScalerLUTInfo drm_lut_info = {};
-  drm_lut_info.cir_lut = lut_info->cir_lut;
-  drm_lut_info.dir_lut = lut_info->dir_lut;
-  drm_lut_info.sep_lut = lut_info->sep_lut;
-  drm_lut_info.cir_lut_size = lut_info->cir_lut_size;
-  drm_lut_info.dir_lut_size = lut_info->dir_lut_size;
-  drm_lut_info.sep_lut_size = lut_info->sep_lut_size;
-  drm_mgr_intf_->SetScalerLUT(drm_lut_info);
-
-  return kErrorNone;
-}
-
-DisplayError HWDeviceDRM::SetMixerAttributes(const HWMixerAttributes &mixer_attributes) {
-  if (IsResolutionSwitchEnabled()) {
-    return kErrorNotSupported;
-  }
-
-  if (!hw_resource_.hw_dest_scalar_info.count) {
-    return kErrorNotSupported;
-  }
-
-  uint32_t index = current_mode_index_;
-
-  if (mixer_attributes.width > display_attributes_[index].x_pixels ||
-      mixer_attributes.height > display_attributes_[index].y_pixels) {
-    DLOGW("Input resolution exceeds display resolution! input: res %dx%d display: res %dx%d",
-          mixer_attributes.width, mixer_attributes.height, display_attributes_[index].x_pixels,
-          display_attributes_[index].y_pixels);
-    return kErrorNotSupported;
-  }
-
-  uint32_t max_input_width = hw_resource_.hw_dest_scalar_info.max_input_width;
-  if (display_attributes_[index].is_device_split) {
-    max_input_width *= 2;
-  }
-
-  if (mixer_attributes.width > max_input_width) {
-    DLOGW("Input width exceeds width limit! input_width %d width_limit %d", mixer_attributes.width,
-          max_input_width);
-    return kErrorNotSupported;
-  }
-
-  float mixer_aspect_ratio = FLOAT(mixer_attributes.width) / FLOAT(mixer_attributes.height);
-  float display_aspect_ratio =
-      FLOAT(display_attributes_[index].x_pixels) / FLOAT(display_attributes_[index].y_pixels);
-
-  if (display_aspect_ratio != mixer_aspect_ratio) {
-    DLOGW("Aspect ratio mismatch! input: res %dx%d display: res %dx%d", mixer_attributes.width,
-          mixer_attributes.height, display_attributes_[index].x_pixels,
-          display_attributes_[index].y_pixels);
-    return kErrorNotSupported;
-  }
-
-  float scale_x = FLOAT(display_attributes_[index].x_pixels) / FLOAT(mixer_attributes.width);
-  float scale_y = FLOAT(display_attributes_[index].y_pixels) / FLOAT(mixer_attributes.height);
-  float max_scale_up = hw_resource_.hw_dest_scalar_info.max_scale_up;
-  if (scale_x > max_scale_up || scale_y > max_scale_up) {
-    DLOGW(
-        "Up scaling ratio exceeds for destination scalar upscale limit scale_x %f scale_y %f "
-        "max_scale_up %f",
-        scale_x, scale_y, max_scale_up);
-    return kErrorNotSupported;
-  }
-
-  float mixer_split_ratio = FLOAT(mixer_attributes_.split_left) / FLOAT(mixer_attributes_.width);
-
-  mixer_attributes_ = mixer_attributes;
-  mixer_attributes_.split_left = mixer_attributes_.width;
-  if (display_attributes_[index].is_device_split) {
-    mixer_attributes_.split_left = UINT32(FLOAT(mixer_attributes.width) * mixer_split_ratio);
-  }
-
-  return kErrorNone;
-}
-
-DisplayError HWDeviceDRM::GetMixerAttributes(HWMixerAttributes *mixer_attributes) {
-  if (!mixer_attributes) {
-    return kErrorParameters;
-  }
-
-  *mixer_attributes = mixer_attributes_;
-
-  return kErrorNone;
-}
-
-void HWDeviceDRM::GetDRMDisplayToken(sde_drm::DRMDisplayToken *token) const {
-  *token = token_;
-}
-
-void HWDeviceDRM::UpdateMixerAttributes() {
-  uint32_t index = current_mode_index_;
-
-  mixer_attributes_.width = display_attributes_[index].x_pixels;
-  mixer_attributes_.height = display_attributes_[index].y_pixels;
-  mixer_attributes_.split_left = display_attributes_[index].is_device_split
-                                     ? hw_panel_info_.split_info.left_split
-                                     : mixer_attributes_.width;
-  DLOGI("Mixer WxH %dx%d for %s", mixer_attributes_.width, mixer_attributes_.height, device_name_);
-}
-
-void HWDeviceDRM::SetSecureConfig(const LayerBuffer &input_buffer, DRMSecureMode *fb_secure_mode,
-                                  DRMSecurityLevel *security_level) {
-  *fb_secure_mode = DRMSecureMode::NON_SECURE;
-  *security_level = DRMSecurityLevel::SECURE_NON_SECURE;
-
-  if (input_buffer.flags.secure) {
-    if (input_buffer.flags.secure_camera) {
-      // IOMMU configuration for this framebuffer mode is secure domain & requires
-      // only stage II translation, when this buffer is accessed by Display H/W.
-      // Secure and non-secure planes can be attached to this CRTC.
-      *fb_secure_mode = DRMSecureMode::SECURE_DIR_TRANSLATION;
-    } else if (input_buffer.flags.secure_display) {
-      // IOMMU configuration for this framebuffer mode is secure domain & requires
-      // only stage II translation, when this buffer is accessed by Display H/W.
-      // Only secure planes can be attached to this CRTC.
-      *fb_secure_mode = DRMSecureMode::SECURE_DIR_TRANSLATION;
-      *security_level = DRMSecurityLevel::SECURE_ONLY;
-    } else {
-      // IOMMU configuration for this framebuffer mode is secure domain & requires both
-      // stage I and stage II translations, when this buffer is accessed by Display H/W.
-      // Secure and non-secure planes can be attached to this CRTC.
-      *fb_secure_mode = DRMSecureMode::SECURE;
-    }
-  }
-}
-
-void HWDeviceDRM::SetTopology(sde_drm::DRMTopology drm_topology, HWTopology *hw_topology) {
-  switch (drm_topology) {
-    case DRMTopology::SINGLE_LM:          *hw_topology = kSingleLM;        break;
-    case DRMTopology::SINGLE_LM_DSC:      *hw_topology = kSingleLMDSC;     break;
-    case DRMTopology::DUAL_LM:            *hw_topology = kDualLM;          break;
-    case DRMTopology::DUAL_LM_DSC:        *hw_topology = kDualLMDSC;       break;
-    case DRMTopology::DUAL_LM_MERGE:      *hw_topology = kDualLMMerge;     break;
-    case DRMTopology::DUAL_LM_MERGE_DSC:  *hw_topology = kDualLMMergeDSC;  break;
-    case DRMTopology::DUAL_LM_DSCMERGE:   *hw_topology = kDualLMDSCMerge;  break;
-    case DRMTopology::PPSPLIT:            *hw_topology = kPPSplit;         break;
-    default:                              *hw_topology = kUnknown;         break;
-  }
-}
-
-void HWDeviceDRM::SetMultiRectMode(const uint32_t flags, DRMMultiRectMode *target) {
-  *target = DRMMultiRectMode::NONE;
-  if (flags & kMultiRect) {
-    *target = DRMMultiRectMode::SERIAL;
-    if (flags & kMultiRectParallelMode) {
-      *target = DRMMultiRectMode::PARALLEL;
-    }
-  }
-}
-
-void HWDeviceDRM::SetFullROI() {
-  // Reset the CRTC ROI and connector ROI only for the panel that supports partial update
-  if (!hw_panel_info_.partial_update) {
-    return;
-  }
-  uint32_t index = current_mode_index_;
-  DRMRect crtc_rects = {0, 0, mixer_attributes_.width, mixer_attributes_.height};
-  DRMRect conn_rects = {0, 0, display_attributes_[index].x_pixels,
-                         display_attributes_[index].y_pixels};
-  drm_atomic_intf_->Perform(DRMOps::CRTC_SET_ROI, token_.crtc_id, 1, &crtc_rects);
-  drm_atomic_intf_->Perform(DRMOps::CONNECTOR_SET_ROI, token_.conn_id, 1, &conn_rects);
-}
-
-}  // namespace sdm
diff --git a/sdm/libs/core/drm/hw_device_drm.h b/sdm/libs/core/drm/hw_device_drm.h
deleted file mode 100644
index d2fa276..0000000
--- a/sdm/libs/core/drm/hw_device_drm.h
+++ /dev/null
@@ -1,195 +0,0 @@
-/*
-* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without
-* modification, are permitted provided that the following conditions are
-* met:
-*     * Redistributions of source code must retain the above copyright
-*       notice, this list of conditions and the following disclaimer.
-*     * Redistributions in binary form must reproduce the above
-*       copyright notice, this list of conditions and the following
-*       disclaimer in the documentation and/or other materials provided
-*       with the distribution.
-*     * Neither the name of The Linux Foundation nor the names of its
-*       contributors may be used to endorse or promote products derived
-*       from this software without specific prior written permission.
-*
-* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
-* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
-* ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
-* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
-* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#ifndef __HW_DEVICE_DRM_H__
-#define __HW_DEVICE_DRM_H__
-
-#include <drm_interface.h>
-#include <errno.h>
-#include <pthread.h>
-#include <xf86drmMode.h>
-#include <string>
-#include <unordered_map>
-#include <vector>
-
-#include "hw_interface.h"
-#include "hw_scale_drm.h"
-
-#define IOCTL_LOGE(ioctl, type) \
-  DLOGE("ioctl %s, device = %d errno = %d, desc = %s", #ioctl, type, errno, strerror(errno))
-
-namespace sdm {
-class HWInfoInterface;
-
-class HWDeviceDRM : public HWInterface {
- public:
-  HWDeviceDRM(BufferSyncHandler *buffer_sync_handler, BufferAllocator *buffer_allocator,
-                       HWInfoInterface *hw_info_intf);
-  virtual ~HWDeviceDRM() {}
-  virtual DisplayError Init();
-  virtual DisplayError Deinit();
-  void GetDRMDisplayToken(sde_drm::DRMDisplayToken *token) const;
-  bool IsPrimaryDisplay() const { return hw_panel_info_.is_primary_panel; }
-
- protected:
-  // From HWInterface
-  virtual DisplayError GetActiveConfig(uint32_t *active_config);
-  virtual DisplayError GetNumDisplayAttributes(uint32_t *count);
-  virtual DisplayError GetDisplayAttributes(uint32_t index,
-                                            HWDisplayAttributes *display_attributes);
-  virtual DisplayError GetHWPanelInfo(HWPanelInfo *panel_info);
-  virtual DisplayError SetDisplayAttributes(uint32_t index);
-  virtual DisplayError SetDisplayAttributes(const HWDisplayAttributes &display_attributes);
-  virtual DisplayError GetConfigIndex(char *mode, uint32_t *index);
-  virtual DisplayError PowerOn(int *release_fence);
-  virtual DisplayError PowerOff();
-  virtual DisplayError Doze(int *release_fence);
-  virtual DisplayError DozeSuspend(int *release_fence);
-  virtual DisplayError Standby();
-  virtual DisplayError Validate(HWLayers *hw_layers);
-  virtual DisplayError Commit(HWLayers *hw_layers);
-  virtual DisplayError Flush();
-  virtual DisplayError GetPPFeaturesVersion(PPFeatureVersion *vers);
-  virtual DisplayError SetPPFeatures(PPFeaturesConfig *feature_list);
-  // This API is no longer supported, expectation is to call the correct API on HWEvents
-  virtual DisplayError SetVSyncState(bool enable);
-  virtual void SetIdleTimeoutMs(uint32_t timeout_ms);
-  virtual DisplayError SetDisplayMode(const HWDisplayMode hw_display_mode);
-  virtual DisplayError SetRefreshRate(uint32_t refresh_rate);
-  virtual DisplayError SetPanelBrightness(int level);
-  virtual DisplayError GetHWScanInfo(HWScanInfo *scan_info);
-  virtual DisplayError GetVideoFormat(uint32_t config_index, uint32_t *video_format);
-  virtual DisplayError GetMaxCEAFormat(uint32_t *max_cea_format);
-  virtual DisplayError SetCursorPosition(HWLayers *hw_layers, int x, int y);
-  virtual DisplayError OnMinHdcpEncryptionLevelChange(uint32_t min_enc_level);
-  virtual DisplayError GetPanelBrightness(int *level);
-  virtual DisplayError SetAutoRefresh(bool enable) { autorefresh_ = enable; return kErrorNone; }
-  virtual DisplayError SetS3DMode(HWS3DMode s3d_mode);
-  virtual DisplayError SetScaleLutConfig(HWScaleLutInfo *lut_info);
-  virtual DisplayError SetMixerAttributes(const HWMixerAttributes &mixer_attributes);
-  virtual DisplayError GetMixerAttributes(HWMixerAttributes *mixer_attributes);
-  virtual void InitializeConfigs();
-  virtual DisplayError DumpDebugData() { return kErrorNone; }
-  virtual void PopulateHWPanelInfo();
-
-  enum {
-    kHWEventVSync,
-    kHWEventBlank,
-  };
-
-  static const int kMaxStringLength = 1024;
-  static const int kNumPhysicalDisplays = 2;
-  static const int kMaxSysfsCommandLength = 12;
-  static constexpr const char *kBrightnessNode =
-    "/sys/class/backlight/panel0-backlight/brightness";
-
-  DisplayError SetFormat(const LayerBufferFormat &source, uint32_t *target);
-  DisplayError SetStride(HWDeviceType device_type, LayerBufferFormat format, uint32_t width,
-                         uint32_t *target);
-  DisplayError PopulateDisplayAttributes(uint32_t index);
-  void GetHWDisplayPortAndMode();
-  void GetHWPanelMaxBrightness();
-  bool EnableHotPlugDetection(int enable);
-  void UpdateMixerAttributes();
-  void SetSolidfillStages();
-  void AddSolidfillStage(const HWSolidfillStage &sf, uint32_t plane_alpha);
-  void SetBlending(const LayerBlending &source, sde_drm::DRMBlendType *target);
-  void SetSrcConfig(const LayerBuffer &input_buffer, const HWRotatorMode &mode, uint32_t *config);
-  void SelectCscType(const LayerBuffer &input_buffer, sde_drm::DRMCscType *type);
-  void SetRect(const LayerRect &source, sde_drm::DRMRect *target);
-  void SetRotation(LayerTransform transform, const HWRotatorMode &mode, uint32_t* rot_bit_mask);
-  DisplayError DefaultCommit(HWLayers *hw_layers);
-  DisplayError AtomicCommit(HWLayers *hw_layers);
-  void SetupAtomic(HWLayers *hw_layers, bool validate);
-  void SetSecureConfig(const LayerBuffer &input_buffer, sde_drm::DRMSecureMode *fb_secure_mode,
-                       sde_drm::DRMSecurityLevel *security_level);
-  bool IsResolutionSwitchEnabled() const { return resolution_switch_enabled_; }
-  void SetTopology(sde_drm::DRMTopology drm_topology, HWTopology *hw_topology);
-  void SetMultiRectMode(const uint32_t flags, sde_drm::DRMMultiRectMode *target);
-  void SetFullROI();
-
-  class Registry {
-   public:
-    explicit Registry(BufferAllocator *buffer_allocator);
-    ~Registry();
-    // Called on each Validate and Commit to register layer buffers fds to the slot pointed to by
-    // current_index_
-    void Register(HWLayers *hw_layers);
-    // Clears the slot pointed to by current_index_
-    void Unregister();
-    // Moves current_index_ to the next position
-    void Next();
-    // Called on display disconnect to release all gem handles and fb_ids
-    void Clear();
-    // Maps given fd to FB ID
-    void MapBufferToFbId(LayerBuffer* buffer);
-    // Finds an fb_id corresponding to an fd in current map
-    uint32_t GetFbId(int fd);
-
-   private:
-    uint8_t rmfb_delay_ = 1;  // N cycle delay before destroy
-    // fd to fb_id map. fd is used as key only for a single draw cycle between
-    // prepare and commit. It should not be used for caching in future due to fd recycling
-    std::unordered_map<int, uint32_t> *hashmap_ {};
-    int current_index_ = 0;
-    BufferAllocator *buffer_allocator_ = {};
-  };
-
- protected:
-  const char *device_name_ = {};
-  bool default_mode_ = false;
-  sde_drm::DRMDisplayType disp_type_ = {};
-  HWInfoInterface *hw_info_intf_ = {};
-  BufferSyncHandler *buffer_sync_handler_ = {};
-  int dev_fd_ = -1;
-  Registry registry_;
-  sde_drm::DRMDisplayToken token_ = {};
-  HWResourceInfo hw_resource_ = {};
-  HWPanelInfo hw_panel_info_ = {};
-  HWScaleDRM *hw_scale_ = {};
-  sde_drm::DRMManagerInterface *drm_mgr_intf_ = {};
-  sde_drm::DRMAtomicReqInterface *drm_atomic_intf_ = {};
-  std::vector<HWDisplayAttributes> display_attributes_ = {};
-  uint32_t current_mode_index_ = 0;
-  sde_drm::DRMConnectorInfo connector_info_ = {};
-  bool first_cycle_ = true;
-
- private:
-  bool synchronous_commit_ = false;
-  HWMixerAttributes mixer_attributes_ = {};
-  std::string interface_str_ = "DSI";
-  std::vector<sde_drm::DRMSolidfillStage> solid_fills_ {};
-  bool resolution_switch_enabled_ = false;
-  uint32_t vrefresh_ = 0;
-  bool autorefresh_ = false;
-};
-
-}  // namespace sdm
-
-#endif  // __HW_DEVICE_DRM_H__
diff --git a/sdm/libs/core/drm/hw_events_drm.cpp b/sdm/libs/core/drm/hw_events_drm.cpp
deleted file mode 100644
index 4d1eea9..0000000
--- a/sdm/libs/core/drm/hw_events_drm.cpp
+++ /dev/null
@@ -1,616 +0,0 @@
-/*
-* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without
-* modification, are permitted provided that the following conditions are
-* met:
-*     * Redistributions of source code must retain the above copyright
-*       notice, this list of conditions and the following disclaimer.
-*     * Redistributions in binary form must reproduce the above
-*       copyright notice, this list of conditions and the following
-*       disclaimer in the documentation and/or other materials provided
-*       with the distribution.
-*     * Neither the name of The Linux Foundation nor the names of its
-*       contributors may be used to endorse or promote products derived
-*       from this software without specific prior written permission.
-*
-* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
-* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
-* ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
-* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
-* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#include <drm_master.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <math.h>
-#include <pthread.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/prctl.h>
-#include <sys/resource.h>
-#include <sys/types.h>
-#include <utils/debug.h>
-#include <utils/sys.h>
-#include <xf86drm.h>
-#include <drm/msm_drm.h>
-
-#include <algorithm>
-#include <map>
-#include <utility>
-#include <vector>
-
-#include "hw_events_drm.h"
-
-#define __CLASS__ "HWEventsDRM"
-
-namespace sdm {
-
-using drm_utils::DRMMaster;
-
-DisplayError HWEventsDRM::InitializePollFd() {
-  for (uint32_t i = 0; i < event_data_list_.size(); i++) {
-    char data[kMaxStringLength]{};
-    HWEventData &event_data = event_data_list_[i];
-    poll_fds_[i] = {};
-    poll_fds_[i].fd = -1;
-
-    switch (event_data.event_type) {
-      case HWEvent::VSYNC: {
-        poll_fds_[i].events = POLLIN | POLLPRI | POLLERR;
-        if (is_primary_) {
-          DRMMaster *master = nullptr;
-          int ret = DRMMaster::GetInstance(&master);
-          if (ret < 0) {
-            DLOGE("Failed to acquire DRMMaster instance");
-            return kErrorNotSupported;
-          }
-          master->GetHandle(&poll_fds_[i].fd);
-        } else {
-          poll_fds_[i].fd = drmOpen("msm_drm", nullptr);
-        }
-        vsync_index_ = i;
-      } break;
-      case HWEvent::EXIT: {
-        // Create an eventfd to be used to unblock the poll system call when
-        // a thread is exiting.
-        poll_fds_[i].fd = Sys::eventfd_(0, 0);
-        poll_fds_[i].events |= POLLIN;
-        // Clear any existing data
-        Sys::pread_(poll_fds_[i].fd, data, kMaxStringLength, 0);
-      } break;
-      case HWEvent::IDLE_NOTIFY: {
-        poll_fds_[i].fd = drmOpen("msm_drm", nullptr);
-        if (poll_fds_[i].fd < 0) {
-          DLOGE("drmOpen failed with error %d", poll_fds_[i].fd);
-          return kErrorResources;
-        }
-        poll_fds_[i].events = POLLIN | POLLPRI | POLLERR;
-        idle_notify_index_ = i;
-      } break;
-      case HWEvent::IDLE_POWER_COLLAPSE: {
-        poll_fds_[i].fd = drmOpen("msm_drm", nullptr);
-        if (poll_fds_[i].fd < 0) {
-          DLOGE("drmOpen failed with error %d", poll_fds_[i].fd);
-          return kErrorResources;
-        }
-        poll_fds_[i].events = POLLIN | POLLPRI | POLLERR;
-        idle_pc_index_ = i;
-      } break;
-      case HWEvent::PANEL_DEAD: {
-        poll_fds_[i].fd = drmOpen("msm_drm", nullptr);
-        if (poll_fds_[i].fd < 0) {
-          DLOGE("drmOpen failed with error %d", poll_fds_[i].fd);
-          return kErrorResources;
-        }
-        poll_fds_[i].events = POLLIN | POLLPRI | POLLERR;
-        panel_dead_index_ = i;
-      } break;
-      case HWEvent::CEC_READ_MESSAGE:
-      case HWEvent::SHOW_BLANK_EVENT:
-      case HWEvent::THERMAL_LEVEL:
-      case HWEvent::PINGPONG_TIMEOUT:
-        break;
-    }
-  }
-
-  return kErrorNone;
-}
-
-DisplayError HWEventsDRM::SetEventParser() {
-  DisplayError error = kErrorNone;
-
-  for (auto &event_data : event_data_list_) {
-    switch (event_data.event_type) {
-      case HWEvent::VSYNC:
-        event_data.event_parser = &HWEventsDRM::HandleVSync;
-        break;
-      case HWEvent::IDLE_NOTIFY:
-        event_data.event_parser = &HWEventsDRM::HandleIdleTimeout;
-        break;
-      case HWEvent::CEC_READ_MESSAGE:
-        event_data.event_parser = &HWEventsDRM::HandleCECMessage;
-        break;
-      case HWEvent::EXIT:
-        event_data.event_parser = &HWEventsDRM::HandleThreadExit;
-        break;
-      case HWEvent::SHOW_BLANK_EVENT:
-        event_data.event_parser = &HWEventsDRM::HandleBlank;
-        break;
-      case HWEvent::THERMAL_LEVEL:
-        event_data.event_parser = &HWEventsDRM::HandleThermal;
-        break;
-      case HWEvent::IDLE_POWER_COLLAPSE:
-        event_data.event_parser = &HWEventsDRM::HandleIdlePowerCollapse;
-        break;
-      case HWEvent::PANEL_DEAD:
-        event_data.event_parser = &HWEventsDRM::HandlePanelDead;
-        break;
-      default:
-        error = kErrorParameters;
-        break;
-    }
-  }
-
-  return error;
-}
-
-void HWEventsDRM::PopulateHWEventData(const vector<HWEvent> &event_list) {
-  for (auto &event : event_list) {
-    HWEventData event_data;
-    event_data.event_type = event;
-    event_data_list_.push_back(std::move(event_data));
-  }
-
-  SetEventParser();
-  InitializePollFd();
-}
-
-DisplayError HWEventsDRM::Init(int display_type, HWEventHandler *event_handler,
-                               const vector<HWEvent> &event_list,
-                               const HWInterface *hw_intf) {
-  if (!event_handler)
-    return kErrorParameters;
-
-  static_cast<const HWDeviceDRM *>(hw_intf)->GetDRMDisplayToken(&token_);
-  is_primary_ = static_cast<const HWDeviceDRM *>(hw_intf)->IsPrimaryDisplay();
-
-  DLOGI("Setup event handler for display %d, CRTC %d, Connector %d",
-        display_type, token_.crtc_id, token_.conn_id);
-
-  event_handler_ = event_handler;
-  poll_fds_.resize(event_list.size());
-  event_thread_name_ += " - " + std::to_string(display_type);
-
-  PopulateHWEventData(event_list);
-
-  if (pthread_create(&event_thread_, NULL, &DisplayEventThread, this) < 0) {
-    DLOGE("Failed to start %s, error = %s", event_thread_name_.c_str());
-    return kErrorResources;
-  }
-
-  RegisterVSync();
-  vsync_registered_ = true;
-  RegisterPanelDead(true);
-  RegisterIdleNotify(true);
-  RegisterIdlePowerCollapse(true);
-
-  return kErrorNone;
-}
-
-DisplayError HWEventsDRM::Deinit() {
-  exit_threads_ = true;
-  RegisterPanelDead(false);
-  RegisterIdleNotify(false);
-  RegisterIdlePowerCollapse(false);
-  Sys::pthread_cancel_(event_thread_);
-  WakeUpEventThread();
-  pthread_join(event_thread_, NULL);
-  CloseFds();
-
-  return kErrorNone;
-}
-
-DisplayError HWEventsDRM::SetEventState(HWEvent event, bool enable, void *arg) {
-  switch (event) {
-    case HWEvent::VSYNC: {
-      std::lock_guard<std::mutex> lock(vsync_mutex_);
-      vsync_enabled_ = enable;
-      if (vsync_enabled_ && !vsync_registered_) {
-        RegisterVSync();
-        vsync_registered_ = true;
-      }
-    } break;
-    default:
-      DLOGE("Event not supported");
-      return kErrorNotSupported;
-  }
-
-  return kErrorNone;
-}
-
-void HWEventsDRM::WakeUpEventThread() {
-  for (uint32_t i = 0; i < event_data_list_.size(); i++) {
-    if (event_data_list_[i].event_type == HWEvent::EXIT && poll_fds_[i].fd >= 0) {
-      uint64_t exit_value = 1;
-      ssize_t write_size = Sys::write_(poll_fds_[i].fd, &exit_value, sizeof(uint64_t));
-      if (write_size != sizeof(uint64_t)) {
-        DLOGW("Error triggering exit fd (%d). write size = %d, error = %s", poll_fds_[i].fd,
-              write_size, strerror(errno));
-      }
-      break;
-    }
-  }
-}
-
-DisplayError HWEventsDRM::CloseFds() {
-  for (uint32_t i = 0; i < event_data_list_.size(); i++) {
-    switch (event_data_list_[i].event_type) {
-      case HWEvent::VSYNC:
-        if (!is_primary_) {
-          Sys::close_(poll_fds_[i].fd);
-        }
-        poll_fds_[i].fd = -1;
-        break;
-      case HWEvent::EXIT:
-        Sys::close_(poll_fds_[i].fd);
-        poll_fds_[i].fd = -1;
-        break;
-      case HWEvent::IDLE_NOTIFY:
-      case HWEvent::IDLE_POWER_COLLAPSE:
-      case HWEvent::PANEL_DEAD:
-        drmClose(poll_fds_[i].fd);
-        poll_fds_[i].fd = -1;
-        break;
-      case HWEvent::CEC_READ_MESSAGE:
-      case HWEvent::SHOW_BLANK_EVENT:
-      case HWEvent::THERMAL_LEVEL:
-        break;
-      default:
-        return kErrorNotSupported;
-    }
-  }
-
-  return kErrorNone;
-}
-
-void *HWEventsDRM::DisplayEventThread(void *context) {
-  if (context) {
-    return reinterpret_cast<HWEventsDRM *>(context)->DisplayEventHandler();
-  }
-
-  return NULL;
-}
-
-void *HWEventsDRM::DisplayEventHandler() {
-  char data[kMaxStringLength]{};
-
-  prctl(PR_SET_NAME, event_thread_name_.c_str(), 0, 0, 0);
-  setpriority(PRIO_PROCESS, 0, kThreadPriorityUrgent);
-
-  while (!exit_threads_) {
-    int error = Sys::poll_(poll_fds_.data(), UINT32(poll_fds_.size()), -1);
-    if (error <= 0) {
-      DLOGW("poll failed. error = %s", strerror(errno));
-      continue;
-    }
-
-    for (uint32_t i = 0; i < event_data_list_.size(); i++) {
-      pollfd &poll_fd = poll_fds_[i];
-      if (poll_fd.fd < 0) {
-        continue;
-      }
-
-      switch (event_data_list_[i].event_type) {
-        case HWEvent::VSYNC:
-        case HWEvent::PANEL_DEAD:
-        case HWEvent::IDLE_NOTIFY:
-        case HWEvent::IDLE_POWER_COLLAPSE:
-          if (poll_fd.revents & (POLLIN | POLLPRI | POLLERR)) {
-            (this->*(event_data_list_[i]).event_parser)(nullptr);
-          }
-          break;
-        case HWEvent::EXIT:
-          if ((poll_fd.revents & POLLIN) &&
-              (Sys::read_(poll_fd.fd, data, kMaxStringLength) > 0)) {
-            (this->*(event_data_list_[i]).event_parser)(data);
-          }
-          break;
-        case HWEvent::CEC_READ_MESSAGE:
-        case HWEvent::SHOW_BLANK_EVENT:
-        case HWEvent::THERMAL_LEVEL:
-        case HWEvent::PINGPONG_TIMEOUT:
-          if ((poll_fd.revents & POLLPRI) &&
-              (Sys::pread_(poll_fd.fd, data, kMaxStringLength, 0) > 0)) {
-            (this->*(event_data_list_[i]).event_parser)(data);
-          }
-          break;
-      }
-    }
-  }
-
-  pthread_exit(0);
-
-  return nullptr;
-}
-
-DisplayError HWEventsDRM::RegisterVSync() {
-  drmVBlank vblank {};
-  uint32_t high_crtc = token_.crtc_index << DRM_VBLANK_HIGH_CRTC_SHIFT;
-  vblank.request.type = (drmVBlankSeqType)(DRM_VBLANK_RELATIVE | DRM_VBLANK_EVENT |
-                                           (high_crtc & DRM_VBLANK_HIGH_CRTC_MASK));
-  vblank.request.sequence = 1;
-  // DRM hack to pass in context to unused field signal. Driver will write this to the node being
-  // polled on, and will be read as part of drm event handling and sent to handler
-  vblank.request.signal = reinterpret_cast<unsigned long>(this);  // NOLINT
-  int error = drmWaitVBlank(poll_fds_[vsync_index_].fd, &vblank);
-  if (error < 0) {
-    DLOGE("drmWaitVBlank failed with err %d", errno);
-    return kErrorResources;
-  }
-
-  return kErrorNone;
-}
-
-DisplayError HWEventsDRM::RegisterPanelDead(bool enable) {
-  uint32_t i = 0;
-  for (; i < event_data_list_.size(); i++) {
-    if (event_data_list_[i].event_type == HWEvent::PANEL_DEAD) {
-      break;
-    }
-  }
-
-  if (i == event_data_list_.size()) {
-    DLOGI("panel dead is not supported event");
-    return kErrorNone;
-  }
-
-  struct drm_msm_event_req req = {};
-  int ret = 0;
-
-  req.object_id = token_.conn_id;
-  req.object_type = DRM_MODE_OBJECT_CONNECTOR;
-  req.event = DRM_EVENT_PANEL_DEAD;
-  if (enable) {
-    ret = drmIoctl(poll_fds_[panel_dead_index_].fd, DRM_IOCTL_MSM_REGISTER_EVENT, &req);
-  } else {
-    ret = drmIoctl(poll_fds_[panel_dead_index_].fd, DRM_IOCTL_MSM_DEREGISTER_EVENT, &req);
-  }
-
-  if (ret) {
-    DLOGE("register panel dead enable:%d failed", enable);
-    return kErrorResources;
-  }
-
-  return kErrorNone;
-}
-
-DisplayError HWEventsDRM::RegisterIdleNotify(bool enable) {
-  uint32_t i = 0;
-  for (; i < event_data_list_.size(); i++) {
-    if (event_data_list_[i].event_type == HWEvent::IDLE_NOTIFY) {
-      break;
-    }
-  }
-
-  if (i == event_data_list_.size()) {
-    DLOGI("idle notify is not supported event");
-    return kErrorNone;
-  }
-
-  struct drm_msm_event_req req = {};
-  int ret = 0;
-
-  req.object_id = token_.crtc_id;
-  req.object_type = DRM_MODE_OBJECT_CRTC;
-  req.event = DRM_EVENT_IDLE_NOTIFY;
-  if (enable) {
-    ret = drmIoctl(poll_fds_[idle_notify_index_].fd, DRM_IOCTL_MSM_REGISTER_EVENT, &req);
-  } else {
-    ret = drmIoctl(poll_fds_[idle_notify_index_].fd, DRM_IOCTL_MSM_DEREGISTER_EVENT, &req);
-  }
-
-  if (ret) {
-    DLOGE("register idle notify enable:%d failed", enable);
-    return kErrorResources;
-  }
-
-  return kErrorNone;
-}
-
-DisplayError HWEventsDRM::RegisterIdlePowerCollapse(bool enable) {
-  uint32_t i = 0;
-  for (; i < event_data_list_.size(); i++) {
-    if (event_data_list_[i].event_type == HWEvent::IDLE_POWER_COLLAPSE) {
-      break;
-    }
-  }
-
-  if (i == event_data_list_.size()) {
-    DLOGI("idle power collapse is not supported event");
-    return kErrorNone;
-  }
-
-  struct drm_msm_event_req req = {};
-  int ret = 0;
-
-  req.object_id = token_.crtc_id;
-  req.object_type = DRM_MODE_OBJECT_CRTC;
-  req.event = DRM_EVENT_SDE_POWER;
-  if (enable) {
-    ret = drmIoctl(poll_fds_[idle_pc_index_].fd, DRM_IOCTL_MSM_REGISTER_EVENT, &req);
-  } else {
-    ret = drmIoctl(poll_fds_[idle_pc_index_].fd, DRM_IOCTL_MSM_DEREGISTER_EVENT, &req);
-  }
-
-  if (ret) {
-    DLOGE("register idle power collapse enable:%d failed", enable);
-    return kErrorResources;
-  }
-
-  return kErrorNone;
-}
-
-void HWEventsDRM::HandleVSync(char *data) {
-  drmEventContext event = {};
-  event.version = DRM_EVENT_CONTEXT_VERSION;
-  event.vblank_handler = &HWEventsDRM::VSyncHandlerCallback;
-  int error = drmHandleEvent(poll_fds_[vsync_index_].fd, &event);
-  if (error != 0) {
-    DLOGE("drmHandleEvent failed: %i", error);
-  }
-
-  std::lock_guard<std::mutex> lock(vsync_mutex_);
-  vsync_registered_ = false;
-  if (vsync_enabled_) {
-    RegisterVSync();
-    vsync_registered_ = true;
-  }
-}
-
-void HWEventsDRM::HandlePanelDead(char *data) {
-  char event_data[kMaxStringLength] = {0};
-  int32_t size;
-  struct drm_msm_event_resp *event_resp = NULL;
-
-  size = (int32_t)Sys::pread_(poll_fds_[panel_dead_index_].fd, event_data, kMaxStringLength, 0);
-  if (size <= 0) {
-    return;
-  }
-
-  if (size > kMaxStringLength) {
-    DLOGE("event size %d is greater than event buffer size %zd\n", size, kMaxStringLength);
-    return;
-  }
-
-  if (size < (int32_t)sizeof(*event_resp)) {
-    DLOGE("Invalid event size %d expected %zd\n", size, sizeof(*event_resp));
-    return;
-  }
-
-  int32_t i = 0;
-  while (i < size) {
-    event_resp = (struct drm_msm_event_resp *)&event_data[i];
-    switch (event_resp->base.type) {
-      case DRM_EVENT_PANEL_DEAD:
-      {
-        DLOGI("Received panel dead event");
-        event_handler_->PanelDead();
-        break;
-      }
-      default: {
-        DLOGE("invalid event %d", event_resp->base.type);
-        break;
-      }
-    }
-    i += event_resp->base.length;
-  }
-
-  return;
-}
-
-void HWEventsDRM::VSyncHandlerCallback(int fd, unsigned int sequence, unsigned int tv_sec,
-                                       unsigned int tv_usec, void *data) {
-  int64_t timestamp = (int64_t)(tv_sec)*1000000000 + (int64_t)(tv_usec)*1000;
-  reinterpret_cast<HWEventsDRM *>(data)->event_handler_->VSync(timestamp);
-}
-
-void HWEventsDRM::HandleIdleTimeout(char *data) {
-  char event_data[kMaxStringLength];
-  int32_t size;
-  struct drm_msm_event_resp *event_resp = NULL;
-
-  size = (int32_t)Sys::pread_(poll_fds_[idle_notify_index_].fd, event_data, kMaxStringLength, 0);
-  if (size < 0) {
-    return;
-  }
-
-  if (size > kMaxStringLength) {
-    DLOGE("event size %d is greater than event buffer size %zd\n", size, kMaxStringLength);
-    return;
-  }
-
-  if (size < (int32_t)sizeof(*event_resp)) {
-    DLOGE("size %d exp %zd\n", size, sizeof(*event_resp));
-    return;
-  }
-
-  int32_t i = 0;
-
-  while (i < size) {
-    event_resp = (struct drm_msm_event_resp *)&event_data[i];
-    switch (event_resp->base.type) {
-      case DRM_EVENT_IDLE_NOTIFY:
-      {
-        DLOGV("Received Idle time event");
-        event_handler_->IdleTimeout();
-        break;
-      }
-      default: {
-        DLOGE("invalid event %d", event_resp->base.type);
-        break;
-      }
-    }
-    i += event_resp->base.length;
-  }
-
-  return;
-}
-
-void HWEventsDRM::HandleCECMessage(char *data) {
-  event_handler_->CECMessage(data);
-}
-
-void HWEventsDRM::HandleIdlePowerCollapse(char *data) {
-  char event_data[kMaxStringLength];
-  int32_t size;
-  struct drm_msm_event_resp *event_resp = NULL;
-
-  size = (int32_t)Sys::pread_(poll_fds_[idle_pc_index_].fd, event_data, kMaxStringLength, 0);
-  if (size < 0) {
-    return;
-  }
-
-  if (size > kMaxStringLength) {
-    DLOGE("event size %d is greater than event buffer size %zd\n", size, kMaxStringLength);
-    return;
-  }
-
-  if (size < (int32_t)sizeof(*event_resp)) {
-    DLOGE("size %d exp %zd\n", size, sizeof(*event_resp));
-    return;
-  }
-
-  int32_t i = 0;
-
-  while (i < size) {
-    event_resp = (struct drm_msm_event_resp *)&event_data[i];
-    switch (event_resp->base.type) {
-      case DRM_EVENT_SDE_POWER:
-      {
-        uint32_t* event_payload = reinterpret_cast<uint32_t *>(event_resp->data);
-        if (*event_payload == 0) {
-          DLOGV("Received Idle power collapse event");
-          event_handler_->IdlePowerCollapse();
-        }
-        break;
-      }
-      default: {
-        DLOGE("invalid event %d", event_resp->base.type);
-        break;
-      }
-    }
-    i += event_resp->base.length;
-  }
-
-  return;
-}
-
-}  // namespace sdm
diff --git a/sdm/libs/core/drm/hw_events_drm.h b/sdm/libs/core/drm/hw_events_drm.h
deleted file mode 100644
index fafe606..0000000
--- a/sdm/libs/core/drm/hw_events_drm.h
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
-* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without
-* modification, are permitted provided that the following conditions are
-* met:
-*     * Redistributions of source code must retain the above copyright
-*       notice, this list of conditions and the following disclaimer.
-*     * Redistributions in binary form must reproduce the above
-*       copyright notice, this list of conditions and the following
-*       disclaimer in the documentation and/or other materials provided
-*       with the distribution.
-*     * Neither the name of The Linux Foundation nor the names of its
-*       contributors may be used to endorse or promote products derived
-*       from this software without specific prior written permission.
-*
-* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
-* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
-* ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
-* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
-* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#ifndef __HW_EVENTS_DRM_H__
-#define __HW_EVENTS_DRM_H__
-
-#include <drm_interface.h>
-#include <sys/poll.h>
-#include <map>
-#include <mutex>
-#include <string>
-#include <utility>
-#include <vector>
-
-#include "hw_events_interface.h"
-#include "hw_interface.h"
-#include "hw_device_drm.h"
-
-namespace sdm {
-
-using std::vector;
-
-class HWEventsDRM : public HWEventsInterface {
- public:
-  virtual DisplayError Init(int display_type, HWEventHandler *event_handler,
-                            const vector<HWEvent> &event_list,
-                            const HWInterface *hw_intf);
-  virtual DisplayError Deinit();
-  virtual DisplayError SetEventState(HWEvent event, bool enable, void *aux = nullptr);
-
- private:
-  static const int kMaxStringLength = 1024;
-
-  typedef void (HWEventsDRM::*EventParser)(char *);
-
-  struct HWEventData {
-    HWEvent event_type {};
-    EventParser event_parser {};
-  };
-
-  static void *DisplayEventThread(void *context);
-  static void VSyncHandlerCallback(int fd, unsigned int sequence, unsigned int tv_sec,
-                                   unsigned int tv_usec, void *data);
-
-  void *DisplayEventHandler();
-  void HandleVSync(char *data);
-  void HandleIdleTimeout(char *data);
-  void HandleCECMessage(char *data);
-  void HandleThreadExit(char *data) {}
-  void HandleThermal(char *data) {}
-  void HandleBlank(char *data) {}
-  void HandleIdlePowerCollapse(char *data);
-  void HandlePanelDead(char *data);
-  void PopulateHWEventData(const vector<HWEvent> &event_list);
-  void WakeUpEventThread();
-  DisplayError SetEventParser();
-  DisplayError InitializePollFd();
-  DisplayError CloseFds();
-  DisplayError RegisterVSync();
-  DisplayError RegisterPanelDead(bool enable);
-  DisplayError RegisterIdleNotify(bool enable);
-  DisplayError RegisterIdlePowerCollapse(bool enable);
-
-  HWEventHandler *event_handler_{};
-  vector<HWEventData> event_data_list_{};
-  vector<pollfd> poll_fds_{};
-  pthread_t event_thread_{};
-  std::string event_thread_name_ = "SDM_EventThread";
-  bool exit_threads_ = false;
-  uint32_t vsync_index_ = 0;
-  bool vsync_enabled_ = false;
-  bool vsync_registered_ = false;
-  std::mutex vsync_mutex_;  // To protect vsync_enabled_ and vsync_registered_
-  uint32_t idle_notify_index_ = 0;
-  sde_drm::DRMDisplayToken token_ = {};
-  bool is_primary_ = false;
-  uint32_t panel_dead_index_ = 0;
-  uint32_t idle_pc_index_ = 0;
-};
-
-}  // namespace sdm
-
-#endif  // __HW_EVENTS_DRM_H__
diff --git a/sdm/libs/core/drm/hw_info_drm.cpp b/sdm/libs/core/drm/hw_info_drm.cpp
deleted file mode 100644
index 6469094..0000000
--- a/sdm/libs/core/drm/hw_info_drm.cpp
+++ /dev/null
@@ -1,672 +0,0 @@
-/*
-* Copyright (c) 2017 - 2018, The Linux Foundation. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without
-* modification, are permitted provided that the following conditions are
-* met:
-*     * Redistributions of source code must retain the above copyright
-*       notice, this list of conditions and the following disclaimer.
-*     * Redistributions in binary form must reproduce the above
-*       copyright notice, this list of conditions and the following
-*       disclaimer in the documentation and/or other materials provided
-*       with the distribution.
-*     * Neither the name of The Linux Foundation nor the names of its
-*       contributors may be used to endorse or promote products derived
-*       from this software without specific prior written permission.
-*
-* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
-* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
-* ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
-* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
-* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#include <dlfcn.h>
-#include <drm/drm_fourcc.h>
-#include <drm_lib_loader.h>
-#include <drm_master.h>
-#include <drm_res_mgr.h>
-#include <fcntl.h>
-#include <media/msm_sde_rotator.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <utils/constants.h>
-#include <utils/debug.h>
-#include <utils/sys.h>
-
-#include <algorithm>
-#include <fstream>
-#include <iostream>
-#include <map>
-#include <memory>
-#include <string>
-#include <utility>
-#include <vector>
-
-#include "hw_info_drm.h"
-
-#ifndef DRM_FORMAT_MOD_QCOM_COMPRESSED
-#define DRM_FORMAT_MOD_QCOM_COMPRESSED fourcc_mod_code(QCOM, 1)
-#endif
-#ifndef DRM_FORMAT_MOD_QCOM_DX
-#define DRM_FORMAT_MOD_QCOM_DX fourcc_mod_code(QCOM, 0x2)
-#endif
-#ifndef DRM_FORMAT_MOD_QCOM_TIGHT
-#define DRM_FORMAT_MOD_QCOM_TIGHT fourcc_mod_code(QCOM, 0x4)
-#endif
-
-#define __CLASS__ "HWInfoDRM"
-
-using drm_utils::DRMMaster;
-using drm_utils::DRMResMgr;
-using drm_utils::DRMLibLoader;
-using sde_drm::GetDRMManager;
-using sde_drm::DRMPlanesInfo;
-using sde_drm::DRMCrtcInfo;
-using sde_drm::DRMPlaneType;
-
-using std::vector;
-using std::map;
-using std::string;
-using std::fstream;
-using std::to_string;
-
-namespace sdm {
-
-static HWQseedStepVersion GetQseedStepVersion(sde_drm::QSEEDStepVersion drm_version) {
-  HWQseedStepVersion sdm_version;
-  switch (drm_version) {
-    case sde_drm::QSEEDStepVersion::V2:
-    default:
-      sdm_version = kQseed3v2;
-      break;
-    case sde_drm::QSEEDStepVersion::V3:
-      sdm_version = kQseed3v3;
-      break;
-    case sde_drm::QSEEDStepVersion::V4:
-      sdm_version = kQseed3v4;
-      break;
-  }
-  return sdm_version;
-}
-
-HWResourceInfo *HWInfoDRM::hw_resource_ = nullptr;
-
-HWInfoDRM::HWInfoDRM() {
-  default_mode_ = (DRMLibLoader::GetInstance()->IsLoaded() == false);
-  if (!default_mode_) {
-    DRMMaster *drm_master = {};
-    int dev_fd = -1;
-    DRMMaster::GetInstance(&drm_master);
-    if (!drm_master) {
-      DLOGE("Failed to acquire DRMMaster instance");
-      return;
-    }
-    drm_master->GetHandle(&dev_fd);
-    DRMLibLoader::GetInstance()->FuncGetDRMManager()(dev_fd, &drm_mgr_intf_);
-  }
-}
-
-HWInfoDRM::~HWInfoDRM() {
-  delete hw_resource_;
-  hw_resource_ = nullptr;
-
-  if (drm_mgr_intf_) {
-    DRMLibLoader::GetInstance()->FuncDestroyDRMManager()();
-    drm_mgr_intf_ = nullptr;
-  }
-
-  DRMLibLoader::Destroy();
-  DRMMaster::DestroyInstance();
-}
-
-DisplayError HWInfoDRM::GetDynamicBWLimits(HWResourceInfo *hw_resource) {
-  HWDynBwLimitInfo* bw_info = &hw_resource->dyn_bw_info;
-  for (int index = 0; index < kBwModeMax; index++) {
-    bw_info->total_bw_limit[index] = hw_resource->max_bandwidth_low;
-    bw_info->pipe_bw_limit[index] = hw_resource->max_pipe_bw;
-  }
-
-  return kErrorNone;
-}
-
-DisplayError HWInfoDRM::GetHWResourceInfo(HWResourceInfo *hw_resource) {
-  if (hw_resource_) {
-    *hw_resource = *hw_resource_;
-    return kErrorNone;
-  }
-
-  hw_resource->num_blending_stages = 1;
-  hw_resource->max_pipe_width = 2560;
-  hw_resource->max_cursor_size = 128;
-  hw_resource->max_scale_down = 1;
-  hw_resource->max_scale_up = 1;
-  hw_resource->has_decimation = false;
-  hw_resource->max_bandwidth_low = 9600000;
-  hw_resource->max_bandwidth_high = 9600000;
-  hw_resource->max_pipe_bw = 4500000;
-  hw_resource->max_sde_clk = 412500000;
-  hw_resource->clk_fudge_factor = FLOAT(105) / FLOAT(100);
-  hw_resource->macrotile_nv12_factor = 8;
-  hw_resource->macrotile_factor = 4;
-  hw_resource->linear_factor = 1;
-  hw_resource->scale_factor = 1;
-  hw_resource->extra_fudge_factor = 2;
-  hw_resource->amortizable_threshold = 25;
-  hw_resource->system_overhead_lines = 0;
-  hw_resource->hw_dest_scalar_info.count = 0;
-  hw_resource->hw_dest_scalar_info.max_scale_up = 0;
-  hw_resource->hw_dest_scalar_info.max_input_width = 0;
-  hw_resource->hw_dest_scalar_info.max_output_width = 0;
-  hw_resource->is_src_split = true;
-  hw_resource->has_dyn_bw_support = false;
-  hw_resource->has_qseed3 = false;
-  hw_resource->has_concurrent_writeback = false;
-
-  hw_resource->hw_version = SDEVERSION(4, 0, 1);
-  // TODO(user): On FB driver hw_revision comprises of major version, minor version and hw_revision.
-  // On DRM driver, hw_revision is deprecated and hw_version comprises major version, minor version
-  // and hw_revision information. Since QDCM uses hw_revision variable populate hw_revision with
-  // hw_version. Remove hw_revision variable when FB code is deperecated.
-  hw_resource->hw_revision = SDEVERSION(4, 0, 1);
-
-  // TODO(user): Deprecate
-  hw_resource->max_mixer_width = 2560;
-  hw_resource->writeback_index = 0;
-  hw_resource->has_bwc = false;
-  hw_resource->has_ubwc = true;
-  hw_resource->has_macrotile = true;
-  hw_resource->separate_rotator = true;
-  hw_resource->has_non_scalar_rgb = false;
-
-  GetSystemInfo(hw_resource);
-  GetHWPlanesInfo(hw_resource);
-  GetWBInfo(hw_resource);
-
-  // Disable destination scalar count to 0 if extension library is not present or disabled
-  // through property
-  int value = 0;
-  bool disable_dest_scalar = false;
-  if (Debug::GetProperty(DISABLE_DESTINATION_SCALER_PROP, &value) == kErrorNone) {
-    disable_dest_scalar = (value == 1);
-  }
-  DynLib extension_lib;
-  if (!extension_lib.Open("libsdmextension.so") || disable_dest_scalar) {
-    hw_resource->hw_dest_scalar_info.count = 0;
-  }
-
-  DLOGI("Max plane width = %d", hw_resource->max_pipe_width);
-  DLOGI("Max cursor width = %d", hw_resource->max_cursor_size);
-  DLOGI("Max plane upscale = %d", hw_resource->max_scale_up);
-  DLOGI("Max plane downscale = %d", hw_resource->max_scale_down);
-  DLOGI("Has Decimation = %d", hw_resource->has_decimation);
-  DLOGI("Max Blending Stages = %d", hw_resource->num_blending_stages);
-  DLOGI("Has Source Split = %d", hw_resource->is_src_split);
-  DLOGI("Has QSEED3 = %d", hw_resource->has_qseed3);
-  DLOGI("Has UBWC = %d", hw_resource->has_ubwc);
-  DLOGI("Has Concurrent Writeback = %d", hw_resource->has_concurrent_writeback);
-  DLOGI("Max Low Bw = %" PRIu64 "", hw_resource->max_bandwidth_low);
-  DLOGI("Max High Bw = % " PRIu64 "", hw_resource->max_bandwidth_high);
-  DLOGI("Max Pipe Bw = %" PRIu64 " KBps", hw_resource->max_pipe_bw);
-  DLOGI("MaxSDEClock = % " PRIu64 " Hz", hw_resource->max_sde_clk);
-  DLOGI("Clock Fudge Factor = %f", hw_resource->clk_fudge_factor);
-  DLOGI("Prefill factors:");
-  DLOGI("\tTiled_NV12 = %d", hw_resource->macrotile_nv12_factor);
-  DLOGI("\tTiled = %d", hw_resource->macrotile_factor);
-  DLOGI("\tLinear = %d", hw_resource->linear_factor);
-  DLOGI("\tScale = %d", hw_resource->scale_factor);
-  DLOGI("\tFudge_factor = %d", hw_resource->extra_fudge_factor);
-  DLOGI("\tib_fudge_factor = %f", hw_resource->ib_fudge_factor);
-
-  if (hw_resource->separate_rotator || hw_resource->num_dma_pipe) {
-    GetHWRotatorInfo(hw_resource);
-  }
-
-  if (hw_resource->has_dyn_bw_support) {
-    DisplayError ret = GetDynamicBWLimits(hw_resource);
-    if (ret != kErrorNone) {
-      DLOGE("Failed to read dynamic band width info");
-      return ret;
-    }
-
-    DLOGI("Has Support for multiple bw limits shown below");
-    for (int index = 0; index < kBwModeMax; index++) {
-      DLOGI("Mode-index=%d  total_bw_limit=%d and pipe_bw_limit=%d", index,
-            hw_resource->dyn_bw_info.total_bw_limit[index],
-            hw_resource->dyn_bw_info.pipe_bw_limit[index]);
-    }
-  }
-
-  if (!hw_resource_) {
-    hw_resource_ = new HWResourceInfo();
-    *hw_resource_ = *hw_resource;
-  }
-
-  return kErrorNone;
-}
-
-void HWInfoDRM::GetSystemInfo(HWResourceInfo *hw_resource) {
-  DRMCrtcInfo info;
-  drm_mgr_intf_->GetCrtcInfo(0 /* system_info */, &info);
-  hw_resource->has_hdr = info.has_hdr;
-  hw_resource->is_src_split = info.has_src_split;
-  hw_resource->has_qseed3 = (info.qseed_version == sde_drm::QSEEDVersion::V3);
-  hw_resource->num_blending_stages = info.max_blend_stages;
-  hw_resource->num_solidfill_stages = info.max_solidfill_stages;
-  hw_resource->smart_dma_rev = (info.smart_dma_rev == sde_drm::SmartDMARevision::V2) ?
-    SmartDMARevision::V2 : SmartDMARevision::V1;
-  hw_resource->ib_fudge_factor = info.ib_fudge_factor;
-  hw_resource->hw_dest_scalar_info.prefill_lines = info.dest_scale_prefill_lines;
-  hw_resource->undersized_prefill_lines = info.undersized_prefill_lines;
-  hw_resource->macrotile_factor = info.macrotile_prefill_lines;
-  hw_resource->macrotile_nv12_factor = info.nv12_prefill_lines;
-  hw_resource->linear_factor = info.linear_prefill_lines;
-  hw_resource->scale_factor = info.downscale_prefill_lines;
-  hw_resource->extra_fudge_factor = info.extra_prefill_lines;
-  hw_resource->amortizable_threshold = info.amortized_threshold;
-  hw_resource->max_bandwidth_low = info.max_bandwidth_low / kKiloUnit;
-  hw_resource->max_bandwidth_high = info.max_bandwidth_high / kKiloUnit;
-  hw_resource->max_sde_clk = info.max_sde_clk;
-  hw_resource->hw_version = info.hw_version;
-  // TODO(user): On FB driver hw_revision comprises of major version, minor version and hw_revision.
-  // On DRM driver, hw_revision is deprecated and hw_version comprises major version, minor version
-  // and hw_revision information. Since QDCM uses hw_revision variable populate hw_revision with
-  // hw_version. Remove hw_revision variable when FB code is deperecated.
-  hw_resource->hw_revision = info.hw_version;
-
-  std::vector<LayerBufferFormat> sdm_format;
-  for (auto &it : info.comp_ratio_rt_map) {
-    std::pair<uint32_t, uint64_t> drm_format = it.first;
-    GetSDMFormat(drm_format.first, drm_format.second, &sdm_format);
-    hw_resource->comp_ratio_rt_map.insert(std::make_pair(sdm_format[0], it.second));
-    sdm_format.clear();
-  }
-
-  for (auto &it : info.comp_ratio_nrt_map) {
-    std::pair<uint32_t, uint64_t> drm_format = it.first;
-    GetSDMFormat(drm_format.first, drm_format.second, &sdm_format);
-    hw_resource->comp_ratio_rt_map.insert(std::make_pair(sdm_format[0], it.second));
-    sdm_format.clear();
-  }
-
-  hw_resource->hw_dest_scalar_info.count = info.dest_scaler_count;
-  hw_resource->hw_dest_scalar_info.max_scale_up = info.max_dest_scale_up;
-  hw_resource->hw_dest_scalar_info.max_input_width = info.max_dest_scaler_input_width;
-  hw_resource->hw_dest_scalar_info.max_output_width = info.max_dest_scaler_output_width;
-  hw_resource->min_prefill_lines = info.min_prefill_lines;
-}
-
-void HWInfoDRM::GetHWPlanesInfo(HWResourceInfo *hw_resource) {
-  DRMPlanesInfo planes;
-  drm_mgr_intf_->GetPlanesInfo(&planes);
-
-  // To simulate reduced config.
-  uint32_t max_vig_pipes = 0;
-  uint32_t max_dma_pipes = 0;
-  Debug::GetReducedConfig(&max_vig_pipes, &max_dma_pipes);
-  uint32_t max_virtual_pipes = max_vig_pipes + max_dma_pipes;
-  uint32_t vig_pipe_count = 0;
-  uint32_t dma_pipe_count = 0;
-  uint32_t virtual_pipe_count = 0;
-
-  for (auto &pipe_obj : planes) {
-    if (max_vig_pipes && max_dma_pipes) {
-      uint32_t master_plane_id = pipe_obj.second.master_plane_id;
-      if ((pipe_obj.second.type == DRMPlaneType::DMA) && (dma_pipe_count < max_dma_pipes)
-          && !master_plane_id) {
-        dma_pipe_count++;
-      } else if ((pipe_obj.second.type == DRMPlaneType::VIG) && (vig_pipe_count < max_vig_pipes)
-          && !master_plane_id) {
-        vig_pipe_count++;
-      } else if ((master_plane_id) && (virtual_pipe_count < max_virtual_pipes)) {
-        bool is_virtual = false;
-        for (auto &pipe_caps : hw_resource->hw_pipes) {
-          if (master_plane_id == pipe_caps.id) {
-            is_virtual = true;
-            virtual_pipe_count++;
-            break;
-          }
-        }
-        if (!is_virtual) {
-          continue;
-        }
-      } else {
-        continue;
-      }
-    }
-
-    HWPipeCaps pipe_caps;
-    string name = {};
-    switch (pipe_obj.second.type) {
-      case DRMPlaneType::DMA:
-        name = "DMA";
-        pipe_caps.type = kPipeTypeDMA;
-        if (!hw_resource->num_dma_pipe) {
-          PopulateSupportedFmts(kHWDMAPipe, pipe_obj.second, hw_resource);
-        }
-        hw_resource->num_dma_pipe++;
-        break;
-      case DRMPlaneType::VIG:
-        name = "VIG";
-        pipe_caps.type = kPipeTypeVIG;
-        if (!hw_resource->num_vig_pipe) {
-          PopulatePipeCaps(pipe_obj.second, hw_resource);
-          PopulateSupportedFmts(kHWVIGPipe, pipe_obj.second, hw_resource);
-        }
-        hw_resource->num_vig_pipe++;
-        break;
-      case DRMPlaneType::CURSOR:
-        name = "CURSOR";
-        pipe_caps.type = kPipeTypeCursor;
-        if (!hw_resource->num_cursor_pipe) {
-          PopulateSupportedFmts(kHWCursorPipe, pipe_obj.second, hw_resource);
-          hw_resource->max_cursor_size = pipe_obj.second.max_linewidth;
-        }
-        hw_resource->num_cursor_pipe++;
-        break;
-      default:
-        continue;  // Not adding any other pipe type
-    }
-    pipe_caps.id = pipe_obj.first;
-    pipe_caps.master_pipe_id = pipe_obj.second.master_plane_id;
-    DLOGI("Adding %s Pipe : Id %x, master_pipe_id : Id %x",
-          name.c_str(), pipe_obj.first, pipe_obj.second.master_plane_id);
-    hw_resource->hw_pipes.push_back(std::move(pipe_caps));
-  }
-}
-
-void HWInfoDRM::PopulatePipeCaps(const sde_drm::DRMPlaneTypeInfo &info,
-                                    HWResourceInfo *hw_resource) {
-  hw_resource->max_pipe_width = info.max_linewidth;
-  hw_resource->max_scale_down = info.max_downscale;
-  hw_resource->max_scale_up = info.max_upscale;
-  hw_resource->has_decimation = info.max_horizontal_deci > 1 && info.max_vertical_deci > 1;
-  hw_resource->max_pipe_bw = info.max_pipe_bandwidth / kKiloUnit;
-  hw_resource->cache_size = info.cache_size;
-  hw_resource->pipe_qseed3_version = GetQseedStepVersion(info.qseed3_version);
-}
-
-void HWInfoDRM::PopulateSupportedFmts(HWSubBlockType sub_blk_type,
-                                      const sde_drm::DRMPlaneTypeInfo  &info,
-                                      HWResourceInfo *hw_resource) {
-  vector<LayerBufferFormat> sdm_formats;
-  FormatsMap &fmts_map = hw_resource->supported_formats_map;
-
-  if (fmts_map.find(sub_blk_type) == fmts_map.end()) {
-    for (auto &fmts : info.formats_supported) {
-      GetSDMFormat(fmts.first, fmts.second, &sdm_formats);
-    }
-
-    fmts_map.insert(make_pair(sub_blk_type, sdm_formats));
-  }
-}
-
-void HWInfoDRM::GetWBInfo(HWResourceInfo *hw_resource) {
-  HWSubBlockType sub_blk_type = kHWWBIntfOutput;
-  vector<LayerBufferFormat> supported_sdm_formats;
-  sde_drm::DRMDisplayToken token;
-
-  // Fake register
-  if (drm_mgr_intf_->RegisterDisplay(sde_drm::DRMDisplayType::VIRTUAL, &token)) {
-    return;
-  }
-
-  sde_drm::DRMConnectorInfo connector_info;
-  drm_mgr_intf_->GetConnectorInfo(token.conn_id, &connector_info);
-  for (auto &fmts : connector_info.formats_supported) {
-    GetSDMFormat(fmts.first, fmts.second, &supported_sdm_formats);
-  }
-
-  hw_resource->supported_formats_map.erase(sub_blk_type);
-  hw_resource->supported_formats_map.insert(make_pair(sub_blk_type, supported_sdm_formats));
-
-  drm_mgr_intf_->UnregisterDisplay(token);
-}
-
-void HWInfoDRM::GetSDMFormat(uint32_t v4l2_format, LayerBufferFormat *sdm_format) {
-  switch (v4l2_format) {
-    case SDE_PIX_FMT_ARGB_8888:         *sdm_format = kFormatARGB8888;                 break;
-    case SDE_PIX_FMT_RGBA_8888:         *sdm_format = kFormatRGBA8888;                 break;
-    case SDE_PIX_FMT_BGRA_8888:         *sdm_format = kFormatBGRA8888;                 break;
-    case SDE_PIX_FMT_RGBX_8888:         *sdm_format = kFormatRGBX8888;                 break;
-    case SDE_PIX_FMT_BGRX_8888:         *sdm_format = kFormatBGRX8888;                 break;
-    case SDE_PIX_FMT_RGBA_5551:         *sdm_format = kFormatRGBA5551;                 break;
-    case SDE_PIX_FMT_RGBA_4444:         *sdm_format = kFormatRGBA4444;                 break;
-    case SDE_PIX_FMT_RGB_888:           *sdm_format = kFormatRGB888;                   break;
-    case SDE_PIX_FMT_BGR_888:           *sdm_format = kFormatBGR888;                   break;
-    case SDE_PIX_FMT_RGB_565:           *sdm_format = kFormatRGB565;                   break;
-    case SDE_PIX_FMT_BGR_565:           *sdm_format = kFormatBGR565;                   break;
-    case SDE_PIX_FMT_Y_CB_CR_H2V2:      *sdm_format = kFormatYCbCr420Planar;           break;
-    case SDE_PIX_FMT_Y_CR_CB_H2V2:      *sdm_format = kFormatYCrCb420Planar;           break;
-    case SDE_PIX_FMT_Y_CR_CB_GH2V2:     *sdm_format = kFormatYCrCb420PlanarStride16;   break;
-    case SDE_PIX_FMT_Y_CBCR_H2V2:       *sdm_format = kFormatYCbCr420SemiPlanar;       break;
-    case SDE_PIX_FMT_Y_CRCB_H2V2:       *sdm_format = kFormatYCrCb420SemiPlanar;       break;
-    case SDE_PIX_FMT_Y_CBCR_H1V2:       *sdm_format = kFormatYCbCr422H1V2SemiPlanar;   break;
-    case SDE_PIX_FMT_Y_CRCB_H1V2:       *sdm_format = kFormatYCrCb422H1V2SemiPlanar;   break;
-    case SDE_PIX_FMT_Y_CBCR_H2V1:       *sdm_format = kFormatYCbCr422H2V1SemiPlanar;   break;
-    case SDE_PIX_FMT_Y_CRCB_H2V1:       *sdm_format = kFormatYCrCb422H2V1SemiPlanar;   break;
-    case SDE_PIX_FMT_YCBYCR_H2V1:       *sdm_format = kFormatYCbCr422H2V1Packed;       break;
-    case SDE_PIX_FMT_Y_CBCR_H2V2_VENUS: *sdm_format = kFormatYCbCr420SemiPlanarVenus;  break;
-    case SDE_PIX_FMT_Y_CRCB_H2V2_VENUS: *sdm_format = kFormatYCrCb420SemiPlanarVenus;  break;
-    case SDE_PIX_FMT_RGBA_8888_UBWC:    *sdm_format = kFormatRGBA8888Ubwc;             break;
-    case SDE_PIX_FMT_RGBX_8888_UBWC:    *sdm_format = kFormatRGBX8888Ubwc;             break;
-    case SDE_PIX_FMT_RGB_565_UBWC:      *sdm_format = kFormatBGR565Ubwc;               break;
-    case SDE_PIX_FMT_Y_CBCR_H2V2_UBWC:  *sdm_format = kFormatYCbCr420SPVenusUbwc;      break;
-    case SDE_PIX_FMT_RGBA_1010102:      *sdm_format = kFormatRGBA1010102;              break;
-    case SDE_PIX_FMT_ARGB_2101010:      *sdm_format = kFormatARGB2101010;              break;
-    case SDE_PIX_FMT_RGBX_1010102:      *sdm_format = kFormatRGBX1010102;              break;
-    case SDE_PIX_FMT_XRGB_2101010:      *sdm_format = kFormatXRGB2101010;              break;
-    case SDE_PIX_FMT_BGRA_1010102:      *sdm_format = kFormatBGRA1010102;              break;
-    case SDE_PIX_FMT_ABGR_2101010:      *sdm_format = kFormatABGR2101010;              break;
-    case SDE_PIX_FMT_BGRX_1010102:      *sdm_format = kFormatBGRX1010102;              break;
-    case SDE_PIX_FMT_XBGR_2101010:      *sdm_format = kFormatXBGR2101010;              break;
-    case SDE_PIX_FMT_RGBA_1010102_UBWC: *sdm_format = kFormatRGBA1010102Ubwc;          break;
-    case SDE_PIX_FMT_RGBX_1010102_UBWC: *sdm_format = kFormatRGBX1010102Ubwc;          break;
-    case SDE_PIX_FMT_Y_CBCR_H2V2_P010:  *sdm_format = kFormatYCbCr420P010;             break;
-    case SDE_PIX_FMT_Y_CBCR_H2V2_TP10_UBWC:  *sdm_format = kFormatYCbCr420TP10Ubwc;     break;
-    case SDE_PIX_FMT_Y_CBCR_H2V2_P010_UBWC:  *sdm_format = kFormatYCbCr420P010Ubwc;     break;
-    case SDE_PIX_FMT_Y_CBCR_H2V2_P010_VENUS: *sdm_format = kFormatYCbCr420P010Venus;    break;
-    default: *sdm_format = kFormatInvalid;
-  }
-}
-
-void HWInfoDRM::GetRotatorFormatsForType(int fd, uint32_t type,
-                                         vector<LayerBufferFormat> *supported_formats) {
-  struct v4l2_fmtdesc fmtdesc = {};
-  fmtdesc.type = type;
-  while (!Sys::ioctl_(fd, static_cast<int>(VIDIOC_ENUM_FMT), &fmtdesc)) {
-    LayerBufferFormat sdm_format = kFormatInvalid;
-    GetSDMFormat(fmtdesc.pixelformat, &sdm_format);
-    if (sdm_format != kFormatInvalid) {
-      supported_formats->push_back(sdm_format);
-    }
-    fmtdesc.index++;
-  }
-}
-
-DisplayError HWInfoDRM::GetRotatorSupportedFormats(uint32_t v4l2_index,
-                                                   HWResourceInfo *hw_resource) {
-  string path = "/dev/video" + to_string(v4l2_index);
-  int fd = Sys::open_(path.c_str(), O_RDONLY);
-  if (fd < 0) {
-    DLOGE("Failed to open %s with error %d", path.c_str(), errno);
-    return kErrorNotSupported;
-  }
-
-  vector<LayerBufferFormat> supported_formats = {};
-  GetRotatorFormatsForType(fd, V4L2_BUF_TYPE_VIDEO_OUTPUT, &supported_formats);
-  hw_resource->supported_formats_map.erase(kHWRotatorInput);
-  hw_resource->supported_formats_map.insert(make_pair(kHWRotatorInput, supported_formats));
-
-  supported_formats = {};
-  GetRotatorFormatsForType(fd, V4L2_BUF_TYPE_VIDEO_CAPTURE, &supported_formats);
-  hw_resource->supported_formats_map.erase(kHWRotatorOutput);
-  hw_resource->supported_formats_map.insert(make_pair(kHWRotatorOutput, supported_formats));
-
-  Sys::close_(fd);
-
-  return kErrorNone;
-}
-
-DisplayError HWInfoDRM::GetHWRotatorInfo(HWResourceInfo *hw_resource) {
-  string v4l2_path = "/sys/class/video4linux/video";
-  const uint32_t kMaxV4L2Nodes = 64;
-
-  for (uint32_t i = 0; i < kMaxV4L2Nodes; i++) {
-    string path = v4l2_path + to_string(i) + "/name";
-    Sys::fstream fs(path, fstream::in);
-    if (!fs.is_open()) {
-      continue;
-    }
-
-    string line;
-    if (Sys::getline_(fs, line) && (!strncmp(line.c_str(), "sde_rotator", strlen("sde_rotator")))) {
-      hw_resource->hw_rot_info.device_path = string("/dev/video" + to_string(i));
-      hw_resource->hw_rot_info.num_rotator++;
-      hw_resource->hw_rot_info.type = HWRotatorInfo::ROT_TYPE_V4L2;
-      hw_resource->hw_rot_info.has_downscale = true;
-      GetRotatorSupportedFormats(i, hw_resource);
-
-      string caps_path = v4l2_path + to_string(i) + "/device/caps";
-      Sys::fstream caps_fs(caps_path, fstream::in);
-
-      if (caps_fs.is_open()) {
-        string caps;
-        while (Sys::getline_(caps_fs, caps)) {
-          const string downscale_compression = "downscale_compression=";
-          const string min_downscale = "min_downscale=";
-          if (caps.find(downscale_compression) != string::npos) {
-            hw_resource->hw_rot_info.downscale_compression =
-              std::stoi(string(caps, downscale_compression.length()));
-          } else if (caps.find(min_downscale) != string::npos) {
-            hw_resource->hw_rot_info.min_downscale =
-              std::stof(string(caps, min_downscale.length()));
-          }
-        }
-      }
-
-      // We support only 1 rotator
-      break;
-    }
-  }
-
-  DLOGI("V4L2 Rotator: Count = %d, Downscale = %d, Min_downscale = %f, Downscale_compression = %d",
-        hw_resource->hw_rot_info.num_rotator, hw_resource->hw_rot_info.has_downscale,
-        hw_resource->hw_rot_info.min_downscale, hw_resource->hw_rot_info.downscale_compression);
-
-  return kErrorNone;
-}
-
-void HWInfoDRM::GetSDMFormat(uint32_t drm_format, uint64_t drm_format_modifier,
-                             vector<LayerBufferFormat> *sdm_formats) {
-  vector<LayerBufferFormat> &fmts(*sdm_formats);
-  switch (drm_format) {
-    case DRM_FORMAT_BGRA8888:
-      fmts.push_back(kFormatARGB8888);
-      break;
-    case DRM_FORMAT_ABGR8888:
-      fmts.push_back(drm_format_modifier ? kFormatRGBA8888Ubwc : kFormatRGBA8888);
-      break;
-    case DRM_FORMAT_ARGB8888:
-      fmts.push_back(kFormatBGRA8888);
-      break;
-    case DRM_FORMAT_BGRX8888:
-      fmts.push_back(kFormatXRGB8888);
-      break;
-    case DRM_FORMAT_XBGR8888:
-      fmts.push_back(drm_format_modifier ? kFormatRGBX8888Ubwc : kFormatRGBX8888);
-      break;
-    case DRM_FORMAT_XRGB8888:
-      fmts.push_back(kFormatBGRX8888);
-      break;
-    case DRM_FORMAT_ABGR1555:
-      fmts.push_back(kFormatRGBA5551);
-      break;
-    case DRM_FORMAT_ABGR4444:
-      fmts.push_back(kFormatRGBA4444);
-      break;
-    case DRM_FORMAT_BGR888:
-      fmts.push_back(kFormatRGB888);
-      break;
-    case DRM_FORMAT_RGB888:
-      fmts.push_back(kFormatBGR888);
-      break;
-    case DRM_FORMAT_BGR565:
-      fmts.push_back(drm_format_modifier ? kFormatBGR565Ubwc : kFormatRGB565);
-      break;
-    case DRM_FORMAT_RGB565:
-      fmts.push_back(kFormatBGR565);
-      break;
-    case DRM_FORMAT_ABGR2101010:
-      fmts.push_back(drm_format_modifier ? kFormatRGBA1010102Ubwc : kFormatRGBA1010102);
-      break;
-    case DRM_FORMAT_BGRA1010102:
-      fmts.push_back(kFormatARGB2101010);
-      break;
-    case DRM_FORMAT_XBGR2101010:
-      fmts.push_back(drm_format_modifier ? kFormatRGBX1010102Ubwc : kFormatRGBX1010102);
-      break;
-    case DRM_FORMAT_BGRX1010102:
-      fmts.push_back(kFormatXRGB2101010);
-      break;
-    case DRM_FORMAT_ARGB2101010:
-      fmts.push_back(kFormatBGRA1010102);
-      break;
-    case DRM_FORMAT_RGBA1010102:
-      fmts.push_back(kFormatABGR2101010);
-      break;
-    case DRM_FORMAT_XRGB2101010:
-      fmts.push_back(kFormatBGRX1010102);
-      break;
-    case DRM_FORMAT_RGBX1010102:
-      fmts.push_back(kFormatXBGR2101010);
-      break;
-    case DRM_FORMAT_YVU420:
-      fmts.push_back(kFormatYCrCb420PlanarStride16);
-      break;
-    case DRM_FORMAT_NV12:
-      if (drm_format_modifier == (DRM_FORMAT_MOD_QCOM_COMPRESSED |
-          DRM_FORMAT_MOD_QCOM_DX | DRM_FORMAT_MOD_QCOM_TIGHT)) {
-          fmts.push_back(kFormatYCbCr420TP10Ubwc);
-      } else if (drm_format_modifier == (DRM_FORMAT_MOD_QCOM_COMPRESSED |
-                                         DRM_FORMAT_MOD_QCOM_DX)) {
-        fmts.push_back(kFormatYCbCr420P010Ubwc);
-      } else if (drm_format_modifier == DRM_FORMAT_MOD_QCOM_COMPRESSED) {
-         fmts.push_back(kFormatYCbCr420SPVenusUbwc);
-      } else if (drm_format_modifier == DRM_FORMAT_MOD_QCOM_DX) {
-        fmts.push_back(kFormatYCbCr420P010);
-        fmts.push_back(kFormatYCbCr420P010Venus);
-      } else {
-         fmts.push_back(kFormatYCbCr420SemiPlanarVenus);
-         fmts.push_back(kFormatYCbCr420SemiPlanar);
-      }
-      break;
-    case DRM_FORMAT_NV21:
-      fmts.push_back(kFormatYCrCb420SemiPlanarVenus);
-      fmts.push_back(kFormatYCrCb420SemiPlanar);
-      break;
-    case DRM_FORMAT_NV16:
-      fmts.push_back(kFormatYCbCr422H2V1SemiPlanar);
-      break;
-    default:
-      break;
-  }
-}
-
-DisplayError HWInfoDRM::GetFirstDisplayInterfaceType(HWDisplayInterfaceInfo *hw_disp_info) {
-  hw_disp_info->type = kPrimary;
-  hw_disp_info->is_connected = true;
-
-  return kErrorNone;
-}
-
-}  // namespace sdm
diff --git a/sdm/libs/core/drm/hw_info_drm.h b/sdm/libs/core/drm/hw_info_drm.h
deleted file mode 100644
index 82fb175..0000000
--- a/sdm/libs/core/drm/hw_info_drm.h
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
-* Copyright (c) 2017, The Linux Foundation. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without
-* modification, are permitted provided that the following conditions are
-* met:
-*     * Redistributions of source code must retain the above copyright
-*       notice, this list of conditions and the following disclaimer.
-*     * Redistributions in binary form must reproduce the above
-*       copyright notice, this list of conditions and the following
-*       disclaimer in the documentation and/or other materials provided
-*       with the distribution.
-*     * Neither the name of The Linux Foundation nor the names of its
-*       contributors may be used to endorse or promote products derived
-*       from this software without specific prior written permission.
-*
-* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
-* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
-* ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
-* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
-* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#ifndef __HW_INFO_DRM_H__
-#define __HW_INFO_DRM_H__
-
-#include <core/core_interface.h>
-#include <core/sdm_types.h>
-#include <drm_interface.h>
-#include <private/hw_info_types.h>
-#include <bitset>
-#include <vector>
-
-#include "hw_info_interface.h"
-
-namespace sdm {
-
-class HWInfoDRM: public HWInfoInterface {
- public:
-  HWInfoDRM();
-  virtual ~HWInfoDRM();
-  virtual DisplayError GetHWResourceInfo(HWResourceInfo *hw_resource);
-  virtual DisplayError GetFirstDisplayInterfaceType(HWDisplayInterfaceInfo *hw_disp_info);
-
- private:
-  DisplayError GetHWRotatorInfo(HWResourceInfo *hw_resource);
-  void GetSystemInfo(HWResourceInfo *hw_resource);
-  void GetHWPlanesInfo(HWResourceInfo *hw_resource);
-  void GetWBInfo(HWResourceInfo *hw_resource);
-  DisplayError GetDynamicBWLimits(HWResourceInfo *hw_resource);
-  void GetSDMFormat(uint32_t drm_format, uint64_t drm_format_modifier,
-                    std::vector<LayerBufferFormat> *sdm_formats);
-  void GetSDMFormat(uint32_t v4l2_format, LayerBufferFormat *sdm_format);
-  void GetRotatorFormatsForType(int fd, uint32_t type,
-                                std::vector<LayerBufferFormat> *supported_formats);
-  DisplayError GetRotatorSupportedFormats(uint32_t v4l2_index, HWResourceInfo *hw_resource);
-  void PopulateSupportedFmts(HWSubBlockType sub_blk_type, const sde_drm::DRMPlaneTypeInfo  &info,
-                             HWResourceInfo *hw_resource);
-  void PopulatePipeCaps(const sde_drm::DRMPlaneTypeInfo &info, HWResourceInfo *hw_resource);
-
-  sde_drm::DRMManagerInterface *drm_mgr_intf_ = {};
-  bool default_mode_ = false;
-
-  static const int kMaxStringLength = 1024;
-  static const int kKiloUnit = 1000;
-
-  static HWResourceInfo *hw_resource_;
-};
-
-}  // namespace sdm
-
-#endif  // __HW_INFO_DRM_H__
diff --git a/sdm/libs/core/drm/hw_peripheral_drm.cpp b/sdm/libs/core/drm/hw_peripheral_drm.cpp
deleted file mode 100644
index 44c22e7..0000000
--- a/sdm/libs/core/drm/hw_peripheral_drm.cpp
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
-Copyright (c) 2017, The Linux Foundation. All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-    * Redistributions of source code must retain the above copyright
-      notice, this list of conditions and the following disclaimer.
-    * Redistributions in binary form must reproduce the above
-      copyright notice, this list of conditions and the following
-      disclaimer in the documentation and/or other materials provided
-      with the distribution.
-    * Neither the name of The Linux Foundation nor the names of its
-      contributors may be used to endorse or promote products derived
-      from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
-WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
-ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
-BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
-IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#include <utils/debug.h>
-
-#include "hw_peripheral_drm.h"
-
-#define __CLASS__ "HWPeripheralDRM"
-
-using sde_drm::DRMDisplayType;
-using sde_drm::DRMOps;
-using sde_drm::DRMPowerMode;
-
-namespace sdm {
-
-HWPeripheralDRM::HWPeripheralDRM(BufferSyncHandler *buffer_sync_handler,
-                                 BufferAllocator *buffer_allocator,
-                                 HWInfoInterface *hw_info_intf)
-  : HWDeviceDRM(buffer_sync_handler, buffer_allocator, hw_info_intf) {
-  disp_type_ = DRMDisplayType::PERIPHERAL;
-  device_name_ = "Peripheral Display";
-}
-
-DisplayError HWPeripheralDRM::Init() {
-  DisplayError ret = HWDeviceDRM::Init();
-  if (ret != kErrorNone) {
-    DLOGE("Init failed for %s", device_name_);
-    return ret;
-  }
-
-  scalar_data_.resize(hw_resource_.hw_dest_scalar_info.count);
-
-  return kErrorNone;
-}
-
-DisplayError HWPeripheralDRM::Validate(HWLayers *hw_layers) {
-  HWLayersInfo &hw_layer_info = hw_layers->info;
-  SetDestScalarData(hw_layer_info);
-
-  return HWDeviceDRM::Validate(hw_layers);
-}
-
-DisplayError HWPeripheralDRM::Commit(HWLayers *hw_layers) {
-  HWLayersInfo &hw_layer_info = hw_layers->info;
-  SetDestScalarData(hw_layer_info);
-
-  return HWDeviceDRM::Commit(hw_layers);
-}
-
-void HWPeripheralDRM::ResetDisplayParams() {
-  sde_dest_scalar_data_ = {};
-  for (uint32_t j = 0; j < scalar_data_.size(); j++) {
-    scalar_data_[j] = {};
-  }
-}
-
-void HWPeripheralDRM::SetDestScalarData(HWLayersInfo hw_layer_info) {
-  if (!hw_resource_.hw_dest_scalar_info.count) {
-    return;
-  }
-
-  uint32_t index = 0;
-  for (uint32_t i = 0; i < hw_resource_.hw_dest_scalar_info.count; i++) {
-    DestScaleInfoMap::iterator it = hw_layer_info.dest_scale_info_map.find(i);
-
-    if (it == hw_layer_info.dest_scale_info_map.end()) {
-      continue;
-    }
-
-    HWDestScaleInfo *dest_scale_info = it->second;
-    SDEScaler *scale = &scalar_data_[index];
-    hw_scale_->SetScaler(dest_scale_info->scale_data, scale);
-    sde_drm_dest_scaler_cfg *dest_scalar_data = &sde_dest_scalar_data_.ds_cfg[index];
-    dest_scalar_data->flags = 0;
-    if (scale->scaler_v2.enable) {
-      dest_scalar_data->flags |= SDE_DRM_DESTSCALER_ENABLE;
-    }
-    if (scale->scaler_v2.de.enable) {
-      dest_scalar_data->flags |= SDE_DRM_DESTSCALER_ENHANCER_UPDATE;
-    }
-    if (dest_scale_info->scale_update) {
-      dest_scalar_data->flags |= SDE_DRM_DESTSCALER_SCALE_UPDATE;
-    }
-    dest_scalar_data->index = i;
-    dest_scalar_data->lm_width = dest_scale_info->mixer_width;
-    dest_scalar_data->lm_height = dest_scale_info->mixer_height;
-    dest_scalar_data->scaler_cfg = reinterpret_cast<uint64_t>(&scale->scaler_v2);
-    if (hw_panel_info_.partial_update) {
-      dest_scalar_data->flags |= SDE_DRM_DESTSCALER_PU_ENABLE;
-    }
-    index++;
-  }
-  sde_dest_scalar_data_.num_dest_scaler = UINT32(hw_layer_info.dest_scale_info_map.size());
-  drm_atomic_intf_->Perform(DRMOps::CRTC_SET_DEST_SCALER_CONFIG, token_.crtc_id,
-                            reinterpret_cast<uint64_t>(&sde_dest_scalar_data_));
-}
-
-DisplayError HWPeripheralDRM::Flush() {
-  DisplayError err = HWDeviceDRM::Flush();
-  if (err != kErrorNone) {
-    return err;
-  }
-
-  ResetDisplayParams();
-  return kErrorNone;
-}
-
-
-}  // namespace sdm
diff --git a/sdm/libs/core/drm/hw_peripheral_drm.h b/sdm/libs/core/drm/hw_peripheral_drm.h
deleted file mode 100644
index e4b33cf..0000000
--- a/sdm/libs/core/drm/hw_peripheral_drm.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
-Copyright (c) 2017, The Linux Foundation. All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-    * Redistributions of source code must retain the above copyright
-      notice, this list of conditions and the following disclaimer.
-    * Redistributions in binary form must reproduce the above
-      copyright notice, this list of conditions and the following
-      disclaimer in the documentation and/or other materials provided
-      with the distribution.
-    * Neither the name of The Linux Foundation nor the names of its
-      contributors may be used to endorse or promote products derived
-      from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
-WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
-ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
-BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
-IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#ifndef __HW_PERIPHERAL_DRM_H__
-#define __HW_PERIPHERAL_DRM_H__
-
-#include <vector>
-#include "hw_device_drm.h"
-
-namespace sdm {
-
-class HWPeripheralDRM : public HWDeviceDRM {
- public:
-  explicit HWPeripheralDRM(BufferSyncHandler *buffer_sync_handler,
-                           BufferAllocator *buffer_allocator,
-                           HWInfoInterface *hw_info_intf);
-  virtual ~HWPeripheralDRM() {}
-
- protected:
-  virtual DisplayError Init();
-  virtual DisplayError Validate(HWLayers *hw_layers);
-  virtual DisplayError Commit(HWLayers *hw_layers);
-  virtual DisplayError Flush();
- private:
-  void SetDestScalarData(HWLayersInfo hw_layer_info);
-  void ResetDisplayParams();
-  sde_drm_dest_scaler_data sde_dest_scalar_data_ = {};
-  std::vector<SDEScaler> scalar_data_ = {};
-};
-
-}  // namespace sdm
-
-#endif  // __HW_PERIPHERAL_DRM_H__
diff --git a/sdm/libs/core/drm/hw_scale_drm.cpp b/sdm/libs/core/drm/hw_scale_drm.cpp
deleted file mode 100644
index b2f6d3b..0000000
--- a/sdm/libs/core/drm/hw_scale_drm.cpp
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
-* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without
-* modification, are permitted provided that the following conditions are
-* met:
-*     * Redistributions of source code must retain the above copyright
-*       notice, this list of conditions and the following disclaimer.
-*     * Redistributions in binary form must reproduce the above
-*       copyright notice, this list of conditions and the following
-*       disclaimer in the documentation and/or other materials provided
-*       with the distribution.
-*     * Neither the name of The Linux Foundation nor the names of its
-*       contributors may be used to endorse or promote products derived
-*       from this software without specific prior written permission.
-*
-* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
-* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
-* ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
-* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
-* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#include <stdio.h>
-#include <utils/debug.h>
-
-#include "hw_scale_drm.h"
-
-#define __CLASS__ "HWScaleDRM"
-
-namespace sdm {
-
-static uint32_t GetScalingFilter(ScalingFilterConfig filter_cfg) {
-  switch (filter_cfg) {
-    case kFilterEdgeDirected:
-      return FILTER_EDGE_DIRECTED_2D;
-    case kFilterCircular:
-      return FILTER_CIRCULAR_2D;
-    case kFilterSeparable:
-      return FILTER_SEPARABLE_1D;
-    case kFilterBilinear:
-      return FILTER_BILINEAR;
-    default:
-      DLOGE("Invalid Scaling Filter");
-      return kFilterMax;
-  }
-}
-
-static uint32_t GetAlphaInterpolation(HWAlphaInterpolation alpha_filter_cfg) {
-  switch (alpha_filter_cfg) {
-    case kInterpolationPixelRepeat:
-      return FILTER_ALPHA_DROP_REPEAT;
-    case kInterpolationBilinear:
-      return FILTER_ALPHA_BILINEAR;
-    case kInterpolation2D:
-      return FILTER_ALPHA_2D;
-    default:
-      DLOGE("Invalid Alpha Interpolation");
-      return kInterpolationMax;
-  }
-}
-
-void HWScaleDRM::SetScaler(const HWScaleData &scale_data, SDEScaler *scaler) {
-  if (version_ == Version::V2) {
-    SetScalerV2(scale_data, &scaler->scaler_v2);
-  }
-}
-
-void HWScaleDRM::SetScalerV2(const HWScaleData &scale_data, sde_drm_scaler_v2 *scaler) {
-  if (!scale_data.enable.scale && !scale_data.enable.direction_detection &&
-      !scale_data.enable.detail_enhance) {
-    scaler->enable = 0;
-    scaler->dir_en = 0;
-    scaler->de.enable = 0;
-    return;
-  }
-
-  scaler->enable = scale_data.enable.scale | scale_data.enable.direction_detection |
-                   scale_data.detail_enhance.enable;
-
-  scaler->dir_en = scale_data.enable.direction_detection;
-  scaler->de.enable = scale_data.detail_enhance.enable;
-
-  for (int i = 0; i < SDE_MAX_PLANES; i++) {
-    const HWPlane &plane = scale_data.plane[i];
-    scaler->init_phase_x[i] = plane.init_phase_x;
-    scaler->phase_step_x[i] = plane.phase_step_x;
-    scaler->init_phase_y[i] = plane.init_phase_y;
-    scaler->phase_step_y[i] = plane.phase_step_y;
-
-    // TODO(user): Remove right, bottom from HWPlane and rename to LR, TB similar to qseed3
-    // Also remove roi_width which is unused.
-    scaler->pe.num_ext_pxls_lr[i] = plane.left.extension;
-    scaler->pe.num_ext_pxls_tb[i] = plane.top.extension;
-
-    scaler->pe.left_ftch[i] = plane.left.overfetch;
-    scaler->pe.top_ftch[i] = plane.top.overfetch;
-    scaler->pe.right_ftch[i] = plane.right.overfetch;
-    scaler->pe.btm_ftch[i] = plane.bottom.overfetch;
-
-    scaler->pe.left_rpt[i] = plane.left.repeat;
-    scaler->pe.top_rpt[i] = plane.top.repeat;
-    scaler->pe.right_rpt[i] = plane.right.repeat;
-    scaler->pe.btm_rpt[i] = plane.bottom.repeat;
-
-    scaler->preload_x[i] = UINT32(plane.preload_x);
-    scaler->preload_y[i] = UINT32(plane.preload_y);
-
-    scaler->src_width[i] = plane.src_width;
-    scaler->src_height[i] = plane.src_height;
-  }
-
-  scaler->dst_width = scale_data.dst_width;
-  scaler->dst_height = scale_data.dst_height;
-
-  scaler->y_rgb_filter_cfg = GetScalingFilter(scale_data.y_rgb_filter_cfg);
-  scaler->uv_filter_cfg = GetScalingFilter(scale_data.uv_filter_cfg);
-  scaler->alpha_filter_cfg = GetAlphaInterpolation(scale_data.alpha_filter_cfg);
-  scaler->blend_cfg = scale_data.blend_cfg;
-
-  scaler->lut_flag = (scale_data.lut_flag.lut_swap ? SCALER_LUT_SWAP : 0) |
-                     (scale_data.lut_flag.lut_dir_wr ? SCALER_LUT_DIR_WR : 0) |
-                     (scale_data.lut_flag.lut_y_cir_wr ? SCALER_LUT_Y_CIR_WR : 0) |
-                     (scale_data.lut_flag.lut_uv_cir_wr ? SCALER_LUT_UV_CIR_WR : 0) |
-                     (scale_data.lut_flag.lut_y_sep_wr ? SCALER_LUT_Y_SEP_WR : 0) |
-                     (scale_data.lut_flag.lut_uv_sep_wr ? SCALER_LUT_UV_SEP_WR : 0);
-
-  scaler->dir_lut_idx = scale_data.dir_lut_idx;
-  scaler->y_rgb_cir_lut_idx = scale_data.y_rgb_cir_lut_idx;
-  scaler->uv_cir_lut_idx = scale_data.uv_cir_lut_idx;
-  scaler->y_rgb_sep_lut_idx = scale_data.y_rgb_sep_lut_idx;
-  scaler->uv_sep_lut_idx = scale_data.uv_sep_lut_idx;
-
-  if (scaler->de.enable) {
-    sde_drm_de_v1 *det_enhance = &scaler->de;
-    det_enhance->sharpen_level1 = scale_data.detail_enhance.sharpen_level1;
-    det_enhance->sharpen_level2 = scale_data.detail_enhance.sharpen_level2;
-    det_enhance->clip = scale_data.detail_enhance.clip;
-    det_enhance->limit = scale_data.detail_enhance.limit;
-    det_enhance->thr_quiet = scale_data.detail_enhance.thr_quiet;
-    det_enhance->thr_dieout = scale_data.detail_enhance.thr_dieout;
-    det_enhance->thr_low = scale_data.detail_enhance.thr_low;
-    det_enhance->thr_high = scale_data.detail_enhance.thr_high;
-    det_enhance->prec_shift = scale_data.detail_enhance.prec_shift;
-
-    for (int i = 0; i < SDE_MAX_DE_CURVES; i++) {
-      det_enhance->adjust_a[i] = scale_data.detail_enhance.adjust_a[i];
-      det_enhance->adjust_b[i] = scale_data.detail_enhance.adjust_b[i];
-      det_enhance->adjust_c[i] = scale_data.detail_enhance.adjust_c[i];
-    }
-  }
-
-  return;
-}
-
-}  // namespace sdm
diff --git a/sdm/libs/core/drm/hw_scale_drm.h b/sdm/libs/core/drm/hw_scale_drm.h
deleted file mode 100644
index 6f96eca..0000000
--- a/sdm/libs/core/drm/hw_scale_drm.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
-* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without
-* modification, are permitted provided that the following conditions are
-* met:
-*     * Redistributions of source code must retain the above copyright
-*       notice, this list of conditions and the following disclaimer.
-*     * Redistributions in binary form must reproduce the above
-*       copyright notice, this list of conditions and the following
-*       disclaimer in the documentation and/or other materials provided
-*       with the distribution.
-*     * Neither the name of The Linux Foundation nor the names of its
-*       contributors may be used to endorse or promote products derived
-*       from this software without specific prior written permission.
-*
-* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
-* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
-* ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
-* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
-* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#ifndef __HW_SCALE_DRM_H__
-#define __HW_SCALE_DRM_H__
-
-#include <stdint.h>
-#include <stdlib.h>
-#include <drm.h>
-// The 3 headers above are a workaround to prevent kernel drm.h from being used that has the
-// "virtual" keyword used for a variable. In future replace libdrm version drm.h with kernel
-// version drm/drm.h
-#include <drm/sde_drm.h>
-#include <private/hw_info_types.h>
-
-namespace sdm {
-
-struct SDEScaler {
-  struct sde_drm_scaler_v2 scaler_v2 = {};
-  // More here, maybe in a union
-};
-
-class HWScaleDRM {
- public:
-  enum class Version { V2 };
-  explicit HWScaleDRM(Version v) : version_(v) {}
-  void SetScaler(const HWScaleData &scale, SDEScaler *scaler);
-
- private:
-  void SetScalerV2(const HWScaleData &scale, sde_drm_scaler_v2 *scaler_v2);
-  Version version_ = Version::V2;
-};
-
-}  // namespace sdm
-
-#endif  // __HW_SCALE_DRM_H__
diff --git a/sdm/libs/core/drm/hw_tv_drm.cpp b/sdm/libs/core/drm/hw_tv_drm.cpp
deleted file mode 100644
index adf1f1e..0000000
--- a/sdm/libs/core/drm/hw_tv_drm.cpp
+++ /dev/null
@@ -1,321 +0,0 @@
-/*
-* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without
-* modification, are permitted provided that the following conditions are
-* met:
-*     * Redistributions of source code must retain the above copyright
-*       notice, this list of conditions and the following disclaimer.
-*     * Redistributions in binary form must reproduce the above
-*       copyright notice, this list of conditions and the following
-*       disclaimer in the documentation and/or other materials provided
-*       with the distribution.
-*     * Neither the name of The Linux Foundation nor the names of its
-*       contributors may be used to endorse or promote products derived
-*       from this software without specific prior written permission.
-*
-* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
-* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
-* ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
-* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
-* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#include "hw_tv_drm.h"
-#include <sys/time.h>
-#include <utils/debug.h>
-#include <utils/sys.h>
-#include <utils/formats.h>
-#include <drm_lib_loader.h>
-#include <drm_master.h>
-#include <drm_res_mgr.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <string>
-#include <vector>
-#include <map>
-#include <utility>
-
-#ifndef HDR_EOTF_SMTPE_ST2084
-#define HDR_EOTF_SMTPE_ST2084 2
-#endif
-#ifndef HDR_EOTF_HLG
-#define HDR_EOTF_HLG 3
-#endif
-
-#define __CLASS__ "HWTVDRM"
-
-#define HDR_DISABLE 0
-#define HDR_ENABLE 1
-#define MIN_HDR_RESET_WAITTIME 2
-
-using drm_utils::DRMMaster;
-using drm_utils::DRMResMgr;
-using drm_utils::DRMLibLoader;
-using drm_utils::DRMBuffer;
-using sde_drm::GetDRMManager;
-using sde_drm::DestroyDRMManager;
-using sde_drm::DRMDisplayType;
-using sde_drm::DRMDisplayToken;
-using sde_drm::DRMConnectorInfo;
-using sde_drm::DRMPPFeatureInfo;
-using sde_drm::DRMOps;
-using sde_drm::DRMTopology;
-using sde_drm::DRMPowerMode;
-
-namespace sdm {
-
-static int32_t GetEOTF(const GammaTransfer &transfer) {
-  int32_t hdr_transfer = -1;
-
-  switch (transfer) {
-  case Transfer_SMPTE_ST2084:
-    hdr_transfer = HDR_EOTF_SMTPE_ST2084;
-    break;
-  case Transfer_HLG:
-    hdr_transfer = HDR_EOTF_HLG;
-    break;
-  default:
-    DLOGW("Unknown Transfer: %d", transfer);
-  }
-
-  return hdr_transfer;
-}
-
-HWTVDRM::HWTVDRM(BufferSyncHandler *buffer_sync_handler, BufferAllocator *buffer_allocator,
-                     HWInfoInterface *hw_info_intf)
-  : HWDeviceDRM(buffer_sync_handler, buffer_allocator, hw_info_intf) {
-  disp_type_ = DRMDisplayType::TV;
-  device_name_ = "TV Display Device";
-}
-
-DisplayError HWTVDRM::SetDisplayAttributes(uint32_t index) {
-  if (index >= connector_info_.modes.size()) {
-    DLOGE("Invalid mode index %d mode size %d", index, UINT32(connector_info_.modes.size()));
-    return kErrorNotSupported;
-  }
-
-  current_mode_index_ = index;
-  PopulateHWPanelInfo();
-  UpdateMixerAttributes();
-
-  DLOGI("Display attributes[%d]: WxH: %dx%d, DPI: %fx%f, FPS: %d, LM_SPLIT: %d, V_BACK_PORCH: %d," \
-        " V_FRONT_PORCH: %d, V_PULSE_WIDTH: %d, V_TOTAL: %d, H_TOTAL: %d, CLK: %dKHZ, TOPOLOGY: %d",
-        index, display_attributes_[index].x_pixels, display_attributes_[index].y_pixels,
-        display_attributes_[index].x_dpi, display_attributes_[index].y_dpi,
-        display_attributes_[index].fps, display_attributes_[index].is_device_split,
-        display_attributes_[index].v_back_porch, display_attributes_[index].v_front_porch,
-        display_attributes_[index].v_pulse_width, display_attributes_[index].v_total,
-        display_attributes_[index].h_total, display_attributes_[index].clock_khz,
-        display_attributes_[index].topology);
-
-  return kErrorNone;
-}
-
-DisplayError HWTVDRM::GetConfigIndex(char *mode, uint32_t *index) {
-  uint32_t width = 0, height = 0, fps = 0, format = 0;
-  std::string str(mode);
-
-  // mode should be in width:height:fps:format
-  // TODO(user): it is not fully robust, User needs to provide in above format only
-  if (str.length() != 0) {
-    width = UINT32(stoi(str));
-    height = UINT32(stoi(str.substr(str.find(':') + 1)));
-    std::string str3 = str.substr(str.find(':') + 1);
-    fps = UINT32(stoi(str3.substr(str3.find(':')  + 1)));
-    std::string str4 = str3.substr(str3.find(':') + 1);
-    format = UINT32(stoi(str4.substr(str4.find(':') + 1)));
-  }
-
-  for (size_t idex = 0; idex < connector_info_.modes.size(); idex ++) {
-    if ((height == connector_info_.modes[idex].mode.vdisplay) &&
-        (width == connector_info_.modes[idex].mode.hdisplay) &&
-        (fps == connector_info_.modes[idex].mode.vrefresh)) {
-      if ((format >> 1) & (connector_info_.modes[idex].mode.flags >> kBitYUV)) {
-        *index = UINT32(idex);
-        break;
-      }
-
-      if (format & (connector_info_.modes[idex].mode.flags >> kBitRGB)) {
-        *index = UINT32(idex);
-        break;
-      }
-    }
-  }
-
-  return kErrorNone;
-}
-
-DisplayError HWTVDRM::PowerOff() {
-  DTRACE_SCOPED();
-
-  int ret = drm_atomic_intf_->Commit(true /* synchronous */, false /* retain_planes*/);
-  if (ret) {
-    DLOGE("%s failed with error %d", __FUNCTION__, ret);
-    return kErrorHardware;
-  }
-
-  return kErrorNone;
-}
-
-DisplayError HWTVDRM::Doze(int *release_fence) {
-  return kErrorNone;
-}
-
-DisplayError HWTVDRM::DozeSuspend(int *release_fence) {
-  return kErrorNone;
-}
-
-DisplayError HWTVDRM::Standby() {
-  return kErrorNone;
-}
-
-void HWTVDRM::PopulateHWPanelInfo() {
-  hw_panel_info_ = {};
-
-  HWDeviceDRM::PopulateHWPanelInfo();
-  hw_panel_info_.hdr_enabled = connector_info_.ext_hdr_prop.hdr_supported;
-  hw_panel_info_.hdr_metadata_type_one = connector_info_.ext_hdr_prop.hdr_metadata_type_one;
-  hw_panel_info_.hdr_eotf = connector_info_.ext_hdr_prop.hdr_eotf;
-  hw_panel_info_.peak_luminance = connector_info_.ext_hdr_prop.hdr_max_luminance;
-  hw_panel_info_.average_luminance = connector_info_.ext_hdr_prop.hdr_avg_luminance;
-  hw_panel_info_.blackness_level = connector_info_.ext_hdr_prop.hdr_min_luminance;
-  DLOGI("TV Panel: %s, type_one = %d, eotf = %d, luminance[max = %d, min = %d, avg = %d]",
-        hw_panel_info_.hdr_enabled ? "HDR" : "Non-HDR", hw_panel_info_.hdr_metadata_type_one,
-        hw_panel_info_.hdr_eotf, hw_panel_info_.peak_luminance, hw_panel_info_.blackness_level,
-        hw_panel_info_.average_luminance);
-}
-
-DisplayError HWTVDRM::Commit(HWLayers *hw_layers) {
-  DisplayError error = UpdateHDRMetaData(hw_layers);
-  if (error != kErrorNone) {
-    return error;
-  }
-  return HWDeviceDRM::Commit(hw_layers);
-}
-
-DisplayError HWTVDRM::UpdateHDRMetaData(HWLayers *hw_layers) {
-  static struct timeval hdr_reset_start, hdr_reset_end;
-  static bool reset_hdr_flag = false;
-  const HWHDRLayerInfo &hdr_layer_info = hw_layers->info.hdr_layer_info;
-  if (!hw_panel_info_.hdr_enabled) {
-    return kErrorNone;
-  }
-
-  DisplayError error = kErrorNone;
-
-  Layer hdr_layer = {};
-  if (hdr_layer_info.operation == HWHDRLayerInfo::kSet && hdr_layer_info.layer_index > -1) {
-    hdr_layer = *(hw_layers->info.stack->layers.at(UINT32(hdr_layer_info.layer_index)));
-  }
-
-  const LayerBuffer *layer_buffer = &hdr_layer.input_buffer;
-  const MasteringDisplay &mastering_display = layer_buffer->color_metadata.masteringDisplayInfo;
-  const ContentLightLevel &light_level = layer_buffer->color_metadata.contentLightLevel;
-  const Primaries &primaries = mastering_display.primaries;
-
-  if (hdr_layer_info.operation == HWHDRLayerInfo::kSet) {
-    // Reset reset_hdr_flag to handle where there are two consecutive HDR video playbacks with not
-    // enough non-HDR frames in between to reset the HDR metadata.
-    reset_hdr_flag = false;
-
-    int32_t eotf = GetEOTF(layer_buffer->color_metadata.transfer);
-    hdr_metadata_.hdr_supported = 1;
-    hdr_metadata_.hdr_state = HDR_ENABLE;
-    hdr_metadata_.eotf = (eotf < 0) ? 0 : UINT32(eotf);
-    hdr_metadata_.white_point_x = primaries.whitePoint[0];
-    hdr_metadata_.white_point_y = primaries.whitePoint[1];
-    hdr_metadata_.display_primaries_x[0] = primaries.rgbPrimaries[0][0];
-    hdr_metadata_.display_primaries_y[0] = primaries.rgbPrimaries[0][1];
-    hdr_metadata_.display_primaries_x[1] = primaries.rgbPrimaries[1][0];
-    hdr_metadata_.display_primaries_y[1] = primaries.rgbPrimaries[1][1];
-    hdr_metadata_.display_primaries_x[2] = primaries.rgbPrimaries[2][0];
-    hdr_metadata_.display_primaries_y[2] = primaries.rgbPrimaries[2][1];
-    hdr_metadata_.min_luminance = mastering_display.minDisplayLuminance;
-    hdr_metadata_.max_luminance = mastering_display.maxDisplayLuminance/10000;
-    hdr_metadata_.max_content_light_level = light_level.maxContentLightLevel;
-    hdr_metadata_.max_average_light_level = light_level.minPicAverageLightLevel;
-
-    drm_atomic_intf_->Perform(DRMOps::CONNECTOR_SET_HDR_METADATA, token_.conn_id, &hdr_metadata_);
-    DumpHDRMetaData(hdr_layer_info.operation);
-  } else if (hdr_layer_info.operation == HWHDRLayerInfo::kReset) {
-    memset(&hdr_metadata_, 0, sizeof(hdr_metadata_));
-    hdr_metadata_.hdr_supported = 1;
-    hdr_metadata_.hdr_state = HDR_ENABLE;
-    reset_hdr_flag = true;
-    gettimeofday(&hdr_reset_start, NULL);
-
-    drm_atomic_intf_->Perform(DRMOps::CONNECTOR_SET_HDR_METADATA, token_.conn_id, &hdr_metadata_);
-    DumpHDRMetaData(hdr_layer_info.operation);
-  } else if (hdr_layer_info.operation == HWHDRLayerInfo::kNoOp) {
-    // TODO(user): This case handles the state transition from HDR_ENABLED to HDR_DISABLED.
-    // As per HDMI spec requirement, we need to send zero metadata for atleast 2 sec after end of
-    // playback. This timer calculates the 2 sec window after playback stops to stop sending HDR
-    // metadata. This will be replaced with an idle timer implementation in the future.
-    if (reset_hdr_flag) {
-      gettimeofday(&hdr_reset_end, NULL);
-      float hdr_reset_time_start = ((hdr_reset_start.tv_sec*1000) + (hdr_reset_start.tv_usec/1000));
-      float hdr_reset_time_end = ((hdr_reset_end.tv_sec*1000) + (hdr_reset_end.tv_usec/1000));
-
-      if (((hdr_reset_time_end-hdr_reset_time_start)/1000) >= MIN_HDR_RESET_WAITTIME) {
-        memset(&hdr_metadata_, 0, sizeof(hdr_metadata_));
-        hdr_metadata_.hdr_supported = 1;
-        hdr_metadata_.hdr_state = HDR_DISABLE;
-        reset_hdr_flag = false;
-
-        drm_atomic_intf_->Perform(DRMOps::CONNECTOR_SET_HDR_METADATA, token_.conn_id,
-                                  &hdr_metadata_);
-      }
-    }
-  }
-
-  return error;
-}
-
-void HWTVDRM::DumpHDRMetaData(HWHDRLayerInfo::HDROperation operation) {
-  DLOGI("Operation = %d, HDR Metadata: MaxDisplayLuminance = %d MinDisplayLuminance = %d\n"
-        "MaxContentLightLevel = %d MaxAverageLightLevel = %d Red_x = %d Red_y = %d Green_x = %d\n"
-        "Green_y = %d Blue_x = %d Blue_y = %d WhitePoint_x = %d WhitePoint_y = %d EOTF = %d\n",
-        operation, hdr_metadata_.max_luminance, hdr_metadata_.min_luminance,
-        hdr_metadata_.max_content_light_level, hdr_metadata_.max_average_light_level,
-        hdr_metadata_.display_primaries_x[0], hdr_metadata_.display_primaries_y[0],
-        hdr_metadata_.display_primaries_x[1], hdr_metadata_.display_primaries_y[1],
-        hdr_metadata_.display_primaries_x[2], hdr_metadata_.display_primaries_y[2],
-        hdr_metadata_.white_point_x, hdr_metadata_.white_point_y, hdr_metadata_.eotf);
-}
-
-DisplayError HWTVDRM::OnMinHdcpEncryptionLevelChange(uint32_t min_enc_level) {
-  DisplayError error = kErrorNone;
-  int fd = -1;
-  char data[kMaxStringLength] = {'\0'};
-
-  snprintf(data, sizeof(data), "/sys/devices/virtual/hdcp/msm_hdcp/min_level_change");
-
-  fd = Sys::open_(data, O_WRONLY);
-  if (fd < 0) {
-    DLOGE("File '%s' could not be opened. errno = %d, desc = %s", data, errno, strerror(errno));
-    return kErrorHardware;
-  }
-
-  snprintf(data, sizeof(data), "%d", min_enc_level);
-
-  ssize_t err = Sys::pwrite_(fd, data, strlen(data), 0);
-  if (err <= 0) {
-    DLOGE("Write failed, Error = %s", strerror(errno));
-    error = kErrorHardware;
-  }
-
-  Sys::close_(fd);
-
-  return error;
-}
-
-}  // namespace sdm
-
diff --git a/sdm/libs/core/drm/hw_tv_drm.h b/sdm/libs/core/drm/hw_tv_drm.h
deleted file mode 100644
index 3e592f9..0000000
--- a/sdm/libs/core/drm/hw_tv_drm.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
-* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without modification, are permitted
-* provided that the following conditions are met:
-*    * Redistributions of source code must retain the above copyright notice, this list of
-*      conditions and the following disclaimer.
-*    * Redistributions in binary form must reproduce the above copyright notice, this list of
-*      conditions and the following disclaimer in the documentation and/or other materials provided
-*      with the distribution.
-*    * Neither the name of The Linux Foundation nor the names of its contributors may be used to
-*      endorse or promote products derived from this software without specific prior written
-*      permission.
-*
-* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-* NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
-* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
-* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
-* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#ifndef __HW_TV_DRM_H__
-#define __HW_TV_DRM_H__
-
-#include <map>
-#include <vector>
-
-#include "hw_device_drm.h"
-
-namespace sdm {
-
-using std::vector;
-
-class HWTVDRM : public HWDeviceDRM {
- public:
-  explicit HWTVDRM(BufferSyncHandler *buffer_sync_handler, BufferAllocator *buffer_allocator,
-                     HWInfoInterface *hw_info_intf);
-
- protected:
-  virtual DisplayError SetDisplayAttributes(uint32_t index);
-  virtual DisplayError GetConfigIndex(char *mode, uint32_t *index);
-  virtual DisplayError PowerOff();
-  virtual DisplayError Doze(int *release_fence);
-  virtual DisplayError DozeSuspend(int *release_fence);
-  virtual DisplayError Standby();
-  virtual DisplayError Commit(HWLayers *hw_layers);
-  virtual void PopulateHWPanelInfo();
-  virtual DisplayError OnMinHdcpEncryptionLevelChange(uint32_t min_enc_level);
-
- private:
-  DisplayError UpdateHDRMetaData(HWLayers *hw_layers);
-  void DumpHDRMetaData(HWHDRLayerInfo::HDROperation operation);
-
-  static const int kBitRGB  = 20;
-  static const int kBitYUV  = 21;
-  drm_msm_ext_hdr_metadata hdr_metadata_ = {};
-};
-
-}  // namespace sdm
-
-#endif  // __HW_TV_DRM_H__
-
diff --git a/sdm/libs/core/drm/hw_virtual_drm.cpp b/sdm/libs/core/drm/hw_virtual_drm.cpp
deleted file mode 100644
index 6f7b12b..0000000
--- a/sdm/libs/core/drm/hw_virtual_drm.cpp
+++ /dev/null
@@ -1,226 +0,0 @@
-/*
-Copyright (c) 2017, The Linux Foundation. All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-    * Redistributions of source code must retain the above copyright
-      notice, this list of conditions and the following disclaimer.
-    * Redistributions in binary form must reproduce the above
-      copyright notice, this list of conditions and the following
-      disclaimer in the documentation and/or other materials provided
-      with the distribution.
-    * Neither the name of The Linux Foundation nor the names of its
-      contributors may be used to endorse or promote products derived
-      from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
-WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
-ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
-BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
-IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#include <stdio.h>
-#include <ctype.h>
-#include <drm_logger.h>
-#include <utils/debug.h>
-#include <algorithm>
-#include <vector>
-#include "hw_device_drm.h"
-#include "hw_virtual_drm.h"
-#include "hw_info_drm.h"
-
-#define __CLASS__ "HWVirtualDRM"
-
-using std::vector;
-
-using sde_drm::DRMDisplayType;
-using sde_drm::DRMConnectorInfo;
-using sde_drm::DRMRect;
-using sde_drm::DRMOps;
-using sde_drm::DRMPowerMode;
-using sde_drm::DRMSecureMode;
-
-namespace sdm {
-
-HWVirtualDRM::HWVirtualDRM(BufferSyncHandler *buffer_sync_handler,
-                           BufferAllocator *buffer_allocator,
-                           HWInfoInterface *hw_info_intf)
-                           : HWDeviceDRM(buffer_sync_handler, buffer_allocator, hw_info_intf) {
-  HWDeviceDRM::device_name_ = "Virtual Display Device";
-  HWDeviceDRM::disp_type_ = DRMDisplayType::VIRTUAL;
-}
-
-void HWVirtualDRM::ConfigureWbConnectorFbId(uint32_t fb_id) {
-  drm_atomic_intf_->Perform(DRMOps::CONNECTOR_SET_OUTPUT_FB_ID, token_.conn_id, fb_id);
-  return;
-}
-
-void HWVirtualDRM::ConfigureWbConnectorDestRect() {
-  DRMRect dst = {};
-  dst.left = 0;
-  dst.bottom = display_attributes_[current_mode_index_].y_pixels;
-  dst.top = 0;
-  dst.right = display_attributes_[current_mode_index_].x_pixels;
-  drm_atomic_intf_->Perform(DRMOps::CONNECTOR_SET_OUTPUT_RECT, token_.conn_id, dst);
-  return;
-}
-
-void HWVirtualDRM::ConfigureWbConnectorSecureMode(bool secure) {
-  DRMSecureMode secure_mode = secure ? DRMSecureMode::SECURE : DRMSecureMode::NON_SECURE;
-  drm_atomic_intf_->Perform(DRMOps::CONNECTOR_SET_FB_SECURE_MODE, token_.conn_id, secure_mode);
-}
-
-void HWVirtualDRM::InitializeConfigs() {
-  display_attributes_.resize(connector_info_.modes.size());
-  for (uint32_t i = 0; i < connector_info_.modes.size(); i++) {
-    PopulateDisplayAttributes(i);
-  }
-}
-
-DisplayError HWVirtualDRM::SetWbConfigs(const HWDisplayAttributes &display_attributes) {
-  drmModeModeInfo mode = {};
-  vector<drmModeModeInfo> modes;
-
-  mode.hdisplay = mode.hsync_start = mode.hsync_end = mode.htotal =
-                                       UINT16(display_attributes.x_pixels);
-  mode.vdisplay = mode.vsync_start = mode.vsync_end = mode.vtotal =
-                                       UINT16(display_attributes.y_pixels);
-  mode.vrefresh = UINT32(display_attributes.fps);
-  mode.clock = (mode.htotal * mode.vtotal * mode.vrefresh) / 1000;
-  snprintf(mode.name, DRM_DISPLAY_MODE_LEN, "%dx%d", mode.hdisplay, mode.vdisplay);
-  modes.push_back(mode);
-  for (auto &item : connector_info_.modes) {
-    modes.push_back(item.mode);
-  }
-
-  // Inform the updated mode list to the driver
-  struct sde_drm_wb_cfg wb_cfg = {};
-  wb_cfg.connector_id = token_.conn_id;
-  wb_cfg.flags = SDE_DRM_WB_CFG_FLAGS_CONNECTED;
-  wb_cfg.count_modes = UINT32(modes.size());
-  wb_cfg.modes = (uint64_t)modes.data();
-
-  int ret = -EINVAL;
-#ifdef DRM_IOCTL_SDE_WB_CONFIG
-  ret = drmIoctl(dev_fd_, DRM_IOCTL_SDE_WB_CONFIG, &wb_cfg);
-#endif
-  if (ret) {
-    DLOGE("Dump WBConfig: mode_count %d flags %x", wb_cfg.count_modes, wb_cfg.flags);
-    DumpConnectorModeInfo();
-    return kErrorHardware;
-  }
-
-  return kErrorNone;
-}
-
-void HWVirtualDRM::DumpConnectorModeInfo() {
-  for (uint32_t i = 0; i < (uint32_t)connector_info_.modes.size(); i++) {
-    DLOGI("Mode[%d] Name:%s vref:%d hdisp:%d hsync_s:%d hsync_e:%d htotal:%d " \
-          "vdisp:%d vsync_s:%d vsync_e:%d vtotal:%d\n", i, connector_info_.modes[i].mode.name,
-          connector_info_.modes[i].mode.vrefresh, connector_info_.modes[i].mode.hdisplay,
-          connector_info_.modes[i].mode.hsync_start, connector_info_.modes[i].mode.hsync_end,
-          connector_info_.modes[i].mode.htotal, connector_info_.modes[i].mode.vdisplay,
-          connector_info_.modes[i].mode.vsync_start, connector_info_.modes[i].mode.vsync_end,
-          connector_info_.modes[i].mode.vtotal);
-  }
-}
-
-DisplayError HWVirtualDRM::Commit(HWLayers *hw_layers) {
-  LayerBuffer *output_buffer = hw_layers->info.stack->output_buffer;
-  DisplayError err = kErrorNone;
-
-  registry_.Register(hw_layers);
-  registry_.MapBufferToFbId(output_buffer);
-  uint32_t fb_id = registry_.GetFbId(output_buffer->planes[0].fd);
-
-  ConfigureWbConnectorFbId(fb_id);
-  ConfigureWbConnectorDestRect();
-  ConfigureWbConnectorSecureMode(output_buffer->flags.secure);
-
-  err = HWDeviceDRM::AtomicCommit(hw_layers);
-  if (err != kErrorNone) {
-    DLOGE("Atomic commit failed for crtc_id %d conn_id %d", token_.crtc_id, token_.conn_id);
-  }
-
-  registry_.Next();
-  registry_.Unregister();
-
-  return(err);
-}
-
-DisplayError HWVirtualDRM::Validate(HWLayers *hw_layers) {
-  LayerBuffer *output_buffer = hw_layers->info.stack->output_buffer;
-
-  registry_.MapBufferToFbId(output_buffer);
-  uint32_t fb_id = registry_.GetFbId(output_buffer->planes[0].fd);
-
-  ConfigureWbConnectorFbId(fb_id);
-  ConfigureWbConnectorDestRect();
-  ConfigureWbConnectorSecureMode(output_buffer->flags.secure);
-
-  return HWDeviceDRM::Validate(hw_layers);
-}
-
-DisplayError HWVirtualDRM::SetDisplayAttributes(const HWDisplayAttributes &display_attributes) {
-  if (display_attributes.x_pixels == 0 || display_attributes.y_pixels == 0) {
-    return kErrorParameters;
-  }
-
-  int mode_index = -1;
-  GetModeIndex(display_attributes, &mode_index);
-
-  if (mode_index < 0) {
-    DisplayError error = SetWbConfigs(display_attributes);
-    if (error != kErrorNone) {
-      return error;
-    }
-  }
-
-  // Reload connector info for updated info
-  drm_mgr_intf_->GetConnectorInfo(token_.conn_id, &connector_info_);
-  GetModeIndex(display_attributes, &mode_index);
-
-  if (mode_index < 0) {
-    DLOGE("Mode not found for resolution %dx%d fps %d", display_attributes.x_pixels,
-          display_attributes.y_pixels, UINT32(display_attributes.fps));
-    DumpConnectorModeInfo();
-    return kErrorNotSupported;
-  }
-
-  current_mode_index_ = UINT32(mode_index);
-  InitializeConfigs();
-  PopulateHWPanelInfo();
-  UpdateMixerAttributes();
-
-  DLOGI("New WB Resolution: %dx%d cur_mode_index %d", display_attributes.x_pixels,
-        display_attributes.y_pixels, current_mode_index_);
-
-  return kErrorNone;
-}
-
-DisplayError HWVirtualDRM::GetPPFeaturesVersion(PPFeatureVersion *vers) {
-  return kErrorNone;
-}
-
-void HWVirtualDRM::GetModeIndex(const HWDisplayAttributes &display_attributes, int *mode_index) {
-  *mode_index = -1;
-  for (uint32_t i = 0; i < connector_info_.modes.size(); i++) {
-    if (display_attributes.x_pixels == connector_info_.modes[i].mode.hdisplay &&
-        display_attributes.y_pixels == connector_info_.modes[i].mode.vdisplay &&
-        display_attributes.fps == connector_info_.modes[i].mode.vrefresh) {
-      *mode_index = INT32(i);
-      break;
-    }
-  }
-}
-
-}  // namespace sdm
-
diff --git a/sdm/libs/core/drm/hw_virtual_drm.h b/sdm/libs/core/drm/hw_virtual_drm.h
deleted file mode 100644
index 257e08a..0000000
--- a/sdm/libs/core/drm/hw_virtual_drm.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
-Copyright (c) 2017, The Linux Foundation. All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-    * Redistributions of source code must retain the above copyright
-      notice, this list of conditions and the following disclaimer.
-    * Redistributions in binary form must reproduce the above
-      copyright notice, this list of conditions and the following
-      disclaimer in the documentation and/or other materials provided
-      with the distribution.
-    * Neither the name of The Linux Foundation nor the names of its
-      contributors may be used to endorse or promote products derived
-      from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
-WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
-ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
-BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
-IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#ifndef __HW_VIRTUAL_DRM_H__
-#define __HW_VIRTUAL_DRM_H__
-
-#include "hw_device_drm.h"
-#include <drm/msm_drm.h>
-#include <drm/sde_drm.h>
-#include <vector>
-
-namespace sdm {
-
-class HWVirtualDRM : public HWDeviceDRM {
- public:
-  HWVirtualDRM(BufferSyncHandler *buffer_sync_handler,
-               BufferAllocator *buffer_allocator, HWInfoInterface *hw_info_intf);
-  virtual ~HWVirtualDRM() {}
-  virtual DisplayError SetVSyncState(bool enable) { return kErrorNotSupported; }
-  virtual DisplayError SetMixerAttributes(const HWMixerAttributes &mixer_attributes) {
-    return kErrorNotSupported;
-  }
-  virtual DisplayError SetDisplayAttributes(const HWDisplayAttributes &display_attributes);
-
- protected:
-  virtual DisplayError Validate(HWLayers *hw_layers);
-  virtual DisplayError Commit(HWLayers *hw_layers);
-  virtual DisplayError GetPPFeaturesVersion(PPFeatureVersion *vers);
-
- private:
-  void ConfigureWbConnectorFbId(uint32_t fb_id);
-  void ConfigureWbConnectorDestRect();
-  void ConfigureWbConnectorSecureMode(bool secure);
-  void InitializeConfigs();
-  void DumpConnectorModeInfo();
-  DisplayError SetWbConfigs(const HWDisplayAttributes &display_attributes);
-  void GetModeIndex(const HWDisplayAttributes &display_attributes, int *mode_index);
-};
-
-}  // namespace sdm
-
-#endif  // __HW_VIRTUAL_DRM_H__
-
diff --git a/sdm/libs/core/fb/hw_color_manager.cpp b/sdm/libs/core/fb/hw_color_manager.cpp
deleted file mode 100644
index a6c78b0..0000000
--- a/sdm/libs/core/fb/hw_color_manager.cpp
+++ /dev/null
@@ -1,166 +0,0 @@
-/*
-* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without
-* modification, are permitted provided that the following conditions are
-* met:
-*     * Redistributions of source code must retain the above copyright
-*       notice, this list of conditions and the following disclaimer.
-*     * Redistributions in binary form must reproduce the above
-*       copyright notice, this list of conditions and the following
-*       disclaimer in the documentation and/or other materials provided
-*       with the distribution.
-*     * Neither the name of The Linux Foundation nor the names of its
-*       contributors may be used to endorse or promote products derived
-*       from this software without specific prior written permission.
-*
-* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
-* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
-* ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
-* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
-* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#include <ctype.h>
-#include <math.h>
-#include <fcntl.h>
-#include <inttypes.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/resource.h>
-#include <sys/prctl.h>
-#include <linux/msm_mdp.h>
-#include <utils/constants.h>
-#include <utils/debug.h>
-#include "hw_color_manager.h"
-
-#define __CLASS__ "HWColorManager"
-
-namespace sdm {
-
-DisplayError (*HWColorManager::SetFeature[])(const PPFeatureInfo &, msmfb_mdp_pp *) = {
-        [kGlobalColorFeaturePcc] = &HWColorManager::SetPCC,
-        [kGlobalColorFeatureIgc] = &HWColorManager::SetIGC,
-        [kGlobalColorFeaturePgc] = &HWColorManager::SetPGC,
-        [kMixerColorFeatureGc] = &HWColorManager::SetMixerGC,
-        [kGlobalColorFeaturePaV2] = &HWColorManager::SetPAV2,
-        [kGlobalColorFeatureDither] = &HWColorManager::SetDither,
-        [kGlobalColorFeatureGamut] = &HWColorManager::SetGamut,
-        [kGlobalColorFeaturePADither] = &HWColorManager::SetPADither,
-};
-
-DisplayError HWColorManager::SetPCC(const PPFeatureInfo &feature, msmfb_mdp_pp *kernel_params) {
-  DisplayError ret = kErrorNone;
-
-  kernel_params->op = mdp_op_pcc_cfg;
-  kernel_params->data.pcc_cfg_data.version = feature.feature_version_;
-  kernel_params->data.pcc_cfg_data.block = MDP_LOGICAL_BLOCK_DISP_0 + feature.disp_id_;
-  kernel_params->data.pcc_cfg_data.ops = feature.enable_flags_;
-  kernel_params->data.pcc_cfg_data.cfg_payload = feature.GetConfigData();
-  DLOGV_IF(kTagQDCM, "kernel params version = %d, block = %d, flags = %d",
-           kernel_params->data.pcc_cfg_data.version, kernel_params->data.pcc_cfg_data.block,
-           kernel_params->data.pcc_cfg_data.ops);
-
-  return ret;
-}
-
-DisplayError HWColorManager::SetIGC(const PPFeatureInfo &feature, msmfb_mdp_pp *kernel_params) {
-  DisplayError ret = kErrorNone;
-
-  kernel_params->op = mdp_op_lut_cfg;
-  kernel_params->data.lut_cfg_data.lut_type = mdp_lut_igc;
-  kernel_params->data.lut_cfg_data.data.igc_lut_data.block =
-      MDP_LOGICAL_BLOCK_DISP_0 + feature.disp_id_;
-  kernel_params->data.lut_cfg_data.data.igc_lut_data.version = feature.feature_version_;
-  kernel_params->data.lut_cfg_data.data.igc_lut_data.ops = feature.enable_flags_;
-  kernel_params->data.lut_cfg_data.data.igc_lut_data.cfg_payload = feature.GetConfigData();
-
-  return ret;
-}
-
-DisplayError HWColorManager::SetPGC(const PPFeatureInfo &feature, msmfb_mdp_pp *kernel_params) {
-  DisplayError ret = kErrorNone;
-
-  kernel_params->op = mdp_op_lut_cfg;
-  kernel_params->data.lut_cfg_data.lut_type = mdp_lut_pgc;
-  kernel_params->data.lut_cfg_data.data.pgc_lut_data.version = feature.feature_version_;
-  kernel_params->data.lut_cfg_data.data.pgc_lut_data.block =
-      MDP_LOGICAL_BLOCK_DISP_0 + feature.disp_id_;
-  kernel_params->data.lut_cfg_data.data.pgc_lut_data.flags = feature.enable_flags_;
-  kernel_params->data.lut_cfg_data.data.pgc_lut_data.cfg_payload = feature.GetConfigData();
-
-  return ret;
-}
-
-DisplayError HWColorManager::SetMixerGC(const PPFeatureInfo &feature, msmfb_mdp_pp *kernel_params) {
-  DisplayError ret = kErrorNone;
-
-  kernel_params->op = mdp_op_lut_cfg;
-  kernel_params->data.lut_cfg_data.lut_type = mdp_lut_pgc;
-  kernel_params->data.lut_cfg_data.data.pgc_lut_data.version = feature.feature_version_;
-  kernel_params->data.lut_cfg_data.data.pgc_lut_data.block =
-      (MDP_LOGICAL_BLOCK_DISP_0 + feature.disp_id_) | MDSS_PP_LM_CFG;
-  kernel_params->data.lut_cfg_data.data.pgc_lut_data.flags = feature.enable_flags_;
-  kernel_params->data.lut_cfg_data.data.pgc_lut_data.cfg_payload = feature.GetConfigData();
-  return ret;
-}
-
-DisplayError HWColorManager::SetPAV2(const PPFeatureInfo &feature, msmfb_mdp_pp *kernel_params) {
-  DisplayError ret = kErrorNone;
-
-  kernel_params->op = mdp_op_pa_v2_cfg;
-  kernel_params->data.pa_v2_cfg_data.version = feature.feature_version_;
-  kernel_params->data.pa_v2_cfg_data.block = MDP_LOGICAL_BLOCK_DISP_0 + feature.disp_id_;
-  kernel_params->data.pa_v2_cfg_data.flags = feature.enable_flags_;
-  kernel_params->data.pa_v2_cfg_data.cfg_payload = feature.GetConfigData();
-  DLOGV_IF(kTagQDCM, "kernel params version = %d, block = %d, flags = %d",
-           kernel_params->data.pa_v2_cfg_data.version, kernel_params->data.pa_v2_cfg_data.block,
-           kernel_params->data.pa_v2_cfg_data.flags);
-
-  return ret;
-}
-
-DisplayError HWColorManager::SetDither(const PPFeatureInfo &feature, msmfb_mdp_pp *kernel_params) {
-  DisplayError ret = kErrorNone;
-
-  kernel_params->op = mdp_op_dither_cfg;
-  kernel_params->data.dither_cfg_data.version = feature.feature_version_;
-  kernel_params->data.dither_cfg_data.block = MDP_LOGICAL_BLOCK_DISP_0 + feature.disp_id_;
-  kernel_params->data.dither_cfg_data.flags = feature.enable_flags_;
-  kernel_params->data.dither_cfg_data.cfg_payload = feature.GetConfigData();
-
-  return ret;
-}
-
-DisplayError HWColorManager::SetGamut(const PPFeatureInfo &feature, msmfb_mdp_pp *kernel_params) {
-  DisplayError ret = kErrorNone;
-
-  kernel_params->op = mdp_op_gamut_cfg;
-  kernel_params->data.gamut_cfg_data.version = feature.feature_version_;
-  kernel_params->data.gamut_cfg_data.block = MDP_LOGICAL_BLOCK_DISP_0 + feature.disp_id_;
-  kernel_params->data.gamut_cfg_data.flags = feature.enable_flags_;
-  kernel_params->data.gamut_cfg_data.cfg_payload = feature.GetConfigData();
-
-  return ret;
-}
-
-DisplayError HWColorManager::SetPADither(const PPFeatureInfo &feature,
-                                         msmfb_mdp_pp *kernel_params) {
-  DisplayError ret = kErrorNone;
-#ifdef PA_DITHER
-  kernel_params->op = mdp_op_pa_dither_cfg;
-  kernel_params->data.dither_cfg_data.version = feature.feature_version_;
-  kernel_params->data.dither_cfg_data.block = MDP_LOGICAL_BLOCK_DISP_0 + feature.disp_id_;
-  kernel_params->data.dither_cfg_data.flags = feature.enable_flags_;
-  kernel_params->data.dither_cfg_data.cfg_payload = feature.GetConfigData();
-#endif
-  return ret;
-}
-
-}  // namespace sdm
diff --git a/sdm/libs/core/fb/hw_color_manager.h b/sdm/libs/core/fb/hw_color_manager.h
deleted file mode 100644
index c9eea5b..0000000
--- a/sdm/libs/core/fb/hw_color_manager.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/* Copyright (c) 2015-2016, The Linux Foundataion. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without
-* modification, are permitted provided that the following conditions are
-* met:
-*     * Redistributions of source code must retain the above copyright
-*       notice, this list of conditions and the following disclaimer.
-*     * Redistributions in binary form must reproduce the above
-*       copyright notice, this list of conditions and the following
-*       disclaimer in the documentation and/or other materials provided
-*       with the distribution.
-*     * Neither the name of The Linux Foundation nor the names of its
-*       contributors may be used to endorse or promote products derived
-*       from this software without specific prior written permission.
-*
-* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
-* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
-* ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
-* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
-* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*
-*/
-
-#ifndef __HW_COLOR_MANAGER_H__
-#define __HW_COLOR_MANAGER_H__
-
-#include <linux/msm_mdp_ext.h>
-#include <linux/msm_mdp.h>
-
-#include <private/color_params.h>
-
-namespace sdm {
-
-class HWColorManager {
- public:
-  static DisplayError SetPCC(const PPFeatureInfo &feature, msmfb_mdp_pp *kernel_params);
-  static DisplayError SetIGC(const PPFeatureInfo &feature, msmfb_mdp_pp *kernel_params);
-  static DisplayError SetPGC(const PPFeatureInfo &feature, msmfb_mdp_pp *kernel_params);
-  static DisplayError SetMixerGC(const PPFeatureInfo &feature, msmfb_mdp_pp *kernel_params);
-  static DisplayError SetPAV2(const PPFeatureInfo &feature, msmfb_mdp_pp *kernel_params);
-  static DisplayError SetDither(const PPFeatureInfo &feature, msmfb_mdp_pp *kernel_params);
-  static DisplayError SetGamut(const PPFeatureInfo &feature, msmfb_mdp_pp *kernel_params);
-  static DisplayError SetPADither(const PPFeatureInfo &feature, msmfb_mdp_pp *kernel_params);
-
-  static DisplayError (*SetFeature[kMaxNumPPFeatures])(const PPFeatureInfo &feature,
-                                                       msmfb_mdp_pp *kernel_params);
-
- protected:
-  HWColorManager() {}
-};
-
-}  // namespace sdm
-
-#endif  // __HW_COLOR_MANAGER_H__
diff --git a/sdm/libs/core/fb/hw_device.cpp b/sdm/libs/core/fb/hw_device.cpp
deleted file mode 100644
index 148f866..0000000
--- a/sdm/libs/core/fb/hw_device.cpp
+++ /dev/null
@@ -1,1400 +0,0 @@
-/*
-* Copyright (c) 2014 - 2018, The Linux Foundation. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without
-* modification, are permitted provided that the following conditions are
-* met:
-*     * Redistributions of source code must retain the above copyright
-*       notice, this list of conditions and the following disclaimer.
-*     * Redistributions in binary form must reproduce the above
-*       copyright notice, this list of conditions and the following
-*       disclaimer in the documentation and/or other materials provided
-*       with the distribution.
-*     * Neither the name of The Linux Foundation nor the names of its
-*       contributors may be used to endorse or promote products derived
-*       from this software without specific prior written permission.
-*
-* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
-* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
-* ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
-* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
-* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#define __STDC_FORMAT_MACROS
-
-#include <stdio.h>
-#include <ctype.h>
-#include <math.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <string.h>
-#include <inttypes.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/ioctl.h>
-#include <linux/fb.h>
-#include <utils/constants.h>
-#include <utils/debug.h>
-#include <utils/sys.h>
-#include <vector>
-#include <algorithm>
-#include <string>
-#include <sstream>
-
-#include "hw_device.h"
-#include "hw_primary.h"
-#include "hw_hdmi.h"
-#include "hw_virtual.h"
-#include "hw_info_interface.h"
-
-#define __CLASS__ "HWDevice"
-
-using std::string;
-using std::to_string;
-using std::fstream;
-
-namespace sdm {
-
-HWDevice::HWDevice(BufferSyncHandler *buffer_sync_handler)
-  : fb_node_index_(-1), fb_path_("/sys/devices/virtual/graphics/fb"),
-    buffer_sync_handler_(buffer_sync_handler), synchronous_commit_(false) {
-}
-
-DisplayError HWDevice::Init() {
-  // Read the fb node index
-  fb_node_index_ = GetFBNodeIndex(device_type_);
-  if (fb_node_index_ == -1) {
-    DLOGE("device type = %d should be present", device_type_);
-    return kErrorHardware;
-  }
-
-  const char *dev_name = NULL;
-  vector<string> dev_paths = {"/dev/graphics/fb", "/dev/fb"};
-  for (size_t i = 0; i < dev_paths.size(); i++) {
-    dev_paths[i] += to_string(fb_node_index_);
-    if (Sys::access_(dev_paths[i].c_str(), F_OK) >= 0) {
-      dev_name = dev_paths[i].c_str();
-      DLOGI("access(%s) successful", dev_name);
-      break;
-    }
-
-    DLOGI("access(%s), errno = %d, error = %s", dev_paths[i].c_str(), errno, strerror(errno));
-  }
-
-  if (!dev_name) {
-    DLOGE("access() failed for all possible paths");
-    return kErrorHardware;
-  }
-
-  // Populate Panel Info (Used for Partial Update)
-  PopulateHWPanelInfo();
-  // Populate HW Capabilities
-  hw_resource_ = HWResourceInfo();
-  hw_info_intf_->GetHWResourceInfo(&hw_resource_);
-
-  device_fd_ = Sys::open_(dev_name, O_RDWR);
-  if (device_fd_ < 0) {
-    DLOGE("open %s failed errno = %d, error = %s", dev_name, errno, strerror(errno));
-    return kErrorResources;
-  }
-
-  return HWScale::Create(&hw_scale_, hw_resource_.has_qseed3);
-}
-
-DisplayError HWDevice::Deinit() {
-  HWScale::Destroy(hw_scale_);
-
-  if (device_fd_ >= 0) {
-    Sys::close_(device_fd_);
-    device_fd_ = -1;
-  }
-
-  if (stored_retire_fence >= 0) {
-    Sys::close_(stored_retire_fence);
-    stored_retire_fence = -1;
-  }
-  return kErrorNone;
-}
-
-DisplayError HWDevice::GetActiveConfig(uint32_t *active_config) {
-  *active_config = 0;
-  return kErrorNone;
-}
-
-DisplayError HWDevice::GetNumDisplayAttributes(uint32_t *count) {
-  *count = 1;
-  return kErrorNone;
-}
-
-DisplayError HWDevice::GetDisplayAttributes(uint32_t index,
-                                            HWDisplayAttributes *display_attributes) {
-  return kErrorNone;
-}
-
-DisplayError HWDevice::GetHWPanelInfo(HWPanelInfo *panel_info) {
-  *panel_info = hw_panel_info_;
-  return kErrorNone;
-}
-
-DisplayError HWDevice::SetDisplayAttributes(uint32_t index) {
-  return kErrorNone;
-}
-
-DisplayError HWDevice::SetDisplayAttributes(const HWDisplayAttributes &display_attributes) {
-  return kErrorNotSupported;
-}
-
-DisplayError HWDevice::GetConfigIndex(char *mode, uint32_t *index) {
-  return kErrorNone;
-}
-
-DisplayError HWDevice::PowerOn(int *release_fence) {
-  DTRACE_SCOPED();
-
-  if (Sys::ioctl_(device_fd_, FBIOBLANK, FB_BLANK_UNBLANK) < 0) {
-    if (errno == ESHUTDOWN) {
-      DLOGI_IF(kTagDriverConfig, "Driver is processing shutdown sequence");
-      return kErrorShutDown;
-    }
-    IOCTL_LOGE(FB_BLANK_UNBLANK, device_type_);
-    return kErrorHardware;
-  }
-
-  return kErrorNone;
-}
-
-DisplayError HWDevice::PowerOff() {
-  return kErrorNone;
-}
-
-DisplayError HWDevice::Doze(int *release_fence) {
-  return kErrorNone;
-}
-
-DisplayError HWDevice::DozeSuspend(int *release_fence) {
-  return kErrorNone;
-}
-
-DisplayError HWDevice::Standby() {
-  return kErrorNone;
-}
-
-DisplayError HWDevice::Validate(HWLayers *hw_layers) {
-  DTRACE_SCOPED();
-
-  DisplayError error = kErrorNone;
-
-  HWLayersInfo &hw_layer_info = hw_layers->info;
-  uint32_t hw_layer_count = UINT32(hw_layer_info.hw_layers.size());
-
-  DLOGD_IF(kTagDriverConfig, "************************** %s Validate Input ***********************",
-           device_name_);
-  DLOGD_IF(kTagDriverConfig, "SDE layer count is %d", hw_layer_count);
-
-  mdp_layer_commit_v1 &mdp_commit = mdp_disp_commit_.commit_v1;
-  uint32_t &mdp_layer_count = mdp_commit.input_layer_cnt;
-
-  DLOGI_IF(kTagDriverConfig, "left_roi: x = %d, y = %d, w = %d, h = %d", mdp_commit.left_roi.x,
-    mdp_commit.left_roi.y, mdp_commit.left_roi.w, mdp_commit.left_roi.h);
-  DLOGI_IF(kTagDriverConfig, "right_roi: x = %d, y = %d, w = %d, h = %d", mdp_commit.right_roi.x,
-    mdp_commit.right_roi.y, mdp_commit.right_roi.w, mdp_commit.right_roi.h);
-
-  for (uint32_t i = 0; i < hw_layer_count; i++) {
-    const Layer &layer = hw_layer_info.hw_layers.at(i);
-    LayerBuffer input_buffer = layer.input_buffer;
-    HWPipeInfo *left_pipe = &hw_layers->config[i].left_pipe;
-    HWPipeInfo *right_pipe = &hw_layers->config[i].right_pipe;
-    HWRotatorSession *hw_rotator_session = &hw_layers->config[i].hw_rotator_session;
-    bool is_rotator_used = (hw_rotator_session->hw_block_count != 0);
-
-    for (uint32_t count = 0; count < 2; count++) {
-      HWPipeInfo *pipe_info = (count == 0) ? left_pipe : right_pipe;
-      HWRotateInfo *hw_rotate_info = &hw_rotator_session->hw_rotate_info[count];
-
-      if (hw_rotate_info->valid) {
-        input_buffer = hw_rotator_session->output_buffer;
-      }
-
-      if (pipe_info->valid) {
-        mdp_input_layer &mdp_layer = mdp_in_layers_[mdp_layer_count];
-        mdp_layer_buffer &mdp_buffer = mdp_layer.buffer;
-
-        mdp_buffer.width = input_buffer.width;
-        mdp_buffer.height = input_buffer.height;
-        mdp_buffer.comp_ratio.denom = 1000;
-        mdp_buffer.comp_ratio.numer = UINT32(hw_layers->config[i].compression * 1000);
-
-        if (layer.flags.solid_fill) {
-          mdp_buffer.format = MDP_ARGB_8888;
-        } else {
-          error = SetFormat(input_buffer.format, &mdp_buffer.format);
-          if (error != kErrorNone) {
-            return error;
-          }
-        }
-        mdp_layer.alpha = layer.plane_alpha;
-        mdp_layer.z_order = UINT16(pipe_info->z_order);
-        mdp_layer.transp_mask = 0xffffffff;
-        SetBlending(layer.blending, &mdp_layer.blend_op);
-        mdp_layer.pipe_ndx = pipe_info->pipe_id;
-        mdp_layer.horz_deci = pipe_info->horizontal_decimation;
-        mdp_layer.vert_deci = pipe_info->vertical_decimation;
-#ifdef MDP_COMMIT_RECT_NUM
-        mdp_layer.rect_num = pipe_info->rect;
-#endif
-        SetRect(pipe_info->src_roi, &mdp_layer.src_rect);
-        SetRect(pipe_info->dst_roi, &mdp_layer.dst_rect);
-        SetMDPFlags(&layer, is_rotator_used, hw_layer_info.async_cursor_updates, &mdp_layer.flags);
-        SetCSC(layer.input_buffer.color_metadata, &mdp_layer.color_space);
-        if (pipe_info->flags & kIGC) {
-          SetIGC(&layer.input_buffer, mdp_layer_count);
-        }
-        if (pipe_info->flags & kMultiRect) {
-          mdp_layer.flags |= MDP_LAYER_MULTIRECT_ENABLE;
-          if (pipe_info->flags & kMultiRectParallelMode) {
-            mdp_layer.flags |= MDP_LAYER_MULTIRECT_PARALLEL_MODE;
-          }
-        }
-        mdp_layer.bg_color = layer.solid_fill_color;
-
-        // HWScaleData to MDP driver
-        hw_scale_->SetHWScaleData(pipe_info->scale_data, mdp_layer_count, &mdp_commit,
-                                  pipe_info->sub_block_type);
-        mdp_layer.scale = hw_scale_->GetScaleDataRef(mdp_layer_count, pipe_info->sub_block_type);
-
-        mdp_layer_count++;
-
-        DLOGD_IF(kTagDriverConfig, "******************* Layer[%d] %s pipe Input ******************",
-                 i, count ? "Right" : "Left");
-        DLOGD_IF(kTagDriverConfig, "in_w %d, in_h %d, in_f %d", mdp_buffer.width, mdp_buffer.height,
-                 mdp_buffer.format);
-        DLOGD_IF(kTagDriverConfig, "plane_alpha %d, zorder %d, blending %d, horz_deci %d, "
-                 "vert_deci %d, pipe_id = 0x%x, mdp_flags 0x%x", mdp_layer.alpha, mdp_layer.z_order,
-                 mdp_layer.blend_op, mdp_layer.horz_deci, mdp_layer.vert_deci, mdp_layer.pipe_ndx,
-                 mdp_layer.flags);
-        DLOGV_IF(kTagDriverConfig, "src_rect [%d, %d, %d, %d]", mdp_layer.src_rect.x,
-                 mdp_layer.src_rect.y, mdp_layer.src_rect.w, mdp_layer.src_rect.h);
-        DLOGV_IF(kTagDriverConfig, "dst_rect [%d, %d, %d, %d]", mdp_layer.dst_rect.x,
-                 mdp_layer.dst_rect.y, mdp_layer.dst_rect.w, mdp_layer.dst_rect.h);
-        hw_scale_->DumpScaleData(mdp_layer.scale);
-        DLOGD_IF(kTagDriverConfig, "*************************************************************");
-      }
-    }
-  }
-
-  // TODO(user): This block should move to the derived class
-  if (device_type_ == kDeviceVirtual) {
-    LayerBuffer *output_buffer = hw_layers->info.stack->output_buffer;
-    mdp_out_layer_.writeback_ndx = hw_resource_.writeback_index;
-    mdp_out_layer_.buffer.width = output_buffer->width;
-    mdp_out_layer_.buffer.height = output_buffer->height;
-    if (output_buffer->flags.secure) {
-      mdp_out_layer_.flags |= MDP_LAYER_SECURE_SESSION;
-    }
-    mdp_out_layer_.buffer.comp_ratio.denom = 1000;
-    mdp_out_layer_.buffer.comp_ratio.numer = UINT32(hw_layers->output_compression * 1000);
-#ifdef OUT_LAYER_COLOR_SPACE
-    SetCSC(output_buffer->color_metadata, &mdp_out_layer_.color_space);
-#endif
-    SetFormat(output_buffer->format, &mdp_out_layer_.buffer.format);
-
-    DLOGI_IF(kTagDriverConfig, "********************* Output buffer Info ************************");
-    DLOGI_IF(kTagDriverConfig, "out_w %d, out_h %d, out_f %d, wb_id %d",
-             mdp_out_layer_.buffer.width, mdp_out_layer_.buffer.height,
-             mdp_out_layer_.buffer.format, mdp_out_layer_.writeback_ndx);
-    DLOGI_IF(kTagDriverConfig, "*****************************************************************");
-  }
-
-  uint32_t index = 0;
-  for (uint32_t i = 0; i < hw_resource_.hw_dest_scalar_info.count; i++) {
-    DestScaleInfoMap::iterator it = hw_layer_info.dest_scale_info_map.find(i);
-
-    if (it == hw_layer_info.dest_scale_info_map.end()) {
-      continue;
-    }
-
-    HWDestScaleInfo *dest_scale_info = it->second;
-
-    mdp_destination_scaler_data *dest_scalar_data = &mdp_dest_scalar_data_[index];
-    hw_scale_->SetHWScaleData(dest_scale_info->scale_data, index, &mdp_commit,
-                              kHWDestinationScalar);
-
-    if (dest_scale_info->scale_update) {
-      dest_scalar_data->flags |= MDP_DESTSCALER_SCALE_UPDATE;
-    }
-
-    dest_scalar_data->dest_scaler_ndx = i;
-    dest_scalar_data->lm_width = dest_scale_info->mixer_width;
-    dest_scalar_data->lm_height = dest_scale_info->mixer_height;
-#ifdef MDP_DESTSCALER_ROI_ENABLE
-    SetRect(dest_scale_info->panel_roi, &dest_scalar_data->panel_roi);
-    dest_scalar_data->flags |= MDP_DESTSCALER_ROI_ENABLE;
-#endif
-    dest_scalar_data->scale = reinterpret_cast <uint64_t>
-      (hw_scale_->GetScaleDataRef(index, kHWDestinationScalar));
-
-    index++;
-
-    DLOGD_IF(kTagDriverConfig, "************************ DestScalar[%d] **************************",
-             dest_scalar_data->dest_scaler_ndx);
-    DLOGD_IF(kTagDriverConfig, "Mixer WxH %dx%d flags %x", dest_scalar_data->lm_width,
-             dest_scalar_data->lm_height, dest_scalar_data->flags);
-#ifdef MDP_DESTSCALER_ROI_ENABLE
-    DLOGD_IF(kTagDriverConfig, "Panel ROI [%d, %d, %d, %d]", dest_scalar_data->panel_roi.x,
-             dest_scalar_data->panel_roi.y, dest_scalar_data->panel_roi.w,
-             dest_scalar_data->panel_roi.h);
-#endif
-    DLOGD_IF(kTagDriverConfig, "*****************************************************************");
-  }
-  mdp_commit.dest_scaler_cnt = UINT32(hw_layer_info.dest_scale_info_map.size());
-
-  mdp_commit.flags |= MDP_VALIDATE_LAYER;
-#ifdef MDP_COMMIT_RECT_NUM
-  mdp_commit.flags |= MDP_COMMIT_RECT_NUM;
-#endif
-  if (Sys::ioctl_(device_fd_, INT(MSMFB_ATOMIC_COMMIT), &mdp_disp_commit_) < 0) {
-    if (errno == ESHUTDOWN) {
-      DLOGI_IF(kTagDriverConfig, "Driver is processing shutdown sequence");
-      return kErrorShutDown;
-    }
-    IOCTL_LOGE(MSMFB_ATOMIC_COMMIT, device_type_);
-    DumpLayerCommit(mdp_disp_commit_);
-    return kErrorHardware;
-  }
-
-  return kErrorNone;
-}
-
-void HWDevice::DumpLayerCommit(const mdp_layer_commit &layer_commit) {
-  const mdp_layer_commit_v1 &mdp_commit = layer_commit.commit_v1;
-  const mdp_input_layer *mdp_layers = mdp_commit.input_layers;
-  const mdp_rect &l_roi = mdp_commit.left_roi;
-  const mdp_rect &r_roi = mdp_commit.right_roi;
-
-  DLOGI("mdp_commit: flags = %x, release fence = %x", mdp_commit.flags, mdp_commit.release_fence);
-  DLOGI("left_roi: x = %d, y = %d, w = %d, h = %d", l_roi.x, l_roi.y, l_roi.w, l_roi.h);
-  DLOGI("right_roi: x = %d, y = %d, w = %d, h = %d", r_roi.x, r_roi.y, r_roi.w, r_roi.h);
-  for (uint32_t i = 0; i < mdp_commit.dest_scaler_cnt; i++) {
-    mdp_destination_scaler_data *dest_scalar_data = &mdp_dest_scalar_data_[i];
-    mdp_scale_data_v2 *mdp_scale = reinterpret_cast<mdp_scale_data_v2 *>(dest_scalar_data->scale);
-
-    DLOGI("Dest scalar index %d Mixer WxH %dx%d", dest_scalar_data->dest_scaler_ndx,
-          dest_scalar_data->lm_width, dest_scalar_data->lm_height);
-#ifdef MDP_DESTSCALER_ROI_ENABLE
-    DLOGI("Panel ROI [%d, %d, %d, %d]", dest_scalar_data->panel_roi.x,
-           dest_scalar_data->panel_roi.y, dest_scalar_data->panel_roi.w,
-           dest_scalar_data->panel_roi.h);
-#endif
-    DLOGI("Dest scalar Dst WxH %dx%d", mdp_scale->dst_width, mdp_scale->dst_height);
-  }
-  for (uint32_t i = 0; i < mdp_commit.input_layer_cnt; i++) {
-    const mdp_input_layer &layer = mdp_layers[i];
-    const mdp_rect &src_rect = layer.src_rect;
-    const mdp_rect &dst_rect = layer.dst_rect;
-    DLOGI("layer = %d, pipe_ndx = %x, z = %d, flags = %x",
-      i, layer.pipe_ndx, layer.z_order, layer.flags);
-    DLOGI("src_width = %d, src_height = %d, src_format = %d",
-      layer.buffer.width, layer.buffer.height, layer.buffer.format);
-    DLOGI("src_rect: x = %d, y = %d, w = %d, h = %d",
-      src_rect.x, src_rect.y, src_rect.w, src_rect.h);
-    DLOGI("dst_rect: x = %d, y = %d, w = %d, h = %d",
-      dst_rect.x, dst_rect.y, dst_rect.w, dst_rect.h);
-  }
-}
-
-DisplayError HWDevice::Commit(HWLayers *hw_layers) {
-  DTRACE_SCOPED();
-
-  HWLayersInfo &hw_layer_info = hw_layers->info;
-  uint32_t hw_layer_count = UINT32(hw_layer_info.hw_layers.size());
-
-  DLOGD_IF(kTagDriverConfig, "*************************** %s Commit Input ************************",
-           device_name_);
-  DLOGD_IF(kTagDriverConfig, "SDE layer count is %d", hw_layer_count);
-
-  mdp_layer_commit_v1 &mdp_commit = mdp_disp_commit_.commit_v1;
-  uint32_t mdp_layer_index = 0;
-
-  for (uint32_t i = 0; i < hw_layer_count; i++) {
-    const Layer &layer = hw_layer_info.hw_layers.at(i);
-    LayerBuffer *input_buffer = const_cast<LayerBuffer *>(&layer.input_buffer);
-    HWPipeInfo *left_pipe = &hw_layers->config[i].left_pipe;
-    HWPipeInfo *right_pipe = &hw_layers->config[i].right_pipe;
-    HWRotatorSession *hw_rotator_session = &hw_layers->config[i].hw_rotator_session;
-
-    for (uint32_t count = 0; count < 2; count++) {
-      HWPipeInfo *pipe_info = (count == 0) ? left_pipe : right_pipe;
-      HWRotateInfo *hw_rotate_info = &hw_rotator_session->hw_rotate_info[count];
-
-      if (hw_rotate_info->valid) {
-        input_buffer = &hw_rotator_session->output_buffer;
-      }
-
-      if (pipe_info->valid) {
-        mdp_layer_buffer &mdp_buffer = mdp_in_layers_[mdp_layer_index].buffer;
-        mdp_input_layer &mdp_layer = mdp_in_layers_[mdp_layer_index];
-        if (input_buffer->planes[0].fd >= 0) {
-          mdp_buffer.plane_count = 1;
-          mdp_buffer.planes[0].fd = input_buffer->planes[0].fd;
-          mdp_buffer.planes[0].offset = input_buffer->planes[0].offset;
-          SetStride(device_type_, input_buffer->format, input_buffer->planes[0].stride,
-                    &mdp_buffer.planes[0].stride);
-        } else {
-          mdp_buffer.plane_count = 0;
-        }
-
-        mdp_buffer.fence = input_buffer->acquire_fence_fd;
-        mdp_layer_index++;
-
-        DLOGD_IF(kTagDriverConfig, "****************** Layer[%d] %s pipe Input *******************",
-                 i, count ? "Right" : "Left");
-        DLOGD_IF(kTagDriverConfig, "in_w %d, in_h %d, in_f %d, horz_deci %d, vert_deci %d",
-                 mdp_buffer.width, mdp_buffer.height, mdp_buffer.format, mdp_layer.horz_deci,
-                 mdp_layer.vert_deci);
-        DLOGV_IF(kTagDriverConfig, "in_buf_fd %d, in_buf_offset %d, in_buf_stride %d, " \
-                 "in_plane_count %d, in_fence %d, layer count %d", mdp_buffer.planes[0].fd,
-                 mdp_buffer.planes[0].offset, mdp_buffer.planes[0].stride, mdp_buffer.plane_count,
-                 mdp_buffer.fence, mdp_commit.input_layer_cnt);
-        DLOGD_IF(kTagDriverConfig, "*************************************************************");
-      }
-    }
-  }
-
-  // TODO(user): Move to derived class
-  if (device_type_ == kDeviceVirtual) {
-    LayerBuffer *output_buffer = hw_layers->info.stack->output_buffer;
-
-    if (output_buffer->planes[0].fd >= 0) {
-      mdp_out_layer_.buffer.planes[0].fd = output_buffer->planes[0].fd;
-      mdp_out_layer_.buffer.planes[0].offset = output_buffer->planes[0].offset;
-      SetStride(device_type_, output_buffer->format, output_buffer->planes[0].stride,
-                &mdp_out_layer_.buffer.planes[0].stride);
-      mdp_out_layer_.buffer.plane_count = 1;
-    } else {
-      DLOGE("Invalid output buffer fd");
-      return kErrorParameters;
-    }
-
-    mdp_out_layer_.buffer.fence = output_buffer->acquire_fence_fd;
-
-    DLOGI_IF(kTagDriverConfig, "********************** Output buffer Info ***********************");
-    DLOGI_IF(kTagDriverConfig, "out_fd %d, out_offset %d, out_stride %d, acquire_fence %d",
-             mdp_out_layer_.buffer.planes[0].fd, mdp_out_layer_.buffer.planes[0].offset,
-             mdp_out_layer_.buffer.planes[0].stride,  mdp_out_layer_.buffer.fence);
-    DLOGI_IF(kTagDriverConfig, "*****************************************************************");
-  }
-
-  mdp_commit.release_fence = -1;
-  mdp_commit.flags &= UINT32(~MDP_VALIDATE_LAYER);
-  if (synchronous_commit_) {
-    mdp_commit.flags |= MDP_COMMIT_WAIT_FOR_FINISH;
-  }
-  if (Sys::ioctl_(device_fd_, INT(MSMFB_ATOMIC_COMMIT), &mdp_disp_commit_) < 0) {
-    if (errno == ESHUTDOWN) {
-      DLOGI_IF(kTagDriverConfig, "Driver is processing shutdown sequence");
-      return kErrorShutDown;
-    }
-    IOCTL_LOGE(MSMFB_ATOMIC_COMMIT, device_type_);
-    DumpLayerCommit(mdp_disp_commit_);
-    synchronous_commit_ = false;
-    return kErrorHardware;
-  }
-
-  LayerStack *stack = hw_layer_info.stack;
-  stack->retire_fence_fd = mdp_commit.retire_fence;
-#ifdef VIDEO_MODE_DEFER_RETIRE_FENCE
-  if (hw_panel_info_.mode == kModeVideo) {
-    stack->retire_fence_fd = stored_retire_fence;
-    stored_retire_fence =  mdp_commit.retire_fence;
-  }
-#endif
-  // MDP returns only one release fence for the entire layer stack. Duplicate this fence into all
-  // layers being composed by MDP.
-
-  for (uint32_t i = 0; i < hw_layer_count; i++) {
-    const Layer &layer = hw_layer_info.hw_layers.at(i);
-    LayerBuffer *input_buffer = const_cast<LayerBuffer *>(&layer.input_buffer);
-    HWRotatorSession *hw_rotator_session = &hw_layers->config[i].hw_rotator_session;
-
-    if (hw_rotator_session->hw_block_count) {
-      input_buffer = &hw_rotator_session->output_buffer;
-      input_buffer->release_fence_fd = Sys::dup_(mdp_commit.release_fence);
-      continue;
-    }
-
-    input_buffer->release_fence_fd = Sys::dup_(mdp_commit.release_fence);
-  }
-
-  hw_layer_info.sync_handle = Sys::dup_(mdp_commit.release_fence);
-
-  DLOGI_IF(kTagDriverConfig, "*************************** %s Commit Input ************************",
-           device_name_);
-  DLOGI_IF(kTagDriverConfig, "retire_fence_fd %d", stack->retire_fence_fd);
-  DLOGI_IF(kTagDriverConfig, "*******************************************************************");
-
-  if (mdp_commit.release_fence >= 0) {
-    Sys::close_(mdp_commit.release_fence);
-  }
-
-  if (synchronous_commit_) {
-    // A synchronous commit can be requested when changing the display mode so we need to update
-    // panel info.
-    PopulateHWPanelInfo();
-    synchronous_commit_ = false;
-  }
-
-  return kErrorNone;
-}
-
-DisplayError HWDevice::Flush() {
-  ResetDisplayParams();
-  mdp_layer_commit_v1 &mdp_commit = mdp_disp_commit_.commit_v1;
-  mdp_commit.input_layer_cnt = 0;
-  mdp_commit.output_layer = NULL;
-
-  mdp_commit.flags &= UINT32(~MDP_VALIDATE_LAYER);
-  if (Sys::ioctl_(device_fd_, INT(MSMFB_ATOMIC_COMMIT), &mdp_disp_commit_) < 0) {
-    if (errno == ESHUTDOWN) {
-      DLOGI_IF(kTagDriverConfig, "Driver is processing shutdown sequence");
-      return kErrorShutDown;
-    }
-    IOCTL_LOGE(MSMFB_ATOMIC_COMMIT, device_type_);
-    DumpLayerCommit(mdp_disp_commit_);
-    return kErrorHardware;
-  }
-  return kErrorNone;
-}
-
-DisplayError HWDevice::SetFormat(const LayerBufferFormat &source, uint32_t *target) {
-  switch (source) {
-  case kFormatARGB8888:                 *target = MDP_ARGB_8888;         break;
-  case kFormatRGBA8888:                 *target = MDP_RGBA_8888;         break;
-  case kFormatBGRA8888:                 *target = MDP_BGRA_8888;         break;
-  case kFormatRGBX8888:                 *target = MDP_RGBX_8888;         break;
-  case kFormatBGRX8888:                 *target = MDP_BGRX_8888;         break;
-  case kFormatRGBA5551:                 *target = MDP_RGBA_5551;         break;
-  case kFormatRGBA4444:                 *target = MDP_RGBA_4444;         break;
-  case kFormatRGB888:                   *target = MDP_RGB_888;           break;
-  case kFormatBGR888:                   *target = MDP_BGR_888;           break;
-  case kFormatRGB565:                   *target = MDP_RGB_565;           break;
-  case kFormatBGR565:                   *target = MDP_BGR_565;           break;
-  case kFormatYCbCr420Planar:           *target = MDP_Y_CB_CR_H2V2;      break;
-  case kFormatYCrCb420Planar:           *target = MDP_Y_CR_CB_H2V2;      break;
-  case kFormatYCrCb420PlanarStride16:   *target = MDP_Y_CR_CB_GH2V2;     break;
-  case kFormatYCbCr420SemiPlanar:       *target = MDP_Y_CBCR_H2V2;       break;
-  case kFormatYCrCb420SemiPlanar:       *target = MDP_Y_CRCB_H2V2;       break;
-  case kFormatYCbCr422H1V2SemiPlanar:   *target = MDP_Y_CBCR_H1V2;       break;
-  case kFormatYCrCb422H1V2SemiPlanar:   *target = MDP_Y_CRCB_H1V2;       break;
-  case kFormatYCbCr422H2V1SemiPlanar:   *target = MDP_Y_CBCR_H2V1;       break;
-  case kFormatYCrCb422H2V1SemiPlanar:   *target = MDP_Y_CRCB_H2V1;       break;
-  case kFormatYCbCr422H2V1Packed:       *target = MDP_YCBYCR_H2V1;       break;
-  case kFormatYCbCr420SemiPlanarVenus:  *target = MDP_Y_CBCR_H2V2_VENUS; break;
-  case kFormatRGBA8888Ubwc:             *target = MDP_RGBA_8888_UBWC;    break;
-  case kFormatRGBX8888Ubwc:             *target = MDP_RGBX_8888_UBWC;    break;
-  case kFormatBGR565Ubwc:               *target = MDP_RGB_565_UBWC;      break;
-  case kFormatYCbCr420SPVenusUbwc:      *target = MDP_Y_CBCR_H2V2_UBWC;  break;
-  case kFormatCbYCrY422H2V1Packed:      *target = MDP_CBYCRY_H2V1;       break;
-  case kFormatRGBA1010102:              *target = MDP_RGBA_1010102;      break;
-  case kFormatARGB2101010:              *target = MDP_ARGB_2101010;      break;
-  case kFormatRGBX1010102:              *target = MDP_RGBX_1010102;      break;
-  case kFormatXRGB2101010:              *target = MDP_XRGB_2101010;      break;
-  case kFormatBGRA1010102:              *target = MDP_BGRA_1010102;      break;
-  case kFormatABGR2101010:              *target = MDP_ABGR_2101010;      break;
-  case kFormatBGRX1010102:              *target = MDP_BGRX_1010102;      break;
-  case kFormatXBGR2101010:              *target = MDP_XBGR_2101010;      break;
-  case kFormatRGBA1010102Ubwc:          *target = MDP_RGBA_1010102_UBWC; break;
-  case kFormatRGBX1010102Ubwc:          *target = MDP_RGBX_1010102_UBWC; break;
-  case kFormatYCbCr420P010:             *target = MDP_Y_CBCR_H2V2_P010;  break;
-  case kFormatYCbCr420TP10Ubwc:         *target = MDP_Y_CBCR_H2V2_TP10_UBWC; break;
-  default:
-    DLOGE("Unsupported format type %d", source);
-    return kErrorParameters;
-  }
-
-  return kErrorNone;
-}
-
-DisplayError HWDevice::SetStride(HWDeviceType device_type, LayerBufferFormat format,
-                                      uint32_t width, uint32_t *target) {
-  // TODO(user): This SetStride function is a workaround to satisfy the driver expectation for
-  // rotator and virtual devices. Eventually this will be taken care in the driver.
-  if (device_type != kDeviceRotator && device_type != kDeviceVirtual) {
-    *target = width;
-    return kErrorNone;
-  }
-
-  switch (format) {
-  case kFormatARGB8888:
-  case kFormatRGBA8888:
-  case kFormatBGRA8888:
-  case kFormatRGBX8888:
-  case kFormatBGRX8888:
-  case kFormatRGBA8888Ubwc:
-  case kFormatRGBX8888Ubwc:
-  case kFormatRGBA1010102:
-  case kFormatARGB2101010:
-  case kFormatRGBX1010102:
-  case kFormatXRGB2101010:
-  case kFormatBGRA1010102:
-  case kFormatABGR2101010:
-  case kFormatBGRX1010102:
-  case kFormatXBGR2101010:
-  case kFormatRGBA1010102Ubwc:
-  case kFormatRGBX1010102Ubwc:
-    *target = width * 4;
-    break;
-  case kFormatRGB888:
-  case kFormatBGR888:
-    *target = width * 3;
-    break;
-  case kFormatRGB565:
-  case kFormatBGR565:
-  case kFormatBGR565Ubwc:
-    *target = width * 2;
-    break;
-  case kFormatYCbCr420SemiPlanarVenus:
-  case kFormatYCbCr420SPVenusUbwc:
-  case kFormatYCbCr420Planar:
-  case kFormatYCrCb420Planar:
-  case kFormatYCrCb420PlanarStride16:
-  case kFormatYCbCr420SemiPlanar:
-  case kFormatYCrCb420SemiPlanar:
-  case kFormatYCbCr420TP10Ubwc:
-    *target = width;
-    break;
-  case kFormatYCbCr422H2V1Packed:
-  case kFormatCbYCrY422H2V1Packed:
-  case kFormatYCrCb422H2V1SemiPlanar:
-  case kFormatYCrCb422H1V2SemiPlanar:
-  case kFormatYCbCr422H2V1SemiPlanar:
-  case kFormatYCbCr422H1V2SemiPlanar:
-  case kFormatYCbCr420P010:
-  case kFormatRGBA5551:
-  case kFormatRGBA4444:
-    *target = width * 2;
-    break;
-  default:
-    DLOGE("Unsupported format type %d", format);
-    return kErrorParameters;
-  }
-
-  return kErrorNone;
-}
-
-void HWDevice::SetBlending(const LayerBlending &source, mdss_mdp_blend_op *target) {
-  switch (source) {
-  case kBlendingPremultiplied:  *target = BLEND_OP_PREMULTIPLIED;   break;
-  case kBlendingOpaque:         *target = BLEND_OP_OPAQUE;          break;
-  case kBlendingCoverage:       *target = BLEND_OP_COVERAGE;        break;
-  default:                      *target = BLEND_OP_NOT_DEFINED;     break;
-  }
-}
-
-void HWDevice::SetRect(const LayerRect &source, mdp_rect *target) {
-  target->x = UINT32(source.left);
-  target->y = UINT32(source.top);
-  target->w = UINT32(source.right) - target->x;
-  target->h = UINT32(source.bottom) - target->y;
-}
-
-void HWDevice::SetMDPFlags(const Layer *layer, const bool &is_rotator_used,
-                           bool async_cursor_updates, uint32_t *mdp_flags) {
-  const LayerBuffer &input_buffer = layer->input_buffer;
-
-  // Flips will be taken care by rotator, if layer uses rotator for downscale/rotation. So ignore
-  // flip flags for MDP.
-  if (!is_rotator_used) {
-    if (layer->transform.flip_vertical) {
-      *mdp_flags |= MDP_LAYER_FLIP_UD;
-    }
-
-    if (layer->transform.flip_horizontal) {
-      *mdp_flags |= MDP_LAYER_FLIP_LR;
-    }
-
-    if (input_buffer.flags.interlace) {
-      *mdp_flags |= MDP_LAYER_DEINTERLACE;
-    }
-  }
-
-  if (input_buffer.flags.secure_camera) {
-    *mdp_flags |= MDP_LAYER_SECURE_CAMERA_SESSION;
-  } else if (input_buffer.flags.secure) {
-    *mdp_flags |= MDP_LAYER_SECURE_SESSION;
-  }
-
-  if (input_buffer.flags.secure_display) {
-    *mdp_flags |= MDP_LAYER_SECURE_DISPLAY_SESSION;
-  }
-
-  if (layer->flags.solid_fill) {
-    *mdp_flags |= MDP_LAYER_SOLID_FILL;
-  }
-
-  if (layer->flags.cursor && async_cursor_updates) {
-    // command mode panels does not support async position update
-    *mdp_flags |= MDP_LAYER_ASYNC;
-  }
-}
-
-int HWDevice::GetFBNodeIndex(HWDeviceType device_type) {
-  for (int i = 0; i < kFBNodeMax; i++) {
-    HWPanelInfo panel_info;
-    GetHWPanelInfoByNode(i, &panel_info);
-    switch (device_type) {
-    case kDevicePrimary:
-      if (panel_info.is_primary_panel) {
-        return i;
-      }
-      break;
-    case kDeviceHDMI:
-      if (panel_info.is_pluggable == true) {
-        if (IsFBNodeConnected(i)) {
-          return i;
-        }
-      }
-      break;
-    case kDeviceVirtual:
-      if (panel_info.port == kPortWriteBack) {
-        return i;
-      }
-      break;
-    default:
-      break;
-    }
-  }
-  return -1;
-}
-
-void HWDevice::PopulateHWPanelInfo() {
-  hw_panel_info_ = HWPanelInfo();
-  GetHWPanelInfoByNode(fb_node_index_, &hw_panel_info_);
-  DLOGI("Device type = %d, Display Port = %d, Display Mode = %d, Device Node = %d, Is Primary = %d",
-        device_type_, hw_panel_info_.port, hw_panel_info_.mode, fb_node_index_,
-        hw_panel_info_.is_primary_panel);
-  DLOGI("Partial Update = %d, supported roi_count =%d, Dynamic FPS = %d",
-        hw_panel_info_.partial_update, hw_panel_info_.left_roi_count, hw_panel_info_.dynamic_fps);
-  DLOGI("Align: left = %d, width = %d, top = %d, height = %d",
-        hw_panel_info_.left_align, hw_panel_info_.width_align,
-        hw_panel_info_.top_align, hw_panel_info_.height_align);
-  DLOGI("ROI: min_width = %d, min_height = %d, need_merge = %d",
-        hw_panel_info_.min_roi_width, hw_panel_info_.min_roi_height,
-        hw_panel_info_.needs_roi_merge);
-  DLOGI("FPS: min = %d, max =%d", hw_panel_info_.min_fps, hw_panel_info_.max_fps);
-  DLOGI("Ping Pong Split = %d",  hw_panel_info_.ping_pong_split);
-  DLOGI("Left Split = %d, Right Split = %d", hw_panel_info_.split_info.left_split,
-        hw_panel_info_.split_info.right_split);
-}
-
-void HWDevice::GetHWPanelNameByNode(int device_node, HWPanelInfo *panel_info) {
-  string file_name = fb_path_ + to_string(device_node) + "/msm_fb_panel_info";
-
-  Sys::fstream fs(file_name, fstream::in);
-  if (!fs.is_open()) {
-    DLOGW("Failed to open msm_fb_panel_info node device node %d", device_node);
-    return;
-  }
-
-  string line;
-  while (Sys::getline_(fs, line)) {
-    uint32_t token_count = 0;
-    const uint32_t max_count = 10;
-    char *tokens[max_count] = { NULL };
-    if (!ParseLine(line.c_str(), "=\n", tokens, max_count, &token_count)) {
-      if (tokens[0] != NULL) {
-        if (!strncmp(tokens[0], "panel_name", strlen("panel_name"))) {
-           snprintf(panel_info->panel_name, sizeof(panel_info->panel_name), "%s", tokens[1]);
-           break;
-        }
-      }
-    }
-  }
-}
-
-void HWDevice::GetHWPanelInfoByNode(int device_node, HWPanelInfo *panel_info) {
-  string file_name = fb_path_ + to_string(device_node) + "/msm_fb_panel_info";
-
-  Sys::fstream fs(file_name, fstream::in);
-  if (!fs.is_open()) {
-    DLOGW("Failed to open msm_fb_panel_info node device node %d", device_node);
-    return;
-  }
-
-  string line;
-  while (Sys::getline_(fs, line)) {
-    uint32_t token_count = 0;
-    const uint32_t max_count = 10;
-    char *tokens[max_count] = { NULL };
-    if (!ParseLine(line.c_str(), tokens, max_count, &token_count)) {
-      if (!strncmp(tokens[0], "pu_en", strlen("pu_en"))) {
-        panel_info->partial_update = atoi(tokens[1]);
-      } else if (!strncmp(tokens[0], "xstart", strlen("xstart"))) {
-        panel_info->left_align = atoi(tokens[1]);
-      } else if (!strncmp(tokens[0], "walign", strlen("walign"))) {
-        panel_info->width_align = atoi(tokens[1]);
-      } else if (!strncmp(tokens[0], "ystart", strlen("ystart"))) {
-        panel_info->top_align = atoi(tokens[1]);
-      } else if (!strncmp(tokens[0], "halign", strlen("halign"))) {
-        panel_info->height_align = atoi(tokens[1]);
-      } else if (!strncmp(tokens[0], "min_w", strlen("min_w"))) {
-        panel_info->min_roi_width = atoi(tokens[1]);
-      } else if (!strncmp(tokens[0], "min_h", strlen("min_h"))) {
-        panel_info->min_roi_height = atoi(tokens[1]);
-      } else if (!strncmp(tokens[0], "roi_merge", strlen("roi_merge"))) {
-        panel_info->needs_roi_merge = atoi(tokens[1]);
-      } else if (!strncmp(tokens[0], "dyn_fps_en", strlen("dyn_fps_en"))) {
-        panel_info->dynamic_fps = atoi(tokens[1]);
-      } else if (!strncmp(tokens[0], "dfps_porch_mode", strlen("dfps_porch_mode"))) {
-        panel_info->dfps_porch_mode = atoi(tokens[1]);
-      } else if (!strncmp(tokens[0], "is_pingpong_split", strlen("is_pingpong_split"))) {
-        panel_info->ping_pong_split = atoi(tokens[1]);
-      } else if (!strncmp(tokens[0], "min_fps", strlen("min_fps"))) {
-        panel_info->min_fps = UINT32(atoi(tokens[1]));
-      } else if (!strncmp(tokens[0], "max_fps", strlen("max_fps"))) {
-        panel_info->max_fps = UINT32(atoi(tokens[1]));
-      } else if (!strncmp(tokens[0], "primary_panel", strlen("primary_panel"))) {
-        panel_info->is_primary_panel = atoi(tokens[1]);
-      } else if (!strncmp(tokens[0], "is_pluggable", strlen("is_pluggable"))) {
-        panel_info->is_pluggable = atoi(tokens[1]);
-      } else if (!strncmp(tokens[0], "pu_roi_cnt", strlen("pu_roi_cnt"))) {
-        panel_info->left_roi_count = UINT32(atoi(tokens[1]));
-        panel_info->right_roi_count = UINT32(atoi(tokens[1]));
-      } else if (!strncmp(tokens[0], "is_hdr_enabled", strlen("is_hdr_enabled"))) {
-        panel_info->hdr_enabled = atoi(tokens[1]);
-      } else if (!strncmp(tokens[0], "peak_brightness", strlen("peak_brightness"))) {
-        panel_info->peak_luminance = UINT32(atoi(tokens[1]));
-      } else if (!strncmp(tokens[0], "average_brightness", strlen("average_brightness"))) {
-        panel_info->average_luminance = UINT32(atoi(tokens[1]));
-      } else if (!strncmp(tokens[0], "blackness_level", strlen("blackness_level"))) {
-        panel_info->blackness_level = UINT32(atoi(tokens[1]));
-      } else if (!strncmp(tokens[0], "white_chromaticity_x", strlen("white_chromaticity_x"))) {
-        panel_info->primaries.white_point[0] = UINT32(atoi(tokens[1]));
-      } else if (!strncmp(tokens[0], "white_chromaticity_y", strlen("white_chromaticity_y"))) {
-        panel_info->primaries.white_point[1] = UINT32(atoi(tokens[1]));
-      } else if (!strncmp(tokens[0], "red_chromaticity_x", strlen("red_chromaticity_x"))) {
-        panel_info->primaries.red[0] = UINT32(atoi(tokens[1]));
-      } else if (!strncmp(tokens[0], "red_chromaticity_y", strlen("red_chromaticity_y"))) {
-        panel_info->primaries.red[1] = UINT32(atoi(tokens[1]));
-      } else if (!strncmp(tokens[0], "green_chromaticity_x", strlen("green_chromaticity_x"))) {
-        panel_info->primaries.green[0] = UINT32(atoi(tokens[1]));
-      } else if (!strncmp(tokens[0], "green_chromaticity_y", strlen("green_chromaticity_y"))) {
-        panel_info->primaries.green[1] = UINT32(atoi(tokens[1]));
-      } else if (!strncmp(tokens[0], "blue_chromaticity_x", strlen("blue_chromaticity_x"))) {
-        panel_info->primaries.blue[0] = UINT32(atoi(tokens[1]));
-      } else if (!strncmp(tokens[0], "blue_chromaticity_y", strlen("blue_chromaticity_y"))) {
-        panel_info->primaries.blue[1] = UINT32(atoi(tokens[1]));
-      } else if (!strncmp(tokens[0], "panel_orientation", strlen("panel_orientation"))) {
-        int32_t panel_orient = atoi(tokens[1]);
-        panel_info->panel_orientation.flip_horizontal = ((panel_orient & MDP_FLIP_LR) > 0);
-        panel_info->panel_orientation.flip_vertical = ((panel_orient & MDP_FLIP_UD) > 0);
-        panel_info->panel_orientation.rotation = ((panel_orient & MDP_ROT_90) > 0);
-      }
-    }
-  }
-
-  GetHWDisplayPortAndMode(device_node, panel_info);
-  GetSplitInfo(device_node, panel_info);
-  GetHWPanelNameByNode(device_node, panel_info);
-  GetHWPanelMaxBrightnessFromNode(panel_info);
-}
-
-void HWDevice::GetHWDisplayPortAndMode(int device_node, HWPanelInfo *panel_info) {
-  DisplayPort *port = &panel_info->port;
-  HWDisplayMode *mode = &panel_info->mode;
-
-  *port = kPortDefault;
-  *mode = kModeDefault;
-
-  string file_name = fb_path_ + to_string(device_node) + "/msm_fb_type";
-
-  Sys::fstream fs(file_name, fstream::in);
-  if (!fs.is_open()) {
-    DLOGW("File not found %s", file_name.c_str());
-    return;
-  }
-
-  string line;
-  if (!Sys::getline_(fs, line)) {
-    return;
-  }
-
-  if ((strncmp(line.c_str(), "mipi dsi cmd panel", strlen("mipi dsi cmd panel")) == 0)) {
-    *port = kPortDSI;
-    *mode = kModeCommand;
-  } else if ((strncmp(line.c_str(), "mipi dsi video panel", strlen("mipi dsi video panel")) == 0)) {
-    *port = kPortDSI;
-    *mode = kModeVideo;
-  } else if ((strncmp(line.c_str(), "lvds panel", strlen("lvds panel")) == 0)) {
-    *port = kPortLVDS;
-    *mode = kModeVideo;
-  } else if ((strncmp(line.c_str(), "edp panel", strlen("edp panel")) == 0)) {
-    *port = kPortEDP;
-    *mode = kModeVideo;
-  } else if ((strncmp(line.c_str(), "dtv panel", strlen("dtv panel")) == 0)) {
-    *port = kPortDTV;
-    *mode = kModeVideo;
-  } else if ((strncmp(line.c_str(), "writeback panel", strlen("writeback panel")) == 0)) {
-    *port = kPortWriteBack;
-    *mode = kModeCommand;
-  } else if ((strncmp(line.c_str(), "dp panel", strlen("dp panel")) == 0)) {
-    *port = kPortDP;
-    *mode = kModeVideo;
-  }
-
-  return;
-}
-
-void HWDevice::GetSplitInfo(int device_node, HWPanelInfo *panel_info) {
-  // Split info - for MDSS Version 5 - No need to check version here
-  string file_name = fb_path_ + to_string(device_node) + "/msm_fb_split";
-
-  Sys::fstream fs(file_name, fstream::in);
-  if (!fs.is_open()) {
-    DLOGW("File not found %s", file_name.c_str());
-    return;
-  }
-
-  // Format "left right" space as delimiter
-  uint32_t token_count = 0;
-  const uint32_t max_count = 10;
-  char *tokens[max_count] = { NULL };
-  string line;
-  if (Sys::getline_(fs, line)) {
-    if (!ParseLine(line.c_str(), tokens, max_count, &token_count)) {
-      panel_info->split_info.left_split = UINT32(atoi(tokens[0]));
-      panel_info->split_info.right_split = UINT32(atoi(tokens[1]));
-    }
-  }
-}
-
-void HWDevice::GetHWPanelMaxBrightnessFromNode(HWPanelInfo *panel_info) {
-  char brightness[kMaxStringLength] = { 0 };
-  char kMaxBrightnessNode[64] = { 0 };
-
-  snprintf(kMaxBrightnessNode, sizeof(kMaxBrightnessNode), "%s",
-           "/sys/class/leds/lcd-backlight/max_brightness");
-
-  panel_info->panel_max_brightness = 0;
-  int fd = Sys::open_(kMaxBrightnessNode, O_RDONLY);
-  if (fd < 0) {
-    DLOGW("Failed to open max brightness node = %s, error = %s", kMaxBrightnessNode,
-          strerror(errno));
-    return;
-  }
-
-  if (Sys::pread_(fd, brightness, sizeof(brightness), 0) > 0) {
-    panel_info->panel_max_brightness = atoi(brightness);
-    DLOGI("Max brightness level = %d", panel_info->panel_max_brightness);
-  } else {
-    DLOGW("Failed to read max brightness level. error = %s", strerror(errno));
-  }
-  Sys::close_(fd);
-}
-
-int HWDevice::ParseLine(const char *input, char *tokens[], const uint32_t max_token,
-                        uint32_t *count) {
-  char *tmp_token = NULL;
-  char *temp_ptr;
-  uint32_t index = 0;
-  const char *delim = ", =\n";
-  if (!input) {
-    return -1;
-  }
-  tmp_token = strtok_r(const_cast<char *>(input), delim, &temp_ptr);
-  while (tmp_token && index < max_token) {
-    tokens[index++] = tmp_token;
-    tmp_token = strtok_r(NULL, delim, &temp_ptr);
-  }
-  *count = index;
-
-  return 0;
-}
-
-int HWDevice::ParseLine(const char *input, const char *delim, char *tokens[],
-                        const uint32_t max_token, uint32_t *count) {
-  char *tmp_token = NULL;
-  char *temp_ptr;
-  uint32_t index = 0;
-  if (!input) {
-    return -1;
-  }
-  tmp_token = strtok_r(const_cast<char *>(input), delim, &temp_ptr);
-  while (tmp_token && index < max_token) {
-    tokens[index++] = tmp_token;
-    tmp_token = strtok_r(NULL, delim, &temp_ptr);
-  }
-  *count = index;
-
-  return 0;
-}
-
-bool HWDevice::EnableHotPlugDetection(int enable) {
-  char hpdpath[kMaxStringLength];
-  const char *value = enable ? "1" : "0";
-
-  // Enable HPD for all pluggable devices.
-  for (int i = 0; i < kFBNodeMax; i++) {
-    HWPanelInfo panel_info;
-    GetHWPanelInfoByNode(i, &panel_info);
-    if (panel_info.is_pluggable == true) {
-      snprintf(hpdpath , sizeof(hpdpath), "%s%d/hpd", fb_path_, i);
-
-      ssize_t length = SysFsWrite(hpdpath, value, 1);
-      if (length <= 0) {
-        return false;
-      }
-    }
-  }
-
-  return true;
-}
-
-void HWDevice::ResetDisplayParams() {
-  memset(&mdp_disp_commit_, 0, sizeof(mdp_disp_commit_));
-  memset(&mdp_in_layers_, 0, sizeof(mdp_in_layers_));
-  memset(&mdp_out_layer_, 0, sizeof(mdp_out_layer_));
-  mdp_out_layer_.buffer.fence = -1;
-  hw_scale_->ResetScaleParams();
-  memset(&pp_params_, 0, sizeof(pp_params_));
-  memset(&igc_lut_data_, 0, sizeof(igc_lut_data_));
-
-  for (size_t i = 0; i < mdp_dest_scalar_data_.size(); i++) {
-    mdp_dest_scalar_data_[i] = {};
-  }
-
-  for (uint32_t i = 0; i < kMaxSDELayers * 2; i++) {
-    mdp_in_layers_[i].buffer.fence = -1;
-  }
-
-  mdp_disp_commit_.version = MDP_COMMIT_VERSION_1_0;
-  mdp_disp_commit_.commit_v1.input_layers = mdp_in_layers_;
-  mdp_disp_commit_.commit_v1.output_layer = &mdp_out_layer_;
-  mdp_disp_commit_.commit_v1.release_fence = -1;
-  mdp_disp_commit_.commit_v1.retire_fence = -1;
-  mdp_disp_commit_.commit_v1.dest_scaler = mdp_dest_scalar_data_.data();
-}
-
-void HWDevice::SetCSC(const ColorMetaData &color_metadata, mdp_color_space *color_space) {
-  switch (color_metadata.colorPrimaries) {
-  case ColorPrimaries_BT601_6_525:
-  case ColorPrimaries_BT601_6_625:
-    *color_space = ((color_metadata.range == Range_Full) ? MDP_CSC_ITU_R_601_FR :
-                                                           MDP_CSC_ITU_R_601);
-    break;
-  case ColorPrimaries_BT709_5:
-    *color_space = MDP_CSC_ITU_R_709;
-    break;
-#if defined MDP_CSC_ITU_R_2020 && defined MDP_CSC_ITU_R_2020_FR
-  case ColorPrimaries_BT2020:
-    *color_space = static_cast<mdp_color_space>((color_metadata.range == Range_Full) ?
-                                                 MDP_CSC_ITU_R_2020_FR : MDP_CSC_ITU_R_2020);
-    break;
-#endif
-  default:
-    break;
-  }
-}
-
-void HWDevice::SetIGC(const LayerBuffer *layer_buffer, uint32_t index) {
-  mdp_input_layer &mdp_layer = mdp_in_layers_[index];
-  mdp_overlay_pp_params &pp_params = pp_params_[index];
-  mdp_igc_lut_data_v1_7 &igc_lut_data = igc_lut_data_[index];
-
-  switch (layer_buffer->igc) {
-  case kIGCsRGB:
-    igc_lut_data.table_fmt = mdp_igc_srgb;
-    pp_params.igc_cfg.ops = MDP_PP_OPS_WRITE | MDP_PP_OPS_ENABLE;
-    break;
-
-  default:
-    pp_params.igc_cfg.ops = MDP_PP_OPS_DISABLE;
-    break;
-  }
-
-  pp_params.config_ops = MDP_OVERLAY_PP_IGC_CFG;
-  pp_params.igc_cfg.version = mdp_igc_v1_7;
-  pp_params.igc_cfg.cfg_payload = &igc_lut_data;
-
-  mdp_layer.pp_info = &pp_params;
-  mdp_layer.flags |= MDP_LAYER_PP;
-}
-
-DisplayError HWDevice::SetCursorPosition(HWLayers *hw_layers, int x, int y) {
-  DTRACE_SCOPED();
-
-  HWLayersInfo &hw_layer_info = hw_layers->info;
-  uint32_t count = UINT32(hw_layer_info.hw_layers.size());
-  uint32_t cursor_index = count - 1;
-  HWPipeInfo *left_pipe = &hw_layers->config[cursor_index].left_pipe;
-
-  mdp_async_layer async_layer = {};
-  async_layer.flags = MDP_LAYER_ASYNC;
-  async_layer.pipe_ndx = left_pipe->pipe_id;
-  async_layer.src.x = UINT32(left_pipe->src_roi.left);
-  async_layer.src.y = UINT32(left_pipe->src_roi.top);
-  async_layer.dst.x = UINT32(left_pipe->dst_roi.left);
-  async_layer.dst.y = UINT32(left_pipe->dst_roi.top);
-
-  mdp_position_update pos_update = {};
-  pos_update.input_layer_cnt = 1;
-  pos_update.input_layers = &async_layer;
-  if (Sys::ioctl_(device_fd_, INT(MSMFB_ASYNC_POSITION_UPDATE), &pos_update) < 0) {
-    if (errno == ESHUTDOWN) {
-      DLOGI_IF(kTagDriverConfig, "Driver is processing shutdown sequence");
-      return kErrorShutDown;
-    }
-    IOCTL_LOGE(MSMFB_ASYNC_POSITION_UPDATE, device_type_);
-    return kErrorHardware;
-  }
-
-  return kErrorNone;
-}
-
-DisplayError HWDevice::GetPPFeaturesVersion(PPFeatureVersion *vers) {
-  return kErrorNotSupported;
-}
-
-DisplayError HWDevice::SetPPFeatures(PPFeaturesConfig *feature_list) {
-  return kErrorNotSupported;
-}
-
-DisplayError HWDevice::SetVSyncState(bool enable) {
-  int vsync_on = enable ? 1 : 0;
-  if (Sys::ioctl_(device_fd_, MSMFB_OVERLAY_VSYNC_CTRL, &vsync_on) < 0) {
-    if (errno == ESHUTDOWN) {
-      DLOGI_IF(kTagDriverConfig, "Driver is processing shutdown sequence");
-      return kErrorShutDown;
-    }
-    IOCTL_LOGE(MSMFB_OVERLAY_VSYNC_CTRL, device_type_);
-    return kErrorHardware;
-  }
-  return kErrorNone;
-}
-
-void HWDevice::SetIdleTimeoutMs(uint32_t timeout_ms) {
-}
-
-DisplayError HWDevice::SetDisplayMode(const HWDisplayMode hw_display_mode) {
-  return kErrorNotSupported;
-}
-
-DisplayError HWDevice::SetRefreshRate(uint32_t refresh_rate) {
-  return kErrorNotSupported;
-}
-
-DisplayError HWDevice::SetPanelBrightness(int level) {
-  return kErrorNotSupported;
-}
-
-DisplayError HWDevice::GetHWScanInfo(HWScanInfo *scan_info) {
-  return kErrorNotSupported;
-}
-
-DisplayError HWDevice::GetVideoFormat(uint32_t config_index, uint32_t *video_format) {
-  return kErrorNotSupported;
-}
-
-DisplayError HWDevice::GetMaxCEAFormat(uint32_t *max_cea_format) {
-  return kErrorNotSupported;
-}
-
-DisplayError HWDevice::OnMinHdcpEncryptionLevelChange(uint32_t min_enc_level) {
-  return kErrorNotSupported;
-}
-
-DisplayError HWDevice::GetPanelBrightness(int *level) {
-  return kErrorNotSupported;
-}
-
-ssize_t HWDevice::SysFsWrite(const char* file_node, const char* value, ssize_t length) {
-  int fd = Sys::open_(file_node, O_RDWR, 0);
-  if (fd < 0) {
-    DLOGW("Open failed = %s", file_node);
-    return -1;
-  }
-  ssize_t len = Sys::pwrite_(fd, value, static_cast<size_t>(length), 0);
-  if (len <= 0) {
-    DLOGE("Write failed for path %s with value %s", file_node, value);
-  }
-  Sys::close_(fd);
-
-  return len;
-}
-
-bool HWDevice::IsFBNodeConnected(int fb_node) {
-  string file_name = fb_path_ + to_string(fb_node) + "/connected";
-
-  Sys::fstream fs(file_name, fstream::in);
-  if (!fs.is_open()) {
-    DLOGW("File not found %s", file_name.c_str());
-    return false;
-  }
-
-  string line;
-  if (!Sys::getline_(fs, line)) {
-    return false;
-  }
-
-  return atoi(line.c_str());
-}
-
-DisplayError HWDevice::SetS3DMode(HWS3DMode s3d_mode) {
-  return kErrorNotSupported;
-}
-
-DisplayError HWDevice::SetScaleLutConfig(HWScaleLutInfo *lut_info) {
-  mdp_scale_luts_info mdp_lut_info = {};
-  mdp_set_cfg cfg = {};
-
-  if (!hw_resource_.has_qseed3) {
-    DLOGV_IF(kTagDriverConfig, "No support for QSEED3 luts");
-    return kErrorNone;
-  }
-
-  if (!lut_info->dir_lut_size && !lut_info->dir_lut && !lut_info->cir_lut_size &&
-      !lut_info->cir_lut && !lut_info->sep_lut_size && !lut_info->sep_lut) {
-      // HWSupports QSEED3, but LutInfo is invalid as scalar is disabled by property or
-      // its loading failed. Driver will use default settings/filter
-      return kErrorNone;
-  }
-
-  mdp_lut_info.dir_lut_size = lut_info->dir_lut_size;
-  mdp_lut_info.dir_lut = lut_info->dir_lut;
-  mdp_lut_info.cir_lut_size = lut_info->cir_lut_size;
-  mdp_lut_info.cir_lut = lut_info->cir_lut;
-  mdp_lut_info.sep_lut_size = lut_info->sep_lut_size;
-  mdp_lut_info.sep_lut = lut_info->sep_lut;
-
-  cfg.flags = MDP_QSEED3_LUT_CFG;
-  cfg.len = sizeof(mdp_scale_luts_info);
-  cfg.payload = reinterpret_cast<uint64_t>(&mdp_lut_info);
-
-  if (Sys::ioctl_(device_fd_, MSMFB_MDP_SET_CFG, &cfg) < 0) {
-    if (errno == ESHUTDOWN) {
-      DLOGI_IF(kTagDriverConfig, "Driver is processing shutdown sequence");
-      return kErrorShutDown;
-    }
-    IOCTL_LOGE(MSMFB_MDP_SET_CFG, device_type_);
-    return kErrorHardware;
-  }
-
-  return kErrorNone;
-}
-
-DisplayError HWDevice::SetMixerAttributes(const HWMixerAttributes &mixer_attributes) {
-  if (!hw_resource_.hw_dest_scalar_info.count) {
-    return kErrorNotSupported;
-  }
-
-  if (mixer_attributes.width > display_attributes_.x_pixels ||
-      mixer_attributes.height > display_attributes_.y_pixels) {
-    DLOGW_IF(kTagDriverConfig, "Input resolution exceeds display resolution! input: res %dx%d "\
-             "display: res %dx%d", mixer_attributes.width, mixer_attributes.height,
-             display_attributes_.x_pixels, display_attributes_.y_pixels);
-    return kErrorNotSupported;
-  }
-
-  uint32_t max_input_width = hw_resource_.hw_dest_scalar_info.max_input_width;
-  if (display_attributes_.is_device_split) {
-    max_input_width *= 2;
-  }
-
-  if (mixer_attributes.width > max_input_width) {
-    DLOGW_IF(kTagDriverConfig, "Input width exceeds width limit! input_width %d width_limit %d",
-             mixer_attributes.width, max_input_width);
-    return kErrorNotSupported;
-  }
-
-  float mixer_aspect_ratio = FLOAT(mixer_attributes.width) / FLOAT(mixer_attributes.height);
-  float display_aspect_ratio =
-    FLOAT(display_attributes_.x_pixels) / FLOAT(display_attributes_.y_pixels);
-
-  if (display_aspect_ratio != mixer_aspect_ratio) {
-    DLOGW_IF(kTagDriverConfig, "Aspect ratio mismatch! input: res %dx%d display: res %dx%d",
-             mixer_attributes.width, mixer_attributes.height, display_attributes_.x_pixels,
-             display_attributes_.y_pixels);
-    return kErrorNotSupported;
-  }
-
-  float scale_x = FLOAT(display_attributes_.x_pixels) / FLOAT(mixer_attributes.width);
-  float scale_y = FLOAT(display_attributes_.y_pixels) / FLOAT(mixer_attributes.height);
-  float max_scale_up = hw_resource_.hw_dest_scalar_info.max_scale_up;
-  if (scale_x > max_scale_up || scale_y > max_scale_up) {
-    DLOGW_IF(kTagDriverConfig, "Up scaling ratio exceeds for destination scalar upscale " \
-             "limit scale_x %f scale_y %f max_scale_up %f", scale_x, scale_y, max_scale_up);
-    return kErrorNotSupported;
-  }
-
-  float mixer_split_ratio = FLOAT(mixer_attributes_.split_left) / FLOAT(mixer_attributes_.width);
-
-  mixer_attributes_ = mixer_attributes;
-  mixer_attributes_.split_left = mixer_attributes_.width;
-  if (display_attributes_.is_device_split) {
-    mixer_attributes_.split_left = UINT32(FLOAT(mixer_attributes.width) * mixer_split_ratio);
-  }
-
-  return kErrorNone;
-}
-
-DisplayError HWDevice::GetMixerAttributes(HWMixerAttributes *mixer_attributes) {
-  if (!mixer_attributes) {
-    return kErrorParameters;
-  }
-
-  *mixer_attributes = mixer_attributes_;
-
-  return kErrorNone;
-}
-
-DisplayError HWDevice::DumpDebugData() {
-  DLOGW("Pingpong timeout occurred in the driver.");
-#ifdef USER_DEBUG
-  // Save the xlogs on ping pong time out
-  const char* xlog_path = "/data/vendor/display/mdp_xlog";
-  DLOGD("Dumping debugfs data to %s", xlog_path);
-  std::ostringstream  dst;
-  auto file = open(xlog_path, O_CREAT | O_TRUNC | O_DSYNC | O_RDWR, S_IRUSR | S_IWUSR | S_IRGRP);
-  if (file < 0) {
-    DLOGE("Couldn't open file: err:%d (%s)", errno, strerror(errno));
-    return kErrorResources;
-  }
-  dst << "+++ MDP:XLOG +++" << std::endl;
-  std::ifstream  src("/sys/kernel/debug/mdp/xlog/dump");
-  dst << src.rdbuf() << std::endl;
-  src.close();
-
-  dst << "+++ MDP:REG_XLOG +++" << std::endl;
-  src.open("/sys/kernel/debug/mdp/xlog/reg_xlog");
-  dst << src.rdbuf() << std::endl;
-  src.close();
-
-  dst << "+++ MDP:DBGBUS_XLOG +++" << std::endl;
-  src.open("/sys/kernel/debug/mdp/xlog/dbgbus_xlog");
-  dst << src.rdbuf() << std::endl;
-  src.close();
-
-  dst << "+++ MDP:VBIF_DBGBUS_XLOG +++" << std::endl;
-  src.open("/sys/kernel/debug/mdp/xlog/vbif_dbgbus_xlog");
-  dst << src.rdbuf() << std::endl;
-  src.close();
-  auto ret = write(file, dst.str().c_str(), dst.str().size());
-  if (ret < 0) {
-    DLOGE("Failed to write xlog data err: %d (%s)", errno, strerror(errno));
-  } else {
-    fsync(file);
-  }
-  close(file);
-  DLOGD("Finished dumping xlogs");;
-#endif
-  return kErrorNone;
-}
-
-}  // namespace sdm
-
diff --git a/sdm/libs/core/fb/hw_device.h b/sdm/libs/core/fb/hw_device.h
deleted file mode 100644
index fe954ae..0000000
--- a/sdm/libs/core/fb/hw_device.h
+++ /dev/null
@@ -1,165 +0,0 @@
-/*
-* Copyright (c) 2014 - 2018, The Linux Foundation. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without modification, are permitted
-* provided that the following conditions are met:
-*    * Redistributions of source code must retain the above copyright notice, this list of
-*      conditions and the following disclaimer.
-*    * Redistributions in binary form must reproduce the above copyright notice, this list of
-*      conditions and the following disclaimer in the documentation and/or other materials provided
-*      with the distribution.
-*    * Neither the name of The Linux Foundation nor the names of its contributors may be used to
-*      endorse or promote products derived from this software without specific prior written
-*      permission.
-*
-* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-* NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
-* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
-* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
-* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#ifndef __HW_DEVICE_H__
-#define __HW_DEVICE_H__
-
-#include <errno.h>
-#include <linux/msm_mdp_ext.h>
-#include <linux/mdss_rotator.h>
-#include <pthread.h>
-#include <vector>
-
-#include "hw_interface.h"
-#include "hw_scale.h"
-
-#define IOCTL_LOGE(ioctl, type) DLOGE("ioctl %s, device = %d errno = %d, desc = %s", #ioctl, \
-                                      type, errno, strerror(errno))
-
-#ifndef MDP_LAYER_MULTIRECT_ENABLE
-#define MDP_LAYER_MULTIRECT_ENABLE 0
-#endif
-
-#ifndef MDP_LAYER_MULTIRECT_PARALLEL_MODE
-#define MDP_LAYER_MULTIRECT_PARALLEL_MODE 0
-#endif
-
-#ifndef MDP_LAYER_SECURE_CAMERA_SESSION
-#define MDP_LAYER_SECURE_CAMERA_SESSION 0
-#endif
-
-namespace sdm {
-class HWInfoInterface;
-
-class HWDevice : public HWInterface {
- public:
-  virtual ~HWDevice() {}
-  virtual DisplayError Init();
-  virtual DisplayError Deinit();
-
- protected:
-  explicit HWDevice(BufferSyncHandler *buffer_sync_handler);
-
-  // From HWInterface
-  virtual DisplayError GetActiveConfig(uint32_t *active_config);
-  virtual DisplayError GetNumDisplayAttributes(uint32_t *count);
-  virtual DisplayError GetDisplayAttributes(uint32_t index,
-                                            HWDisplayAttributes *display_attributes);
-  virtual DisplayError GetHWPanelInfo(HWPanelInfo *panel_info);
-  virtual DisplayError SetDisplayAttributes(uint32_t index);
-  virtual DisplayError SetDisplayAttributes(const HWDisplayAttributes &display_attributes);
-  virtual DisplayError GetConfigIndex(char *mode, uint32_t *index);
-  virtual DisplayError PowerOn(int *release_fence);
-  virtual DisplayError PowerOff();
-  virtual DisplayError Doze(int *release_fence);
-  virtual DisplayError DozeSuspend(int *release_fence);
-  virtual DisplayError Standby();
-  virtual DisplayError Validate(HWLayers *hw_layers);
-  virtual DisplayError Commit(HWLayers *hw_layers);
-  virtual DisplayError Flush();
-  virtual DisplayError GetPPFeaturesVersion(PPFeatureVersion *vers);
-  virtual DisplayError SetPPFeatures(PPFeaturesConfig *feature_list);
-  virtual DisplayError SetVSyncState(bool enable);
-  virtual void SetIdleTimeoutMs(uint32_t timeout_ms);
-  virtual DisplayError SetDisplayMode(const HWDisplayMode hw_display_mode);
-  virtual DisplayError SetRefreshRate(uint32_t refresh_rate);
-  virtual DisplayError SetPanelBrightness(int level);
-  virtual DisplayError GetHWScanInfo(HWScanInfo *scan_info);
-  virtual DisplayError GetVideoFormat(uint32_t config_index, uint32_t *video_format);
-  virtual DisplayError GetMaxCEAFormat(uint32_t *max_cea_format);
-  virtual DisplayError SetCursorPosition(HWLayers *hw_layers, int x, int y);
-  virtual DisplayError OnMinHdcpEncryptionLevelChange(uint32_t min_enc_level);
-  virtual DisplayError GetPanelBrightness(int *level);
-  virtual DisplayError SetAutoRefresh(bool enable) { return kErrorNone; }
-  virtual DisplayError SetS3DMode(HWS3DMode s3d_mode);
-  virtual DisplayError SetScaleLutConfig(HWScaleLutInfo *lut_info);
-  virtual DisplayError SetMixerAttributes(const HWMixerAttributes &mixer_attributes);
-  virtual DisplayError GetMixerAttributes(HWMixerAttributes *mixer_attributes);
-  virtual DisplayError DumpDebugData();
-
-  enum {
-    kHWEventVSync,
-    kHWEventBlank,
-  };
-
-  static const int kMaxStringLength = 1024;
-  static const int kNumPhysicalDisplays = 2;
-  // This indicates the number of fb devices created in the driver for all interfaces. Any addition
-  // of new fb devices should be added here.
-  static const int kFBNodeMax = 4;
-
-  void DumpLayerCommit(const mdp_layer_commit &layer_commit);
-  DisplayError SetFormat(const LayerBufferFormat &source, uint32_t *target);
-  DisplayError SetStride(HWDeviceType device_type, LayerBufferFormat format,
-                         uint32_t width, uint32_t *target);
-  void SetBlending(const LayerBlending &source, mdss_mdp_blend_op *target);
-  void SetRect(const LayerRect &source, mdp_rect *target);
-  void SetMDPFlags(const Layer *layer, const bool &is_rotator_used,
-                   bool async_cursor_updates, uint32_t *mdp_flags);
-  // Retrieves HW FrameBuffer Node Index
-  int GetFBNodeIndex(HWDeviceType device_type);
-  // Populates HWPanelInfo based on node index
-  void PopulateHWPanelInfo();
-  void GetHWPanelInfoByNode(int device_node, HWPanelInfo *panel_info);
-  void GetHWPanelNameByNode(int device_node, HWPanelInfo *panel_info);
-  void GetHWDisplayPortAndMode(int device_node, HWPanelInfo *panel_info);
-  void GetSplitInfo(int device_node, HWPanelInfo *panel_info);
-  void GetHWPanelMaxBrightnessFromNode(HWPanelInfo *panel_info);
-  int ParseLine(const char *input, char *tokens[], const uint32_t max_token, uint32_t *count);
-  int ParseLine(const char *input, const char *delim, char *tokens[],
-                const uint32_t max_token, uint32_t *count);
-  void ResetDisplayParams();
-  void SetCSC(const ColorMetaData &color_metadata, mdp_color_space *color_space);
-  void SetIGC(const LayerBuffer *layer_buffer, uint32_t index);
-
-  bool EnableHotPlugDetection(int enable);
-  ssize_t SysFsWrite(const char* file_node, const char* value, ssize_t length);
-  bool IsFBNodeConnected(int fb_node);
-
-  HWResourceInfo hw_resource_;
-  HWPanelInfo hw_panel_info_;
-  HWInfoInterface *hw_info_intf_;
-  int fb_node_index_;
-  const char *fb_path_;
-  BufferSyncHandler *buffer_sync_handler_;
-  int device_fd_ = -1;
-  int stored_retire_fence = -1;
-  HWDeviceType device_type_;
-  mdp_layer_commit mdp_disp_commit_;
-  mdp_input_layer mdp_in_layers_[kMaxSDELayers * 2];   // split panel (left + right)
-  HWScale *hw_scale_ = NULL;
-  mdp_overlay_pp_params pp_params_[kMaxSDELayers * 2];
-  mdp_igc_lut_data_v1_7 igc_lut_data_[kMaxSDELayers * 2];
-  mdp_output_layer mdp_out_layer_;
-  const char *device_name_;
-  bool synchronous_commit_;
-  HWDisplayAttributes display_attributes_ = {};
-  HWMixerAttributes mixer_attributes_ = {};
-  std::vector<mdp_destination_scaler_data> mdp_dest_scalar_data_;
-};
-
-}  // namespace sdm
-
-#endif  // __HW_DEVICE_H__
-
diff --git a/sdm/libs/core/fb/hw_events.cpp b/sdm/libs/core/fb/hw_events.cpp
deleted file mode 100644
index d944624..0000000
--- a/sdm/libs/core/fb/hw_events.cpp
+++ /dev/null
@@ -1,257 +0,0 @@
-/*
-* Copyright (c) 2015 - 2017, The Linux Foundation. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without
-* modification, are permitted provided that the following conditions are
-* met:
-*     * Redistributions of source code must retain the above copyright
-*       notice, this list of conditions and the following disclaimer.
-*     * Redistributions in binary form must reproduce the above
-*       copyright notice, this list of conditions and the following
-*       disclaimer in the documentation and/or other materials provided
-*       with the distribution.
-*     * Neither the name of The Linux Foundation nor the names of its
-*       contributors may be used to endorse or promote products derived
-*       from this software without specific prior written permission.
-*
-* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
-* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
-* ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
-* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
-* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <math.h>
-#include <fcntl.h>
-#include <sys/types.h>
-#include <sys/resource.h>
-#include <sys/prctl.h>
-#include <utils/debug.h>
-#include <utils/sys.h>
-#include <pthread.h>
-#include <algorithm>
-#include <vector>
-#include <map>
-#include <utility>
-
-#include "hw_events.h"
-
-#define __CLASS__ "HWEvents"
-
-namespace sdm {
-
-pollfd HWEvents::InitializePollFd(HWEventData *event_data) {
-  char node_path[kMaxStringLength] = {0};
-  char data[kMaxStringLength] = {0};
-  pollfd poll_fd = {0};
-  poll_fd.fd = -1;
-
-  if (event_data->event_type == HWEvent::EXIT) {
-    // Create an eventfd to be used to unblock the poll system call when
-    // a thread is exiting.
-    poll_fd.fd = Sys::eventfd_(0, 0);
-    poll_fd.events |= POLLIN;
-    exit_fd_ = poll_fd.fd;
-  } else {
-    snprintf(node_path, sizeof(node_path), "%s%d/%s", fb_path_, fb_num_,
-             map_event_to_node_[event_data->event_type]);
-    poll_fd.fd = Sys::open_(node_path, O_RDONLY);
-    poll_fd.events |= POLLPRI | POLLERR;
-  }
-
-  if (poll_fd.fd < 0) {
-    DLOGW("open failed for display=%d event=%s, error=%s", fb_num_,
-          map_event_to_node_[event_data->event_type], strerror(errno));
-    return poll_fd;
-  }
-
-  // Read once on all fds to clear data on all fds.
-  Sys::pread_(poll_fd.fd, data , kMaxStringLength, 0);
-
-  return poll_fd;
-}
-
-DisplayError HWEvents::SetEventParser(HWEvent event_type, HWEventData *event_data) {
-  DisplayError error = kErrorNone;
-  switch (event_type) {
-    case HWEvent::VSYNC:
-      event_data->event_parser = &HWEvents::HandleVSync;
-      break;
-    case HWEvent::IDLE_NOTIFY:
-      event_data->event_parser = &HWEvents::HandleIdleTimeout;
-      break;
-    case HWEvent::CEC_READ_MESSAGE:
-      event_data->event_parser = &HWEvents::HandleCECMessage;
-      break;
-    case HWEvent::EXIT:
-      event_data->event_parser = &HWEvents::HandleThreadExit;
-      break;
-    case HWEvent::SHOW_BLANK_EVENT:
-      event_data->event_parser = &HWEvents::HandleBlank;
-      break;
-    case HWEvent::THERMAL_LEVEL:
-      event_data->event_parser = &HWEvents::HandleThermal;
-      break;
-    case HWEvent::IDLE_POWER_COLLAPSE:
-      event_data->event_parser = &HWEvents::HandleIdlePowerCollapse;
-      break;
-    case HWEvent::PINGPONG_TIMEOUT:
-      event_data->event_parser = &HWEvents::HandlePingPongTimeout;
-      break;
-    default:
-      error = kErrorParameters;
-      break;
-  }
-
-  return error;
-}
-
-void HWEvents::PopulateHWEventData() {
-  for (uint32_t i = 0; i < event_list_.size(); i++) {
-    HWEventData event_data;
-    event_data.event_type = event_list_[i];
-    SetEventParser(event_list_[i], &event_data);
-    poll_fds_[i] = InitializePollFd(&event_data);
-    event_data_list_.push_back(event_data);
-  }
-}
-
-DisplayError HWEvents::Init(int fb_num, HWEventHandler *event_handler,
-                            const vector<HWEvent> &event_list,
-                            const HWInterface *hw_intf) {
-  if (!event_handler)
-    return kErrorParameters;
-
-  event_handler_ = event_handler;
-  fb_num_ = fb_num;
-  event_list_ = event_list;
-  poll_fds_.resize(event_list_.size());
-  event_thread_name_ += " - " + std::to_string(fb_num_);
-  map_event_to_node_ = {{HWEvent::VSYNC, "vsync_event"},
-                        {HWEvent::EXIT, "thread_exit"},
-                        {HWEvent::IDLE_NOTIFY, "idle_notify"},
-                        {HWEvent::SHOW_BLANK_EVENT, "show_blank_event"},
-                        {HWEvent::CEC_READ_MESSAGE, "cec/rd_msg"},
-                        {HWEvent::THERMAL_LEVEL, "msm_fb_thermal_level"},
-                        {HWEvent::IDLE_POWER_COLLAPSE, "idle_power_collapse"},
-                        {HWEvent::PINGPONG_TIMEOUT, "pingpong_timeout"}};
-
-  PopulateHWEventData();
-
-  if (pthread_create(&event_thread_, NULL, &DisplayEventThread, this) < 0) {
-    DLOGE("Failed to start %s, error = %s", event_thread_name_.c_str());
-    return kErrorResources;
-  }
-
-  return kErrorNone;
-}
-
-DisplayError HWEvents::Deinit() {
-  exit_threads_ = true;
-  Sys::pthread_cancel_(event_thread_);
-
-  uint64_t exit_value = 1;
-  ssize_t write_size = Sys::write_(exit_fd_, &exit_value, sizeof(uint64_t));
-  if (write_size != sizeof(uint64_t))
-    DLOGW("Error triggering exit_fd_ (%d). write size = %d, error = %s", exit_fd_, write_size,
-          strerror(errno));
-
-  pthread_join(event_thread_, NULL);
-
-  for (uint32_t i = 0; i < event_list_.size(); i++) {
-    Sys::close_(poll_fds_[i].fd);
-    poll_fds_[i].fd = -1;
-  }
-
-  return kErrorNone;
-}
-
-void* HWEvents::DisplayEventThread(void *context) {
-  if (context) {
-    return reinterpret_cast<HWEvents *>(context)->DisplayEventHandler();
-  }
-
-  return NULL;
-}
-
-void* HWEvents::DisplayEventHandler() {
-  char data[kMaxStringLength] = {0};
-
-  prctl(PR_SET_NAME, event_thread_name_.c_str(), 0, 0, 0);
-  setpriority(PRIO_PROCESS, 0, kThreadPriorityUrgent);
-
-  while (!exit_threads_) {
-    int error = Sys::poll_(poll_fds_.data(), UINT32(event_list_.size()), -1);
-
-    if (error <= 0) {
-      DLOGW("poll failed. error = %s", strerror(errno));
-      continue;
-    }
-
-    for (uint32_t event = 0; event < event_list_.size(); event++) {
-      pollfd &poll_fd = poll_fds_[event];
-
-      if (event_list_.at(event) == HWEvent::EXIT) {
-        if ((poll_fd.revents & POLLIN) && (Sys::read_(poll_fd.fd, data, kMaxStringLength) > 0)) {
-          (this->*(event_data_list_[event]).event_parser)(data);
-        }
-      } else {
-        if ((poll_fd.revents & POLLPRI) &&
-                (Sys::pread_(poll_fd.fd, data, kMaxStringLength, 0) > 0)) {
-          (this->*(event_data_list_[event]).event_parser)(data);
-        }
-      }
-    }
-  }
-
-  pthread_exit(0);
-
-  return NULL;
-}
-
-void HWEvents::HandleVSync(char *data) {
-  int64_t timestamp = 0;
-  if (!strncmp(data, "VSYNC=", strlen("VSYNC="))) {
-    timestamp = strtoll(data + strlen("VSYNC="), NULL, 0);
-  }
-
-  event_handler_->VSync(timestamp);
-}
-
-void HWEvents::HandleIdleTimeout(char *data) {
-  event_handler_->IdleTimeout();
-}
-
-void HWEvents::HandlePingPongTimeout(char *data) {
-  event_handler_->PingPongTimeout();
-}
-
-void HWEvents::HandleThermal(char *data) {
-  int64_t thermal_level = 0;
-  if (!strncmp(data, "thermal_level=", strlen("thermal_level="))) {
-    thermal_level = strtoll(data + strlen("thermal_level="), NULL, 0);
-  }
-
-  DLOGI("Received thermal notification with thermal level = %d", thermal_level);
-
-  event_handler_->ThermalEvent(thermal_level);
-}
-
-void HWEvents::HandleCECMessage(char *data) {
-  event_handler_->CECMessage(data);
-}
-
-void HWEvents::HandleIdlePowerCollapse(char *data) {
-  event_handler_->IdlePowerCollapse();
-}
-
-}  // namespace sdm
diff --git a/sdm/libs/core/fb/hw_events.h b/sdm/libs/core/fb/hw_events.h
deleted file mode 100644
index 8ffd6d5..0000000
--- a/sdm/libs/core/fb/hw_events.h
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
-* Copyright (c) 2015 - 2017, The Linux Foundation. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without modification, are permitted
-* provided that the following conditions are met:
-*    * Redistributions of source code must retain the above copyright notice, this list of
-*      conditions and the following disclaimer.
-*    * Redistributions in binary form must reproduce the above copyright notice, this list of
-*      conditions and the following disclaimer in the documentation and/or other materials provided
-*      with the distribution.
-*    * Neither the name of The Linux Foundation nor the names of its contributors may be used to
-*      endorse or promote products derived from this software without specific prior written
-*      permission.
-*
-* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-* NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
-* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
-* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
-* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#ifndef __HW_EVENTS_H__
-#define __HW_EVENTS_H__
-
-#include <sys/poll.h>
-#include <string>
-#include <vector>
-#include <map>
-#include <utility>
-
-#include "hw_interface.h"
-#include "hw_events_interface.h"
-
-namespace sdm {
-
-using std::vector;
-using std::map;
-
-class HWEvents : public HWEventsInterface {
- public:
-  virtual DisplayError Init(int fb_num, HWEventHandler *event_handler,
-                            const vector<HWEvent> &event_list,
-                            const HWInterface *hw_intf);
-  virtual DisplayError Deinit();
-  virtual DisplayError SetEventState(HWEvent event, bool enable, void *aux = nullptr) {
-    return kErrorNotSupported;
-  }
-
- private:
-  static const int kMaxStringLength = 1024;
-
-  typedef void (HWEvents::*EventParser)(char *);
-
-  struct HWEventData {
-    HWEvent event_type {};
-    EventParser event_parser {};
-  };
-
-  static void* DisplayEventThread(void *context);
-  void* DisplayEventHandler();
-  void HandleVSync(char *data);
-  void HandleBlank(char *data) { }
-  void HandleIdleTimeout(char *data);
-  void HandleThermal(char *data);
-  void HandleCECMessage(char *data);
-  void HandleThreadExit(char *data) { }
-  void HandleIdlePowerCollapse(char *data);
-  void HandlePingPongTimeout(char *data);
-  void PopulateHWEventData();
-  DisplayError SetEventParser(HWEvent event_type, HWEventData *event_data);
-  pollfd InitializePollFd(HWEventData *event_data);
-
-  HWEventHandler *event_handler_ = {};
-  vector<HWEvent> event_list_ = {};
-  vector<HWEventData> event_data_list_ = {};
-  vector<pollfd> poll_fds_ = {};
-  map<HWEvent, const char *> map_event_to_node_ = {};
-  pthread_t event_thread_ = {};
-  std::string event_thread_name_ = "SDM_EventThread";
-  bool exit_threads_ = false;
-  const char* fb_path_ = "/sys/devices/virtual/graphics/fb";
-  int fb_num_ = -1;
-  int exit_fd_ = -1;
-};
-
-}  // namespace sdm
-
-#endif  // __HW_EVENTS_H__
-
diff --git a/sdm/libs/core/fb/hw_hdmi.cpp b/sdm/libs/core/fb/hw_hdmi.cpp
deleted file mode 100644
index 532c3ba..0000000
--- a/sdm/libs/core/fb/hw_hdmi.cpp
+++ /dev/null
@@ -1,1123 +0,0 @@
-/*
-* Copyright (c) 2015 - 2018, The Linux Foundation. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without
-* modification, are permitted provided that the following conditions are
-* met:
-*     * Redistributions of source code must retain the above copyright
-*       notice, this list of conditions and the following disclaimer.
-*     * Redistributions in binary form must reproduce the above
-*       copyright notice, this list of conditions and the following
-*       disclaimer in the documentation and/or other materials provided
-*       with the distribution.
-*     * Neither the name of The Linux Foundation nor the names of its
-*       contributors may be used to endorse or promote products derived
-*       from this software without specific prior written permission.
-*
-* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
-* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
-* ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
-* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
-* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#include <stdio.h>
-#include <unistd.h>
-#include <string.h>
-#include <sys/ioctl.h>
-#include <ctype.h>
-#include <fcntl.h>
-#include <linux/videodev2.h>
-#include <utils/debug.h>
-#include <utils/sys.h>
-#include <utils/formats.h>
-
-#include <string>
-#include <vector>
-#include <map>
-#include <utility>
-
-#include "hw_hdmi.h"
-
-#define __CLASS__ "HWHDMI"
-
-#define  MIN_HDR_RESET_WAITTIME_SEC 2
-
-namespace sdm {
-
-#ifdef MDP_HDR_STREAM
-static int32_t GetEOTF(const GammaTransfer &transfer) {
-  int32_t mdp_transfer = -1;
-
-  switch (transfer) {
-  case Transfer_SMPTE_ST2084:
-    mdp_transfer = MDP_HDR_EOTF_SMTPE_ST2084;
-    break;
-  case Transfer_HLG:
-    mdp_transfer = MDP_HDR_EOTF_HLG;
-    break;
-  default:
-    DLOGW("Unknown Transfer: %d", transfer);
-  }
-
-  return mdp_transfer;
-}
-
-static int32_t GetColoriMetry(const LayerBuffer & layer_buffer) {
-  bool is_yuv = layer_buffer.flags.video;
-  int32_t colorimetry = -1;
-
-  if (is_yuv) {
-    switch (layer_buffer.color_metadata.colorPrimaries) {
-    case ColorPrimaries_BT601_6_525:
-    case ColorPrimaries_BT601_6_625:
-      colorimetry = MDP_COLORIMETRY_YCBCR_ITU_R_BT_601;
-      break;
-    case ColorPrimaries_BT709_5:
-      colorimetry = MDP_COLORIMETRY_YCBCR_ITU_R_BT_709;
-      break;
-    case ColorPrimaries_BT2020:
-      colorimetry = MDP_COLORIMETRY_YCBCR_ITU_R_BT_2020_YCBCR;
-      break;
-    default:
-      DLOGW("Unknown color primary = %d for YUV", layer_buffer.color_metadata.colorPrimaries);
-    }
-  }
-
-  return colorimetry;
-}
-
-static int32_t GetPixelEncoding(const LayerBuffer &layer_buffer) {
-  bool is_yuv = layer_buffer.flags.video;
-  int32_t mdp_pixel_encoding = -1;
-  mdp_pixel_encoding = MDP_PIXEL_ENCODING_RGB;  // set RGB as default
-
-  if (is_yuv) {
-    switch (layer_buffer.format) {
-    case kFormatYCbCr420SemiPlanarVenus:
-    case kFormatYCbCr420SPVenusUbwc:
-    case kFormatYCbCr420Planar:
-    case kFormatYCrCb420Planar:
-    case kFormatYCrCb420PlanarStride16:
-    case kFormatYCbCr420SemiPlanar:
-    case kFormatYCrCb420SemiPlanar:
-    case kFormatYCbCr420P010:
-    case kFormatYCbCr420TP10Ubwc:
-      mdp_pixel_encoding = MDP_PIXEL_ENCODING_YCBCR_420;
-      break;
-    case kFormatYCbCr422H2V1Packed:
-    case kFormatYCrCb422H2V1SemiPlanar:
-    case kFormatYCrCb422H1V2SemiPlanar:
-    case kFormatYCbCr422H2V1SemiPlanar:
-    case kFormatYCbCr422H1V2SemiPlanar:
-      mdp_pixel_encoding = MDP_PIXEL_ENCODING_YCBCR_422;
-      break;
-    default:  // other yuv formats
-      DLOGW("New YUV format = %d, need to add support", layer_buffer.format);
-      break;
-    }
-  }
-
-  return mdp_pixel_encoding;
-}
-static int32_t GetBitsPerComponent(const LayerBuffer &layer_buffer) {
-  bool is_yuv = layer_buffer.flags.video;
-  bool is_10_bit = Is10BitFormat(layer_buffer.format);
-  int32_t mdp_bpc = -1;
-
-  if (is_yuv) {
-    mdp_bpc = is_10_bit ? MDP_YUV_10_BPC : MDP_YUV_8_BPC;
-  } else {
-    mdp_bpc = is_10_bit ? MDP_RGB_10_BPC : MDP_RGB_8_BPC;
-  }
-
-  return mdp_bpc;
-}
-
-static uint32_t GetRange(const ColorRange &range) {
-  return ((range == Range_Full) ? MDP_DYNAMIC_RANGE_VESA : MDP_DYNAMIC_RANGE_CEA);
-}
-
-static uint32_t GetContentType(const LayerBuffer &layer_buffer) {
-  return (layer_buffer.flags.video ? MDP_CONTENT_TYPE_VIDEO : MDP_CONTENT_TYPE_GRAPHICS);
-}
-#endif
-
-static bool MapHDMIDisplayTiming(const msm_hdmi_mode_timing_info *mode,
-                                 fb_var_screeninfo *info) {
-  if (!mode || !info) {
-    return false;
-  }
-
-  info->reserved[0] = 0;
-  info->reserved[1] = 0;
-  info->reserved[2] = 0;
-  info->reserved[3] = (info->reserved[3] & 0xFFFF) | (mode->video_format << 16);
-  info->xoffset = 0;
-  info->yoffset = 0;
-  info->xres = mode->active_h;
-  info->yres = mode->active_v;
-  info->pixclock = (mode->pixel_freq) * 1000;
-  info->vmode = mode->interlaced ? FB_VMODE_INTERLACED : FB_VMODE_NONINTERLACED;
-  info->right_margin = mode->front_porch_h;
-  info->hsync_len = mode->pulse_width_h;
-  info->left_margin = mode->back_porch_h;
-  info->lower_margin = mode->front_porch_v;
-  info->vsync_len = mode->pulse_width_v;
-  info->upper_margin = mode->back_porch_v;
-
-  info->grayscale = V4L2_PIX_FMT_RGB24;
-  // If the mode supports YUV420 set grayscale to the FOURCC value for YUV420.
-  std::bitset<32> pixel_formats = mode->pixel_formats;
-  if (pixel_formats[1]) {
-    info->grayscale = V4L2_PIX_FMT_NV12;
-  }
-
-  return true;
-}
-
-HWHDMI::HWHDMI(BufferSyncHandler *buffer_sync_handler,  HWInfoInterface *hw_info_intf)
-  : HWDevice(buffer_sync_handler), hw_scan_info_(), active_config_index_(0) {
-  HWDevice::device_type_ = kDeviceHDMI;
-  HWDevice::device_name_ = "HDMI Display Device";
-  HWDevice::hw_info_intf_ = hw_info_intf;
-  (void)hdr_reset_start_;
-  (void)hdr_reset_end_;
-  (void)reset_hdr_flag_;
-  (void)cdm_color_space_;
-}
-
-DisplayError HWHDMI::Init() {
-  DisplayError error = kErrorNone;
-
-  SetSourceProductInformation("vendor_name", "ro.product.manufacturer");
-  SetSourceProductInformation("product_description", "ro.product.name");
-
-  error = HWDevice::Init();
-  if (error != kErrorNone) {
-    return error;
-  }
-
-  mdp_dest_scalar_data_.resize(hw_resource_.hw_dest_scalar_info.count);
-
-  error = ReadEDIDInfo();
-  if (error != kErrorNone) {
-    Deinit();
-    return error;
-  }
-
-  if (!IsResolutionFilePresent()) {
-    Deinit();
-    return kErrorHardware;
-  }
-
-  error = ReadTimingInfo();
-  if (error != kErrorNone) {
-    Deinit();
-    return error;
-  }
-
-  ReadScanInfo();
-
-  GetPanelS3DMode();
-
-  s3d_mode_sdm_to_mdp_.insert(std::pair<HWS3DMode, msm_hdmi_s3d_mode>
-                             (kS3DModeNone, HDMI_S3D_NONE));
-  s3d_mode_sdm_to_mdp_.insert(std::pair<HWS3DMode, msm_hdmi_s3d_mode>
-                             (kS3DModeLR, HDMI_S3D_SIDE_BY_SIDE));
-  s3d_mode_sdm_to_mdp_.insert(std::pair<HWS3DMode, msm_hdmi_s3d_mode>
-                             (kS3DModeRL, HDMI_S3D_SIDE_BY_SIDE));
-  s3d_mode_sdm_to_mdp_.insert(std::pair<HWS3DMode, msm_hdmi_s3d_mode>
-                             (kS3DModeTB, HDMI_S3D_TOP_AND_BOTTOM));
-  s3d_mode_sdm_to_mdp_.insert(std::pair<HWS3DMode, msm_hdmi_s3d_mode>
-                             (kS3DModeFP, HDMI_S3D_FRAME_PACKING));
-
-  return error;
-}
-
-DisplayError HWHDMI::GetNumDisplayAttributes(uint32_t *count) {
-  *count = UINT32(hdmi_modes_.size());
-  if (*count <= 0) {
-    return kErrorHardware;
-  }
-
-  return kErrorNone;
-}
-
-DisplayError HWHDMI::GetActiveConfig(uint32_t *active_config_index) {
-  *active_config_index = active_config_index_;
-  return kErrorNone;
-}
-
-DisplayError HWHDMI::ReadEDIDInfo() {
-  ssize_t length = -1;
-  char edid_str[kPageSize] = {'\0'};
-  char edid_path[kMaxStringLength] = {'\0'};
-  snprintf(edid_path, sizeof(edid_path), "%s%d/edid_modes", fb_path_, fb_node_index_);
-  int edid_file = Sys::open_(edid_path, O_RDONLY);
-  if (edid_file < 0) {
-    DLOGE("EDID file open failed.");
-    return kErrorHardware;
-  }
-
-  length = Sys::pread_(edid_file, edid_str, sizeof(edid_str)-1, 0);
-  if (length <= 0) {
-    DLOGE("%s: edid_modes file empty");
-    return kErrorHardware;
-  }
-  Sys::close_(edid_file);
-
-  DLOGI("EDID mode string: %s", edid_str);
-  while (length > 1 && isspace(edid_str[length-1])) {
-    --length;
-  }
-  edid_str[length] = '\0';
-
-  if (length > 0) {
-    // Get EDID modes from the EDID string
-    char *ptr = edid_str;
-    const uint32_t edid_count_max = 128;
-    char *tokens[edid_count_max] = { NULL };
-    uint32_t hdmi_mode_count = 0;
-
-    ParseLine(ptr, tokens, edid_count_max, &hdmi_mode_count);
-
-    supported_video_modes_.resize(hdmi_mode_count);
-
-    hdmi_modes_.resize(hdmi_mode_count);
-    for (uint32_t i = 0; i < hdmi_mode_count; i++) {
-      hdmi_modes_[i] = UINT32(atoi(tokens[i]));
-    }
-  }
-
-  return kErrorNone;
-}
-
-DisplayError HWHDMI::GetDisplayAttributes(uint32_t index,
-                                          HWDisplayAttributes *display_attributes) {
-  DTRACE_SCOPED();
-
-  if (index >= hdmi_modes_.size()) {
-    return kErrorNotSupported;
-  }
-
-  // Get the resolution info from the look up table
-  msm_hdmi_mode_timing_info *timing_mode = &supported_video_modes_[0];
-  for (uint32_t i = 0; i < hdmi_modes_.size(); i++) {
-    msm_hdmi_mode_timing_info *cur = &supported_video_modes_[i];
-    if (cur->video_format == hdmi_modes_[index]) {
-      timing_mode = cur;
-      break;
-    }
-  }
-  display_attributes->x_pixels = timing_mode->active_h;
-  display_attributes->y_pixels = timing_mode->active_v;
-  display_attributes->v_front_porch = timing_mode->front_porch_v;
-  display_attributes->v_back_porch = timing_mode->back_porch_v;
-  display_attributes->v_pulse_width = timing_mode->pulse_width_v;
-  uint32_t h_blanking = timing_mode->front_porch_h + timing_mode->back_porch_h +
-      timing_mode->pulse_width_h;
-  display_attributes->h_total = timing_mode->active_h + h_blanking;
-  display_attributes->x_dpi = 0;
-  display_attributes->y_dpi = 0;
-  display_attributes->fps = timing_mode->refresh_rate / 1000;
-  display_attributes->vsync_period_ns = UINT32(1000000000L / display_attributes->fps);
-  display_attributes->is_device_split = false;
-  if (display_attributes->x_pixels > hw_resource_.max_mixer_width) {
-    display_attributes->is_device_split = true;
-    display_attributes->h_total += h_blanking;
-  }
-
-  GetDisplayS3DSupport(index, display_attributes);
-  std::bitset<32> pixel_formats = timing_mode->pixel_formats;
-
-  display_attributes->is_yuv = pixel_formats[1];
-
-  return kErrorNone;
-}
-
-DisplayError HWHDMI::SetDisplayAttributes(uint32_t index) {
-  DTRACE_SCOPED();
-
-  if (index > hdmi_modes_.size()) {
-    return kErrorNotSupported;
-  }
-
-  // Variable screen info
-  fb_var_screeninfo vscreeninfo = {};
-  if (Sys::ioctl_(device_fd_, FBIOGET_VSCREENINFO, &vscreeninfo) < 0) {
-    IOCTL_LOGE(FBIOGET_VSCREENINFO, device_type_);
-    return kErrorHardware;
-  }
-
-  DLOGI("GetInfo<Mode=%d %dx%d (%d,%d,%d),(%d,%d,%d) %dMHz>", vscreeninfo.reserved[3],
-        vscreeninfo.xres, vscreeninfo.yres, vscreeninfo.right_margin, vscreeninfo.hsync_len,
-        vscreeninfo.left_margin, vscreeninfo.lower_margin, vscreeninfo.vsync_len,
-        vscreeninfo.upper_margin, vscreeninfo.pixclock/1000000);
-
-  msm_hdmi_mode_timing_info *timing_mode = &supported_video_modes_[0];
-  for (uint32_t i = 0; i < hdmi_modes_.size(); i++) {
-    msm_hdmi_mode_timing_info *cur = &supported_video_modes_[i];
-    if (cur->video_format == hdmi_modes_[index]) {
-      timing_mode = cur;
-      break;
-    }
-  }
-
-  if (MapHDMIDisplayTiming(timing_mode, &vscreeninfo) == false) {
-    return kErrorParameters;
-  }
-
-  msmfb_metadata metadata = {};
-  metadata.op = metadata_op_vic;
-  metadata.data.video_info_code = timing_mode->video_format;
-  if (Sys::ioctl_(device_fd_, MSMFB_METADATA_SET, &metadata) < 0) {
-    IOCTL_LOGE(MSMFB_METADATA_SET, device_type_);
-    return kErrorHardware;
-  }
-
-  DLOGI("SetInfo<Mode=%d %dx%d (%d,%d,%d),(%d,%d,%d) %dMHz>", vscreeninfo.reserved[3] & 0xFF00,
-        vscreeninfo.xres, vscreeninfo.yres, vscreeninfo.right_margin, vscreeninfo.hsync_len,
-        vscreeninfo.left_margin, vscreeninfo.lower_margin, vscreeninfo.vsync_len,
-        vscreeninfo.upper_margin, vscreeninfo.pixclock/1000000);
-
-  vscreeninfo.activate = FB_ACTIVATE_NOW | FB_ACTIVATE_ALL | FB_ACTIVATE_FORCE;
-  if (Sys::ioctl_(device_fd_, FBIOPUT_VSCREENINFO, &vscreeninfo) < 0) {
-    IOCTL_LOGE(FBIOPUT_VSCREENINFO, device_type_);
-    return kErrorHardware;
-  }
-
-  active_config_index_ = index;
-
-  frame_rate_ = timing_mode->refresh_rate;
-
-  // Get the display attributes for current active config index
-  GetDisplayAttributes(active_config_index_, &display_attributes_);
-  UpdateMixerAttributes();
-
-  supported_s3d_modes_.clear();
-  supported_s3d_modes_.push_back(kS3DModeNone);
-  for (uint32_t mode = kS3DModeNone + 1; mode < kS3DModeMax; mode ++) {
-    if (display_attributes_.s3d_config[(HWS3DMode)mode]) {
-      supported_s3d_modes_.push_back((HWS3DMode)mode);
-    }
-  }
-
-  SetS3DMode(kS3DModeNone);
-
-  return kErrorNone;
-}
-
-DisplayError HWHDMI::GetConfigIndex(char *mode, uint32_t *index) {
-  std::string str(mode);
-  uint32_t value = UINT32(stoi(str));
-
-  // Check if the mode is valid and return corresponding index
-  for (uint32_t i = 0; i < hdmi_modes_.size(); i++) {
-    if (hdmi_modes_[i] == value) {
-      *index = i;
-      DLOGI("Index = %d for config = %d", *index, value);
-      return kErrorNone;
-    }
-  }
-
-  DLOGE("Config = %d not supported", value);
-  return kErrorNotSupported;
-}
-
-DisplayError HWHDMI::Validate(HWLayers *hw_layers) {
-  HWDevice::ResetDisplayParams();
-  return HWDevice::Validate(hw_layers);
-}
-
-DisplayError HWHDMI::Commit(HWLayers *hw_layers) {
-  DisplayError error = UpdateHDRMetaData(hw_layers);
-  if (error != kErrorNone) {
-    return error;
-  }
-  if (cdm_color_space_commit_) {
-#ifdef MDP_COMMIT_UPDATE_CDM_COLOR_SPACE
-    mdp_layer_commit_v1 &mdp_commit = mdp_disp_commit_.commit_v1;
-    mdp_commit.cdm_color_space = cdm_color_space_;
-    mdp_commit.flags |= MDP_COMMIT_UPDATE_CDM_COLOR_SPACE;
-#endif
-  }
-
-  error = HWDevice::Commit(hw_layers);
-  if (cdm_color_space_commit_)
-    cdm_color_space_commit_ = false;
-
-  return error;
-}
-
-DisplayError HWHDMI::GetHWScanInfo(HWScanInfo *scan_info) {
-  if (!scan_info) {
-    return kErrorParameters;
-  }
-  *scan_info = hw_scan_info_;
-  return kErrorNone;
-}
-
-DisplayError HWHDMI::GetVideoFormat(uint32_t config_index, uint32_t *video_format) {
-  if (config_index > hdmi_modes_.size()) {
-    return kErrorNotSupported;
-  }
-
-  *video_format = hdmi_modes_[config_index];
-
-  return kErrorNone;
-}
-
-DisplayError HWHDMI::GetMaxCEAFormat(uint32_t *max_cea_format) {
-  *max_cea_format = HDMI_VFRMT_END;
-
-  return kErrorNone;
-}
-
-DisplayError HWHDMI::OnMinHdcpEncryptionLevelChange(uint32_t min_enc_level) {
-  DisplayError error = kErrorNone;
-  int fd = -1;
-  char data[kMaxStringLength] = {'\0'};
-
-  snprintf(data, sizeof(data), "%s%d/hdcp2p2/min_level_change", fb_path_, fb_node_index_);
-
-  fd = Sys::open_(data, O_WRONLY);
-  if (fd < 0) {
-    DLOGW("File '%s' could not be opened.", data);
-    return kErrorHardware;
-  }
-
-  snprintf(data, sizeof(data), "%d", min_enc_level);
-
-  ssize_t err = Sys::pwrite_(fd, data, strlen(data), 0);
-  if (err <= 0) {
-    DLOGE("Write failed, Error = %s", strerror(errno));
-    error = kErrorHardware;
-  }
-
-  Sys::close_(fd);
-
-  return error;
-}
-
-HWScanSupport HWHDMI::MapHWScanSupport(uint32_t value) {
-  switch (value) {
-  // TODO(user): Read the scan type from driver defined values instead of hardcoding
-  case 0:
-    return kScanNotSupported;
-  case 1:
-    return kScanAlwaysOverscanned;
-  case 2:
-    return kScanAlwaysUnderscanned;
-  case 3:
-    return kScanBoth;
-  default:
-    return kScanNotSupported;
-    break;
-  }
-}
-
-void HWHDMI::ReadScanInfo() {
-  int scan_info_file = -1;
-  ssize_t len = -1;
-  char data[kPageSize] = {'\0'};
-
-  snprintf(data, sizeof(data), "%s%d/scan_info", fb_path_, fb_node_index_);
-  scan_info_file = Sys::open_(data, O_RDONLY);
-  if (scan_info_file < 0) {
-    DLOGW("File '%s' not found.", data);
-    return;
-  }
-
-  memset(&data[0], 0, sizeof(data));
-  len = Sys::pread_(scan_info_file, data, sizeof(data) - 1, 0);
-  if (len <= 0) {
-    Sys::close_(scan_info_file);
-    DLOGW("File %s%d/scan_info is empty.", fb_path_, fb_node_index_);
-    return;
-  }
-  data[len] = '\0';
-  Sys::close_(scan_info_file);
-
-  const uint32_t scan_info_max_count = 3;
-  uint32_t scan_info_count = 0;
-  char *tokens[scan_info_max_count] = { NULL };
-  ParseLine(data, tokens, scan_info_max_count, &scan_info_count);
-  if (scan_info_count != scan_info_max_count) {
-    DLOGW("Failed to parse scan info string %s", data);
-    return;
-  }
-
-  hw_scan_info_.pt_scan_support = MapHWScanSupport(UINT32(atoi(tokens[0])));
-  hw_scan_info_.it_scan_support = MapHWScanSupport(UINT32(atoi(tokens[1])));
-  hw_scan_info_.cea_scan_support = MapHWScanSupport(UINT32(atoi(tokens[2])));
-  DLOGI("PT %d IT %d CEA %d", hw_scan_info_.pt_scan_support, hw_scan_info_.it_scan_support,
-        hw_scan_info_.cea_scan_support);
-}
-
-int HWHDMI::OpenResolutionFile(int file_mode) {
-  char file_path[kMaxStringLength];
-  memset(file_path, 0, sizeof(file_path));
-  snprintf(file_path , sizeof(file_path), "%s%d/res_info", fb_path_, fb_node_index_);
-
-  int fd = Sys::open_(file_path, file_mode);
-
-  if (fd < 0) {
-    DLOGE("file '%s' not found : ret = %d err str: %s", file_path, fd, strerror(errno));
-  }
-
-  return fd;
-}
-
-// Method to request HDMI driver to write a new page of timing info into res_info node
-void HWHDMI::RequestNewPage(uint32_t page_number) {
-  char page_string[kPageSize];
-  int fd = OpenResolutionFile(O_WRONLY);
-  if (fd < 0) {
-    return;
-  }
-
-  snprintf(page_string, sizeof(page_string), "%d", page_number);
-
-  DLOGI_IF(kTagDriverConfig, "page=%s", page_string);
-
-  ssize_t err = Sys::pwrite_(fd, page_string, sizeof(page_string), 0);
-  if (err <= 0) {
-    DLOGE("Write to res_info failed (%s)", strerror(errno));
-  }
-
-  Sys::close_(fd);
-}
-
-// Reads the contents of res_info node into a buffer if the file is not empty
-bool HWHDMI::ReadResolutionFile(char *config_buffer) {
-  ssize_t bytes_read = 0;
-  int fd = OpenResolutionFile(O_RDONLY);
-  if (fd >= 0) {
-    bytes_read = Sys::pread_(fd, config_buffer, kPageSize, 0);
-    Sys::close_(fd);
-  }
-
-  DLOGI_IF(kTagDriverConfig, "bytes_read = %d", bytes_read);
-
-  return (bytes_read > 0);
-}
-
-// Populates the internal timing info structure with the timing info obtained
-// from the HDMI driver
-DisplayError HWHDMI::ReadTimingInfo() {
-  uint32_t config_index = 0;
-  uint32_t page_number = MSM_HDMI_INIT_RES_PAGE;
-  uint32_t size = sizeof(msm_hdmi_mode_timing_info);
-
-  while (true) {
-    char config_buffer[kPageSize] = {0};
-    msm_hdmi_mode_timing_info *info = reinterpret_cast<msm_hdmi_mode_timing_info *>(config_buffer);
-    RequestNewPage(page_number);
-
-    if (!ReadResolutionFile(config_buffer)) {
-      break;
-    }
-
-    while (info->video_format && size < kPageSize && config_index < hdmi_modes_.size()) {
-      supported_video_modes_[config_index] = *info;
-      size += sizeof(msm_hdmi_mode_timing_info);
-
-      DLOGI_IF(kTagDriverConfig, "Config=%d Mode %d: (%dx%d) @ %d, pixel formats %d",
-               config_index,
-               supported_video_modes_[config_index].video_format,
-               supported_video_modes_[config_index].active_h,
-               supported_video_modes_[config_index].active_v,
-               supported_video_modes_[config_index].refresh_rate,
-               supported_video_modes_[config_index].pixel_formats);
-
-      info++;
-      config_index++;
-    }
-
-    size = sizeof(msm_hdmi_mode_timing_info);
-    // Request HDMI driver to populate res_info with more
-    // timing information
-    page_number++;
-  }
-
-  if (page_number == MSM_HDMI_INIT_RES_PAGE || config_index == 0) {
-    DLOGE("No timing information found.");
-    return kErrorHardware;
-  }
-
-  return kErrorNone;
-}
-
-bool HWHDMI::IsResolutionFilePresent() {
-  bool is_file_present = false;
-  int fd = OpenResolutionFile(O_RDONLY);
-  if (fd >= 0) {
-    is_file_present = true;
-    Sys::close_(fd);
-  }
-
-  return is_file_present;
-}
-
-void HWHDMI::SetSourceProductInformation(const char *node, const char *name) {
-  char property_value[kMaxStringLength];
-  char sys_fs_path[kMaxStringLength];
-  int hdmi_node_index = GetFBNodeIndex(kDeviceHDMI);
-  if (hdmi_node_index < 0) {
-    return;
-  }
-
-  ssize_t length = 0;
-  DisplayError error = Debug::GetProperty(name, property_value);
-  if (error != kErrorNone) {
-    return;
-  }
-
-  snprintf(sys_fs_path , sizeof(sys_fs_path), "%s%d/%s", fb_path_, hdmi_node_index, node);
-  length = HWDevice::SysFsWrite(sys_fs_path, property_value,
-                                static_cast<ssize_t>(strlen(property_value)));
-  if (length <= 0) {
-    DLOGW("Failed to write %s = %s", node, property_value);
-  }
-}
-
-DisplayError HWHDMI::GetDisplayS3DSupport(uint32_t index,
-                                          HWDisplayAttributes *attrib) {
-  ssize_t length = -1;
-  char edid_s3d_str[kPageSize] = {'\0'};
-  char edid_s3d_path[kMaxStringLength] = {'\0'};
-  snprintf(edid_s3d_path, sizeof(edid_s3d_path), "%s%d/edid_3d_modes", fb_path_, fb_node_index_);
-
-  if (index > hdmi_modes_.size()) {
-    return kErrorNotSupported;
-  }
-
-  attrib->s3d_config[kS3DModeNone] = 1;
-
-  // Three level inception!
-  // The string looks like 16=SSH,4=FP:TAB:SSH,5=FP:SSH,32=FP:TAB:SSH
-  // Initialize all the pointers to NULL to avoid crash in function strtok_r()
-  char *saveptr_l1 = NULL, *saveptr_l2 = NULL, *saveptr_l3 = NULL;
-  char *l1 = NULL, *l2 = NULL, *l3 = NULL;
-
-  int edid_s3d_node = Sys::open_(edid_s3d_path, O_RDONLY);
-  if (edid_s3d_node < 0) {
-    DLOGW("%s could not be opened : %s", edid_s3d_path, strerror(errno));
-    return kErrorNotSupported;
-  }
-
-  length = Sys::pread_(edid_s3d_node, edid_s3d_str, sizeof(edid_s3d_str)-1, 0);
-  if (length <= 0) {
-    Sys::close_(edid_s3d_node);
-    return kErrorNotSupported;
-  }
-
-  l1 = strtok_r(edid_s3d_str, ",", &saveptr_l1);
-  while (l1 != NULL) {
-    l2 = strtok_r(l1, "=", &saveptr_l2);
-    if (l2 != NULL) {
-      if (hdmi_modes_[index] == (uint32_t)atoi(l2)) {
-          l3 = strtok_r(saveptr_l2, ":", &saveptr_l3);
-          while (l3 != NULL) {
-            if (strncmp("SSH", l3, strlen("SSH")) == 0) {
-              attrib->s3d_config[kS3DModeLR] = 1;
-              attrib->s3d_config[kS3DModeRL] = 1;
-            } else if (strncmp("TAB", l3, strlen("TAB")) == 0) {
-              attrib->s3d_config[kS3DModeTB] = 1;
-            } else if (strncmp("FP", l3, strlen("FP")) == 0) {
-              attrib->s3d_config[kS3DModeFP] = 1;
-            }
-            l3 = strtok_r(NULL, ":", &saveptr_l3);
-          }
-      }
-    }
-    l1 = strtok_r(NULL, ",", &saveptr_l1);
-  }
-
-  Sys::close_(edid_s3d_node);
-  return kErrorNone;
-}
-
-bool HWHDMI::IsSupportedS3DMode(HWS3DMode s3d_mode) {
-  for (uint32_t i = 0; i < supported_s3d_modes_.size(); i++) {
-    if (supported_s3d_modes_[i] == s3d_mode) {
-      return true;
-    }
-  }
-  return false;
-}
-
-DisplayError HWHDMI::SetS3DMode(HWS3DMode s3d_mode) {
-  if (!IsSupportedS3DMode(s3d_mode)) {
-    DLOGW("S3D mode is not supported s3d_mode = %d", s3d_mode);
-    return kErrorNotSupported;
-  }
-
-  std::map<HWS3DMode, msm_hdmi_s3d_mode>::iterator it = s3d_mode_sdm_to_mdp_.find(s3d_mode);
-  if (it == s3d_mode_sdm_to_mdp_.end()) {
-    return kErrorNotSupported;
-  }
-  msm_hdmi_s3d_mode s3d_mdp_mode = it->second;
-
-  if (active_mdp_s3d_mode_ == s3d_mdp_mode) {
-    // HDMI_S3D_SIDE_BY_SIDE is an mdp mapping for kS3DModeLR and kS3DModeRL s3d modes. So no need
-    // to update the s3d_mode node. hw_panel_info needs to be updated to differentiate these two s3d
-    // modes in strategy
-    hw_panel_info_.s3d_mode = s3d_mode;
-    return kErrorNone;
-  }
-
-  ssize_t length = -1;
-  char s3d_mode_path[kMaxStringLength] = {'\0'};
-  char s3d_mode_string[kMaxStringLength] = {'\0'};
-  snprintf(s3d_mode_path, sizeof(s3d_mode_path), "%s%d/s3d_mode", fb_path_, fb_node_index_);
-
-  int s3d_mode_node = Sys::open_(s3d_mode_path, O_RDWR);
-  if (s3d_mode_node < 0) {
-    DLOGW("%s could not be opened : %s", s3d_mode_path, strerror(errno));
-    return kErrorNotSupported;
-  }
-
-  snprintf(s3d_mode_string, sizeof(s3d_mode_string), "%d", s3d_mdp_mode);
-  length = Sys::pwrite_(s3d_mode_node, s3d_mode_string, sizeof(s3d_mode_string), 0);
-  if (length <= 0) {
-    DLOGW("Failed to write into s3d node: %s", strerror(errno));
-    Sys::close_(s3d_mode_node);
-    return kErrorNotSupported;
-  }
-
-  active_mdp_s3d_mode_ = s3d_mdp_mode;
-  hw_panel_info_.s3d_mode = s3d_mode;
-  Sys::close_(s3d_mode_node);
-
-  DLOGI_IF(kTagDriverConfig, "Set s3d mode %d", hw_panel_info_.s3d_mode);
-  return kErrorNone;
-}
-
-DisplayError HWHDMI::GetPanelS3DMode() {
-  ssize_t length = -1;
-  char s3d_mode_path[kMaxStringLength] = {'\0'};
-  char s3d_mode_string[kMaxStringLength] = {'\0'};
-  snprintf(s3d_mode_path, sizeof(s3d_mode_path), "%s%d/s3d_mode", fb_path_, fb_node_index_);
-  int panel_s3d_mode = 0;
-
-  int s3d_mode_node = Sys::open_(s3d_mode_path, O_RDWR);
-  if (s3d_mode_node < 0) {
-    DLOGE("%s could not be opened : %s", s3d_mode_path, strerror(errno));
-    return kErrorNotSupported;
-  }
-
-  length = Sys::pread_(s3d_mode_node, s3d_mode_string, sizeof(s3d_mode_string), 0);
-  if (length <= 0) {
-    DLOGE("Failed read s3d node: %s", strerror(errno));
-    Sys::close_(s3d_mode_node);
-    return kErrorNotSupported;
-  }
-
-  panel_s3d_mode = atoi(s3d_mode_string);
-  if (panel_s3d_mode < HDMI_S3D_NONE || panel_s3d_mode >= HDMI_S3D_MAX) {
-    Sys::close_(s3d_mode_node);
-    DLOGW("HDMI panel S3D mode is not supported panel_s3d_mode = %d", panel_s3d_mode);
-    return kErrorUndefined;
-  }
-
-  active_mdp_s3d_mode_  = static_cast<msm_hdmi_s3d_mode>(panel_s3d_mode);
-  Sys::close_(s3d_mode_node);
-
-  DLOGI_IF(kTagDriverConfig, "Get HDMI panel s3d mode %d", active_mdp_s3d_mode_);
-  return kErrorNone;
-}
-
-DisplayError HWHDMI::GetDynamicFrameRateMode(uint32_t refresh_rate, uint32_t *mode,
-                                             DynamicFPSData *data, uint32_t *config_index) {
-  msm_hdmi_mode_timing_info *cur = NULL;
-  msm_hdmi_mode_timing_info *dst = NULL;
-  uint32_t i = 0;
-  int pre_refresh_rate_diff = 0;
-  bool pre_unstd_mode = false;
-
-  for (i = 0; i < hdmi_modes_.size(); i++) {
-    msm_hdmi_mode_timing_info *timing_mode = &supported_video_modes_[i];
-    if (timing_mode->video_format == hdmi_modes_[active_config_index_]) {
-      cur = timing_mode;
-      break;
-    }
-  }
-
-  if (cur == NULL) {
-    DLOGE("can't find timing info for active config index(%d)", active_config_index_);
-    return kErrorUndefined;
-  }
-
-  if (cur->refresh_rate != frame_rate_) {
-    pre_unstd_mode = true;
-  }
-
-  if (i >= hdmi_modes_.size()) {
-    return kErrorNotSupported;
-  }
-
-  dst = cur;
-  pre_refresh_rate_diff = static_cast<int>(dst->refresh_rate) - static_cast<int>(refresh_rate);
-
-  for (i = 0; i < hdmi_modes_.size(); i++) {
-    msm_hdmi_mode_timing_info *timing_mode = &supported_video_modes_[i];
-    if (cur->active_h == timing_mode->active_h &&
-       cur->active_v == timing_mode->active_v &&
-       cur->pixel_formats == timing_mode->pixel_formats ) {
-      int cur_refresh_rate_diff = static_cast<int>(timing_mode->refresh_rate) -
-                                  static_cast<int>(refresh_rate);
-      if (abs(pre_refresh_rate_diff) > abs(cur_refresh_rate_diff)) {
-        pre_refresh_rate_diff = cur_refresh_rate_diff;
-        dst = timing_mode;
-      }
-    }
-  }
-
-  if (pre_refresh_rate_diff > kThresholdRefreshRate) {
-    return kErrorNotSupported;
-  }
-
-  char mode_val[kVideoFormatArrayMax]={};
-  snprintf(mode_val, sizeof(mode_val), "%d", dst->video_format);
-  GetConfigIndex(mode_val, config_index);
-
-  data->hor_front_porch = dst->front_porch_h;
-  data->hor_back_porch = dst->back_porch_h;
-  data->hor_pulse_width = dst->pulse_width_h;
-  data->clk_rate_hz = dst->pixel_freq;
-  data->fps = refresh_rate;
-
-  if (dst->front_porch_h != cur->front_porch_h) {
-    *mode = kModeHFP;
-  }
-
-  if (dst->refresh_rate != refresh_rate || dst->pixel_freq != cur->pixel_freq) {
-    if (*mode == kModeHFP) {
-      if (dst->refresh_rate != refresh_rate) {
-        *mode = kModeHFPCalcClock;
-      } else {
-        *mode = kModeClockHFP;
-      }
-    } else {
-        *mode = kModeClock;
-    }
-  }
-
-  if (pre_unstd_mode && (*mode == kModeHFP)) {
-    *mode = kModeClockHFP;
-  }
-
-  return kErrorNone;
-}
-
-DisplayError HWHDMI::SetRefreshRate(uint32_t refresh_rate) {
-  char mode_path[kMaxStringLength] = {0};
-  char node_path[kMaxStringLength] = {0};
-  uint32_t mode = kModeClock;
-  uint32_t config_index = 0;
-  DynamicFPSData data;
-  DisplayError error = kErrorNone;
-
-  if (refresh_rate == frame_rate_) {
-    return error;
-  }
-
-  error = GetDynamicFrameRateMode(refresh_rate, &mode, &data, &config_index);
-  if (error != kErrorNone) {
-    return error;
-  }
-
-  snprintf(mode_path, sizeof(mode_path), "%s%d/msm_fb_dfps_mode", fb_path_, fb_node_index_);
-  snprintf(node_path, sizeof(node_path), "%s%d/dynamic_fps", fb_path_, fb_node_index_);
-
-  int fd_mode = Sys::open_(mode_path, O_WRONLY);
-  if (fd_mode < 0) {
-    DLOGE("Failed to open %s with error %s", mode_path, strerror(errno));
-    return kErrorFileDescriptor;
-  }
-
-  char dfps_mode[kMaxStringLength];
-  snprintf(dfps_mode, sizeof(dfps_mode), "%d", mode);
-  DLOGI_IF(kTagDriverConfig, "Setting dfps_mode  = %d", mode);
-  ssize_t len = Sys::pwrite_(fd_mode, dfps_mode, strlen(dfps_mode), 0);
-  if (len < 0) {
-    DLOGE("Failed to enable dfps mode %d with error %s", mode, strerror(errno));
-    Sys::close_(fd_mode);
-    return kErrorUndefined;
-  }
-  Sys::close_(fd_mode);
-
-  int fd_node = Sys::open_(node_path, O_WRONLY);
-  if (fd_node < 0) {
-    DLOGE("Failed to open %s with error %s", node_path, strerror(errno));
-    return kErrorFileDescriptor;
-  }
-
-  char refresh_rate_string[kMaxStringLength];
-  if (mode == kModeHFP || mode == kModeClock) {
-    snprintf(refresh_rate_string, sizeof(refresh_rate_string), "%d", data.fps);
-    DLOGI_IF(kTagDriverConfig, "Setting refresh rate = %d", data.fps);
-  } else {
-    snprintf(refresh_rate_string, sizeof(refresh_rate_string), "%d %d %d %d %d",
-             data.hor_front_porch, data.hor_back_porch, data.hor_pulse_width,
-             data.clk_rate_hz, data.fps);
-  }
-  len = Sys::pwrite_(fd_node, refresh_rate_string, strlen(refresh_rate_string), 0);
-  if (len < 0) {
-    DLOGE("Failed to write %d with error %s", refresh_rate, strerror(errno));
-    Sys::close_(fd_node);
-    return kErrorUndefined;
-  }
-  Sys::close_(fd_node);
-
-  error = ReadTimingInfo();
-  if (error != kErrorNone) {
-    return error;
-  }
-
-  GetDisplayAttributes(config_index, &display_attributes_);
-  UpdateMixerAttributes();
-
-  frame_rate_ = refresh_rate;
-  active_config_index_ = config_index;
-
-  DLOGI_IF(kTagDriverConfig, "config_index(%d) Mode(%d) frame_rate(%d)",
-           config_index,
-           mode,
-           frame_rate_);
-
-  return kErrorNone;
-}
-
-void HWHDMI::UpdateMixerAttributes() {
-  mixer_attributes_.width = display_attributes_.x_pixels;
-  mixer_attributes_.height = display_attributes_.y_pixels;
-  mixer_attributes_.split_left = display_attributes_.is_device_split ?
-      (display_attributes_.x_pixels / 2) : mixer_attributes_.width;
-}
-
-DisplayError HWHDMI::UpdateHDRMetaData(HWLayers *hw_layers) {
-  if (!hw_panel_info_.hdr_enabled) {
-    return kErrorNone;
-  }
-
-  DisplayError error = kErrorNone;
-
-#ifdef MDP_HDR_STREAM
-  const HWHDRLayerInfo &hdr_layer_info = hw_layers->info.hdr_layer_info;
-  char hdr_stream_path[kMaxStringLength] = {};
-  snprintf(hdr_stream_path, sizeof(hdr_stream_path), "%s%d/hdr_stream", fb_path_, fb_node_index_);
-
-  Layer hdr_layer = {};
-  if (hdr_layer_info.operation == HWHDRLayerInfo::kSet && hdr_layer_info.layer_index > -1) {
-    hdr_layer = *(hw_layers->info.stack->layers.at(UINT32(hdr_layer_info.layer_index)));
-  }
-
-  const LayerBuffer *layer_buffer = &hdr_layer.input_buffer;
-  const MasteringDisplay &mastering_display = layer_buffer->color_metadata.masteringDisplayInfo;
-  const ContentLightLevel &light_level = layer_buffer->color_metadata.contentLightLevel;
-  const Primaries &primaries = mastering_display.primaries;
-
-  mdp_hdr_stream_ctrl hdr_ctrl = {};
-  if (hdr_layer_info.operation == HWHDRLayerInfo::kSet) {
-    int32_t eotf = GetEOTF(layer_buffer->color_metadata.transfer);
-    hdr_ctrl.hdr_stream.eotf = (eotf < 0) ? 0 : UINT32(eotf);
-    hdr_ctrl.hdr_stream.white_point_x = primaries.whitePoint[0];
-    hdr_ctrl.hdr_stream.white_point_y = primaries.whitePoint[1];
-    hdr_ctrl.hdr_stream.display_primaries_x[0] = primaries.rgbPrimaries[0][0];
-    hdr_ctrl.hdr_stream.display_primaries_y[0] = primaries.rgbPrimaries[0][1];
-    hdr_ctrl.hdr_stream.display_primaries_x[1] = primaries.rgbPrimaries[1][0];
-    hdr_ctrl.hdr_stream.display_primaries_y[1] = primaries.rgbPrimaries[1][1];
-    hdr_ctrl.hdr_stream.display_primaries_x[2] = primaries.rgbPrimaries[2][0];
-    hdr_ctrl.hdr_stream.display_primaries_y[2] = primaries.rgbPrimaries[2][1];
-    hdr_ctrl.hdr_stream.min_luminance = mastering_display.minDisplayLuminance;
-    hdr_ctrl.hdr_stream.max_luminance = mastering_display.maxDisplayLuminance/10000;
-    hdr_ctrl.hdr_stream.max_content_light_level = light_level.maxContentLightLevel;
-    hdr_ctrl.hdr_stream.max_average_light_level = light_level.minPicAverageLightLevel;
-    hdr_ctrl.hdr_state = HDR_ENABLE;
-    reset_hdr_flag_ = false;
-#ifdef MDP_COMMIT_UPDATE_CDM_COLOR_SPACE
-    HWDevice::SetCSC(layer_buffer->color_metadata, &cdm_color_space_);
-    cdm_color_space_commit_ = true;
-#endif
-    // DP related
-    int32_t pixel_encoding = GetPixelEncoding(hdr_layer.input_buffer);
-    hdr_ctrl.hdr_stream.pixel_encoding = (pixel_encoding < 0) ? 0 : UINT32(pixel_encoding);
-    int32_t colorimetry = GetColoriMetry(hdr_layer.input_buffer);
-    hdr_ctrl.hdr_stream.colorimetry = (colorimetry < 0) ? 0 : UINT32(colorimetry);
-    hdr_ctrl.hdr_stream.range = GetRange(hdr_layer.input_buffer.color_metadata.range);
-    int32_t bits_per_component = GetBitsPerComponent(hdr_layer.input_buffer);
-    hdr_ctrl.hdr_stream.bits_per_component =
-                           (bits_per_component  < 0) ? 0 : UINT32(bits_per_component);
-    hdr_ctrl.hdr_stream.content_type = GetContentType(hdr_layer.input_buffer);
-
-    DLOGD_IF(kTagDriverConfig, "kSet: HDR Stream : MaxDisplayLuminance = %d\n"
-      "MinDisplayLuminance = %d MaxContentLightLevel = %d MaxAverageLightLevel = %d\n"
-      "Red_x = %d Red_y = %d Green_x = %d Green_y = %d Blue_x = %d Blue_y = %d\n"
-      "WhitePoint_x = %d WhitePoint_y = %d EOTF = %d PixelEncoding = %d Colorimetry = %d\n"
-      "Range = %d BPC = %d ContentType = %d hdr_state = %d",
-      hdr_ctrl.hdr_stream.max_luminance, hdr_ctrl.hdr_stream.min_luminance,
-      hdr_ctrl.hdr_stream.max_content_light_level, hdr_ctrl.hdr_stream.max_average_light_level,
-      hdr_ctrl.hdr_stream.display_primaries_x[0], hdr_ctrl.hdr_stream.display_primaries_y[0],
-      hdr_ctrl.hdr_stream.display_primaries_x[1], hdr_ctrl.hdr_stream.display_primaries_y[1],
-      hdr_ctrl.hdr_stream.display_primaries_x[2], hdr_ctrl.hdr_stream.display_primaries_y[2],
-      hdr_ctrl.hdr_stream.white_point_x, hdr_ctrl.hdr_stream.white_point_x,
-      hdr_ctrl.hdr_stream.eotf, hdr_ctrl.hdr_stream.pixel_encoding,
-      hdr_ctrl.hdr_stream.colorimetry, hdr_ctrl.hdr_stream.range,
-      hdr_ctrl.hdr_stream.bits_per_component, hdr_ctrl.hdr_stream.content_type,
-      hdr_ctrl.hdr_state);
-  } else if (hdr_layer_info.operation == HWHDRLayerInfo::kReset) {
-    memset(&hdr_ctrl.hdr_stream, 0, sizeof(hdr_ctrl.hdr_stream));
-    hdr_ctrl.hdr_state = HDR_RESET;
-    reset_hdr_flag_ = true;
-    hdr_reset_start_ = time(NULL);
-#ifdef MDP_COMMIT_UPDATE_CDM_COLOR_SPACE
-    cdm_color_space_ = (mdp_color_space) MDP_CSC_DEFAULT;
-    cdm_color_space_commit_ = true;
-#endif
-    DLOGD_IF(kTagDriverConfig, "kReset: HDR Stream: HDR_RESET");
-  } else if (hdr_layer_info.operation == HWHDRLayerInfo::kNoOp) {
-     if (reset_hdr_flag_) {
-       hdr_reset_end_ = time(NULL);
-
-       if ((hdr_reset_end_ - hdr_reset_start_) >= MIN_HDR_RESET_WAITTIME_SEC) {
-          reset_hdr_flag_ = false;
-          memset(&hdr_ctrl.hdr_stream, 0, sizeof(hdr_ctrl.hdr_stream));
-          hdr_ctrl.hdr_state = HDR_DISABLE;
-          DLOGD_IF(kTagDriverConfig, "kNoOp: HDR Stream: HDR_DISABLE");
-       } else {
-          return kErrorNone;
-       }
-     } else {
-        return kErrorNone;
-     }
-  }
-
-  int fd = Sys::open_(hdr_stream_path, O_WRONLY);
-  if (fd < 0) {
-    DLOGE("Failed to open %s with error %s", hdr_stream_path, strerror(errno));
-    return kErrorFileDescriptor;
-  }
-
-  const void *hdr_metadata = reinterpret_cast<const void*>(&hdr_ctrl);
-  ssize_t len = Sys::pwrite_(fd, hdr_metadata, sizeof(hdr_ctrl), 0);
-  if (len <= 0) {
-    DLOGE("Failed to write hdr_metadata");
-    error = kErrorUndefined;
-  }
-  Sys::close_(fd);
-#endif
-
-  return error;
-}
-
-}  // namespace sdm
-
diff --git a/sdm/libs/core/fb/hw_hdmi.h b/sdm/libs/core/fb/hw_hdmi.h
deleted file mode 100644
index 183e9db..0000000
--- a/sdm/libs/core/fb/hw_hdmi.h
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
-* Copyright (c) 2015 - 2017, The Linux Foundation. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without modification, are permitted
-* provided that the following conditions are met:
-*    * Redistributions of source code must retain the above copyright notice, this list of
-*      conditions and the following disclaimer.
-*    * Redistributions in binary form must reproduce the above copyright notice, this list of
-*      conditions and the following disclaimer in the documentation and/or other materials provided
-*      with the distribution.
-*    * Neither the name of The Linux Foundation nor the names of its contributors may be used to
-*      endorse or promote products derived from this software without specific prior written
-*      permission.
-*
-* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-* NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
-* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
-* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
-* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#ifndef __HW_HDMI_H__
-#define __HW_HDMI_H__
-
-#include <video/msm_hdmi_modes.h>
-#include <map>
-#include <vector>
-
-#include "hw_device.h"
-
-namespace sdm {
-
-using std::vector;
-
-class HWHDMI : public HWDevice {
- public:
-  HWHDMI(BufferSyncHandler *buffer_sync_handler, HWInfoInterface *hw_info_intf);
-
- protected:
-  enum HWFramerateUpdate {
-    // Switch framerate by switch to other standard modes though panel blank/unblank
-    kModeSuspendResume,
-    // Switch framerate by tuning pixel clock
-    kModeClock,
-    // Switch framerate by tuning vertical front porch
-    kModeVFP,
-    // Switch framerate by tuning horizontal front porch
-    kModeHFP,
-    // Switch framerate by tuning horizontal front porch and clock
-    kModeClockHFP,
-    // Switch framerate by tuning horizontal front porch and re-caculate clock
-    kModeHFPCalcClock,
-    kModeMAX
-  };
-
-  /**
-   * struct DynamicFPSData - defines dynamic fps related data
-   * @hor_front_porch: horizontal front porch
-   * @hor_back_porch: horizontal back porch
-   * @hor_pulse_width: horizontal pulse width
-   * @clk_rate_hz: panel clock rate in HZ
-   * @fps: frames per second
-   */
-  struct DynamicFPSData {
-    uint32_t hor_front_porch;
-    uint32_t hor_back_porch;
-    uint32_t hor_pulse_width;
-    uint32_t clk_rate_hz;
-    uint32_t fps;
-  };
-
-  virtual DisplayError Init();
-  virtual DisplayError GetNumDisplayAttributes(uint32_t *count);
-  // Requirement to call this only after the first config has been explicitly set by client
-  virtual DisplayError GetActiveConfig(uint32_t *active_config);
-  virtual DisplayError GetDisplayAttributes(uint32_t index,
-                                            HWDisplayAttributes *display_attributes);
-  virtual DisplayError GetHWScanInfo(HWScanInfo *scan_info);
-  virtual DisplayError GetVideoFormat(uint32_t config_index, uint32_t *video_format);
-  virtual DisplayError GetMaxCEAFormat(uint32_t *max_cea_format);
-  virtual DisplayError OnMinHdcpEncryptionLevelChange(uint32_t min_enc_level);
-  virtual DisplayError SetDisplayAttributes(uint32_t index);
-  virtual DisplayError GetConfigIndex(char *mode, uint32_t *index);
-  virtual DisplayError Validate(HWLayers *hw_layers);
-  virtual DisplayError Commit(HWLayers *hw_layers);
-  virtual DisplayError SetS3DMode(HWS3DMode s3d_mode);
-  virtual DisplayError SetRefreshRate(uint32_t refresh_rate);
-
- private:
-  DisplayError ReadEDIDInfo();
-  void ReadScanInfo();
-  HWScanSupport MapHWScanSupport(uint32_t value);
-  int OpenResolutionFile(int file_mode);
-  void RequestNewPage(uint32_t page_number);
-  DisplayError ReadTimingInfo();
-  bool ReadResolutionFile(char *config_buffer);
-  bool IsResolutionFilePresent();
-  void SetSourceProductInformation(const char *node, const char *name);
-  DisplayError GetDisplayS3DSupport(uint32_t index,
-                                    HWDisplayAttributes *attrib);
-  DisplayError GetPanelS3DMode();
-  bool IsSupportedS3DMode(HWS3DMode s3d_mode);
-  void UpdateMixerAttributes();
-  DisplayError UpdateHDRMetaData(HWLayers *hw_layers);
-
-  DisplayError GetDynamicFrameRateMode(uint32_t refresh_rate, uint32_t*mode,
-                                       DynamicFPSData *data, uint32_t *config_index);
-  static const int kThresholdRefreshRate = 1000;
-  static const int kVideoFormatArrayMax = 8;
-  vector<uint32_t> hdmi_modes_;
-  // Holds the hdmi timing information. Ex: resolution, fps etc.,
-  vector<msm_hdmi_mode_timing_info> supported_video_modes_;
-  HWScanInfo hw_scan_info_;
-  uint32_t active_config_index_;
-  std::map<HWS3DMode, msm_hdmi_s3d_mode> s3d_mode_sdm_to_mdp_;
-  vector<HWS3DMode> supported_s3d_modes_;
-  msm_hdmi_s3d_mode active_mdp_s3d_mode_ = HDMI_S3D_NONE;
-  uint32_t frame_rate_ = 0;
-  time_t hdr_reset_start_ = 0, hdr_reset_end_ = 0;
-  bool reset_hdr_flag_ = false;
-  mdp_color_space cdm_color_space_ = {};
-  bool cdm_color_space_commit_ = false;
-};
-
-}  // namespace sdm
-
-#endif  // __HW_HDMI_H__
-
diff --git a/sdm/libs/core/fb/hw_info.cpp b/sdm/libs/core/fb/hw_info.cpp
deleted file mode 100644
index 2cdae06..0000000
--- a/sdm/libs/core/fb/hw_info.cpp
+++ /dev/null
@@ -1,560 +0,0 @@
-/*
-* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without modification, are permitted
-* provided that the following conditions are met:
-*    * Redistributions of source code must retain the above copyright notice, this list of
-*      conditions and the following disclaimer.
-*    * Redistributions in binary form must reproduce the above copyright notice, this list of
-*      conditions and the following disclaimer in the documentation and/or other materials provided
-*      with the distribution.
-*    * Neither the name of The Linux Foundation nor the names of its contributors may be used to
-*      endorse or promote products derived from this software without specific prior written
-*      permission.
-*
-* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-* NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
-* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
-* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
-* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#include <string.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <fcntl.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <utils/constants.h>
-#include <utils/debug.h>
-#include <utils/sys.h>
-#include <dlfcn.h>
-
-#include <algorithm>
-#include <iostream>
-#include <fstream>
-#include <map>
-#include <memory>
-#include <string>
-#include <utility>
-#include <vector>
-
-#include "hw_info.h"
-
-#define __CLASS__ "HWInfo"
-
-using std::vector;
-using std::map;
-using std::string;
-using std::fstream;
-using std::to_string;
-
-namespace sdm {
-
-// kDefaultFormatSupport contains the bit map of supported formats for each hw blocks.
-// For eg: if Cursor supports MDP_RGBA_8888[bit-13] and MDP_RGB_565[bit-0], then cursor pipe array
-// contains { 0x01[0-3], 0x00[4-7], 0x00[8-12], 0x01[13-16], 0x00[17-20], 0x00[21-24], 0x00[24-28] }
-const std::bitset<8> HWInfo::kDefaultFormatSupport[kHWSubBlockMax][
-                                                      BITS_TO_BYTES(MDP_IMGTYPE_LIMIT1)] = {
-  { 0xFF, 0xF5, 0x1C, 0x1E, 0x20, 0xFF, 0x01, 0x00, 0xFE, 0x1F },  // kHWVIGPipe
-  { 0x33, 0xE0, 0x00, 0x16, 0x00, 0xBF, 0x00, 0x00, 0xFE, 0x07 },  // kHWRGBPipe
-  { 0x33, 0xE0, 0x00, 0x16, 0x00, 0xBF, 0x00, 0x00, 0xFE, 0x07 },  // kHWDMAPipe
-  { 0x12, 0x60, 0x0C, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x00 },  // kHWCursorPipe
-  { 0xFF, 0xF5, 0x1C, 0x1E, 0x20, 0xFF, 0x01, 0x00, 0xFE, 0x1F },  // kHWRotatorInput
-  { 0xFF, 0xF5, 0x1C, 0x1E, 0x20, 0xFF, 0x01, 0x00, 0xFE, 0x1F },  // kHWRotatorOutput
-  { 0x3F, 0xF4, 0x10, 0x1E, 0x20, 0xFF, 0x01, 0x00, 0xAA, 0x16 },  // kHWWBIntfOutput
-};
-
-int HWInfo::ParseString(const char *input, char *tokens[], const uint32_t max_token,
-                        const char *delim, uint32_t *count) {
-  char *tmp_token = NULL;
-  char *temp_ptr;
-  uint32_t index = 0;
-  if (!input) {
-    return -1;
-  }
-  tmp_token = strtok_r(const_cast<char *>(input), delim, &temp_ptr);
-  while (tmp_token && index < max_token) {
-    tokens[index++] = tmp_token;
-    tmp_token = strtok_r(NULL, delim, &temp_ptr);
-  }
-  *count = index;
-
-  return 0;
-}
-
-DisplayError HWInfo::GetDynamicBWLimits(HWResourceInfo *hw_resource) {
-  Sys::fstream fs(kBWModeBitmap, fstream::in);
-  if (!fs.is_open()) {
-    DLOGE("File '%s' not found", kBWModeBitmap);
-    return kErrorHardware;
-  }
-
-  HWDynBwLimitInfo* bw_info = &hw_resource->dyn_bw_info;
-  for (int index = 0; index < kBwModeMax; index++) {
-    bw_info->total_bw_limit[index] = hw_resource->max_bandwidth_low;
-    bw_info->pipe_bw_limit[index] = hw_resource->max_pipe_bw;
-  }
-
-  uint32_t token_count = 0;
-  const uint32_t max_count = kBwModeMax;
-  char *tokens[max_count] = { NULL };
-  string line;
-  while (Sys::getline_(fs, line)) {
-    if (!ParseString(line.c_str(), tokens, max_count, ":, =\n", &token_count)) {
-      if (!strncmp(tokens[0], "default_pipe", strlen("default_pipe"))) {
-        bw_info->pipe_bw_limit[kBwDefault] = UINT32(atoi(tokens[1]));
-      } else if (!strncmp(tokens[0], "camera_pipe", strlen("camera_pipe"))) {
-        bw_info->pipe_bw_limit[kBwCamera] = UINT32(atoi(tokens[1]));
-      } else if (!strncmp(tokens[0], "vflip_pipe", strlen("vflip_pipe"))) {
-        bw_info->pipe_bw_limit[kBwVFlip] = UINT32(atoi(tokens[1]));
-      } else if (!strncmp(tokens[0], "hflip_pipe", strlen("hflip_pipe"))) {
-        bw_info->pipe_bw_limit[kBwHFlip] = UINT32(atoi(tokens[1]));
-      } else if (!strncmp(tokens[0], "default", strlen("default"))) {
-        bw_info->total_bw_limit[kBwDefault] = UINT32(atoi(tokens[1]));
-      } else if (!strncmp(tokens[0], "camera", strlen("camera"))) {
-        bw_info->total_bw_limit[kBwCamera] = UINT32(atoi(tokens[1]));
-      } else if (!strncmp(tokens[0], "vflip", strlen("vflip"))) {
-        bw_info->total_bw_limit[kBwVFlip] = UINT32(atoi(tokens[1]));
-      } else if (!strncmp(tokens[0], "hflip", strlen("hflip"))) {
-        bw_info->total_bw_limit[kBwHFlip] = UINT32(atoi(tokens[1]));
-      }
-    }
-  }
-
-  return kErrorNone;
-}
-
-DisplayError HWInfo::GetHWResourceInfo(HWResourceInfo *hw_resource) {
-  if (hw_resource_) {
-    *hw_resource = *hw_resource_;
-    return kErrorNone;
-  }
-  string fb_path = "/sys/devices/virtual/graphics/fb"
-                      + to_string(kHWCapabilitiesNode) + "/mdp/caps";
-
-  Sys::fstream fs(fb_path, fstream::in);
-  if (!fs.is_open()) {
-    DLOGE("File '%s' not found", fb_path.c_str());
-    return kErrorHardware;
-  }
-
-  hw_resource_ = new HWResourceInfo;
-
-  InitSupportedFormatMap(hw_resource_);
-  hw_resource_->hw_version = kHWMdssVersion5;
-
-  uint32_t token_count = 0;
-  const uint32_t max_count = 256;
-  char *tokens[max_count] = { NULL };
-  string line;
-  while (Sys::getline_(fs, line)) {
-    // parse the line and update information accordingly
-    if (!ParseString(line.c_str(), tokens, max_count, ":, =\n", &token_count)) {
-      if (!strncmp(tokens[0], "hw_rev", strlen("hw_rev"))) {
-        hw_resource_->hw_revision = UINT32(atoi(tokens[1]));  // HW Rev, v1/v2
-      } else if (!strncmp(tokens[0], "rot_input_fmts", strlen("rot_input_fmts"))) {
-        ParseFormats(&tokens[1], (token_count - 1), kHWRotatorInput, hw_resource_);
-      } else if (!strncmp(tokens[0], "rot_output_fmts", strlen("rot_output_fmts"))) {
-        ParseFormats(&tokens[1], (token_count - 1), kHWRotatorOutput, hw_resource_);
-      } else if (!strncmp(tokens[0], "wb_output_fmts", strlen("wb_output_fmts"))) {
-        ParseFormats(&tokens[1], (token_count - 1), kHWWBIntfOutput, hw_resource_);
-      } else if (!strncmp(tokens[0], "blending_stages", strlen("blending_stages"))) {
-        hw_resource_->num_blending_stages = UINT8(atoi(tokens[1]));
-      } else if (!strncmp(tokens[0], "max_downscale_ratio", strlen("max_downscale_ratio"))) {
-        hw_resource_->max_scale_down = UINT32(atoi(tokens[1]));
-      } else if (!strncmp(tokens[0], "max_upscale_ratio", strlen("max_upscale_ratio"))) {
-        hw_resource_->max_scale_up = UINT32(atoi(tokens[1]));
-      } else if (!strncmp(tokens[0], "max_bandwidth_low", strlen("max_bandwidth_low"))) {
-        hw_resource_->max_bandwidth_low = std::stoull(tokens[1]);
-      } else if (!strncmp(tokens[0], "max_bandwidth_high", strlen("max_bandwidth_high"))) {
-        hw_resource_->max_bandwidth_high = std::stoull(tokens[1]);
-      } else if (!strncmp(tokens[0], "max_mixer_width", strlen("max_mixer_width"))) {
-        hw_resource_->max_mixer_width = UINT32(atoi(tokens[1]));
-      } else if (!strncmp(tokens[0], "max_pipe_width", strlen("max_pipe_width"))) {
-        hw_resource_->max_pipe_width = UINT32(atoi(tokens[1]));
-      } else if (!strncmp(tokens[0], "max_cursor_size", strlen("max_cursor_size"))) {
-        hw_resource_->max_cursor_size = UINT32(atoi(tokens[1]));
-      } else if (!strncmp(tokens[0], "max_pipe_bw", strlen("max_pipe_bw"))) {
-        hw_resource_->max_pipe_bw = std::stoull(tokens[1]);
-      } else if (!strncmp(tokens[0], "max_mdp_clk", strlen("max_mdp_clk"))) {
-        hw_resource_->max_sde_clk = UINT32(atoi(tokens[1]));
-      } else if (!strncmp(tokens[0], "clk_fudge_factor", strlen("clk_fudge_factor"))) {
-        hw_resource_->clk_fudge_factor = FLOAT(atoi(tokens[1])) / FLOAT(atoi(tokens[2]));
-      } else if (!strncmp(tokens[0], "fmt_mt_nv12_factor", strlen("fmt_mt_nv12_factor"))) {
-        hw_resource_->macrotile_nv12_factor = UINT32(atoi(tokens[1]));
-      } else if (!strncmp(tokens[0], "fmt_mt_factor", strlen("fmt_mt_factor"))) {
-        hw_resource_->macrotile_factor = UINT32(atoi(tokens[1]));
-      } else if (!strncmp(tokens[0], "fmt_linear_factor", strlen("fmt_linear_factor"))) {
-        hw_resource_->linear_factor = UINT32(atoi(tokens[1]));
-      } else if (!strncmp(tokens[0], "scale_factor", strlen("scale_factor"))) {
-        hw_resource_->scale_factor = UINT32(atoi(tokens[1]));
-      } else if (!strncmp(tokens[0], "xtra_ff_factor", strlen("xtra_ff_factor"))) {
-        hw_resource_->extra_fudge_factor = UINT32(atoi(tokens[1]));
-      } else if (!strncmp(tokens[0], "amortizable_threshold", strlen("amortizable_threshold"))) {
-        hw_resource_->amortizable_threshold = UINT32(atoi(tokens[1]));
-      } else if (!strncmp(tokens[0], "system_overhead_lines", strlen("system_overhead_lines"))) {
-        hw_resource_->system_overhead_lines = UINT32(atoi(tokens[1]));
-      } else if (!strncmp(tokens[0], "wb_intf_index", strlen("wb_intf_index"))) {
-        hw_resource_->writeback_index = UINT32(atoi(tokens[1]));
-      } else if (!strncmp(tokens[0], "dest_scaler_count", strlen("dest_scaler_count"))) {
-        hw_resource_->hw_dest_scalar_info.count = UINT32(atoi(tokens[1]));
-      } else if (!strncmp(tokens[0], "max_dest_scale_up", strlen("max_dest_scale_up"))) {
-        hw_resource_->hw_dest_scalar_info.max_scale_up = UINT32(atoi(tokens[1]));
-      } else if (!strncmp(tokens[0], "max_dest_scaler_input_width",
-                 strlen("max_dest_scaler_input_width"))) {
-        hw_resource_->hw_dest_scalar_info.max_input_width = UINT32(atoi(tokens[1]));
-      } else if (!strncmp(tokens[0], "max_dest_scaler_output_width",
-                 strlen("max_dest_scaler_output_width"))) {
-        hw_resource_->hw_dest_scalar_info.max_output_width = UINT32(atoi(tokens[1]));
-      } else if (!strncmp(tokens[0], "features", strlen("features"))) {
-        for (uint32_t i = 0; i < token_count; i++) {
-          if (!strncmp(tokens[i], "bwc", strlen("bwc"))) {
-            hw_resource_->has_bwc = true;
-          } else if (!strncmp(tokens[i], "ubwc", strlen("ubwc"))) {
-            hw_resource_->has_ubwc = true;
-          } else if (!strncmp(tokens[i], "decimation", strlen("decimation"))) {
-            hw_resource_->has_decimation = true;
-          } else if (!strncmp(tokens[i], "tile_format", strlen("tile_format"))) {
-            hw_resource_->has_macrotile = true;
-          } else if (!strncmp(tokens[i], "src_split", strlen("src_split"))) {
-            hw_resource_->is_src_split = true;
-          } else if (!strncmp(tokens[i], "non_scalar_rgb", strlen("non_scalar_rgb"))) {
-            hw_resource_->has_non_scalar_rgb = true;
-          } else if (!strncmp(tokens[i], "dynamic_bw_limit", strlen("dynamic_bw_limit"))) {
-            hw_resource_->has_dyn_bw_support = true;
-          } else if (!strncmp(tokens[i], "separate_rotator", strlen("separate_rotator"))) {
-            hw_resource_->separate_rotator = true;
-          } else if (!strncmp(tokens[i], "qseed3", strlen("qseed3"))) {
-            hw_resource_->has_qseed3 = true;
-          } else if (!strncmp(tokens[i], "has_ppp", strlen("has_ppp"))) {
-            hw_resource_->has_ppp = true;
-          } else if (!strncmp(tokens[i], "concurrent_writeback", strlen("concurrent_writeback"))) {
-            hw_resource_->has_concurrent_writeback = true;
-          } else if (!strncmp(tokens[i], "avr", strlen("avr"))) {
-            hw_resource_->has_avr = true;
-          } else if (!strncmp(tokens[i], "hdr", strlen("hdr"))) {
-            hw_resource_->has_hdr = true;
-          }
-        }
-      } else if (!strncmp(tokens[0], "pipe_count", strlen("pipe_count"))) {
-        uint32_t pipe_count = UINT8(atoi(tokens[1]));
-        for (uint32_t i = 0; i < pipe_count; i++) {
-          Sys::getline_(fs, line);
-          if (!ParseString(line.c_str(), tokens, max_count, ": =\n", &token_count)) {
-            HWPipeCaps pipe_caps;
-            pipe_caps.type = kPipeTypeUnused;
-            for (uint32_t j = 0; j < token_count; j += 2) {
-              if (!strncmp(tokens[j], "pipe_type", strlen("pipe_type"))) {
-                if (!strncmp(tokens[j+1], "vig", strlen("vig"))) {
-                  pipe_caps.type = kPipeTypeVIG;
-                  hw_resource_->num_vig_pipe++;
-                } else if (!strncmp(tokens[j+1], "rgb", strlen("rgb"))) {
-                  pipe_caps.type = kPipeTypeRGB;
-                  hw_resource_->num_rgb_pipe++;
-                } else if (!strncmp(tokens[j+1], "dma", strlen("dma"))) {
-                  pipe_caps.type = kPipeTypeDMA;
-                  hw_resource_->num_dma_pipe++;
-                } else if (!strncmp(tokens[j+1], "cursor", strlen("cursor"))) {
-                  pipe_caps.type = kPipeTypeCursor;
-                  hw_resource_->num_cursor_pipe++;
-                }
-              } else if (!strncmp(tokens[j], "pipe_ndx", strlen("pipe_ndx"))) {
-                pipe_caps.id = UINT32(atoi(tokens[j+1]));
-              } else if (!strncmp(tokens[j], "rects", strlen("rects"))) {
-                pipe_caps.max_rects = UINT32(atoi(tokens[j+1]));
-              } else if (!strncmp(tokens[j], "fmts_supported", strlen("fmts_supported"))) {
-                char *tokens_fmt[max_count] = { NULL };
-                uint32_t token_fmt_count = 0;
-                if (!ParseString(tokens[j+1], tokens_fmt, max_count, ",\n", &token_fmt_count)) {
-                  if (pipe_caps.type == kPipeTypeVIG) {
-                    ParseFormats(tokens_fmt, token_fmt_count, kHWVIGPipe, hw_resource_);
-                  } else if (pipe_caps.type == kPipeTypeRGB) {
-                    ParseFormats(tokens_fmt, token_fmt_count, kHWRGBPipe, hw_resource_);
-                  } else if (pipe_caps.type == kPipeTypeDMA) {
-                    ParseFormats(tokens_fmt, token_fmt_count, kHWDMAPipe, hw_resource_);
-                  } else if (pipe_caps.type == kPipeTypeCursor) {
-                    ParseFormats(tokens_fmt, token_fmt_count, kHWCursorPipe, hw_resource_);
-                  }
-                }
-              }
-            }
-            hw_resource_->hw_pipes.push_back(pipe_caps);
-          }
-        }
-      }
-    }
-  }
-
-  // Disable destination scalar count to 0 if extension library is not present
-  DynLib extension_lib;
-  if (!extension_lib.Open("libsdmextension.so")) {
-    hw_resource_->hw_dest_scalar_info.count = 0;
-  }
-
-  DLOGI("SDE Version = %d, SDE Revision = %x, RGB = %d, VIG = %d, DMA = %d, Cursor = %d",
-        hw_resource_->hw_version, hw_resource_->hw_revision, hw_resource_->num_rgb_pipe,
-        hw_resource_->num_vig_pipe, hw_resource_->num_dma_pipe, hw_resource_->num_cursor_pipe);
-  DLOGI("Upscale Ratio = %d, Downscale Ratio = %d, Blending Stages = %d",
-        hw_resource_->max_scale_up, hw_resource_->max_scale_down,
-        hw_resource_->num_blending_stages);
-  DLOGI("SourceSplit = %d QSEED3 = %d", hw_resource_->is_src_split, hw_resource_->has_qseed3);
-  DLOGI("BWC = %d, UBWC = %d, Decimation = %d, Tile Format = %d Concurrent Writeback = %d",
-        hw_resource_->has_bwc, hw_resource_->has_ubwc, hw_resource_->has_decimation,
-        hw_resource_->has_macrotile, hw_resource_->has_concurrent_writeback);
-  DLOGI("MaxLowBw = %" PRIu64 " , MaxHighBw = % " PRIu64 "", hw_resource_->max_bandwidth_low,
-        hw_resource_->max_bandwidth_high);
-  DLOGI("MaxPipeBw = %" PRIu64 " KBps, MaxSDEClock = % " PRIu64 " Hz, ClockFudgeFactor = %f",
-        hw_resource_->max_pipe_bw, hw_resource_->max_sde_clk, hw_resource_->clk_fudge_factor);
-  DLOGI("Prefill factors: Tiled_NV12 = %d, Tiled = %d, Linear = %d, Scale = %d, Fudge_factor = %d",
-        hw_resource_->macrotile_nv12_factor, hw_resource_->macrotile_factor,
-        hw_resource_->linear_factor, hw_resource_->scale_factor, hw_resource_->extra_fudge_factor);
-
-  if (hw_resource_->separate_rotator || hw_resource_->num_dma_pipe) {
-    GetHWRotatorInfo(hw_resource_);
-  }
-
-  // If the driver doesn't spell out the wb index, assume it to be the number of rotators,
-  // based on legacy implementation.
-  if (hw_resource_->writeback_index == kHWBlockMax) {
-    hw_resource_->writeback_index = hw_resource_->hw_rot_info.num_rotator;
-  }
-
-  if (hw_resource_->has_dyn_bw_support) {
-    DisplayError ret = GetDynamicBWLimits(hw_resource_);
-    if (ret != kErrorNone) {
-      DLOGE("Failed to read dynamic band width info");
-      return ret;
-    }
-
-    DLOGI("Has Support for multiple bw limits shown below");
-    for (int index = 0; index < kBwModeMax; index++) {
-      DLOGI("Mode-index=%d  total_bw_limit=%d and pipe_bw_limit=%d",
-            index, hw_resource_->dyn_bw_info.total_bw_limit[index],
-            hw_resource_->dyn_bw_info.pipe_bw_limit[index]);
-    }
-  }
-
-  *hw_resource = *hw_resource_;
-
-  return kErrorNone;
-}
-
-DisplayError HWInfo::GetHWRotatorInfo(HWResourceInfo *hw_resource) {
-  if (GetMDSSRotatorInfo(hw_resource) != kErrorNone)
-    return GetV4L2RotatorInfo(hw_resource);
-
-  return kErrorNone;
-}
-
-DisplayError HWInfo::GetMDSSRotatorInfo(HWResourceInfo *hw_resource) {
-  Sys::fstream fs(kRotatorCapsPath, fstream::in);
-  if (!fs.is_open()) {
-    DLOGW("File '%s' not found", kRotatorCapsPath);
-    return kErrorNotSupported;
-  }
-
-  uint32_t token_count = 0;
-  const uint32_t max_count = 10;
-  char *tokens[max_count] = { NULL };
-  string line;
-
-  hw_resource->hw_rot_info.type = HWRotatorInfo::ROT_TYPE_MDSS;
-  while (Sys::getline_(fs, line)) {
-    if (!ParseString(line.c_str(), tokens, max_count, ":, =\n", &token_count)) {
-      if (!strncmp(tokens[0], "wb_count", strlen("wb_count"))) {
-        hw_resource->hw_rot_info.num_rotator = UINT8(atoi(tokens[1]));
-        hw_resource->hw_rot_info.device_path = "/dev/mdss_rotator";
-      } else if (!strncmp(tokens[0], "downscale", strlen("downscale"))) {
-        hw_resource->hw_rot_info.has_downscale = UINT8(atoi(tokens[1]));
-      }
-    }
-  }
-
-  DLOGI("MDSS Rotator: Count = %d, Downscale = %d, Min_downscale = %f",
-        hw_resource->hw_rot_info.num_rotator, hw_resource->hw_rot_info.has_downscale,
-        hw_resource->hw_rot_info.min_downscale);
-
-  return kErrorNone;
-}
-
-DisplayError HWInfo::GetV4L2RotatorInfo(HWResourceInfo *hw_resource) {
-  string v4l2_path = "/sys/class/video4linux/video";
-  const uint32_t kMaxV4L2Nodes = 64;
-  bool found = false;
-
-  for (uint32_t i = 0; (i < kMaxV4L2Nodes) && (false == found); i++) {
-    string path = v4l2_path + to_string(i) + "/name";
-    Sys::fstream fs(path, fstream::in);
-    if (!fs.is_open()) {
-      continue;
-    }
-
-    string line;
-    if (Sys::getline_(fs, line) &&
-        (!strncmp(line.c_str(), "sde_rotator", strlen("sde_rotator")))) {
-       hw_resource->hw_rot_info.device_path = string("/dev/video" + to_string(i));
-       hw_resource->hw_rot_info.num_rotator++;
-       hw_resource->hw_rot_info.type = HWRotatorInfo::ROT_TYPE_V4L2;
-       hw_resource->hw_rot_info.has_downscale = true;
-
-       string caps_path = v4l2_path + to_string(i) + "/device/caps";
-       Sys::fstream caps_fs(caps_path, fstream::in);
-
-       if (caps_fs.is_open()) {
-         uint32_t token_count = 0;
-         const uint32_t max_count = 10;
-         char *tokens[max_count] = { NULL };
-         string caps;
-         while (Sys::getline_(caps_fs, caps)) {
-           if (!ParseString(caps.c_str(), tokens, max_count, ":, =\n", &token_count)) {
-             if (tokens[0] != NULL) {
-               if (!strncmp(tokens[0], "downscale_compression", strlen("downscale_compression"))) {
-                 hw_resource->hw_rot_info.downscale_compression = UINT8(atoi(tokens[1]));
-               } else if (!strncmp(tokens[0], "min_downscale", strlen("min_downscale"))) {
-                 hw_resource->hw_rot_info.min_downscale = FLOAT(atof(tokens[1]));
-               }
-             }
-           }
-         }
-       }
-
-       // We support only 1 rotator
-       found = true;
-    }
-  }
-
-  DLOGI("V4L2 Rotator: Count = %d, Downscale = %d, Min_downscale = %f, Downscale_compression = %d",
-        hw_resource->hw_rot_info.num_rotator, hw_resource->hw_rot_info.has_downscale,
-        hw_resource->hw_rot_info.min_downscale, hw_resource->hw_rot_info.downscale_compression);
-
-  return kErrorNone;
-}
-
-LayerBufferFormat HWInfo::GetSDMFormat(int mdp_format) {
-  switch (mdp_format) {
-  case MDP_ARGB_8888:              return kFormatARGB8888;
-  case MDP_RGBA_8888:              return kFormatRGBA8888;
-  case MDP_BGRA_8888:              return kFormatBGRA8888;
-  case MDP_XRGB_8888:              return kFormatXRGB8888;
-  case MDP_RGBX_8888:              return kFormatRGBX8888;
-  case MDP_BGRX_8888:              return kFormatBGRX8888;
-  case MDP_RGBA_5551:              return kFormatRGBA5551;
-  case MDP_RGBA_4444:              return kFormatRGBA4444;
-  case MDP_RGB_888:                return kFormatRGB888;
-  case MDP_BGR_888:                return kFormatBGR888;
-  case MDP_RGB_565:                return kFormatRGB565;
-  case MDP_BGR_565:                return kFormatBGR565;
-  case MDP_RGBA_8888_UBWC:         return kFormatRGBA8888Ubwc;
-  case MDP_RGBX_8888_UBWC:         return kFormatRGBX8888Ubwc;
-  case MDP_RGB_565_UBWC:           return kFormatBGR565Ubwc;
-  case MDP_Y_CB_CR_H2V2:           return kFormatYCbCr420Planar;
-  case MDP_Y_CR_CB_H2V2:           return kFormatYCrCb420Planar;
-  case MDP_Y_CR_CB_GH2V2:          return kFormatYCrCb420PlanarStride16;
-  case MDP_Y_CBCR_H2V2:            return kFormatYCbCr420SemiPlanar;
-  case MDP_Y_CRCB_H2V2:            return kFormatYCrCb420SemiPlanar;
-  case MDP_Y_CBCR_H2V2_VENUS:      return kFormatYCbCr420SemiPlanarVenus;
-  case MDP_Y_CBCR_H1V2:            return kFormatYCbCr422H1V2SemiPlanar;
-  case MDP_Y_CRCB_H1V2:            return kFormatYCrCb422H1V2SemiPlanar;
-  case MDP_Y_CBCR_H2V1:            return kFormatYCbCr422H2V1SemiPlanar;
-  case MDP_Y_CRCB_H2V1:            return kFormatYCrCb422H2V1SemiPlanar;
-  case MDP_Y_CBCR_H2V2_UBWC:       return kFormatYCbCr420SPVenusUbwc;
-  case MDP_Y_CRCB_H2V2_VENUS:      return kFormatYCrCb420SemiPlanarVenus;
-  case MDP_YCBYCR_H2V1:            return kFormatYCbCr422H2V1Packed;
-  case MDP_RGBA_1010102:           return kFormatRGBA1010102;
-  case MDP_ARGB_2101010:           return kFormatARGB2101010;
-  case MDP_RGBX_1010102:           return kFormatRGBX1010102;
-  case MDP_XRGB_2101010:           return kFormatXRGB2101010;
-  case MDP_BGRA_1010102:           return kFormatBGRA1010102;
-  case MDP_ABGR_2101010:           return kFormatABGR2101010;
-  case MDP_BGRX_1010102:           return kFormatBGRX1010102;
-  case MDP_XBGR_2101010:           return kFormatXBGR2101010;
-  case MDP_RGBA_1010102_UBWC:      return kFormatRGBA1010102Ubwc;
-  case MDP_RGBX_1010102_UBWC:      return kFormatRGBX1010102Ubwc;
-  case MDP_Y_CBCR_H2V2_P010:       return kFormatYCbCr420P010;
-  case MDP_Y_CBCR_H2V2_TP10_UBWC:  return kFormatYCbCr420TP10Ubwc;
-  default:                         return kFormatInvalid;
-  }
-}
-
-void HWInfo::InitSupportedFormatMap(HWResourceInfo *hw_resource) {
-  hw_resource->supported_formats_map.clear();
-
-  for (int sub_blk_type = INT(kHWVIGPipe); sub_blk_type < INT(kHWSubBlockMax); sub_blk_type++) {
-    PopulateSupportedFormatMap(kDefaultFormatSupport[sub_blk_type], MDP_IMGTYPE_LIMIT1,
-                               (HWSubBlockType)sub_blk_type, hw_resource);
-  }
-}
-
-void HWInfo::ParseFormats(char *tokens[], uint32_t token_count, HWSubBlockType sub_blk_type,
-                          HWResourceInfo *hw_resource) {
-  if (token_count > BITS_TO_BYTES(MDP_IMGTYPE_LIMIT1)) {
-    return;
-  }
-
-  std::unique_ptr<std::bitset<8>[]> format_supported(new std::bitset<8>[token_count]);
-  for (uint32_t i = 0; i < token_count; i++) {
-    format_supported[i] = UINT8(atoi(tokens[i]));
-  }
-
-  PopulateSupportedFormatMap(format_supported.get(), (token_count << 3), sub_blk_type, hw_resource);
-}
-
-void HWInfo::PopulateSupportedFormatMap(const std::bitset<8> *format_supported,
-                                        uint32_t format_count, HWSubBlockType sub_blk_type,
-                                        HWResourceInfo *hw_resource) {
-  vector <LayerBufferFormat> supported_sdm_formats;
-  for (uint32_t mdp_format = 0; mdp_format < format_count; mdp_format++) {
-    if (format_supported[mdp_format >> 3][mdp_format & 7]) {
-      LayerBufferFormat sdm_format = GetSDMFormat(INT(mdp_format));
-      if (sdm_format != kFormatInvalid) {
-        supported_sdm_formats.push_back(sdm_format);
-      }
-    }
-  }
-
-  hw_resource->supported_formats_map.erase(sub_blk_type);
-  hw_resource->supported_formats_map.insert(make_pair(sub_blk_type, supported_sdm_formats));
-}
-
-DisplayError HWInfo::GetFirstDisplayInterfaceType(HWDisplayInterfaceInfo *hw_disp_info) {
-  Sys::fstream fs("/sys/devices/virtual/graphics/fb0/msm_fb_type", fstream::in);
-  if (!fs.is_open()) {
-    return kErrorHardware;
-  }
-
-  string line;
-  if (!Sys::getline_(fs, line)) {
-    return kErrorHardware;
-  }
-
-  if (!strncmp(line.c_str(), "dtv panel", strlen("dtv panel")) ||
-      !strncmp(line.c_str(), "dp panel", strlen("dp panel"))) {
-    hw_disp_info->type = kHDMI;
-    DLOGI("First display is HDMI");
-  } else {
-    hw_disp_info->type = kPrimary;
-    DLOGI("First display is internal display");
-  }
-
-  fs.close();
-  fs.open("/sys/devices/virtual/graphics/fb0/connected", fstream::in);
-  if (!fs.is_open()) {
-    // If fb0 is for a DSI/connected panel, then connected node will not exist.
-    hw_disp_info->is_connected = true;
-  } else {
-    if (!Sys::getline_(fs, line)) {
-      return kErrorHardware;
-    }
-
-    hw_disp_info->is_connected =  (!strncmp(line.c_str(), "1", strlen("1")));
-  }
-
-  return kErrorNone;
-}
-
-}  // namespace sdm
-
diff --git a/sdm/libs/core/fb/hw_info.h b/sdm/libs/core/fb/hw_info.h
deleted file mode 100644
index cbceba0..0000000
--- a/sdm/libs/core/fb/hw_info.h
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
-* Copyright (c) 2015 - 2017, The Linux Foundation. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without modification, are permitted
-* provided that the following conditions are met:
-*    * Redistributions of source code must retain the above copyright notice, this list of
-*      conditions and the following disclaimer.
-*    * Redistributions in binary form must reproduce the above copyright notice, this list of
-*      conditions and the following disclaimer in the documentation and/or other materials provided
-*      with the distribution.
-*    * Neither the name of The Linux Foundation nor the names of its contributors may be used to
-*      endorse or promote products derived from this software without specific prior written
-*      permission.
-*
-* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-* NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
-* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
-* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
-* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#ifndef __HW_INFO_H__
-#define __HW_INFO_H__
-
-#include <core/sdm_types.h>
-#include <core/core_interface.h>
-#include <private/hw_info_types.h>
-#include <linux/msm_mdp.h>
-#include <bitset>
-
-#include "hw_info_interface.h"
-
-#ifndef MDP_IMGTYPE_END
-#define MDP_IMGTYPE_LIMIT1 0x100
-#endif
-
-namespace sdm {
-
-class HWInfo: public HWInfoInterface {
- public:
-  virtual ~HWInfo() { delete hw_resource_; }
-  virtual DisplayError GetHWResourceInfo(HWResourceInfo *hw_resource);
-  virtual DisplayError GetFirstDisplayInterfaceType(HWDisplayInterfaceInfo *hw_disp_info);
-
- private:
-  virtual DisplayError GetHWRotatorInfo(HWResourceInfo *hw_resource);
-  virtual DisplayError GetMDSSRotatorInfo(HWResourceInfo *hw_resource);
-  virtual DisplayError GetV4L2RotatorInfo(HWResourceInfo *hw_resource);
-
-  // TODO(user): Read Mdss version from the driver
-  static const int kHWMdssVersion5 = 500;  // MDSS_V5
-  static const int kMaxStringLength = 1024;
-  // MDP Capabilities are replicated across all frame buffer devices.
-  // However, we rely on reading the capabalities from fbO since this
-  // is guaranteed to be available.
-  static const int kHWCapabilitiesNode = 0;
-  static const std::bitset<8> kDefaultFormatSupport[kHWSubBlockMax][
-                                                        BITS_TO_BYTES(MDP_IMGTYPE_LIMIT1)];
-  static constexpr const char *kRotatorCapsPath = "/sys/devices/virtual/rotator/mdss_rotator/caps";
-  static constexpr const char *kBWModeBitmap
-                                  = "/sys/devices/virtual/graphics/fb0/mdp/bw_mode_bitmap";
-
-  static int ParseString(const char *input, char *tokens[], const uint32_t max_token,
-                         const char *delim, uint32_t *count);
-  DisplayError GetDynamicBWLimits(HWResourceInfo *hw_resource);
-  LayerBufferFormat GetSDMFormat(int mdp_format);
-  void InitSupportedFormatMap(HWResourceInfo *hw_resource);
-  void ParseFormats(char *tokens[], uint32_t token_count, HWSubBlockType sub_block_type,
-                    HWResourceInfo *hw_resource);
-  void PopulateSupportedFormatMap(const std::bitset<8> *format_supported, uint32_t format_count,
-                                  HWSubBlockType sub_blk_type, HWResourceInfo *hw_resource);
-  HWResourceInfo *hw_resource_ = NULL;
-};
-
-}  // namespace sdm
-
-#endif  // __HW_INFO_H__
-
diff --git a/sdm/libs/core/fb/hw_primary.cpp b/sdm/libs/core/fb/hw_primary.cpp
deleted file mode 100644
index 4c72402..0000000
--- a/sdm/libs/core/fb/hw_primary.cpp
+++ /dev/null
@@ -1,673 +0,0 @@
-/*
-* Copyright (c) 2015 - 2018, The Linux Foundation. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without
-* modification, are permitted provided that the following conditions are
-* met:
-*     * Redistributions of source code must retain the above copyright
-*       notice, this list of conditions and the following disclaimer.
-*     * Redistributions in binary form must reproduce the above
-*       copyright notice, this list of conditions and the following
-*       disclaimer in the documentation and/or other materials provided
-*       with the distribution.
-*     * Neither the name of The Linux Foundation nor the names of its
-*       contributors may be used to endorse or promote products derived
-*       from this software without specific prior written permission.
-*
-* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
-* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
-* ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
-* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
-* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#include <stdio.h>
-#include <unistd.h>
-#include <string.h>
-#include <pthread.h>
-#include <fcntl.h>
-#include <sys/prctl.h>
-#include <sys/ioctl.h>
-#include <sys/time.h>
-#include <sys/resource.h>
-#include <utils/debug.h>
-#include <utils/sys.h>
-#include <core/display_interface.h>
-#include <linux/msm_mdp_ext.h>
-#include <utils/rect.h>
-
-#include <string>
-
-#include "hw_primary.h"
-#include "hw_color_manager.h"
-
-#define __CLASS__ "HWPrimary"
-
-#ifndef MDP_COMMIT_CWB_EN
-#define MDP_COMMIT_CWB_EN 0x800
-#endif
-
-#ifndef MDP_COMMIT_CWB_DSPP
-#define MDP_COMMIT_CWB_DSPP 0x1000
-#endif
-
-#ifndef MDP_COMMIT_AVR_EN
-#define MDP_COMMIT_AVR_EN 0x08
-#endif
-
-#ifndef MDP_COMMIT_AVR_ONE_SHOT_MODE
-#define MDP_COMMIT_AVR_ONE_SHOT_MODE 0x10
-#endif
-
-#ifndef MDP_COMMIT_PARTIAL_UPDATE_DUAL_ROI
-#define MDP_COMMIT_PARTIAL_UPDATE_DUAL_ROI  0x20
-#endif
-
-namespace sdm {
-
-using std::string;
-using std::to_string;
-using std::fstream;
-
-HWPrimary::HWPrimary(BufferSyncHandler *buffer_sync_handler, HWInfoInterface *hw_info_intf)
-  : HWDevice(buffer_sync_handler) {
-  HWDevice::device_type_ = kDevicePrimary;
-  HWDevice::device_name_ = "Primary Display Device";
-  HWDevice::hw_info_intf_ = hw_info_intf;
-}
-
-DisplayError HWPrimary::Init() {
-  DisplayError error = kErrorNone;
-
-  error = HWDevice::Init();
-  if (error != kErrorNone) {
-    return error;
-  }
-
-  mdp_dest_scalar_data_.resize(hw_resource_.hw_dest_scalar_info.count);
-
-  error = PopulateDisplayAttributes();
-  if (error != kErrorNone) {
-    return error;
-  }
-
-  UpdateMixerAttributes();
-
-  // Need to enable HPD, but toggle at start when HDMI is external
-  // This helps for framework reboot or adb shell stop/start
-  EnableHotPlugDetection(0);
-  EnableHotPlugDetection(1);
-  InitializeConfigs();
-
-  avr_prop_disabled_ = Debug::IsAVRDisabled();
-
-  return error;
-}
-
-bool HWPrimary::GetCurrentModeFromSysfs(size_t *curr_x_pixels, size_t *curr_y_pixels) {
-  bool ret = false;
-  string mode_path = fb_path_ + string("0/mode");
-
-  Sys::fstream fs(mode_path, fstream::in);
-  if (!fs.is_open()) {
-    return false;
-  }
-
-  string line;
-  if (Sys::getline_(fs, line)) {
-    // String is of form "U:1600x2560p-0". Documentation/fb/modedb.txt in
-    // kernel has more info on the format.
-    size_t xpos = line.find(':');
-    size_t ypos = line.find('x');
-
-    if (xpos == string::npos || ypos == string::npos) {
-      DLOGI("Resolution switch not supported");
-    } else {
-      *curr_x_pixels = static_cast<size_t>(atoi(line.c_str() + xpos + 1));
-      *curr_y_pixels = static_cast<size_t>(atoi(line.c_str() + ypos + 1));
-      DLOGI("Current Config: %u x %u", *curr_x_pixels, *curr_y_pixels);
-      ret = true;
-    }
-  }
-
-  return ret;
-}
-
-void HWPrimary::InitializeConfigs() {
-  size_t curr_x_pixels = 0;
-  size_t curr_y_pixels = 0;
-
-  if (!GetCurrentModeFromSysfs(&curr_x_pixels, &curr_y_pixels)) {
-    return;
-  }
-
-  string modes_path = string(fb_path_) + string("0/modes");
-
-  Sys::fstream fs(modes_path, fstream::in);
-  if (!fs.is_open()) {
-    DLOGI("Unable to process modes");
-    return;
-  }
-
-  string line;
-  while (Sys::getline_(fs, line)) {
-    DisplayConfigVariableInfo config;
-    // std::getline (unlike ::getline) removes \n while driver expects it in mode, so add back
-    line += '\n';
-    size_t xpos = line.find(':');
-    size_t ypos = line.find('x');
-
-    if (xpos == string::npos || ypos == string::npos) {
-      continue;
-    }
-
-    config.x_pixels = UINT32(atoi(line.c_str() + xpos + 1));
-    config.y_pixels = UINT32(atoi(line.c_str() + ypos + 1));
-    DLOGI("Found mode %d x %d", config.x_pixels, config.y_pixels);
-    display_configs_.push_back(config);
-    display_config_strings_.push_back(string(line.c_str()));
-
-    if (curr_x_pixels == config.x_pixels && curr_y_pixels == config.y_pixels) {
-      active_config_index_ = UINT32(display_configs_.size() - 1);
-      DLOGI("Active config index %u", active_config_index_);
-    }
-  }
-}
-
-DisplayError HWPrimary::GetNumDisplayAttributes(uint32_t *count) {
-  *count = IsResolutionSwitchEnabled() ? UINT32(display_configs_.size()) : 1;
-  return kErrorNone;
-}
-
-DisplayError HWPrimary::GetActiveConfig(uint32_t *active_config_index) {
-  *active_config_index = active_config_index_;
-  return kErrorNone;
-}
-
-DisplayError HWPrimary::GetDisplayAttributes(uint32_t index,
-                                             HWDisplayAttributes *display_attributes) {
-  if (!display_attributes) {
-    return kErrorParameters;
-  }
-
-  if (IsResolutionSwitchEnabled() && index >= display_configs_.size()) {
-    return kErrorParameters;
-  }
-
-  *display_attributes = display_attributes_;
-  if (IsResolutionSwitchEnabled()) {
-    // Overwrite only the parent portion of object
-    display_attributes->x_pixels = display_configs_.at(index).x_pixels;
-    display_attributes->y_pixels = display_configs_.at(index).y_pixels;
-  }
-
-  return kErrorNone;
-}
-
-DisplayError HWPrimary::PopulateDisplayAttributes() {
-  DTRACE_SCOPED();
-
-  // Variable screen info
-  fb_var_screeninfo var_screeninfo = {};
-
-  if (Sys::ioctl_(device_fd_, FBIOGET_VSCREENINFO, &var_screeninfo) < 0) {
-    IOCTL_LOGE(FBIOGET_VSCREENINFO, device_type_);
-    return kErrorHardware;
-  }
-
-  // Frame rate
-  msmfb_metadata meta_data = {};
-  meta_data.op = metadata_op_frame_rate;
-  if (Sys::ioctl_(device_fd_, MSMFB_METADATA_GET, &meta_data) < 0) {
-    IOCTL_LOGE(MSMFB_METADATA_GET, device_type_);
-    return kErrorHardware;
-  }
-
-  // If driver doesn't return width/height information, default to 320 dpi
-  if (INT(var_screeninfo.width) <= 0 || INT(var_screeninfo.height) <= 0) {
-    var_screeninfo.width  = UINT32(((FLOAT(var_screeninfo.xres) * 25.4f)/320.0f) + 0.5f);
-    var_screeninfo.height = UINT32(((FLOAT(var_screeninfo.yres) * 25.4f)/320.0f) + 0.5f);
-    DLOGW("Driver doesn't report panel physical width and height - defaulting to 320dpi");
-  }
-
-  display_attributes_.x_pixels = var_screeninfo.xres;
-  display_attributes_.y_pixels = var_screeninfo.yres;
-  display_attributes_.v_front_porch = var_screeninfo.lower_margin;
-  display_attributes_.v_back_porch = var_screeninfo.upper_margin;
-  display_attributes_.v_pulse_width = var_screeninfo.vsync_len;
-  uint32_t h_blanking = var_screeninfo.right_margin + var_screeninfo.left_margin +
-      var_screeninfo.hsync_len;
-  display_attributes_.h_total = var_screeninfo.xres + h_blanking;
-  display_attributes_.x_dpi =
-      (FLOAT(var_screeninfo.xres) * 25.4f) / FLOAT(var_screeninfo.width);
-  display_attributes_.y_dpi =
-      (FLOAT(var_screeninfo.yres) * 25.4f) / FLOAT(var_screeninfo.height);
-  display_attributes_.fps = meta_data.data.panel_frame_rate;
-  display_attributes_.vsync_period_ns = UINT32(1000000000L / display_attributes_.fps);
-  display_attributes_.is_device_split = (hw_panel_info_.split_info.right_split ||
-      (var_screeninfo.xres > hw_resource_.max_mixer_width));
-  display_attributes_.h_total += (display_attributes_.is_device_split ||
-    hw_panel_info_.ping_pong_split)? h_blanking : 0;
-
-  return kErrorNone;
-}
-
-DisplayError HWPrimary::SetDisplayAttributes(uint32_t index) {
-  DisplayError ret = kErrorNone;
-
-  if (!IsResolutionSwitchEnabled()) {
-    return kErrorNotSupported;
-  }
-
-  if (index >= display_configs_.size()) {
-    return kErrorParameters;
-  }
-
-  string mode_path = string(fb_path_) + string("0/mode");
-  int fd = Sys::open_(mode_path.c_str(), O_WRONLY);
-
-  if (fd < 0) {
-    DLOGE("Opening mode failed");
-    return kErrorNotSupported;
-  }
-
-  ssize_t written = Sys::pwrite_(fd, display_config_strings_.at(index).c_str(),
-                                 display_config_strings_.at(index).length(), 0);
-  if (written > 0) {
-    DLOGI("Successfully set config %u", index);
-    PopulateHWPanelInfo();
-    PopulateDisplayAttributes();
-    UpdateMixerAttributes();
-    active_config_index_ = index;
-  } else {
-    DLOGE("Writing config index %u failed with error: %s", index, strerror(errno));
-    ret = kErrorParameters;
-  }
-
-  Sys::close_(fd);
-
-  return ret;
-}
-
-DisplayError HWPrimary::SetRefreshRate(uint32_t refresh_rate) {
-  char node_path[kMaxStringLength] = {0};
-
-  if (hw_resource_.has_avr && !avr_prop_disabled_) {
-    return kErrorNotSupported;
-  }
-
-  snprintf(node_path, sizeof(node_path), "%s%d/dynamic_fps", fb_path_, fb_node_index_);
-
-  int fd = Sys::open_(node_path, O_WRONLY);
-  if (fd < 0) {
-    DLOGE("Failed to open %s with error %s", node_path, strerror(errno));
-    return kErrorFileDescriptor;
-  }
-
-  char refresh_rate_string[kMaxStringLength];
-  snprintf(refresh_rate_string, sizeof(refresh_rate_string), "%d", refresh_rate);
-  DLOGI_IF(kTagDriverConfig, "Setting refresh rate = %d", refresh_rate);
-  ssize_t len = Sys::pwrite_(fd, refresh_rate_string, strlen(refresh_rate_string), 0);
-  if (len < 0) {
-    DLOGE("Failed to write %d with error %s", refresh_rate, strerror(errno));
-    Sys::close_(fd);
-    return kErrorUndefined;
-  }
-  Sys::close_(fd);
-
-  DisplayError error = PopulateDisplayAttributes();
-  if (error != kErrorNone) {
-    return error;
-  }
-
-  return kErrorNone;
-}
-
-DisplayError HWPrimary::GetConfigIndex(char *mode, uint32_t *index) {
-  return HWDevice::GetConfigIndex(mode, index);
-}
-
-DisplayError HWPrimary::PowerOff() {
-  if (Sys::ioctl_(device_fd_, FBIOBLANK, FB_BLANK_POWERDOWN) < 0) {
-    IOCTL_LOGE(FB_BLANK_POWERDOWN, device_type_);
-    return kErrorHardware;
-  }
-
-  auto_refresh_ = false;
-
-  return kErrorNone;
-}
-
-DisplayError HWPrimary::Doze(int *release_fence) {
-  if (Sys::ioctl_(device_fd_, FBIOBLANK, FB_BLANK_NORMAL) < 0) {
-    IOCTL_LOGE(FB_BLANK_NORMAL, device_type_);
-    return kErrorHardware;
-  }
-
-  return kErrorNone;
-}
-
-DisplayError HWPrimary::DozeSuspend(int *release_fence) {
-  if (Sys::ioctl_(device_fd_, FBIOBLANK, FB_BLANK_VSYNC_SUSPEND) < 0) {
-    IOCTL_LOGE(FB_BLANK_VSYNC_SUSPEND, device_type_);
-    return kErrorHardware;
-  }
-
-  return kErrorNone;
-}
-
-DisplayError HWPrimary::Validate(HWLayers *hw_layers) {
-  HWLayersInfo &hw_layer_info = hw_layers->info;
-  LayerStack *stack = hw_layer_info.stack;
-
-  HWDevice::ResetDisplayParams();
-
-  mdp_layer_commit_v1 &mdp_commit = mdp_disp_commit_.commit_v1;
-
-  LayerRect left_roi = hw_layer_info.left_frame_roi.at(0);
-  LayerRect right_roi = hw_layer_info.right_frame_roi.at(0);
-
-  mdp_commit.left_roi.x = UINT32(left_roi.left);
-  mdp_commit.left_roi.y = UINT32(left_roi.top);
-  mdp_commit.left_roi.w = UINT32(left_roi.right - left_roi.left);
-  mdp_commit.left_roi.h = UINT32(left_roi.bottom - left_roi.top);
-
-  // Update second roi information in right_roi
-  if (hw_layer_info.left_frame_roi.size() == 2) {
-    mdp_commit.flags |= MDP_COMMIT_PARTIAL_UPDATE_DUAL_ROI;
-    right_roi = hw_layer_info.left_frame_roi.at(1);
-  }
-
-  // SDM treats ROI as one full coordinate system.
-  // In case source split is disabled, However, Driver assumes Mixer to operate in
-  // different co-ordinate system.
-  if (IsValid(right_roi)) {
-    mdp_commit.right_roi.x = UINT32(right_roi.left);
-    if (!hw_resource_.is_src_split) {
-      mdp_commit.right_roi.x = UINT32(right_roi.left) - mixer_attributes_.split_left;
-    }
-    mdp_commit.right_roi.y = UINT32(right_roi.top);
-    mdp_commit.right_roi.w = UINT32(right_roi.right - right_roi.left);
-    mdp_commit.right_roi.h = UINT32(right_roi.bottom - right_roi.top);
-  }
-
-  if (stack->output_buffer && hw_resource_.has_concurrent_writeback) {
-    LayerBuffer *output_buffer = stack->output_buffer;
-    mdp_out_layer_.writeback_ndx = hw_resource_.writeback_index;
-    mdp_out_layer_.buffer.width = output_buffer->unaligned_width;
-    mdp_out_layer_.buffer.height = output_buffer->unaligned_height;
-    mdp_out_layer_.buffer.comp_ratio.denom = 1000;
-    mdp_out_layer_.buffer.comp_ratio.numer = UINT32(hw_layers->output_compression * 1000);
-    mdp_out_layer_.buffer.fence = -1;
-#ifdef OUT_LAYER_COLOR_SPACE
-    SetCSC(output_buffer->color_metadata, &mdp_out_layer_.color_space);
-#endif
-    SetFormat(output_buffer->format, &mdp_out_layer_.buffer.format);
-    mdp_commit.flags |= MDP_COMMIT_CWB_EN;
-    mdp_commit.flags |= (stack->flags.post_processed_output) ? MDP_COMMIT_CWB_DSPP : 0;
-    DLOGI_IF(kTagDriverConfig, "****************** Conc WB Output buffer Info ******************");
-    DLOGI_IF(kTagDriverConfig, "out_w %d, out_h %d, out_f %d, wb_id %d DSPP output %d",
-             mdp_out_layer_.buffer.width, mdp_out_layer_.buffer.height,
-             mdp_out_layer_.buffer.format, mdp_out_layer_.writeback_ndx,
-             stack->flags.post_processed_output);
-    DLOGI_IF(kTagDriverConfig, "****************************************************************");
-  }
-
-  if (hw_resource_.has_avr) {
-    SetAVRFlags(hw_layers->hw_avr_info, &mdp_commit.flags);
-  }
-
-  return HWDevice::Validate(hw_layers);
-}
-
-DisplayError HWPrimary::Commit(HWLayers *hw_layers) {
-  LayerBuffer *output_buffer = hw_layers->info.stack->output_buffer;
-
-  if (hw_resource_.has_concurrent_writeback && output_buffer) {
-    if (output_buffer->planes[0].fd >= 0) {
-      mdp_out_layer_.buffer.planes[0].fd = output_buffer->planes[0].fd;
-      mdp_out_layer_.buffer.planes[0].offset = output_buffer->planes[0].offset;
-      SetStride(device_type_, output_buffer->format, output_buffer->planes[0].stride,
-                &mdp_out_layer_.buffer.planes[0].stride);
-      mdp_out_layer_.buffer.plane_count = 1;
-      mdp_out_layer_.buffer.fence = -1;
-
-      DLOGI_IF(kTagDriverConfig, "****************** Conc WB Output buffer Info ****************");
-      DLOGI_IF(kTagDriverConfig, "out_fd %d, out_offset %d, out_stride %d",
-               mdp_out_layer_.buffer.planes[0].fd, mdp_out_layer_.buffer.planes[0].offset,
-               mdp_out_layer_.buffer.planes[0].stride);
-      DLOGI_IF(kTagDriverConfig, "**************************************************************");
-    } else {
-      DLOGE("Invalid output buffer fd");
-      return kErrorParameters;
-    }
-  }
-
-  DisplayError ret = HWDevice::Commit(hw_layers);
-
-  if (ret == kErrorNone && hw_resource_.has_concurrent_writeback && output_buffer) {
-    output_buffer->release_fence_fd = mdp_out_layer_.buffer.fence;
-  }
-
-  return ret;
-}
-
-void HWPrimary::SetIdleTimeoutMs(uint32_t timeout_ms) {
-  char node_path[kMaxStringLength] = {0};
-
-  DLOGI_IF(kTagDriverConfig, "Setting idle timeout to = %d ms", timeout_ms);
-
-  snprintf(node_path, sizeof(node_path), "%s%d/idle_time", fb_path_, fb_node_index_);
-
-  // Open a sysfs node to send the timeout value to driver.
-  int fd = Sys::open_(node_path, O_WRONLY);
-  if (fd < 0) {
-    DLOGE("Unable to open %s, node %s", node_path, strerror(errno));
-    return;
-  }
-
-  char timeout_string[64];
-  snprintf(timeout_string, sizeof(timeout_string), "%d", timeout_ms);
-
-  // Notify driver about the timeout value
-  ssize_t length = Sys::pwrite_(fd, timeout_string, strlen(timeout_string), 0);
-  if (length <= 0) {
-    DLOGE("Unable to write into %s, node %s", node_path, strerror(errno));
-  }
-
-  Sys::close_(fd);
-}
-
-DisplayError HWPrimary::SetVSyncState(bool enable) {
-  DTRACE_SCOPED();
-  return HWDevice::SetVSyncState(enable);
-}
-
-DisplayError HWPrimary::SetDisplayMode(const HWDisplayMode hw_display_mode) {
-  uint32_t mode = kModeDefault;
-
-  switch (hw_display_mode) {
-  case kModeVideo:
-    mode = kModeLPMVideo;
-    break;
-  case kModeCommand:
-    mode = kModeLPMCommand;
-    break;
-  default:
-    DLOGW("Failed to translate SDE display mode %d to a MSMFB_LPM_ENABLE mode",
-          hw_display_mode);
-    return kErrorParameters;
-  }
-
-  if (Sys::ioctl_(device_fd_, INT(MSMFB_LPM_ENABLE), &mode) < 0) {
-    IOCTL_LOGE(MSMFB_LPM_ENABLE, device_type_);
-    return kErrorHardware;
-  }
-
-  DLOGI("Triggering display mode change to %d on next commit.", hw_display_mode);
-  synchronous_commit_ = true;
-
-  return kErrorNone;
-}
-
-DisplayError HWPrimary::SetPanelBrightness(int level) {
-  char buffer[kMaxSysfsCommandLength] = {0};
-
-  DLOGV_IF(kTagDriverConfig, "Set brightness level to %d", level);
-  int fd = Sys::open_(kBrightnessNode, O_RDWR);
-  if (fd < 0) {
-    DLOGV_IF(kTagDriverConfig, "Failed to open node = %s, error = %s ", kBrightnessNode,
-             strerror(errno));
-    return kErrorFileDescriptor;
-  }
-
-  int32_t bytes = snprintf(buffer, kMaxSysfsCommandLength, "%d\n", level);
-  if (bytes < 0) {
-    DLOGV_IF(kTagDriverConfig, "Failed to copy new brightness level = %d", level);
-    Sys::close_(fd);
-    return kErrorUndefined;
-  }
-
-  ssize_t ret = Sys::pwrite_(fd, buffer, static_cast<size_t>(bytes), 0);
-  if (ret <= 0) {
-    DLOGV_IF(kTagDriverConfig, "Failed to write to node = %s, error = %s ", kBrightnessNode,
-             strerror(errno));
-    Sys::close_(fd);
-    return kErrorUndefined;
-  }
-  Sys::close_(fd);
-
-  return kErrorNone;
-}
-
-DisplayError HWPrimary::GetPanelBrightness(int *level) {
-  char brightness[kMaxStringLength] = {0};
-
-  if (!level) {
-    DLOGV_IF(kTagDriverConfig, "Invalid input, null pointer.");
-    return kErrorParameters;
-  }
-
-  int fd = Sys::open_(kBrightnessNode, O_RDWR);
-  if (fd < 0) {
-    DLOGV_IF(kTagDriverConfig, "Failed to open brightness node = %s, error = %s", kBrightnessNode,
-             strerror(errno));
-    return kErrorFileDescriptor;
-  }
-
-  if (Sys::pread_(fd, brightness, sizeof(brightness), 0) > 0) {
-    *level = atoi(brightness);
-    DLOGV_IF(kTagDriverConfig, "Brightness level = %d", *level);
-  }
-  Sys::close_(fd);
-
-  return kErrorNone;
-}
-
-DisplayError HWPrimary::SetAutoRefresh(bool enable) {
-  const int kWriteLength = 2;
-  char buffer[kWriteLength] = {'\0'};
-  ssize_t bytes = snprintf(buffer, kWriteLength, "%d", enable);
-
-  if (enable == auto_refresh_) {
-    return kErrorNone;
-  }
-
-  if (HWDevice::SysFsWrite(kAutoRefreshNode, buffer, bytes) <= 0) {  // Returns bytes written
-    return kErrorUndefined;
-  }
-
-  auto_refresh_ = enable;
-
-  return kErrorNone;
-}
-
-DisplayError HWPrimary::GetPPFeaturesVersion(PPFeatureVersion *vers) {
-  mdp_pp_feature_version version = {};
-
-#ifdef PA_DITHER
-  uint32_t feature_id_mapping[kMaxNumPPFeatures] = { PCC, IGC, GC, GC, PA,
-                                                     DITHER, GAMUT, PA_DITHER };
-#else
-  uint32_t feature_id_mapping[kMaxNumPPFeatures] = { PCC, IGC, GC, GC, PA, DITHER, GAMUT };
-#endif
-
-  for (int i(0); i < kMaxNumPPFeatures; i++) {
-    version.pp_feature = feature_id_mapping[i];
-
-    if (Sys::ioctl_(device_fd_,  INT(MSMFB_MDP_PP_GET_FEATURE_VERSION), &version) < 0) {
-      IOCTL_LOGE(MSMFB_MDP_PP_GET_FEATURE_VERSION, device_type_);
-      return kErrorHardware;
-    }
-    vers->version[i] = version.version_info;
-  }
-
-  return kErrorNone;
-}
-
-// It was entered with PPFeaturesConfig::locker_ being hold.
-DisplayError HWPrimary::SetPPFeatures(PPFeaturesConfig *feature_list) {
-  msmfb_mdp_pp kernel_params = {};
-  int ret = 0;
-  PPFeatureInfo *feature = NULL;
-
-  while (true) {
-    ret = feature_list->RetrieveNextFeature(&feature);
-    if (ret)
-        break;
-
-    if (feature) {
-      DLOGV_IF(kTagDriverConfig, "feature_id = %d", feature->feature_id_);
-
-      if ((feature->feature_id_ < kMaxNumPPFeatures)) {
-        HWColorManager::SetFeature[feature->feature_id_](*feature, &kernel_params);
-        if (Sys::ioctl_(device_fd_, INT(MSMFB_MDP_PP), &kernel_params) < 0) {
-          IOCTL_LOGE(MSMFB_MDP_PP, device_type_);
-
-          feature_list->Reset();
-          return kErrorHardware;
-        }
-      }
-    }
-  }  // while(true)
-
-  // Once all features were consumed, then destroy all feature instance from feature_list,
-  // Then mark it as non-dirty of PPFeaturesConfig cache.
-  feature_list->Reset();
-
-  return kErrorNone;
-}
-
-DisplayError HWPrimary::SetMixerAttributes(const HWMixerAttributes &mixer_attributes) {
-  if (IsResolutionSwitchEnabled()) {
-    return kErrorNotSupported;
-  }
-
-  return HWDevice::SetMixerAttributes(mixer_attributes);
-}
-
-void HWPrimary::UpdateMixerAttributes() {
-  mixer_attributes_.width = display_attributes_.x_pixels;
-  mixer_attributes_.height = display_attributes_.y_pixels;
-  mixer_attributes_.split_left = display_attributes_.is_device_split ?
-      hw_panel_info_.split_info.left_split : mixer_attributes_.width;
-}
-
-void HWPrimary::SetAVRFlags(const HWAVRInfo &hw_avr_info, uint32_t *avr_flags) {
-  if (hw_avr_info.enable) {
-    *avr_flags |= MDP_COMMIT_AVR_EN;
-  }
-
-  if (hw_avr_info.mode == kOneShotMode) {
-    *avr_flags |= MDP_COMMIT_AVR_ONE_SHOT_MODE;
-  }
-}
-
-}  // namespace sdm
-
diff --git a/sdm/libs/core/fb/hw_primary.h b/sdm/libs/core/fb/hw_primary.h
deleted file mode 100644
index b385109..0000000
--- a/sdm/libs/core/fb/hw_primary.h
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
-* Copyright (c) 2015-2016, 2018 The Linux Foundation. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without modification, are permitted
-* provided that the following conditions are met:
-*    * Redistributions of source code must retain the above copyright notice, this list of
-*      conditions and the following disclaimer.
-*    * Redistributions in binary form must reproduce the above copyright notice, this list of
-*      conditions and the following disclaimer in the documentation and/or other materials provided
-*      with the distribution.
-*    * Neither the name of The Linux Foundation nor the names of its contributors may be used to
-*      endorse or promote products derived from this software without specific prior written
-*      permission.
-*
-* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-* NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
-* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
-* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
-* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#ifndef __HW_PRIMARY_H__
-#define __HW_PRIMARY_H__
-
-#include <sys/poll.h>
-#include <vector>
-#include <string>
-
-#include "hw_device.h"
-
-namespace sdm {
-
-class HWPrimary : public HWDevice {
- public:
-  HWPrimary(BufferSyncHandler *buffer_sync_handler, HWInfoInterface *hw_info_intf);
-
- protected:
-  virtual DisplayError Init();
-  virtual DisplayError GetNumDisplayAttributes(uint32_t *count);
-  virtual DisplayError GetActiveConfig(uint32_t *active_config);
-  virtual DisplayError GetDisplayAttributes(uint32_t index,
-                                            HWDisplayAttributes *display_attributes);
-  virtual DisplayError SetDisplayAttributes(uint32_t index);
-  virtual DisplayError GetConfigIndex(char *mode, uint32_t *index);
-  virtual DisplayError PowerOff();
-  virtual DisplayError Doze(int *release_fence);
-  virtual DisplayError DozeSuspend(int *release_fence);
-  virtual DisplayError Validate(HWLayers *hw_layers);
-  virtual DisplayError Commit(HWLayers *hw_layers);
-  virtual void SetIdleTimeoutMs(uint32_t timeout_ms);
-  virtual DisplayError SetVSyncState(bool enable);
-  virtual DisplayError SetDisplayMode(const HWDisplayMode hw_display_mode);
-  virtual DisplayError SetRefreshRate(uint32_t refresh_rate);
-  virtual DisplayError SetPanelBrightness(int level);
-  virtual DisplayError GetPPFeaturesVersion(PPFeatureVersion *vers);
-  virtual DisplayError SetPPFeatures(PPFeaturesConfig *feature_list);
-  virtual DisplayError GetPanelBrightness(int *level);
-  virtual DisplayError SetAutoRefresh(bool enable);
-  virtual DisplayError SetMixerAttributes(const HWMixerAttributes &mixer_attributes);
-
- private:
-  // Panel modes for the MSMFB_LPM_ENABLE ioctl
-  enum {
-    kModeLPMVideo,
-    kModeLPMCommand,
-  };
-
-  enum {
-    kMaxSysfsCommandLength = 12,
-  };
-
-  DisplayError PopulateDisplayAttributes();
-  void InitializeConfigs();
-  bool IsResolutionSwitchEnabled() { return !display_configs_.empty(); }
-  bool GetCurrentModeFromSysfs(size_t *curr_x_pixels, size_t *curr_y_pixels);
-  void UpdateMixerAttributes();
-  void SetAVRFlags(const HWAVRInfo &hw_avr_info, uint32_t *avr_flags);
-
-  std::vector<DisplayConfigVariableInfo> display_configs_;
-  std::vector<std::string> display_config_strings_;
-  uint32_t active_config_index_ = 0;
-  const char *kBrightnessNode = "/sys/class/leds/lcd-backlight/brightness";
-  const char *kAutoRefreshNode = "/sys/devices/virtual/graphics/fb0/msm_cmd_autorefresh_en";
-  bool auto_refresh_ = false;
-  bool avr_prop_disabled_ = false;
-};
-
-}  // namespace sdm
-
-#endif  // __HW_PRIMARY_H__
-
diff --git a/sdm/libs/core/fb/hw_scale.cpp b/sdm/libs/core/fb/hw_scale.cpp
deleted file mode 100644
index 0258570..0000000
--- a/sdm/libs/core/fb/hw_scale.cpp
+++ /dev/null
@@ -1,314 +0,0 @@
-/*
-* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without modification, are permitted
-* provided that the following conditions are met:
-*    * Redistributions of source code must retain the above copyright notice, this list of
-*      conditions and the following disclaimer.
-*    * Redistributions in binary form must reproduce the above copyright notice, this list of
-*      conditions and the following disclaimer in the documentation and/or other materials provided
-*      with the distribution.
-*    * Neither the name of The Linux Foundation nor the names of its contributors may be used to
-*      endorse or promote products derived from this software without specific prior written
-*      permission.
-*
-* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-* NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
-* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
-* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
-* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#include <stdio.h>
-#include <utils/debug.h>
-#include "hw_scale.h"
-
-#define __CLASS__ "HWScale"
-
-namespace sdm {
-
-DisplayError HWScale::Create(HWScale **intf, bool has_qseed3) {
-  if (has_qseed3) {
-    *intf = new HWScaleV2();
-  } else {
-    *intf = new HWScaleV1();
-  }
-
-  return kErrorNone;
-}
-
-DisplayError HWScale::Destroy(HWScale *intf) {
-  delete intf;
-
-  return kErrorNone;
-}
-
-void HWScaleV1::SetHWScaleData(const HWScaleData &scale_data, uint32_t index,
-                               mdp_layer_commit_v1 *mdp_commit, HWSubBlockType sub_block_type) {
-  if (!scale_data.enable.scale) {
-    return;
-  }
-
-  if (sub_block_type == kHWDestinationScalar) {
-    return;
-  }
-
-  mdp_input_layer *mdp_layer = &mdp_commit->input_layers[index];
-  mdp_layer->flags |= MDP_LAYER_ENABLE_PIXEL_EXT;
-  mdp_scale_data *mdp_scale = &scale_data_v1_.at(index);
-  mdp_scale->enable_pxl_ext = scale_data.enable.scale;
-  for (int i = 0; i < MAX_PLANES; i++) {
-    const HWPlane &plane = scale_data.plane[i];
-    mdp_scale->init_phase_x[i] = plane.init_phase_x;
-    mdp_scale->phase_step_x[i] = plane.phase_step_x;
-    mdp_scale->init_phase_y[i] = plane.init_phase_y;
-    mdp_scale->phase_step_y[i] = plane.phase_step_y;
-
-    mdp_scale->num_ext_pxls_left[i] = plane.left.extension;
-    mdp_scale->left_ftch[i] = plane.left.overfetch;
-    mdp_scale->left_rpt[i] = plane.left.repeat;
-
-    mdp_scale->num_ext_pxls_top[i] = plane.top.extension;
-    mdp_scale->top_ftch[i] = plane.top.overfetch;
-    mdp_scale->top_rpt[i] = plane.top.repeat;
-
-    mdp_scale->num_ext_pxls_right[i] = plane.right.extension;
-    mdp_scale->right_ftch[i] = plane.right.overfetch;
-    mdp_scale->right_rpt[i] = plane.right.repeat;
-
-    mdp_scale->num_ext_pxls_btm[i] = plane.bottom.extension;
-    mdp_scale->btm_ftch[i] = plane.bottom.overfetch;
-    mdp_scale->btm_rpt[i] = plane.bottom.repeat;
-
-    mdp_scale->roi_w[i] = plane.roi_width;
-  }
-
-  return;
-}
-
-void* HWScaleV1::GetScaleDataRef(uint32_t index, HWSubBlockType sub_block_type) {
-  if (sub_block_type != kHWDestinationScalar) {
-    return &scale_data_v1_.at(index);
-  }
-
-  return NULL;
-}
-
-void HWScaleV1::DumpScaleData(void *mdp_scale) {
-  if (!mdp_scale) {
-    return;
-  }
-
-  mdp_scale_data *scale = reinterpret_cast<mdp_scale_data *>(mdp_scale);
-  if (scale->enable_pxl_ext) {
-    DLOGD_IF(kTagDriverConfig, "Scale Enable = %d", scale->enable_pxl_ext);
-    for (int j = 0; j < MAX_PLANES; j++) {
-      DLOGV_IF(kTagDriverConfig, "Scale Data[%d] : Phase=[%x %x %x %x] Pixel_Ext=[%d %d %d %d]",
-               j, scale->init_phase_x[j], scale->phase_step_x[j], scale->init_phase_y[j],
-               scale->phase_step_y[j], scale->num_ext_pxls_left[j], scale->num_ext_pxls_top[j],
-               scale->num_ext_pxls_right[j], scale->num_ext_pxls_btm[j]);
-      DLOGV_IF(kTagDriverConfig, "Fetch=[%d %d %d %d]  Repeat=[%d %d %d %d]  roi_width = %d",
-               scale->left_ftch[j], scale->top_ftch[j], scale->right_ftch[j], scale->btm_ftch[j],
-               scale->left_rpt[j], scale->top_rpt[j], scale->right_rpt[j], scale->btm_rpt[j],
-               scale->roi_w[j]);
-    }
-  }
-
-  return;
-}
-
-void HWScaleV2::SetHWScaleData(const HWScaleData &scale_data, uint32_t index,
-                               mdp_layer_commit_v1 *mdp_commit, HWSubBlockType sub_block_type) {
-  if (!scale_data.enable.scale && !scale_data.enable.direction_detection &&
-      !scale_data.enable.detail_enhance ) {
-    return;
-  }
-
-  mdp_scale_data_v2 *mdp_scale;
-  if (sub_block_type != kHWDestinationScalar) {
-    mdp_input_layer *mdp_layer = &mdp_commit->input_layers[index];
-    mdp_layer->flags |= MDP_LAYER_ENABLE_QSEED3_SCALE;
-    mdp_scale = &scale_data_v2_.at(index);
-  } else {
-    mdp_scale_data_v2 mdp_dest_scale = {0};
-
-    dest_scale_data_v2_.insert(std::make_pair(index, mdp_dest_scale));
-    mdp_scale = &dest_scale_data_v2_[index];
-  }
-
-  mdp_scale->enable = (scale_data.enable.scale ? ENABLE_SCALE : 0) |
-                      (scale_data.enable.direction_detection ? ENABLE_DIRECTION_DETECTION : 0) |
-                      (scale_data.enable.detail_enhance ? ENABLE_DETAIL_ENHANCE : 0);
-
-  if (sub_block_type == kHWDestinationScalar) {
-    mdp_destination_scaler_data *mdp_dest_scalar =
-      reinterpret_cast<mdp_destination_scaler_data *>(mdp_commit->dest_scaler);
-
-    mdp_dest_scalar[index].flags = mdp_scale->enable ? MDP_DESTSCALER_ENABLE : 0;
-
-    if (scale_data.enable.detail_enhance) {
-      mdp_dest_scalar[index].flags |= MDP_DESTSCALER_ENHANCER_UPDATE;
-    }
-  }
-
-  for (int i = 0; i < MAX_PLANES; i++) {
-    const HWPlane &plane = scale_data.plane[i];
-    mdp_scale->init_phase_x[i] = plane.init_phase_x;
-    mdp_scale->phase_step_x[i] = plane.phase_step_x;
-    mdp_scale->init_phase_y[i] = plane.init_phase_y;
-    mdp_scale->phase_step_y[i] = plane.phase_step_y;
-
-    mdp_scale->num_ext_pxls_left[i] = UINT32(plane.left.extension);
-    mdp_scale->left_ftch[i] = plane.left.overfetch;
-    mdp_scale->left_rpt[i] = plane.left.repeat;
-
-    mdp_scale->num_ext_pxls_top[i] = UINT32(plane.top.extension);
-    mdp_scale->top_ftch[i] = UINT32(plane.top.overfetch);
-    mdp_scale->top_rpt[i] = UINT32(plane.top.repeat);
-
-    mdp_scale->num_ext_pxls_right[i] = UINT32(plane.right.extension);
-    mdp_scale->right_ftch[i] = plane.right.overfetch;
-    mdp_scale->right_rpt[i] = plane.right.repeat;
-
-    mdp_scale->num_ext_pxls_btm[i] = UINT32(plane.bottom.extension);
-    mdp_scale->btm_ftch[i] = UINT32(plane.bottom.overfetch);
-    mdp_scale->btm_rpt[i] = UINT32(plane.bottom.repeat);
-
-    mdp_scale->roi_w[i] = plane.roi_width;
-
-    mdp_scale->preload_x[i] = UINT32(plane.preload_x);
-    mdp_scale->preload_y[i] = UINT32(plane.preload_y);
-
-    mdp_scale->src_width[i] = plane.src_width;
-    mdp_scale->src_height[i] = plane.src_height;
-  }
-
-  mdp_scale->dst_width = scale_data.dst_width;
-  mdp_scale->dst_height = scale_data.dst_height;
-
-  mdp_scale->y_rgb_filter_cfg = GetMDPScalingFilter(scale_data.y_rgb_filter_cfg);
-  mdp_scale->uv_filter_cfg = GetMDPScalingFilter(scale_data.uv_filter_cfg);
-  mdp_scale->alpha_filter_cfg = GetMDPAlphaInterpolation(scale_data.alpha_filter_cfg);
-  mdp_scale->blend_cfg = scale_data.blend_cfg;
-
-  mdp_scale->lut_flag = (scale_data.lut_flag.lut_swap ? SCALER_LUT_SWAP : 0) |
-                        (scale_data.lut_flag.lut_dir_wr ? SCALER_LUT_DIR_WR : 0) |
-                        (scale_data.lut_flag.lut_y_cir_wr ? SCALER_LUT_Y_CIR_WR : 0) |
-                        (scale_data.lut_flag.lut_uv_cir_wr ? SCALER_LUT_UV_CIR_WR : 0) |
-                        (scale_data.lut_flag.lut_y_sep_wr ? SCALER_LUT_Y_SEP_WR : 0) |
-                        (scale_data.lut_flag.lut_uv_sep_wr ? SCALER_LUT_UV_SEP_WR : 0);
-
-  mdp_scale->dir_lut_idx = scale_data.dir_lut_idx;
-  mdp_scale->y_rgb_cir_lut_idx = scale_data.y_rgb_cir_lut_idx;
-  mdp_scale->uv_cir_lut_idx = scale_data.uv_cir_lut_idx;
-  mdp_scale->y_rgb_sep_lut_idx = scale_data.y_rgb_sep_lut_idx;
-  mdp_scale->uv_sep_lut_idx = scale_data.uv_sep_lut_idx;
-
-  if (mdp_scale->enable & ENABLE_DETAIL_ENHANCE) {
-    mdp_det_enhance_data *mdp_det_enhance = &mdp_scale->detail_enhance;
-    mdp_det_enhance->enable = scale_data.detail_enhance.enable;
-    mdp_det_enhance->sharpen_level1 = scale_data.detail_enhance.sharpen_level1;
-    mdp_det_enhance->sharpen_level2 = scale_data.detail_enhance.sharpen_level2;
-    mdp_det_enhance->clip = scale_data.detail_enhance.clip;
-    mdp_det_enhance->limit = scale_data.detail_enhance.limit;
-    mdp_det_enhance->thr_quiet = scale_data.detail_enhance.thr_quiet;
-    mdp_det_enhance->thr_dieout = scale_data.detail_enhance.thr_dieout;
-    mdp_det_enhance->thr_low = scale_data.detail_enhance.thr_low;
-    mdp_det_enhance->thr_high = scale_data.detail_enhance.thr_high;
-    mdp_det_enhance->prec_shift = scale_data.detail_enhance.prec_shift;
-
-    for (int i = 0; i < MAX_DET_CURVES; i++) {
-      mdp_det_enhance->adjust_a[i] = scale_data.detail_enhance.adjust_a[i];
-      mdp_det_enhance->adjust_b[i] = scale_data.detail_enhance.adjust_b[i];
-      mdp_det_enhance->adjust_c[i] = scale_data.detail_enhance.adjust_c[i];
-    }
-  }
-
-  return;
-}
-
-void* HWScaleV2::GetScaleDataRef(uint32_t index, HWSubBlockType sub_block_type) {
-  if (sub_block_type != kHWDestinationScalar) {
-    return &scale_data_v2_.at(index);
-  } else {
-    return &dest_scale_data_v2_[index];
-  }
-}
-
-uint32_t HWScaleV2::GetMDPScalingFilter(ScalingFilterConfig filter_cfg) {
-  switch (filter_cfg) {
-  case kFilterEdgeDirected:
-    return FILTER_EDGE_DIRECTED_2D;
-  case kFilterCircular:
-    return FILTER_CIRCULAR_2D;
-  case kFilterSeparable:
-    return FILTER_SEPARABLE_1D;
-  case kFilterBilinear:
-    return FILTER_BILINEAR;
-  default:
-    DLOGE("Invalid Scaling Filter");
-    return kFilterMax;
-  }
-}
-
-uint32_t HWScaleV2::GetMDPAlphaInterpolation(HWAlphaInterpolation alpha_filter_cfg) {
-  switch (alpha_filter_cfg) {
-  case kInterpolationPixelRepeat:
-    return FILTER_ALPHA_DROP_REPEAT;
-  case kInterpolationBilinear:
-    return FILTER_ALPHA_BILINEAR;
-  default:
-    DLOGE("Invalid Alpha Interpolation");
-    return kInterpolationMax;
-  }
-}
-
-void HWScaleV2::DumpScaleData(void *mdp_scale) {
-  if (!mdp_scale) {
-    return;
-  }
-
-  mdp_scale_data_v2 *scale = reinterpret_cast<mdp_scale_data_v2 *>(mdp_scale);
-  if (scale->enable) {
-    DLOGD_IF(kTagDriverConfig, "Scale Enable = %d", scale->enable);
-    for (int j = 0; j < MAX_PLANES; j++) {
-      DLOGV_IF(kTagDriverConfig, "Scale Data[%d]: Phase_init[x y]=[%x %x] Phase_step:[x y]=[%x %x]",
-        j, scale->init_phase_x[j], scale->init_phase_y[j], scale->phase_step_x[j],
-        scale->phase_step_y[j]);
-      DLOGV_IF(kTagDriverConfig, "Preload[x y]=[%x %x], Pixel Ext=[%d %d] Ovfetch=[%d %d %d %d]",
-        scale->preload_x[j], scale->preload_y[j], scale->num_ext_pxls_left[j],
-        scale->num_ext_pxls_top[j], scale->left_ftch[j], scale->top_ftch[j], scale->right_ftch[j],
-        scale->btm_ftch[j]);
-      DLOGV_IF(kTagDriverConfig, "Repeat=[%d %d %d %d] Src[w x h]=[%d %d] roi_width = %d",
-        scale->left_rpt[j], scale->top_rpt[j], scale->right_rpt[j], scale->btm_rpt[j],
-        scale->src_width[j], scale->src_height[j], scale->roi_w[j]);
-    }
-
-    DLOGD_IF(kTagDriverConfig, "LUT flags = %d", scale->lut_flag);
-    DLOGV_IF(kTagDriverConfig, "y_rgb_filter=%d, uv_filter=%d, alpha_filter=%d, blend_cfg=%d",
-      scale->y_rgb_filter_cfg, scale->uv_filter_cfg, scale->alpha_filter_cfg, scale->blend_cfg);
-    DLOGV_IF(kTagDriverConfig, "dir_lut=%d, y_rgb_cir=%d, uv_cir=%d, y_rgb_sep=%d, uv_sep=%d",
-      scale->dir_lut_idx, scale->y_rgb_cir_lut_idx, scale->uv_cir_lut_idx,
-      scale->y_rgb_sep_lut_idx, scale->uv_sep_lut_idx);
-    if (scale->enable & ENABLE_DETAIL_ENHANCE) {
-      mdp_det_enhance_data *de = &scale->detail_enhance;
-      DLOGV_IF(kTagDriverConfig, "Detail Enhance: enable: %d sharpen_level1: %d sharpen_level2: %d",
-        de->enable, de->sharpen_level1, de->sharpen_level2);
-      DLOGV_IF(kTagDriverConfig, "clip: %d limit:%d thr_quiet: %d thr_dieout: %d",
-        de->clip, de->limit, de->thr_quiet, de->thr_dieout);
-      DLOGV_IF(kTagDriverConfig, "thr_low: %d thr_high: %d prec_shift: %d", de->thr_low,
-        de->thr_high, de->prec_shift);
-      for (uint32_t i = 0; i < MAX_DET_CURVES; i++) {
-        DLOGV_IF(kTagDriverConfig, "adjust_a[%d]: %d adjust_b[%d]: %d adjust_c[%d]: %d", i,
-          de->adjust_a[i], i, de->adjust_b[i], i, de->adjust_c[i]);
-      }
-    }
-  }
-
-  return;
-}
-
-}  // namespace sdm
diff --git a/sdm/libs/core/fb/hw_scale.h b/sdm/libs/core/fb/hw_scale.h
deleted file mode 100644
index 7590833..0000000
--- a/sdm/libs/core/fb/hw_scale.h
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
-* Copyright (c) 2016, The Linux Foundation. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without modification, are permitted
-* provided that the following conditions are met:
-*    * Redistributions of source code must retain the above copyright notice, this list of
-*      conditions and the following disclaimer.
-*    * Redistributions in binary form must reproduce the above copyright notice, this list of
-*      conditions and the following disclaimer in the documentation and/or other materials provided
-*      with the distribution.
-*    * Neither the name of The Linux Foundation nor the names of its contributors may be used to
-*      endorse or promote products derived from this software without specific prior written
-*      permission.
-*
-* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-* NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
-* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
-* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
-* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#ifndef __HW_SCALE_H__
-#define __HW_SCALE_H__
-
-#include <linux/msm_mdp_ext.h>
-#include <private/hw_info_types.h>
-
-#include <cstring>
-#include <array>
-#include <map>
-
-namespace sdm {
-
-class HWScale {
- public:
-  static DisplayError Create(HWScale **intf, bool has_qseed3);
-  static DisplayError Destroy(HWScale *intf);
-
-  virtual void SetHWScaleData(const HWScaleData &scale, uint32_t index,
-                              mdp_layer_commit_v1 *mdp_commit, HWSubBlockType sub_block_type) = 0;
-  virtual void* GetScaleDataRef(uint32_t index, HWSubBlockType sub_block_type) = 0;
-  virtual void DumpScaleData(void *mdp_scale) = 0;
-  virtual void ResetScaleParams() = 0;
- protected:
-  virtual ~HWScale() { }
-};
-
-class HWScaleV1 : public HWScale {
- public:
-  virtual void SetHWScaleData(const HWScaleData &scale, uint32_t index,
-                              mdp_layer_commit_v1 *mdp_commit, HWSubBlockType sub_block_type);
-  virtual void* GetScaleDataRef(uint32_t index, HWSubBlockType sub_block_type);
-  virtual void DumpScaleData(void *mdp_scale);
-  virtual void ResetScaleParams() { scale_data_v1_ = {}; }
-
- protected:
-  ~HWScaleV1() {}
-  std::array<mdp_scale_data, (kMaxSDELayers * 2)> scale_data_v1_ = {};
-};
-
-class HWScaleV2 : public HWScale {
- public:
-  virtual void SetHWScaleData(const HWScaleData &scale, uint32_t index,
-                              mdp_layer_commit_v1 *mdp_commit, HWSubBlockType sub_block_type);
-  virtual void* GetScaleDataRef(uint32_t index, HWSubBlockType sub_block_type);
-  virtual void DumpScaleData(void *mdp_scale);
-  virtual void ResetScaleParams() { scale_data_v2_ = {}; dest_scale_data_v2_ = {}; }
-
- protected:
-  ~HWScaleV2() {}
-  std::array<mdp_scale_data_v2, (kMaxSDELayers * 2)> scale_data_v2_ = {};
-  std::map<uint32_t, mdp_scale_data_v2> dest_scale_data_v2_ = {};
-
- private:
-  uint32_t GetMDPAlphaInterpolation(HWAlphaInterpolation alpha_filter_cfg);
-  uint32_t GetMDPScalingFilter(ScalingFilterConfig filter_cfg);
-};
-
-}  // namespace sdm
-
-#endif  // __HW_SCALE_H__
-
diff --git a/sdm/libs/core/fb/hw_virtual.cpp b/sdm/libs/core/fb/hw_virtual.cpp
deleted file mode 100644
index 21017a5..0000000
--- a/sdm/libs/core/fb/hw_virtual.cpp
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
-* Copyright (c) 2015 - 2016, The Linux Foundation. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without
-* modification, are permitted provided that the following conditions are
-* met:
-*     * Redistributions of source code must retain the above copyright
-*       notice, this list of conditions and the following disclaimer.
-*     * Redistributions in binary form must reproduce the above
-*       copyright notice, this list of conditions and the following
-*       disclaimer in the documentation and/or other materials provided
-*       with the distribution.
-*     * Neither the name of The Linux Foundation nor the names of its
-*       contributors may be used to endorse or promote products derived
-*       from this software without specific prior written permission.
-*
-* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
-* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
-* ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
-* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
-* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#include <utils/debug.h>
-#include "hw_virtual.h"
-
-#define __CLASS__ "HWVirtual"
-
-namespace sdm {
-
-HWVirtual::HWVirtual(BufferSyncHandler *buffer_sync_handler, HWInfoInterface *hw_info_intf)
-  : HWDevice(buffer_sync_handler) {
-  HWDevice::device_type_ = kDeviceVirtual;
-  HWDevice::device_name_ = "Virtual Display Device";
-  HWDevice::hw_info_intf_ = hw_info_intf;
-}
-
-DisplayError HWVirtual::Init() {
-  return HWDevice::Init();
-}
-
-DisplayError HWVirtual::Validate(HWLayers *hw_layers) {
-  HWDevice::ResetDisplayParams();
-  return HWDevice::Validate(hw_layers);
-}
-
-DisplayError HWVirtual::GetMixerAttributes(HWMixerAttributes *mixer_attributes) {
-  mixer_attributes->width = display_attributes_.x_pixels;
-  mixer_attributes->height = display_attributes_.y_pixels;
-  mixer_attributes_.split_left = display_attributes_.is_device_split ?
-      (display_attributes_.x_pixels / 2) : mixer_attributes_.width;
-
-  return kErrorNone;
-}
-
-DisplayError HWVirtual::SetDisplayAttributes(const HWDisplayAttributes &display_attributes) {
-  if (display_attributes.x_pixels == 0 || display_attributes.y_pixels == 0) {
-    return kErrorParameters;
-  }
-
-  display_attributes_ = display_attributes;
-
-  if (display_attributes_.x_pixels > hw_resource_.max_mixer_width) {
-    display_attributes_.is_device_split = true;
-  }
-
-  return kErrorNone;
-}
-
-DisplayError HWVirtual::GetDisplayAttributes(uint32_t index,
-                                             HWDisplayAttributes *display_attributes) {
-  display_attributes->fps = 60;
-  // TODO(user): Need to update WB fps
-
-  return kErrorNone;
-}
-
-
-}  // namespace sdm
-
diff --git a/sdm/libs/core/fb/hw_virtual.h b/sdm/libs/core/fb/hw_virtual.h
deleted file mode 100644
index 1c204cd..0000000
--- a/sdm/libs/core/fb/hw_virtual.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
-* Copyright (c) 2015 - 2016, The Linux Foundation. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without modification, are permitted
-* provided that the following conditions are met:
-*    * Redistributions of source code must retain the above copyright notice, this list of
-*      conditions and the following disclaimer.
-*    * Redistributions in binary form must reproduce the above copyright notice, this list of
-*      conditions and the following disclaimer in the documentation and/or other materials provided
-*      with the distribution.
-*    * Neither the name of The Linux Foundation nor the names of its contributors may be used to
-*      endorse or promote products derived from this software without specific prior written
-*      permission.
-*
-* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-* NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
-* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
-* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
-* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#ifndef __HW_VIRTUAL_H__
-#define __HW_VIRTUAL_H__
-
-#include "hw_device.h"
-
-namespace sdm {
-
-class HWVirtual : public HWDevice {
- public:
-  HWVirtual(BufferSyncHandler *buffer_sync_handler, HWInfoInterface *hw_info_intf);
-  virtual DisplayError SetVSyncState(bool enable) { return kErrorNotSupported; }
-  virtual DisplayError SetMixerAttributes(const HWMixerAttributes &mixer_attributes) {
-    return kErrorNotSupported;
-  }
-  virtual DisplayError GetMixerAttributes(HWMixerAttributes *mixer_attributes);
-  virtual DisplayError SetDisplayAttributes(const HWDisplayAttributes &display_attributes);
-  virtual DisplayError GetDisplayAttributes(uint32_t index,
-                                            HWDisplayAttributes *display_attributes);
-
- protected:
-  virtual DisplayError Init();
-  virtual DisplayError Validate(HWLayers *hw_layers);
-};
-
-}  // namespace sdm
-
-#endif  // __HW_VIRTUAL_H__
-
diff --git a/sdm/libs/core/hw_events_interface.cpp b/sdm/libs/core/hw_events_interface.cpp
deleted file mode 100644
index 84a7dab..0000000
--- a/sdm/libs/core/hw_events_interface.cpp
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
-* Copyright (c) 2017, The Linux Foundation. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without
-* modification, are permitted provided that the following conditions are
-* met:
-*     * Redistributions of source code must retain the above copyright
-*       notice, this list of conditions and the following disclaimer.
-*     * Redistributions in binary form must reproduce the above
-*       copyright notice, this list of conditions and the following
-*       disclaimer in the documentation and/or other materials provided
-*       with the distribution.
-*     * Neither the name of The Linux Foundation nor the names of its
-*       contributors may be used to endorse or promote products derived
-*       from this software without specific prior written permission.
-*
-* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
-* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
-* ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
-* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
-* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#include <utils/utils.h>
-#include <vector>
-
-#include "hw_events_interface.h"
-#include "fb/hw_events.h"
-#include "drm/hw_events_drm.h"
-
-#define __CLASS__ "HWEventsInterface"
-
-namespace sdm {
-
-DisplayError HWEventsInterface::Create(int display_type, HWEventHandler *event_handler,
-                                       const std::vector<HWEvent> &event_list,
-                                       const HWInterface *hw_intf, HWEventsInterface **intf) {
-  DisplayError error = kErrorNone;
-  HWEventsInterface *hw_events = nullptr;
-  if (GetDriverType() == DriverType::FB) {
-    hw_events = new HWEvents();
-  } else {
-    hw_events = new HWEventsDRM();
-  }
-
-  error = hw_events->Init(display_type, event_handler, event_list, hw_intf);
-  if (error != kErrorNone) {
-    delete hw_events;
-  } else {
-    *intf = hw_events;
-  }
-
-  return error;
-}
-
-DisplayError HWEventsInterface::Destroy(HWEventsInterface *intf) {
-  if (intf) {
-    intf->Deinit();
-    delete intf;
-  }
-
-  return kErrorNone;
-}
-
-}  // namespace sdm
diff --git a/sdm/libs/core/hw_events_interface.h b/sdm/libs/core/hw_events_interface.h
deleted file mode 100644
index 828dcda..0000000
--- a/sdm/libs/core/hw_events_interface.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
-* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without modification, are permitted
-* provided that the following conditions are met:
-*    * Redistributions of source code must retain the above copyright notice, this list of
-*      conditions and the following disclaimer.
-*    * Redistributions in binary form must reproduce the above copyright notice, this list of
-*      conditions and the following disclaimer in the documentation and/or other materials provided
-*      with the distribution.
-*    * Neither the name of The Linux Foundation nor the names of its contributors may be used to
-*      endorse or promote products derived from this software without specific prior written
-*      permission.
-*
-* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-* NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
-* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
-* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
-* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#ifndef __HW_EVENTS_INTERFACE_H__
-#define __HW_EVENTS_INTERFACE_H__
-
-#include <private/hw_info_types.h>
-#include <inttypes.h>
-#include <utility>
-#include <vector>
-
-namespace sdm {
-
-class HWEventHandler;
-class HWInterface;
-
-enum HWEvent {
-  VSYNC = 0,
-  EXIT,
-  IDLE_NOTIFY,
-  CEC_READ_MESSAGE,
-  SHOW_BLANK_EVENT,
-  THERMAL_LEVEL,
-  IDLE_POWER_COLLAPSE,
-  PINGPONG_TIMEOUT,
-  PANEL_DEAD,
-};
-
-class HWEventsInterface {
- public:
-  virtual DisplayError Init(int display_type, HWEventHandler *event_handler,
-                            const std::vector<HWEvent> &event_list,
-                            const HWInterface *hw_intf) = 0;
-  virtual DisplayError Deinit() = 0;
-  virtual DisplayError SetEventState(HWEvent event, bool enable, void *aux = nullptr) = 0;
-
-  static DisplayError Create(int display_type, HWEventHandler *event_handler,
-                             const std::vector<HWEvent> &event_list,
-                             const HWInterface *hw_intf, HWEventsInterface **intf);
-  static DisplayError Destroy(HWEventsInterface *intf);
-
- protected:
-  virtual ~HWEventsInterface() { }
-};
-
-}  // namespace sdm
-
-#endif  // __HW_EVENTS_INTERFACE_H__
-
diff --git a/sdm/libs/core/hw_info_interface.cpp b/sdm/libs/core/hw_info_interface.cpp
deleted file mode 100644
index 79bc79a..0000000
--- a/sdm/libs/core/hw_info_interface.cpp
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
-* Copyright (c) 2017, The Linux Foundation. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without
-* modification, are permitted provided that the following conditions are
-* met:
-*     * Redistributions of source code must retain the above copyright
-*       notice, this list of conditions and the following disclaimer.
-*     * Redistributions in binary form must reproduce the above
-*       copyright notice, this list of conditions and the following
-*       disclaimer in the documentation and/or other materials provided
-*       with the distribution.
-*     * Neither the name of The Linux Foundation nor the names of its
-*       contributors may be used to endorse or promote products derived
-*       from this software without specific prior written permission.
-*
-* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
-* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
-* ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
-* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
-* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#include <utils/utils.h>
-
-#include "hw_info_interface.h"
-#include "fb/hw_info.h"
-#include "drm/hw_info_drm.h"
-
-#define __CLASS__ "HWInfoInterface"
-
-namespace sdm {
-
-DisplayError HWInfoInterface::Create(HWInfoInterface **intf) {
-  if (GetDriverType() == DriverType::FB) {
-    *intf = new HWInfo();
-  } else {
-    *intf = new HWInfoDRM();
-  }
-
-  return kErrorNone;
-}
-
-DisplayError HWInfoInterface::Destroy(HWInfoInterface *intf) {
-  if (intf) {
-    delete intf;
-  }
-
-  return kErrorNone;
-}
-
-}  // namespace sdm
diff --git a/sdm/libs/core/hw_info_interface.h b/sdm/libs/core/hw_info_interface.h
deleted file mode 100644
index 401c8bf..0000000
--- a/sdm/libs/core/hw_info_interface.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
-* Copyright (c) 2014 - 2016, The Linux Foundation. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without modification, are permitted
-* provided that the following conditions are met:
-*    * Redistributions of source code must retain the above copyright notice, this list of
-*      conditions and the following disclaimer.
-*    * Redistributions in binary form must reproduce the above copyright notice, this list of
-*      conditions and the following disclaimer in the documentation and/or other materials provided
-*      with the distribution.
-*    * Neither the name of The Linux Foundation nor the names of its contributors may be used to
-*      endorse or promote products derived from this software without specific prior written
-*      permission.
-*
-* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-* NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
-* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
-* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
-* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#ifndef __HW_INFO_INTERFACE_H__
-#define __HW_INFO_INTERFACE_H__
-
-#include <inttypes.h>
-#include <core/core_interface.h>
-#include <private/hw_info_types.h>
-
-namespace sdm {
-
-class HWInfoInterface {
- public:
-  static DisplayError Create(HWInfoInterface **intf);
-  static DisplayError Destroy(HWInfoInterface *intf);
-  virtual DisplayError GetHWResourceInfo(HWResourceInfo *hw_resource) = 0;
-  virtual DisplayError GetFirstDisplayInterfaceType(HWDisplayInterfaceInfo *hw_disp_info) = 0;
-
- protected:
-  virtual ~HWInfoInterface() { }
-};
-
-}  // namespace sdm
-
-#endif  // __HW_INFO_INTERFACE_H__
-
diff --git a/sdm/libs/core/hw_interface.cpp b/sdm/libs/core/hw_interface.cpp
deleted file mode 100644
index 902dcbc..0000000
--- a/sdm/libs/core/hw_interface.cpp
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
-* Copyright (c) 2017, The Linux Foundation. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without
-* modification, are permitted provided that the following conditions are
-* met:
-*     * Redistributions of source code must retain the above copyright
-*       notice, this list of conditions and the following disclaimer.
-*     * Redistributions in binary form must reproduce the above
-*       copyright notice, this list of conditions and the following
-*       disclaimer in the documentation and/or other materials provided
-*       with the distribution.
-*     * Neither the name of The Linux Foundation nor the names of its
-*       contributors may be used to endorse or promote products derived
-*       from this software without specific prior written permission.
-*
-* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
-* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
-* ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
-* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
-* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#include <utils/debug.h>
-#include <utils/utils.h>
-
-#include "hw_interface.h"
-#include "fb/hw_device.h"
-#include "fb/hw_primary.h"
-#include "fb/hw_hdmi.h"
-#include "fb/hw_virtual.h"
-#include "drm/hw_peripheral_drm.h"
-#include "drm/hw_virtual_drm.h"
-#include "drm/hw_tv_drm.h"
-
-#define __CLASS__ "HWInterface"
-
-namespace sdm {
-
-DisplayError HWInterface::Create(DisplayType type, HWInfoInterface *hw_info_intf,
-                                 BufferSyncHandler *buffer_sync_handler,
-                                 BufferAllocator *buffer_allocator, HWInterface **intf) {
-  DisplayError error = kErrorNone;
-  HWInterface *hw = nullptr;
-  DriverType driver_type = GetDriverType();
-
-  switch (type) {
-    case kPrimary:
-      if (driver_type == DriverType::FB) {
-        hw = new HWPrimary(buffer_sync_handler, hw_info_intf);
-      } else {
-        hw = new HWPeripheralDRM(buffer_sync_handler, buffer_allocator, hw_info_intf);
-      }
-      break;
-    case kHDMI:
-      if (driver_type == DriverType::FB) {
-        hw = new HWHDMI(buffer_sync_handler, hw_info_intf);
-      } else {
-        hw = new HWTVDRM(buffer_sync_handler, buffer_allocator, hw_info_intf);
-      }
-      break;
-    case kVirtual:
-      if (driver_type == DriverType::FB) {
-        hw = new HWVirtual(buffer_sync_handler, hw_info_intf);
-      } else {
-        hw = new HWVirtualDRM(buffer_sync_handler, buffer_allocator, hw_info_intf);
-      }
-      break;
-    default:
-      DLOGE("Undefined display type");
-      return kErrorUndefined;
-  }
-
-  error = hw->Init();
-  if (error != kErrorNone) {
-    delete hw;
-    DLOGE("Init on HW Intf type %d failed", type);
-    return error;
-  }
-  *intf = hw;
-
-  return error;
-}
-
-DisplayError HWInterface::Destroy(HWInterface *intf) {
-  if (intf) {
-    intf->Deinit();
-    delete intf;
-  }
-
-  return kErrorNone;
-}
-
-}  // namespace sdm
diff --git a/sdm/libs/core/hw_interface.h b/sdm/libs/core/hw_interface.h
deleted file mode 100644
index cdb7cba..0000000
--- a/sdm/libs/core/hw_interface.h
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
-* Copyright (c) 2014 - 2018, The Linux Foundation. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without modification, are permitted
-* provided that the following conditions are met:
-*    * Redistributions of source code must retain the above copyright notice, this list of
-*      conditions and the following disclaimer.
-*    * Redistributions in binary form must reproduce the above copyright notice, this list of
-*      conditions and the following disclaimer in the documentation and/or other materials provided
-*      with the distribution.
-*    * Neither the name of The Linux Foundation nor the names of its contributors may be used to
-*      endorse or promote products derived from this software without specific prior written
-*      permission.
-*
-* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-* NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
-* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
-* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
-* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#ifndef __HW_INTERFACE_H__
-#define __HW_INTERFACE_H__
-
-#include <core/buffer_allocator.h>
-#include <core/buffer_sync_handler.h>
-#include <core/display_interface.h>
-#include <private/hw_info_types.h>
-#include <private/color_interface.h>
-#include <utils/constants.h>
-
-#include "hw_info_interface.h"
-
-namespace sdm {
-
-enum HWScanSupport {
-  kScanNotSupported,
-  kScanAlwaysOverscanned,
-  kScanAlwaysUnderscanned,
-  kScanBoth,
-};
-
-struct HWScanInfo {
-  HWScanSupport pt_scan_support;    // Scan support for preferred timing
-  HWScanSupport it_scan_support;    // Scan support for digital monitor or industry timings
-  HWScanSupport cea_scan_support;   // Scan support for CEA resolution timings
-
-  HWScanInfo() : pt_scan_support(kScanNotSupported), it_scan_support(kScanNotSupported),
-                 cea_scan_support(kScanNotSupported) { }
-};
-
-// HWEventHandler - Implemented in DisplayBase and HWInterface implementation
-class HWEventHandler {
- public:
-  virtual DisplayError VSync(int64_t timestamp) = 0;
-  virtual DisplayError Blank(bool blank) = 0;
-  virtual void IdleTimeout() = 0;
-  virtual void ThermalEvent(int64_t thermal_level) = 0;
-  virtual void CECMessage(char *message) = 0;
-  virtual void IdlePowerCollapse() = 0;
-  virtual void PingPongTimeout() = 0;
-  virtual void PanelDead() = 0;
-
- protected:
-  virtual ~HWEventHandler() { }
-};
-
-class HWInterface {
- public:
-  static DisplayError Create(DisplayType type, HWInfoInterface *hw_info_intf,
-                             BufferSyncHandler *buffer_sync_handler,
-                             BufferAllocator *buffer_allocator, HWInterface **intf);
-  static DisplayError Destroy(HWInterface *intf);
-
-  virtual DisplayError Init() = 0;
-  virtual DisplayError Deinit() = 0;
-  virtual DisplayError GetActiveConfig(uint32_t *active_config) = 0;
-  virtual DisplayError GetNumDisplayAttributes(uint32_t *count) = 0;
-  virtual DisplayError GetDisplayAttributes(uint32_t index,
-                                            HWDisplayAttributes *display_attributes) = 0;
-  virtual DisplayError GetHWPanelInfo(HWPanelInfo *panel_info) = 0;
-  virtual DisplayError SetDisplayAttributes(uint32_t index) = 0;
-  virtual DisplayError SetDisplayAttributes(const HWDisplayAttributes &display_attributes) = 0;
-  virtual DisplayError GetConfigIndex(char *mode, uint32_t *index) = 0;
-  virtual DisplayError PowerOn(int *release_fence) = 0;
-  virtual DisplayError PowerOff() = 0;
-  virtual DisplayError Doze(int *release_fence) = 0;
-  virtual DisplayError DozeSuspend(int *release_fence) = 0;
-  virtual DisplayError Standby() = 0;
-  virtual DisplayError Validate(HWLayers *hw_layers) = 0;
-  virtual DisplayError Commit(HWLayers *hw_layers) = 0;
-  virtual DisplayError Flush() = 0;
-  virtual DisplayError GetPPFeaturesVersion(PPFeatureVersion *vers) = 0;
-  virtual DisplayError SetPPFeatures(PPFeaturesConfig *feature_list) = 0;
-  virtual DisplayError SetVSyncState(bool enable) = 0;
-  virtual void SetIdleTimeoutMs(uint32_t timeout_ms) = 0;
-  virtual DisplayError SetDisplayMode(const HWDisplayMode hw_display_mode) = 0;
-  virtual DisplayError SetRefreshRate(uint32_t refresh_rate) = 0;
-  virtual DisplayError SetPanelBrightness(int level) = 0;
-  virtual DisplayError GetHWScanInfo(HWScanInfo *scan_info) = 0;
-  virtual DisplayError GetVideoFormat(uint32_t config_index, uint32_t *video_format) = 0;
-  virtual DisplayError GetMaxCEAFormat(uint32_t *max_cea_format) = 0;
-  virtual DisplayError SetCursorPosition(HWLayers *hw_layers, int x, int y) = 0;
-  virtual DisplayError OnMinHdcpEncryptionLevelChange(uint32_t min_enc_level) = 0;
-  virtual DisplayError GetPanelBrightness(int *level) = 0;
-  virtual DisplayError SetAutoRefresh(bool enable) = 0;
-  virtual DisplayError SetS3DMode(HWS3DMode s3d_mode) = 0;
-  virtual DisplayError SetScaleLutConfig(HWScaleLutInfo *lut_info) = 0;
-  virtual DisplayError SetMixerAttributes(const HWMixerAttributes &mixer_attributes) = 0;
-  virtual DisplayError GetMixerAttributes(HWMixerAttributes *mixer_attributes) = 0;
-  virtual DisplayError DumpDebugData() = 0;
-
- protected:
-  virtual ~HWInterface() { }
-};
-
-}  // namespace sdm
-
-#endif  // __HW_INTERFACE_H__
-
diff --git a/sdm/libs/core/resource_default.cpp b/sdm/libs/core/resource_default.cpp
deleted file mode 100644
index e8cce43..0000000
--- a/sdm/libs/core/resource_default.cpp
+++ /dev/null
@@ -1,945 +0,0 @@
-/*
-* Copyright (c) 2014 - 2016, The Linux Foundation. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without modification, are permitted
-* provided that the following conditions are met:
-*    * Redistributions of source code must retain the above copyright notice, this list of
-*      conditions and the following disclaimer.
-*    * Redistributions in binary form must reproduce the above copyright notice, this list of
-*      conditions and the following disclaimer in the documentation and/or other materials provided
-*      with the distribution.
-*    * Neither the name of The Linux Foundation nor the names of its contributors may be used to
-*      endorse or promote products derived from this software without specific prior written
-*      permission.
-*
-* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-* NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
-* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
-* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
-* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#include <math.h>
-#include <utils/constants.h>
-#include <utils/debug.h>
-#include <utils/rect.h>
-#include <utils/formats.h>
-#include <utils/sys.h>
-#include <dlfcn.h>
-#include <algorithm>
-
-#include "resource_default.h"
-
-#define __CLASS__ "ResourceDefault"
-
-namespace sdm {
-
-DisplayError ResourceDefault::CreateResourceDefault(const HWResourceInfo &hw_resource_info,
-                                                    ResourceInterface **resource_intf) {
-  DisplayError error = kErrorNone;
-
-  ResourceDefault *resource_default = new ResourceDefault(hw_resource_info);
-  if (!resource_default) {
-    return kErrorNone;
-  }
-
-  error = resource_default->Init();
-  if (error != kErrorNone) {
-    delete resource_default;
-  }
-
-  *resource_intf = resource_default;
-
-  return kErrorNone;
-}
-
-DisplayError ResourceDefault::DestroyResourceDefault(ResourceInterface *resource_intf) {
-  ResourceDefault *resource_default = static_cast<ResourceDefault *>(resource_intf);
-
-  resource_default->Deinit();
-  delete resource_default;
-
-  return kErrorNone;
-}
-
-ResourceDefault::ResourceDefault(const HWResourceInfo &hw_res_info)
-  : hw_res_info_(hw_res_info) {
-}
-
-DisplayError ResourceDefault::Init() {
-  DisplayError error = kErrorNone;
-
-  num_pipe_ = hw_res_info_.num_vig_pipe + hw_res_info_.num_rgb_pipe + hw_res_info_.num_dma_pipe;
-
-  if (!num_pipe_) {
-    DLOGE("Number of H/W pipes is Zero!");
-    return kErrorParameters;
-  }
-
-  src_pipes_.resize(num_pipe_);
-
-  // Priority order of pipes: VIG, RGB, DMA
-  uint32_t vig_index = 0;
-  uint32_t rgb_index = hw_res_info_.num_vig_pipe;
-  uint32_t dma_index = rgb_index + hw_res_info_.num_rgb_pipe;
-
-  for (uint32_t i = 0; i < num_pipe_; i++) {
-    const HWPipeCaps &pipe_caps = hw_res_info_.hw_pipes.at(i);
-    if (pipe_caps.type == kPipeTypeVIG) {
-      src_pipes_[vig_index].type = kPipeTypeVIG;
-      src_pipes_[vig_index].index = i;
-      src_pipes_[vig_index].mdss_pipe_id = pipe_caps.id;
-      vig_index++;
-    } else if (pipe_caps.type == kPipeTypeRGB) {
-      src_pipes_[rgb_index].type = kPipeTypeRGB;
-      src_pipes_[rgb_index].index = i;
-      src_pipes_[rgb_index].mdss_pipe_id = pipe_caps.id;
-      rgb_index++;
-    } else if (pipe_caps.type == kPipeTypeDMA) {
-      src_pipes_[dma_index].type = kPipeTypeDMA;
-      src_pipes_[dma_index].index = i;
-      src_pipes_[dma_index].mdss_pipe_id = pipe_caps.id;
-      dma_index++;
-    }
-  }
-
-  for (uint32_t i = 0; i < num_pipe_; i++) {
-    src_pipes_[i].priority = INT(i);
-  }
-
-  DLOGI("hw_rev=%x, DMA=%d RGB=%d VIG=%d", hw_res_info_.hw_revision, hw_res_info_.num_dma_pipe,
-    hw_res_info_.num_rgb_pipe, hw_res_info_.num_vig_pipe);
-
-  if (hw_res_info_.max_scale_down < 1 || hw_res_info_.max_scale_up < 1) {
-    DLOGE("Max scaling setting is invalid! max_scale_down = %d, max_scale_up = %d",
-          hw_res_info_.max_scale_down, hw_res_info_.max_scale_up);
-    hw_res_info_.max_scale_down = 1;
-    hw_res_info_.max_scale_up = 1;
-  }
-
-  // TODO(user): clean it up, query from driver for initial pipe status.
-#ifndef SDM_VIRTUAL_DRIVER
-  rgb_index = hw_res_info_.num_vig_pipe;
-  src_pipes_[rgb_index].owner = kPipeOwnerKernelMode;
-  src_pipes_[rgb_index + 1].owner = kPipeOwnerKernelMode;
-#endif
-
-  return error;
-}
-
-DisplayError ResourceDefault::Deinit() {
-  return kErrorNone;
-}
-
-DisplayError ResourceDefault::RegisterDisplay(DisplayType type,
-                                              const HWDisplayAttributes &display_attributes,
-                                              const HWPanelInfo &hw_panel_info,
-                                              const HWMixerAttributes &mixer_attributes,
-                                              Handle *display_ctx) {
-  DisplayError error = kErrorNone;
-
-  HWBlockType hw_block_id = kHWBlockMax;
-  switch (type) {
-  case kPrimary:
-    if (!hw_block_ctx_[kHWPrimary].is_in_use) {
-      hw_block_id = kHWPrimary;
-    }
-    break;
-
-  case kHDMI:
-    if (!hw_block_ctx_[kHWHDMI].is_in_use) {
-      hw_block_id = kHWHDMI;
-    }
-    break;
-
-  default:
-    DLOGW("RegisterDisplay, invalid type %d", type);
-    return kErrorParameters;
-  }
-
-  if (hw_block_id == kHWBlockMax) {
-    return kErrorResources;
-  }
-
-  DisplayResourceContext *display_resource_ctx = new DisplayResourceContext();
-  if (!display_resource_ctx) {
-    return kErrorMemory;
-  }
-
-  hw_block_ctx_[hw_block_id].is_in_use = true;
-
-  display_resource_ctx->display_attributes = display_attributes;
-  display_resource_ctx->hw_block_id = hw_block_id;
-  display_resource_ctx->mixer_attributes = mixer_attributes;
-
-  *display_ctx = display_resource_ctx;
-  return error;
-}
-
-DisplayError ResourceDefault::UnregisterDisplay(Handle display_ctx) {
-  DisplayResourceContext *display_resource_ctx =
-                          reinterpret_cast<DisplayResourceContext *>(display_ctx);
-  Purge(display_ctx);
-
-  hw_block_ctx_[display_resource_ctx->hw_block_id].is_in_use = false;
-
-  delete display_resource_ctx;
-
-  return kErrorNone;
-}
-
-DisplayError ResourceDefault::ReconfigureDisplay(Handle display_ctx,
-                                                 const HWDisplayAttributes &display_attributes,
-                                                 const HWPanelInfo &hw_panel_info,
-                                                 const HWMixerAttributes &mixer_attributes) {
-  SCOPE_LOCK(locker_);
-
-  DisplayResourceContext *display_resource_ctx =
-                          reinterpret_cast<DisplayResourceContext *>(display_ctx);
-
-  display_resource_ctx->display_attributes = display_attributes;
-  display_resource_ctx->mixer_attributes = mixer_attributes;
-
-  return kErrorNone;
-}
-
-DisplayError ResourceDefault::Start(Handle display_ctx) {
-  locker_.Lock();
-
-  return kErrorNone;
-}
-
-DisplayError ResourceDefault::Stop(Handle display_ctx, HWLayers *hw_layers) {
-  locker_.Unlock();
-
-  return kErrorNone;
-}
-
-DisplayError ResourceDefault::Prepare(Handle display_ctx, HWLayers *hw_layers) {
-  DisplayResourceContext *display_resource_ctx =
-                          reinterpret_cast<DisplayResourceContext *>(display_ctx);
-
-  DisplayError error = kErrorNone;
-  const struct HWLayersInfo &layer_info = hw_layers->info;
-  HWBlockType hw_block_id = display_resource_ctx->hw_block_id;
-
-  DLOGV_IF(kTagResources, "==== Resource reserving start: hw_block = %d ====", hw_block_id);
-
-  if (layer_info.hw_layers.size() > 1) {
-    DLOGV_IF(kTagResources, "More than one FB layers");
-    return kErrorResources;
-  }
-
-  const Layer &layer = layer_info.hw_layers.at(0);
-
-  if (layer.composition != kCompositionGPUTarget) {
-    DLOGV_IF(kTagResources, "Not an FB layer");
-    return kErrorParameters;
-  }
-
-  error = Config(display_resource_ctx, hw_layers);
-  if (error != kErrorNone) {
-    DLOGV_IF(kTagResources, "Resource config failed");
-    return error;
-  }
-
-  for (uint32_t i = 0; i < num_pipe_; i++) {
-    if (src_pipes_[i].hw_block_id == hw_block_id && src_pipes_[i].owner == kPipeOwnerUserMode) {
-      src_pipes_[i].ResetState();
-    }
-  }
-
-  uint32_t left_index = num_pipe_;
-  uint32_t right_index = num_pipe_;
-  bool need_scale = false;
-
-  struct HWLayerConfig &layer_config = hw_layers->config[0];
-
-  HWPipeInfo *left_pipe = &layer_config.left_pipe;
-  HWPipeInfo *right_pipe = &layer_config.right_pipe;
-
-  // left pipe is needed
-  if (left_pipe->valid) {
-    need_scale = IsScalingNeeded(left_pipe);
-    left_index = GetPipe(hw_block_id, need_scale);
-    if (left_index >= num_pipe_) {
-      DLOGV_IF(kTagResources, "Get left pipe failed: hw_block_id = %d, need_scale = %d",
-               hw_block_id, need_scale);
-      ResourceStateLog();
-      goto CleanupOnError;
-    }
-  }
-
-  error = SetDecimationFactor(left_pipe);
-  if (error != kErrorNone) {
-    goto CleanupOnError;
-  }
-
-  if (!right_pipe->valid) {
-    // assign single pipe
-    if (left_index < num_pipe_) {
-      left_pipe->pipe_id = src_pipes_[left_index].mdss_pipe_id;
-    }
-    DLOGV_IF(kTagResources, "1 pipe acquired for FB layer, left_pipe = %x", left_pipe->pipe_id);
-    return kErrorNone;
-  }
-
-  need_scale = IsScalingNeeded(right_pipe);
-
-  right_index = GetPipe(hw_block_id, need_scale);
-  if (right_index >= num_pipe_) {
-    DLOGV_IF(kTagResources, "Get right pipe failed: hw_block_id = %d, need_scale = %d", hw_block_id,
-             need_scale);
-    ResourceStateLog();
-    goto CleanupOnError;
-  }
-
-  if (src_pipes_[right_index].priority < src_pipes_[left_index].priority) {
-    // Swap pipe based on priority
-    std::swap(left_index, right_index);
-  }
-
-  // assign dual pipes
-  left_pipe->pipe_id = src_pipes_[left_index].mdss_pipe_id;
-  right_pipe->pipe_id = src_pipes_[right_index].mdss_pipe_id;
-
-  error = SetDecimationFactor(right_pipe);
-  if (error != kErrorNone) {
-    goto CleanupOnError;
-  }
-
-  DLOGV_IF(kTagResources, "2 pipes acquired for FB layer, left_pipe = %x, right_pipe = %x",
-           left_pipe->pipe_id,  right_pipe->pipe_id);
-
-  return kErrorNone;
-
-CleanupOnError:
-  DLOGV_IF(kTagResources, "Resource reserving failed! hw_block = %d", hw_block_id);
-
-  return kErrorResources;
-}
-
-DisplayError ResourceDefault::PostPrepare(Handle display_ctx, HWLayers *hw_layers) {
-  SCOPE_LOCK(locker_);
-
-  return kErrorNone;
-}
-
-DisplayError ResourceDefault::Commit(Handle display_ctx, HWLayers *hw_layers) {
-  SCOPE_LOCK(locker_);
-
-  return kErrorNone;
-}
-
-DisplayError ResourceDefault::PostCommit(Handle display_ctx, HWLayers *hw_layers) {
-  SCOPE_LOCK(locker_);
-  DisplayResourceContext *display_resource_ctx =
-                          reinterpret_cast<DisplayResourceContext *>(display_ctx);
-  HWBlockType hw_block_id = display_resource_ctx->hw_block_id;
-  uint64_t frame_count = display_resource_ctx->frame_count;
-
-  DLOGV_IF(kTagResources, "Resource for hw_block = %d, frame_count = %d", hw_block_id, frame_count);
-
-  // handoff pipes which are used by splash screen
-  if ((frame_count == 0) && (hw_block_id == kHWPrimary)) {
-    for (uint32_t i = 0; i < num_pipe_; i++) {
-      if (src_pipes_[i].hw_block_id == hw_block_id && src_pipes_[i].owner == kPipeOwnerKernelMode) {
-        src_pipes_[i].owner = kPipeOwnerUserMode;
-      }
-    }
-  }
-
-  if (hw_layers->info.sync_handle >= 0)
-    Sys::close_(hw_layers->info.sync_handle);
-
-  display_resource_ctx->frame_count++;
-
-  return kErrorNone;
-}
-
-void ResourceDefault::Purge(Handle display_ctx) {
-  SCOPE_LOCK(locker_);
-
-  DisplayResourceContext *display_resource_ctx =
-                          reinterpret_cast<DisplayResourceContext *>(display_ctx);
-  HWBlockType hw_block_id = display_resource_ctx->hw_block_id;
-
-  for (uint32_t i = 0; i < num_pipe_; i++) {
-    if (src_pipes_[i].hw_block_id == hw_block_id && src_pipes_[i].owner == kPipeOwnerUserMode) {
-      src_pipes_[i].ResetState();
-    }
-  }
-  DLOGV_IF(kTagResources, "display id = %d", display_resource_ctx->hw_block_id);
-}
-
-DisplayError ResourceDefault::SetMaxMixerStages(Handle display_ctx, uint32_t max_mixer_stages) {
-  SCOPE_LOCK(locker_);
-
-  return kErrorNone;
-}
-
-uint32_t ResourceDefault::SearchPipe(HWBlockType hw_block_id, SourcePipe *src_pipes,
-                                uint32_t num_pipe) {
-  uint32_t index = num_pipe_;
-  SourcePipe *src_pipe;
-
-  // search the pipe being used
-  for (uint32_t i = 0; i < num_pipe; i++) {
-    src_pipe = &src_pipes[i];
-    if (src_pipe->owner == kPipeOwnerUserMode && src_pipe->hw_block_id == kHWBlockMax) {
-      index = src_pipe->index;
-      src_pipe->hw_block_id = hw_block_id;
-      break;
-    }
-  }
-
-  return index;
-}
-
-uint32_t ResourceDefault::NextPipe(PipeType type, HWBlockType hw_block_id) {
-  uint32_t num_pipe = 0;
-  SourcePipe *src_pipes = NULL;
-
-  switch (type) {
-  case kPipeTypeVIG:
-    src_pipes = &src_pipes_[0];
-    num_pipe = hw_res_info_.num_vig_pipe;
-    break;
-  case kPipeTypeRGB:
-    src_pipes = &src_pipes_[hw_res_info_.num_vig_pipe];
-    num_pipe = hw_res_info_.num_rgb_pipe;
-    break;
-  case kPipeTypeDMA:
-  default:
-    src_pipes = &src_pipes_[hw_res_info_.num_vig_pipe + hw_res_info_.num_rgb_pipe];
-    num_pipe = hw_res_info_.num_dma_pipe;
-    break;
-  }
-
-  return SearchPipe(hw_block_id, src_pipes, num_pipe);
-}
-
-uint32_t ResourceDefault::GetPipe(HWBlockType hw_block_id, bool need_scale) {
-  uint32_t index = num_pipe_;
-
-  // The default behavior is to assume RGB and VG pipes have scalars
-  if (!need_scale) {
-    index = NextPipe(kPipeTypeDMA, hw_block_id);
-  }
-
-  if ((index >= num_pipe_) && (!need_scale || !hw_res_info_.has_non_scalar_rgb)) {
-    index = NextPipe(kPipeTypeRGB, hw_block_id);
-  }
-
-  if (index >= num_pipe_) {
-    index = NextPipe(kPipeTypeVIG, hw_block_id);
-  }
-
-  return index;
-}
-
-bool ResourceDefault::IsScalingNeeded(const HWPipeInfo *pipe_info) {
-  const LayerRect &src_roi = pipe_info->src_roi;
-  const LayerRect &dst_roi = pipe_info->dst_roi;
-
-  return ((dst_roi.right - dst_roi.left) != (src_roi.right - src_roi.left)) ||
-          ((dst_roi.bottom - dst_roi.top) != (src_roi.bottom - src_roi.top));
-}
-
-void ResourceDefault::ResourceStateLog() {
-  DLOGV_IF(kTagResources, "==== resource manager pipe state ====");
-  uint32_t i;
-  for (i = 0; i < num_pipe_; i++) {
-    SourcePipe *src_pipe = &src_pipes_[i];
-    DLOGV_IF(kTagResources, "index = %d, id = %x, hw_block = %d, owner = %s",
-                 src_pipe->index, src_pipe->mdss_pipe_id, src_pipe->hw_block_id,
-                 (src_pipe->owner == kPipeOwnerUserMode) ? "user mode" : "kernel mode");
-  }
-}
-
-DisplayError ResourceDefault::SrcSplitConfig(DisplayResourceContext *display_resource_ctx,
-                                        const LayerRect &src_rect, const LayerRect &dst_rect,
-                                        HWLayerConfig *layer_config) {
-  HWPipeInfo *left_pipe = &layer_config->left_pipe;
-  HWPipeInfo *right_pipe = &layer_config->right_pipe;
-  float src_width = src_rect.right - src_rect.left;
-  float dst_width = dst_rect.right - dst_rect.left;
-
-  // Layer cannot qualify for SrcSplit if source or destination width exceeds max pipe width.
-  if ((src_width > hw_res_info_.max_pipe_width) || (dst_width > hw_res_info_.max_pipe_width)) {
-    SplitRect(src_rect, dst_rect, &left_pipe->src_roi, &left_pipe->dst_roi, &right_pipe->src_roi,
-              &right_pipe->dst_roi);
-    left_pipe->valid = true;
-    right_pipe->valid = true;
-  } else {
-    left_pipe->src_roi = src_rect;
-    left_pipe->dst_roi = dst_rect;
-    left_pipe->valid = true;
-    *right_pipe = {};
-  }
-
-  return kErrorNone;
-}
-
-DisplayError ResourceDefault::DisplaySplitConfig(DisplayResourceContext *display_resource_ctx,
-                                            const LayerRect &src_rect, const LayerRect &dst_rect,
-                                            HWLayerConfig *layer_config) {
-  HWMixerAttributes &mixer_attributes = display_resource_ctx->mixer_attributes;
-
-  // for display split case
-  HWPipeInfo *left_pipe = &layer_config->left_pipe;
-  HWPipeInfo *right_pipe = &layer_config->right_pipe;
-  LayerRect scissor_left, scissor_right, dst_left, crop_left, crop_right, dst_right;
-
-  scissor_left.right = FLOAT(mixer_attributes.split_left);
-  scissor_left.bottom = FLOAT(mixer_attributes.height);
-
-  scissor_right.left = FLOAT(mixer_attributes.split_left);
-  scissor_right.top = 0.0f;
-  scissor_right.right = FLOAT(mixer_attributes.width);
-  scissor_right.bottom = FLOAT(mixer_attributes.height);
-
-  crop_left = src_rect;
-  dst_left = dst_rect;
-  crop_right = crop_left;
-  dst_right = dst_left;
-
-  bool crop_left_valid = CalculateCropRects(scissor_left, &crop_left, &dst_left);
-  bool crop_right_valid = false;
-
-  if (IsValid(scissor_right)) {
-    crop_right_valid = CalculateCropRects(scissor_right, &crop_right, &dst_right);
-  }
-
-  // Reset left_pipe and right_pipe to invalid by default
-  *left_pipe = {};
-  *right_pipe = {};
-
-  if (crop_left_valid) {
-    // assign left pipe
-    left_pipe->src_roi = crop_left;
-    left_pipe->dst_roi = dst_left;
-    left_pipe->valid = true;
-  }
-
-  // assign right pipe if needed
-  if (crop_right_valid) {
-    right_pipe->src_roi = crop_right;
-    right_pipe->dst_roi = dst_right;
-    right_pipe->valid = true;
-  }
-
-  return kErrorNone;
-}
-
-DisplayError ResourceDefault::Config(DisplayResourceContext *display_resource_ctx,
-                                HWLayers *hw_layers) {
-  HWLayersInfo &layer_info = hw_layers->info;
-  DisplayError error = kErrorNone;
-  const Layer &layer = layer_info.hw_layers.at(0);
-
-  error = ValidateLayerParams(&layer);
-  if (error != kErrorNone) {
-    return error;
-  }
-
-  struct HWLayerConfig *layer_config = &hw_layers->config[0];
-  HWPipeInfo &left_pipe = layer_config->left_pipe;
-  HWPipeInfo &right_pipe = layer_config->right_pipe;
-
-  LayerRect src_rect = layer.src_rect;
-  LayerRect dst_rect = layer.dst_rect;
-
-  error = ValidateDimensions(src_rect, dst_rect);
-  if (error != kErrorNone) {
-    return error;
-  }
-
-  BufferLayout layout = GetBufferLayout(layer.input_buffer.format);
-  error = ValidateScaling(src_rect, dst_rect, false /*rotated90 */, layout,
-                          false /* use_rotator_downscale */);
-  if (error != kErrorNone) {
-    return error;
-  }
-
-  if (hw_res_info_.is_src_split) {
-    error = SrcSplitConfig(display_resource_ctx, src_rect, dst_rect, layer_config);
-  } else {
-    error = DisplaySplitConfig(display_resource_ctx, src_rect, dst_rect, layer_config);
-  }
-
-  if (error != kErrorNone) {
-    return error;
-  }
-
-  error = AlignPipeConfig(&layer, &left_pipe, &right_pipe);
-  if (error != kErrorNone) {
-    return error;
-  }
-
-  // set z_order, left_pipe should always be valid
-  left_pipe.z_order = 0;
-
-  DLOGV_IF(kTagResources, "==== FB layer Config ====");
-  Log(kTagResources, "input layer src_rect", layer.src_rect);
-  Log(kTagResources, "input layer dst_rect", layer.dst_rect);
-  Log(kTagResources, "cropped src_rect", src_rect);
-  Log(kTagResources, "cropped dst_rect", dst_rect);
-  Log(kTagResources, "left pipe src", layer_config->left_pipe.src_roi);
-  Log(kTagResources, "left pipe dst", layer_config->left_pipe.dst_roi);
-  if (right_pipe.valid) {
-    right_pipe.z_order = 0;
-    Log(kTagResources, "right pipe src", layer_config->right_pipe.src_roi);
-    Log(kTagResources, "right pipe dst", layer_config->right_pipe.dst_roi);
-  }
-
-  return error;
-}
-
-bool ResourceDefault::CalculateCropRects(const LayerRect &scissor, LayerRect *crop,
-                                         LayerRect *dst) {
-  float &crop_left = crop->left;
-  float &crop_top = crop->top;
-  float &crop_right = crop->right;
-  float &crop_bottom = crop->bottom;
-  float crop_width = crop->right - crop->left;
-  float crop_height = crop->bottom - crop->top;
-
-  float &dst_left = dst->left;
-  float &dst_top = dst->top;
-  float &dst_right = dst->right;
-  float &dst_bottom = dst->bottom;
-  float dst_width = dst->right - dst->left;
-  float dst_height = dst->bottom - dst->top;
-
-  const float &sci_left = scissor.left;
-  const float &sci_top = scissor.top;
-  const float &sci_right = scissor.right;
-  const float &sci_bottom = scissor.bottom;
-
-  float left_cut_ratio = 0.0, right_cut_ratio = 0.0, top_cut_ratio = 0.0, bottom_cut_ratio = 0.0;
-  bool need_cut = false;
-
-  if (dst_left < sci_left) {
-    left_cut_ratio = (sci_left - dst_left) / dst_width;
-    dst_left = sci_left;
-    need_cut = true;
-  }
-
-  if (dst_right > sci_right) {
-    right_cut_ratio = (dst_right - sci_right) / dst_width;
-    dst_right = sci_right;
-    need_cut = true;
-  }
-
-  if (dst_top < sci_top) {
-    top_cut_ratio = (sci_top - dst_top) / (dst_height);
-    dst_top = sci_top;
-    need_cut = true;
-  }
-
-  if (dst_bottom > sci_bottom) {
-    bottom_cut_ratio = (dst_bottom - sci_bottom) / (dst_height);
-    dst_bottom = sci_bottom;
-    need_cut = true;
-  }
-
-  if (!need_cut)
-    return true;
-
-  crop_left += crop_width * left_cut_ratio;
-  crop_top += crop_height * top_cut_ratio;
-  crop_right -= crop_width * right_cut_ratio;
-  crop_bottom -= crop_height * bottom_cut_ratio;
-  Normalize(1, 1, crop);
-  Normalize(1, 1, dst);
-  if (IsValid(*crop) && IsValid(*dst))
-    return true;
-  else
-    return false;
-}
-
-DisplayError ResourceDefault::ValidateLayerParams(const Layer *layer) {
-  const LayerRect &src = layer->src_rect;
-  const LayerRect &dst = layer->dst_rect;
-  const LayerBuffer &input_buffer = layer->input_buffer;
-
-  if (input_buffer.format == kFormatInvalid) {
-    DLOGV_IF(kTagResources, "Invalid input buffer format %d", input_buffer.format);
-    return kErrorNotSupported;
-  }
-
-  if (!IsValid(src) || !IsValid(dst)) {
-    Log(kTagResources, "input layer src_rect", src);
-    Log(kTagResources, "input layer dst_rect", dst);
-    return kErrorNotSupported;
-  }
-
-  // Make sure source in integral only if it is a non secure layer.
-  if (!input_buffer.flags.secure &&
-      ((src.left - roundf(src.left) != 0.0f) ||
-       (src.top - roundf(src.top) != 0.0f) ||
-       (src.right - roundf(src.right) != 0.0f) ||
-       (src.bottom - roundf(src.bottom) != 0.0f))) {
-    DLOGV_IF(kTagResources, "Input ROI is not integral");
-    return kErrorNotSupported;
-  }
-
-  return kErrorNone;
-}
-
-DisplayError ResourceDefault::ValidateDimensions(const LayerRect &crop, const LayerRect &dst) {
-  if (!IsValid(crop)) {
-    Log(kTagResources, "Invalid crop rect", crop);
-    return kErrorNotSupported;
-  }
-
-  if (!IsValid(dst)) {
-    Log(kTagResources, "Invalid dst rect", dst);
-    return kErrorNotSupported;
-  }
-
-  float crop_width = crop.right - crop.left;
-  float crop_height = crop.bottom - crop.top;
-  float dst_width = dst.right - dst.left;
-  float dst_height = dst.bottom - dst.top;
-
-  if ((UINT32(crop_width - dst_width) == 1) || (UINT32(crop_height - dst_height) == 1)) {
-    DLOGV_IF(kTagResources, "One pixel downscaling detected crop_w = %.0f, dst_w = %.0f, " \
-             "crop_h = %.0f, dst_h = %.0f", crop_width, dst_width, crop_height, dst_height);
-    return kErrorNotSupported;
-  }
-
-  return kErrorNone;
-}
-
-DisplayError ResourceDefault::ValidatePipeParams(HWPipeInfo *pipe_info, LayerBufferFormat format) {
-  DisplayError error = kErrorNone;
-
-  const LayerRect &src_rect = pipe_info->src_roi;
-  const LayerRect &dst_rect = pipe_info->dst_roi;
-
-  error = ValidateDimensions(src_rect, dst_rect);
-  if (error != kErrorNone) {
-    return error;
-  }
-
-  BufferLayout layout = GetBufferLayout(format);
-  error = ValidateScaling(src_rect, dst_rect, false /* rotated90 */, layout,
-                          false /* use_rotator_downscale */);
-  if (error != kErrorNone) {
-    return error;
-  }
-
-  return kErrorNone;
-}
-
-DisplayError ResourceDefault::ValidateScaling(const LayerRect &crop, const LayerRect &dst,
-                                              bool rotate90, BufferLayout layout,
-                                              bool use_rotator_downscale) {
-  DisplayError error = kErrorNone;
-
-  float scale_x = 1.0f;
-  float scale_y = 1.0f;
-
-  error = GetScaleFactor(crop, dst, &scale_x, &scale_y);
-  if (error != kErrorNone) {
-    return error;
-  }
-
-  error = ValidateDownScaling(scale_x, scale_y, (layout != kLinear));
-  if (error != kErrorNone) {
-    return error;
-  }
-
-  error = ValidateUpScaling(scale_x, scale_y);
-  if (error != kErrorNone) {
-    return error;
-  }
-
-  return kErrorNone;
-}
-
-DisplayError ResourceDefault::ValidateDownScaling(float scale_x, float scale_y, bool ubwc_tiled) {
-  if ((UINT32(scale_x) > 1) || (UINT32(scale_y) > 1)) {
-    float max_scale_down = FLOAT(hw_res_info_.max_scale_down);
-
-    // MDP H/W cannot apply decimation on UBWC tiled framebuffer
-    if (!ubwc_tiled && hw_res_info_.has_decimation) {
-      max_scale_down *= FLOAT(kMaxDecimationDownScaleRatio);
-    }
-
-    if (scale_x > max_scale_down || scale_y > max_scale_down) {
-      DLOGV_IF(kTagResources,
-               "Scaling down is over the limit: scale_x = %.0f, scale_y = %.0f, " \
-               "has_deci = %d", scale_x, scale_y, hw_res_info_.has_decimation);
-      return kErrorNotSupported;
-    }
-  }
-
-  DLOGV_IF(kTagResources, "scale_x = %.4f, scale_y = %.4f", scale_x, scale_y);
-
-  return kErrorNone;
-}
-
-DisplayError ResourceDefault::ValidateUpScaling(float scale_x, float scale_y) {
-  float max_scale_up = FLOAT(hw_res_info_.max_scale_up);
-
-  if (UINT32(scale_x) < 1 && scale_x > 0.0f) {
-    if ((1.0f / scale_x) > max_scale_up) {
-      DLOGV_IF(kTagResources, "Scaling up is over limit scale_x = %f", 1.0f / scale_x);
-      return kErrorNotSupported;
-    }
-  }
-
-  if (UINT32(scale_y) < 1 && scale_y > 0.0f) {
-    if ((1.0f / scale_y) > max_scale_up) {
-      DLOGV_IF(kTagResources, "Scaling up is over limit scale_y = %f", 1.0f / scale_y);
-      return kErrorNotSupported;
-    }
-  }
-
-  DLOGV_IF(kTagResources, "scale_x = %.4f, scale_y = %.4f", scale_x, scale_y);
-
-  return kErrorNone;
-}
-
-DisplayError ResourceDefault::GetScaleFactor(const LayerRect &crop, const LayerRect &dst,
-                                        float *scale_x, float *scale_y) {
-  float crop_width = crop.right - crop.left;
-  float crop_height = crop.bottom - crop.top;
-  float dst_width = dst.right - dst.left;
-  float dst_height = dst.bottom - dst.top;
-
-  *scale_x = crop_width / dst_width;
-  *scale_y = crop_height / dst_height;
-
-  return kErrorNone;
-}
-
-DisplayError ResourceDefault::SetDecimationFactor(HWPipeInfo *pipe) {
-  float src_h = pipe->src_roi.bottom - pipe->src_roi.top;
-  float dst_h = pipe->dst_roi.bottom - pipe->dst_roi.top;
-  float down_scale_h = src_h / dst_h;
-
-  float src_w = pipe->src_roi.right - pipe->src_roi.left;
-  float dst_w = pipe->dst_roi.right - pipe->dst_roi.left;
-  float down_scale_w = src_w / dst_w;
-
-  pipe->horizontal_decimation = 0;
-  pipe->vertical_decimation = 0;
-
-  if (CalculateDecimation(down_scale_w, &pipe->horizontal_decimation) != kErrorNone) {
-    return kErrorNotSupported;
-  }
-
-  if (CalculateDecimation(down_scale_h, &pipe->vertical_decimation) != kErrorNone) {
-    return kErrorNotSupported;
-  }
-
-  DLOGI_IF(kTagResources, "horizontal_decimation %d, vertical_decimation %d",
-           pipe->horizontal_decimation, pipe->vertical_decimation);
-
-  return kErrorNone;
-}
-
-void ResourceDefault::SplitRect(const LayerRect &src_rect, const LayerRect &dst_rect,
-                           LayerRect *src_left, LayerRect *dst_left, LayerRect *src_right,
-                           LayerRect *dst_right) {
-  // Split rectangle horizontally and evenly into two.
-  float src_width = src_rect.right - src_rect.left;
-  float dst_width = dst_rect.right - dst_rect.left;
-  float src_width_ori = src_width;
-  src_width = ROUND_UP_ALIGN_DOWN(src_width / 2, 1);
-  dst_width = ROUND_UP_ALIGN_DOWN(dst_width * src_width / src_width_ori, 1);
-
-  src_left->left = src_rect.left;
-  src_left->right = src_rect.left + src_width;
-  src_right->left = src_left->right;
-  src_right->right = src_rect.right;
-
-  src_left->top = src_rect.top;
-  src_left->bottom = src_rect.bottom;
-  src_right->top = src_rect.top;
-  src_right->bottom = src_rect.bottom;
-
-  dst_left->top = dst_rect.top;
-  dst_left->bottom = dst_rect.bottom;
-  dst_right->top = dst_rect.top;
-  dst_right->bottom = dst_rect.bottom;
-
-  dst_left->left = dst_rect.left;
-  dst_left->right = dst_rect.left + dst_width;
-  dst_right->left = dst_left->right;
-  dst_right->right = dst_rect.right;
-}
-
-DisplayError ResourceDefault::AlignPipeConfig(const Layer *layer, HWPipeInfo *left_pipe,
-                                              HWPipeInfo *right_pipe) {
-  DisplayError error = kErrorNone;
-  if (!left_pipe->valid) {
-    DLOGE_IF(kTagResources, "left_pipe should not be invalid");
-    return kErrorNotSupported;
-  }
-
-  error = ValidatePipeParams(left_pipe, layer->input_buffer.format);
-  if (error != kErrorNone) {
-    goto PipeConfigExit;
-  }
-
-  if (right_pipe->valid) {
-    // Make sure the  left and right ROI are conjunct
-    right_pipe->src_roi.left = left_pipe->src_roi.right;
-    right_pipe->dst_roi.left = left_pipe->dst_roi.right;
-    error = ValidatePipeParams(right_pipe, layer->input_buffer.format);
-  }
-
-PipeConfigExit:
-  if (error != kErrorNone) {
-    DLOGV_IF(kTagResources, "AlignPipeConfig failed");
-  }
-  return error;
-}
-
-DisplayError ResourceDefault::CalculateDecimation(float downscale, uint8_t *decimation) {
-  float max_down_scale = FLOAT(hw_res_info_.max_scale_down);
-
-  if (downscale <= max_down_scale) {
-    *decimation = 0;
-    return kErrorNone;
-  } else if (!hw_res_info_.has_decimation) {
-    DLOGE("Downscaling exceeds the maximum MDP downscale limit but decimation not enabled");
-    return kErrorNotSupported;
-  }
-
-  // Decimation is the remaining downscale factor after doing max SDE downscale.
-  // In SDE, decimation is supported in powers of 2.
-  // For ex: If a pipe needs downscale of 8 but max_down_scale is 4
-  // So decimation = powf(2.0, ceilf(log2f(8 / 4))) = powf(2.0, 1.0) = 2
-  *decimation = UINT8(ceilf(log2f(downscale / max_down_scale)));
-  return kErrorNone;
-}
-
-DisplayError ResourceDefault::ValidateAndSetCursorPosition(Handle display_ctx, HWLayers *hw_layers,
-                                                           int x, int y,
-                                                           DisplayConfigVariableInfo *fb_config) {
-  return kErrorNotSupported;
-}
-
-DisplayError ResourceDefault::SetMaxBandwidthMode(HWBwModes mode) {
-  return kErrorNotSupported;
-}
-
-DisplayError ResourceDefault::GetScaleLutConfig(HWScaleLutInfo *lut_info) {
-  return kErrorNone;
-}
-
-DisplayError ResourceDefault::SetDetailEnhancerData(Handle display_ctx,
-                                                    const DisplayDetailEnhancerData &de_data) {
-  return kErrorNotSupported;
-}
-
-}  // namespace sdm
diff --git a/sdm/libs/core/resource_default.h b/sdm/libs/core/resource_default.h
deleted file mode 100644
index a67eb09..0000000
--- a/sdm/libs/core/resource_default.h
+++ /dev/null
@@ -1,150 +0,0 @@
-/*
-* Copyright (c) 2014 - 2017, The Linux Foundation. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without modification, are permitted
-* provided that the following conditions are met:
-*    * Redistributions of source code must retain the above copyright notice, this list of
-*      conditions and the following disclaimer.
-*    * Redistributions in binary form must reproduce the above copyright notice, this list of
-*      conditions and the following disclaimer in the documentation and/or other materials provided
-*      with the distribution.
-*    * Neither the name of The Linux Foundation nor the names of its contributors may be used to
-*      endorse or promote products derived from this software without specific prior written
-*      permission.
-*
-* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-* NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
-* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
-* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
-* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#ifndef __RESOURCE_DEFAULT_H__
-#define __RESOURCE_DEFAULT_H__
-
-#include <core/display_interface.h>
-#include <private/resource_interface.h>
-#include <utils/locker.h>
-#include <vector>
-
-#include "hw_interface.h"
-
-namespace sdm {
-
-class ResourceDefault : public ResourceInterface {
- public:
-  static DisplayError CreateResourceDefault(const HWResourceInfo &hw_resource_info,
-                                            ResourceInterface **resource_intf);
-  static DisplayError DestroyResourceDefault(ResourceInterface *resource_intf);
-  virtual DisplayError RegisterDisplay(DisplayType type,
-                                       const HWDisplayAttributes &display_attributes,
-                                       const HWPanelInfo &hw_panel_info,
-                                       const HWMixerAttributes &mixer_attributes,
-                                       Handle *display_ctx);
-  virtual DisplayError UnregisterDisplay(Handle display_ctx);
-  virtual DisplayError ReconfigureDisplay(Handle display_ctx,
-                                          const HWDisplayAttributes &display_attributes,
-                                          const HWPanelInfo &hw_panel_info,
-                                          const HWMixerAttributes &mixer_attributes);
-  virtual DisplayError Start(Handle display_ctx);
-  virtual DisplayError Stop(Handle display_ctx, HWLayers *hw_layers);
-  virtual DisplayError Prepare(Handle display_ctx, HWLayers *hw_layers);
-  virtual DisplayError PostPrepare(Handle display_ctx, HWLayers *hw_layers);
-  virtual DisplayError Commit(Handle display_ctx, HWLayers *hw_layers);
-  virtual DisplayError PostCommit(Handle display_ctx, HWLayers *hw_layers);
-  virtual void Purge(Handle display_ctx);
-  virtual DisplayError SetMaxMixerStages(Handle display_ctx, uint32_t max_mixer_stages);
-  virtual DisplayError ValidateScaling(const LayerRect &crop, const LayerRect &dst, bool rotate90,
-                                       BufferLayout layout, bool use_rotator_downscale);
-  DisplayError ValidateCursorConfig(Handle display_ctx, const Layer *layer, bool is_top);
-  DisplayError ValidateAndSetCursorPosition(Handle display_ctx, HWLayers *hw_layers, int x, int y,
-                                            DisplayConfigVariableInfo *fb_config);
-  DisplayError SetMaxBandwidthMode(HWBwModes mode);
-  virtual DisplayError SetDetailEnhancerData(Handle display_ctx,
-                                             const DisplayDetailEnhancerData &de_data);
-  virtual DisplayError Perform(int cmd, ...) { return kErrorNone; }
-
- private:
-  enum PipeOwner {
-    kPipeOwnerUserMode,       // Pipe state when it is available for reservation
-    kPipeOwnerKernelMode,  // Pipe state when pipe is owned by kernel
-  };
-
-  // todo: retrieve all these from kernel
-  enum {
-    kMaxDecimationDownScaleRatio = 16,
-  };
-
-  struct SourcePipe {
-    PipeType type;
-    PipeOwner owner;
-    uint32_t mdss_pipe_id;
-    uint32_t index;
-    HWBlockType hw_block_id;
-    int priority;
-
-    SourcePipe() : type(kPipeTypeUnused), owner(kPipeOwnerUserMode), mdss_pipe_id(0),
-                  index(0), hw_block_id(kHWBlockMax), priority(0) { }
-
-    inline void ResetState() { hw_block_id = kHWBlockMax;}
-  };
-
-  struct DisplayResourceContext {
-    HWDisplayAttributes display_attributes;
-    HWBlockType hw_block_id;
-    uint64_t frame_count;
-    HWMixerAttributes mixer_attributes;
-
-    DisplayResourceContext() : hw_block_id(kHWBlockMax), frame_count(0) { }
-  };
-
-  struct HWBlockContext {
-    bool is_in_use;
-    HWBlockContext() : is_in_use(false) { }
-  };
-
-  explicit ResourceDefault(const HWResourceInfo &hw_res_info);
-  DisplayError Init();
-  DisplayError Deinit();
-  uint32_t NextPipe(PipeType pipe_type, HWBlockType hw_block_id);
-  uint32_t SearchPipe(HWBlockType hw_block_id, SourcePipe *src_pipes, uint32_t num_pipe);
-  uint32_t GetPipe(HWBlockType hw_block_id, bool need_scale);
-  bool IsScalingNeeded(const HWPipeInfo *pipe_info);
-  DisplayError Config(DisplayResourceContext *display_resource_ctx, HWLayers *hw_layers);
-  DisplayError DisplaySplitConfig(DisplayResourceContext *display_resource_ctx,
-                                 const LayerRect &src_rect, const LayerRect &dst_rect,
-                                 HWLayerConfig *layer_config);
-  DisplayError SrcSplitConfig(DisplayResourceContext *display_resource_ctx,
-                             const LayerRect &src_rect, const LayerRect &dst_rect,
-                             HWLayerConfig *layer_config);
-  bool CalculateCropRects(const LayerRect &scissor, LayerRect *crop, LayerRect *dst);
-  DisplayError ValidateLayerParams(const Layer *layer);
-  DisplayError ValidateDimensions(const LayerRect &crop, const LayerRect &dst);
-  DisplayError ValidatePipeParams(HWPipeInfo *pipe_info, LayerBufferFormat format);
-  DisplayError ValidateDownScaling(float scale_x, float scale_y, bool ubwc_tiled);
-  DisplayError ValidateUpScaling(float scale_x, float scale_y);
-  DisplayError GetScaleFactor(const LayerRect &crop, const LayerRect &dst, float *scale_x,
-                             float *scale_y);
-  DisplayError SetDecimationFactor(HWPipeInfo *pipe);
-  void SplitRect(const LayerRect &src_rect, const LayerRect &dst_rect, LayerRect *src_left,
-                LayerRect *dst_left, LayerRect *src_right, LayerRect *dst_right);
-  DisplayError AlignPipeConfig(const Layer *layer, HWPipeInfo *left_pipe,
-                               HWPipeInfo *right_pipe);
-  void ResourceStateLog(void);
-  DisplayError CalculateDecimation(float downscale, uint8_t *decimation);
-  DisplayError GetScaleLutConfig(HWScaleLutInfo *lut_info);
-
-  Locker locker_;
-  HWResourceInfo hw_res_info_;
-  HWBlockContext hw_block_ctx_[kHWBlockMax];
-  std::vector<SourcePipe> src_pipes_;
-  uint32_t num_pipe_ = 0;
-};
-
-}  // namespace sdm
-
-#endif  // __RESOURCE_DEFAULT_H__
-
diff --git a/sdm/libs/core/strategy.cpp b/sdm/libs/core/strategy.cpp
deleted file mode 100644
index a02e309..0000000
--- a/sdm/libs/core/strategy.cpp
+++ /dev/null
@@ -1,255 +0,0 @@
-/*
-* Copyright (c) 2014 - 2018, The Linux Foundation. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without modification, are permitted
-* provided that the following conditions are met:
-*    * Redistributions of source code must retain the above copyright notice, this list of
-*      conditions and the following disclaimer.
-*    * Redistributions in binary form must reproduce the above copyright notice, this list of
-*      conditions and the following disclaimer in the documentation and/or other materials provided
-*      with the distribution.
-*    * Neither the name of The Linux Foundation nor the names of its contributors may be used to
-*      endorse or promote products derived from this software without specific prior written
-*      permission.
-*
-* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-* NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
-* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
-* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
-* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#include <utils/constants.h>
-#include <utils/debug.h>
-
-#include "strategy.h"
-#include "utils/rect.h"
-
-#define __CLASS__ "Strategy"
-
-namespace sdm {
-
-Strategy::Strategy(ExtensionInterface *extension_intf, BufferAllocator *buffer_allocator,
-                   DisplayType type,
-                   const HWResourceInfo &hw_resource_info, const HWPanelInfo &hw_panel_info,
-                   const HWMixerAttributes &mixer_attributes,
-                   const HWDisplayAttributes &display_attributes,
-                   const DisplayConfigVariableInfo &fb_config)
-  : extension_intf_(extension_intf), display_type_(type), hw_resource_info_(hw_resource_info),
-    hw_panel_info_(hw_panel_info), mixer_attributes_(mixer_attributes),
-    display_attributes_(display_attributes), fb_config_(fb_config),
-    buffer_allocator_(buffer_allocator) {
-}
-
-DisplayError Strategy::Init() {
-  DisplayError error = kErrorNone;
-
-  if (extension_intf_) {
-    error = extension_intf_->CreateStrategyExtn(display_type_, buffer_allocator_, hw_resource_info_,
-                                                hw_panel_info_, mixer_attributes_, fb_config_,
-                                                &strategy_intf_);
-    if (error != kErrorNone) {
-      DLOGE("Failed to create strategy");
-      return error;
-    }
-
-    error = extension_intf_->CreatePartialUpdate(display_type_, hw_resource_info_, hw_panel_info_,
-                                                 mixer_attributes_, display_attributes_, fb_config_,
-                                                 &partial_update_intf_);
-  }
-
-  return kErrorNone;
-}
-
-DisplayError Strategy::Deinit() {
-  if (strategy_intf_) {
-    if (partial_update_intf_) {
-      extension_intf_->DestroyPartialUpdate(partial_update_intf_);
-    }
-
-    extension_intf_->DestroyStrategyExtn(strategy_intf_);
-  }
-
-  return kErrorNone;
-}
-
-DisplayError Strategy::Start(HWLayersInfo *hw_layers_info, uint32_t *max_attempts,
-                             const PUConstraints &pu_constraints) {
-  DisplayError error = kErrorNone;
-
-  hw_layers_info_ = hw_layers_info;
-  extn_start_success_ = false;
-
-  if (!disable_gpu_comp_ && !hw_layers_info_->gpu_target_index) {
-    DLOGE("GPU composition is enabled and GPU target buffer not provided.");
-    return kErrorNotSupported;
-  }
-
-  if (partial_update_intf_) {
-    partial_update_intf_->Start(pu_constraints);
-  }
-  GenerateROI();
-
-  if (strategy_intf_) {
-    error = strategy_intf_->Start(hw_layers_info_, max_attempts);
-    if (error == kErrorNone) {
-      extn_start_success_ = true;
-      return kErrorNone;
-    }
-  }
-
-  *max_attempts = 1;
-
-  return kErrorNone;
-}
-
-DisplayError Strategy::Stop() {
-  if (strategy_intf_) {
-    return strategy_intf_->Stop();
-  }
-
-  return kErrorNone;
-}
-
-DisplayError Strategy::GetNextStrategy(StrategyConstraints *constraints) {
-  if (extn_start_success_) {
-    return strategy_intf_->GetNextStrategy(constraints);
-  }
-
-  // Do not fallback to GPU if GPU comp is disabled.
-  if (disable_gpu_comp_) {
-    return kErrorNotSupported;
-  }
-
-  // Mark all application layers for GPU composition. Find GPU target buffer and store its index for
-  // programming the hardware.
-  LayerStack *layer_stack = hw_layers_info_->stack;
-  for (uint32_t i = 0; i < hw_layers_info_->app_layer_count; i++) {
-    layer_stack->layers.at(i)->composition = kCompositionGPU;
-    layer_stack->layers.at(i)->request.flags.request_flags = 0;  // Reset layer request
-  }
-
-  // When mixer resolution and panel resolutions are same (1600x2560) and FB resolution is
-  // 1080x1920 FB_Target destination coordinates(mapped to FB resolution 1080x1920) need to
-  // be mapped to destination coordinates of mixer resolution(1600x2560).
-  Layer *gpu_target_layer = layer_stack->layers.at(hw_layers_info_->gpu_target_index);
-  float layer_mixer_width = FLOAT(mixer_attributes_.width);
-  float layer_mixer_height = FLOAT(mixer_attributes_.height);
-  float fb_width = FLOAT(fb_config_.x_pixels);
-  float fb_height = FLOAT(fb_config_.y_pixels);
-  LayerRect src_domain = (LayerRect){0.0f, 0.0f, fb_width, fb_height};
-  LayerRect dst_domain = (LayerRect){0.0f, 0.0f, layer_mixer_width, layer_mixer_height};
-
-  Layer layer = *gpu_target_layer;
-  hw_layers_info_->index.push_back(hw_layers_info_->gpu_target_index);
-  hw_layers_info_->roi_index.push_back(0);
-  layer.transform.flip_horizontal ^= hw_panel_info_.panel_orientation.flip_horizontal;
-  layer.transform.flip_vertical ^= hw_panel_info_.panel_orientation.flip_vertical;
-  // Flip rect to match transform.
-  TransformHV(src_domain, layer.dst_rect, layer.transform, &layer.dst_rect);
-  // Scale to mixer resolution.
-  MapRect(src_domain, dst_domain, layer.dst_rect, &layer.dst_rect);
-  hw_layers_info_->hw_layers.push_back(layer);
-
-  return kErrorNone;
-}
-
-void Strategy::GenerateROI() {
-  bool split_display = false;
-
-  if (partial_update_intf_ && partial_update_intf_->GenerateROI(hw_layers_info_) == kErrorNone) {
-    return;
-  }
-
-  float layer_mixer_width = mixer_attributes_.width;
-  float layer_mixer_height = mixer_attributes_.height;
-
-  if (!hw_resource_info_.is_src_split && display_attributes_.is_device_split) {
-    split_display = true;
-  }
-
-  hw_layers_info_->left_frame_roi = {};
-  hw_layers_info_->right_frame_roi = {};
-
-  if (split_display) {
-    float left_split = FLOAT(mixer_attributes_.split_left);
-    hw_layers_info_->left_frame_roi.push_back(LayerRect(0.0f, 0.0f,
-                                left_split, layer_mixer_height));
-    hw_layers_info_->right_frame_roi.push_back(LayerRect(left_split,
-                                0.0f, layer_mixer_width, layer_mixer_height));
-  } else {
-    hw_layers_info_->left_frame_roi.push_back(LayerRect(0.0f, 0.0f,
-                                layer_mixer_width, layer_mixer_height));
-    hw_layers_info_->right_frame_roi.push_back(LayerRect(0.0f, 0.0f, 0.0f, 0.0f));
-  }
-}
-
-DisplayError Strategy::Reconfigure(const HWPanelInfo &hw_panel_info,
-                         const HWDisplayAttributes &display_attributes,
-                         const HWMixerAttributes &mixer_attributes,
-                         const DisplayConfigVariableInfo &fb_config) {
-  DisplayError error = kErrorNone;
-
-  if (!extension_intf_) {
-    return kErrorNone;
-  }
-
-  // TODO(user): PU Intf will not be created for video mode panels, hence re-evaluate if
-  // reconfigure is needed.
-  if (partial_update_intf_) {
-    extension_intf_->DestroyPartialUpdate(partial_update_intf_);
-    partial_update_intf_ = NULL;
-  }
-
-  extension_intf_->CreatePartialUpdate(display_type_, hw_resource_info_, hw_panel_info,
-                                       mixer_attributes, display_attributes, fb_config,
-                                       &partial_update_intf_);
-
-  error = strategy_intf_->Reconfigure(hw_panel_info, hw_resource_info_, mixer_attributes,
-                                      fb_config);
-  if (error != kErrorNone) {
-    return error;
-  }
-
-  hw_panel_info_ = hw_panel_info;
-  display_attributes_ = display_attributes;
-  mixer_attributes_ = mixer_attributes;
-  fb_config_ = fb_config;
-
-  return kErrorNone;
-}
-
-DisplayError Strategy::SetCompositionState(LayerComposition composition_type, bool enable) {
-  DLOGI("composition type = %d, enable = %d", composition_type, enable);
-
-  if (composition_type == kCompositionGPU) {
-    disable_gpu_comp_ = !enable;
-  }
-
-  if (strategy_intf_) {
-    return strategy_intf_->SetCompositionState(composition_type, enable);
-  }
-
-  return kErrorNone;
-}
-
-DisplayError Strategy::Purge() {
-  if (strategy_intf_) {
-    return strategy_intf_->Purge();
-  }
-
-  return kErrorNone;
-}
-
-DisplayError Strategy::SetIdleTimeoutMs(uint32_t active_ms) {
-  if (strategy_intf_) {
-    return strategy_intf_->SetIdleTimeoutMs(active_ms);
-  }
-
-  return kErrorNotSupported;
-}
-
-}  // namespace sdm
diff --git a/sdm/libs/core/strategy.h b/sdm/libs/core/strategy.h
deleted file mode 100644
index b75a3dd..0000000
--- a/sdm/libs/core/strategy.h
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
-* Copyright (c) 2014 - 2017, The Linux Foundation. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without modification, are permitted
-* provided that the following conditions are met:
-*    * Redistributions of source code must retain the above copyright notice, this list of
-*      conditions and the following disclaimer.
-*    * Redistributions in binary form must reproduce the above copyright notice, this list of
-*      conditions and the following disclaimer in the documentation and/or other materials provided
-*      with the distribution.
-*    * Neither the name of The Linux Foundation nor the names of its contributors may be used to
-*      endorse or promote products derived from this software without specific prior written
-*      permission.
-*
-* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-* NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
-* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
-* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
-* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#ifndef __STRATEGY_H__
-#define __STRATEGY_H__
-
-#include <core/display_interface.h>
-#include <private/extension_interface.h>
-#include <core/buffer_allocator.h>
-
-namespace sdm {
-
-class Strategy {
- public:
-  Strategy(ExtensionInterface *extension_intf, BufferAllocator *buffer_allocator,
-           DisplayType type,
-           const HWResourceInfo &hw_resource_info, const HWPanelInfo &hw_panel_info,
-           const HWMixerAttributes &mixer_attributes, const HWDisplayAttributes &display_attributes,
-           const DisplayConfigVariableInfo &fb_config);
-
-  DisplayError Init();
-  DisplayError Deinit();
-
-  DisplayError Start(HWLayersInfo *hw_layers_info, uint32_t *max_attempts,
-                     const PUConstraints &pu_constraints);
-  DisplayError GetNextStrategy(StrategyConstraints *constraints);
-  DisplayError Stop();
-  DisplayError Reconfigure(const HWPanelInfo &hw_panel_info,
-                           const HWDisplayAttributes &hw_display_attributes,
-                           const HWMixerAttributes &mixer_attributes,
-                           const DisplayConfigVariableInfo &fb_config);
-  DisplayError SetCompositionState(LayerComposition composition_type, bool enable);
-  DisplayError Purge();
-  DisplayError SetIdleTimeoutMs(uint32_t active_ms);
-
- private:
-  void GenerateROI();
-
-  ExtensionInterface *extension_intf_ = NULL;
-  StrategyInterface *strategy_intf_ = NULL;
-  PartialUpdateInterface *partial_update_intf_ = NULL;
-  DisplayType display_type_;
-  HWResourceInfo hw_resource_info_;
-  HWPanelInfo hw_panel_info_;
-  HWLayersInfo *hw_layers_info_ = NULL;
-  HWMixerAttributes mixer_attributes_ = {};
-  HWDisplayAttributes display_attributes_ = {};
-  DisplayConfigVariableInfo fb_config_ = {};
-  bool extn_start_success_ = false;
-  bool disable_gpu_comp_ = false;
-  BufferAllocator *buffer_allocator_ = NULL;
-};
-
-}  // namespace sdm
-
-#endif  // __STRATEGY_H__
-
diff --git a/sdm/libs/hwc2/Android.mk b/sdm/libs/hwc2/Android.mk
deleted file mode 100644
index 373ba48..0000000
--- a/sdm/libs/hwc2/Android.mk
+++ /dev/null
@@ -1,53 +0,0 @@
-LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-include $(LOCAL_PATH)/../../../common.mk
-
-ifeq ($(use_hwc2),true)
-
-LOCAL_MODULE                  := hwcomposer.$(TARGET_BOARD_PLATFORM)
-LOCAL_VENDOR_MODULE           := true
-LOCAL_MODULE_RELATIVE_PATH    := hw
-LOCAL_MODULE_TAGS             := optional
-LOCAL_C_INCLUDES              := $(common_includes)
-LOCAL_HEADER_LIBRARIES        := display_headers
-
-LOCAL_CFLAGS                  := -Wno-missing-field-initializers -Wno-unused-parameter \
-                                 -std=c++11 -fcolor-diagnostics\
-                                 -DLOG_TAG=\"SDM\" $(common_flags)
-LOCAL_CLANG                   := true
-
-LOCAL_SHARED_LIBRARIES        := libsdmcore libqservice libbinder libhardware libhardware_legacy \
-                                 libutils libcutils libsync libqdutils libqdMetaData \
-                                 libdisplaydebug libsdmutils libc++ liblog libgrallocutils libui \
-                                 libgpu_tonemapper libhidlbase libhidltransport \
-                                 vendor.display.config@1.0 android.hardware.graphics.mapper@2.0 \
-                                 android.hardware.graphics.allocator@2.0
-
-ifeq ($(display_config_version), DISPLAY_CONFIG_1_1)
-LOCAL_SHARED_LIBRARIES        += vendor.display.config@1.1
-endif
-
-LOCAL_SRC_FILES               := hwc_session.cpp \
-                                 hwc_session_services.cpp \
-                                 hwc_display.cpp \
-                                 hwc_display_primary.cpp \
-                                 hwc_display_external.cpp \
-                                 hwc_display_virtual.cpp \
-                                 hwc_debugger.cpp \
-                                 hwc_buffer_sync_handler.cpp \
-                                 hwc_color_manager.cpp \
-                                 hwc_layers.cpp \
-                                 hwc_callbacks.cpp \
-                                 cpuhint.cpp \
-                                 hwc_tonemapper.cpp \
-                                 display_null.cpp \
-                                 hwc_socket_handler.cpp \
-                                 hwc_buffer_allocator.cpp \
-                                 hwc_display_external_test.cpp
-
-ifeq ($(TARGET_HAS_WIDE_COLOR_DISPLAY), true)
-    LOCAL_CFLAGS += -DFEATURE_WIDE_COLOR
-endif
-
-include $(BUILD_SHARED_LIBRARY)
-endif
diff --git a/sdm/libs/hwc2/cpuhint.cpp b/sdm/libs/hwc2/cpuhint.cpp
deleted file mode 100644
index ca88ead..0000000
--- a/sdm/libs/hwc2/cpuhint.cpp
+++ /dev/null
@@ -1,108 +0,0 @@
-/* Copyright (c) 2015, The Linux Foundataion. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without
-* modification, are permitted provided that the following conditions are
-* met:
-*     * Redistributions of source code must retain the above copyright
-*       notice, this list of conditions and the following disclaimer.
-*     * Redistributions in binary form must reproduce the above
-*       copyright notice, this list of conditions and the following
-*       disclaimer in the documentation and/or other materials provided
-*       with the distribution.
-*     * Neither the name of The Linux Foundation nor the names of its
-*       contributors may be used to endorse or promote products derived
-*       from this software without specific prior written permission.
-*
-* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
-* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
-* ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
-* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
-* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*
-*/
-
-#include <cutils/properties.h>
-#include <dlfcn.h>
-#include <utils/debug.h>
-
-#include "cpuhint.h"
-#include "hwc_debugger.h"
-
-#define __CLASS__ "CPUHint"
-
-namespace sdm {
-
-DisplayError CPUHint::Init(HWCDebugHandler *debug_handler) {
-  char path[PROPERTY_VALUE_MAX];
-  if (debug_handler->GetProperty("ro.vendor.extension_library", path) != kErrorNone) {
-    DLOGI("Vendor Extension Library not enabled");
-    return kErrorNotSupported;
-  }
-
-  int pre_enable_window = -1;
-  debug_handler->GetProperty(PERF_HINT_WINDOW_PROP, &pre_enable_window);
-  if (pre_enable_window <= 0) {
-    DLOGI("Invalid CPU Hint Pre-enable Window %d", pre_enable_window);
-    return kErrorNotSupported;
-  }
-
-  DLOGI("CPU Hint Pre-enable Window %d", pre_enable_window);
-  pre_enable_window_ = pre_enable_window;
-
-  if (vendor_ext_lib_.Open(path)) {
-    if (!vendor_ext_lib_.Sym("perf_lock_acq", reinterpret_cast<void **>(&fn_lock_acquire_)) ||
-        !vendor_ext_lib_.Sym("perf_lock_rel", reinterpret_cast<void **>(&fn_lock_release_))) {
-      DLOGW("Failed to load symbols for Vendor Extension Library");
-      return kErrorNotSupported;
-    }
-    DLOGI("Successfully Loaded Vendor Extension Library symbols");
-    enabled_ = true;
-  } else {
-    DLOGW("Failed to open %s : %s", path, vendor_ext_lib_.Error());
-  }
-
-  return kErrorNone;
-}
-
-void CPUHint::Set() {
-  if (!enabled_) {
-    return;
-  }
-  if (lock_acquired_) {
-    return;
-  }
-  if (frame_countdown_) {
-    --frame_countdown_;
-    return;
-  }
-
-  int hint = HINT;
-  lock_handle_ = fn_lock_acquire_(0 /*handle*/, 0/*duration*/,
-                                  &hint, sizeof(hint) / sizeof(int));
-  if (lock_handle_ >= 0) {
-    lock_acquired_ = true;
-  }
-}
-
-void CPUHint::Reset() {
-  if (!enabled_) {
-    return;
-  }
-
-  frame_countdown_ = pre_enable_window_;
-
-  if (!lock_acquired_) {
-    return;
-  }
-
-  fn_lock_release_(lock_handle_);
-  lock_acquired_ = false;
-}
-
-}  // namespace sdm
diff --git a/sdm/libs/hwc2/cpuhint.h b/sdm/libs/hwc2/cpuhint.h
deleted file mode 100644
index e758763..0000000
--- a/sdm/libs/hwc2/cpuhint.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/* Copyright (c) 2015, The Linux Foundataion. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without
-* modification, are permitted provided that the following conditions are
-* met:
-*     * Redistributions of source code must retain the above copyright
-*       notice, this list of conditions and the following disclaimer.
-*     * Redistributions in binary form must reproduce the above
-*       copyright notice, this list of conditions and the following
-*       disclaimer in the documentation and/or other materials provided
-*       with the distribution.
-*     * Neither the name of The Linux Foundation nor the names of its
-*       contributors may be used to endorse or promote products derived
-*       from this software without specific prior written permission.
-*
-* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
-* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
-* ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
-* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
-* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*
-*/
-
-#ifndef __CPUHINT_H__
-#define __CPUHINT_H__
-
-#include <core/sdm_types.h>
-#include <utils/sys.h>
-
-namespace sdm {
-
-class HWCDebugHandler;
-
-class CPUHint {
- public:
-  DisplayError Init(HWCDebugHandler *debug_handler);
-  void Set();
-  void Reset();
-
- private:
-  enum { HINT =  0x4501 /* 45-display layer hint, 01-Enable */ };
-  bool enabled_ = false;
-  // frames to wait before setting this hint
-  int pre_enable_window_ = 0;
-  int frame_countdown_ = 0;
-  int lock_handle_ = 0;
-  bool lock_acquired_ = false;
-  DynLib vendor_ext_lib_;
-  int (*fn_lock_acquire_)(int handle, int duration, int *hints, int num_args) = NULL;
-  int (*fn_lock_release_)(int value) = NULL;
-};
-
-}  // namespace sdm
-
-#endif  // __CPUHINT_H__
diff --git a/sdm/libs/hwc2/display_null.cpp b/sdm/libs/hwc2/display_null.cpp
deleted file mode 100644
index 7e52911..0000000
--- a/sdm/libs/hwc2/display_null.cpp
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
-* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without
-* modification, are permitted provided that the following conditions are
-* met:
-*     * Redistributions of source code must retain the above copyright
-*       notice, this list of conditions and the following disclaimer.
-*     * Redistributions in binary form must reproduce the above
-*       copyright notice, this list of conditions and the following
-*       disclaimer in the documentation and/or other materials provided
-*       with the distribution.
-*     * Neither the name of The Linux Foundation nor the names of its
-*       contributors may be used to endorse or promote products derived
-*       from this software without specific prior written permission.
-*
-* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
-* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
-* ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
-* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
-* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#include "display_null.h"
-
-#define __CLASS__ "DisplayNull"
-
-namespace sdm {
-
-DisplayError DisplayNull::Commit(LayerStack *layer_stack) {
-  for (Layer *layer : layer_stack->layers) {
-    if (layer->composition != kCompositionGPUTarget) {
-      layer->composition = kCompositionSDE;
-      layer->input_buffer.release_fence_fd = -1;
-    }
-  }
-  layer_stack->retire_fence_fd = -1;
-
-  return kErrorNone;
-}
-
-DisplayError DisplayNull::GetDisplayState(DisplayState *state) {
-  *state = state_;
-  return kErrorNone;
-}
-
-DisplayError DisplayNull::SetDisplayState(DisplayState state, int *release_fence) {
-  state_ = state;
-  return kErrorNone;
-}
-
-DisplayError DisplayNull::SetFrameBufferConfig(const DisplayConfigVariableInfo &variable_info) {
-  fb_config_ = variable_info;
-  return kErrorNone;
-}
-
-DisplayError DisplayNull::GetFrameBufferConfig(DisplayConfigVariableInfo *variable_info) {
-  *variable_info = fb_config_;
-  return kErrorNone;
-}
-
-}  // namespace sdm
diff --git a/sdm/libs/hwc2/display_null.h b/sdm/libs/hwc2/display_null.h
deleted file mode 100644
index bd49a16..0000000
--- a/sdm/libs/hwc2/display_null.h
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
-* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without
-* modification, are permitted provided that the following conditions are
-* met:
-*     * Redistributions of source code must retain the above copyright
-*       notice, this list of conditions and the following disclaimer.
-*     * Redistributions in binary form must reproduce the above
-*       copyright notice, this list of conditions and the following
-*       disclaimer in the documentation and/or other materials provided
-*       with the distribution.
-*     * Neither the name of The Linux Foundation nor the names of its
-*       contributors may be used to endorse or promote products derived
-*       from this software without specific prior written permission.
-*
-* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
-* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
-* ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
-* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
-* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#ifndef __DISPLAY_NULL_H__
-#define __DISPLAY_NULL_H__
-
-#include <core/display_interface.h>
-#include <string>
-#include <vector>
-
-namespace sdm {
-
-#define MAKE_NO_OP(virtual_method_name) \
-      virtual DisplayError virtual_method_name { return kErrorNone; }
-
-class DisplayNull : public DisplayInterface {
- public:
-  virtual ~DisplayNull() { }
-  virtual DisplayError Commit(LayerStack *layer_stack);
-  virtual DisplayError GetDisplayState(DisplayState *state);
-  virtual DisplayError SetDisplayState(DisplayState state, int *release_fence);
-  virtual DisplayError SetFrameBufferConfig(const DisplayConfigVariableInfo &variable_info);
-  virtual DisplayError GetFrameBufferConfig(DisplayConfigVariableInfo *variable_info);
-  virtual bool IsUnderscanSupported() { return true; }
-  virtual void SetIdleTimeoutMs(uint32_t active_ms) { }
-  virtual bool IsPrimaryDisplay() { return true; }
-
-  void SetActive(bool active) {
-    active_ = active;
-  }
-
-  bool IsActive() {
-    return active_;
-  }
-
-  MAKE_NO_OP(Prepare(LayerStack *))
-  MAKE_NO_OP(Flush())
-  MAKE_NO_OP(GetNumVariableInfoConfigs(uint32_t *))
-  MAKE_NO_OP(GetConfig(uint32_t, DisplayConfigVariableInfo *))
-  MAKE_NO_OP(GetConfig(DisplayConfigFixedInfo *))
-  MAKE_NO_OP(GetActiveConfig(uint32_t *))
-  MAKE_NO_OP(GetVSyncState(bool *))
-  MAKE_NO_OP(SetActiveConfig(uint32_t))
-  MAKE_NO_OP(SetActiveConfig(DisplayConfigVariableInfo *))
-  MAKE_NO_OP(SetMaxMixerStages(uint32_t))
-  MAKE_NO_OP(ControlPartialUpdate(bool, uint32_t *))
-  MAKE_NO_OP(DisablePartialUpdateOneFrame())
-  MAKE_NO_OP(SetDisplayMode(uint32_t))
-  MAKE_NO_OP(SetPanelBrightness(int))
-  MAKE_NO_OP(CachePanelBrightness(int))
-  MAKE_NO_OP(OnMinHdcpEncryptionLevelChange(uint32_t))
-  MAKE_NO_OP(ColorSVCRequestRoute(const PPDisplayAPIPayload &, PPDisplayAPIPayload *,
-                                  PPPendingParams *))
-  MAKE_NO_OP(GetColorModeCount(uint32_t *))
-  MAKE_NO_OP(GetColorModes(uint32_t *, std::vector<std::string> *))
-  MAKE_NO_OP(GetColorModeAttr(const std::string &, AttrVal *))
-  MAKE_NO_OP(SetColorMode(const std::string &))
-  MAKE_NO_OP(SetColorModeById(int32_t))
-  MAKE_NO_OP(SetColorTransform(const uint32_t, const double *))
-  MAKE_NO_OP(GetDefaultColorMode(std::string *))
-  MAKE_NO_OP(ApplyDefaultDisplayMode())
-  MAKE_NO_OP(SetCursorPosition(int, int))
-  MAKE_NO_OP(GetRefreshRateRange(uint32_t *, uint32_t *))
-  MAKE_NO_OP(SetRefreshRate(uint32_t, bool))
-  MAKE_NO_OP(GetPanelBrightness(int *))
-  MAKE_NO_OP(SetVSyncState(bool))
-  MAKE_NO_OP(SetMixerResolution(uint32_t, uint32_t))
-  MAKE_NO_OP(GetMixerResolution(uint32_t *, uint32_t *))
-  MAKE_NO_OP(SetDetailEnhancerData(const DisplayDetailEnhancerData &))
-  MAKE_NO_OP(GetDisplayPort(DisplayPort *))
-  MAKE_NO_OP(SetCompositionState(LayerComposition, bool))
-  MAKE_NO_OP(GetClientTargetSupport(uint32_t, uint32_t, LayerBufferFormat,
-                                    const ColorMetaData &))
-  std::string Dump() { return ""; }
-
- private:
-  bool active_ = false;
-  DisplayState state_ = kStateOff;
-  DisplayConfigVariableInfo fb_config_ = {};
-};
-
-}  // namespace sdm
-
-#endif  // __DISPLAY_NULL_H__
diff --git a/sdm/libs/hwc2/hwc_buffer_allocator.cpp b/sdm/libs/hwc2/hwc_buffer_allocator.cpp
deleted file mode 100644
index e1d32db..0000000
--- a/sdm/libs/hwc2/hwc_buffer_allocator.cpp
+++ /dev/null
@@ -1,442 +0,0 @@
-/*
- * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *  * Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *  * Redistributions in binary form must reproduce the above
- *    copyright notice, this list of conditions and the following
- *    disclaimer in the documentation and/or other materials provided
- *    with the distribution.
- *  * Neither the name of The Linux Foundation nor the names of its
- *    contributors may be used to endorse or promote products derived
- *    from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <gralloc_priv.h>
-
-#include <core/buffer_allocator.h>
-#include <utils/constants.h>
-#include <utils/debug.h>
-
-#include "gr_utils.h"
-#include "hwc_buffer_allocator.h"
-#include "hwc_debugger.h"
-
-#define __CLASS__ "HWCBufferAllocator"
-
-using android::hardware::graphics::common::V1_0::PixelFormat;
-using android::hardware::graphics::mapper::V2_0::BufferDescriptor;
-using android::hardware::graphics::mapper::V2_0::Error;
-using android::hardware::hidl_handle;
-using android::hardware::hidl_vec;
-
-namespace sdm {
-
-DisplayError HWCBufferAllocator::GetGrallocInstance() {
-  // Lazy initialization of gralloc HALs
-  if (mapper_ != nullptr || allocator_ != nullptr) {
-    return kErrorNone;
-  }
-
-  allocator_ = IAllocator::getService();
-  mapper_ = IMapper::getService();
-
-  if (mapper_ == nullptr || allocator_ == nullptr) {
-    DLOGE("Unable to get mapper or allocator");
-    return kErrorCriticalResource;
-  }
-  return kErrorNone;
-}
-
-DisplayError HWCBufferAllocator::AllocateBuffer(BufferInfo *buffer_info) {
-  auto err = GetGrallocInstance();
-  if (err != kErrorNone) {
-    return err;
-  }
-  const BufferConfig &buffer_config = buffer_info->buffer_config;
-  AllocatedBufferInfo *alloc_buffer_info = &buffer_info->alloc_buffer_info;
-  int format;
-  uint64_t alloc_flags = 0;
-  int error = SetBufferInfo(buffer_config.format, &format, &alloc_flags);
-  if (error != 0) {
-    return kErrorParameters;
-  }
-
-  if (buffer_config.secure) {
-    alloc_flags |= BufferUsage::PROTECTED;
-  }
-
-  if (buffer_config.secure_camera) {
-    alloc_flags |= BufferUsage::CAMERA_OUTPUT;
-  }
-
-  if (!buffer_config.cache) {
-    // Allocate uncached buffers
-    alloc_flags |= GRALLOC_USAGE_PRIVATE_UNCACHED;
-  }
-
-  if (buffer_config.gfx_client) {
-    alloc_flags |= BufferUsage::GPU_TEXTURE;
-  }
-
-  alloc_flags |= BufferUsage::COMPOSER_OVERLAY;
-
-  IMapper::BufferDescriptorInfo descriptor_info;
-  descriptor_info.width = buffer_config.width;
-  descriptor_info.height = buffer_config.height;
-  descriptor_info.layerCount = 1;
-  descriptor_info.format = static_cast<PixelFormat>(format);
-  descriptor_info.usage = alloc_flags;
-  auto descriptor = BufferDescriptor();
-  auto hidl_err = Error::NONE;
-
-  mapper_->createDescriptor(descriptor_info, [&](const auto &_error, const auto &_descriptor) {
-    hidl_err = _error;
-    descriptor = _descriptor;
-  });
-  if (hidl_err != Error::NONE) {
-    DLOGE("Failed to create descriptor");
-    return kErrorMemory;
-  }
-
-  hidl_handle raw_handle = nullptr;
-  private_handle_t *hnd = nullptr;
-
-  allocator_->allocate(descriptor, 1,
-                       [&](const auto &_error, const auto &_stride, const auto &_buffers) {
-                         hidl_err = _error;
-                         raw_handle = _buffers[0];
-                       });
-  if (hidl_err != Error::NONE) {
-    DLOGE("Failed to allocate buffer");
-    return kErrorMemory;
-  }
-
-  const native_handle_t *buf = nullptr;
-  mapper_->importBuffer(raw_handle, [&](const auto &_error, const auto &_buffer) {
-    hidl_err = _error;
-    buf = static_cast<const native_handle_t *>(_buffer);
-  });
-
-  if (hidl_err != Error::NONE) {
-    DLOGE("Failed to import buffer into HWC");
-    return kErrorMemory;
-  }
-
-  hnd = (private_handle_t *)buf;  // NOLINT
-  alloc_buffer_info->fd = hnd->fd;
-  alloc_buffer_info->stride = UINT32(hnd->width);
-  alloc_buffer_info->aligned_width = UINT32(hnd->width);
-  alloc_buffer_info->aligned_height = UINT32(hnd->height);
-  alloc_buffer_info->size = hnd->size;
-
-  buffer_info->private_data = reinterpret_cast<void *>(hnd);
-  return kErrorNone;
-}
-
-DisplayError HWCBufferAllocator::FreeBuffer(BufferInfo *buffer_info) {
-  DisplayError err = kErrorNone;
-  auto hnd = reinterpret_cast<void *>(buffer_info->private_data);
-  mapper_->freeBuffer(hnd);
-  AllocatedBufferInfo &alloc_buffer_info = buffer_info->alloc_buffer_info;
-
-  alloc_buffer_info.fd = -1;
-  alloc_buffer_info.stride = 0;
-  alloc_buffer_info.size = 0;
-  buffer_info->private_data = NULL;
-  return err;
-}
-
-void HWCBufferAllocator::GetCustomWidthAndHeight(const private_handle_t *handle, int *width,
-                                                 int *height) {
-  *width = handle->width;
-  *height = handle->height;
-  gralloc::GetCustomDimensions(const_cast<private_handle_t *>(handle), width, height);
-}
-
-void HWCBufferAllocator::GetAlignedWidthAndHeight(int width, int height, int format,
-                                                  uint32_t alloc_type, int *aligned_width,
-                                                  int *aligned_height) {
-  uint64_t usage = 0;
-  if (alloc_type & GRALLOC_USAGE_HW_FB) {
-    usage |= BufferUsage::COMPOSER_CLIENT_TARGET;
-  }
-  if (alloc_type & GRALLOC_USAGE_PRIVATE_ALLOC_UBWC) {
-    usage |= GRALLOC_USAGE_PRIVATE_ALLOC_UBWC;
-  }
-  uint32_t aligned_w = UINT(width);
-  uint32_t aligned_h = UINT(height);
-  gralloc::BufferInfo info(width, height, format, usage);
-  gralloc::GetAlignedWidthAndHeight(info, &aligned_w, &aligned_h);
-  *aligned_width = INT(aligned_w);
-  *aligned_height = INT(aligned_h);
-}
-
-uint32_t HWCBufferAllocator::GetBufferSize(BufferInfo *buffer_info) {
-  const BufferConfig &buffer_config = buffer_info->buffer_config;
-  uint64_t alloc_flags = GRALLOC_USAGE_PRIVATE_IOMMU_HEAP;
-
-  int width = INT(buffer_config.width);
-  int height = INT(buffer_config.height);
-  int format;
-
-  if (buffer_config.secure) {
-    alloc_flags |= INT(GRALLOC_USAGE_PROTECTED);
-  }
-
-  if (!buffer_config.cache) {
-    // Allocate uncached buffers
-    alloc_flags |= GRALLOC_USAGE_PRIVATE_UNCACHED;
-  }
-
-  if (SetBufferInfo(buffer_config.format, &format, &alloc_flags) < 0) {
-    return 0;
-  }
-
-  uint32_t aligned_width = 0, aligned_height = 0, buffer_size = 0;
-  gralloc::BufferInfo info(width, height, format, alloc_flags);
-  GetBufferSizeAndDimensions(info, &buffer_size, &aligned_width, &aligned_height);
-  return buffer_size;
-}
-
-int HWCBufferAllocator::SetBufferInfo(LayerBufferFormat format, int *target, uint64_t *flags) {
-  switch (format) {
-    case kFormatRGBA8888:
-      *target = HAL_PIXEL_FORMAT_RGBA_8888;
-      break;
-    case kFormatRGBX8888:
-      *target = HAL_PIXEL_FORMAT_RGBX_8888;
-      break;
-    case kFormatRGB888:
-      *target = HAL_PIXEL_FORMAT_RGB_888;
-      break;
-    case kFormatRGB565:
-      *target = HAL_PIXEL_FORMAT_RGB_565;
-      break;
-    case kFormatBGR565:
-      *target = HAL_PIXEL_FORMAT_BGR_565;
-      break;
-    case kFormatBGR888:
-      *target = HAL_PIXEL_FORMAT_BGR_888;
-      break;
-    case kFormatBGRA8888:
-      *target = HAL_PIXEL_FORMAT_BGRA_8888;
-      break;
-    case kFormatYCrCb420PlanarStride16:
-      *target = HAL_PIXEL_FORMAT_YV12;
-      break;
-    case kFormatYCrCb420SemiPlanar:
-      *target = HAL_PIXEL_FORMAT_YCrCb_420_SP;
-      break;
-    case kFormatYCbCr420SemiPlanar:
-      *target = HAL_PIXEL_FORMAT_YCbCr_420_SP;
-      break;
-    case kFormatYCbCr422H2V1Packed:
-      *target = HAL_PIXEL_FORMAT_YCbCr_422_I;
-      break;
-    case kFormatCbYCrY422H2V1Packed:
-      *target = HAL_PIXEL_FORMAT_CbYCrY_422_I;
-      break;
-    case kFormatYCbCr422H2V1SemiPlanar:
-      *target = HAL_PIXEL_FORMAT_YCbCr_422_SP;
-      break;
-    case kFormatYCbCr420SemiPlanarVenus:
-      *target = HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS;
-      break;
-    case kFormatYCrCb420SemiPlanarVenus:
-      *target = HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS;
-      break;
-    case kFormatYCbCr420SPVenusUbwc:
-      *target = HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC;
-      *flags |= GRALLOC_USAGE_PRIVATE_ALLOC_UBWC;
-      break;
-    case kFormatRGBA5551:
-      *target = HAL_PIXEL_FORMAT_RGBA_5551;
-      break;
-    case kFormatRGBA4444:
-      *target = HAL_PIXEL_FORMAT_RGBA_4444;
-      break;
-    case kFormatRGBA1010102:
-      *target = HAL_PIXEL_FORMAT_RGBA_1010102;
-      break;
-    case kFormatARGB2101010:
-      *target = HAL_PIXEL_FORMAT_ARGB_2101010;
-      break;
-    case kFormatRGBX1010102:
-      *target = HAL_PIXEL_FORMAT_RGBX_1010102;
-      break;
-    case kFormatXRGB2101010:
-      *target = HAL_PIXEL_FORMAT_XRGB_2101010;
-      break;
-    case kFormatBGRA1010102:
-      *target = HAL_PIXEL_FORMAT_BGRA_1010102;
-      break;
-    case kFormatABGR2101010:
-      *target = HAL_PIXEL_FORMAT_ABGR_2101010;
-      break;
-    case kFormatBGRX1010102:
-      *target = HAL_PIXEL_FORMAT_BGRX_1010102;
-      break;
-    case kFormatXBGR2101010:
-      *target = HAL_PIXEL_FORMAT_XBGR_2101010;
-      break;
-    case kFormatYCbCr420P010:
-      *target = HAL_PIXEL_FORMAT_YCbCr_420_P010;
-      break;
-    case kFormatYCbCr420TP10Ubwc:
-      *target = HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC;
-      *flags |= GRALLOC_USAGE_PRIVATE_ALLOC_UBWC;
-      break;
-    case kFormatYCbCr420P010Ubwc:
-      *target = HAL_PIXEL_FORMAT_YCbCr_420_P010_UBWC;
-      *flags |= GRALLOC_USAGE_PRIVATE_ALLOC_UBWC;
-      break;
-    case kFormatYCbCr420P010Venus:
-      *target = HAL_PIXEL_FORMAT_YCbCr_420_P010_VENUS;
-      break;
-    case kFormatRGBA8888Ubwc:
-      *target = HAL_PIXEL_FORMAT_RGBA_8888;
-      *flags |= GRALLOC_USAGE_PRIVATE_ALLOC_UBWC;
-      break;
-    case kFormatRGBX8888Ubwc:
-      *target = HAL_PIXEL_FORMAT_RGBX_8888;
-      *flags |= GRALLOC_USAGE_PRIVATE_ALLOC_UBWC;
-      break;
-    case kFormatBGR565Ubwc:
-      *target = HAL_PIXEL_FORMAT_BGR_565;
-      *flags |= GRALLOC_USAGE_PRIVATE_ALLOC_UBWC;
-      break;
-    case kFormatRGBA1010102Ubwc:
-      *target = HAL_PIXEL_FORMAT_RGBA_1010102;
-      *flags |= GRALLOC_USAGE_PRIVATE_ALLOC_UBWC;
-      break;
-    case kFormatRGBX1010102Ubwc:
-      *target = HAL_PIXEL_FORMAT_RGBX_1010102;
-      *flags |= GRALLOC_USAGE_PRIVATE_ALLOC_UBWC;
-      break;
-    default:
-      DLOGE("Unsupported format = 0x%x", format);
-      return -EINVAL;
-  }
-  return 0;
-}
-
-DisplayError HWCBufferAllocator::GetAllocatedBufferInfo(
-    const BufferConfig &buffer_config, AllocatedBufferInfo *allocated_buffer_info) {
-  // TODO(user): This API should pass the buffer_info of the already allocated buffer
-  // The private_data can then be typecast to the private_handle and used directly.
-  uint64_t alloc_flags = GRALLOC_USAGE_PRIVATE_IOMMU_HEAP;
-
-  int width = INT(buffer_config.width);
-  int height = INT(buffer_config.height);
-  int format;
-
-  if (buffer_config.secure) {
-    alloc_flags |= INT(GRALLOC_USAGE_PROTECTED);
-  }
-
-  if (!buffer_config.cache) {
-    // Allocate uncached buffers
-    alloc_flags |= GRALLOC_USAGE_PRIVATE_UNCACHED;
-  }
-
-  if (SetBufferInfo(buffer_config.format, &format, &alloc_flags) < 0) {
-    return kErrorParameters;
-  }
-
-  uint32_t aligned_width = 0, aligned_height = 0, buffer_size = 0;
-  gralloc::BufferInfo info(width, height, format, alloc_flags);
-  GetBufferSizeAndDimensions(info, &buffer_size, &aligned_width, &aligned_height);
-  allocated_buffer_info->stride = UINT32(aligned_width);
-  allocated_buffer_info->aligned_width = UINT32(aligned_width);
-  allocated_buffer_info->aligned_height = UINT32(aligned_height);
-  allocated_buffer_info->size = UINT32(buffer_size);
-
-  return kErrorNone;
-}
-
-DisplayError HWCBufferAllocator::GetBufferLayout(const AllocatedBufferInfo &buf_info,
-                                                 uint32_t stride[4], uint32_t offset[4],
-                                                 uint32_t *num_planes) {
-  // TODO(user): Transition APIs to not need a private handle
-  private_handle_t hnd(-1, 0, 0, 0, 0, 0, 0);
-  int format = HAL_PIXEL_FORMAT_RGBA_8888;
-  uint64_t flags = 0;
-
-  SetBufferInfo(buf_info.format, &format, &flags);
-  // Setup only the required stuff, skip rest
-  hnd.format = format;
-  hnd.width = INT32(buf_info.aligned_width);
-  hnd.height = INT32(buf_info.aligned_height);
-  if (flags & GRALLOC_USAGE_PRIVATE_ALLOC_UBWC) {
-    hnd.flags = private_handle_t::PRIV_FLAGS_UBWC_ALIGNED;
-  }
-
-  int ret = gralloc::GetBufferLayout(&hnd, stride, offset, num_planes);
-  if (ret < 0) {
-    DLOGE("GetBufferLayout failed");
-    return kErrorParameters;
-  }
-
-  return kErrorNone;
-}
-
-DisplayError HWCBufferAllocator::MapBuffer(const private_handle_t *handle, int acquire_fence) {
-  auto err = GetGrallocInstance();
-  if (err != kErrorNone) {
-    return err;
-  }
-  void *buffer_ptr = NULL;
-  const IMapper::Rect access_region = {.left = 0, .top = 0, .width = 0, .height = 0};
-
-  NATIVE_HANDLE_DECLARE_STORAGE(acquire_fence_storage, 1, 0);
-  hidl_handle acquire_fence_handle;
-  if (acquire_fence >= 0) {
-    auto h = native_handle_init(acquire_fence_storage, 1, 0);
-    h->data[0] = acquire_fence;
-    acquire_fence_handle = h;
-  }
-
-  auto hnd = const_cast<private_handle_t *>(handle);
-  mapper_->lock(reinterpret_cast<void *>(hnd), (uint64_t)BufferUsage::CPU_READ_OFTEN,
-                access_region, acquire_fence_handle, [&](const auto &_error, const auto &_buffer) {
-                  if (_error == Error::NONE) {
-                    buffer_ptr = _buffer;
-                  }
-                });
-
-  if (!buffer_ptr) {
-    return kErrorUndefined;
-  }
-  return kErrorNone;
-}
-
-DisplayError HWCBufferAllocator::UnmapBuffer(const private_handle_t *handle, int *release_fence) {
-  DisplayError err = kErrorNone;
-  *release_fence = -1;
-  auto hnd = const_cast<private_handle_t *>(handle);
-  mapper_->unlock(reinterpret_cast<void *>(hnd),
-                  [&](const auto &_error, const auto &_release_fence) {
-                    if (_error != Error::NONE) {
-                      err = kErrorUndefined;
-                    }
-                  });
-  return err;
-}
-
-}  // namespace sdm
diff --git a/sdm/libs/hwc2/hwc_buffer_allocator.h b/sdm/libs/hwc2/hwc_buffer_allocator.h
deleted file mode 100644
index d6f251f..0000000
--- a/sdm/libs/hwc2/hwc_buffer_allocator.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *  * Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *  * Redistributions in binary form must reproduce the above
- *    copyright notice, this list of conditions and the following
- *    disclaimer in the documentation and/or other materials provided
- *    with the distribution.
- *  * Neither the name of The Linux Foundation nor the names of its
- *    contributors may be used to endorse or promote products derived
- *    from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-#ifndef __HWC_BUFFER_ALLOCATOR_H__
-#define __HWC_BUFFER_ALLOCATOR_H__
-
-#include <fcntl.h>
-#include <sys/mman.h>
-
-#include <android/hardware/graphics/allocator/2.0/IAllocator.h>
-#include <android/hardware/graphics/mapper/2.0/IMapper.h>
-#include "gralloc_priv.h"
-
-using android::hardware::graphics::allocator::V2_0::IAllocator;
-using android::hardware::graphics::mapper::V2_0::IMapper;
-
-namespace sdm {
-
-template <class Type>
-inline Type ALIGN(Type x, Type align) {
-  return (x + align - 1) & ~(align - 1);
-}
-
-class HWCBufferAllocator : public BufferAllocator {
- public:
-  DisplayError AllocateBuffer(BufferInfo *buffer_info);
-  DisplayError FreeBuffer(BufferInfo *buffer_info);
-  uint32_t GetBufferSize(BufferInfo *buffer_info);
-
-  void GetCustomWidthAndHeight(const private_handle_t *handle, int *width, int *height);
-  void GetAlignedWidthAndHeight(int width, int height, int format, uint32_t alloc_type,
-                                int *aligned_width, int *aligned_height);
-  DisplayError GetAllocatedBufferInfo(const BufferConfig &buffer_config,
-                                      AllocatedBufferInfo *allocated_buffer_info);
-  DisplayError GetBufferLayout(const AllocatedBufferInfo &buf_info, uint32_t stride[4],
-                               uint32_t offset[4], uint32_t *num_planes);
-  int SetBufferInfo(LayerBufferFormat format, int *target, uint64_t *flags);
-  DisplayError MapBuffer(const private_handle_t *handle, int acquire_fence);
-  DisplayError UnmapBuffer(const private_handle_t *handle, int *release_fence);
-
- private:
-  DisplayError GetGrallocInstance();
-  android::sp<IMapper> mapper_;
-  android::sp<IAllocator> allocator_;
-};
-
-}  // namespace sdm
-#endif  // __HWC_BUFFER_ALLOCATOR_H__
diff --git a/sdm/libs/hwc2/hwc_buffer_sync_handler.cpp b/sdm/libs/hwc2/hwc_buffer_sync_handler.cpp
deleted file mode 100644
index f2dacb2..0000000
--- a/sdm/libs/hwc2/hwc_buffer_sync_handler.cpp
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
-* Copyright (c) 2015, The Linux Foundation. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without
-* modification, are permitted provided that the following conditions are
-* met:
-*  * Redistributions of source code must retain the above copyright
-*    notice, this list of conditions and the following disclaimer.
-*  * Redistributions in binary form must reproduce the above
-*    copyright notice, this list of conditions and the following
-*    disclaimer in the documentation and/or other materials provided
-*    with the distribution.
-*  * Neither the name of The Linux Foundation nor the names of its
-*    contributors may be used to endorse or promote products derived
-*    from this software without specific prior written permission.
-*
-* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
-* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
-* ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
-* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
-* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#include <errno.h>
-#include <sync/sync.h>
-#include <utils/constants.h>
-#include <utils/debug.h>
-
-#include "hwc_debugger.h"
-#include "hwc_buffer_sync_handler.h"
-
-#define __CLASS__ "HWCBufferSyncHandler"
-
-namespace sdm {
-
-DisplayError HWCBufferSyncHandler::SyncWait(int fd) {
-  int error = 0;
-
-  if (fd >= 0) {
-    error = sync_wait(fd, 1000);
-    if (error < 0) {
-      DLOGE("sync_wait error errno = %d, desc = %s", errno,  strerror(errno));
-      return kErrorTimeOut;
-    }
-  }
-
-  return kErrorNone;
-}
-
-DisplayError HWCBufferSyncHandler::SyncMerge(int fd1, int fd2, int *merged_fd) {
-  DisplayError error = kErrorNone;
-
-  // Merge the two fences.  In the case where one of the fences is not a
-  // valid fence (e.g. NO_FENCE) merge the one valid fence with itself so
-  // that a new fence with the given name is created.
-  // TODO(user): "SyncMerge"string should be replaced with user-defined string to represent
-  // why it is merged.
-  if (fd1 >= 0 && fd2 >= 0) {
-    *merged_fd = sync_merge("SyncMerge", fd1, fd2);
-  } else if (fd1 >= 0) {
-    *merged_fd = sync_merge("SyncMerge", fd1, fd1);
-  } else if (fd2 >= 0) {
-    *merged_fd = sync_merge("SyncMerge", fd2, fd2);
-  } else {
-    *merged_fd = -1;
-    return kErrorNone;
-  }
-
-  if (*merged_fd == -1) {
-    DLOGE("Sync merge error! fd1 %d fd2 %d", fd1, fd2);
-    error = kErrorFileDescriptor;
-  }
-
-  return error;
-}
-
-bool HWCBufferSyncHandler::IsSyncSignaled(int fd) {
-  if (sync_wait(fd, 0) < 0) {
-    return false;
-  } else {
-    return true;
-  }
-}
-
-}  // namespace sdm
-
diff --git a/sdm/libs/hwc2/hwc_buffer_sync_handler.h b/sdm/libs/hwc2/hwc_buffer_sync_handler.h
deleted file mode 100644
index 81479d8..0000000
--- a/sdm/libs/hwc2/hwc_buffer_sync_handler.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
-* Copyright (c) 2015, The Linux Foundation. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without
-* modification, are permitted provided that the following conditions are
-* met:
-*  * Redistributions of source code must retain the above copyright
-*    notice, this list of conditions and the following disclaimer.
-*  * Redistributions in binary form must reproduce the above
-*    copyright notice, this list of conditions and the following
-*    disclaimer in the documentation and/or other materials provided
-*    with the distribution.
-*  * Neither the name of The Linux Foundation nor the names of its
-*    contributors may be used to endorse or promote products derived
-*    from this software without specific prior written permission.
-*
-* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
-* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
-* ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
-* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
-* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-
-#ifndef __HWC_BUFFER_SYNC_HANDLER_H__
-#define __HWC_BUFFER_SYNC_HANDLER_H__
-
-#include <sys/mman.h>
-#include <fcntl.h>
-#include <core/sdm_types.h>
-#include <core/buffer_sync_handler.h>
-
-namespace sdm {
-
-class HWCBufferSyncHandler : public BufferSyncHandler {
- public:
-  HWCBufferSyncHandler() { }
-
-  virtual DisplayError SyncWait(int fd);
-  virtual DisplayError SyncMerge(int fd1, int fd2, int *merged_fd);
-  virtual bool IsSyncSignaled(int fd);
-};
-
-}  // namespace sdm
-#endif  // __HWC_BUFFER_SYNC_HANDLER_H__
-
-
diff --git a/sdm/libs/hwc2/hwc_callbacks.cpp b/sdm/libs/hwc2/hwc_callbacks.cpp
deleted file mode 100644
index 48593f1..0000000
--- a/sdm/libs/hwc2/hwc_callbacks.cpp
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *    * Redistributions of source code must retain the above copyright
- *      notice, this list of conditions and the following disclaimer.
- *    * Redistributions in binary form must reproduce the above
- *      copyright notice, this list of conditions and the following
- *      disclaimer in the documentation and/or other materials provided
- *      with the distribution.
- *    * Neither the name of The Linux Foundation. nor the names of its
- *      contributors may be used to endorse or promote products derived
- *      from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-#include <utils/constants.h>
-#include <utils/debug.h>
-#include "hwc_callbacks.h"
-
-#define __CLASS__ "HWCCallbacks"
-
-namespace sdm {
-
-HWC2::Error HWCCallbacks::Hotplug(hwc2_display_t display, HWC2::Connection state) {
-  if (!hotplug_) {
-    return HWC2::Error::NoResources;
-  }
-  hotplug_(hotplug_data_, display, INT32(state));
-  return HWC2::Error::None;
-}
-
-HWC2::Error HWCCallbacks::Refresh(hwc2_display_t display) {
-  if (!refresh_) {
-    return HWC2::Error::NoResources;
-  }
-  refresh_(refresh_data_, display);
-  return HWC2::Error::None;
-}
-
-HWC2::Error HWCCallbacks::Vsync(hwc2_display_t display, int64_t timestamp) {
-  if (!vsync_) {
-    return HWC2::Error::NoResources;
-  }
-  DTRACE_SCOPED();
-  vsync_(vsync_data_, display, timestamp);
-  return HWC2::Error::None;
-}
-
-HWC2::Error HWCCallbacks::Register(HWC2::Callback descriptor, hwc2_callback_data_t callback_data,
-                                   hwc2_function_pointer_t pointer) {
-  switch (descriptor) {
-    case HWC2::Callback::Hotplug:
-      hotplug_data_ = callback_data;
-      hotplug_ = reinterpret_cast<HWC2_PFN_HOTPLUG>(pointer);
-      break;
-    case HWC2::Callback::Refresh:
-      refresh_data_ = callback_data;
-      refresh_ = reinterpret_cast<HWC2_PFN_REFRESH>(pointer);
-      break;
-    case HWC2::Callback::Vsync:
-      vsync_data_ = callback_data;
-      vsync_ = reinterpret_cast<HWC2_PFN_VSYNC>(pointer);
-      break;
-    default:
-      return HWC2::Error::BadParameter;
-  }
-  return HWC2::Error::None;
-}
-
-}  // namespace sdm
diff --git a/sdm/libs/hwc2/hwc_callbacks.h b/sdm/libs/hwc2/hwc_callbacks.h
deleted file mode 100644
index d3f4e52..0000000
--- a/sdm/libs/hwc2/hwc_callbacks.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *    * Redistributions of source code must retain the above copyright
- *      notice, this list of conditions and the following disclaimer.
- *    * Redistributions in binary form must reproduce the above
- *      copyright notice, this list of conditions and the following
- *      disclaimer in the documentation and/or other materials provided
- *      with the distribution.
- *    * Neither the name of The Linux Foundation. nor the names of its
- *      contributors may be used to endorse or promote products derived
- *      from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef __HWC_CALLBACKS_H__
-#define __HWC_CALLBACKS_H__
-
-#define HWC2_INCLUDE_STRINGIFICATION
-#define HWC2_USE_CPP11
-#include <hardware/hwcomposer2.h>
-#undef HWC2_INCLUDE_STRINGIFICATION
-#undef HWC2_USE_CPP11
-
-namespace sdm {
-
-class HWCCallbacks {
- public:
-  HWC2::Error Hotplug(hwc2_display_t display, HWC2::Connection state);
-  HWC2::Error Refresh(hwc2_display_t display);
-  HWC2::Error Vsync(hwc2_display_t display, int64_t timestamp);
-  HWC2::Error Register(HWC2::Callback, hwc2_callback_data_t callback_data,
-                       hwc2_function_pointer_t pointer);
-
-  bool VsyncCallbackRegistered() { return (vsync_ != nullptr && vsync_data_ != nullptr); }
-
- private:
-  hwc2_callback_data_t hotplug_data_ = nullptr;
-  hwc2_callback_data_t refresh_data_ = nullptr;
-  hwc2_callback_data_t vsync_data_ = nullptr;
-
-  HWC2_PFN_HOTPLUG hotplug_ = nullptr;
-  HWC2_PFN_REFRESH refresh_ = nullptr;
-  HWC2_PFN_VSYNC vsync_ = nullptr;
-};
-
-}  // namespace sdm
-
-#endif  // __HWC_CALLBACKS_H__
diff --git a/sdm/libs/hwc2/hwc_color_manager.cpp b/sdm/libs/hwc2/hwc_color_manager.cpp
deleted file mode 100644
index 8023b6a..0000000
--- a/sdm/libs/hwc2/hwc_color_manager.cpp
+++ /dev/null
@@ -1,478 +0,0 @@
-/*
-* Copyright (c) 2015 - 2017, The Linux Foundation. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without
-* modification, are permitted provided that the following conditions are
-* met:
-*     * Redistributions of source code must retain the above copyright
-*       notice, this list of conditions and the following disclaimer.
-*     * Redistributions in binary form must reproduce the above
-*       copyright notice, this list of conditions and the following
-*       disclaimer in the documentation and/or other materials provided
-*       with the distribution.
-*     * Neither the name of The Linux Foundation nor the names of its
-*       contributors may be used to endorse or promote products derived
-*       from this software without specific prior written permission.
-*
-* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
-* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
-* ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
-* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
-* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#include <dlfcn.h>
-#include <cutils/sockets.h>
-#include <cutils/native_handle.h>
-#include <utils/String16.h>
-#include <binder/Parcel.h>
-#include <gralloc_priv.h>
-#include <hardware/hwcomposer.h>
-#include <hardware/hwcomposer_defs.h>
-#include <QService.h>
-
-#include <utils/constants.h>
-#include <utils/debug.h>
-#include <core/buffer_allocator.h>
-#include <private/color_params.h>
-#include "hwc_buffer_allocator.h"
-#include "hwc_buffer_sync_handler.h"
-#include "hwc_session.h"
-#include "hwc_debugger.h"
-
-#define __CLASS__ "HWCColorManager"
-
-namespace sdm {
-
-uint32_t HWCColorManager::Get8BitsARGBColorValue(const PPColorFillParams &params) {
-  uint32_t argb_color = ((params.color.r << 16) & 0xff0000) | ((params.color.g << 8) & 0xff00) |
-                        ((params.color.b) & 0xff);
-  return argb_color;
-}
-
-int HWCColorManager::CreatePayloadFromParcel(const android::Parcel &in, uint32_t *disp_id,
-                                             PPDisplayAPIPayload *sink) {
-  int ret = 0;
-  uint32_t id(0);
-  uint32_t size(0);
-
-  id = UINT32(in.readInt32());
-  size = UINT32(in.readInt32());
-  if (size > 0 && size == in.dataAvail()) {
-    const void *data = in.readInplace(size);
-    const uint8_t *temp = reinterpret_cast<const uint8_t *>(data);
-
-    sink->size = size;
-    sink->payload = const_cast<uint8_t *>(temp);
-    *disp_id = id;
-  } else {
-    DLOGW("Failing size checking, size = %d", size);
-    ret = -EINVAL;
-  }
-
-  return ret;
-}
-
-void HWCColorManager::MarshallStructIntoParcel(const PPDisplayAPIPayload &data,
-                                               android::Parcel *out_parcel) {
-  out_parcel->writeInt32(INT32(data.size));
-  if (data.payload)
-    out_parcel->write(data.payload, data.size);
-}
-
-HWCColorManager *HWCColorManager::CreateColorManager(HWCBufferAllocator * buffer_allocator) {
-  HWCColorManager *color_mgr = new HWCColorManager(buffer_allocator);
-
-  if (color_mgr) {
-    // Load display API interface library. And retrieve color API function tables.
-    DynLib &color_apis_lib = color_mgr->color_apis_lib_;
-    if (color_apis_lib.Open(DISPLAY_API_INTERFACE_LIBRARY_NAME)) {
-      if (!color_apis_lib.Sym(DISPLAY_API_FUNC_TABLES, &color_mgr->color_apis_)) {
-        DLOGE("Fail to retrieve = %s from %s", DISPLAY_API_FUNC_TABLES,
-              DISPLAY_API_INTERFACE_LIBRARY_NAME);
-        delete color_mgr;
-        return NULL;
-      }
-    } else {
-      DLOGW("Unable to load = %s", DISPLAY_API_INTERFACE_LIBRARY_NAME);
-      delete color_mgr;
-      return NULL;
-    }
-    DLOGI("Successfully loaded %s", DISPLAY_API_INTERFACE_LIBRARY_NAME);
-
-    // Load diagclient library and invokes its entry point to pass in display APIs.
-    DynLib &diag_client_lib = color_mgr->diag_client_lib_;
-    if (diag_client_lib.Open(QDCM_DIAG_CLIENT_LIBRARY_NAME)) {
-      if (!diag_client_lib.Sym(INIT_QDCM_DIAG_CLIENT_NAME,
-                               reinterpret_cast<void **>(&color_mgr->qdcm_diag_init_)) ||
-        !diag_client_lib.Sym(DEINIT_QDCM_DIAG_CLIENT_NAME,
-                               reinterpret_cast<void **>(&color_mgr->qdcm_diag_deinit_))) {
-        DLOGE("Fail to retrieve = %s from %s", INIT_QDCM_DIAG_CLIENT_NAME,
-              QDCM_DIAG_CLIENT_LIBRARY_NAME);
-      } else {
-        // invoke Diag Client entry point to initialize.
-        color_mgr->qdcm_diag_init_(color_mgr->color_apis_);
-        DLOGI("Successfully loaded %s and %s and diag_init'ed", DISPLAY_API_INTERFACE_LIBRARY_NAME,
-              QDCM_DIAG_CLIENT_LIBRARY_NAME);
-      }
-    } else {
-      DLOGW("Unable to load = %s", QDCM_DIAG_CLIENT_LIBRARY_NAME);
-      // only QDCM Diag client failed to be loaded and system still should function.
-    }
-  } else {
-    DLOGE("Unable to create HWCColorManager");
-    return NULL;
-  }
-
-  return color_mgr;
-}
-
-HWCColorManager::HWCColorManager(HWCBufferAllocator *buffer_allocator) :
-    buffer_allocator_(buffer_allocator) {
-}
-
-HWCColorManager::~HWCColorManager() {
-}
-
-void HWCColorManager::DestroyColorManager() {
-  if (qdcm_mode_mgr_) {
-    delete qdcm_mode_mgr_;
-  }
-  if (qdcm_diag_deinit_) {
-    qdcm_diag_deinit_();
-  }
-  delete this;
-}
-
-int HWCColorManager::EnableQDCMMode(bool enable, HWCDisplay *hwc_display) {
-  int ret = 0;
-
-  if (!qdcm_mode_mgr_) {
-    qdcm_mode_mgr_ = HWCQDCMModeManager::CreateQDCMModeMgr();
-    if (!qdcm_mode_mgr_) {
-      DLOGE("Unable to create QDCM operating mode manager.");
-      ret = -EFAULT;
-    }
-  }
-
-  if (qdcm_mode_mgr_) {
-    ret = qdcm_mode_mgr_->EnableQDCMMode(enable, hwc_display);
-  }
-
-  return ret;
-}
-
-int HWCColorManager::SetSolidFill(const void *params, bool enable, HWCDisplay *hwc_display) {
-  SCOPE_LOCK(locker_);
-  LayerSolidFill solid_fill_color;
-
-  if (params) {
-    solid_fill_params_ = *reinterpret_cast<const PPColorFillParams *>(params);
-  } else {
-    solid_fill_params_ = PPColorFillParams();
-  }
-
-  if (solid_fill_params_.color.r_bitdepth != solid_fill_params_.color.b_bitdepth
-    || solid_fill_params_.color.r_bitdepth != solid_fill_params_.color.g_bitdepth) {
-    DLOGE("invalid bit depth r %d g %d b %d", solid_fill_params_.color.r_bitdepth,
-        solid_fill_params_.color.g_bitdepth, solid_fill_params_.color.b_bitdepth);
-    return -EINVAL;
-  }
-
-  solid_fill_color.bit_depth = solid_fill_params_.color.r_bitdepth;
-  solid_fill_color.red = solid_fill_params_.color.r;
-  solid_fill_color.blue = solid_fill_params_.color.b;
-  solid_fill_color.green = solid_fill_params_.color.g;
-  solid_fill_color.alpha = 0x3ff;
-
-  if (enable) {
-    LayerRect solid_fill_rect = {
-      FLOAT(solid_fill_params_.rect.x), FLOAT(solid_fill_params_.rect.y),
-      FLOAT(solid_fill_params_.rect.x) + FLOAT(solid_fill_params_.rect.width),
-      FLOAT(solid_fill_params_.rect.y) + FLOAT(solid_fill_params_.rect.height),
-    };
-
-    hwc_display->Perform(HWCDisplayPrimary::SET_QDCM_SOLID_FILL_INFO, &solid_fill_color);
-    hwc_display->Perform(HWCDisplayPrimary::SET_QDCM_SOLID_FILL_RECT, &solid_fill_rect);
-  } else {
-    solid_fill_color.red = 0;
-    solid_fill_color.blue = 0;
-    solid_fill_color.green = 0;
-    solid_fill_color.alpha = 0;
-    hwc_display->Perform(HWCDisplayPrimary::UNSET_QDCM_SOLID_FILL_INFO, &solid_fill_color);
-  }
-
-  return 0;
-}
-
-int HWCColorManager::SetFrameCapture(void *params, bool enable, HWCDisplay *hwc_display) {
-  SCOPE_LOCK(locker_);
-  int ret = 0;
-
-  PPFrameCaptureData *frame_capture_data = reinterpret_cast<PPFrameCaptureData *>(params);
-
-  if (enable) {
-    std::memset(&buffer_info, 0x00, sizeof(buffer_info));
-    hwc_display->GetPanelResolution(&buffer_info.buffer_config.width,
-                                    &buffer_info.buffer_config.height);
-    if (frame_capture_data->input_params.out_pix_format == PP_PIXEL_FORMAT_RGB_888) {
-      buffer_info.buffer_config.format = kFormatRGB888;
-    } else if (frame_capture_data->input_params.out_pix_format == PP_PIXEL_FORMAT_RGB_2101010) {
-      buffer_info.buffer_config.format = kFormatRGBA1010102;
-    } else {
-      DLOGE("Pixel-format: %d NOT support.", frame_capture_data->input_params.out_pix_format);
-      return -EFAULT;
-    }
-
-    buffer_info.buffer_config.buffer_count = 1;
-    buffer_info.alloc_buffer_info.fd = -1;
-    buffer_info.alloc_buffer_info.stride = 0;
-    buffer_info.alloc_buffer_info.size = 0;
-
-    ret = buffer_allocator_->AllocateBuffer(&buffer_info);
-    if (ret != 0) {
-      DLOGE("Buffer allocation failed. ret: %d", ret);
-      return -ENOMEM;
-    } else {
-      void *buffer = mmap(NULL, buffer_info.alloc_buffer_info.size, PROT_READ | PROT_WRITE,
-                          MAP_SHARED, buffer_info.alloc_buffer_info.fd, 0);
-
-      if (buffer == MAP_FAILED) {
-        DLOGE("mmap failed. err = %d", errno);
-        frame_capture_data->buffer = NULL;
-        ret = buffer_allocator_->FreeBuffer(&buffer_info);
-        return -EFAULT;
-      } else {
-        frame_capture_data->buffer = reinterpret_cast<uint8_t *>(buffer);
-        frame_capture_data->buffer_stride = buffer_info.alloc_buffer_info.stride;
-        frame_capture_data->buffer_size = buffer_info.alloc_buffer_info.size;
-      }
-      ret = hwc_display->FrameCaptureAsync(buffer_info, 1);
-      if (ret < 0) {
-        DLOGE("FrameCaptureAsync failed. ret = %d", ret);
-      }
-    }
-  } else {
-    ret = hwc_display->GetFrameCaptureStatus();
-    if (!ret) {
-      if (frame_capture_data->buffer != NULL) {
-        if (munmap(frame_capture_data->buffer, buffer_info.alloc_buffer_info.size) != 0) {
-          DLOGE("munmap failed. err = %d", errno);
-        }
-      }
-      if (buffer_allocator_ != NULL) {
-        std::memset(frame_capture_data, 0x00, sizeof(PPFrameCaptureData));
-        ret = buffer_allocator_->FreeBuffer(&buffer_info);
-        if (ret != 0) {
-          DLOGE("FreeBuffer failed. ret = %d", ret);
-        }
-      }
-    } else {
-      DLOGE("GetFrameCaptureStatus failed. ret = %d", ret);
-    }
-  }
-  return ret;
-}
-
-int HWCColorManager::SetHWDetailedEnhancerConfig(void *params, HWCDisplay *hwc_display) {
-  int err = -1;
-  DisplayDetailEnhancerData de_data;
-
-  PPDETuningCfgData *de_tuning_cfg_data = reinterpret_cast<PPDETuningCfgData*>(params);
-  if (de_tuning_cfg_data->cfg_pending == true) {
-    if (!de_tuning_cfg_data->cfg_en) {
-      de_data.enable = 0;
-    } else {
-      de_data.override_flags = kOverrideDEEnable;
-      de_data.enable = 1;
-
-      if (de_tuning_cfg_data->params.flags & kDeTuningFlagSharpFactor) {
-        de_data.override_flags |= kOverrideDESharpen1;
-        de_data.sharp_factor = de_tuning_cfg_data->params.sharp_factor;
-      }
-
-      if (de_tuning_cfg_data->params.flags & kDeTuningFlagClip) {
-        de_data.override_flags |= kOverrideDEClip;
-        de_data.clip = de_tuning_cfg_data->params.clip;
-      }
-
-      if (de_tuning_cfg_data->params.flags & kDeTuningFlagThrQuiet) {
-        de_data.override_flags |= kOverrideDEThrQuiet;
-        de_data.thr_quiet = de_tuning_cfg_data->params.thr_quiet;
-      }
-
-      if (de_tuning_cfg_data->params.flags & kDeTuningFlagThrDieout) {
-        de_data.override_flags |= kOverrideDEThrDieout;
-        de_data.thr_dieout = de_tuning_cfg_data->params.thr_dieout;
-      }
-
-      if (de_tuning_cfg_data->params.flags & kDeTuningFlagThrLow) {
-        de_data.override_flags |= kOverrideDEThrLow;
-        de_data.thr_low = de_tuning_cfg_data->params.thr_low;
-      }
-
-      if (de_tuning_cfg_data->params.flags & kDeTuningFlagThrHigh) {
-        de_data.override_flags |= kOverrideDEThrHigh;
-        de_data.thr_high = de_tuning_cfg_data->params.thr_high;
-      }
-
-      if (de_tuning_cfg_data->params.flags & kDeTuningFlagContentQualLevel) {
-        switch (de_tuning_cfg_data->params.quality) {
-          case kDeContentQualLow:
-            de_data.quality_level = kContentQualityLow;
-            break;
-          case kDeContentQualMedium:
-            de_data.quality_level = kContentQualityMedium;
-            break;
-          case kDeContentQualHigh:
-            de_data.quality_level = kContentQualityHigh;
-            break;
-          case kDeContentQualUnknown:
-          default:
-            de_data.quality_level = kContentQualityUnknown;
-            break;
-        }
-      }
-    }
-    err = hwc_display->SetDetailEnhancerConfig(de_data);
-    if (err) {
-      DLOGW("SetDetailEnhancerConfig failed. err = %d", err);
-    }
-    de_tuning_cfg_data->cfg_pending = false;
-  }
-  return err;
-}
-
-void HWCColorManager::SetColorModeDetailEnhancer(HWCDisplay *hwc_display) {
-  SCOPE_LOCK(locker_);
-  int err = -1;
-  PPPendingParams pending_action;
-  PPDisplayAPIPayload req_payload;
-
-  pending_action.action = kGetDetailedEnhancerData;
-  pending_action.params = NULL;
-
-  if (hwc_display) {
-    err = hwc_display->ColorSVCRequestRoute(req_payload, NULL, &pending_action);
-    if (!err && pending_action.action == kConfigureDetailedEnhancer) {
-      err = SetHWDetailedEnhancerConfig(pending_action.params, hwc_display);
-    }
-  }
-  return;
-}
-
-int HWCColorManager::SetDetailedEnhancer(void *params, HWCDisplay *hwc_display) {
-  SCOPE_LOCK(locker_);
-  int err = -1;
-  err = SetHWDetailedEnhancerConfig(params, hwc_display);
-  return err;
-}
-
-const HWCQDCMModeManager::ActiveFeatureCMD HWCQDCMModeManager::kActiveFeatureCMD[] = {
-    HWCQDCMModeManager::ActiveFeatureCMD("cabl:on", "cabl:off", "cabl:status", "running"),
-    HWCQDCMModeManager::ActiveFeatureCMD("ad:on", "ad:off", "ad:query:status", "running"),
-    HWCQDCMModeManager::ActiveFeatureCMD("svi:on", "svi:off", "svi:status", "running"),
-};
-
-const char *const HWCQDCMModeManager::kSocketName = "pps";
-const char *const HWCQDCMModeManager::kTagName = "surfaceflinger";
-const char *const HWCQDCMModeManager::kPackageName = "colormanager";
-
-HWCQDCMModeManager *HWCQDCMModeManager::CreateQDCMModeMgr() {
-  HWCQDCMModeManager *mode_mgr = new HWCQDCMModeManager();
-
-  if (!mode_mgr) {
-    DLOGW("No memory to create HWCQDCMModeManager.");
-    return NULL;
-  } else {
-    mode_mgr->socket_fd_ =
-        ::socket_local_client(kSocketName, ANDROID_SOCKET_NAMESPACE_RESERVED, SOCK_STREAM);
-    if (mode_mgr->socket_fd_ < 0) {
-      // it should not be disastrous and we still can grab wakelock in QDCM mode.
-      DLOGW("Unable to connect to dpps socket!");
-    }
-
-    // retrieve system GPU idle timeout value for later to recover.
-    mode_mgr->entry_timeout_ = UINT32(HWCDebugHandler::GetIdleTimeoutMs());
-  }
-
-  return mode_mgr;
-}
-
-HWCQDCMModeManager::~HWCQDCMModeManager() {
-  if (socket_fd_ >= 0)
-    ::close(socket_fd_);
-}
-
-int HWCQDCMModeManager::EnableActiveFeatures(bool enable,
-                                             const HWCQDCMModeManager::ActiveFeatureCMD &cmds,
-                                             bool *was_running) {
-  int ret = 0;
-  ssize_t size = 0;
-  char response[kSocketCMDMaxLength] = {
-      0,
-  };
-
-  if (socket_fd_ < 0) {
-    DLOGW("No socket connection available - assuming dpps is not enabled");
-    return 0;
-  }
-
-  if (!enable) {  // if client requesting to disable it.
-    // query CABL status, if off, no action. keep the status.
-    size = ::write(socket_fd_, cmds.cmd_query_status, strlen(cmds.cmd_query_status));
-    if (size < 0) {
-      DLOGW("Unable to send data over socket %s", ::strerror(errno));
-      ret = -EFAULT;
-    } else {
-      size = ::read(socket_fd_, response, kSocketCMDMaxLength);
-      if (size < 0) {
-        DLOGW("Unable to read data over socket %s", ::strerror(errno));
-        ret = -EFAULT;
-      } else if (!strncmp(response, cmds.running, strlen(cmds.running))) {
-        *was_running = true;
-      }
-    }
-
-    if (*was_running) {  // if was running, it's requested to disable it.
-      size = ::write(socket_fd_, cmds.cmd_off, strlen(cmds.cmd_off));
-      if (size < 0) {
-        DLOGW("Unable to send data over socket %s", ::strerror(errno));
-        ret = -EFAULT;
-      }
-    }
-  } else {  // if was running, need enable it back.
-    if (*was_running) {
-      size = ::write(socket_fd_, cmds.cmd_on, strlen(cmds.cmd_on));
-      if (size < 0) {
-        DLOGW("Unable to send data over socket %s", ::strerror(errno));
-        ret = -EFAULT;
-      }
-    }
-  }
-
-  return ret;
-}
-
-int HWCQDCMModeManager::EnableQDCMMode(bool enable, HWCDisplay *hwc_display) {
-  int ret = 0;
-
-  ret = EnableActiveFeatures((enable ? false : true), kActiveFeatureCMD[kCABLFeature],
-                             &cabl_was_running_);
-
-  // if enter QDCM mode, disable GPU fallback idle timeout.
-  if (hwc_display) {
-    uint32_t timeout = enable ? 0 : entry_timeout_;
-    hwc_display->SetIdleTimeoutMs(timeout);
-  }
-
-  return ret;
-}
-
-}  // namespace sdm
diff --git a/sdm/libs/hwc2/hwc_color_manager.h b/sdm/libs/hwc2/hwc_color_manager.h
deleted file mode 100644
index f88a5bb..0000000
--- a/sdm/libs/hwc2/hwc_color_manager.h
+++ /dev/null
@@ -1,143 +0,0 @@
-/* Copyright (c) 2015-2017, The Linux Foundataion. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without
-* modification, are permitted provided that the following conditions are
-* met:
-*     * Redistributions of source code must retain the above copyright
-*       notice, this list of conditions and the following disclaimer.
-*     * Redistributions in binary form must reproduce the above
-*       copyright notice, this list of conditions and the following
-*       disclaimer in the documentation and/or other materials provided
-*       with the distribution.
-*     * Neither the name of The Linux Foundation nor the names of its
-*       contributors may be used to endorse or promote products derived
-*       from this software without specific prior written permission.
-*
-* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
-* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
-* ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
-* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
-* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*
-*/
-
-#ifndef __HWC_COLOR_MANAGER_H__
-#define __HWC_COLOR_MANAGER_H__
-
-#include <stdlib.h>
-#include <binder/Parcel.h>
-#include <binder/BinderService.h>
-#include <core/sdm_types.h>
-#include <utils/locker.h>
-
-namespace sdm {
-
-// This macro defines name for display APIs interface wrapper library.
-// This macro shall be used to load library using dlopen().
-#define DISPLAY_API_INTERFACE_LIBRARY_NAME "libsdm-disp-vndapis.so"
-
-// This macro defines variable name of display color APIs function tables
-// This macro shall be used to specify name of the variable in dlsym().
-#define DISPLAY_API_FUNC_TABLES "display_color_apis_ftables"
-#define QDCM_DIAG_CLIENT_LIBRARY_NAME "libsdm-diag.so"
-#define INIT_QDCM_DIAG_CLIENT_NAME "QDCMDiagInit"
-#define DEINIT_QDCM_DIAG_CLIENT_NAME "QDCMDiagDeInit"
-
-typedef int (*QDCMDiagInit)(void *ftables);
-
-typedef int (*QDCMDiagDeInit)(void);
-
-// Class to encapsulte all details of managing QDCM operating mode.
-class HWCQDCMModeManager {
- public:
-  static const uint32_t kSocketCMDMaxLength = 4096;
-  static const uint32_t kFullWakeLock = 0x0000001a;
-  static const uint32_t kAcquireCauseWakeup = 0x10000000;
-  static const uint32_t kONAfterRelease = 0x20000000;
-  enum ActiveFeatureID {
-    kCABLFeature,
-    kADFeature,
-    kSVIFeature,
-    kMaxNumActiveFeature,
-  };
-
-  struct ActiveFeatureCMD {
-    const char *cmd_on = NULL;
-    const char *cmd_off = NULL;
-    const char *cmd_query_status = NULL;
-    const char *running = NULL;
-    ActiveFeatureCMD(const char *arg1, const char *arg2, const char *arg3, const char *arg4)
-        : cmd_on(arg1), cmd_off(arg2), cmd_query_status(arg3), running(arg4) {}
-  };
-
-  static const ActiveFeatureCMD kActiveFeatureCMD[kMaxNumActiveFeature];
-
- public:
-  static HWCQDCMModeManager *CreateQDCMModeMgr();
-  ~HWCQDCMModeManager();
-  int EnableQDCMMode(bool enable, HWCDisplay *hwc_display);
-
- protected:
-  bool SendSocketCmd();
-  int AcquireAndroidWakeLock(bool enable);
-  int EnableActiveFeatures(bool enable);
-  int EnableActiveFeatures(bool enable, const ActiveFeatureCMD &cmds, bool *was_running);
-
- private:
-  bool cabl_was_running_ = false;
-  int socket_fd_ = -1;
-  android::sp<android::IBinder> wakelock_token_ = NULL;
-  uint32_t entry_timeout_ = 0;
-  static const char *const kSocketName;
-  static const char *const kTagName;
-  static const char *const kPackageName;
-};
-
-// Class to encapsulte all HWC/OS specific behaviours for ColorManager.
-class HWCColorManager {
- public:
-  static const int kNumSolidFillLayers = 2;
-  static HWCColorManager *CreateColorManager(HWCBufferAllocator *buffer_allocator);
-  static int CreatePayloadFromParcel(const android::Parcel &in, uint32_t *disp_id,
-                                     PPDisplayAPIPayload *sink);
-  static void MarshallStructIntoParcel(const PPDisplayAPIPayload &data,
-                                       android::Parcel *out_parcel);
-
-  explicit HWCColorManager(HWCBufferAllocator *buffer_allocator);
-  ~HWCColorManager();
-  void DestroyColorManager();
-  int EnableQDCMMode(bool enable, HWCDisplay *hwc_display);
-  int SetSolidFill(const void *params, bool enable, HWCDisplay *hwc_display);
-  int SetFrameCapture(void *params, bool enable, HWCDisplay *hwc_display);
-  int SetDetailedEnhancer(void *params, HWCDisplay *hwc_display);
-  void SetColorModeDetailEnhancer(HWCDisplay *hwc_display);
-  int SetHWDetailedEnhancerConfig(void *params, HWCDisplay *hwc_display);
-
- protected:
-  int CreateSolidFillLayers(HWCDisplay *hwc_display);
-  void DestroySolidFillLayers();
-  static uint32_t Get8BitsARGBColorValue(const PPColorFillParams &params);
-
- private:
-  DynLib color_apis_lib_;
-  DynLib diag_client_lib_;
-  void *color_apis_ = NULL;
-  QDCMDiagInit qdcm_diag_init_ = NULL;
-  QDCMDiagDeInit qdcm_diag_deinit_ = NULL;
-  HWCQDCMModeManager *qdcm_mode_mgr_ = NULL;
-
-  PPColorFillParams solid_fill_params_;
-  HWCBufferAllocator *buffer_allocator_ = NULL;
-  BufferInfo buffer_info;
-  Locker locker_;
-};
-
-}  // namespace sdm
-
-#endif  // __HWC_COLOR_MANAGER_H__
diff --git a/sdm/libs/hwc2/hwc_debugger.cpp b/sdm/libs/hwc2/hwc_debugger.cpp
deleted file mode 100644
index e92f170..0000000
--- a/sdm/libs/hwc2/hwc_debugger.cpp
+++ /dev/null
@@ -1,240 +0,0 @@
-/*
-* Copyright (c) 2014 - 2018, The Linux Foundation. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without
-* modification, are permitted provided that the following conditions are
-* met:
-*     * Redistributions of source code must retain the above copyright
-*       notice, this list of conditions and the following disclaimer.
-*     * Redistributions in binary form must reproduce the above
-*       copyright notice, this list of conditions and the following
-*       disclaimer in the documentation and/or other materials provided
-*       with the distribution.
-*     * Neither the name of The Linux Foundation nor the names of its
-*       contributors may be used to endorse or promote products derived
-*       from this software without specific prior written permission.
-*
-* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
-* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
-* ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
-* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
-* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#include <utils/constants.h>
-#include <cutils/properties.h>
-#include <utils/debug.h>
-
-#include "hwc_debugger.h"
-
-namespace sdm {
-
-HWCDebugHandler HWCDebugHandler::debug_handler_;
-
-HWCDebugHandler::HWCDebugHandler() {
-  DebugHandler::Set(HWCDebugHandler::Get());
-}
-
-void HWCDebugHandler::DebugAll(bool enable, int verbose_level) {
-  if (enable) {
-    debug_handler_.log_mask_ = 0x7FFFFFFF;
-    if (verbose_level) {
-      // Enable verbose scalar logs only when explicitly enabled
-      debug_handler_.log_mask_[kTagScalar] = 0;
-    }
-    debug_handler_.verbose_level_ = verbose_level;
-  } else {
-    debug_handler_.log_mask_ = 0x1;   // kTagNone should always be printed.
-    debug_handler_.verbose_level_ = 0;
-  }
-
-  DebugHandler::SetLogMask(debug_handler_.log_mask_);
-}
-
-void HWCDebugHandler::DebugResources(bool enable, int verbose_level) {
-  if (enable) {
-    debug_handler_.log_mask_[kTagResources] = 1;
-    debug_handler_.verbose_level_ = verbose_level;
-  } else {
-    debug_handler_.log_mask_[kTagResources] = 0;
-    debug_handler_.verbose_level_ = 0;
-  }
-
-  DebugHandler::SetLogMask(debug_handler_.log_mask_);
-}
-
-void HWCDebugHandler::DebugStrategy(bool enable, int verbose_level) {
-  if (enable) {
-    debug_handler_.log_mask_[kTagStrategy] = 1;
-    debug_handler_.verbose_level_ = verbose_level;
-  } else {
-    debug_handler_.log_mask_[kTagStrategy] = 0;
-    debug_handler_.verbose_level_ = 0;
-  }
-
-  DebugHandler::SetLogMask(debug_handler_.log_mask_);
-}
-
-void HWCDebugHandler::DebugCompManager(bool enable, int verbose_level) {
-  if (enable) {
-    debug_handler_.log_mask_[kTagCompManager] = 1;
-    debug_handler_.verbose_level_ = verbose_level;
-  } else {
-    debug_handler_.log_mask_[kTagCompManager] = 0;
-    debug_handler_.verbose_level_ = 0;
-  }
-
-  DebugHandler::SetLogMask(debug_handler_.log_mask_);
-}
-
-void HWCDebugHandler::DebugDriverConfig(bool enable, int verbose_level) {
-  if (enable) {
-    debug_handler_.log_mask_[kTagDriverConfig] = 1;
-    debug_handler_.verbose_level_ = verbose_level;
-  } else {
-    debug_handler_.log_mask_[kTagDriverConfig] = 0;
-    debug_handler_.verbose_level_ = 0;
-  }
-
-  DebugHandler::SetLogMask(debug_handler_.log_mask_);
-}
-
-void HWCDebugHandler::DebugRotator(bool enable, int verbose_level) {
-  if (enable) {
-    debug_handler_.log_mask_[kTagRotator] = 1;
-    debug_handler_.verbose_level_ = verbose_level;
-  } else {
-    debug_handler_.log_mask_[kTagRotator] = 0;
-    debug_handler_.verbose_level_ = 0;
-  }
-
-  DebugHandler::SetLogMask(debug_handler_.log_mask_);
-}
-
-void HWCDebugHandler::DebugScalar(bool enable, int verbose_level) {
-  if (enable) {
-    debug_handler_.log_mask_[kTagScalar] = 1;
-    debug_handler_.verbose_level_ = verbose_level;
-  } else {
-    debug_handler_.log_mask_[kTagScalar] = 0;
-    debug_handler_.verbose_level_ = 0;
-  }
-
-  DebugHandler::SetLogMask(debug_handler_.log_mask_);
-}
-
-void HWCDebugHandler::DebugQdcm(bool enable, int verbose_level) {
-  if (enable) {
-    debug_handler_.log_mask_[kTagQDCM] = 1;
-    debug_handler_.verbose_level_ = verbose_level;
-  } else {
-    debug_handler_.log_mask_[kTagQDCM] = 0;
-    debug_handler_.verbose_level_ = 0;
-  }
-
-  DebugHandler::SetLogMask(debug_handler_.log_mask_);
-}
-
-void HWCDebugHandler::DebugClient(bool enable, int verbose_level) {
-  if (enable) {
-    debug_handler_.log_mask_[kTagClient] = 1;
-    debug_handler_.verbose_level_ = verbose_level;
-  } else {
-    debug_handler_.log_mask_[kTagClient] = 0;
-    debug_handler_.verbose_level_ = 0;
-  }
-
-  DebugHandler::SetLogMask(debug_handler_.log_mask_);
-}
-
-void HWCDebugHandler::DebugDisplay(bool enable, int verbose_level) {
-  if (enable) {
-    debug_handler_.log_mask_[kTagDisplay] = 1;
-    debug_handler_.verbose_level_ = verbose_level;
-  } else {
-    debug_handler_.log_mask_[kTagDisplay] = 0;
-    debug_handler_.verbose_level_ = 0;
-  }
-
-  DebugHandler::SetLogMask(debug_handler_.log_mask_);
-}
-
-void HWCDebugHandler::Error(const char *format, ...) {
-  va_list list;
-  va_start(list, format);
-  __android_log_vprint(ANDROID_LOG_ERROR, LOG_TAG, format, list);
-}
-
-void HWCDebugHandler::Warning(const char *format, ...) {
-  va_list list;
-  va_start(list, format);
-  __android_log_vprint(ANDROID_LOG_WARN, LOG_TAG, format, list);
-}
-
-void HWCDebugHandler::Info(const char *format, ...) {
-  va_list list;
-  va_start(list, format);
-  __android_log_vprint(ANDROID_LOG_INFO, LOG_TAG, format, list);
-}
-
-void HWCDebugHandler::Debug(const char *format, ...) {
-  va_list list;
-  va_start(list, format);
-  __android_log_vprint(ANDROID_LOG_DEBUG, LOG_TAG, format, list);
-}
-
-void HWCDebugHandler::Verbose(const char *format, ...) {
-  if (debug_handler_.verbose_level_) {
-    va_list list;
-    va_start(list, format);
-    __android_log_vprint(ANDROID_LOG_VERBOSE, LOG_TAG, format, list);
-  }
-}
-
-void HWCDebugHandler::BeginTrace(const char *class_name, const char *function_name,
-                                 const char *custom_string) {
-  if (atrace_is_tag_enabled(ATRACE_TAG)) {
-    char name[PATH_MAX] = {0};
-    snprintf(name, sizeof(name), "%s::%s::%s", class_name, function_name, custom_string);
-    atrace_begin(ATRACE_TAG, name);
-  }
-}
-
-void HWCDebugHandler::EndTrace() {
-  atrace_end(ATRACE_TAG);
-}
-
-int  HWCDebugHandler::GetIdleTimeoutMs() {
-  int value = IDLE_TIMEOUT_DEFAULT_MS;
-  debug_handler_.GetProperty(IDLE_TIME_PROP, &value);
-
-  return value;
-}
-
-int HWCDebugHandler::GetProperty(const char *property_name, int *value) {
-  char property[PROPERTY_VALUE_MAX];
-
-  if (property_get(property_name, property, NULL) > 0) {
-    *value = atoi(property);
-    return kErrorNone;
-  }
-
-  return kErrorNotSupported;
-}
-
-int HWCDebugHandler::GetProperty(const char *property_name, char *value) {
-  if (property_get(property_name, value, NULL) > 0) {
-    return kErrorNone;
-  }
-
-  return kErrorNotSupported;
-}
-
-}  // namespace sdm
-
diff --git a/sdm/libs/hwc2/hwc_debugger.h b/sdm/libs/hwc2/hwc_debugger.h
deleted file mode 100644
index 7ebca8a..0000000
--- a/sdm/libs/hwc2/hwc_debugger.h
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
-* Copyright (c) 2014 - 2018, The Linux Foundation. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without
-* modification, are permitted provided that the following conditions are
-* met:
-*     * Redistributions of source code must retain the above copyright
-*       notice, this list of conditions and the following disclaimer.
-*     * Redistributions in binary form must reproduce the above
-*       copyright notice, this list of conditions and the following
-*       disclaimer in the documentation and/or other materials provided
-*       with the distribution.
-*     * Neither the name of The Linux Foundation nor the names of its
-*       contributors may be used to endorse or promote products derived
-*       from this software without specific prior written permission.
-*
-* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
-* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
-* ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
-* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
-* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#ifndef __HWC_DEBUGGER_H__
-#define __HWC_DEBUGGER_H__
-
-#define ATRACE_TAG (ATRACE_TAG_GRAPHICS | ATRACE_TAG_HAL)
-
-#include <core/sdm_types.h>
-#include <debug_handler.h>
-#include <log/log.h>
-#include <utils/Trace.h>
-#include <bitset>
-
-namespace sdm {
-
-using display::DebugHandler;
-
-class HWCDebugHandler : public DebugHandler {
- public:
-  HWCDebugHandler();
-  static inline DebugHandler* Get() { return &debug_handler_; }
-  static const char* DumpDir() { return "/data/vendor/display"; }
-
-  static void DebugAll(bool enable, int verbose_level);
-  static void DebugResources(bool enable, int verbose_level);
-  static void DebugStrategy(bool enable, int verbose_level);
-  static void DebugCompManager(bool enable, int verbose_level);
-  static void DebugDriverConfig(bool enable, int verbose_level);
-  static void DebugRotator(bool enable, int verbose_level);
-  static void DebugScalar(bool enable, int verbose_level);
-  static void DebugQdcm(bool enable, int verbose_level);
-  static void DebugClient(bool enable, int verbose_level);
-  static void DebugDisplay(bool enable, int verbose_level);
-  static int  GetIdleTimeoutMs();
-
-  virtual void Error(const char *format, ...);
-  virtual void Warning(const char *format, ...);
-  virtual void Info(const char *format, ...);
-  virtual void Debug(const char *format, ...);
-  virtual void Verbose(const char *format, ...);
-  virtual void BeginTrace(const char *class_name, const char *function_name,
-                          const char *custom_string);
-  virtual void EndTrace();
-  virtual int GetProperty(const char *property_name, int *value);
-  virtual int GetProperty(const char *property_name, char *value);
-
- private:
-  static HWCDebugHandler debug_handler_;
-  std::bitset<32> log_mask_;
-  int32_t verbose_level_;
-};
-
-}  // namespace sdm
-
-#endif  // __HWC_DEBUGGER_H__
-
diff --git a/sdm/libs/hwc2/hwc_display.cpp b/sdm/libs/hwc2/hwc_display.cpp
deleted file mode 100644
index 41e6f8a..0000000
--- a/sdm/libs/hwc2/hwc_display.cpp
+++ /dev/null
@@ -1,2157 +0,0 @@
-/*
- * Copyright (c) 2014-2018, The Linux Foundation. All rights reserved.
- * Not a Contribution.
- *
- * Copyright 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 <cutils/properties.h>
-#include <errno.h>
-#include <math.h>
-#include <sync/sync.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <utils/constants.h>
-#include <utils/debug.h>
-#include <utils/formats.h>
-#include <utils/rect.h>
-#include <qd_utils.h>
-
-#include <algorithm>
-#include <iomanip>
-#include <map>
-#include <sstream>
-#include <string>
-#include <utility>
-#include <vector>
-
-#include "hwc_display.h"
-#include "hwc_debugger.h"
-#include "hwc_tonemapper.h"
-#include "hwc_session.h"
-
-#ifdef QTI_BSP
-#include <hardware/display_defs.h>
-#endif
-
-#define __CLASS__ "HWCDisplay"
-
-namespace sdm {
-
-// This weight function is needed because the color primaries are not sorted by gamut size
-static ColorPrimaries WidestPrimaries(ColorPrimaries p1, ColorPrimaries p2) {
-  int weight = 10;
-  int lp1 = p1, lp2 = p2;
-  // TODO(user) add weight to other wide gamut primaries
-  if (lp1 == ColorPrimaries_BT2020) {
-    lp1 *= weight;
-  }
-  if (lp1 == ColorPrimaries_BT2020) {
-    lp2 *= weight;
-  }
-  if (lp1 >= lp2) {
-    return p1;
-  } else {
-    return p2;
-  }
-}
-
-HWCColorMode::HWCColorMode(DisplayInterface *display_intf) : display_intf_(display_intf) {}
-
-HWC2::Error HWCColorMode::Init() {
-  PopulateColorModes();
-  return ApplyDefaultColorMode();
-}
-
-HWC2::Error HWCColorMode::DeInit() {
-  color_mode_transform_map_.clear();
-  return HWC2::Error::None;
-}
-
-uint32_t HWCColorMode::GetColorModeCount() {
-  uint32_t count = UINT32(color_mode_transform_map_.size());
-  DLOGI("Supported color mode count = %d", count);
-
-  return std::max(1U, count);
-}
-
-HWC2::Error HWCColorMode::GetColorModes(uint32_t *out_num_modes,
-                                        android_color_mode_t *out_modes) {
-  auto it = color_mode_transform_map_.begin();
-  *out_num_modes = std::min(*out_num_modes, UINT32(color_mode_transform_map_.size()));
-  for (uint32_t i = 0; i < *out_num_modes; it++, i++) {
-    out_modes[i] = it->first;
-    DLOGI("Supports color mode[%d] = %d", i, it->first);
-  }
-
-  return HWC2::Error::None;
-}
-
-HWC2::Error HWCColorMode::SetColorMode(android_color_mode_t mode) {
-  DTRACE_SCOPED();
-  // first mode in 2D matrix is the mode (identity)
-  if (mode < HAL_COLOR_MODE_NATIVE || mode > HAL_COLOR_MODE_DISPLAY_P3) {
-    DLOGE("Could not find mode: %d", mode);
-    return HWC2::Error::BadParameter;
-  }
-  if (color_mode_transform_map_.find(mode) == color_mode_transform_map_.end()) {
-    return HWC2::Error::Unsupported;
-  }
-
-  auto status = HandleColorModeTransform(mode, current_color_transform_, color_matrix_);
-  if (status != HWC2::Error::None) {
-    DLOGE("failed for mode = %d", mode);
-  }
-
-  DLOGV_IF(kTagClient, "Color mode %d successfully set.", mode);
-  return status;
-}
-
-HWC2::Error HWCColorMode::SetColorModeById(int32_t color_mode_id) {
-  DLOGI("Applying mode: %d", color_mode_id);
-  DisplayError error = display_intf_->SetColorModeById(color_mode_id);
-  if (error != kErrorNone) {
-    DLOGI_IF(kTagClient, "Failed to apply mode: %d", color_mode_id);
-    return HWC2::Error::BadParameter;
-  }
-  return HWC2::Error::None;
-}
-
-HWC2::Error HWCColorMode::RestoreColorTransform() {
-  DisplayError error = display_intf_->SetColorTransform(kColorTransformMatrixCount, color_matrix_);
-  if (error != kErrorNone) {
-    DLOGE("Failed to set Color Transform");
-    return HWC2::Error::BadParameter;
-  }
-
-  return HWC2::Error::None;
-}
-
-HWC2::Error HWCColorMode::SetColorTransform(const float *matrix, android_color_transform_t hint) {
-  DTRACE_SCOPED();
-  double color_matrix[kColorTransformMatrixCount] = {0};
-  CopyColorTransformMatrix(matrix, color_matrix);
-
-  auto status = HandleColorModeTransform(current_color_mode_, hint, color_matrix);
-  if (status != HWC2::Error::None) {
-    DLOGE("failed for hint = %d", hint);
-  }
-
-  return status;
-}
-
-HWC2::Error HWCColorMode::HandleColorModeTransform(android_color_mode_t mode,
-                                                   android_color_transform_t hint,
-                                                   const double *matrix) {
-  android_color_transform_t transform_hint = hint;
-  std::string color_mode_transform;
-  bool use_matrix = false;
-  if (hint != HAL_COLOR_TRANSFORM_ARBITRARY_MATRIX) {
-    // if the mode + transfrom request from HWC matches one mode in SDM, set that
-    if (color_mode_transform.empty()) {
-      transform_hint = HAL_COLOR_TRANSFORM_IDENTITY;
-      use_matrix = true;
-    } else {
-      color_mode_transform = color_mode_transform_map_[mode][hint];
-    }
-  } else {
-    use_matrix = true;
-    transform_hint = HAL_COLOR_TRANSFORM_IDENTITY;
-  }
-
-  // if the mode count is 1, then only native mode is supported, so just apply matrix w/o
-  // setting mode
-  if (color_mode_transform_map_.size() > 1U && current_color_mode_ != mode) {
-    color_mode_transform = color_mode_transform_map_[mode][transform_hint];
-    DisplayError error = display_intf_->SetColorMode(color_mode_transform);
-    if (error != kErrorNone) {
-      DLOGE("Failed to set color_mode  = %d transform_hint = %d", mode, hint);
-      // failure to force client composition
-      return HWC2::Error::Unsupported;
-    }
-    DLOGI("Setting Color Mode = %d Transform Hint = %d Success", mode, hint);
-  }
-
-  if (use_matrix) {
-    DisplayError error = display_intf_->SetColorTransform(kColorTransformMatrixCount, matrix);
-    if (error != kErrorNone) {
-      DLOGE("Failed to set Color Transform Matrix");
-      // failure to force client composition
-      return HWC2::Error::Unsupported;
-    }
-  }
-
-  current_color_mode_ = mode;
-  current_color_transform_ = hint;
-  CopyColorTransformMatrix(matrix, color_matrix_);
-
-  return HWC2::Error::None;
-}
-
-void HWCColorMode::PopulateColorModes() {
-  uint32_t color_mode_count = 0;
-  // SDM returns modes which is string combination of mode + transform.
-  DisplayError error = display_intf_->GetColorModeCount(&color_mode_count);
-  if (error != kErrorNone || (color_mode_count == 0)) {
-    DLOGW("GetColorModeCount failed, use native color mode");
-    PopulateTransform(HAL_COLOR_MODE_NATIVE, "native", "identity");
-    return;
-  }
-
-  DLOGV_IF(kTagClient, "Color Modes supported count = %d", color_mode_count);
-
-  const std::string color_transform = "identity";
-  std::vector<std::string> color_modes(color_mode_count);
-  error = display_intf_->GetColorModes(&color_mode_count, &color_modes);
-  for (uint32_t i = 0; i < color_mode_count; i++) {
-    std::string &mode_string = color_modes.at(i);
-    DLOGV_IF(kTagClient, "Color Mode[%d] = %s", i, mode_string.c_str());
-    AttrVal attr;
-    error = display_intf_->GetColorModeAttr(mode_string, &attr);
-    std::string color_gamut, dynamic_range, pic_quality;
-    if (!attr.empty()) {
-      for (auto &it : attr) {
-        if (it.first.find(kColorGamutAttribute) != std::string::npos) {
-          color_gamut = it.second;
-        } else if (it.first.find(kDynamicRangeAttribute) != std::string::npos) {
-          dynamic_range = it.second;
-        } else if (it.first.find(kPictureQualityAttribute) != std::string::npos) {
-          pic_quality = it.second;
-        }
-      }
-
-      DLOGV_IF(kTagClient, "color_gamut : %s, dynamic_range : %s, pic_quality : %s",
-               color_gamut.c_str(), dynamic_range.c_str(), pic_quality.c_str());
-
-      if (dynamic_range == kHdr) {
-        continue;
-      }
-      if ((color_gamut == kNative) &&
-          (pic_quality.empty() || pic_quality == kStandard)) {
-        PopulateTransform(HAL_COLOR_MODE_NATIVE, mode_string, color_transform);
-      } else if ((color_gamut == kSrgb) &&
-                 (pic_quality.empty() || pic_quality == kStandard)) {
-        PopulateTransform(HAL_COLOR_MODE_SRGB, mode_string, color_transform);
-      } else if ((color_gamut == kDcip3) &&
-                 (pic_quality.empty() || pic_quality == kStandard)) {
-        PopulateTransform(HAL_COLOR_MODE_DISPLAY_P3, mode_string, color_transform);
-      } else if ((color_gamut == kDisplayP3) &&
-                 (pic_quality.empty() || pic_quality == kStandard)) {
-        PopulateTransform(HAL_COLOR_MODE_DISPLAY_P3, mode_string, color_transform);
-      }
-    }
-
-    // Look at the mode name, if no color gamut is found
-    if (color_gamut.empty()) {
-      if (mode_string.find("hal_native") != std::string::npos) {
-        PopulateTransform(HAL_COLOR_MODE_NATIVE, mode_string, mode_string);
-      } else if (mode_string.find("hal_srgb") != std::string::npos) {
-        PopulateTransform(HAL_COLOR_MODE_SRGB, mode_string, mode_string);
-      } else if (mode_string.find("hal_adobe") != std::string::npos) {
-        PopulateTransform(HAL_COLOR_MODE_ADOBE_RGB, mode_string, mode_string);
-      } else if (mode_string.find("hal_dci_p3") != std::string::npos) {
-        PopulateTransform(HAL_COLOR_MODE_DCI_P3, mode_string, mode_string);
-      } else if (mode_string.find("hal_display_p3") != std::string::npos) {
-        PopulateTransform(HAL_COLOR_MODE_DISPLAY_P3, mode_string, mode_string);
-      }
-    }
-  }
-}
-
-void HWCColorMode::PopulateTransform(const android_color_mode_t &mode,
-                                     const std::string &color_mode,
-                                     const std::string &color_transform) {
-  // TODO(user): Check the substring from QDCM
-  if (color_transform.find("identity") != std::string::npos) {
-    color_mode_transform_map_[mode][HAL_COLOR_TRANSFORM_IDENTITY] = color_mode;
-  } else if (color_transform.find("arbitrary") != std::string::npos) {
-    // no color mode for arbitrary
-  } else if (color_transform.find("inverse") != std::string::npos) {
-    color_mode_transform_map_[mode][HAL_COLOR_TRANSFORM_VALUE_INVERSE] = color_mode;
-  } else if (color_transform.find("grayscale") != std::string::npos) {
-    color_mode_transform_map_[mode][HAL_COLOR_TRANSFORM_GRAYSCALE] = color_mode;
-  } else if (color_transform.find("correct_protonopia") != std::string::npos) {
-    color_mode_transform_map_[mode][HAL_COLOR_TRANSFORM_CORRECT_PROTANOPIA] = color_mode;
-  } else if (color_transform.find("correct_deuteranopia") != std::string::npos) {
-    color_mode_transform_map_[mode][HAL_COLOR_TRANSFORM_CORRECT_DEUTERANOPIA] = color_mode;
-  } else if (color_transform.find("correct_tritanopia") != std::string::npos) {
-    color_mode_transform_map_[mode][HAL_COLOR_TRANSFORM_CORRECT_TRITANOPIA] = color_mode;
-  } else {
-    color_mode_transform_map_[mode][HAL_COLOR_TRANSFORM_IDENTITY] = color_mode;
-  }
-}
-
-HWC2::Error HWCColorMode::ApplyDefaultColorMode() {
-  android_color_mode_t color_mode = HAL_COLOR_MODE_NATIVE;
-  if (color_mode_transform_map_.size() == 1U) {
-    color_mode = color_mode_transform_map_.begin()->first;
-  } else if (color_mode_transform_map_.size() > 1U) {
-    std::string default_color_mode;
-    bool found = false;
-    DisplayError error = display_intf_->GetDefaultColorMode(&default_color_mode);
-    if (error == kErrorNone) {
-      // get the default mode corresponding android_color_mode_t
-      for (auto &it_mode : color_mode_transform_map_) {
-        for (auto &it : it_mode.second) {
-          if (it.second == default_color_mode) {
-            found = true;
-            break;
-          }
-        }
-        if (found) {
-          color_mode = it_mode.first;
-          break;
-        }
-      }
-    }
-
-    // return the first andrid_color_mode_t when we encouter if not found
-    if (!found) {
-      color_mode = color_mode_transform_map_.begin()->first;
-    }
-  }
-  return SetColorMode(color_mode);
-}
-
-void HWCColorMode::Dump(std::ostringstream* os) {
-  *os << "color modes supported: ";
-  for (auto it : color_mode_transform_map_) {
-    *os << it.first <<" ";
-  }
-  *os << "current mode: " << current_color_mode_ << std::endl;
-  *os << "current transform: ";
-  for (uint32_t i = 0; i < kColorTransformMatrixCount; i++) {
-    if (i % 4 == 0) {
-     *os << std::endl;
-    }
-    *os << std::fixed << std::setprecision(2) << std::setw(6) << std::setfill(' ')
-        << color_matrix_[i] << " ";
-  }
-  *os << std::endl;
-}
-
-HWCDisplay::HWCDisplay(CoreInterface *core_intf, HWCCallbacks *callbacks, DisplayType type,
-                       hwc2_display_t id, bool needs_blit, qService::QService *qservice,
-                       DisplayClass display_class, BufferAllocator *buffer_allocator)
-    : core_intf_(core_intf),
-      callbacks_(callbacks),
-      type_(type),
-      id_(id),
-      needs_blit_(needs_blit),
-      qservice_(qservice),
-      display_class_(display_class) {
-  buffer_allocator_ = static_cast<HWCBufferAllocator *>(buffer_allocator);
-}
-
-int HWCDisplay::Init() {
-  DisplayError error = core_intf_->CreateDisplay(type_, this, &display_intf_);
-  if (error != kErrorNone) {
-    DLOGE("Display create failed. Error = %d display_type %d event_handler %p disp_intf %p", error,
-          type_, this, &display_intf_);
-    return -EINVAL;
-  }
-
-  validated_ = false;
-  HWCDebugHandler::Get()->GetProperty(DISABLE_HDR, &disable_hdr_handling_);
-  if (disable_hdr_handling_) {
-    DLOGI("HDR Handling disabled");
-  }
-
-  int property_swap_interval = 1;
-  HWCDebugHandler::Get()->GetProperty(ZERO_SWAP_INTERVAL, &property_swap_interval);
-  if (property_swap_interval == 0) {
-    swap_interval_zero_ = true;
-  }
-
-  client_target_ = new HWCLayer(id_, buffer_allocator_);
-
-  int blit_enabled = 0;
-  HWCDebugHandler::Get()->GetProperty(DISABLE_BLIT_COMPOSITION_PROP, &blit_enabled);
-  if (needs_blit_ && blit_enabled) {
-    // TODO(user): Add blit engine when needed
-  }
-
-  error = display_intf_->GetNumVariableInfoConfigs(&num_configs_);
-  if (error != kErrorNone) {
-    DLOGE("Getting config count failed. Error = %d", error);
-    return -EINVAL;
-  }
-
-  tone_mapper_ = new HWCToneMapper(buffer_allocator_);
-
-  display_intf_->GetRefreshRateRange(&min_refresh_rate_, &max_refresh_rate_);
-  current_refresh_rate_ = max_refresh_rate_;
-
-  GetUnderScanConfig();
-  DLOGI("Display created with id: %d", id_);
-
-  return 0;
-}
-
-int HWCDisplay::Deinit() {
-  DisplayError error = core_intf_->DestroyDisplay(display_intf_);
-  if (error != kErrorNone) {
-    DLOGE("Display destroy failed. Error = %d", error);
-    return -EINVAL;
-  }
-
-  delete client_target_;
-  for (auto hwc_layer : layer_set_) {
-    delete hwc_layer;
-  }
-
-  if (color_mode_) {
-    color_mode_->DeInit();
-    delete color_mode_;
-  }
-
-  delete tone_mapper_;
-  tone_mapper_ = nullptr;
-
-  return 0;
-}
-
-// LayerStack operations
-HWC2::Error HWCDisplay::CreateLayer(hwc2_layer_t *out_layer_id) {
-  HWCLayer *layer = *layer_set_.emplace(new HWCLayer(id_, buffer_allocator_));
-  layer_map_.emplace(std::make_pair(layer->GetId(), layer));
-  *out_layer_id = layer->GetId();
-  geometry_changes_ |= GeometryChanges::kAdded;
-  validated_ = false;
-  layer_stack_invalid_ = true;
-
-  return HWC2::Error::None;
-}
-
-HWCLayer *HWCDisplay::GetHWCLayer(hwc2_layer_t layer_id) {
-  const auto map_layer = layer_map_.find(layer_id);
-  if (map_layer == layer_map_.end()) {
-    DLOGE("[%" PRIu64 "] GetLayer(%" PRIu64 ") failed: no such layer", id_, layer_id);
-    return nullptr;
-  } else {
-    return map_layer->second;
-  }
-}
-
-HWC2::Error HWCDisplay::DestroyLayer(hwc2_layer_t layer_id) {
-  const auto map_layer = layer_map_.find(layer_id);
-  if (map_layer == layer_map_.end()) {
-    DLOGE("[%" PRIu64 "] destroyLayer(%" PRIu64 ") failed: no such layer", id_, layer_id);
-    return HWC2::Error::BadLayer;
-  }
-  const auto layer = map_layer->second;
-  layer_map_.erase(map_layer);
-  const auto z_range = layer_set_.equal_range(layer);
-  for (auto current = z_range.first; current != z_range.second; ++current) {
-    if (*current == layer) {
-      current = layer_set_.erase(current);
-      delete layer;
-      break;
-    }
-  }
-
-  geometry_changes_ |= GeometryChanges::kRemoved;
-  validated_ = false;
-  layer_stack_invalid_ = true;
-
-  return HWC2::Error::None;
-}
-
-
-void HWCDisplay::BuildLayerStack() {
-  layer_stack_ = LayerStack();
-  display_rect_ = LayerRect();
-  metadata_refresh_rate_ = 0;
-  auto working_primaries = ColorPrimaries_BT709_5;
-  bool secure_display_active = false;
-  layer_stack_.flags.animating = animating_;
-
-  uint32_t color_mode_count = 0;
-  display_intf_->GetColorModeCount(&color_mode_count);
-
-  bool extended_range = false;
-
-  // Add one layer for fb target
-  // TODO(user): Add blit target layers
-  for (auto hwc_layer : layer_set_) {
-    // Reset layer data which SDM may change
-    hwc_layer->ResetPerFrameData();
-
-    Layer *layer = hwc_layer->GetSDMLayer();
-    layer->flags = {};   // Reset earlier flags
-    if (hwc_layer->GetClientRequestedCompositionType() == HWC2::Composition::Client) {
-      layer->flags.skip = true;
-    } else if (hwc_layer->GetClientRequestedCompositionType() == HWC2::Composition::SolidColor) {
-      layer->flags.solid_fill = true;
-    }
-
-    if (!hwc_layer->ValidateAndSetCSC()) {
-#ifdef FEATURE_WIDE_COLOR
-      layer->flags.skip = true;
-#endif
-    }
-
-    auto range = hwc_layer->GetLayerDataspace() & HAL_DATASPACE_RANGE_MASK;
-    if (range == HAL_DATASPACE_RANGE_EXTENDED) {
-      extended_range = true;
-    }
-
-    working_primaries = WidestPrimaries(working_primaries,
-                                        layer->input_buffer.color_metadata.colorPrimaries);
-
-    // set default composition as GPU for SDM
-    layer->composition = kCompositionGPU;
-
-    if (swap_interval_zero_) {
-      if (layer->input_buffer.acquire_fence_fd >= 0) {
-        close(layer->input_buffer.acquire_fence_fd);
-        layer->input_buffer.acquire_fence_fd = -1;
-      }
-    }
-
-    bool is_secure = false;
-    const private_handle_t *handle =
-        reinterpret_cast<const private_handle_t *>(layer->input_buffer.buffer_id);
-    if (handle) {
-      if (handle->buffer_type == BUFFER_TYPE_VIDEO) {
-        layer_stack_.flags.video_present = true;
-      }
-      // TZ Protected Buffer - L1
-      // Gralloc Usage Protected Buffer - L3 - which needs to be treated as Secure & avoid fallback
-      if (handle->flags & private_handle_t::PRIV_FLAGS_PROTECTED_BUFFER ||
-          handle->flags & private_handle_t::PRIV_FLAGS_SECURE_BUFFER) {
-        layer_stack_.flags.secure_present = true;
-        is_secure = true;
-      }
-    }
-
-    if (layer->input_buffer.flags.secure_display) {
-      secure_display_active = true;
-      is_secure = true;
-    }
-
-    if (hwc_layer->IsSingleBuffered() &&
-       !(hwc_layer->IsRotationPresent() || hwc_layer->IsScalingPresent())) {
-      layer->flags.single_buffer = true;
-      layer_stack_.flags.single_buffered_layer_present = true;
-    }
-
-    if (hwc_layer->GetClientRequestedCompositionType() == HWC2::Composition::Cursor) {
-      // Currently we support only one HWCursor & only at top most z-order
-      if ((*layer_set_.rbegin())->GetId() == hwc_layer->GetId()) {
-        layer->flags.cursor = true;
-        layer_stack_.flags.cursor_present = true;
-      }
-    }
-
-    bool hdr_layer = layer->input_buffer.color_metadata.colorPrimaries == ColorPrimaries_BT2020 &&
-                     (layer->input_buffer.color_metadata.transfer == Transfer_SMPTE_ST2084 ||
-                     layer->input_buffer.color_metadata.transfer == Transfer_HLG);
-    if (hdr_layer && !disable_hdr_handling_ && color_mode_count) {
-      // dont honor HDR when its handling is disabled
-      layer->input_buffer.flags.hdr = true;
-      layer_stack_.flags.hdr_present = true;
-    }
-
-    if (hwc_layer->IsNonIntegralSourceCrop() && !is_secure && !hdr_layer &&
-        !layer->flags.single_buffer && !layer->flags.solid_fill) {
-      layer->flags.skip = true;
-    }
-
-    if (layer->flags.skip) {
-      layer_stack_.flags.skip_present = true;
-    }
-
-    // TODO(user): Move to a getter if this is needed at other places
-    hwc_rect_t scaled_display_frame = {INT(layer->dst_rect.left), INT(layer->dst_rect.top),
-                                       INT(layer->dst_rect.right), INT(layer->dst_rect.bottom)};
-    if (hwc_layer->GetGeometryChanges() & kDisplayFrame) {
-      ApplyScanAdjustment(&scaled_display_frame);
-    }
-    hwc_layer->SetLayerDisplayFrame(scaled_display_frame);
-    hwc_layer->ResetPerFrameData();
-    // SDM requires these details even for solid fill
-    if (layer->flags.solid_fill) {
-      LayerBuffer *layer_buffer = &layer->input_buffer;
-      layer_buffer->width = UINT32(layer->dst_rect.right - layer->dst_rect.left);
-      layer_buffer->height = UINT32(layer->dst_rect.bottom - layer->dst_rect.top);
-      layer_buffer->unaligned_width = layer_buffer->width;
-      layer_buffer->unaligned_height = layer_buffer->height;
-      layer_buffer->acquire_fence_fd = -1;
-      layer_buffer->release_fence_fd = -1;
-      layer->src_rect.left = 0;
-      layer->src_rect.top = 0;
-      layer->src_rect.right = layer_buffer->width;
-      layer->src_rect.bottom = layer_buffer->height;
-    }
-
-    if (hwc_layer->HasMetaDataRefreshRate() && layer->frame_rate > metadata_refresh_rate_) {
-      metadata_refresh_rate_ = SanitizeRefreshRate(layer->frame_rate);
-    }
-
-    display_rect_ = Union(display_rect_, layer->dst_rect);
-    geometry_changes_ |= hwc_layer->GetGeometryChanges();
-
-    layer->flags.updating = true;
-    if (layer_set_.size() <= kMaxLayerCount) {
-      layer->flags.updating = IsLayerUpdating(layer);
-    }
-
-    layer_stack_.layers.push_back(layer);
-  }
-
-
-#ifdef FEATURE_WIDE_COLOR
-  for (auto hwc_layer : layer_set_) {
-    auto layer = hwc_layer->GetSDMLayer();
-    if (layer->input_buffer.color_metadata.colorPrimaries != working_primaries &&
-        !hwc_layer->SupportLocalConversion(working_primaries)) {
-      layer->flags.skip = true;
-    }
-    if (layer->flags.skip) {
-      layer_stack_.flags.skip_present = true;
-    }
-  }
-#endif
-
-  // TODO(user): Set correctly when SDM supports geometry_changes as bitmask
-  layer_stack_.flags.geometry_changed = UINT32(geometry_changes_ > 0);
-  // Append client target to the layer stack
-  Layer *sdm_client_target = client_target_->GetSDMLayer();
-  sdm_client_target->flags.updating = IsLayerUpdating(sdm_client_target);
-  layer_stack_.layers.push_back(sdm_client_target);
-  // fall back frame composition to GPU when client target is 10bit
-  // TODO(user): clarify the behaviour from Client(SF) and SDM Extn -
-  // when handling 10bit FBT, as it would affect blending
-  if (Is10BitFormat(sdm_client_target->input_buffer.format) || extended_range) {
-    // Must fall back to client composition
-    MarkLayersForClientComposition();
-  }
-  // set secure display
-  SetSecureDisplay(secure_display_active);
-}
-
-void HWCDisplay::BuildSolidFillStack() {
-  layer_stack_ = LayerStack();
-  display_rect_ = LayerRect();
-
-  layer_stack_.layers.push_back(solid_fill_layer_);
-  layer_stack_.flags.geometry_changed = 1U;
-  // Append client target to the layer stack
-  layer_stack_.layers.push_back(client_target_->GetSDMLayer());
-}
-
-HWC2::Error HWCDisplay::SetLayerZOrder(hwc2_layer_t layer_id, uint32_t z) {
-  const auto map_layer = layer_map_.find(layer_id);
-  if (map_layer == layer_map_.end()) {
-    DLOGE("[%" PRIu64 "] updateLayerZ failed to find layer", id_);
-    return HWC2::Error::BadLayer;
-  }
-
-  const auto layer = map_layer->second;
-  const auto z_range = layer_set_.equal_range(layer);
-  bool layer_on_display = false;
-  for (auto current = z_range.first; current != z_range.second; ++current) {
-    if (*current == layer) {
-      if ((*current)->GetZ() == z) {
-        // Don't change anything if the Z hasn't changed
-        return HWC2::Error::None;
-      }
-      current = layer_set_.erase(current);
-      layer_on_display = true;
-      break;
-    }
-  }
-
-  if (!layer_on_display) {
-    DLOGE("[%" PRIu64 "] updateLayerZ failed to find layer on display", id_);
-    return HWC2::Error::BadLayer;
-  }
-
-  layer->SetLayerZOrder(z);
-  layer_set_.emplace(layer);
-  return HWC2::Error::None;
-}
-
-HWC2::Error HWCDisplay::SetVsyncEnabled(HWC2::Vsync enabled) {
-  DLOGV("Display ID: %d enabled: %s", id_, to_string(enabled).c_str());
-  ATRACE_INT("SetVsyncState ", enabled == HWC2::Vsync::Enable ? 1 : 0);
-  DisplayError error = kErrorNone;
-
-  if (shutdown_pending_ || !callbacks_->VsyncCallbackRegistered()) {
-    return HWC2::Error::None;
-  }
-
-  bool state;
-  if (enabled == HWC2::Vsync::Enable)
-    state = true;
-  else if (enabled == HWC2::Vsync::Disable)
-    state = false;
-  else
-    return HWC2::Error::BadParameter;
-
-  error = display_intf_->SetVSyncState(state);
-
-  if (error != kErrorNone) {
-    if (error == kErrorShutDown) {
-      shutdown_pending_ = true;
-      return HWC2::Error::None;
-    }
-    DLOGE("Failed. enabled = %s, error = %d", to_string(enabled).c_str(), error);
-    return HWC2::Error::BadDisplay;
-  }
-
-  return HWC2::Error::None;
-}
-
-HWC2::Error HWCDisplay::SetPowerMode(HWC2::PowerMode mode) {
-  DLOGV("display = %d, mode = %s", id_, to_string(mode).c_str());
-  DisplayState state = kStateOff;
-  bool flush_on_error = flush_on_error_;
-
-  if (shutdown_pending_) {
-    return HWC2::Error::None;
-  }
-
-  switch (mode) {
-    case HWC2::PowerMode::Off:
-      // During power off, all of the buffers are released.
-      // Do not flush until a buffer is successfully submitted again.
-      flush_on_error = false;
-      state = kStateOff;
-      if (tone_mapper_) {
-        tone_mapper_->Terminate();
-      }
-      break;
-    case HWC2::PowerMode::On:
-      state = kStateOn;
-      last_power_mode_ = HWC2::PowerMode::On;
-      break;
-    case HWC2::PowerMode::Doze:
-      state = kStateDoze;
-      last_power_mode_ = HWC2::PowerMode::Doze;
-      break;
-    case HWC2::PowerMode::DozeSuspend:
-      state = kStateDozeSuspend;
-      last_power_mode_ = HWC2::PowerMode::DozeSuspend;
-      break;
-    default:
-      return HWC2::Error::BadParameter;
-  }
-  int release_fence = -1;
-
-  ATRACE_INT("SetPowerMode ", state);
-  DisplayError error = display_intf_->SetDisplayState(state, &release_fence);
-  validated_ = false;
-
-  if (error == kErrorNone) {
-    flush_on_error_ = flush_on_error;
-  } else {
-    if (error == kErrorShutDown) {
-      shutdown_pending_ = true;
-      return HWC2::Error::None;
-    }
-    DLOGE("Set state failed. Error = %d", error);
-    return HWC2::Error::BadParameter;
-  }
-
-  if (release_fence >= 0) {
-    for (auto hwc_layer : layer_set_) {
-      auto fence = hwc_layer->PopBackReleaseFence();
-      auto merged_fence = -1;
-      if (fence >= 0) {
-        merged_fence = sync_merge("sync_merge", release_fence, fence);
-        ::close(fence);
-      } else {
-        merged_fence = ::dup(release_fence);
-      }
-      hwc_layer->PushBackReleaseFence(merged_fence);
-    }
-    ::close(release_fence);
-  }
-  return HWC2::Error::None;
-}
-
-HWC2::Error HWCDisplay::GetClientTargetSupport(uint32_t width, uint32_t height, int32_t format,
-                                               int32_t dataspace) {
-  ColorMetaData color_metadata = {};
-  if (dataspace != HAL_DATASPACE_UNKNOWN) {
-    GetColorPrimary(dataspace, &(color_metadata.colorPrimaries));
-    GetTransfer(dataspace, &(color_metadata.transfer));
-    GetRange(dataspace, &(color_metadata.range));
-  }
-
-  LayerBufferFormat sdm_format = GetSDMFormat(format, 0);
-  if (display_intf_->GetClientTargetSupport(width, height, sdm_format,
-                                            color_metadata) != kErrorNone) {
-    return HWC2::Error::Unsupported;
-  }
-
-  return HWC2::Error::None;
-}
-
-HWC2::Error HWCDisplay::GetColorModes(uint32_t *out_num_modes, android_color_mode_t *out_modes) {
-  if (out_modes == nullptr) {
-    *out_num_modes = 1;
-  } else if (out_modes && *out_num_modes > 0) {
-    *out_num_modes = 1;
-    out_modes[0] = HAL_COLOR_MODE_NATIVE;
-  }
-
-  return HWC2::Error::None;
-}
-
-HWC2::Error HWCDisplay::GetDisplayConfigs(uint32_t *out_num_configs, hwc2_config_t *out_configs) {
-  if (out_num_configs == nullptr) {
-    return HWC2::Error::BadParameter;
-  }
-
-  if (out_configs == nullptr) {
-    *out_num_configs = num_configs_;
-    return HWC2::Error::None;
-  }
-
-  *out_num_configs = std::min(*out_num_configs, num_configs_);
-  for (uint32_t i = 0; i < *out_num_configs; i++) {
-    out_configs[i] = i;
-  }
-
-  return HWC2::Error::None;
-}
-
-HWC2::Error HWCDisplay::GetDisplayAttribute(hwc2_config_t config, HWC2::Attribute attribute,
-                                            int32_t *out_value) {
-  DisplayConfigVariableInfo variable_config;
-  // Get display attributes from config index only if resolution switch is supported.
-  // Otherwise always send mixer attributes. This is to support destination scaler.
-  if (num_configs_ > 1) {
-    if (GetDisplayAttributesForConfig(INT(config), &variable_config) != kErrorNone) {
-      DLOGE("Get variable config failed");
-      return HWC2::Error::BadDisplay;
-    }
-  } else {
-    if (display_intf_->GetFrameBufferConfig(&variable_config) != kErrorNone) {
-      DLOGV("Get variable config failed");
-      return HWC2::Error::BadDisplay;
-    }
-  }
-
-  switch (attribute) {
-    case HWC2::Attribute::VsyncPeriod:
-      *out_value = INT32(variable_config.vsync_period_ns);
-      break;
-    case HWC2::Attribute::Width:
-      *out_value = INT32(variable_config.x_pixels);
-      break;
-    case HWC2::Attribute::Height:
-      *out_value = INT32(variable_config.y_pixels);
-      break;
-    case HWC2::Attribute::DpiX:
-      *out_value = INT32(variable_config.x_dpi * 1000.0f);
-      break;
-    case HWC2::Attribute::DpiY:
-      *out_value = INT32(variable_config.y_dpi * 1000.0f);
-      break;
-    default:
-      DLOGW("Spurious attribute type = %s", to_string(attribute).c_str());
-      *out_value = -1;
-      return HWC2::Error::BadConfig;
-  }
-
-  return HWC2::Error::None;
-}
-
-HWC2::Error HWCDisplay::GetDisplayName(uint32_t *out_size, char *out_name) {
-  // TODO(user): Get panel name and EDID name and populate it here
-  if (out_size == nullptr) {
-    return HWC2::Error::BadParameter;
-  }
-
-  std::string name;
-  switch (id_) {
-    case HWC_DISPLAY_PRIMARY:
-      name = "Primary Display";
-      break;
-    case HWC_DISPLAY_EXTERNAL:
-      name = "External Display";
-      break;
-    case HWC_DISPLAY_VIRTUAL:
-      name = "Virtual Display";
-      break;
-    default:
-      name = "Unknown";
-      break;
-  }
-
-  if (out_name == nullptr) {
-    *out_size = UINT32(name.size()) + 1;
-  } else {
-    *out_size = std::min((UINT32(name.size()) + 1), *out_size);
-    if (*out_size > 0) {
-      std::strncpy(out_name, name.c_str(), *out_size);
-      out_name[*out_size - 1] = '\0';
-    } else {
-      DLOGW("Invalid size requested");
-    }
-  }
-
-  return HWC2::Error::None;
-}
-
-HWC2::Error HWCDisplay::GetDisplayType(int32_t *out_type) {
-  if (out_type != nullptr) {
-    if (id_ == HWC_DISPLAY_VIRTUAL) {
-      *out_type = HWC2_DISPLAY_TYPE_VIRTUAL;
-    } else {
-      *out_type = HWC2_DISPLAY_TYPE_PHYSICAL;
-    }
-    return HWC2::Error::None;
-  } else {
-    return HWC2::Error::BadParameter;
-  }
-}
-
-HWC2::Error HWCDisplay::GetActiveConfig(hwc2_config_t *out_config) {
-  if (out_config == nullptr) {
-    return HWC2::Error::BadDisplay;
-  }
-
-  uint32_t active_index = 0;
-  if (GetActiveDisplayConfig(&active_index) != kErrorNone) {
-    return HWC2::Error::BadConfig;
-  }
-
-  *out_config = active_index;
-
-  return HWC2::Error::None;
-}
-
-HWC2::Error HWCDisplay::SetClientTarget(buffer_handle_t target, int32_t acquire_fence,
-                                        int32_t dataspace, hwc_region_t damage) {
-  // TODO(user): SurfaceFlinger gives us a null pointer here when doing full SDE composition
-  // The error is problematic for layer caching as it would overwrite our cached client target.
-  // Reported bug 28569722 to resolve this.
-  // For now, continue to use the last valid buffer reported to us for layer caching.
-  if (target == nullptr) {
-    return HWC2::Error::None;
-  }
-
-  if (acquire_fence == 0) {
-    DLOGE("acquire_fence is zero");
-    return HWC2::Error::BadParameter;
-  }
-
-  Layer *sdm_layer = client_target_->GetSDMLayer();
-  sdm_layer->frame_rate = current_refresh_rate_;
-  client_target_->SetLayerBuffer(target, acquire_fence);
-  client_target_->SetLayerSurfaceDamage(damage);
-  if (client_target_->GetLayerDataspace() != dataspace) {
-    client_target_->SetLayerDataspace(dataspace);
-    Layer *sdm_layer = client_target_->GetSDMLayer();
-    // Data space would be validated at GetClientTargetSupport, so just use here.
-    sdm::GetSDMColorSpace(dataspace, &sdm_layer->input_buffer.color_metadata);
-  }
-
-  return HWC2::Error::None;
-}
-
-HWC2::Error HWCDisplay::SetActiveConfig(hwc2_config_t config) {
-  if (SetActiveDisplayConfig(config) != kErrorNone) {
-    return HWC2::Error::BadConfig;
-  }
-
-  validated_ = false;
-  return HWC2::Error::None;
-}
-
-DisplayError HWCDisplay::SetMixerResolution(uint32_t width, uint32_t height) {
-  return kErrorNotSupported;
-}
-
-HWC2::Error HWCDisplay::SetFrameDumpConfig(uint32_t count, uint32_t bit_mask_layer_type) {
-  dump_frame_count_ = count;
-  dump_frame_index_ = 0;
-  dump_input_layers_ = ((bit_mask_layer_type & (1 << INPUT_LAYER_DUMP)) != 0);
-
-  if (tone_mapper_) {
-    tone_mapper_->SetFrameDumpConfig(count);
-  }
-
-  DLOGI("num_frame_dump %d, input_layer_dump_enable %d", dump_frame_count_, dump_input_layers_);
-  validated_ = false;
-  return HWC2::Error::None;
-}
-
-HWC2::PowerMode HWCDisplay::GetLastPowerMode() {
-  return last_power_mode_;
-}
-
-DisplayError HWCDisplay::VSync(const DisplayEventVSync &vsync) {
-  callbacks_->Vsync(id_, vsync.timestamp);
-  return kErrorNone;
-}
-
-DisplayError HWCDisplay::Refresh() {
-  return kErrorNotSupported;
-}
-
-DisplayError HWCDisplay::CECMessage(char *message) {
-  if (qservice_) {
-    qservice_->onCECMessageReceived(message, 0);
-  } else {
-    DLOGW("Qservice instance not available.");
-  }
-
-  return kErrorNone;
-}
-
-DisplayError HWCDisplay::HandleEvent(DisplayEvent event) {
-  switch (event) {
-    case kIdleTimeout: {
-      SCOPE_LOCK(HWCSession::locker_[type_]);
-      if (pending_commit_) {
-        // If idle timeout event comes in between prepare
-        // and commit, drop it since device is not really
-        // idle.
-        return kErrorNotSupported;
-      }
-      validated_ = false;
-      break;
-    }
-    case kThermalEvent:
-    case kIdlePowerCollapse:
-    case kPanelDeadEvent: {
-      SEQUENCE_WAIT_SCOPE_LOCK(HWCSession::locker_[type_]);
-      validated_ = false;
-    } break;
-    default:
-      DLOGW("Unknown event: %d", event);
-      break;
-  }
-
-  return kErrorNone;
-}
-
-HWC2::Error HWCDisplay::PrepareLayerStack(uint32_t *out_num_types, uint32_t *out_num_requests) {
-  layer_changes_.clear();
-  layer_requests_.clear();
-  if (shutdown_pending_) {
-    return HWC2::Error::BadDisplay;
-  }
-
-  UpdateRefreshRate();
-  if (!skip_prepare_) {
-    DisplayError error = display_intf_->Prepare(&layer_stack_);
-    if (error != kErrorNone) {
-      if (error == kErrorShutDown) {
-        shutdown_pending_ = true;
-      } else if (error != kErrorPermission) {
-        DLOGE("Prepare failed. Error = %d", error);
-        // To prevent surfaceflinger infinite wait, flush the previous frame during Commit()
-        // so that previous buffer and fences are released, and override the error.
-        flush_ = true;
-      }
-      return HWC2::Error::BadDisplay;
-    } else {
-      validated_ = true;
-    }
-  } else {
-    // Skip is not set
-    MarkLayersForGPUBypass();
-    skip_prepare_ = false;
-    DLOGI("SecureDisplay %s, Skip Prepare/Commit and Flush",
-          secure_display_active_ ? "Starting" : "Stopping");
-    flush_ = true;
-  }
-
-  for (auto hwc_layer : layer_set_) {
-    Layer *layer = hwc_layer->GetSDMLayer();
-    LayerComposition &composition = layer->composition;
-
-    if ((composition == kCompositionSDE) || (composition == kCompositionHybrid) ||
-        (composition == kCompositionBlit)) {
-      layer_requests_[hwc_layer->GetId()] = HWC2::LayerRequest::ClearClientTarget;
-    }
-
-    HWC2::Composition requested_composition = hwc_layer->GetClientRequestedCompositionType();
-    // Set SDM composition to HWC2 type in HWCLayer
-    hwc_layer->SetComposition(composition);
-    HWC2::Composition device_composition  = hwc_layer->GetDeviceSelectedCompositionType();
-    // Update the changes list only if the requested composition is different from SDM comp type
-    // TODO(user): Take Care of other comptypes(BLIT)
-    if (requested_composition != device_composition) {
-      layer_changes_[hwc_layer->GetId()] = device_composition;
-    }
-    hwc_layer->ResetValidation();
-  }
-  client_target_->ResetValidation();
-  *out_num_types = UINT32(layer_changes_.size());
-  *out_num_requests = UINT32(layer_requests_.size());
-  skip_validate_ = false;
-  layer_stack_invalid_ = false;
-
-  if (*out_num_types > 0) {
-    return HWC2::Error::HasChanges;
-  }
-
-  return HWC2::Error::None;
-}
-
-HWC2::Error HWCDisplay::AcceptDisplayChanges() {
-  if (layer_set_.empty()) {
-    return HWC2::Error::None;
-  }
-
-  if (!validated_) {
-    return HWC2::Error::NotValidated;
-  }
-
-  for (const auto& change : layer_changes_) {
-    auto hwc_layer = layer_map_[change.first];
-    auto composition = change.second;
-    if (hwc_layer != nullptr) {
-      hwc_layer->UpdateClientCompositionType(composition);
-    } else {
-      DLOGW("Invalid layer: %" PRIu64, change.first);
-    }
-  }
-  return HWC2::Error::None;
-}
-
-HWC2::Error HWCDisplay::GetChangedCompositionTypes(uint32_t *out_num_elements,
-                                                   hwc2_layer_t *out_layers, int32_t *out_types) {
-  if (layer_set_.empty()) {
-    return HWC2::Error::None;
-  }
-
-  if (!validated_) {
-    DLOGW("Display is not validated");
-    return HWC2::Error::NotValidated;
-  }
-
-  *out_num_elements = UINT32(layer_changes_.size());
-  if (out_layers != nullptr && out_types != nullptr) {
-    int i = 0;
-    for (auto change : layer_changes_) {
-      out_layers[i] = change.first;
-      out_types[i] = INT32(change.second);
-      i++;
-    }
-  }
-  return HWC2::Error::None;
-}
-
-HWC2::Error HWCDisplay::GetReleaseFences(uint32_t *out_num_elements, hwc2_layer_t *out_layers,
-                                         int32_t *out_fences) {
-  if (out_num_elements == nullptr) {
-    return HWC2::Error::BadParameter;
-  }
-
-  if (out_layers != nullptr && out_fences != nullptr) {
-    *out_num_elements = std::min(*out_num_elements, UINT32(layer_set_.size()));
-    auto it = layer_set_.begin();
-    for (uint32_t i = 0; i < *out_num_elements; i++, it++) {
-      auto hwc_layer = *it;
-      out_layers[i] = hwc_layer->GetId();
-      out_fences[i] = hwc_layer->PopFrontReleaseFence();
-    }
-  } else {
-    *out_num_elements = UINT32(layer_set_.size());
-  }
-
-  return HWC2::Error::None;
-}
-
-HWC2::Error HWCDisplay::GetDisplayRequests(int32_t *out_display_requests,
-                                           uint32_t *out_num_elements, hwc2_layer_t *out_layers,
-                                           int32_t *out_layer_requests) {
-  if (layer_set_.empty()) {
-    return HWC2::Error::None;
-  }
-
-  if (out_display_requests == nullptr || out_num_elements == nullptr) {
-    return HWC2::Error::BadParameter;
-  }
-
-  // No display requests for now
-  // Use for sharing blit buffers and
-  // writing wfd buffer directly to output if there is full GPU composition
-  // and no color conversion needed
-  if (!validated_) {
-    DLOGW("Display is not validated");
-    return HWC2::Error::NotValidated;
-  }
-
-  *out_display_requests = 0;
-  if (out_layers != nullptr && out_layer_requests != nullptr) {
-    *out_num_elements = std::min(*out_num_elements, UINT32(layer_requests_.size()));
-    auto it = layer_requests_.begin();
-    for (uint32_t i = 0; i < *out_num_elements; i++, it++) {
-      out_layers[i] = it->first;
-      out_layer_requests[i] = INT32(it->second);
-    }
-  } else {
-    *out_num_elements = UINT32(layer_requests_.size());
-  }
-
-  auto client_target_layer = client_target_->GetSDMLayer();
-  if (client_target_layer->request.flags.flip_buffer) {
-    *out_display_requests = INT32(HWC2::DisplayRequest::FlipClientTarget);
-  }
-
-  return HWC2::Error::None;
-}
-
-HWC2::Error HWCDisplay::GetHdrCapabilities(uint32_t *out_num_types, int32_t *out_types,
-                                           float *out_max_luminance,
-                                           float *out_max_average_luminance,
-                                           float *out_min_luminance) {
-  if (out_num_types == nullptr || out_max_luminance == nullptr ||
-      out_max_average_luminance == nullptr || out_min_luminance == nullptr) {
-    return HWC2::Error::BadParameter;
-  }
-
-  DisplayConfigFixedInfo fixed_info = {};
-  display_intf_->GetConfig(&fixed_info);
-
-  if (!fixed_info.hdr_supported) {
-    *out_num_types = 0;
-    DLOGI("HDR is not supported");
-    return HWC2::Error::None;
-  }
-
-  if (out_types == nullptr) {
-    // We support HDR10 and HLG
-    *out_num_types = 2;
-  } else {
-    // HDR10 and HLG are supported
-    out_types[0] = HAL_HDR_HDR10;
-    out_types[1] = HAL_HDR_HLG;
-    static const float kLuminanceFactor = 10000.0;
-    // luminance is expressed in the unit of 0.0001 cd/m2, convert it to 1cd/m2.
-    *out_max_luminance = FLOAT(fixed_info.max_luminance)/kLuminanceFactor;
-    *out_max_average_luminance = FLOAT(fixed_info.average_luminance)/kLuminanceFactor;
-    *out_min_luminance = FLOAT(fixed_info.min_luminance)/kLuminanceFactor;
-  }
-
-  return HWC2::Error::None;
-}
-
-
-HWC2::Error HWCDisplay::CommitLayerStack(void) {
-  if (flush_) {
-     return HWC2::Error::None;
-  }
-
-  if (skip_validate_ && !CanSkipValidate()) {
-    validated_ = false;
-  }
-
-  if (!validated_) {
-    DLOGV_IF(kTagClient, "Display %d is not validated", id_);
-    return HWC2::Error::NotValidated;
-  }
-
-  if (shutdown_pending_ || layer_set_.empty()) {
-    return HWC2::Error::None;
-  }
-
-  DumpInputBuffers();
-
-  DisplayError error = kErrorUndefined;
-  int status = 0;
-  if (tone_mapper_) {
-    if (layer_stack_.flags.hdr_present) {
-      status = tone_mapper_->HandleToneMap(&layer_stack_);
-      if (status != 0) {
-        DLOGE("Error handling HDR in ToneMapper");
-      }
-    } else {
-      tone_mapper_->Terminate();
-    }
-  }
-
-  error = display_intf_->Commit(&layer_stack_);
-
-  if (error == kErrorNone) {
-    // A commit is successfully submitted, start flushing on failure now onwards.
-    flush_on_error_ = true;
-  } else {
-    if (error == kErrorShutDown) {
-      shutdown_pending_ = true;
-      return HWC2::Error::Unsupported;
-    } else if (error == kErrorNotValidated) {
-      validated_ = false;
-      return HWC2::Error::NotValidated;
-    } else if (error != kErrorPermission) {
-      DLOGE("Commit failed. Error = %d", error);
-      // To prevent surfaceflinger infinite wait, flush the previous frame during Commit()
-      // so that previous buffer and fences are released, and override the error.
-      flush_ = true;
-    }
-  }
-
-  skip_validate_ = true;
-  return HWC2::Error::None;
-}
-
-HWC2::Error HWCDisplay::PostCommitLayerStack(int32_t *out_retire_fence) {
-  auto status = HWC2::Error::None;
-
-  // Do no call flush on errors, if a successful buffer is never submitted.
-  if (flush_ && flush_on_error_) {
-    display_intf_->Flush();
-    validated_ = false;
-  }
-
-  if (tone_mapper_ && tone_mapper_->IsActive()) {
-     tone_mapper_->PostCommit(&layer_stack_);
-  }
-
-  // TODO(user): No way to set the client target release fence on SF
-  int32_t &client_target_release_fence =
-      client_target_->GetSDMLayer()->input_buffer.release_fence_fd;
-  if (client_target_release_fence >= 0) {
-    close(client_target_release_fence);
-    client_target_release_fence = -1;
-  }
-  client_target_->ResetGeometryChanges();
-
-  for (auto hwc_layer : layer_set_) {
-    hwc_layer->ResetGeometryChanges();
-    Layer *layer = hwc_layer->GetSDMLayer();
-    LayerBuffer *layer_buffer = &layer->input_buffer;
-
-    if (!flush_) {
-      // If swapinterval property is set to 0 or for single buffer layers, do not update f/w
-      // release fences and discard fences from driver
-      if (swap_interval_zero_ || layer->flags.single_buffer) {
-        close(layer_buffer->release_fence_fd);
-      } else if (layer->composition != kCompositionGPU) {
-        hwc_layer->PushBackReleaseFence(layer_buffer->release_fence_fd);
-      } else {
-        hwc_layer->PushBackReleaseFence(-1);
-      }
-    } else {
-      // In case of flush, we don't return an error to f/w, so it will get a release fence out of
-      // the hwc_layer's release fence queue. We should push a -1 to preserve release fence
-      // circulation semantics.
-      hwc_layer->PushBackReleaseFence(-1);
-    }
-
-    layer_buffer->release_fence_fd = -1;
-    if (layer_buffer->acquire_fence_fd >= 0) {
-      close(layer_buffer->acquire_fence_fd);
-      layer_buffer->acquire_fence_fd = -1;
-    }
-
-    layer->request.flags = {};
-  }
-
-  client_target_->GetSDMLayer()->request.flags = {};
-  *out_retire_fence = -1;
-  if (!flush_) {
-    // if swapinterval property is set to 0 then close and reset the list retire fence
-    if (swap_interval_zero_) {
-      close(layer_stack_.retire_fence_fd);
-      layer_stack_.retire_fence_fd = -1;
-    }
-    *out_retire_fence = layer_stack_.retire_fence_fd;
-    layer_stack_.retire_fence_fd = -1;
-
-    if (dump_frame_count_) {
-      dump_frame_count_--;
-      dump_frame_index_++;
-    }
-  }
-  config_pending_ = false;
-
-  geometry_changes_ = GeometryChanges::kNone;
-  flush_ = false;
-
-  return status;
-}
-
-void HWCDisplay::SetIdleTimeoutMs(uint32_t timeout_ms) {
-  return;
-}
-
-DisplayError HWCDisplay::SetMaxMixerStages(uint32_t max_mixer_stages) {
-  DisplayError error = kErrorNone;
-
-  if (display_intf_) {
-    error = display_intf_->SetMaxMixerStages(max_mixer_stages);
-    validated_ = false;
-  }
-
-  return error;
-}
-
-LayerBufferFormat HWCDisplay::GetSDMFormat(const int32_t &source, const int flags) {
-  LayerBufferFormat format = kFormatInvalid;
-  if (flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED) {
-    switch (source) {
-      case HAL_PIXEL_FORMAT_RGBA_8888:
-        format = kFormatRGBA8888Ubwc;
-        break;
-      case HAL_PIXEL_FORMAT_RGBX_8888:
-        format = kFormatRGBX8888Ubwc;
-        break;
-      case HAL_PIXEL_FORMAT_BGR_565:
-        format = kFormatBGR565Ubwc;
-        break;
-      case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
-      case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
-      case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
-        format = kFormatYCbCr420SPVenusUbwc;
-        break;
-      case HAL_PIXEL_FORMAT_RGBA_1010102:
-        format = kFormatRGBA1010102Ubwc;
-        break;
-      case HAL_PIXEL_FORMAT_RGBX_1010102:
-        format = kFormatRGBX1010102Ubwc;
-        break;
-      case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
-        format = kFormatYCbCr420TP10Ubwc;
-        break;
-      case HAL_PIXEL_FORMAT_YCbCr_420_P010_UBWC:
-        format = kFormatYCbCr420P010Ubwc;
-        break;
-      default:
-        DLOGE("Unsupported format type for UBWC %d", source);
-        return kFormatInvalid;
-    }
-    return format;
-  }
-
-  switch (source) {
-    case HAL_PIXEL_FORMAT_RGBA_8888:
-      format = kFormatRGBA8888;
-      break;
-    case HAL_PIXEL_FORMAT_RGBA_5551:
-      format = kFormatRGBA5551;
-      break;
-    case HAL_PIXEL_FORMAT_RGBA_4444:
-      format = kFormatRGBA4444;
-      break;
-    case HAL_PIXEL_FORMAT_BGRA_8888:
-      format = kFormatBGRA8888;
-      break;
-    case HAL_PIXEL_FORMAT_RGBX_8888:
-      format = kFormatRGBX8888;
-      break;
-    case HAL_PIXEL_FORMAT_BGRX_8888:
-      format = kFormatBGRX8888;
-      break;
-    case HAL_PIXEL_FORMAT_RGB_888:
-      format = kFormatRGB888;
-      break;
-    case HAL_PIXEL_FORMAT_RGB_565:
-      format = kFormatRGB565;
-      break;
-    case HAL_PIXEL_FORMAT_BGR_565:
-      format = kFormatBGR565;
-      break;
-    case HAL_PIXEL_FORMAT_BGR_888:
-      format = kFormatBGR888;
-      break;
-    case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
-    case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
-      format = kFormatYCbCr420SemiPlanarVenus;
-      break;
-    case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS:
-      format = kFormatYCrCb420SemiPlanarVenus;
-      break;
-    case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
-      format = kFormatYCbCr420SPVenusUbwc;
-      break;
-    case HAL_PIXEL_FORMAT_YV12:
-      format = kFormatYCrCb420PlanarStride16;
-      break;
-    case HAL_PIXEL_FORMAT_YCrCb_420_SP:
-      format = kFormatYCrCb420SemiPlanar;
-      break;
-    case HAL_PIXEL_FORMAT_YCbCr_420_SP:
-      format = kFormatYCbCr420SemiPlanar;
-      break;
-    case HAL_PIXEL_FORMAT_YCbCr_422_SP:
-      format = kFormatYCbCr422H2V1SemiPlanar;
-      break;
-    case HAL_PIXEL_FORMAT_YCbCr_422_I:
-      format = kFormatYCbCr422H2V1Packed;
-      break;
-    case HAL_PIXEL_FORMAT_CbYCrY_422_I:
-      format = kFormatCbYCrY422H2V1Packed;
-      break;
-    case HAL_PIXEL_FORMAT_RGBA_1010102:
-      format = kFormatRGBA1010102;
-      break;
-    case HAL_PIXEL_FORMAT_ARGB_2101010:
-      format = kFormatARGB2101010;
-      break;
-    case HAL_PIXEL_FORMAT_RGBX_1010102:
-      format = kFormatRGBX1010102;
-      break;
-    case HAL_PIXEL_FORMAT_XRGB_2101010:
-      format = kFormatXRGB2101010;
-      break;
-    case HAL_PIXEL_FORMAT_BGRA_1010102:
-      format = kFormatBGRA1010102;
-      break;
-    case HAL_PIXEL_FORMAT_ABGR_2101010:
-      format = kFormatABGR2101010;
-      break;
-    case HAL_PIXEL_FORMAT_BGRX_1010102:
-      format = kFormatBGRX1010102;
-      break;
-    case HAL_PIXEL_FORMAT_XBGR_2101010:
-      format = kFormatXBGR2101010;
-      break;
-    case HAL_PIXEL_FORMAT_YCbCr_420_P010:
-      format = kFormatYCbCr420P010;
-      break;
-    case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
-      format = kFormatYCbCr420TP10Ubwc;
-      break;
-    case HAL_PIXEL_FORMAT_YCbCr_420_P010_UBWC:
-      format = kFormatYCbCr420P010Ubwc;
-      break;
-    case HAL_PIXEL_FORMAT_YCbCr_420_P010_VENUS:
-      format = kFormatYCbCr420P010Venus;
-      break;
-    default:
-      DLOGW("Unsupported format type = %d", source);
-      return kFormatInvalid;
-  }
-
-  return format;
-}
-
-void HWCDisplay::DumpInputBuffers() {
-  char dir_path[PATH_MAX];
-
-  if (!dump_frame_count_ || flush_ || !dump_input_layers_) {
-    return;
-  }
-
-  DLOGI("dump_frame_count %d dump_input_layers %d", dump_frame_count_, dump_input_layers_);
-  snprintf(dir_path, sizeof(dir_path), "%s/frame_dump_%s", HWCDebugHandler::DumpDir(),
-           GetDisplayString());
-
-  if (mkdir(dir_path, 0777) != 0 && errno != EEXIST) {
-    DLOGW("Failed to create %s directory errno = %d, desc = %s", dir_path, errno, strerror(errno));
-    return;
-  }
-
-  // if directory exists already, need to explicitly change the permission.
-  if (errno == EEXIST && chmod(dir_path, 0777) != 0) {
-    DLOGW("Failed to change permissions on %s directory", dir_path);
-    return;
-  }
-
-  for (uint32_t i = 0; i < layer_stack_.layers.size(); i++) {
-    auto layer = layer_stack_.layers.at(i);
-    const private_handle_t *pvt_handle =
-        reinterpret_cast<const private_handle_t *>(layer->input_buffer.buffer_id);
-    auto acquire_fence_fd = layer->input_buffer.acquire_fence_fd;
-
-    if (acquire_fence_fd >= 0) {
-      int error = sync_wait(acquire_fence_fd, 1000);
-      if (error < 0) {
-        DLOGW("sync_wait error errno = %d, desc = %s", errno, strerror(errno));
-        return;
-      }
-    }
-
-    DLOGI("Dump layer[%d] of %d pvt_handle %x pvt_handle->base %x", i, layer_stack_.layers.size(),
-          pvt_handle, pvt_handle? pvt_handle->base : 0);
-
-    if (!pvt_handle) {
-      DLOGE("Buffer handle is null");
-      return;
-    }
-
-    if (!pvt_handle->base) {
-      DisplayError error = buffer_allocator_->MapBuffer(pvt_handle, -1);
-      if (error != kErrorNone) {
-        DLOGE("Failed to map buffer, error = %d", error);
-        return;
-      }
-    }
-
-    char dump_file_name[PATH_MAX];
-    size_t result = 0;
-
-    snprintf(dump_file_name, sizeof(dump_file_name), "%s/input_layer%d_%dx%d_%s_frame%d.raw",
-             dir_path, i, pvt_handle->width, pvt_handle->height,
-             qdutils::GetHALPixelFormatString(pvt_handle->format), dump_frame_index_);
-
-    FILE *fp = fopen(dump_file_name, "w+");
-    if (fp) {
-      result = fwrite(reinterpret_cast<void *>(pvt_handle->base), pvt_handle->size, 1, fp);
-      fclose(fp);
-    }
-
-    int release_fence = -1;
-    DisplayError error = buffer_allocator_->UnmapBuffer(pvt_handle, &release_fence);
-    if (error != kErrorNone) {
-      DLOGE("Failed to unmap buffer, error = %d", error);
-      return;
-    }
-
-    DLOGI("Frame Dump %s: is %s", dump_file_name, result ? "Successful" : "Failed");
-  }
-}
-
-void HWCDisplay::DumpOutputBuffer(const BufferInfo &buffer_info, void *base, int fence) {
-  char dir_path[PATH_MAX];
-
-  snprintf(dir_path, sizeof(dir_path), "%s/frame_dump_%s", HWCDebugHandler::DumpDir(),
-           GetDisplayString());
-
-  if (mkdir(dir_path, 777) != 0 && errno != EEXIST) {
-    DLOGW("Failed to create %s directory errno = %d, desc = %s", dir_path, errno, strerror(errno));
-    return;
-  }
-
-  // if directory exists already, need to explicitly change the permission.
-  if (errno == EEXIST && chmod(dir_path, 0777) != 0) {
-    DLOGW("Failed to change permissions on %s directory", dir_path);
-    return;
-  }
-
-  if (base) {
-    char dump_file_name[PATH_MAX];
-    size_t result = 0;
-
-    if (fence >= 0) {
-      int error = sync_wait(fence, 1000);
-      if (error < 0) {
-        DLOGW("sync_wait error errno = %d, desc = %s", errno, strerror(errno));
-        return;
-      }
-    }
-
-    snprintf(dump_file_name, sizeof(dump_file_name), "%s/output_layer_%dx%d_%s_frame%d.raw",
-             dir_path, buffer_info.buffer_config.width, buffer_info.buffer_config.height,
-             GetFormatString(buffer_info.buffer_config.format), dump_frame_index_);
-
-    FILE *fp = fopen(dump_file_name, "w+");
-    if (fp) {
-      result = fwrite(base, buffer_info.alloc_buffer_info.size, 1, fp);
-      fclose(fp);
-    }
-
-    DLOGI("Frame Dump of %s is %s", dump_file_name, result ? "Successful" : "Failed");
-  }
-}
-
-const char *HWCDisplay::GetDisplayString() {
-  switch (type_) {
-    case kPrimary:
-      return "primary";
-    case kHDMI:
-      return "hdmi";
-    case kVirtual:
-      return "virtual";
-    default:
-      return "invalid";
-  }
-}
-
-int HWCDisplay::SetFrameBufferResolution(uint32_t x_pixels, uint32_t y_pixels) {
-  if (x_pixels <= 0 || y_pixels <= 0) {
-    DLOGW("Unsupported config: x_pixels=%d, y_pixels=%d", x_pixels, y_pixels);
-    return -EINVAL;
-  }
-
-  DisplayConfigVariableInfo fb_config;
-  DisplayError error = display_intf_->GetFrameBufferConfig(&fb_config);
-  if (error != kErrorNone) {
-    DLOGV("Get frame buffer config failed. Error = %d", error);
-    return -EINVAL;
-  }
-
-  fb_config.x_pixels = x_pixels;
-  fb_config.y_pixels = y_pixels;
-
-  error = display_intf_->SetFrameBufferConfig(fb_config);
-  if (error != kErrorNone) {
-    DLOGV("Set frame buffer config failed. Error = %d", error);
-    return -EINVAL;
-  }
-
-  // Create rects to represent the new source and destination crops
-  LayerRect crop = LayerRect(0, 0, FLOAT(x_pixels), FLOAT(y_pixels));
-  hwc_rect_t scaled_display_frame = {0, 0, INT(x_pixels), INT(y_pixels)};
-  ApplyScanAdjustment(&scaled_display_frame);
-  client_target_->SetLayerDisplayFrame(scaled_display_frame);
-  client_target_->ResetPerFrameData();
-
-  auto client_target_layer = client_target_->GetSDMLayer();
-  client_target_layer->src_rect = crop;
-
-  int aligned_width;
-  int aligned_height;
-  uint32_t usage = GRALLOC_USAGE_HW_FB;
-  int format = HAL_PIXEL_FORMAT_RGBA_8888;
-  int ubwc_disabled = 0;
-  int flags = 0;
-
-  // By default UBWC is enabled and below property is global enable/disable for all
-  // buffers allocated through gralloc , including framebuffer targets.
-  HWCDebugHandler::Get()->GetProperty(DISABLE_UBWC_PROP, &ubwc_disabled);
-  if (!ubwc_disabled) {
-    usage |= GRALLOC_USAGE_PRIVATE_ALLOC_UBWC;
-    flags |= private_handle_t::PRIV_FLAGS_UBWC_ALIGNED;
-  }
-
-  buffer_allocator_->GetAlignedWidthAndHeight(INT(x_pixels), INT(y_pixels), format, usage,
-                                              &aligned_width, &aligned_height);
-
-  // TODO(user): How does the dirty region get set on the client target? File bug on Google
-  client_target_layer->composition = kCompositionGPUTarget;
-  client_target_layer->input_buffer.format = GetSDMFormat(format, flags);
-  client_target_layer->input_buffer.width = UINT32(aligned_width);
-  client_target_layer->input_buffer.height = UINT32(aligned_height);
-  client_target_layer->input_buffer.unaligned_width = x_pixels;
-  client_target_layer->input_buffer.unaligned_height = y_pixels;
-  client_target_layer->plane_alpha = 255;
-
-  DLOGI("New framebuffer resolution (%dx%d)", fb_config.x_pixels, fb_config.y_pixels);
-
-  return 0;
-}
-
-void HWCDisplay::GetFrameBufferResolution(uint32_t *x_pixels, uint32_t *y_pixels) {
-  DisplayConfigVariableInfo fb_config;
-  display_intf_->GetFrameBufferConfig(&fb_config);
-
-  *x_pixels = fb_config.x_pixels;
-  *y_pixels = fb_config.y_pixels;
-}
-
-DisplayError HWCDisplay::GetMixerResolution(uint32_t *x_pixels, uint32_t *y_pixels) {
-  return display_intf_->GetMixerResolution(x_pixels, y_pixels);
-}
-
-void HWCDisplay::GetPanelResolution(uint32_t *x_pixels, uint32_t *y_pixels) {
-  DisplayConfigVariableInfo display_config;
-  uint32_t active_index = 0;
-
-  display_intf_->GetActiveConfig(&active_index);
-  display_intf_->GetConfig(active_index, &display_config);
-
-  *x_pixels = display_config.x_pixels;
-  *y_pixels = display_config.y_pixels;
-}
-
-int HWCDisplay::SetDisplayStatus(DisplayStatus display_status) {
-  int status = 0;
-
-  switch (display_status) {
-    case kDisplayStatusResume:
-      display_paused_ = false;
-    case kDisplayStatusOnline:
-      status = INT32(SetPowerMode(HWC2::PowerMode::On));
-      break;
-    case kDisplayStatusPause:
-      display_paused_ = true;
-    case kDisplayStatusOffline:
-      status = INT32(SetPowerMode(HWC2::PowerMode::Off));
-      break;
-    default:
-      DLOGW("Invalid display status %d", display_status);
-      return -EINVAL;
-  }
-
-  if (display_status == kDisplayStatusResume || display_status == kDisplayStatusPause) {
-    callbacks_->Refresh(HWC_DISPLAY_PRIMARY);
-    validated_ = false;
-  }
-
-  return status;
-}
-
-HWC2::Error HWCDisplay::SetCursorPosition(hwc2_layer_t layer, int x, int y) {
-  if (shutdown_pending_) {
-    return HWC2::Error::None;
-  }
-
-  HWCLayer *hwc_layer = GetHWCLayer(layer);
-  if (hwc_layer == nullptr) {
-    return HWC2::Error::BadLayer;
-  }
-  if (hwc_layer->GetDeviceSelectedCompositionType() != HWC2::Composition::Cursor) {
-    return HWC2::Error::None;
-  }
-  if (!skip_validate_ && validated_) {
-    // the device is currently in the middle of the validate/present sequence,
-    // cannot set the Position(as per HWC2 spec)
-    return HWC2::Error::NotValidated;
-  }
-
-  DisplayState state;
-  if (display_intf_->GetDisplayState(&state) == kErrorNone) {
-    if (state != kStateOn) {
-      return HWC2::Error::None;
-    }
-  }
-
-  // TODO(user): HWC1.5 was not letting SetCursorPosition before validateDisplay,
-  // but HWC2.0 doesn't let setting cursor position after validate before present.
-  // Need to revisit.
-
-  auto error = display_intf_->SetCursorPosition(x, y);
-  if (error != kErrorNone) {
-    if (error == kErrorShutDown) {
-      shutdown_pending_ = true;
-      return HWC2::Error::None;
-    }
-
-    DLOGE("Failed for x = %d y = %d, Error = %d", x, y, error);
-    return HWC2::Error::BadDisplay;
-  }
-
-  return HWC2::Error::None;
-}
-
-int HWCDisplay::OnMinHdcpEncryptionLevelChange(uint32_t min_enc_level) {
-  DisplayError error = display_intf_->OnMinHdcpEncryptionLevelChange(min_enc_level);
-  if (error != kErrorNone) {
-    DLOGE("Failed. Error = %d", error);
-    return -1;
-  }
-
-  validated_ = false;
-  return 0;
-}
-
-void HWCDisplay::MarkLayersForGPUBypass() {
-  for (auto hwc_layer : layer_set_) {
-    auto layer = hwc_layer->GetSDMLayer();
-    layer->composition = kCompositionSDE;
-  }
-  validated_ = true;
-}
-
-void HWCDisplay::MarkLayersForClientComposition() {
-  // ClientComposition - GPU comp, to acheive this, set skip flag so that
-  // SDM does not handle this layer and hwc_layer composition will be
-  // set correctly at the end of Prepare.
-  DLOGV_IF(kTagClient, "HWC Layers marked for GPU comp");
-  for (auto hwc_layer : layer_set_) {
-    Layer *layer = hwc_layer->GetSDMLayer();
-    layer->flags.skip = true;
-  }
-  layer_stack_.flags.skip_present = true;
-}
-
-void HWCDisplay::ApplyScanAdjustment(hwc_rect_t *display_frame) {
-}
-
-int HWCDisplay::SetPanelBrightness(int level) {
-  int ret = 0;
-  if (display_intf_) {
-    ret = display_intf_->SetPanelBrightness(level);
-    validated_ = false;
-  } else {
-    ret = -EINVAL;
-  }
-
-  return ret;
-}
-
-int HWCDisplay::GetPanelBrightness(int *level) {
-  return display_intf_->GetPanelBrightness(level);
-}
-
-int HWCDisplay::ToggleScreenUpdates(bool enable) {
-  display_paused_ = enable ? false : true;
-  callbacks_->Refresh(HWC_DISPLAY_PRIMARY);
-  validated_ = false;
-  return 0;
-}
-
-int HWCDisplay::ColorSVCRequestRoute(const PPDisplayAPIPayload &in_payload,
-                                     PPDisplayAPIPayload *out_payload,
-                                     PPPendingParams *pending_action) {
-  int ret = 0;
-
-  if (display_intf_)
-    ret = display_intf_->ColorSVCRequestRoute(in_payload, out_payload, pending_action);
-  else
-    ret = -EINVAL;
-
-  return ret;
-}
-
-void HWCDisplay::SolidFillPrepare() {
-  if (solid_fill_enable_) {
-    if (solid_fill_layer_ == NULL) {
-      // Create a dummy layer here
-      solid_fill_layer_ = new Layer();
-    }
-    uint32_t primary_width = 0, primary_height = 0;
-    GetMixerResolution(&primary_width, &primary_height);
-
-    LayerBuffer *layer_buffer = &solid_fill_layer_->input_buffer;
-    layer_buffer->width = primary_width;
-    layer_buffer->height = primary_height;
-    layer_buffer->unaligned_width = primary_width;
-    layer_buffer->unaligned_height = primary_height;
-    layer_buffer->acquire_fence_fd = -1;
-    layer_buffer->release_fence_fd = -1;
-
-    solid_fill_layer_->composition = kCompositionGPU;
-    solid_fill_layer_->src_rect = solid_fill_rect_;
-    solid_fill_layer_->dst_rect = solid_fill_rect_;
-
-    solid_fill_layer_->blending = kBlendingPremultiplied;
-    solid_fill_layer_->solid_fill_color = 0;
-    solid_fill_layer_->solid_fill_info.bit_depth = solid_fill_color_.bit_depth;
-    solid_fill_layer_->solid_fill_info.red = solid_fill_color_.red;
-    solid_fill_layer_->solid_fill_info.blue = solid_fill_color_.blue;
-    solid_fill_layer_->solid_fill_info.green = solid_fill_color_.green;
-    solid_fill_layer_->solid_fill_info.alpha = solid_fill_color_.alpha;
-    solid_fill_layer_->frame_rate = 60;
-    solid_fill_layer_->visible_regions.push_back(solid_fill_layer_->dst_rect);
-    solid_fill_layer_->flags.updating = 1;
-    solid_fill_layer_->flags.solid_fill = true;
-  } else {
-    // delete the dummy layer
-    delete solid_fill_layer_;
-    solid_fill_layer_ = NULL;
-  }
-
-  if (solid_fill_enable_ && solid_fill_layer_) {
-    BuildSolidFillStack();
-    MarkLayersForGPUBypass();
-  }
-
-  return;
-}
-
-void HWCDisplay::SolidFillCommit() {
-  if (solid_fill_enable_ && solid_fill_layer_) {
-    LayerBuffer *layer_buffer = &solid_fill_layer_->input_buffer;
-    if (layer_buffer->release_fence_fd > 0) {
-      close(layer_buffer->release_fence_fd);
-      layer_buffer->release_fence_fd = -1;
-    }
-    if (layer_stack_.retire_fence_fd > 0) {
-      close(layer_stack_.retire_fence_fd);
-      layer_stack_.retire_fence_fd = -1;
-    }
-  }
-}
-
-int HWCDisplay::GetVisibleDisplayRect(hwc_rect_t *visible_rect) {
-  if (!IsValid(display_rect_)) {
-    return -EINVAL;
-  }
-
-  visible_rect->left = INT(display_rect_.left);
-  visible_rect->top = INT(display_rect_.top);
-  visible_rect->right = INT(display_rect_.right);
-  visible_rect->bottom = INT(display_rect_.bottom);
-  DLOGI("Dpy = %d Visible Display Rect(%d %d %d %d)", visible_rect->left, visible_rect->top,
-        visible_rect->right, visible_rect->bottom);
-
-  return 0;
-}
-
-void HWCDisplay::SetSecureDisplay(bool secure_display_active) {
-  if (secure_display_active_ != secure_display_active) {
-    DLOGI("SecureDisplay state changed from %d to %d Needs Flush!!", secure_display_active_,
-          secure_display_active);
-    secure_display_active_ = secure_display_active;
-    skip_prepare_ = true;
-  }
-  return;
-}
-
-int HWCDisplay::SetActiveDisplayConfig(uint32_t config) {
-  if (display_config_ == config) {
-    return 0;
-  }
-  display_config_ = config;
-  config_pending_ = true;
-  validated_ = false;
-
-  callbacks_->Refresh(id_);
-
-  return 0;
-}
-
-int HWCDisplay::GetActiveDisplayConfig(uint32_t *config) {
-  if (config_pending_) {
-    *config = display_config_;
-    return 0;
-  }
-  return display_intf_->GetActiveConfig(config) == kErrorNone ? 0 : -1;
-}
-
-int HWCDisplay::GetDisplayConfigCount(uint32_t *count) {
-  return display_intf_->GetNumVariableInfoConfigs(count) == kErrorNone ? 0 : -1;
-}
-
-int HWCDisplay::GetDisplayAttributesForConfig(int config,
-                                            DisplayConfigVariableInfo *display_attributes) {
-  return display_intf_->GetConfig(UINT32(config), display_attributes) == kErrorNone ? 0 : -1;
-}
-
-uint32_t HWCDisplay::GetUpdatingLayersCount(void) {
-  uint32_t updating_count = 0;
-
-  for (uint i = 0; i < layer_stack_.layers.size(); i++) {
-    auto layer = layer_stack_.layers.at(i);
-    if (layer->flags.updating) {
-      updating_count++;
-    }
-  }
-
-  return updating_count;
-}
-
-bool HWCDisplay::IsLayerUpdating(const Layer *layer) {
-  // Layer should be considered updating if
-  //   a) layer is in single buffer mode, or
-  //   b) valid dirty_regions(android specific hint for updating status), or
-  //   c) layer stack geometry has changed (TODO(user): Remove when SDM accepts
-  //      geometry_changed as bit fields).
-  return (layer->flags.single_buffer || IsSurfaceUpdated(layer->dirty_regions) ||
-          geometry_changes_);
-}
-
-bool HWCDisplay::IsSurfaceUpdated(const std::vector<LayerRect> &dirty_regions) {
-  // based on dirty_regions determine if its updating
-  // dirty_rect count = 0 - whole layer - updating.
-  // dirty_rect count = 1 or more valid rects - updating.
-  // dirty_rect count = 1 with (0,0,0,0) - not updating.
-  return (dirty_regions.empty() || IsValid(dirty_regions.at(0)));
-}
-
-uint32_t HWCDisplay::SanitizeRefreshRate(uint32_t req_refresh_rate) {
-  uint32_t refresh_rate = req_refresh_rate;
-
-  if (refresh_rate < min_refresh_rate_) {
-    // Pick the next multiple of request which is within the range
-    refresh_rate =
-        (((min_refresh_rate_ / refresh_rate) + ((min_refresh_rate_ % refresh_rate) ? 1 : 0)) *
-         refresh_rate);
-  }
-
-  if (refresh_rate > max_refresh_rate_) {
-    refresh_rate = max_refresh_rate_;
-  }
-
-  return refresh_rate;
-}
-
-DisplayClass HWCDisplay::GetDisplayClass() {
-  return display_class_;
-}
-
-std::string HWCDisplay::Dump() {
-  std::ostringstream os;
-  os << "\n------------HWC----------------\n";
-  os << "HWC2 display_id: " << id_ << std::endl;
-  for (auto layer : layer_set_) {
-    auto sdm_layer = layer->GetSDMLayer();
-    auto transform = sdm_layer->transform;
-    os << "layer: " << std::setw(4) << layer->GetId();
-    os << " z: " << layer->GetZ();
-    os << " compositon: " <<
-          to_string(layer->GetClientRequestedCompositionType()).c_str();
-    os << "/" <<
-          to_string(layer->GetDeviceSelectedCompositionType()).c_str();
-    os << " alpha: " << std::to_string(sdm_layer->plane_alpha).c_str();
-    os << " format: " << std::setw(22) << GetFormatString(sdm_layer->input_buffer.format);
-    os << " dataspace:" << std::hex << "0x" << std::setw(8) << std::setfill('0')
-       << layer->GetLayerDataspace() << std::dec << std::setfill(' ');
-    os << " transform: " << transform.rotation << "/" << transform.flip_horizontal <<
-          "/"<< transform.flip_vertical;
-    os << " buffer_id: " << std::hex << "0x" << sdm_layer->input_buffer.buffer_id << std::dec
-       << std::endl;
-  }
-
-  if (layer_stack_invalid_) {
-    os << "\n Layers added or removed but not reflected to SDM's layer stack yet\n";
-    return os.str();
-  }
-
-  if (color_mode_) {
-    os << "\n----------Color Modes---------\n";
-    color_mode_->Dump(&os);
-  }
-
-  if (display_intf_) {
-    os << "\n------------SDM----------------\n";
-    os << display_intf_->Dump();
-  }
-
-  os << "\n";
-
-  return os.str();
-}
-
-bool HWCDisplay::CanSkipValidate() {
-  if (solid_fill_enable_) {
-    DLOGV_IF(kTagClient, "Solid fill is enabled. Returning false.");
-    return false;
-  }
-
-  // Layer Stack checks
-  if ((layer_stack_.flags.hdr_present && (tone_mapper_ && tone_mapper_->IsActive())) ||
-     layer_stack_.flags.single_buffered_layer_present) {
-    DLOGV_IF(kTagClient, "HDR content present with tone mapping enabled. Returning false.");
-    return false;
-  }
-
-  if (client_target_->NeedsValidation()) {
-    DLOGV_IF(kTagClient, "Framebuffer target needs validation. Returning false.");
-    return false;
-  }
-
-  for (auto hwc_layer : layer_set_) {
-    if (hwc_layer->NeedsValidation()) {
-      DLOGV_IF(kTagClient, "hwc_layer[%d] needs validation. Returning false.",
-               hwc_layer->GetId());
-      return false;
-    }
-
-    // Do not allow Skip Validate, if any layer needs GPU Composition.
-    if (hwc_layer->GetDeviceSelectedCompositionType() == HWC2::Composition::Client) {
-      DLOGV_IF(kTagClient, "hwc_layer[%d] is GPU composed. Returning false.",
-               hwc_layer->GetId());
-      return false;
-    }
-  }
-
-  return true;
-}
-
-void HWCDisplay::UpdateRefreshRate() {
-  for (auto hwc_layer : layer_set_) {
-    if (hwc_layer->HasMetaDataRefreshRate()) {
-      continue;
-    }
-    auto layer = hwc_layer->GetSDMLayer();
-    layer->frame_rate = current_refresh_rate_;
-  }
-}
-
-}  // namespace sdm
diff --git a/sdm/libs/hwc2/hwc_display.h b/sdm/libs/hwc2/hwc_display.h
deleted file mode 100644
index fda8f05..0000000
--- a/sdm/libs/hwc2/hwc_display.h
+++ /dev/null
@@ -1,328 +0,0 @@
-/*
- * Copyright (c) 2014-2018, The Linux Foundation. All rights reserved.
- * Not a Contribution.
- *
- * Copyright 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.
- */
-
-#ifndef __HWC_DISPLAY_H__
-#define __HWC_DISPLAY_H__
-
-#include <sys/stat.h>
-#include <QService.h>
-#include <core/core_interface.h>
-#include <hardware/hwcomposer.h>
-#include <private/color_params.h>
-#include <qdMetaData.h>
-#include <map>
-#include <queue>
-#include <set>
-#include <string>
-#include <utility>
-#include <vector>
-
-#include "hwc_buffer_allocator.h"
-#include "hwc_callbacks.h"
-#include "hwc_layers.h"
-
-namespace sdm {
-
-class BlitEngine;
-class HWCToneMapper;
-
-// Subclasses set this to their type. This has to be different from DisplayType.
-// This is to avoid RTTI and dynamic_cast
-enum DisplayClass {
-  DISPLAY_CLASS_PRIMARY,
-  DISPLAY_CLASS_EXTERNAL,
-  DISPLAY_CLASS_VIRTUAL,
-  DISPLAY_CLASS_NULL
-};
-
-class HWCColorMode {
- public:
-  explicit HWCColorMode(DisplayInterface *display_intf);
-  ~HWCColorMode() {}
-  HWC2::Error Init();
-  HWC2::Error DeInit();
-  void Dump(std::ostringstream* os);
-  uint32_t GetColorModeCount();
-  HWC2::Error GetColorModes(uint32_t *out_num_modes, android_color_mode_t *out_modes);
-  HWC2::Error SetColorMode(android_color_mode_t mode);
-  HWC2::Error SetColorModeById(int32_t color_mode_id);
-  HWC2::Error SetColorTransform(const float *matrix, android_color_transform_t hint);
-  HWC2::Error RestoreColorTransform();
-
- private:
-  static const uint32_t kColorTransformMatrixCount = 16;
-
-  HWC2::Error HandleColorModeTransform(android_color_mode_t mode,
-                                       android_color_transform_t hint, const double *matrix);
-  void PopulateColorModes();
-  void PopulateTransform(const android_color_mode_t &mode,
-                         const std::string &color_mode, const std::string &color_transform);
-  template <class T>
-  void CopyColorTransformMatrix(const T *input_matrix, double *output_matrix) {
-    for (uint32_t i = 0; i < kColorTransformMatrixCount; i++) {
-      output_matrix[i] = static_cast<double>(input_matrix[i]);
-    }
-  }
-  HWC2::Error ApplyDefaultColorMode();
-
-  DisplayInterface *display_intf_ = NULL;
-  android_color_mode_t current_color_mode_ = HAL_COLOR_MODE_NATIVE;
-  android_color_transform_t current_color_transform_ = HAL_COLOR_TRANSFORM_IDENTITY;
-  typedef std::map<android_color_transform_t, std::string> TransformMap;
-  std::map<android_color_mode_t, TransformMap> color_mode_transform_map_ = {};
-  double color_matrix_[kColorTransformMatrixCount] = { 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 };
-};
-
-class HWCDisplay : public DisplayEventHandler {
- public:
-  enum DisplayStatus {
-    kDisplayStatusInvalid = -1,
-    kDisplayStatusOffline,
-    kDisplayStatusOnline,
-    kDisplayStatusPause,
-    kDisplayStatusResume,
-  };
-
-  virtual ~HWCDisplay() {}
-  virtual int Init();
-  virtual int Deinit();
-
-  // Framebuffer configurations
-  virtual void SetIdleTimeoutMs(uint32_t timeout_ms);
-  virtual HWC2::Error SetFrameDumpConfig(uint32_t count, uint32_t bit_mask_layer_type);
-  virtual DisplayError SetMaxMixerStages(uint32_t max_mixer_stages);
-  virtual DisplayError ControlPartialUpdate(bool enable, uint32_t *pending) {
-    return kErrorNotSupported;
-  }
-  virtual HWC2::PowerMode GetLastPowerMode();
-  virtual int SetFrameBufferResolution(uint32_t x_pixels, uint32_t y_pixels);
-  virtual void GetFrameBufferResolution(uint32_t *x_pixels, uint32_t *y_pixels);
-  virtual int SetDisplayStatus(DisplayStatus display_status);
-  virtual int OnMinHdcpEncryptionLevelChange(uint32_t min_enc_level);
-  virtual int Perform(uint32_t operation, ...);
-  virtual void SetSecureDisplay(bool secure_display_active);
-  virtual DisplayError SetMixerResolution(uint32_t width, uint32_t height);
-  virtual DisplayError GetMixerResolution(uint32_t *width, uint32_t *height);
-  virtual void GetPanelResolution(uint32_t *width, uint32_t *height);
-  virtual std::string Dump();
-
-  // Captures frame output in the buffer specified by output_buffer_info. The API is
-  // non-blocking and the client is expected to check operation status later on.
-  // Returns -1 if the input is invalid.
-  virtual int FrameCaptureAsync(const BufferInfo &output_buffer_info, bool post_processed) {
-    return -1;
-  }
-  // Returns the status of frame capture operation requested with FrameCaptureAsync().
-  // -EAGAIN : No status obtain yet, call API again after another frame.
-  // < 0 : Operation happened but failed.
-  // 0 : Success.
-  virtual int GetFrameCaptureStatus() { return -EAGAIN; }
-
-  virtual DisplayError SetDetailEnhancerConfig(const DisplayDetailEnhancerData &de_data) {
-    return kErrorNotSupported;
-  }
-
-  // Display Configurations
-  virtual int SetActiveDisplayConfig(uint32_t config);
-  virtual int GetActiveDisplayConfig(uint32_t *config);
-  virtual int GetDisplayConfigCount(uint32_t *count);
-  virtual int GetDisplayAttributesForConfig(int config,
-                                            DisplayConfigVariableInfo *display_attributes);
-  virtual int SetState(bool connected) {
-    return kErrorNotSupported;
-  }
-  virtual DisplayError Flush() {
-    return kErrorNotSupported;
-  }
-
-  int SetPanelBrightness(int level);
-  int GetPanelBrightness(int *level);
-  int ToggleScreenUpdates(bool enable);
-  int ColorSVCRequestRoute(const PPDisplayAPIPayload &in_payload, PPDisplayAPIPayload *out_payload,
-                           PPPendingParams *pending_action);
-  void SolidFillPrepare();
-  void SolidFillCommit();
-  DisplayClass GetDisplayClass();
-  int GetVisibleDisplayRect(hwc_rect_t *rect);
-  void BuildLayerStack(void);
-  void BuildSolidFillStack(void);
-  HWCLayer *GetHWCLayer(hwc2_layer_t layer_id);
-  void ResetValidation() { validated_ = false; }
-  uint32_t GetGeometryChanges() { return geometry_changes_; }
-
-  // HWC2 APIs
-  virtual HWC2::Error AcceptDisplayChanges(void);
-  virtual HWC2::Error GetActiveConfig(hwc2_config_t *out_config);
-  virtual HWC2::Error SetActiveConfig(hwc2_config_t config);
-  virtual HWC2::Error SetClientTarget(buffer_handle_t target, int32_t acquire_fence,
-                                      int32_t dataspace, hwc_region_t damage);
-  virtual HWC2::Error SetColorMode(android_color_mode_t mode) {
-    return HWC2::Error::Unsupported;
-  }
-  virtual HWC2::Error SetColorModeById(int32_t color_mode_id) {
-    return HWC2::Error::Unsupported;
-  }
-  virtual HWC2::Error RestoreColorTransform() {
-    return HWC2::Error::Unsupported;
-  }
-  virtual HWC2::Error SetColorTransform(const float *matrix, android_color_transform_t hint) {
-    return HWC2::Error::Unsupported;
-  }
-  virtual HWC2::Error HandleColorModeTransform(android_color_mode_t mode,
-                                               android_color_transform_t hint,
-                                               const double *matrix) {
-    return HWC2::Error::Unsupported;
-  }
-  virtual HWC2::Error GetDisplayConfigs(uint32_t *out_num_configs, hwc2_config_t *out_configs);
-  virtual HWC2::Error GetDisplayAttribute(hwc2_config_t config, HWC2::Attribute attribute,
-                                          int32_t *out_value);
-  virtual HWC2::Error GetClientTargetSupport(uint32_t width, uint32_t height, int32_t format,
-                                             int32_t dataspace);
-  virtual HWC2::Error GetColorModes(uint32_t *outNumModes, android_color_mode_t *outModes);
-  virtual HWC2::Error GetChangedCompositionTypes(uint32_t *out_num_elements,
-                                                 hwc2_layer_t *out_layers, int32_t *out_types);
-  virtual HWC2::Error GetDisplayRequests(int32_t *out_display_requests, uint32_t *out_num_elements,
-                                         hwc2_layer_t *out_layers, int32_t *out_layer_requests);
-  virtual HWC2::Error GetDisplayName(uint32_t *out_size, char *out_name);
-  virtual HWC2::Error GetDisplayType(int32_t *out_type);
-  virtual HWC2::Error SetCursorPosition(hwc2_layer_t layer, int x, int y);
-  virtual HWC2::Error SetVsyncEnabled(HWC2::Vsync enabled);
-  virtual HWC2::Error SetPowerMode(HWC2::PowerMode mode);
-  virtual HWC2::Error CreateLayer(hwc2_layer_t *out_layer_id);
-  virtual HWC2::Error DestroyLayer(hwc2_layer_t layer_id);
-  virtual HWC2::Error SetLayerZOrder(hwc2_layer_t layer_id, uint32_t z);
-  virtual HWC2::Error Validate(uint32_t *out_num_types, uint32_t *out_num_requests) = 0;
-  virtual HWC2::Error GetReleaseFences(uint32_t *out_num_elements, hwc2_layer_t *out_layers,
-                                       int32_t *out_fences);
-  virtual HWC2::Error Present(int32_t *out_retire_fence) = 0;
-  virtual HWC2::Error GetHdrCapabilities(uint32_t *out_num_types, int32_t* out_types,
-                                         float* out_max_luminance,
-                                         float* out_max_average_luminance,
-                                         float* out_min_luminance);
-  virtual HWC2::Error SetDisplayAnimating(bool animating) {
-    animating_ = animating;
-    validated_ = false;
-    return HWC2::Error::None;
-  }
-
- protected:
-  // Maximum number of layers supported by display manager.
-  static const uint32_t kMaxLayerCount = 32;
-
-  HWCDisplay(CoreInterface *core_intf, HWCCallbacks *callbacks, DisplayType type, hwc2_display_t id,
-             bool needs_blit, qService::QService *qservice, DisplayClass display_class,
-             BufferAllocator *buffer_allocator);
-
-  // DisplayEventHandler methods
-  virtual DisplayError VSync(const DisplayEventVSync &vsync);
-  virtual DisplayError Refresh();
-  virtual DisplayError CECMessage(char *message);
-  virtual DisplayError HandleEvent(DisplayEvent event);
-  virtual void DumpOutputBuffer(const BufferInfo &buffer_info, void *base, int fence);
-  virtual HWC2::Error PrepareLayerStack(uint32_t *out_num_types, uint32_t *out_num_requests);
-  virtual HWC2::Error CommitLayerStack(void);
-  virtual HWC2::Error PostCommitLayerStack(int32_t *out_retire_fence);
-  virtual DisplayError DisablePartialUpdateOneFrame() {
-    return kErrorNotSupported;
-  }
-  LayerBufferFormat GetSDMFormat(const int32_t &source, const int flags);
-  const char *GetDisplayString();
-  void MarkLayersForGPUBypass(void);
-  void MarkLayersForClientComposition(void);
-  virtual void ApplyScanAdjustment(hwc_rect_t *display_frame);
-  uint32_t GetUpdatingLayersCount(void);
-  bool IsSurfaceUpdated(const std::vector<LayerRect> &dirty_regions);
-  bool IsLayerUpdating(const Layer *layer);
-  uint32_t SanitizeRefreshRate(uint32_t req_refresh_rate);
-  virtual void GetUnderScanConfig() { }
-
-  enum {
-    INPUT_LAYER_DUMP,
-    OUTPUT_LAYER_DUMP,
-  };
-
-  bool validated_ = false;
-  bool layer_stack_invalid_ = true;
-  CoreInterface *core_intf_ = nullptr;
-  HWCCallbacks *callbacks_  = nullptr;
-  HWCBufferAllocator *buffer_allocator_ = NULL;
-  DisplayType type_;
-  hwc2_display_t id_;
-  bool needs_blit_ = false;
-  DisplayInterface *display_intf_ = NULL;
-  LayerStack layer_stack_;
-  HWCLayer *client_target_ = nullptr;                   // Also known as framebuffer target
-  std::map<hwc2_layer_t, HWCLayer *> layer_map_;        // Look up by Id - TODO
-  std::multiset<HWCLayer *, SortLayersByZ> layer_set_;  // Maintain a set sorted by Z
-  std::map<hwc2_layer_t, HWC2::Composition> layer_changes_;
-  std::map<hwc2_layer_t, HWC2::LayerRequest> layer_requests_;
-  bool flush_on_error_ = false;
-  bool flush_ = false;
-  uint32_t dump_frame_count_ = 0;
-  uint32_t dump_frame_index_ = 0;
-  bool dump_input_layers_ = false;
-  HWC2::PowerMode last_power_mode_;
-  bool swap_interval_zero_ = false;
-  bool display_paused_ = false;
-  uint32_t min_refresh_rate_ = 0;
-  uint32_t max_refresh_rate_ = 0;
-  uint32_t current_refresh_rate_ = 0;
-  bool use_metadata_refresh_rate_ = false;
-  uint32_t metadata_refresh_rate_ = 0;
-  uint32_t force_refresh_rate_ = 0;
-  bool boot_animation_completed_ = false;
-  bool shutdown_pending_ = false;
-  bool use_blit_comp_ = false;
-  bool secure_display_active_ = false;
-  bool skip_prepare_ = false;
-  bool solid_fill_enable_ = false;
-  Layer *solid_fill_layer_ = NULL;
-  LayerRect solid_fill_rect_ = {};
-  LayerSolidFill solid_fill_color_ = {};
-  LayerRect display_rect_;
-  bool color_tranform_failed_ = false;
-  HWCColorMode *color_mode_ = NULL;
-  HWCToneMapper *tone_mapper_ = nullptr;
-  uint32_t num_configs_ = 0;
-  int disable_hdr_handling_ = 0;  // disables HDR handling.
-  uint32_t display_config_ = 0;
-  bool config_pending_ = false;
-  bool pending_commit_ = false;
-
- private:
-  void DumpInputBuffers(void);
-  bool CanSkipValidate();
-  void UpdateRefreshRate();
-  qService::QService *qservice_ = NULL;
-  DisplayClass display_class_;
-  uint32_t geometry_changes_ = GeometryChanges::kNone;
-  bool skip_validate_ = false;
-  bool animating_ = false;
-};
-
-inline int HWCDisplay::Perform(uint32_t operation, ...) {
-  return 0;
-}
-
-}  // namespace sdm
-
-#endif  // __HWC_DISPLAY_H__
diff --git a/sdm/libs/hwc2/hwc_display_external.cpp b/sdm/libs/hwc2/hwc_display_external.cpp
deleted file mode 100644
index 21a9284..0000000
--- a/sdm/libs/hwc2/hwc_display_external.cpp
+++ /dev/null
@@ -1,301 +0,0 @@
-/*
-* Copyright (c) 2014-2018, The Linux Foundation. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without
-* modification, are permitted provided that the following conditions are
-* met:
-*     * Redistributions of source code must retain the above copyright
-*       notice, this list of conditions and the following disclaimer.
-*     * Redistributions in binary form must reproduce the above
-*       copyright notice, this list of conditions and the following
-*       disclaimer in the documentation and/or other materials provided
-*       with the distribution.
-*     * Neither the name of The Linux Foundation nor the names of its
-*       contributors may be used to endorse or promote products derived
-*       from this software without specific prior written permission.
-*
-* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
-* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
-* ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
-* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
-* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#include <cutils/properties.h>
-#include <utils/constants.h>
-#include <utils/debug.h>
-#include <algorithm>
-
-#include "hwc_display_external.h"
-#include "hwc_debugger.h"
-
-#define __CLASS__ "HWCDisplayExternal"
-
-namespace sdm {
-
-int HWCDisplayExternal::Create(CoreInterface *core_intf, HWCBufferAllocator *buffer_allocator,
-                               HWCCallbacks *callbacks, qService::QService *qservice,
-                               HWCDisplay **hwc_display) {
-  return Create(core_intf, buffer_allocator, callbacks, 0, 0, qservice, false, hwc_display);
-}
-
-int HWCDisplayExternal::Create(CoreInterface *core_intf, HWCBufferAllocator *buffer_allocator,
-                               HWCCallbacks *callbacks,
-                               uint32_t primary_width, uint32_t primary_height,
-                               qService::QService *qservice, bool use_primary_res,
-                               HWCDisplay **hwc_display) {
-  uint32_t external_width = 0;
-  uint32_t external_height = 0;
-  DisplayError error = kErrorNone;
-
-  HWCDisplay *hwc_display_external = new HWCDisplayExternal(core_intf, buffer_allocator, callbacks,
-                                                            qservice);
-  int status = hwc_display_external->Init();
-  if (status) {
-    delete hwc_display_external;
-    return status;
-  }
-
-  error = hwc_display_external->GetMixerResolution(&external_width, &external_height);
-  if (error != kErrorNone) {
-    Destroy(hwc_display_external);
-    return -EINVAL;
-  }
-
-  if (primary_width && primary_height) {
-    // use_primary_res means HWCDisplayExternal should directly set framebuffer resolution to the
-    // provided primary_width and primary_height
-    if (use_primary_res) {
-      external_width = primary_width;
-      external_height = primary_height;
-    } else {
-      int downscale_enabled = 0;
-      HWCDebugHandler::Get()->GetProperty(ENABLE_EXTERNAL_DOWNSCALE_PROP, &downscale_enabled);
-      if (downscale_enabled) {
-        GetDownscaleResolution(primary_width, primary_height, &external_width, &external_height);
-      }
-    }
-  }
-
-  status = hwc_display_external->SetFrameBufferResolution(external_width, external_height);
-  if (status) {
-    Destroy(hwc_display_external);
-    return status;
-  }
-
-  *hwc_display = hwc_display_external;
-
-  return status;
-}
-
-void HWCDisplayExternal::Destroy(HWCDisplay *hwc_display) {
-  hwc_display->Deinit();
-  delete hwc_display;
-}
-
-HWCDisplayExternal::HWCDisplayExternal(CoreInterface *core_intf,
-                                       HWCBufferAllocator *buffer_allocator,
-                                       HWCCallbacks *callbacks,
-                                       qService::QService *qservice)
-    : HWCDisplay(core_intf, callbacks, kHDMI, HWC_DISPLAY_EXTERNAL, false, qservice,
-                 DISPLAY_CLASS_EXTERNAL, buffer_allocator) {
-}
-
-HWC2::Error HWCDisplayExternal::Validate(uint32_t *out_num_types, uint32_t *out_num_requests) {
-  auto status = HWC2::Error::None;
-
-  if (secure_display_active_) {
-    MarkLayersForGPUBypass();
-    return status;
-  }
-
-  if (config_pending_) {
-    if (display_intf_->SetActiveConfig(display_config_) != kErrorNone) {
-      DLOGW("Invalid display config %d", display_config_);
-      // Reset the display config with active config
-      display_intf_->GetActiveConfig(&display_config_);
-    }
-  }
-
-  BuildLayerStack();
-
-  if (layer_set_.empty()) {
-    flush_ = true;
-    validated_ = true;
-    return status;
-  }
-
-  // TODO(user): SetRefreshRate need to follow new interface when added.
-
-  status = PrepareLayerStack(out_num_types, out_num_requests);
-  return status;
-}
-
-HWC2::Error HWCDisplayExternal::Present(int32_t *out_retire_fence) {
-  auto status = HWC2::Error::None;
-
-  if (!secure_display_active_) {
-    status = HWCDisplay::CommitLayerStack();
-    if (status == HWC2::Error::None) {
-      status = HWCDisplay::PostCommitLayerStack(out_retire_fence);
-    }
-  }
-  return status;
-}
-
-void HWCDisplayExternal::ApplyScanAdjustment(hwc_rect_t *display_frame) {
-  if ((underscan_width_ <= 0) || (underscan_height_ <= 0)) {
-    return;
-  }
-
-  float width_ratio = FLOAT(underscan_width_) / 100.0f;
-  float height_ratio = FLOAT(underscan_height_) / 100.0f;
-
-  uint32_t mixer_width = 0;
-  uint32_t mixer_height = 0;
-  GetMixerResolution(&mixer_width, &mixer_height);
-
-  if (mixer_width == 0 || mixer_height == 0) {
-    DLOGV("Invalid mixer dimensions (%d, %d)", mixer_width, mixer_height);
-    return;
-  }
-
-  uint32_t new_mixer_width = UINT32(mixer_width * FLOAT(1.0f - width_ratio));
-  uint32_t new_mixer_height = UINT32(mixer_height * FLOAT(1.0f - height_ratio));
-
-  int x_offset = INT((FLOAT(mixer_width) * width_ratio) / 2.0f);
-  int y_offset = INT((FLOAT(mixer_height) * height_ratio) / 2.0f);
-
-  display_frame->left = (display_frame->left * INT32(new_mixer_width) / INT32(mixer_width))
-                        + x_offset;
-  display_frame->top = (display_frame->top * INT32(new_mixer_height) / INT32(mixer_height)) +
-                       y_offset;
-  display_frame->right = ((display_frame->right * INT32(new_mixer_width)) / INT32(mixer_width)) +
-                         x_offset;
-  display_frame->bottom = ((display_frame->bottom * INT32(new_mixer_height)) / INT32(mixer_height))
-                          + y_offset;
-}
-
-void HWCDisplayExternal::SetSecureDisplay(bool secure_display_active) {
-  if (secure_display_active_ != secure_display_active) {
-    secure_display_active_ = secure_display_active;
-
-    if (secure_display_active_) {
-      DisplayError error = display_intf_->Flush();
-      validated_ = false;
-      if (error != kErrorNone) {
-        DLOGE("Flush failed. Error = %d", error);
-      }
-    }
-  }
-  return;
-}
-
-static void AdjustSourceResolution(uint32_t dst_width, uint32_t dst_height, uint32_t *src_width,
-                                   uint32_t *src_height) {
-  *src_height = (dst_width * (*src_height)) / (*src_width);
-  *src_width = dst_width;
-}
-
-void HWCDisplayExternal::GetDownscaleResolution(uint32_t primary_width, uint32_t primary_height,
-                                                uint32_t *non_primary_width,
-                                                uint32_t *non_primary_height) {
-  uint32_t primary_area = primary_width * primary_height;
-  uint32_t non_primary_area = (*non_primary_width) * (*non_primary_height);
-
-  if (primary_area > non_primary_area) {
-    if (primary_height > primary_width) {
-      std::swap(primary_height, primary_width);
-    }
-    AdjustSourceResolution(primary_width, primary_height, non_primary_width, non_primary_height);
-  }
-}
-
-int HWCDisplayExternal::SetState(bool connected) {
-  DisplayError error = kErrorNone;
-  DisplayState state = kStateOff;
-  DisplayConfigVariableInfo fb_config = {};
-
-  if (connected) {
-    if (display_null_.IsActive()) {
-      error = core_intf_->CreateDisplay(type_, this, &display_intf_);
-      if (error != kErrorNone) {
-        DLOGE("Display create failed. Error = %d display_type %d event_handler %p disp_intf %p",
-              error, type_, this, &display_intf_);
-        return -EINVAL;
-      }
-
-      // Restore HDMI attributes when display is reconnected.
-      // This is to ensure that surfaceflinger & sdm are in sync.
-      display_null_.GetFrameBufferConfig(&fb_config);
-      int status = SetFrameBufferResolution(fb_config.x_pixels, fb_config.y_pixels);
-      if (status) {
-        DLOGW("Set frame buffer config failed. Error = %d", error);
-        return -1;
-      }
-      int release_fence = -1;
-      display_null_.GetDisplayState(&state);
-      display_intf_->SetDisplayState(state, &release_fence);
-      if (release_fence >= 0) {
-        ::close(release_fence);
-      }
-      validated_ = false;
-
-      SetVsyncEnabled(HWC2::Vsync::Enable);
-
-      display_null_.SetActive(false);
-      DLOGI("Display is connected successfully.");
-    } else {
-      DLOGI("Display is already connected.");
-    }
-  } else {
-    if (!display_null_.IsActive()) {
-      int release_fence = -1;
-      // Preserve required attributes of HDMI display that surfaceflinger sees.
-      // Restore HDMI attributes when display is reconnected.
-      display_intf_->GetDisplayState(&state);
-      display_null_.SetDisplayState(state, &release_fence);
-      if (release_fence >= 0) {
-        ::close(release_fence);
-      }
-
-      error = display_intf_->GetFrameBufferConfig(&fb_config);
-      if (error != kErrorNone) {
-        DLOGW("Get frame buffer config failed. Error = %d", error);
-        return -1;
-      }
-      display_null_.SetFrameBufferConfig(fb_config);
-
-      SetVsyncEnabled(HWC2::Vsync::Disable);
-      core_intf_->DestroyDisplay(display_intf_);
-      display_intf_ = &display_null_;
-
-      display_null_.SetActive(true);
-      DLOGI("Display is disconnected successfully.");
-    } else {
-      DLOGI("Display is already disconnected.");
-    }
-  }
-
-  return 0;
-}
-
-void HWCDisplayExternal::GetUnderScanConfig() {
-  if (!display_intf_->IsUnderscanSupported()) {
-    // Read user defined underscan width and height
-    HWCDebugHandler::Get()->GetProperty(EXTERNAL_ACTION_SAFE_WIDTH_PROP, &underscan_width_);
-    HWCDebugHandler::Get()->GetProperty(EXTERNAL_ACTION_SAFE_HEIGHT_PROP, &underscan_height_);
-  }
-}
-
-DisplayError HWCDisplayExternal::Flush() {
-  return display_intf_->Flush();
-}
-
-}  // namespace sdm
diff --git a/sdm/libs/hwc2/hwc_display_external.h b/sdm/libs/hwc2/hwc_display_external.h
deleted file mode 100644
index 5eb1704..0000000
--- a/sdm/libs/hwc2/hwc_display_external.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright (c) 2014-2018, The Linux Foundation. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
-    * Redistributions of source code must retain the above copyright
-      notice, this list of conditions and the following disclaimer.
-    * Redistributions in binary form must reproduce the above
-      copyright notice, this list of conditions and the following
-      disclaimer in the documentation and/or other materials provided
-      with the distribution.
-    * Neither the name of The Linux Foundation nor the names of its
-      contributors may be used to endorse or promote products derived
-      from this software without specific prior written permission.
-
- * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef __HWC_DISPLAY_EXTERNAL_H__
-#define __HWC_DISPLAY_EXTERNAL_H__
-
-#include "hwc_display.h"
-#include "display_null.h"
-
-namespace sdm {
-
-class HWCDisplayExternal : public HWCDisplay {
- public:
-  static int Create(CoreInterface *core_intf, HWCBufferAllocator *buffer_allocator,
-                    HWCCallbacks *callbacks, uint32_t primary_width,
-                    uint32_t primary_height, qService::QService *qservice, bool use_primary_res,
-                    HWCDisplay **hwc_display);
-  static int Create(CoreInterface *core_intf, HWCBufferAllocator *buffer_allocator,
-                    HWCCallbacks *callbacks, qService::QService *qservice,
-                    HWCDisplay **hwc_display);
-  static void Destroy(HWCDisplay *hwc_display);
-  virtual HWC2::Error Validate(uint32_t *out_num_types, uint32_t *out_num_requests);
-  virtual HWC2::Error Present(int32_t *out_retire_fence);
-  virtual void SetSecureDisplay(bool secure_display_active);
-  virtual int SetState(bool connected);
-  virtual DisplayError Flush();
-
- private:
-  HWCDisplayExternal(CoreInterface *core_intf, HWCBufferAllocator *buffer_allocator,
-                     HWCCallbacks *callbacks, qService::QService *qservice);
-  void ApplyScanAdjustment(hwc_rect_t *display_frame);
-  void GetUnderScanConfig();
-  static void GetDownscaleResolution(uint32_t primary_width, uint32_t primary_height,
-                                     uint32_t *virtual_width, uint32_t *virtual_height);
-
-  DisplayNull display_null_;
-  int underscan_width_ = 0;
-  int underscan_height_ = 0;
-};
-
-}  // namespace sdm
-
-#endif  // __HWC_DISPLAY_EXTERNAL_H__
diff --git a/sdm/libs/hwc2/hwc_display_external_test.cpp b/sdm/libs/hwc2/hwc_display_external_test.cpp
deleted file mode 100644
index 8551854..0000000
--- a/sdm/libs/hwc2/hwc_display_external_test.cpp
+++ /dev/null
@@ -1,751 +0,0 @@
-/*
-* Copyright (c) 2017, The Linux Foundation. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without
-* modification, are permitted provided that the following conditions are
-* met:
-*     * Redistributions of source code must retain the above copyright
-*       notice, this list of conditions and the following disclaimer.
-*     * Redistributions in binary form must reproduce the above
-*       copyright notice, this list of conditions and the following
-*       disclaimer in the documentation and/or other materials provided
-*       with the distribution.
-*     * Neither the name of The Linux Foundation nor the names of its
-*       contributors may be used to endorse or promote products derived
-*       from this software without specific prior written permission.
-*
-* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
-* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
-* ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
-* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
-* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#include <cutils/properties.h>
-#include <sys/mman.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <utils/constants.h>
-#include <utils/debug.h>
-#include <utils/formats.h>
-#include <algorithm>
-#include <array>
-#include <sstream>
-#include <string>
-#include <fstream>
-
-#include "hwc_display_external_test.h"
-#include "hwc_debugger.h"
-
-#define __CLASS__ "HWCDisplayExternalTest"
-
-namespace sdm {
-
-using std::array;
-
-int HWCDisplayExternalTest::Create(CoreInterface *core_intf,
-                                   HWCBufferAllocator *buffer_allocator,
-                                   HWCCallbacks *callbacks,
-                                   qService::QService *qservice, uint32_t panel_bpp,
-                                   uint32_t pattern_type, HWCDisplay **hwc_display) {
-  HWCDisplay *hwc_external_test = new HWCDisplayExternalTest(core_intf, buffer_allocator,
-                                                             callbacks, qservice,
-                                                             panel_bpp, pattern_type);
-
-  int status = static_cast<HWCDisplayExternalTest *>(hwc_external_test)->Init();
-  if (status) {
-    delete hwc_external_test;
-    return status;
-  }
-
-  *hwc_display = hwc_external_test;
-
-  DLOGE("EXTERNAL panel_bpp %d, pattern_type %d", panel_bpp, pattern_type);
-
-  return status;
-}
-
-void HWCDisplayExternalTest::Destroy(HWCDisplay *hwc_display) {
-  static_cast<HWCDisplayExternalTest *>(hwc_display)->Deinit();
-
-  delete hwc_display;
-}
-
-HWCDisplayExternalTest::HWCDisplayExternalTest(CoreInterface *core_intf,
-                                               HWCBufferAllocator *buffer_allocator,
-                                               HWCCallbacks *callbacks,
-                                               qService::QService *qservice, uint32_t panel_bpp,
-                                               uint32_t pattern_type)
-  : HWCDisplay(core_intf, callbacks, kHDMI, HWC_DISPLAY_EXTERNAL, false, qservice,
-               DISPLAY_CLASS_EXTERNAL, buffer_allocator), panel_bpp_(panel_bpp),
-               pattern_type_(pattern_type) {
-}
-
-int HWCDisplayExternalTest::Init() {
-  uint32_t external_width = 0;
-  uint32_t external_height = 0;
-
-  int status = HWCDisplay::Init();
-  if (status) {
-      DLOGE("HWCDisplayExternalTest::Init  status = %d ", status);
-    return status;
-  }
-
-  status = CreateLayerStack();
-  if (status) {
-    Deinit();
-    return status;
-  }
-
-  DisplayError error = HWCDisplay::GetMixerResolution(&external_width, &external_height);
-  if (error != kErrorNone) {
-    Deinit();
-    return -EINVAL;
-  }
-
-  status = HWCDisplay::SetFrameBufferResolution(external_width, external_height);
-  if (status) {
-    Deinit();
-    DLOGE("HWCDisplayExternalTest:: set fb resolution status = %d ", status);
-    return status;
-  }
-
-  return status;
-}
-
-int HWCDisplayExternalTest::Deinit() {
-  DestroyLayerStack();
-  return HWCDisplay::Deinit();
-}
-
-
-HWC2::Error HWCDisplayExternalTest::Validate(uint32_t *out_num_types, uint32_t *out_num_requests) {
-  auto status = HWC2::Error::None;
-  if (secure_display_active_) {
-    MarkLayersForGPUBypass();
-    return status;
-  }
-
-  if (layer_set_.empty()) {
-      flush_ = true;
-      return status;
-  }
-
-  if (shutdown_pending_) {
-    return status;
-  }
-  DisplayError error = display_intf_->Prepare(&layer_stack_);
-  if (error != kErrorNone) {
-    if (error == kErrorShutDown) {
-      shutdown_pending_ = true;
-    } else if (error != kErrorPermission) {
-      DLOGE("Prepare failed. Error = %d", error);
-      // To prevent surfaceflinger infinite wait, flush the previous frame during Commit()
-      // so that previous buffer and fences are released, and override the error.
-      flush_ = true;
-    }
-  }
-
-  MarkLayersForGPUBypass();
-
-  return  status;
-}
-
-HWC2::Error HWCDisplayExternalTest::Present(int32_t *out_retire_fence) {
-  auto status = HWC2::Error::None;
-
-  if (secure_display_active_) {
-    return status;
-  }
-
-  if (shutdown_pending_) {
-    return status;
-  }
-
-  DumpInputBuffer();
-
-  if (!flush_) {
-    DisplayError error = kErrorUndefined;
-    error = display_intf_->Commit(&layer_stack_);
-    if (error == kErrorNone) {
-      // A commit is successfully submitted, start flushing on failure now onwards.
-      flush_on_error_ = true;
-    } else if (error == kErrorShutDown) {
-      shutdown_pending_ = true;
-      status = HWC2::Error::Unsupported;
-    } else if (error == kErrorNotValidated) {
-      status = HWC2::Error::NotValidated;
-    } else if (error != kErrorPermission) {
-      DLOGE("Commit failed. Error = %d", error);
-        // To prevent surfaceflinger infinite wait, flush the previous frame during Commit()
-        // so that previous buffer and fences are released, and override the error.
-        flush_ = true;
-    }
-  }
-  PostCommit(out_retire_fence);
-  return status;
-}
-
-void HWCDisplayExternalTest::SetSecureDisplay(bool secure_display_active) {
-  if (secure_display_active_ != secure_display_active) {
-    secure_display_active_ = secure_display_active;
-
-    if (secure_display_active_) {
-      DisplayError error = display_intf_->Flush();
-      if (error != kErrorNone) {
-        DLOGE("Flush failed. Error = %d", error);
-      }
-    }
-  }
-  return;
-}
-
-int HWCDisplayExternalTest::Perform(uint32_t operation, ...) {
-  return 0;
-}
-
-void HWCDisplayExternalTest::DumpInputBuffer() {
-  if (!dump_frame_count_ || flush_ || !dump_input_layers_) {
-    return;
-  }
-
-  const char *dir_path = "/data/vendor/display/frame_dump_external";
-  uint32_t width = buffer_info_.alloc_buffer_info.aligned_width;
-  uint32_t height = buffer_info_.alloc_buffer_info.aligned_height;
-  string format_str = GetFormatString(buffer_info_.buffer_config.format);
-
-  char *buffer = reinterpret_cast<char *>(mmap(NULL, buffer_info_.alloc_buffer_info.size,
-                                                PROT_READ|PROT_WRITE, MAP_SHARED,
-                                                buffer_info_.alloc_buffer_info.fd, 0));
-  if (buffer == MAP_FAILED) {
-    DLOGW("mmap failed. err = %d", errno);
-    return;
-  }
-
-  if (mkdir(dir_path, 0777) != 0 && errno != EEXIST) {
-    DLOGW("Failed to create %s directory errno = %d, desc = %s", dir_path, errno, strerror(errno));
-    return;
-  }
-
-  // if directory exists already, need to explicitly change the permission.
-  if (errno == EEXIST && chmod(dir_path, 0777) != 0) {
-    DLOGW("Failed to change permissions on %s directory", dir_path);
-    return;
-  }
-
-  if (buffer) {
-    std::stringstream dump_file_name;
-    dump_file_name << dir_path;
-    dump_file_name << "/input_layer_" << width << "x" << height << "_" << format_str << ".raw";
-
-    std::fstream fs;
-    fs.open(dump_file_name.str().c_str(), std::fstream::in | std::fstream::out | std::fstream::app);
-    if (!fs.is_open()) {
-      DLOGI("File open failed %s", dump_file_name.str().c_str());
-      return;
-    }
-
-    fs.write(buffer, (std::streamsize)buffer_info_.alloc_buffer_info.size);
-    fs.close();
-
-    DLOGI("Frame Dump %s: is successful", dump_file_name.str().c_str());
-  }
-
-  // Dump only once as the content is going to be same for all draw cycles
-  if (dump_frame_count_) {
-    dump_frame_count_ = 0;
-  }
-
-  if (munmap(buffer, buffer_info_.alloc_buffer_info.size) != 0) {
-    DLOGW("munmap failed. err = %d", errno);
-    return;
-  }
-}
-
-void HWCDisplayExternalTest::CalcCRC(uint32_t color_val, std::bitset<16> *crc_data) {
-  std::bitset<16> color = {};
-  std::bitset<16> temp_crc = {};
-
-  switch (panel_bpp_) {
-    case kDisplayBpp18:
-      color = (color_val & 0xFC) << 8;
-      break;
-    case kDisplayBpp24:
-      color = color_val << 8;
-      break;
-    case kDisplayBpp30:
-      color = color_val << 6;
-      break;
-    default:
-      return;
-  }
-
-  temp_crc[15] = (*crc_data)[0] ^ (*crc_data)[1] ^ (*crc_data)[2] ^ (*crc_data)[3] ^
-                 (*crc_data)[4] ^ (*crc_data)[5] ^ (*crc_data)[6] ^ (*crc_data)[7] ^
-                 (*crc_data)[8] ^ (*crc_data)[9] ^ (*crc_data)[10] ^ (*crc_data)[11] ^
-                 (*crc_data)[12] ^ (*crc_data)[14] ^ (*crc_data)[15] ^ color[0] ^ color[1] ^
-                 color[2] ^ color[3] ^ color[4] ^ color[5] ^ color[6] ^ color[7] ^ color[8] ^
-                 color[9] ^ color[10] ^ color[11] ^ color[12] ^ color[14] ^ color[15];
-
-  temp_crc[14] = (*crc_data)[12] ^ (*crc_data)[13] ^ color[12] ^ color[13];
-  temp_crc[13] = (*crc_data)[11] ^ (*crc_data)[12] ^ color[11] ^ color[12];
-  temp_crc[12] = (*crc_data)[10] ^ (*crc_data)[11] ^ color[10] ^ color[11];
-  temp_crc[11] = (*crc_data)[9] ^ (*crc_data)[10] ^ color[9] ^ color[10];
-  temp_crc[10] = (*crc_data)[8] ^ (*crc_data)[9] ^ color[8] ^ color[9];
-  temp_crc[9] = (*crc_data)[7] ^ (*crc_data)[8] ^ color[7] ^ color[8];
-  temp_crc[8] = (*crc_data)[6] ^ (*crc_data)[7] ^ color[6] ^ color[7];
-  temp_crc[7] = (*crc_data)[5] ^ (*crc_data)[6] ^ color[5] ^ color[6];
-  temp_crc[6] = (*crc_data)[4] ^ (*crc_data)[5] ^ color[4] ^ color[5];
-  temp_crc[5] = (*crc_data)[3] ^ (*crc_data)[4] ^ color[3] ^ color[4];
-  temp_crc[4] = (*crc_data)[2] ^ (*crc_data)[3] ^ color[2] ^ color[3];
-  temp_crc[3] = (*crc_data)[1] ^ (*crc_data)[2] ^ (*crc_data)[15] ^ color[1] ^ color[2] ^ color[15];
-  temp_crc[2] = (*crc_data)[0] ^ (*crc_data)[1] ^ (*crc_data)[14] ^ color[0] ^ color[1] ^ color[14];
-
-  temp_crc[1] = (*crc_data)[1] ^ (*crc_data)[2] ^ (*crc_data)[3] ^ (*crc_data)[4] ^ (*crc_data)[5] ^
-                (*crc_data)[6] ^ (*crc_data)[7] ^ (*crc_data)[8] ^ (*crc_data)[9] ^
-                (*crc_data)[10] ^ (*crc_data)[11] ^ (*crc_data)[12] ^ (*crc_data)[13] ^
-                (*crc_data)[14] ^ color[1] ^ color[2] ^ color[3] ^ color[4] ^ color[5] ^ color[6] ^
-                color[7] ^ color[8] ^ color[9] ^ color[10] ^ color[11] ^ color[12] ^ color[13] ^
-                color[14];
-
-  temp_crc[0] = (*crc_data)[0] ^ (*crc_data)[1] ^ (*crc_data)[2] ^ (*crc_data)[3] ^ (*crc_data)[4] ^
-                (*crc_data)[5] ^ (*crc_data)[6] ^ (*crc_data)[7] ^ (*crc_data)[8] ^ (*crc_data)[9] ^
-                (*crc_data)[10] ^ (*crc_data)[11] ^ (*crc_data)[12] ^ (*crc_data)[13] ^
-                (*crc_data)[15] ^ color[0] ^ color[1] ^ color[2] ^ color[3] ^ color[4] ^ color[5] ^
-                color[6] ^ color[7] ^ color[8] ^ color[9] ^ color[10] ^ color[11] ^ color[12] ^
-                color[13] ^ color[15];
-
-  (*crc_data) = temp_crc;
-}
-
-int HWCDisplayExternalTest::FillBuffer() {
-  uint8_t *buffer = reinterpret_cast<uint8_t *>(mmap(NULL, buffer_info_.alloc_buffer_info.size,
-                                                PROT_READ|PROT_WRITE, MAP_SHARED,
-                                                buffer_info_.alloc_buffer_info.fd, 0));
-  if (buffer == MAP_FAILED) {
-    DLOGE("mmap failed. err = %d", errno);
-    return -EFAULT;
-  }
-
-  switch (pattern_type_) {
-    case kPatternColorRamp:
-      GenerateColorRamp(buffer);
-      break;
-    case kPatternBWVertical:
-      GenerateBWVertical(buffer);
-      break;
-    case kPatternColorSquare:
-      GenerateColorSquare(buffer);
-      break;
-    default:
-      DLOGW("Invalid Pattern type %d", pattern_type_);
-      return -EINVAL;
-  }
-
-  if (munmap(buffer, buffer_info_.alloc_buffer_info.size) != 0) {
-    DLOGE("munmap failed. err = %d", errno);
-    return -EFAULT;
-  }
-
-  return 0;
-}
-
-int HWCDisplayExternalTest::GetStride(LayerBufferFormat format, uint32_t width, uint32_t *stride) {
-  switch (format) {
-  case kFormatRGBA8888:
-  case kFormatRGBA1010102:
-    *stride = width * 4;
-    break;
-  case kFormatRGB888:
-    *stride = width * 3;
-    break;
-  default:
-    DLOGE("Unsupported format type %d", format);
-    return -EINVAL;
-  }
-
-  return 0;
-}
-
-void HWCDisplayExternalTest::PixelCopy(uint32_t red, uint32_t green, uint32_t blue, uint32_t alpha,
-                                       uint8_t **buffer) {
-  LayerBufferFormat format = buffer_info_.buffer_config.format;
-
-  switch (format) {
-    case kFormatRGBA8888:
-      *(*buffer)++ = UINT8(red & 0xFF);
-      *(*buffer)++ = UINT8(green & 0xFF);
-      *(*buffer)++ = UINT8(blue & 0xFF);
-      *(*buffer)++ = UINT8(alpha & 0xFF);
-      break;
-    case kFormatRGB888:
-      *(*buffer)++ = UINT8(red & 0xFF);
-      *(*buffer)++ = UINT8(green & 0xFF);
-      *(*buffer)++ = UINT8(blue & 0xFF);
-      break;
-    case kFormatRGBA1010102:
-      // Lower 8 bits of red
-      *(*buffer)++ = UINT8(red & 0xFF);
-
-      // Upper 2 bits of Red + Lower 6 bits of green
-      *(*buffer)++ = UINT8(((green & 0x3F) << 2) | ((red >> 0x8) & 0x3));
-
-      // Upper 4 bits of green + Lower 4 bits of blue
-      *(*buffer)++ = UINT8(((blue & 0xF) << 4) | ((green >> 6) & 0xF));
-
-      // Upper 6 bits of blue + Lower 2 bits of alpha
-      *(*buffer)++ = UINT8(((alpha & 0x3) << 6) | ((blue >> 4) & 0x3F));
-      break;
-    default:
-      DLOGW("format not supported format = %d", format);
-      break;
-  }
-}
-
-void HWCDisplayExternalTest::GenerateColorRamp(uint8_t *buffer) {
-  uint32_t width = buffer_info_.buffer_config.width;
-  uint32_t height = buffer_info_.buffer_config.height;
-  LayerBufferFormat format = buffer_info_.buffer_config.format;
-  uint32_t aligned_width = buffer_info_.alloc_buffer_info.aligned_width;
-  uint32_t buffer_stride = 0;
-
-  uint32_t color_ramp = 0;
-  uint32_t start_color_val = 0;
-  uint32_t step_size = 1;
-  uint32_t ramp_width = 0;
-  uint32_t ramp_height = 0;
-  uint32_t shift_by = 0;
-
-  std::bitset<16> crc_red = {};
-  std::bitset<16> crc_green = {};
-  std::bitset<16> crc_blue = {};
-
-  switch (panel_bpp_) {
-    case kDisplayBpp18:
-      ramp_height = 64;
-      ramp_width = 64;
-      shift_by = 2;
-      break;
-    case kDisplayBpp24:
-      ramp_height = 64;
-      ramp_width = 256;
-      break;
-    case kDisplayBpp30:
-      ramp_height = 32;
-      ramp_width = 256;
-      start_color_val = 0x180;
-      break;
-    default:
-      return;
-  }
-
-  GetStride(format, aligned_width, &buffer_stride);
-
-  for (uint32_t loop_height = 0; loop_height < height; loop_height++) {
-    uint32_t color_value = start_color_val;
-    uint8_t *temp = buffer + (loop_height * buffer_stride);
-
-    for (uint32_t loop_width = 0; loop_width < width; loop_width++) {
-      if (color_ramp == kColorRedRamp) {
-        PixelCopy(color_value, 0, 0, 0, &temp);
-        CalcCRC(color_value, &crc_red);
-        CalcCRC(0, &crc_green);
-        CalcCRC(0, &crc_blue);
-      }
-      if (color_ramp == kColorGreenRamp) {
-        PixelCopy(0, color_value, 0, 0, &temp);
-        CalcCRC(0, &crc_red);
-        CalcCRC(color_value, &crc_green);
-        CalcCRC(0, &crc_blue);
-      }
-      if (color_ramp == kColorBlueRamp) {
-        PixelCopy(0, 0, color_value, 0, &temp);
-        CalcCRC(0, &crc_red);
-        CalcCRC(0, &crc_green);
-        CalcCRC(color_value, &crc_blue);
-      }
-      if (color_ramp == kColorWhiteRamp) {
-        PixelCopy(color_value, color_value, color_value, 0, &temp);
-        CalcCRC(color_value, &crc_red);
-        CalcCRC(color_value, &crc_green);
-        CalcCRC(color_value, &crc_blue);
-      }
-
-      color_value = (start_color_val + (((loop_width + 1) % ramp_width) * step_size)) << shift_by;
-    }
-
-    if (panel_bpp_ == kDisplayBpp30 && ((loop_height + 1) % ramp_height) == 0) {
-      if (start_color_val == 0x180) {
-        start_color_val = 0;
-        step_size = 4;
-      } else {
-        start_color_val = 0x180;
-        step_size = 1;
-        color_ramp = (color_ramp + 1) % 4;
-      }
-      continue;
-    }
-
-    if (((loop_height + 1) % ramp_height) == 0) {
-      color_ramp = (color_ramp + 1) % 4;
-    }
-  }
-
-  DLOGI("CRC red %x", crc_red.to_ulong());
-  DLOGI("CRC green %x", crc_green.to_ulong());
-  DLOGI("CRC blue %x", crc_blue.to_ulong());
-}
-
-void HWCDisplayExternalTest::GenerateBWVertical(uint8_t *buffer) {
-  uint32_t width = buffer_info_.buffer_config.width;
-  uint32_t height = buffer_info_.buffer_config.height;
-  LayerBufferFormat format = buffer_info_.buffer_config.format;
-  uint32_t aligned_width = buffer_info_.alloc_buffer_info.aligned_width;
-  uint32_t buffer_stride = 0;
-  uint32_t bits_per_component = panel_bpp_ / 3;
-  uint32_t max_color_val = (1 << bits_per_component) - 1;
-
-  std::bitset<16> crc_red = {};
-  std::bitset<16> crc_green = {};
-  std::bitset<16> crc_blue = {};
-
-  if (panel_bpp_ == kDisplayBpp18) {
-    max_color_val <<= 2;
-  }
-
-  GetStride(format, aligned_width, &buffer_stride);
-
-  for (uint32_t loop_height = 0; loop_height < height; loop_height++) {
-    uint32_t color = 0;
-    uint8_t *temp = buffer + (loop_height * buffer_stride);
-
-    for (uint32_t loop_width = 0; loop_width < width; loop_width++) {
-      if (color == kColorBlack) {
-        PixelCopy(0, 0, 0, 0, &temp);
-        CalcCRC(0, &crc_red);
-        CalcCRC(0, &crc_green);
-        CalcCRC(0, &crc_blue);
-      }
-      if (color == kColorWhite) {
-        PixelCopy(max_color_val, max_color_val, max_color_val, 0, &temp);
-        CalcCRC(max_color_val, &crc_red);
-        CalcCRC(max_color_val, &crc_green);
-        CalcCRC(max_color_val, &crc_blue);
-      }
-
-      color = (color + 1) % 2;
-    }
-  }
-
-  DLOGI("CRC red %x", crc_red.to_ulong());
-  DLOGI("CRC green %x", crc_green.to_ulong());
-  DLOGI("CRC blue %x", crc_blue.to_ulong());
-}
-
-void HWCDisplayExternalTest::GenerateColorSquare(uint8_t *buffer) {
-  uint32_t width = buffer_info_.buffer_config.width;
-  uint32_t height = buffer_info_.buffer_config.height;
-  LayerBufferFormat format = buffer_info_.buffer_config.format;
-  uint32_t aligned_width = buffer_info_.alloc_buffer_info.aligned_width;
-  uint32_t buffer_stride = 0;
-  uint32_t max_color_val = 0;
-  uint32_t min_color_val = 0;
-
-  std::bitset<16> crc_red = {};
-  std::bitset<16> crc_green = {};
-  std::bitset<16> crc_blue = {};
-
-  switch (panel_bpp_) {
-    case kDisplayBpp18:
-      max_color_val = 63 << 2;  // CEA Dynamic range for 18bpp 0 - 63
-      min_color_val = 0;
-      break;
-    case kDisplayBpp24:
-      max_color_val = 235;  // CEA Dynamic range for 24bpp 16 - 235
-      min_color_val = 16;
-      break;
-    case kDisplayBpp30:
-      max_color_val = 940;  // CEA Dynamic range for 30bpp 64 - 940
-      min_color_val = 64;
-      break;
-    default:
-      return;
-  }
-
-  array<array<uint32_t, 3>, 8> colors = {{
-    {{max_color_val, max_color_val, max_color_val}},  // White Color
-    {{max_color_val, max_color_val, min_color_val}},  // Yellow Color
-    {{min_color_val, max_color_val, max_color_val}},  // Cyan Color
-    {{min_color_val, max_color_val, min_color_val}},  // Green Color
-    {{max_color_val, min_color_val, max_color_val}},  // Megenta Color
-    {{max_color_val, min_color_val, min_color_val}},  // Red Color
-    {{min_color_val, min_color_val, max_color_val}},  // Blue Color
-    {{min_color_val, min_color_val, min_color_val}},  // Black Color
-  }};
-
-  GetStride(format, aligned_width, &buffer_stride);
-
-  for (uint32_t loop_height = 0; loop_height < height; loop_height++) {
-    uint32_t color = 0;
-    uint8_t *temp = buffer + (loop_height * buffer_stride);
-
-    for (uint32_t loop_width = 0; loop_width < width; loop_width++) {
-      PixelCopy(colors[color][0], colors[color][1], colors[color][2], 0, &temp);
-      CalcCRC(colors[color][0], &crc_red);
-      CalcCRC(colors[color][1], &crc_green);
-      CalcCRC(colors[color][2], &crc_blue);
-
-      if (((loop_width + 1) % 64) == 0) {
-        color = (color + 1) % colors.size();
-      }
-    }
-
-    if (((loop_height + 1) % 64) == 0) {
-      std::reverse(colors.begin(), (colors.end() - 1));
-    }
-  }
-
-  DLOGI("CRC red %x", crc_red.to_ulong());
-  DLOGI("CRC green %x", crc_green.to_ulong());
-  DLOGI("CRC blue %x", crc_blue.to_ulong());
-}
-
-int HWCDisplayExternalTest::InitLayer(Layer *layer) {
-  uint32_t active_config = 0;
-  DisplayConfigVariableInfo var_info = {};
-
-  GetActiveDisplayConfig(&active_config);
-
-  GetDisplayAttributesForConfig(INT32(active_config), &var_info);
-
-  layer->flags.updating = 1;
-  layer->src_rect = LayerRect(0, 0, var_info.x_pixels, var_info.y_pixels);
-  layer->dst_rect = layer->src_rect;
-  layer->frame_rate = var_info.fps;
-  layer->blending = kBlendingPremultiplied;
-
-  layer->input_buffer.unaligned_width = var_info.x_pixels;
-  layer->input_buffer.unaligned_height = var_info.y_pixels;
-  buffer_info_.buffer_config.format = kFormatRGBA8888;
-
-  if (layer->composition != kCompositionGPUTarget) {
-    buffer_info_.buffer_config.width = var_info.x_pixels;
-    buffer_info_.buffer_config.height = var_info.y_pixels;
-    switch (panel_bpp_) {
-      case kDisplayBpp18:
-      case kDisplayBpp24:
-        buffer_info_.buffer_config.format = kFormatRGB888;
-        break;
-      case kDisplayBpp30:
-        buffer_info_.buffer_config.format = kFormatRGBA1010102;
-        break;
-      default:
-        DLOGW("panel bpp not supported %d", panel_bpp_);
-        return -EINVAL;
-    }
-    buffer_info_.buffer_config.buffer_count = 1;
-
-    int ret = buffer_allocator_->AllocateBuffer(&buffer_info_);
-    if (ret != 0) {
-      DLOGE("Buffer allocation failed. ret: %d", ret);
-      return -ENOMEM;
-    }
-
-    ret = FillBuffer();
-    if (ret != 0) {
-      buffer_allocator_->FreeBuffer(&buffer_info_);
-      return ret;
-    }
-
-    layer->input_buffer.width = buffer_info_.alloc_buffer_info.aligned_width;
-    layer->input_buffer.height = buffer_info_.alloc_buffer_info.aligned_height;
-    layer->input_buffer.size = buffer_info_.alloc_buffer_info.size;
-    layer->input_buffer.planes[0].fd = buffer_info_.alloc_buffer_info.fd;
-    layer->input_buffer.planes[0].stride = buffer_info_.alloc_buffer_info.stride;
-    layer->input_buffer.format = buffer_info_.buffer_config.format;
-
-    DLOGI("Input buffer WxH %dx%d format %s size %d fd %d stride %d", layer->input_buffer.width,
-          layer->input_buffer.height, GetFormatString(layer->input_buffer.format),
-          layer->input_buffer.size, layer->input_buffer.planes[0].fd,
-          layer->input_buffer.planes[0].stride);
-  }
-
-  return 0;
-}
-
-int HWCDisplayExternalTest::DeinitLayer(Layer *layer) {
-  if (layer->composition != kCompositionGPUTarget) {
-    int ret = buffer_allocator_->FreeBuffer(&buffer_info_);
-    if (ret != 0) {
-      DLOGE("Buffer deallocation failed. ret: %d", ret);
-      return -ENOMEM;
-    }
-  }
-
-  return 0;
-}
-
-int HWCDisplayExternalTest::CreateLayerStack() {
-  for (uint32_t i = 0; i < (kTestLayerCnt + 1 /* one dummy gpu_target layer */); i++) {
-    Layer *layer = new Layer();
-
-    if (i == kTestLayerCnt) {
-      layer->composition = kCompositionGPUTarget;
-    }
-    DLOGE("External :: CreateLayerStack %d", i);
-    int ret = InitLayer(layer);
-    if (ret != 0) {
-      delete layer;
-      return ret;
-    }
-    layer_stack_.layers.push_back(layer);
-  }
-
-  return 0;
-}
-
-int HWCDisplayExternalTest::DestroyLayerStack() {
-  for (uint32_t i = 0; i < UINT32(layer_stack_.layers.size()); i++) {
-    Layer *layer = layer_stack_.layers.at(i);
-    int ret = DeinitLayer(layer);
-    if (ret != 0) {
-      return ret;
-    }
-    delete layer;
-  }
-  layer_stack_.layers = {};
-
-  return 0;
-}
-
-HWC2::Error HWCDisplayExternalTest::PostCommit(int32_t *out_retire_fence) {
-  auto status = HWC2::Error::None;
-  // Do no call flush on errors, if a successful buffer is never submitted.
-  if (flush_ && flush_on_error_) {
-    display_intf_->Flush();
-  }
-  if (!flush_) {
-    for (size_t i = 0; i < layer_stack_.layers.size(); i++) {
-      Layer *layer = layer_stack_.layers.at(i);
-      LayerBuffer &layer_buffer = layer->input_buffer;
-
-      close(layer_buffer.release_fence_fd);
-      layer_buffer.release_fence_fd = -1;
-    }
-    close(layer_stack_.retire_fence_fd);
-    layer_stack_.retire_fence_fd = -1;
-    *out_retire_fence = -1;
-  }
-  flush_ = false;
-
-  return status;
-}
-
-}  // namespace sdm
-
diff --git a/sdm/libs/hwc2/hwc_display_external_test.h b/sdm/libs/hwc2/hwc_display_external_test.h
deleted file mode 100644
index ef8027b..0000000
--- a/sdm/libs/hwc2/hwc_display_external_test.h
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
-* Copyright (c) 2017, The Linux Foundation. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without
-* modification, are permitted provided that the following conditions are
-* met:
-*     * Redistributions of source code must retain the above copyright
-*       notice, this list of conditions and the following disclaimer.
-*     * Redistributions in binary form must reproduce the above
-*       copyright notice, this list of conditions and the following
-*       disclaimer in the documentation and/or other materials provided
-*       with the distribution.
-*     * Neither the name of The Linux Foundation nor the names of its
-*       contributors may be used to endorse or promote products derived
-*       from this software without specific prior written permission.
-*
-* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
-* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
-* ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
-* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
-* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#ifndef __HWC_DISPLAY_EXTERNAL_TEST_H__
-#define __HWC_DISPLAY_EXTERNAL_TEST_H__
-
-#include <bitset>
-
-#include "hwc_display.h"
-#include "hwc_buffer_allocator.h"
-
-namespace sdm {
-
-class HWCDisplayExternalTest : public HWCDisplay {
- public:
-  static int Create(CoreInterface *core_intf, HWCBufferAllocator *buffer_allocator,
-                    HWCCallbacks *callbacks, qService::QService *qservice,
-                    uint32_t panel_bpp, uint32_t pattern_type, HWCDisplay **hwc_display);
-  static void Destroy(HWCDisplay *hwc_display);
-  virtual HWC2::Error Validate(uint32_t *out_num_types, uint32_t *out_num_requests);
-  virtual HWC2::Error Present(int32_t *out_retire_fence);
-  virtual void SetSecureDisplay(bool secure_display_active);
-  virtual int Perform(uint32_t operation, ...);
-
- protected:
-  BufferInfo buffer_info_ = {};
-  uint32_t panel_bpp_ = 0;
-  uint32_t pattern_type_ = 0;
-
-  enum ColorPatternType {
-    kPatternNone = 0,
-    kPatternColorRamp,
-    kPatternBWVertical,
-    kPatternColorSquare,
-  };
-
-  enum DisplayBpp {
-    kDisplayBpp18 = 18,
-    kDisplayBpp24 = 24,
-    kDisplayBpp30 = 30,
-  };
-
-  enum ColorRamp {
-    kColorRedRamp = 0,
-    kColorGreenRamp = 1,
-    kColorBlueRamp = 2,
-    kColorWhiteRamp = 3,
-  };
-
-  enum Colors {
-    kColorBlack = 0,
-    kColorWhite = 1,
-  };
-
- private:
-  HWCDisplayExternalTest(CoreInterface *core_intf, HWCBufferAllocator *buffer_allocator,
-                         HWCCallbacks *callbacks, qService::QService *qservice,
-                         uint32_t panel_bpp, uint32_t pattern_type);
-  int Init();
-  int Deinit();
-  void DumpInputBuffer();
-  void CalcCRC(uint32_t color_value, std::bitset<16> *crc_data);
-  int FillBuffer();
-  int GetStride(LayerBufferFormat format, uint32_t width, uint32_t *stride);
-  void PixelCopy(uint32_t red, uint32_t green, uint32_t blue, uint32_t alpha, uint8_t **buffer);
-  void GenerateColorRamp(uint8_t *buffer);
-  void GenerateBWVertical(uint8_t *buffer);
-  void GenerateColorSquare(uint8_t *buffer);
-  int InitLayer(Layer *layer);
-  int DeinitLayer(Layer *layer);
-  int CreateLayerStack();
-  int DestroyLayerStack();
-  HWC2::Error PostCommit(int32_t *out_retire_fence);
-
-  static const uint32_t kTestLayerCnt = 1;
-};
-
-}  // namespace sdm
-
-#endif  // __HWC_DISPLAY_EXTERNAL_TEST_H__
-
diff --git a/sdm/libs/hwc2/hwc_display_primary.cpp b/sdm/libs/hwc2/hwc_display_primary.cpp
deleted file mode 100644
index 75ac0f9..0000000
--- a/sdm/libs/hwc2/hwc_display_primary.cpp
+++ /dev/null
@@ -1,633 +0,0 @@
-/*
-* Copyright (c) 2014 - 2018, The Linux Foundation. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without
-* modification, are permitted provided that the following conditions are
-* met:
-*     * Redistributions of source code must retain the above copyright
-*       notice, this list of conditions and the following disclaimer.
-*     * Redistributions in binary form must reproduce the above
-*       copyright notice, this list of conditions and the following
-*       disclaimer in the documentation and/or other materials provided
-*       with the distribution.
-*     * Neither the name of The Linux Foundation nor the names of its
-*       contributors may be used to endorse or promote products derived
-*       from this software without specific prior written permission.
-*
-* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
-* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
-* ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
-* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
-* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#include <cutils/properties.h>
-#include <sync/sync.h>
-#include <utils/constants.h>
-#include <utils/debug.h>
-#include <stdarg.h>
-#include <sys/mman.h>
-
-#include <map>
-#include <string>
-#include <vector>
-
-#include "hwc_display_primary.h"
-#include "hwc_debugger.h"
-
-#define __CLASS__ "HWCDisplayPrimary"
-
-namespace sdm {
-
-int HWCDisplayPrimary::Create(CoreInterface *core_intf, BufferAllocator *buffer_allocator,
-                              HWCCallbacks *callbacks, qService::QService *qservice,
-                              HWCDisplay **hwc_display) {
-  int status = 0;
-  uint32_t primary_width = 0;
-  uint32_t primary_height = 0;
-
-  HWCDisplay *hwc_display_primary =
-      new HWCDisplayPrimary(core_intf, buffer_allocator, callbacks, qservice);
-  status = hwc_display_primary->Init();
-  if (status) {
-    delete hwc_display_primary;
-    return status;
-  }
-
-  hwc_display_primary->GetMixerResolution(&primary_width, &primary_height);
-  int width = 0, height = 0;
-  HWCDebugHandler::Get()->GetProperty(FB_WIDTH_PROP, &width);
-  HWCDebugHandler::Get()->GetProperty(FB_HEIGHT_PROP, &height);
-  if (width > 0 && height > 0) {
-    primary_width = UINT32(width);
-    primary_height = UINT32(height);
-  }
-
-  status = hwc_display_primary->SetFrameBufferResolution(primary_width, primary_height);
-  if (status) {
-    Destroy(hwc_display_primary);
-    return status;
-  }
-
-  *hwc_display = hwc_display_primary;
-
-  return status;
-}
-
-void HWCDisplayPrimary::Destroy(HWCDisplay *hwc_display) {
-  hwc_display->Deinit();
-  delete hwc_display;
-}
-
-HWCDisplayPrimary::HWCDisplayPrimary(CoreInterface *core_intf, BufferAllocator *buffer_allocator,
-                                     HWCCallbacks *callbacks, qService::QService *qservice)
-    : HWCDisplay(core_intf, callbacks, kPrimary, HWC_DISPLAY_PRIMARY, true, qservice,
-                 DISPLAY_CLASS_PRIMARY, buffer_allocator),
-      buffer_allocator_(buffer_allocator),
-      cpu_hint_(NULL) {
-}
-
-int HWCDisplayPrimary::Init() {
-  cpu_hint_ = new CPUHint();
-  if (cpu_hint_->Init(static_cast<HWCDebugHandler *>(HWCDebugHandler::Get())) != kErrorNone) {
-    delete cpu_hint_;
-    cpu_hint_ = NULL;
-  }
-
-  use_metadata_refresh_rate_ = true;
-  int disable_metadata_dynfps = 0;
-  HWCDebugHandler::Get()->GetProperty(DISABLE_METADATA_DYNAMIC_FPS_PROP, &disable_metadata_dynfps);
-  if (disable_metadata_dynfps) {
-    use_metadata_refresh_rate_ = false;
-  }
-
-  int status = HWCDisplay::Init();
-  if (status) {
-    return status;
-  }
-  color_mode_ = new HWCColorMode(display_intf_);
-  color_mode_->Init();
-  HWCDebugHandler::Get()->GetProperty(ENABLE_DEFAULT_COLOR_MODE, &default_mode_status_);
-
-  return status;
-}
-
-void HWCDisplayPrimary::ProcessBootAnimCompleted() {
-  uint32_t numBootUpLayers = 0;
-  // TODO(user): Remove this hack
-
-  numBootUpLayers = static_cast<uint32_t>(Debug::GetBootAnimLayerCount());
-
-  if (numBootUpLayers == 0) {
-    numBootUpLayers = 2;
-  }
-  /* All other checks namely "init.svc.bootanim" or
-  * HWC_GEOMETRY_CHANGED fail in correctly identifying the
-  * exact bootup transition to homescreen
-  */
-  char property[PROPERTY_VALUE_MAX];
-  bool isEncrypted = false;
-  bool main_class_services_started = false;
-  property_get("ro.crypto.state", property, "unencrypted");
-  if (!strcmp(property, "encrypted")) {
-    property_get("ro.crypto.type", property, "block");
-    if (!strcmp(property, "block")) {
-      isEncrypted = true;
-      property_get("vold.decrypt", property, "");
-      if (!strcmp(property, "trigger_restart_framework")) {
-        main_class_services_started = true;
-      }
-    }
-  }
-
-  if ((!isEncrypted || (isEncrypted && main_class_services_started)) &&
-      (layer_set_.size() > numBootUpLayers)) {
-    DLOGI("Applying default mode");
-    boot_animation_completed_ = true;
-    // Applying default mode after bootanimation is finished And
-    // If Data is Encrypted, it is ready for access.
-    if (display_intf_) {
-      display_intf_->ApplyDefaultDisplayMode();
-      RestoreColorTransform();
-    }
-  }
-}
-
-HWC2::Error HWCDisplayPrimary::Validate(uint32_t *out_num_types, uint32_t *out_num_requests) {
-  auto status = HWC2::Error::None;
-  DisplayError error = kErrorNone;
-
-  if (default_mode_status_ && !boot_animation_completed_) {
-    ProcessBootAnimCompleted();
-  }
-
-  if (display_paused_) {
-    MarkLayersForGPUBypass();
-    return status;
-  }
-
-  if (color_tranform_failed_) {
-    // Must fall back to client composition
-    MarkLayersForClientComposition();
-  }
-
-  if (config_pending_) {
-    if (display_intf_->SetActiveConfig(display_config_) != kErrorNone) {
-      DLOGW("Invalid display config %d", display_config_);
-      // Reset the display config with active config
-      display_intf_->GetActiveConfig(&display_config_);
-    }
-  }
-  // Fill in the remaining blanks in the layers and add them to the SDM layerstack
-  BuildLayerStack();
-  // Checks and replaces layer stack for solid fill
-  SolidFillPrepare();
-
-  bool pending_output_dump = dump_frame_count_ && dump_output_to_file_;
-
-  if (frame_capture_buffer_queued_ || pending_output_dump) {
-    // RHS values were set in FrameCaptureAsync() called from a binder thread. They are picked up
-    // here in a subsequent draw round.
-    layer_stack_.output_buffer = &output_buffer_;
-    layer_stack_.flags.post_processed_output = post_processed_output_;
-  }
-
-  uint32_t num_updating_layers = GetUpdatingLayersCount();
-  bool one_updating_layer = (num_updating_layers == 1);
-  if (num_updating_layers != 0) {
-    ToggleCPUHint(one_updating_layer);
-  }
-
-  uint32_t refresh_rate = GetOptimalRefreshRate(one_updating_layer);
-  bool final_rate = force_refresh_rate_ ? true : false;
-  error = display_intf_->SetRefreshRate(refresh_rate, final_rate);
-  if (error == kErrorNone) {
-    // On success, set current refresh rate to new refresh rate
-    current_refresh_rate_ = refresh_rate;
-  }
-
-  if (layer_set_.empty()) {
-    // Avoid flush for Command mode panel.
-    DisplayConfigFixedInfo display_config;
-    display_intf_->GetConfig(&display_config);
-    flush_ = !(display_config.is_cmdmode && secure_display_active_);
-    validated_ = true;
-    return status;
-  }
-
-  status = PrepareLayerStack(out_num_types, out_num_requests);
-  pending_commit_ = true;
-  return status;
-}
-
-HWC2::Error HWCDisplayPrimary::Present(int32_t *out_retire_fence) {
-  auto status = HWC2::Error::None;
-  if (display_paused_) {
-    // TODO(user): From old HWC implementation
-    // If we do not handle the frame set retireFenceFd to outbufAcquireFenceFd
-    // Revisit this when validating display_paused
-    DisplayError error = display_intf_->Flush();
-    validated_ = false;
-    if (error != kErrorNone) {
-      DLOGE("Flush failed. Error = %d", error);
-    }
-  } else {
-    status = HWCDisplay::CommitLayerStack();
-    if (status == HWC2::Error::None) {
-      HandleFrameOutput();
-      SolidFillCommit();
-      status = HWCDisplay::PostCommitLayerStack(out_retire_fence);
-    }
-  }
-  pending_commit_ = false;
-  return status;
-}
-
-HWC2::Error HWCDisplayPrimary::GetColorModes(uint32_t *out_num_modes,
-                                             android_color_mode_t *out_modes) {
-  if (out_modes == nullptr) {
-    *out_num_modes = color_mode_->GetColorModeCount();
-  } else {
-    color_mode_->GetColorModes(out_num_modes, out_modes);
-  }
-
-  return HWC2::Error::None;
-}
-
-HWC2::Error HWCDisplayPrimary::SetColorMode(android_color_mode_t mode) {
-  auto status = color_mode_->SetColorMode(mode);
-  if (status != HWC2::Error::None) {
-    DLOGE("failed for mode = %d", mode);
-    return status;
-  }
-
-  callbacks_->Refresh(HWC_DISPLAY_PRIMARY);
-  validated_ = false;
-
-  return status;
-}
-
-HWC2::Error HWCDisplayPrimary::SetColorModeById(int32_t color_mode_id) {
-  auto status = color_mode_->SetColorModeById(color_mode_id);
-  if (status != HWC2::Error::None) {
-    DLOGE("failed for mode = %d", color_mode_id);
-    return status;
-  }
-
-  callbacks_->Refresh(HWC_DISPLAY_PRIMARY);
-  validated_ = false;
-
-  return status;
-}
-
-HWC2::Error HWCDisplayPrimary::RestoreColorTransform() {
-  auto status = color_mode_->RestoreColorTransform();
-  if (status != HWC2::Error::None) {
-    DLOGE("failed to RestoreColorTransform");
-    return status;
-  }
-
-  callbacks_->Refresh(HWC_DISPLAY_PRIMARY);
-
-  return status;
-}
-
-HWC2::Error HWCDisplayPrimary::SetColorTransform(const float *matrix,
-                                                 android_color_transform_t hint) {
-  if (!matrix) {
-    return HWC2::Error::BadParameter;
-  }
-
-  auto status = color_mode_->SetColorTransform(matrix, hint);
-  if (status != HWC2::Error::None) {
-    DLOGE("failed for hint = %d", hint);
-    color_tranform_failed_ = true;
-    return status;
-  }
-
-  callbacks_->Refresh(HWC_DISPLAY_PRIMARY);
-  color_tranform_failed_ = false;
-  validated_ = false;
-
-  return status;
-}
-
-int HWCDisplayPrimary::Perform(uint32_t operation, ...) {
-  va_list args;
-  va_start(args, operation);
-  int val = 0;
-  LayerSolidFill *solid_fill_color;
-  LayerRect *rect = NULL;
-
-  switch (operation) {
-    case SET_METADATA_DYN_REFRESH_RATE:
-      val = va_arg(args, int32_t);
-      SetMetaDataRefreshRateFlag(val);
-      break;
-    case SET_BINDER_DYN_REFRESH_RATE:
-      val = va_arg(args, int32_t);
-      ForceRefreshRate(UINT32(val));
-      break;
-    case SET_DISPLAY_MODE:
-      val = va_arg(args, int32_t);
-      SetDisplayMode(UINT32(val));
-      break;
-    case SET_QDCM_SOLID_FILL_INFO:
-      solid_fill_color = va_arg(args, LayerSolidFill*);
-      SetQDCMSolidFillInfo(true, *solid_fill_color);
-      break;
-    case UNSET_QDCM_SOLID_FILL_INFO:
-      solid_fill_color = va_arg(args, LayerSolidFill*);
-      SetQDCMSolidFillInfo(false, *solid_fill_color);
-      break;
-    case SET_QDCM_SOLID_FILL_RECT:
-      rect = va_arg(args, LayerRect*);
-      solid_fill_rect_ = *rect;
-      break;
-    default:
-      DLOGW("Invalid operation %d", operation);
-      va_end(args);
-      return -EINVAL;
-  }
-  va_end(args);
-  validated_ = false;
-
-  return 0;
-}
-
-DisplayError HWCDisplayPrimary::SetDisplayMode(uint32_t mode) {
-  DisplayError error = kErrorNone;
-
-  if (display_intf_) {
-    error = display_intf_->SetDisplayMode(mode);
-  }
-
-  return error;
-}
-
-void HWCDisplayPrimary::SetMetaDataRefreshRateFlag(bool enable) {
-  int disable_metadata_dynfps = 0;
-
-  HWCDebugHandler::Get()->GetProperty(DISABLE_METADATA_DYNAMIC_FPS_PROP, &disable_metadata_dynfps);
-  if (disable_metadata_dynfps) {
-    return;
-  }
-  use_metadata_refresh_rate_ = enable;
-}
-
-void HWCDisplayPrimary::SetQDCMSolidFillInfo(bool enable, const LayerSolidFill &color) {
-  solid_fill_enable_ = enable;
-  solid_fill_color_ = color;
-}
-
-void HWCDisplayPrimary::ToggleCPUHint(bool set) {
-  if (!cpu_hint_) {
-    return;
-  }
-
-  if (set) {
-    cpu_hint_->Set();
-  } else {
-    cpu_hint_->Reset();
-  }
-}
-
-void HWCDisplayPrimary::SetSecureDisplay(bool secure_display_active) {
-  if (secure_display_active_ != secure_display_active) {
-    // Skip Prepare and call Flush for null commit
-    DLOGI("SecureDisplay state changed from %d to %d Needs Flush!!", secure_display_active_,
-          secure_display_active);
-    secure_display_active_ = secure_display_active;
-
-    // Avoid flush for Command mode panel.
-    DisplayConfigFixedInfo display_config;
-    display_intf_->GetConfig(&display_config);
-    skip_prepare_ = !display_config.is_cmdmode;
-  }
-}
-
-void HWCDisplayPrimary::ForceRefreshRate(uint32_t refresh_rate) {
-  if ((refresh_rate && (refresh_rate < min_refresh_rate_ || refresh_rate > max_refresh_rate_)) ||
-      force_refresh_rate_ == refresh_rate) {
-    // Cannot honor force refresh rate, as its beyond the range or new request is same
-    return;
-  }
-
-  force_refresh_rate_ = refresh_rate;
-
-  callbacks_->Refresh(HWC_DISPLAY_PRIMARY);
-
-  return;
-}
-
-uint32_t HWCDisplayPrimary::GetOptimalRefreshRate(bool one_updating_layer) {
-  if (force_refresh_rate_) {
-    return force_refresh_rate_;
-  } else if (use_metadata_refresh_rate_ && one_updating_layer && metadata_refresh_rate_) {
-    return metadata_refresh_rate_;
-  }
-
-  return max_refresh_rate_;
-}
-
-DisplayError HWCDisplayPrimary::Refresh() {
-  DisplayError error = kErrorNone;
-
-  callbacks_->Refresh(HWC_DISPLAY_PRIMARY);
-
-  return error;
-}
-
-void HWCDisplayPrimary::SetIdleTimeoutMs(uint32_t timeout_ms) {
-  display_intf_->SetIdleTimeoutMs(timeout_ms);
-  validated_ = false;
-}
-
-static void SetLayerBuffer(const BufferInfo &output_buffer_info, LayerBuffer *output_buffer) {
-  const BufferConfig& buffer_config = output_buffer_info.buffer_config;
-  const AllocatedBufferInfo &alloc_buffer_info = output_buffer_info.alloc_buffer_info;
-
-  output_buffer->width = alloc_buffer_info.aligned_width;
-  output_buffer->height = alloc_buffer_info.aligned_height;
-  output_buffer->unaligned_width = buffer_config.width;
-  output_buffer->unaligned_height = buffer_config.height;
-  output_buffer->format = buffer_config.format;
-  output_buffer->planes[0].fd = alloc_buffer_info.fd;
-  output_buffer->planes[0].stride = alloc_buffer_info.stride;
-}
-
-void HWCDisplayPrimary::HandleFrameOutput() {
-  if (frame_capture_buffer_queued_) {
-    HandleFrameCapture();
-  } else if (dump_output_to_file_) {
-    HandleFrameDump();
-  }
-}
-
-void HWCDisplayPrimary::HandleFrameCapture() {
-  if (output_buffer_.release_fence_fd >= 0) {
-    frame_capture_status_ = sync_wait(output_buffer_.release_fence_fd, 1000);
-    ::close(output_buffer_.release_fence_fd);
-    output_buffer_.release_fence_fd = -1;
-  }
-
-  frame_capture_buffer_queued_ = false;
-  post_processed_output_ = false;
-  output_buffer_ = {};
-}
-
-void HWCDisplayPrimary::HandleFrameDump() {
-  if (dump_frame_count_ && output_buffer_.release_fence_fd >= 0) {
-    int ret = sync_wait(output_buffer_.release_fence_fd, 1000);
-    ::close(output_buffer_.release_fence_fd);
-    output_buffer_.release_fence_fd = -1;
-    if (ret < 0) {
-      DLOGE("sync_wait error errno = %d, desc = %s", errno, strerror(errno));
-    } else {
-      DumpOutputBuffer(output_buffer_info_, output_buffer_base_, layer_stack_.retire_fence_fd);
-    }
-  }
-
-  if (0 == dump_frame_count_) {
-    dump_output_to_file_ = false;
-    // Unmap and Free buffer
-    if (munmap(output_buffer_base_, output_buffer_info_.alloc_buffer_info.size) != 0) {
-      DLOGE("unmap failed with err %d", errno);
-    }
-    if (buffer_allocator_->FreeBuffer(&output_buffer_info_) != 0) {
-      DLOGE("FreeBuffer failed");
-    }
-
-    post_processed_output_ = false;
-    output_buffer_ = {};
-    output_buffer_info_ = {};
-    output_buffer_base_ = nullptr;
-  }
-}
-
-HWC2::Error HWCDisplayPrimary::SetFrameDumpConfig(uint32_t count, uint32_t bit_mask_layer_type) {
-  HWCDisplay::SetFrameDumpConfig(count, bit_mask_layer_type);
-  dump_output_to_file_ = bit_mask_layer_type & (1 << OUTPUT_LAYER_DUMP);
-  DLOGI("output_layer_dump_enable %d", dump_output_to_file_);
-
-  if (!count || !dump_output_to_file_) {
-    return HWC2::Error::None;
-  }
-
-  // Allocate and map output buffer
-  output_buffer_info_ = {};
-  // Since we dump DSPP output use Panel resolution.
-  GetPanelResolution(&output_buffer_info_.buffer_config.width,
-                     &output_buffer_info_.buffer_config.height);
-  output_buffer_info_.buffer_config.format = kFormatRGB888;
-  output_buffer_info_.buffer_config.buffer_count = 1;
-  if (buffer_allocator_->AllocateBuffer(&output_buffer_info_) != 0) {
-    DLOGE("Buffer allocation failed");
-    output_buffer_info_ = {};
-    return HWC2::Error::NoResources;
-  }
-
-  void *buffer = mmap(NULL, output_buffer_info_.alloc_buffer_info.size, PROT_READ | PROT_WRITE,
-                      MAP_SHARED, output_buffer_info_.alloc_buffer_info.fd, 0);
-
-  if (buffer == MAP_FAILED) {
-    DLOGE("mmap failed with err %d", errno);
-    buffer_allocator_->FreeBuffer(&output_buffer_info_);
-    output_buffer_info_ = {};
-    return HWC2::Error::NoResources;
-  }
-
-  output_buffer_base_ = buffer;
-  post_processed_output_ = true;
-  DisablePartialUpdateOneFrame();
-  validated_ = false;
-  return HWC2::Error::None;
-}
-
-int HWCDisplayPrimary::FrameCaptureAsync(const BufferInfo &output_buffer_info,
-                                         bool post_processed_output) {
-  // Note: This function is called in context of a binder thread and a lock is already held
-  if (output_buffer_info.alloc_buffer_info.fd < 0) {
-    DLOGE("Invalid fd %d", output_buffer_info.alloc_buffer_info.fd);
-    return -1;
-  }
-
-  auto panel_width = 0u;
-  auto panel_height = 0u;
-  auto fb_width = 0u;
-  auto fb_height = 0u;
-
-  GetPanelResolution(&panel_width, &panel_height);
-  GetFrameBufferResolution(&fb_width, &fb_height);
-
-  if (post_processed_output && (output_buffer_info.buffer_config.width < panel_width ||
-                                output_buffer_info.buffer_config.height < panel_height)) {
-    DLOGE("Buffer dimensions should not be less than panel resolution");
-    return -1;
-  } else if (!post_processed_output && (output_buffer_info.buffer_config.width < fb_width ||
-                                        output_buffer_info.buffer_config.height < fb_height)) {
-    DLOGE("Buffer dimensions should not be less than FB resolution");
-    return -1;
-  }
-
-  SetLayerBuffer(output_buffer_info, &output_buffer_);
-  post_processed_output_ = post_processed_output;
-  frame_capture_buffer_queued_ = true;
-  // Status is only cleared on a new call to dump and remains valid otherwise
-  frame_capture_status_ = -EAGAIN;
-  DisablePartialUpdateOneFrame();
-
-  return 0;
-}
-
-DisplayError HWCDisplayPrimary::SetDetailEnhancerConfig
-                                   (const DisplayDetailEnhancerData &de_data) {
-  DisplayError error = kErrorNotSupported;
-
-  if (display_intf_) {
-    error = display_intf_->SetDetailEnhancerData(de_data);
-    validated_ = false;
-  }
-  return error;
-}
-
-DisplayError HWCDisplayPrimary::ControlPartialUpdate(bool enable, uint32_t *pending) {
-  DisplayError error = kErrorNone;
-
-  if (display_intf_) {
-    error = display_intf_->ControlPartialUpdate(enable, pending);
-    validated_ = false;
-  }
-
-  return error;
-}
-
-DisplayError HWCDisplayPrimary::DisablePartialUpdateOneFrame() {
-  DisplayError error = kErrorNone;
-
-  if (display_intf_) {
-    error = display_intf_->DisablePartialUpdateOneFrame();
-    validated_ = false;
-  }
-
-  return error;
-}
-
-
-DisplayError HWCDisplayPrimary::SetMixerResolution(uint32_t width, uint32_t height) {
-  DisplayError error = display_intf_->SetMixerResolution(width, height);
-  validated_ = false;
-  return error;
-}
-
-DisplayError HWCDisplayPrimary::GetMixerResolution(uint32_t *width, uint32_t *height) {
-  return display_intf_->GetMixerResolution(width, height);
-}
-
-}  // namespace sdm
diff --git a/sdm/libs/hwc2/hwc_display_primary.h b/sdm/libs/hwc2/hwc_display_primary.h
deleted file mode 100644
index c1e23ed..0000000
--- a/sdm/libs/hwc2/hwc_display_primary.h
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * Copyright (c) 2014-2017, The Linux Foundation. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
-    * Redistributions of source code must retain the above copyright
-      notice, this list of conditions and the following disclaimer.
-    * Redistributions in binary form must reproduce the above
-      copyright notice, this list of conditions and the following
-      disclaimer in the documentation and/or other materials provided
-      with the distribution.
-    * Neither the name of The Linux Foundation nor the names of its
-      contributors may be used to endorse or promote products derived
-      from this software without specific prior written permission.
-
- * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef __HWC_DISPLAY_PRIMARY_H__
-#define __HWC_DISPLAY_PRIMARY_H__
-
-#include <string>
-
-#include "cpuhint.h"
-#include "hwc_display.h"
-
-namespace sdm {
-
-class HWCDisplayPrimary : public HWCDisplay {
- public:
-  enum {
-    SET_METADATA_DYN_REFRESH_RATE,
-    SET_BINDER_DYN_REFRESH_RATE,
-    SET_DISPLAY_MODE,
-    SET_QDCM_SOLID_FILL_INFO,
-    UNSET_QDCM_SOLID_FILL_INFO,
-    SET_QDCM_SOLID_FILL_RECT,
-  };
-
-  static int Create(CoreInterface *core_intf, BufferAllocator *buffer_allocator,
-                    HWCCallbacks *callbacks, qService::QService *qservice,
-                    HWCDisplay **hwc_display);
-  static void Destroy(HWCDisplay *hwc_display);
-  virtual int Init();
-  virtual HWC2::Error Validate(uint32_t *out_num_types, uint32_t *out_num_requests);
-  virtual HWC2::Error Present(int32_t *out_retire_fence);
-  virtual HWC2::Error GetColorModes(uint32_t *out_num_modes, android_color_mode_t *out_modes);
-  virtual HWC2::Error SetColorMode(android_color_mode_t mode);
-  virtual HWC2::Error SetColorModeById(int32_t color_mode_id);
-  virtual HWC2::Error SetColorTransform(const float *matrix, android_color_transform_t hint);
-  virtual HWC2::Error RestoreColorTransform();
-  virtual int Perform(uint32_t operation, ...);
-  virtual void SetSecureDisplay(bool secure_display_active);
-  virtual DisplayError Refresh();
-  virtual void SetIdleTimeoutMs(uint32_t timeout_ms);
-  virtual HWC2::Error SetFrameDumpConfig(uint32_t count, uint32_t bit_mask_layer_type);
-  virtual int FrameCaptureAsync(const BufferInfo &output_buffer_info, bool post_processed);
-  virtual int GetFrameCaptureStatus() { return frame_capture_status_; }
-  virtual DisplayError SetDetailEnhancerConfig(const DisplayDetailEnhancerData &de_data);
-  virtual DisplayError ControlPartialUpdate(bool enable, uint32_t *pending);
-
- private:
-  HWCDisplayPrimary(CoreInterface *core_intf, BufferAllocator *buffer_allocator,
-                    HWCCallbacks *callbacks, qService::QService *qservice);
-  void SetMetaDataRefreshRateFlag(bool enable);
-  virtual DisplayError SetDisplayMode(uint32_t mode);
-  virtual DisplayError DisablePartialUpdateOneFrame();
-  void ProcessBootAnimCompleted(void);
-  void SetQDCMSolidFillInfo(bool enable, const LayerSolidFill &color);
-  void ToggleCPUHint(bool set);
-  void ForceRefreshRate(uint32_t refresh_rate);
-  uint32_t GetOptimalRefreshRate(bool one_updating_layer);
-  void HandleFrameOutput();
-  void HandleFrameCapture();
-  void HandleFrameDump();
-  DisplayError SetMixerResolution(uint32_t width, uint32_t height);
-  DisplayError GetMixerResolution(uint32_t *width, uint32_t *height);
-
-  BufferAllocator *buffer_allocator_ = nullptr;
-  CPUHint *cpu_hint_ = nullptr;
-
-  // Primary output buffer configuration
-  LayerBuffer output_buffer_ = {};
-  bool post_processed_output_ = false;
-
-  // Members for 1 frame capture in a client provided buffer
-  bool frame_capture_buffer_queued_ = false;
-  int frame_capture_status_ = -EAGAIN;
-
-  // Members for N frame output dump to file
-  bool dump_output_to_file_ = false;
-  BufferInfo output_buffer_info_ = {};
-  void *output_buffer_base_ = nullptr;
-  int default_mode_status_ = 0;
-};
-
-}  // namespace sdm
-
-#endif  // __HWC_DISPLAY_PRIMARY_H__
diff --git a/sdm/libs/hwc2/hwc_display_virtual.cpp b/sdm/libs/hwc2/hwc_display_virtual.cpp
deleted file mode 100644
index 11193bb..0000000
--- a/sdm/libs/hwc2/hwc_display_virtual.cpp
+++ /dev/null
@@ -1,291 +0,0 @@
-/*
-* Copyright (c) 2014-2018, The Linux Foundation. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without
-* modification, are permitted provided that the following conditions are
-* met:
-*     * Redistributions of source code must retain the above copyright
-*       notice, this list of conditions and the following disclaimer.
-*     * Redistributions in binary form must reproduce the above
-*       copyright notice, this list of conditions and the following
-*       disclaimer in the documentation and/or other materials provided
-*       with the distribution.
-*     * Neither the name of The Linux Foundation nor the names of its
-*       contributors may be used to endorse or promote products derived
-*       from this software without specific prior written permission.
-*
-* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
-* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
-* ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
-* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
-* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#include <utils/constants.h>
-#include <utils/debug.h>
-#include <sync/sync.h>
-#include <stdarg.h>
-
-#include "hwc_display_virtual.h"
-#include "hwc_debugger.h"
-
-#define __CLASS__ "HWCDisplayVirtual"
-
-namespace sdm {
-
-int HWCDisplayVirtual::Create(CoreInterface *core_intf, HWCBufferAllocator *buffer_allocator,
-                              HWCCallbacks *callbacks, uint32_t width,
-                              uint32_t height, int32_t *format, HWCDisplay **hwc_display) {
-  int status = 0;
-  HWCDisplayVirtual *hwc_display_virtual = new HWCDisplayVirtual(core_intf, buffer_allocator,
-                                                                 callbacks);
-
-  // TODO(user): Populate format correctly
-  DLOGI("Creating virtual display: w: %d h:%d format:0x%x", width, height, *format);
-
-  status = hwc_display_virtual->Init();
-  if (status) {
-    DLOGW("Failed to initialize virtual display");
-    delete hwc_display_virtual;
-    return status;
-  }
-
-  status = hwc_display_virtual->SetConfig(width, height);
-  if (status) {
-    Destroy(hwc_display_virtual);
-    return status;
-  }
-
-  status = INT32(hwc_display_virtual->SetPowerMode(HWC2::PowerMode::On));
-  if (status) {
-    DLOGW("Failed to set power mode on virtual display");
-    Destroy(hwc_display_virtual);
-    return status;
-  }
-
-  // TODO(user): Validate that we support this width/height
-  status = hwc_display_virtual->SetFrameBufferResolution(width, height);
-
-  if (status) {
-    DLOGW("Failed to set virtual display FB resolution");
-    Destroy(hwc_display_virtual);
-    return status;
-  }
-
-  *hwc_display = static_cast<HWCDisplay *>(hwc_display_virtual);
-
-  return 0;
-}
-
-void HWCDisplayVirtual::Destroy(HWCDisplay *hwc_display) {
-  hwc_display->Deinit();
-  delete hwc_display;
-}
-
-HWCDisplayVirtual::HWCDisplayVirtual(CoreInterface *core_intf, HWCBufferAllocator *buffer_allocator,
-                                     HWCCallbacks *callbacks)
-    : HWCDisplay(core_intf, callbacks, kVirtual, HWC_DISPLAY_VIRTUAL, false, NULL,
-                 DISPLAY_CLASS_VIRTUAL, buffer_allocator) {
-}
-
-int HWCDisplayVirtual::Init() {
-  output_buffer_ = new LayerBuffer();
-  return HWCDisplay::Init();
-}
-
-int HWCDisplayVirtual::Deinit() {
-  int status = 0;
-  if (output_buffer_) {
-    delete output_buffer_;
-    output_buffer_ = nullptr;
-  }
-  status = HWCDisplay::Deinit();
-
-  return status;
-}
-
-HWC2::Error HWCDisplayVirtual::Validate(uint32_t *out_num_types, uint32_t *out_num_requests) {
-  auto status = HWC2::Error::None;
-
-  if (display_paused_) {
-    MarkLayersForGPUBypass();
-    return status;
-  }
-
-  BuildLayerStack();
-  layer_stack_.output_buffer = output_buffer_;
-  // If Output buffer of Virtual Display is not secure, set SKIP flag on the secure layers.
-  if (output_buffer_ && !output_buffer_->flags.secure && layer_stack_.flags.secure_present) {
-    for (auto hwc_layer : layer_set_) {
-      Layer *layer = hwc_layer->GetSDMLayer();
-      if (layer->input_buffer.flags.secure) {
-        layer_stack_.flags.skip_present = true;
-        layer->flags.skip = true;
-      }
-    }
-  }
-
-  if (layer_set_.empty()) {
-    DLOGI("Skipping Validate and Commit");
-    return status;
-  }
-  status = PrepareLayerStack(out_num_types, out_num_requests);
-  return status;
-}
-
-HWC2::Error HWCDisplayVirtual::Present(int32_t *out_retire_fence) {
-  auto status = HWC2::Error::None;
-
-  if (!output_buffer_->buffer_id) {
-    return HWC2::Error::NoResources;
-  }
-
-  if (display_paused_) {
-    DisplayError error = display_intf_->Flush();
-    validated_ = false;
-    if (error != kErrorNone) {
-      DLOGE("Flush failed. Error = %d", error);
-    }
-  } else {
-    status = HWCDisplay::CommitLayerStack();
-    if (status == HWC2::Error::None) {
-      if (dump_frame_count_ && !flush_ && dump_output_layer_) {
-        if (output_handle_) {
-          BufferInfo buffer_info;
-          const private_handle_t *output_handle =
-              reinterpret_cast<const private_handle_t *>(output_buffer_->buffer_id);
-          DisplayError error = kErrorNone;
-          if (!output_handle->base) {
-            error = buffer_allocator_->MapBuffer(output_handle, -1);
-            if (error != kErrorNone) {
-              DLOGE("Failed to map output buffer, error = %d", error);
-              return HWC2::Error::BadParameter;
-            }
-          }
-          buffer_info.buffer_config.width = static_cast<uint32_t>(output_handle->width);
-          buffer_info.buffer_config.height = static_cast<uint32_t>(output_handle->height);
-          buffer_info.buffer_config.format =
-              GetSDMFormat(output_handle->format, output_handle->flags);
-          buffer_info.alloc_buffer_info.size = static_cast<uint32_t>(output_handle->size);
-          DumpOutputBuffer(buffer_info, reinterpret_cast<void *>(output_handle->base),
-                           layer_stack_.retire_fence_fd);
-
-          int release_fence = -1;
-          error = buffer_allocator_->UnmapBuffer(output_handle, &release_fence);
-          if (error != kErrorNone) {
-            DLOGE("Failed to unmap buffer, error = %d", error);
-            return HWC2::Error::BadParameter;
-          }
-        }
-      }
-
-      status = HWCDisplay::PostCommitLayerStack(out_retire_fence);
-    }
-  }
-  if (output_buffer_->acquire_fence_fd >= 0) {
-    close(output_buffer_->acquire_fence_fd);
-    output_buffer_->acquire_fence_fd = -1;
-  }
-  return status;
-}
-
-int HWCDisplayVirtual::SetConfig(uint32_t width, uint32_t height) {
-  DisplayConfigVariableInfo variable_info;
-  variable_info.x_pixels = width;
-  variable_info.y_pixels = height;
-  // TODO(user): Need to get the framerate of primary display and update it.
-  variable_info.fps = 60;
-  DisplayError err = display_intf_->SetActiveConfig(&variable_info);
-  if (err != kErrorNone) {
-    return -EINVAL;
-  }
-  return 0;
-}
-
-HWC2::Error HWCDisplayVirtual::SetOutputBuffer(buffer_handle_t buf, int32_t release_fence) {
-  if (buf == nullptr || release_fence == 0) {
-    return HWC2::Error::BadParameter;
-  }
-  const private_handle_t *output_handle = static_cast<const private_handle_t *>(buf);
-
-  // Fill output buffer parameters (width, height, format, plane information, fence)
-  output_buffer_->acquire_fence_fd = dup(release_fence);
-
-  if (output_handle) {
-    int output_handle_format = output_handle->format;
-    int active_aligned_w, active_aligned_h;
-    int new_width, new_height;
-    int new_aligned_w, new_aligned_h;
-    uint32_t active_width, active_height;
-    ColorMetaData color_metadata = {};
-
-    if (output_handle_format == HAL_PIXEL_FORMAT_RGBA_8888) {
-      output_handle_format = HAL_PIXEL_FORMAT_RGBX_8888;
-    }
-
-    LayerBufferFormat new_sdm_format = GetSDMFormat(output_handle_format, output_handle->flags);
-    if (new_sdm_format == kFormatInvalid) {
-      return HWC2::Error::BadParameter;
-    }
-
-    if (sdm::SetCSC(output_handle, &color_metadata) != kErrorNone) {
-      return HWC2::Error::BadParameter;
-    }
-
-    GetMixerResolution(&active_width, &active_height);
-    buffer_allocator_->GetCustomWidthAndHeight(output_handle, &new_width, &new_height);
-    buffer_allocator_->GetAlignedWidthAndHeight(INT(new_width), INT(new_height),
-                                                output_handle_format, 0, &new_aligned_w,
-                                                &new_aligned_h);
-    buffer_allocator_->GetAlignedWidthAndHeight(INT(active_width), INT(active_height),
-                                                output_handle_format, 0, &active_aligned_w,
-                                                &active_aligned_h);
-    if (new_aligned_w != active_aligned_w  || new_aligned_h != active_aligned_h) {
-      int status = SetConfig(UINT32(new_width), UINT32(new_height));
-      if (status) {
-        DLOGE("SetConfig failed custom WxH %dx%d", new_width, new_height);
-        return HWC2::Error::BadParameter;
-      }
-      validated_ = false;
-    }
-
-    output_buffer_->width = UINT32(new_aligned_w);
-    output_buffer_->height = UINT32(new_aligned_h);
-    output_buffer_->unaligned_width = UINT32(new_width);
-    output_buffer_->unaligned_height = UINT32(new_height);
-    output_buffer_->flags.secure = 0;
-    output_buffer_->flags.video = 0;
-    output_buffer_->buffer_id = reinterpret_cast<uint64_t>(output_handle);
-    output_buffer_->format = new_sdm_format;
-    output_buffer_->color_metadata = color_metadata;
-    output_handle_ = output_handle;
-
-    // TZ Protected Buffer - L1
-    if (output_handle->flags & private_handle_t::PRIV_FLAGS_SECURE_BUFFER) {
-      output_buffer_->flags.secure = 1;
-    }
-
-    // ToDo: Need to extend for non-RGB formats
-    output_buffer_->planes[0].fd = output_handle->fd;
-    output_buffer_->planes[0].offset = output_handle->offset;
-    output_buffer_->planes[0].stride = UINT32(output_handle->width);
-  }
-
-  return HWC2::Error::None;
-}
-
-HWC2::Error HWCDisplayVirtual::SetFrameDumpConfig(uint32_t count, uint32_t bit_mask_layer_type) {
-  HWCDisplay::SetFrameDumpConfig(count, bit_mask_layer_type);
-  dump_output_layer_ = ((bit_mask_layer_type & (1 << OUTPUT_LAYER_DUMP)) != 0);
-
-  DLOGI("output_layer_dump_enable %d", dump_output_layer_);
-  return HWC2::Error::None;
-}
-
-}  // namespace sdm
diff --git a/sdm/libs/hwc2/hwc_display_virtual.h b/sdm/libs/hwc2/hwc_display_virtual.h
deleted file mode 100644
index cf630fb..0000000
--- a/sdm/libs/hwc2/hwc_display_virtual.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (c) 2014-2017, The Linux Foundation. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
-    * Redistributions of source code must retain the above copyright
-      notice, this list of conditions and the following disclaimer.
-    * Redistributions in binary form must reproduce the above
-      copyright notice, this list of conditions and the following
-      disclaimer in the documentation and/or other materials provided
-      with the distribution.
-    * Neither the name of The Linux Foundation nor the names of its
-      contributors may be used to endorse or promote products derived
-      from this software without specific prior written permission.
-
- * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef __HWC_DISPLAY_VIRTUAL_H__
-#define __HWC_DISPLAY_VIRTUAL_H__
-
-#include <qdMetaData.h>
-#include <gralloc_priv.h>
-#include "hwc_display.h"
-
-namespace sdm {
-
-class HWCDisplayVirtual : public HWCDisplay {
- public:
-  static int Create(CoreInterface *core_intf, HWCBufferAllocator *buffer_allocator,
-                    HWCCallbacks *callbacks, uint32_t width,
-                    uint32_t height, int32_t *format, HWCDisplay **hwc_display);
-  static void Destroy(HWCDisplay *hwc_display);
-  virtual int Init();
-  virtual int Deinit();
-  virtual HWC2::Error Validate(uint32_t *out_num_types, uint32_t *out_num_requests);
-  virtual HWC2::Error Present(int32_t *out_retire_fence);
-  virtual HWC2::Error SetFrameDumpConfig(uint32_t count, uint32_t bit_mask_layer_type);
-  HWC2::Error SetOutputBuffer(buffer_handle_t buf, int32_t release_fence);
-
- private:
-  HWCDisplayVirtual(CoreInterface *core_intf, HWCBufferAllocator *buffer_allocator,
-                    HWCCallbacks *callbacks);
-  int SetConfig(uint32_t width, uint32_t height);
-
-  bool dump_output_layer_ = false;
-  LayerBuffer *output_buffer_ = NULL;
-  const private_handle_t *output_handle_ = nullptr;
-};
-
-}  // namespace sdm
-
-#endif  // __HWC_DISPLAY_VIRTUAL_H__
diff --git a/sdm/libs/hwc2/hwc_layers.cpp b/sdm/libs/hwc2/hwc_layers.cpp
deleted file mode 100644
index 2ae1f26..0000000
--- a/sdm/libs/hwc2/hwc_layers.cpp
+++ /dev/null
@@ -1,937 +0,0 @@
-/*
- * Copyright (c) 2014-2018, The Linux Foundation. All rights reserved.
- * Not a Contribution.
- *
- * Copyright 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 "hwc_layers.h"
-#include <utils/debug.h>
-#include <stdint.h>
-#include <utility>
-#include <cmath>
-#include <qdMetaData.h>
-
-#define __CLASS__ "HWCLayer"
-
-namespace sdm {
-
-std::atomic<hwc2_layer_t> HWCLayer::next_id_(1);
-
-DisplayError SetCSC(const private_handle_t *pvt_handle, ColorMetaData *color_metadata) {
-  if (getMetaData(const_cast<private_handle_t *>(pvt_handle), GET_COLOR_METADATA,
-                  color_metadata) != 0) {
-    ColorSpace_t csc = ITU_R_601;
-    if (getMetaData(const_cast<private_handle_t *>(pvt_handle),  GET_COLOR_SPACE,
-                    &csc) == 0) {
-      if (csc == ITU_R_601_FR || csc == ITU_R_2020_FR) {
-        color_metadata->range = Range_Full;
-      }
-
-      switch (csc) {
-      case ITU_R_601:
-      case ITU_R_601_FR:
-        // video and display driver uses 601_525
-        color_metadata->colorPrimaries = ColorPrimaries_BT601_6_525;
-        break;
-      case ITU_R_709:
-        color_metadata->colorPrimaries = ColorPrimaries_BT709_5;
-        break;
-      case ITU_R_2020:
-      case ITU_R_2020_FR:
-        color_metadata->colorPrimaries = ColorPrimaries_BT2020;
-        break;
-      default:
-        DLOGE("Unsupported CSC: %d", csc);
-        return kErrorNotSupported;
-      }
-    } else {
-      return kErrorNotSupported;
-    }
-  }
-
-  return kErrorNone;
-}
-
-// Returns true when color primary is supported
-bool GetColorPrimary(const int32_t &dataspace, ColorPrimaries *color_primary) {
-  auto standard = dataspace & HAL_DATASPACE_STANDARD_MASK;
-  bool supported_csc = true;
-  switch (standard) {
-    case  HAL_DATASPACE_STANDARD_BT709:
-      *color_primary = ColorPrimaries_BT709_5;
-      break;
-    case HAL_DATASPACE_STANDARD_BT601_525:
-    case HAL_DATASPACE_STANDARD_BT601_525_UNADJUSTED:
-      *color_primary = ColorPrimaries_BT601_6_525;
-      break;
-    case HAL_DATASPACE_STANDARD_BT601_625:
-    case HAL_DATASPACE_STANDARD_BT601_625_UNADJUSTED:
-      *color_primary = ColorPrimaries_BT601_6_625;
-      break;
-    case HAL_DATASPACE_STANDARD_DCI_P3:
-      *color_primary = ColorPrimaries_DCIP3;
-      break;
-    case HAL_DATASPACE_STANDARD_BT2020:
-      *color_primary = ColorPrimaries_BT2020;
-      break;
-    default:
-      DLOGV_IF(kTagClient, "Unsupported Standard Request = %d", standard);
-      supported_csc = false;
-  }
-  return supported_csc;
-}
-
-bool GetTransfer(const int32_t &dataspace, GammaTransfer *gamma_transfer) {
-  auto transfer = dataspace & HAL_DATASPACE_TRANSFER_MASK;
-  bool supported_transfer = true;
-  switch (transfer) {
-    case HAL_DATASPACE_TRANSFER_SRGB:
-      *gamma_transfer = Transfer_sRGB;
-      break;
-    case HAL_DATASPACE_TRANSFER_SMPTE_170M:
-      *gamma_transfer = Transfer_SMPTE_170M;
-      break;
-    case HAL_DATASPACE_TRANSFER_ST2084:
-      *gamma_transfer = Transfer_SMPTE_ST2084;
-      break;
-    case HAL_DATASPACE_TRANSFER_HLG:
-      *gamma_transfer = Transfer_HLG;
-      break;
-    case HAL_DATASPACE_TRANSFER_LINEAR:
-      *gamma_transfer = Transfer_Linear;
-      break;
-    case HAL_DATASPACE_TRANSFER_GAMMA2_2:
-      *gamma_transfer = Transfer_Gamma2_2;
-      break;
-    default:
-      DLOGV_IF(kTagClient, "Unsupported Transfer Request = %d", transfer);
-      supported_transfer = false;
-  }
-  return supported_transfer;
-}
-
-void GetRange(const int32_t &dataspace, ColorRange *color_range) {
-  auto range = dataspace & HAL_DATASPACE_RANGE_MASK;
-  switch (range) {
-    case HAL_DATASPACE_RANGE_FULL:
-      *color_range = Range_Full;
-      break;
-    case HAL_DATASPACE_RANGE_LIMITED:
-      *color_range = Range_Limited;
-      break;
-    default:
-      DLOGV_IF(kTagClient, "Unsupported Range Request = %d", range);
-      break;
-  }
-}
-
-bool IsBT2020(const ColorPrimaries &color_primary) {
-  switch (color_primary) {
-  case ColorPrimaries_BT2020:
-    return true;
-    break;
-  default:
-    return false;
-  }
-}
-
-// Retrieve ColorMetaData from android_data_space_t (STANDARD|TRANSFER|RANGE)
-bool GetSDMColorSpace(const int32_t &dataspace, ColorMetaData *color_metadata) {
-  bool valid = false;
-  valid = GetColorPrimary(dataspace, &(color_metadata->colorPrimaries));
-  if (!valid) {
-    return valid;
-  }
-  valid = GetTransfer(dataspace, &(color_metadata->transfer));
-  if (!valid) {
-    return valid;
-  }
-  GetRange(dataspace, &(color_metadata->range));
-
-  return true;
-}
-
-// Layer operations
-HWCLayer::HWCLayer(hwc2_display_t display_id, HWCBufferAllocator *buf_allocator)
-  : id_(next_id_++), display_id_(display_id), buffer_allocator_(buf_allocator) {
-  layer_ = new Layer();
-  // Fences are deferred, so the first time this layer is presented, return -1
-  // TODO(user): Verify that fences are properly obtained on suspend/resume
-  release_fences_.push_back(-1);
-}
-
-HWCLayer::~HWCLayer() {
-  // Close any fences left for this layer
-  while (!release_fences_.empty()) {
-    ::close(release_fences_.front());
-    release_fences_.pop_front();
-  }
-  if (layer_) {
-    if (layer_->input_buffer.acquire_fence_fd >= 0) {
-      ::close(layer_->input_buffer.acquire_fence_fd);
-    }
-    if (buffer_fd_ >= 0) {
-      ::close(buffer_fd_);
-    }
-    delete layer_;
-  }
-}
-
-HWC2::Error HWCLayer::SetLayerBuffer(buffer_handle_t buffer, int32_t acquire_fence) {
-  if (!buffer) {
-    if (client_requested_ == HWC2::Composition::Device ||
-        client_requested_ == HWC2::Composition::Cursor) {
-      DLOGE("Invalid buffer handle: %p on layer: %d client requested comp type %d", buffer, id_,
-            client_requested_);
-      ::close(acquire_fence);
-      return HWC2::Error::BadParameter;
-    } else {
-      return HWC2::Error::None;
-    }
-  }
-
-  if (acquire_fence == 0) {
-    DLOGE("acquire_fence is zero");
-    return HWC2::Error::BadParameter;
-  }
-
-  const private_handle_t *handle = static_cast<const private_handle_t *>(buffer);
-
-  if (handle->fd < 0) {
-    return HWC2::Error::BadParameter;
-  }
-
-  LayerBuffer *layer_buffer = &layer_->input_buffer;
-  int aligned_width, aligned_height;
-  buffer_allocator_->GetCustomWidthAndHeight(handle, &aligned_width, &aligned_height);
-
-  LayerBufferFormat format = GetSDMFormat(handle->format, handle->flags);
-  if ((format != layer_buffer->format) || (UINT32(aligned_width) != layer_buffer->width) ||
-      (UINT32(aligned_height) != layer_buffer->height)) {
-    // Layer buffer geometry has changed.
-    geometry_changes_ |= kBufferGeometry;
-  }
-
-  layer_buffer->format = format;
-  layer_buffer->width = UINT32(aligned_width);
-  layer_buffer->height = UINT32(aligned_height);
-  layer_buffer->unaligned_width = UINT32(handle->unaligned_width);
-  layer_buffer->unaligned_height = UINT32(handle->unaligned_height);
-
-  if (SetMetaData(const_cast<private_handle_t *>(handle), layer_) != kErrorNone) {
-    return HWC2::Error::BadLayer;
-  }
-
-  layer_buffer->flags.video = (handle->buffer_type == BUFFER_TYPE_VIDEO) ? true : false;
-
-  // TZ Protected Buffer - L1
-  bool secure = (handle->flags & private_handle_t::PRIV_FLAGS_SECURE_BUFFER);
-  bool secure_camera = secure && (handle->flags & private_handle_t::PRIV_FLAGS_CAMERA_WRITE);
-  bool secure_display = (handle->flags & private_handle_t::PRIV_FLAGS_SECURE_DISPLAY);
-  if (secure != layer_buffer->flags.secure || secure_camera != layer_buffer->flags.secure_camera ||
-      secure_display != layer_buffer->flags.secure_display) {
-    // Secure attribute of layer buffer has changed.
-    needs_validate_ = true;
-  }
-
-  layer_buffer->flags.secure = secure;
-  layer_buffer->flags.secure_camera = secure_camera;
-  layer_buffer->flags.secure_display = secure_display;
-
-  if (layer_buffer->acquire_fence_fd >= 0) {
-    ::close(layer_buffer->acquire_fence_fd);
-  }
-  layer_buffer->acquire_fence_fd = acquire_fence;
-  if (buffer_fd_ >= 0) {
-    ::close(buffer_fd_);
-  }
-  buffer_fd_ = ::dup(handle->fd);
-  layer_buffer->planes[0].fd = buffer_fd_;
-  layer_buffer->planes[0].offset = handle->offset;
-  layer_buffer->planes[0].stride = UINT32(handle->width);
-  layer_buffer->size = handle->size;
-  layer_buffer->buffer_id = reinterpret_cast<uint64_t>(handle);
-
-  return HWC2::Error::None;
-}
-
-HWC2::Error HWCLayer::SetLayerSurfaceDamage(hwc_region_t damage) {
-  // Check if there is an update in SurfaceDamage rects
-  if (layer_->dirty_regions.size() != damage.numRects) {
-    needs_validate_ = true;
-  } else {
-    for (uint32_t j = 0; j < damage.numRects; j++) {
-      LayerRect damage_rect;
-      SetRect(damage.rects[j], &damage_rect);
-      if (damage_rect != layer_->dirty_regions.at(j)) {
-        needs_validate_ = true;
-        break;
-      }
-    }
-  }
-
-  layer_->dirty_regions.clear();
-  for (uint32_t i = 0; i < damage.numRects; i++) {
-    LayerRect rect;
-    SetRect(damage.rects[i], &rect);
-    layer_->dirty_regions.push_back(rect);
-  }
-  return HWC2::Error::None;
-}
-
-HWC2::Error HWCLayer::SetLayerBlendMode(HWC2::BlendMode mode) {
-  LayerBlending blending = kBlendingPremultiplied;
-  switch (mode) {
-    case HWC2::BlendMode::Coverage:
-      blending = kBlendingCoverage;
-      break;
-    case HWC2::BlendMode::Premultiplied:
-      blending = kBlendingPremultiplied;
-      break;
-    case HWC2::BlendMode::None:
-      blending = kBlendingOpaque;
-      break;
-    default:
-      return HWC2::Error::BadParameter;
-  }
-
-  if (layer_->blending != blending) {
-    geometry_changes_ |= kBlendMode;
-    layer_->blending = blending;
-  }
-  return HWC2::Error::None;
-}
-
-HWC2::Error HWCLayer::SetLayerColor(hwc_color_t color) {
-  if (client_requested_ != HWC2::Composition::SolidColor) {
-    return HWC2::Error::None;
-  }
-  layer_->solid_fill_color = GetUint32Color(color);
-  layer_->input_buffer.format = kFormatARGB8888;
-  DLOGV_IF(kTagClient, "[%" PRIu64 "][%" PRIu64 "] Layer color set to %x", display_id_, id_,
-           layer_->solid_fill_color);
-  return HWC2::Error::None;
-}
-
-HWC2::Error HWCLayer::SetLayerCompositionType(HWC2::Composition type) {
-  // Validation is required when the client changes the composition type
-  if (client_requested_ != type) {
-    needs_validate_ = true;
-  }
-  client_requested_ = type;
-  switch (type) {
-    case HWC2::Composition::Client:
-      break;
-    case HWC2::Composition::Device:
-      // We try and default to this in SDM
-      break;
-    case HWC2::Composition::SolidColor:
-      break;
-    case HWC2::Composition::Cursor:
-      break;
-    case HWC2::Composition::Invalid:
-      return HWC2::Error::BadParameter;
-    default:
-      return HWC2::Error::Unsupported;
-  }
-
-  return HWC2::Error::None;
-}
-
-HWC2::Error HWCLayer::SetLayerDataspace(int32_t dataspace) {
-  // Map deprecated dataspace values to appropriate
-  // new enums
-  if (dataspace & 0xffff) {
-    switch (dataspace & 0xffff) {
-      case HAL_DATASPACE_SRGB:
-        dataspace = HAL_DATASPACE_V0_SRGB;
-        break;
-      case HAL_DATASPACE_JFIF:
-        dataspace = HAL_DATASPACE_V0_JFIF;
-        break;
-      case HAL_DATASPACE_SRGB_LINEAR:
-        dataspace = HAL_DATASPACE_V0_SRGB_LINEAR;
-        break;
-      case HAL_DATASPACE_BT601_625:
-        dataspace = HAL_DATASPACE_V0_BT601_625;
-        break;
-      case HAL_DATASPACE_BT601_525:
-        dataspace = HAL_DATASPACE_V0_BT601_525;
-        break;
-      case HAL_DATASPACE_BT709:
-        dataspace = HAL_DATASPACE_V0_BT709;
-        break;
-      default:
-        // unknown legacy dataspace
-        DLOGW_IF(kTagClient, "Unsupported dataspace type %d", dataspace);
-    }
-  }
-
-  // cache the dataspace, to be used later to update SDM ColorMetaData
-  if (dataspace_ != dataspace) {
-    geometry_changes_ |= kDataspace;
-    dataspace_ = dataspace;
-  }
-  return HWC2::Error::None;
-}
-
-HWC2::Error HWCLayer::SetLayerDisplayFrame(hwc_rect_t frame) {
-  LayerRect dst_rect = {};
-
-  SetRect(frame, &dst_rect);
-  if (dst_rect_ != dst_rect) {
-    geometry_changes_ |= kDisplayFrame;
-    dst_rect_ = dst_rect;
-  }
-
-  return HWC2::Error::None;
-}
-
-void HWCLayer::ResetPerFrameData() {
-  layer_->dst_rect = dst_rect_;
-  layer_->transform = layer_transform_;
-}
-
-HWC2::Error HWCLayer::SetCursorPosition(int32_t x, int32_t y) {
-  hwc_rect_t frame = {};
-  frame.left = x;
-  frame.top = y;
-  frame.right = x + INT(layer_->dst_rect.right - layer_->dst_rect.left);
-  frame.bottom = y + INT(layer_->dst_rect.bottom - layer_->dst_rect.top);
-  SetLayerDisplayFrame(frame);
-
-  return HWC2::Error::None;
-}
-
-HWC2::Error HWCLayer::SetLayerPlaneAlpha(float alpha) {
-  if (alpha < 0.0f || alpha > 1.0f) {
-    return HWC2::Error::BadParameter;
-  }
-
-  //  Conversion of float alpha in range 0.0 to 1.0 similar to the HWC Adapter
-  uint8_t plane_alpha = static_cast<uint8_t>(std::round(255.0f * alpha));
-
-  if (layer_->plane_alpha != plane_alpha) {
-    geometry_changes_ |= kPlaneAlpha;
-    layer_->plane_alpha = plane_alpha;
-  }
-
-  return HWC2::Error::None;
-}
-
-HWC2::Error HWCLayer::SetLayerSourceCrop(hwc_frect_t crop) {
-  LayerRect src_rect = {};
-  SetRect(crop, &src_rect);
-  non_integral_source_crop_ = ((crop.left != roundf(crop.left)) ||
-                              (crop.top != roundf(crop.top)) ||
-                              (crop.right != roundf(crop.right)) ||
-                              (crop.bottom != roundf(crop.bottom)));
-  if (non_integral_source_crop_) {
-    DLOGV_IF(kTagClient, "Crop: LTRB %f %f %f %f", crop.left, crop.top, crop.right, crop.bottom);
-  }
-  if (layer_->src_rect != src_rect) {
-    geometry_changes_ |= kSourceCrop;
-    layer_->src_rect = src_rect;
-  }
-
-  return HWC2::Error::None;
-}
-
-HWC2::Error HWCLayer::SetLayerTransform(HWC2::Transform transform) {
-  LayerTransform layer_transform = {};
-  switch (transform) {
-    case HWC2::Transform::FlipH:
-      layer_transform.flip_horizontal = true;
-      break;
-    case HWC2::Transform::FlipV:
-      layer_transform.flip_vertical = true;
-      break;
-    case HWC2::Transform::Rotate90:
-      layer_transform.rotation = 90.0f;
-      break;
-    case HWC2::Transform::Rotate180:
-      layer_transform.flip_horizontal = true;
-      layer_transform.flip_vertical = true;
-      break;
-    case HWC2::Transform::Rotate270:
-      layer_transform.rotation = 90.0f;
-      layer_transform.flip_horizontal = true;
-      layer_transform.flip_vertical = true;
-      break;
-    case HWC2::Transform::FlipHRotate90:
-      layer_transform.rotation = 90.0f;
-      layer_transform.flip_horizontal = true;
-      break;
-    case HWC2::Transform::FlipVRotate90:
-      layer_transform.rotation = 90.0f;
-      layer_transform.flip_vertical = true;
-      break;
-    case HWC2::Transform::None:
-      break;
-    default:
-      //  bad transform
-      return HWC2::Error::BadParameter;
-  }
-
-  if (layer_transform_ != layer_transform) {
-    geometry_changes_ |= kTransform;
-    layer_transform_ = layer_transform;
-  }
-
-  return HWC2::Error::None;
-}
-
-HWC2::Error HWCLayer::SetLayerVisibleRegion(hwc_region_t visible) {
-  layer_->visible_regions.clear();
-  for (uint32_t i = 0; i < visible.numRects; i++) {
-    LayerRect rect;
-    SetRect(visible.rects[i], &rect);
-    layer_->visible_regions.push_back(rect);
-  }
-
-  return HWC2::Error::None;
-}
-
-HWC2::Error HWCLayer::SetLayerZOrder(uint32_t z) {
-  if (z_ != z) {
-    geometry_changes_ |= kZOrder;
-    z_ = z;
-  }
-  return HWC2::Error::None;
-}
-
-void HWCLayer::SetRect(const hwc_rect_t &source, LayerRect *target) {
-  target->left = FLOAT(source.left);
-  target->top = FLOAT(source.top);
-  target->right = FLOAT(source.right);
-  target->bottom = FLOAT(source.bottom);
-}
-
-void HWCLayer::SetRect(const hwc_frect_t &source, LayerRect *target) {
-  // Recommended way of rounding as in hwcomposer2.h - SetLayerSourceCrop
-  target->left = std::ceil(source.left);
-  target->top = std::ceil(source.top);
-  target->right = std::floor(source.right);
-  target->bottom = std::floor(source.bottom);
-}
-
-uint32_t HWCLayer::GetUint32Color(const hwc_color_t &source) {
-  // Returns 32 bit ARGB
-  uint32_t a = UINT32(source.a) << 24;
-  uint32_t r = UINT32(source.r) << 16;
-  uint32_t g = UINT32(source.g) << 8;
-  uint32_t b = UINT32(source.b);
-  uint32_t color = a | r | g | b;
-  return color;
-}
-
-LayerBufferFormat HWCLayer::GetSDMFormat(const int32_t &source, const int flags) {
-  LayerBufferFormat format = kFormatInvalid;
-  if (flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED) {
-    switch (source) {
-      case HAL_PIXEL_FORMAT_RGBA_8888:
-        format = kFormatRGBA8888Ubwc;
-        break;
-      case HAL_PIXEL_FORMAT_RGBX_8888:
-        format = kFormatRGBX8888Ubwc;
-        break;
-      case HAL_PIXEL_FORMAT_BGR_565:
-        format = kFormatBGR565Ubwc;
-        break;
-      case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
-      case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
-      case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
-        format = kFormatYCbCr420SPVenusUbwc;
-        break;
-      case HAL_PIXEL_FORMAT_RGBA_1010102:
-        format = kFormatRGBA1010102Ubwc;
-        break;
-      case HAL_PIXEL_FORMAT_RGBX_1010102:
-        format = kFormatRGBX1010102Ubwc;
-        break;
-      case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
-        format = kFormatYCbCr420TP10Ubwc;
-        break;
-      case HAL_PIXEL_FORMAT_YCbCr_420_P010_UBWC:
-        format = kFormatYCbCr420P010Ubwc;
-        break;
-      default:
-        DLOGE("Unsupported format type for UBWC %d", source);
-        return kFormatInvalid;
-    }
-    return format;
-  }
-
-  switch (source) {
-    case HAL_PIXEL_FORMAT_RGBA_8888:
-      format = kFormatRGBA8888;
-      break;
-    case HAL_PIXEL_FORMAT_RGBA_5551:
-      format = kFormatRGBA5551;
-      break;
-    case HAL_PIXEL_FORMAT_RGBA_4444:
-      format = kFormatRGBA4444;
-      break;
-    case HAL_PIXEL_FORMAT_BGRA_8888:
-      format = kFormatBGRA8888;
-      break;
-    case HAL_PIXEL_FORMAT_RGBX_8888:
-      format = kFormatRGBX8888;
-      break;
-    case HAL_PIXEL_FORMAT_BGRX_8888:
-      format = kFormatBGRX8888;
-      break;
-    case HAL_PIXEL_FORMAT_RGB_888:
-      format = kFormatRGB888;
-      break;
-    case HAL_PIXEL_FORMAT_BGR_888:
-      format = kFormatBGR888;
-      break;
-    case HAL_PIXEL_FORMAT_RGB_565:
-      format = kFormatRGB565;
-      break;
-    case HAL_PIXEL_FORMAT_BGR_565:
-      format = kFormatBGR565;
-      break;
-    case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
-    case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
-      format = kFormatYCbCr420SemiPlanarVenus;
-      break;
-    case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS:
-      format = kFormatYCrCb420SemiPlanarVenus;
-      break;
-    case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
-      format = kFormatYCbCr420SPVenusUbwc;
-      break;
-    case HAL_PIXEL_FORMAT_YV12:
-      format = kFormatYCrCb420PlanarStride16;
-      break;
-    case HAL_PIXEL_FORMAT_YCrCb_420_SP:
-      format = kFormatYCrCb420SemiPlanar;
-      break;
-    case HAL_PIXEL_FORMAT_YCbCr_420_SP:
-      format = kFormatYCbCr420SemiPlanar;
-      break;
-    case HAL_PIXEL_FORMAT_YCbCr_422_SP:
-      format = kFormatYCbCr422H2V1SemiPlanar;
-      break;
-    case HAL_PIXEL_FORMAT_YCbCr_422_I:
-      format = kFormatYCbCr422H2V1Packed;
-      break;
-    case HAL_PIXEL_FORMAT_CbYCrY_422_I:
-      format = kFormatCbYCrY422H2V1Packed;
-      break;
-    case HAL_PIXEL_FORMAT_RGBA_1010102:
-      format = kFormatRGBA1010102;
-      break;
-    case HAL_PIXEL_FORMAT_ARGB_2101010:
-      format = kFormatARGB2101010;
-      break;
-    case HAL_PIXEL_FORMAT_RGBX_1010102:
-      format = kFormatRGBX1010102;
-      break;
-    case HAL_PIXEL_FORMAT_XRGB_2101010:
-      format = kFormatXRGB2101010;
-      break;
-    case HAL_PIXEL_FORMAT_BGRA_1010102:
-      format = kFormatBGRA1010102;
-      break;
-    case HAL_PIXEL_FORMAT_ABGR_2101010:
-      format = kFormatABGR2101010;
-      break;
-    case HAL_PIXEL_FORMAT_BGRX_1010102:
-      format = kFormatBGRX1010102;
-      break;
-    case HAL_PIXEL_FORMAT_XBGR_2101010:
-      format = kFormatXBGR2101010;
-      break;
-    case HAL_PIXEL_FORMAT_YCbCr_420_P010:
-      format = kFormatYCbCr420P010;
-      break;
-    case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
-      format = kFormatYCbCr420TP10Ubwc;
-      break;
-    case HAL_PIXEL_FORMAT_YCbCr_420_P010_UBWC:
-      format = kFormatYCbCr420P010Ubwc;
-      break;
-    case HAL_PIXEL_FORMAT_YCbCr_420_P010_VENUS:
-      format = kFormatYCbCr420P010Venus;
-      break;
-    case HAL_PIXEL_FORMAT_RGBA_FP16:
-      format = kFormatInvalid;
-      break;
-    default:
-      DLOGW("Unsupported format type = %d", source);
-      return kFormatInvalid;
-  }
-
-  return format;
-}
-
-LayerBufferS3DFormat HWCLayer::GetS3DFormat(uint32_t s3d_format) {
-  LayerBufferS3DFormat sdm_s3d_format = kS3dFormatNone;
-  switch (s3d_format) {
-    case HAL_NO_3D:
-      sdm_s3d_format = kS3dFormatNone;
-      break;
-    case HAL_3D_SIDE_BY_SIDE_L_R:
-      sdm_s3d_format = kS3dFormatLeftRight;
-      break;
-    case HAL_3D_SIDE_BY_SIDE_R_L:
-      sdm_s3d_format = kS3dFormatRightLeft;
-      break;
-    case HAL_3D_TOP_BOTTOM:
-      sdm_s3d_format = kS3dFormatTopBottom;
-      break;
-    default:
-      DLOGW("Invalid S3D format %d", s3d_format);
-  }
-  return sdm_s3d_format;
-}
-
-void HWCLayer::GetUBWCStatsFromMetaData(UBWCStats *cr_stats, UbwcCrStatsVector *cr_vec) {
-  // TODO(user): Check if we can use UBWCStats directly
-  // in layer_buffer or copy directly to Vector
-  if (cr_stats->bDataValid) {
-    switch (cr_stats->version) {
-      case UBWC_2_0:
-        cr_vec->push_back(std::make_pair(32, cr_stats->ubwc_stats.nCRStatsTile32));
-        cr_vec->push_back(std::make_pair(64, cr_stats->ubwc_stats.nCRStatsTile64));
-        cr_vec->push_back(std::make_pair(96, cr_stats->ubwc_stats.nCRStatsTile96));
-        cr_vec->push_back(std::make_pair(128, cr_stats->ubwc_stats.nCRStatsTile128));
-        cr_vec->push_back(std::make_pair(160, cr_stats->ubwc_stats.nCRStatsTile160));
-        cr_vec->push_back(std::make_pair(192, cr_stats->ubwc_stats.nCRStatsTile192));
-        cr_vec->push_back(std::make_pair(256, cr_stats->ubwc_stats.nCRStatsTile256));
-        break;
-      default:
-        DLOGW("Invalid UBWC Version %d", cr_stats->version);
-        break;
-    }  // switch(cr_stats->version)
-  }  // if (cr_stats->bDatvalid)
-}
-
-DisplayError HWCLayer::SetMetaData(const private_handle_t *pvt_handle, Layer *layer) {
-  LayerBuffer *layer_buffer = &layer->input_buffer;
-  private_handle_t *handle = const_cast<private_handle_t *>(pvt_handle);
-  IGC_t igc = {};
-  LayerIGC layer_igc = layer_buffer->igc;
-  if (getMetaData(handle, GET_IGC, &igc) == 0) {
-    if (SetIGC(igc, &layer_igc) != kErrorNone) {
-      return kErrorNotSupported;
-    }
-  }
-
-  float fps = 0;
-  uint32_t frame_rate = layer->frame_rate;
-  if (getMetaData(handle, GET_REFRESH_RATE, &fps) == 0) {
-    frame_rate = (fps != 0) ? RoundToStandardFPS(fps) : layer->frame_rate;
-    has_metadata_refresh_rate_ = true;
-  }
-
-  int32_t interlaced = 0;
-  getMetaData(handle, GET_PP_PARAM_INTERLACED, &interlaced);
-  bool interlace = interlaced ? true : false;
-
-  if (interlace != layer_buffer->flags.interlace) {
-    DLOGI("Layer buffer interlaced metadata has changed. old=%d, new=%d",
-          layer_buffer->flags.interlace, interlace);
-  }
-
-  uint32_t linear_format = 0;
-  if (getMetaData(handle, GET_LINEAR_FORMAT, &linear_format) == 0) {
-    layer_buffer->format = GetSDMFormat(INT32(linear_format), 0);
-  }
-
-  uint32_t s3d = 0;
-  LayerBufferS3DFormat s3d_format = layer_buffer->s3d_format;
-  if (getMetaData(handle, GET_S3D_FORMAT, &s3d) == 0) {
-    s3d_format = GetS3DFormat(s3d);
-  }
-
-  if ((layer_igc != layer_buffer->igc) || (interlace != layer_buffer->flags.interlace) ||
-      (frame_rate != layer->frame_rate) || (s3d_format != layer_buffer->s3d_format)) {
-    // Layer buffer metadata has changed.
-    needs_validate_ = true;
-    layer_buffer->igc = layer_igc;
-    layer->frame_rate = frame_rate;
-    layer_buffer->s3d_format = s3d_format;
-    layer_buffer->flags.interlace = interlace;
-  }
-
-  // Check if metadata is set
-  struct UBWCStats cr_stats[NUM_UBWC_CR_STATS_LAYERS] = {};
-
-  for (int i = 0; i < NUM_UBWC_CR_STATS_LAYERS; i++) {
-    layer_buffer->ubwc_crstats[i].clear();
-  }
-
-  if (getMetaData(handle, GET_UBWC_CR_STATS_INFO, cr_stats) == 0) {
-  // Only copy top layer for now as only top field for interlaced is used
-    GetUBWCStatsFromMetaData(&cr_stats[0], &(layer_buffer->ubwc_crstats[0]));
-  }  // if (getMetaData)
-
-  single_buffer_ = false;
-  getMetaData(const_cast<private_handle_t *>(handle), GET_SINGLE_BUFFER_MODE, &single_buffer_);
-
-  return kErrorNone;
-}
-
-DisplayError HWCLayer::SetIGC(IGC_t source, LayerIGC *target) {
-  switch (source) {
-    case IGC_NotSpecified:
-      *target = kIGCNotSpecified;
-      break;
-    case IGC_sRGB:
-      *target = kIGCsRGB;
-      break;
-    default:
-      DLOGE("Unsupported IGC: %d", source);
-      return kErrorNotSupported;
-  }
-
-  return kErrorNone;
-}
-
-
-
-bool HWCLayer::SupportLocalConversion(ColorPrimaries working_primaries) {
-  if (layer_->input_buffer.color_metadata.colorPrimaries <= ColorPrimaries_BT601_6_525 &&
-      working_primaries <= ColorPrimaries_BT601_6_525) {
-    return true;
-  }
-  return false;
-}
-
-bool HWCLayer::ValidateAndSetCSC() {
-  if (client_requested_ != HWC2::Composition::Device &&
-      client_requested_ != HWC2::Composition::Cursor) {
-    // Check the layers which are configured to Device
-    return true;
-  }
-
-  LayerBuffer *layer_buffer = &layer_->input_buffer;
-  bool use_color_metadata = true;
-#ifdef FEATURE_WIDE_COLOR
-  ColorMetaData csc = {};
-  if (dataspace_ != HAL_DATASPACE_UNKNOWN) {
-    use_color_metadata = false;
-    bool valid_csc = GetSDMColorSpace(dataspace_, &csc);
-    if (!valid_csc) {
-      return false;
-    }
-    // if we are here here, update the sdm layer csc.
-    layer_buffer->color_metadata.transfer = csc.transfer;
-    layer_buffer->color_metadata.colorPrimaries = csc.colorPrimaries;
-    layer_buffer->color_metadata.range = csc.range;
-  }
-#endif
-
-  if (IsBT2020(layer_buffer->color_metadata.colorPrimaries)) {
-     // android_dataspace_t doesnt support mastering display and light levels
-     // so retrieve it from metadata for BT2020(HDR)
-     use_color_metadata = true;
-  }
-
-  if (use_color_metadata) {
-    const private_handle_t *handle =
-      reinterpret_cast<const private_handle_t *>(layer_buffer->buffer_id);
-    if (sdm::SetCSC(handle, &layer_buffer->color_metadata) != kErrorNone) {
-      return false;
-    }
-  }
-
-  return true;
-}
-
-
-uint32_t HWCLayer::RoundToStandardFPS(float fps) {
-  static const uint32_t standard_fps[4] = {24, 30, 48, 60};
-  uint32_t frame_rate = (uint32_t)(fps);
-
-  int count = INT(sizeof(standard_fps) / sizeof(standard_fps[0]));
-  for (int i = 0; i < count; i++) {
-    if ((standard_fps[i] - frame_rate) < 2) {
-      // Most likely used for video, the fps can fluctuate
-      // Ex: b/w 29 and 30 for 30 fps clip
-      return standard_fps[i];
-    }
-  }
-
-  return frame_rate;
-}
-
-void HWCLayer::SetComposition(const LayerComposition &sdm_composition) {
-  auto hwc_composition = HWC2::Composition::Invalid;
-  switch (sdm_composition) {
-    case kCompositionGPU:
-      hwc_composition = HWC2::Composition::Client;
-      break;
-    case kCompositionCursor:
-      hwc_composition = HWC2::Composition::Cursor;
-      break;
-    default:
-      hwc_composition = HWC2::Composition::Device;
-      break;
-  }
-  // Update solid fill composition
-  if (sdm_composition == kCompositionSDE && layer_->flags.solid_fill != 0) {
-    hwc_composition = HWC2::Composition::SolidColor;
-  }
-  device_selected_ = hwc_composition;
-
-  return;
-}
-
-void HWCLayer::PushBackReleaseFence(int32_t fence) {
-  release_fences_.push_back(fence);
-}
-
-int32_t HWCLayer::PopBackReleaseFence() {
-  if (release_fences_.empty())
-    return -1;
-
-  auto fence = release_fences_.back();
-  release_fences_.pop_back();
-
-  return fence;
-}
-
-int32_t HWCLayer::PopFrontReleaseFence() {
-  if (release_fences_.empty())
-    return -1;
-
-  auto fence = release_fences_.front();
-  release_fences_.pop_front();
-
-  return fence;
-}
-
-bool HWCLayer::IsRotationPresent() {
-  return ((layer_->transform.rotation != 0.0f) ||
-         layer_->transform.flip_horizontal ||
-         layer_->transform.flip_vertical);
-}
-
-bool HWCLayer::IsScalingPresent() {
-  uint32_t src_width  = static_cast<uint32_t>(layer_->src_rect.right - layer_->src_rect.left);
-  uint32_t src_height = static_cast<uint32_t>(layer_->src_rect.bottom - layer_->src_rect.top);
-  uint32_t dst_width  = static_cast<uint32_t>(layer_->dst_rect.right - layer_->dst_rect.left);
-  uint32_t dst_height = static_cast<uint32_t>(layer_->dst_rect.bottom - layer_->dst_rect.top);
-
-  return ((src_width != dst_width) || (dst_height != src_height));
-}
-
-}  // namespace sdm
diff --git a/sdm/libs/hwc2/hwc_layers.h b/sdm/libs/hwc2/hwc_layers.h
deleted file mode 100644
index 41ec6ed..0000000
--- a/sdm/libs/hwc2/hwc_layers.h
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- * Copyright (c) 2014-2018, The Linux Foundation. All rights reserved.
- * Not a Contribution.
- *
- * Copyright 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.
- */
-
-#ifndef __HWC_LAYERS_H__
-#define __HWC_LAYERS_H__
-
-/* This class translates HWC2 Layer functions to the SDM LayerStack
- */
-
-#include <gralloc_priv.h>
-#include <qdMetaData.h>
-#include <core/layer_stack.h>
-#define HWC2_INCLUDE_STRINGIFICATION
-#define HWC2_USE_CPP11
-#include <hardware/hwcomposer2.h>
-#undef HWC2_INCLUDE_STRINGIFICATION
-#undef HWC2_USE_CPP11
-#include <map>
-#include <deque>
-#include <set>
-#include "core/buffer_allocator.h"
-#include "hwc_buffer_allocator.h"
-
-namespace sdm {
-
-DisplayError SetCSC(const private_handle_t *pvt_handle, ColorMetaData *color_metadata);
-bool GetColorPrimary(const int32_t &dataspace, ColorPrimaries *color_primary);
-bool GetTransfer(const int32_t &dataspace, GammaTransfer *gamma_transfer);
-void GetRange(const int32_t &dataspace, ColorRange *color_range);
-bool GetSDMColorSpace(const int32_t &dataspace, ColorMetaData *color_metadata);
-bool IsBT2020(const ColorPrimaries &color_primary);
-enum GeometryChanges {
-  kNone         = 0x000,
-  kBlendMode    = 0x001,
-  kDataspace    = 0x002,
-  kDisplayFrame = 0x004,
-  kPlaneAlpha   = 0x008,
-  kSourceCrop   = 0x010,
-  kTransform    = 0x020,
-  kZOrder       = 0x040,
-  kAdded        = 0x080,
-  kRemoved      = 0x100,
-  kBufferGeometry = 0x200,
-};
-
-class HWCLayer {
- public:
-  explicit HWCLayer(hwc2_display_t display_id, HWCBufferAllocator *buf_allocator);
-  ~HWCLayer();
-  uint32_t GetZ() const { return z_; }
-  hwc2_layer_t GetId() const { return id_; }
-  Layer *GetSDMLayer() { return layer_; }
-  void ResetPerFrameData();
-
-  HWC2::Error SetLayerBlendMode(HWC2::BlendMode mode);
-  HWC2::Error SetLayerBuffer(buffer_handle_t buffer, int32_t acquire_fence);
-  HWC2::Error SetLayerColor(hwc_color_t color);
-  HWC2::Error SetLayerCompositionType(HWC2::Composition type);
-  HWC2::Error SetLayerDataspace(int32_t dataspace);
-  HWC2::Error SetLayerDisplayFrame(hwc_rect_t frame);
-  HWC2::Error SetCursorPosition(int32_t x, int32_t y);
-  HWC2::Error SetLayerPlaneAlpha(float alpha);
-  HWC2::Error SetLayerSourceCrop(hwc_frect_t crop);
-  HWC2::Error SetLayerSurfaceDamage(hwc_region_t damage);
-  HWC2::Error SetLayerTransform(HWC2::Transform transform);
-  HWC2::Error SetLayerVisibleRegion(hwc_region_t visible);
-  HWC2::Error SetLayerZOrder(uint32_t z);
-  void SetComposition(const LayerComposition &sdm_composition);
-  HWC2::Composition GetClientRequestedCompositionType() { return client_requested_; }
-  void UpdateClientCompositionType(HWC2::Composition type) { client_requested_ = type; }
-  HWC2::Composition GetDeviceSelectedCompositionType() { return device_selected_; }
-  int32_t GetLayerDataspace() { return dataspace_; }
-  uint32_t GetGeometryChanges() { return geometry_changes_; }
-  void ResetGeometryChanges() { geometry_changes_ = GeometryChanges::kNone; }
-  void PushBackReleaseFence(int32_t fence);
-  int32_t PopBackReleaseFence(void);
-  int32_t PopFrontReleaseFence(void);
-  bool ValidateAndSetCSC();
-  bool SupportLocalConversion(ColorPrimaries working_primaries);
-  void ResetValidation() { needs_validate_ = false; }
-  bool NeedsValidation() { return (needs_validate_ || geometry_changes_); }
-  bool IsSingleBuffered() { return single_buffer_; }
-  bool IsScalingPresent();
-  bool IsRotationPresent();
-  bool IsNonIntegralSourceCrop() { return non_integral_source_crop_; }
-  bool HasMetaDataRefreshRate() { return has_metadata_refresh_rate_; }
-
- private:
-  Layer *layer_ = nullptr;
-  uint32_t z_ = 0;
-  const hwc2_layer_t id_;
-  const hwc2_display_t display_id_;
-  static std::atomic<hwc2_layer_t> next_id_;
-  std::deque<int32_t> release_fences_;
-  HWCBufferAllocator *buffer_allocator_ = NULL;
-  int32_t dataspace_ =  HAL_DATASPACE_UNKNOWN;
-  LayerTransform layer_transform_ = {};
-  LayerRect dst_rect_ = {};
-  bool needs_validate_ = true;
-  bool single_buffer_ = false;
-  int buffer_fd_ = -1;
-  bool non_integral_source_crop_ = false;
-  bool has_metadata_refresh_rate_ = false;
-
-  // Composition requested by client(SF)
-  HWC2::Composition client_requested_ = HWC2::Composition::Device;
-  // Composition selected by SDM
-  HWC2::Composition device_selected_ = HWC2::Composition::Device;
-  uint32_t geometry_changes_ = GeometryChanges::kNone;
-
-  void SetRect(const hwc_rect_t &source, LayerRect *target);
-  void SetRect(const hwc_frect_t &source, LayerRect *target);
-  uint32_t GetUint32Color(const hwc_color_t &source);
-  LayerBufferFormat GetSDMFormat(const int32_t &source, const int flags);
-  LayerBufferS3DFormat GetS3DFormat(uint32_t s3d_format);
-  void GetUBWCStatsFromMetaData(UBWCStats *cr_stats, UbwcCrStatsVector *cr_vec);
-  DisplayError SetMetaData(const private_handle_t *pvt_handle, Layer *layer);
-  DisplayError SetIGC(IGC_t source, LayerIGC *target);
-  uint32_t RoundToStandardFPS(float fps);
-};
-
-struct SortLayersByZ {
-  bool operator()(const HWCLayer *lhs, const HWCLayer *rhs) const {
-    return lhs->GetZ() < rhs->GetZ();
-  }
-};
-
-}  // namespace sdm
-#endif  // __HWC_LAYERS_H__
diff --git a/sdm/libs/hwc2/hwc_session.cpp b/sdm/libs/hwc2/hwc_session.cpp
deleted file mode 100644
index b54b077..0000000
--- a/sdm/libs/hwc2/hwc_session.cpp
+++ /dev/null
@@ -1,1872 +0,0 @@
-/*
- * Copyright (c) 2014-2018, The Linux Foundation. All rights reserved.
- * Not a Contribution.
- *
- * Copyright 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 <core/buffer_allocator.h>
-#include <private/color_params.h>
-#include <utils/constants.h>
-#include <utils/String16.h>
-#include <cutils/properties.h>
-#include <hardware_legacy/uevent.h>
-#include <sys/resource.h>
-#include <sys/prctl.h>
-#include <binder/Parcel.h>
-#include <QService.h>
-#include <display_config.h>
-#include <utils/debug.h>
-#include <sync/sync.h>
-#include <qd_utils.h>
-#include <utils/utils.h>
-#include <algorithm>
-#include <string>
-#include <bitset>
-#include <thread>
-#include <memory>
-
-#include "hwc_buffer_allocator.h"
-#include "hwc_buffer_sync_handler.h"
-#include "hwc_session.h"
-#include "hwc_debugger.h"
-#include "hwc_display_primary.h"
-#include "hwc_display_virtual.h"
-#include "hwc_display_external_test.h"
-
-#define __CLASS__ "HWCSession"
-
-#define HWC_UEVENT_SWITCH_HDMI "change@/devices/virtual/switch/hdmi"
-#define HWC_UEVENT_GRAPHICS_FB0 "change@/devices/virtual/graphics/fb0"
-#define HWC_UEVENT_DRM_EXT_HOTPLUG "mdss_mdp/drm/card"
-
-static sdm::HWCSession::HWCModuleMethods g_hwc_module_methods;
-
-hwc_module_t HAL_MODULE_INFO_SYM = {
-  .common = {
-    .tag = HARDWARE_MODULE_TAG,
-    .version_major = 3,
-    .version_minor = 0,
-    .id = HWC_HARDWARE_MODULE_ID,
-    .name = "QTI Hardware Composer Module",
-    .author = "CodeAurora Forum",
-    .methods = &g_hwc_module_methods,
-    .dso = 0,
-    .reserved = {0},
-  }
-};
-
-namespace sdm {
-
-static HWCUEvent g_hwc_uevent_;
-Locker HWCSession::locker_[HWC_NUM_DISPLAY_TYPES];
-static const int kSolidFillDelay = 100 * 1000;
-
-void HWCUEvent::UEventThread(HWCUEvent *hwc_uevent) {
-  const char *uevent_thread_name = "HWC_UeventThread";
-
-  prctl(PR_SET_NAME, uevent_thread_name, 0, 0, 0);
-  setpriority(PRIO_PROCESS, 0, HAL_PRIORITY_URGENT_DISPLAY);
-
-  int status = uevent_init();
-  if (!status) {
-    std::unique_lock<std::mutex> caller_lock(hwc_uevent->mutex_);
-    hwc_uevent->caller_cv_.notify_one();
-    DLOGE("Failed to init uevent with err %d", status);
-    return;
-  }
-
-  {
-    // Signal caller thread that worker thread is ready to listen to events.
-    std::unique_lock<std::mutex> caller_lock(hwc_uevent->mutex_);
-    hwc_uevent->init_done_ = true;
-    hwc_uevent->caller_cv_.notify_one();
-  }
-
-  while (1) {
-    char uevent_data[PAGE_SIZE] = {};
-
-    // keep last 2 zeroes to ensure double 0 termination
-    int length = uevent_next_event(uevent_data, INT32(sizeof(uevent_data)) - 2);
-
-    // scope of lock to this block only, so that caller is free to set event handler to nullptr;
-    {
-      std::lock_guard<std::mutex> guard(hwc_uevent->mutex_);
-      if (hwc_uevent->uevent_listener_) {
-        hwc_uevent->uevent_listener_->UEventHandler(uevent_data, length);
-      } else {
-        DLOGW("UEvent dropped. No uevent listener.");
-      }
-    }
-  }
-}
-
-HWCUEvent::HWCUEvent() {
-  std::unique_lock<std::mutex> caller_lock(mutex_);
-  std::thread thread(HWCUEvent::UEventThread, this);
-  thread.detach();
-  caller_cv_.wait(caller_lock);
-}
-
-void HWCUEvent::Register(HWCUEventListener *uevent_listener) {
-  DLOGI("Set uevent listener = %p", uevent_listener);
-
-  std::lock_guard<std::mutex> obj(mutex_);
-  uevent_listener_ = uevent_listener;
-}
-
-HWCSession::HWCSession(const hw_module_t *module) {
-  hwc2_device_t::common.tag = HARDWARE_DEVICE_TAG;
-  hwc2_device_t::common.version = HWC_DEVICE_API_VERSION_2_0;
-  hwc2_device_t::common.module = const_cast<hw_module_t *>(module);
-  hwc2_device_t::common.close = Close;
-  hwc2_device_t::getCapabilities = GetCapabilities;
-  hwc2_device_t::getFunction = GetFunction;
-}
-
-int HWCSession::Init() {
-  SCOPE_LOCK(locker_[HWC_DISPLAY_PRIMARY]);
-
-  int status = -EINVAL;
-  const char *qservice_name = "display.qservice";
-
-  if (!g_hwc_uevent_.InitDone()) {
-    return status;
-  }
-
-  // Start QService and connect to it.
-  qService::QService::init();
-  android::sp<qService::IQService> iqservice = android::interface_cast<qService::IQService>(
-      android::defaultServiceManager()->getService(android::String16(qservice_name)));
-
-  if (iqservice.get()) {
-    iqservice->connect(android::sp<qClient::IQClient>(this));
-    qservice_ = reinterpret_cast<qService::QService *>(iqservice.get());
-  } else {
-    DLOGE("Failed to acquire %s", qservice_name);
-    return -EINVAL;
-  }
-
-  StartServices();
-
-  g_hwc_uevent_.Register(this);
-
-  auto error = CoreInterface::CreateCore(&buffer_allocator_, &buffer_sync_handler_,
-                                    &socket_handler_, &core_intf_);
-
-  // If HDMI display is primary display, defer display creation until hotplug event is received.
-  HWDisplayInterfaceInfo hw_disp_info = {};
-  error = core_intf_->GetFirstDisplayInterfaceType(&hw_disp_info);
-  if (error != kErrorNone) {
-    g_hwc_uevent_.Register(nullptr);
-    CoreInterface::DestroyCore();
-    DLOGE("Primary display type not recognized. Error = %d", error);
-    return -EINVAL;
-  }
-
-  if (hw_disp_info.type == kHDMI) {
-    status = 0;
-    hdmi_is_primary_ = true;
-    // Create display if it is connected, else wait for hotplug connect event.
-    if (hw_disp_info.is_connected) {
-      status = CreateExternalDisplay(HWC_DISPLAY_PRIMARY, 0, 0, false);
-    }
-  } else {
-    // Create and power on primary display
-    status = HWCDisplayPrimary::Create(core_intf_, &buffer_allocator_, &callbacks_, qservice_,
-                                       &hwc_display_[HWC_DISPLAY_PRIMARY]);
-    color_mgr_ = HWCColorManager::CreateColorManager(&buffer_allocator_);
-    if (!color_mgr_) {
-      DLOGW("Failed to load HWCColorManager.");
-    }
-  }
-
-  if (status) {
-    g_hwc_uevent_.Register(nullptr);
-    CoreInterface::DestroyCore();
-    return status;
-  }
-
-  is_composer_up_ = true;
-
-  return 0;
-}
-
-int HWCSession::Deinit() {
-  Locker::SequenceCancelScopeLock lock_v(locker_[HWC_DISPLAY_VIRTUAL]);
-  Locker::SequenceCancelScopeLock lock_e(locker_[HWC_DISPLAY_EXTERNAL]);
-  Locker::SequenceCancelScopeLock lock_p(locker_[HWC_DISPLAY_PRIMARY]);
-
-  HWCDisplay *primary_display = hwc_display_[HWC_DISPLAY_PRIMARY];
-  if (primary_display) {
-    if (hdmi_is_primary_) {
-      HWCDisplayExternal::Destroy(primary_display);
-    } else {
-      HWCDisplayPrimary::Destroy(primary_display);
-    }
-  }
-  hwc_display_[HWC_DISPLAY_PRIMARY] = nullptr;
-
-  if (color_mgr_) {
-    color_mgr_->DestroyColorManager();
-  }
-
-  g_hwc_uevent_.Register(nullptr);
-
-  DisplayError error = CoreInterface::DestroyCore();
-  if (error != kErrorNone) {
-    DLOGE("Display core de-initialization failed. Error = %d", error);
-  }
-
-  return 0;
-}
-
-int HWCSession::Open(const hw_module_t *module, const char *name, hw_device_t **device) {
-  if (!module || !name || !device) {
-    DLOGE("Invalid parameters.");
-    return -EINVAL;
-  }
-
-  if (!strcmp(name, HWC_HARDWARE_COMPOSER)) {
-    HWCSession *hwc_session = new HWCSession(module);
-    if (!hwc_session) {
-      return -ENOMEM;
-    }
-
-    int status = hwc_session->Init();
-    if (status != 0) {
-      delete hwc_session;
-      hwc_session = NULL;
-      return status;
-    }
-
-    hwc2_device_t *composer_device = hwc_session;
-    *device = reinterpret_cast<hw_device_t *>(composer_device);
-  }
-
-  return 0;
-}
-
-int HWCSession::Close(hw_device_t *device) {
-  if (!device) {
-    return -EINVAL;
-  }
-
-  hwc2_device_t *composer_device = reinterpret_cast<hwc2_device_t *>(device);
-  HWCSession *hwc_session = static_cast<HWCSession *>(composer_device);
-
-  hwc_session->Deinit();
-
-  return 0;
-}
-
-void HWCSession::GetCapabilities(struct hwc2_device *device, uint32_t *outCount,
-                                 int32_t *outCapabilities) {
-  if (!outCount) {
-    return;
-  }
-
-  int value = 0;
-  bool disable_skip_validate = false;
-  if (Debug::Get()->GetProperty(DISABLE_SKIP_VALIDATE_PROP, &value) == kErrorNone) {
-    disable_skip_validate = (value == 1);
-  }
-  uint32_t count = 1 + (disable_skip_validate ? 0 : 1);
-
-  if (outCapabilities != nullptr && (*outCount >= count)) {
-    outCapabilities[0] = HWC2_CAPABILITY_SKIP_CLIENT_COLOR_TRANSFORM;
-    if (!disable_skip_validate) {
-      outCapabilities[1] = HWC2_CAPABILITY_SKIP_VALIDATE;
-    }
-  }
-  *outCount = count;
-}
-
-template <typename PFN, typename T>
-static hwc2_function_pointer_t AsFP(T function) {
-  static_assert(std::is_same<PFN, T>::value, "Incompatible function pointer");
-  return reinterpret_cast<hwc2_function_pointer_t>(function);
-}
-
-// HWC2 functions returned in GetFunction
-// Defined in the same order as in the HWC2 header
-
-int32_t HWCSession::AcceptDisplayChanges(hwc2_device_t *device, hwc2_display_t display) {
-  return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::AcceptDisplayChanges);
-}
-
-int32_t HWCSession::CreateLayer(hwc2_device_t *device, hwc2_display_t display,
-                                hwc2_layer_t *out_layer_id) {
-  if (!out_layer_id) {
-    return  HWC2_ERROR_BAD_PARAMETER;
-  }
-
-  return CallDisplayFunction(device, display, &HWCDisplay::CreateLayer, out_layer_id);
-}
-
-int32_t HWCSession::CreateVirtualDisplay(hwc2_device_t *device, uint32_t width, uint32_t height,
-                                         int32_t *format, hwc2_display_t *out_display_id) {
-  // TODO(user): Handle concurrency with HDMI
-  if (!device) {
-    return HWC2_ERROR_BAD_DISPLAY;
-  }
-
-  if (!out_display_id || !width || !height || !format) {
-    return  HWC2_ERROR_BAD_PARAMETER;
-  }
-
-  HWCSession *hwc_session = static_cast<HWCSession *>(device);
-  auto status = hwc_session->CreateVirtualDisplayObject(width, height, format);
-
-  if (status == HWC2::Error::None) {
-    *out_display_id = HWC_DISPLAY_VIRTUAL;
-    DLOGI("Created virtual display id:% " PRIu64 " with res: %dx%d",
-          *out_display_id, width, height);
-  } else {
-    DLOGE("Failed to create virtual display: %s", to_string(status).c_str());
-  }
-  return INT32(status);
-}
-
-int32_t HWCSession::DestroyLayer(hwc2_device_t *device, hwc2_display_t display,
-                                 hwc2_layer_t layer) {
-  return CallDisplayFunction(device, display, &HWCDisplay::DestroyLayer, layer);
-}
-
-int32_t HWCSession::DestroyVirtualDisplay(hwc2_device_t *device, hwc2_display_t display) {
-  if (!device || display != HWC_DISPLAY_VIRTUAL) {
-    return HWC2_ERROR_BAD_DISPLAY;
-  }
-
-  SCOPE_LOCK(locker_[display]);
-  DLOGI("Destroying virtual display id:%" PRIu64, display);
-  auto *hwc_session = static_cast<HWCSession *>(device);
-
-  if (hwc_session->hwc_display_[display]) {
-    HWCDisplayVirtual::Destroy(hwc_session->hwc_display_[display]);
-    hwc_session->hwc_display_[display] = nullptr;
-    return HWC2_ERROR_NONE;
-  } else {
-    return HWC2_ERROR_BAD_DISPLAY;
-  }
-}
-
-void HWCSession::Dump(hwc2_device_t *device, uint32_t *out_size, char *out_buffer) {
-  if (!device || !out_size) {
-    return;
-  }
-
-  auto *hwc_session = static_cast<HWCSession *>(device);
-  const size_t max_dump_size = 8192;
-
-  if (out_buffer == nullptr) {
-    *out_size = max_dump_size;
-  } else {
-    std::string s {};
-    for (int id = HWC_DISPLAY_PRIMARY; id <= HWC_DISPLAY_VIRTUAL; id++) {
-      SCOPE_LOCK(locker_[id]);
-      if (hwc_session->hwc_display_[id]) {
-        s += hwc_session->hwc_display_[id]->Dump();
-      }
-    }
-    auto copied = s.copy(out_buffer, std::min(s.size(), max_dump_size), 0);
-    *out_size = UINT32(copied);
-  }
-}
-
-static int32_t GetActiveConfig(hwc2_device_t *device, hwc2_display_t display,
-                               hwc2_config_t *out_config) {
-  return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::GetActiveConfig, out_config);
-}
-
-static int32_t GetChangedCompositionTypes(hwc2_device_t *device, hwc2_display_t display,
-                                          uint32_t *out_num_elements, hwc2_layer_t *out_layers,
-                                          int32_t *out_types) {
-  // null_ptr check only for out_num_elements, as out_layers and out_types can be null.
-  if (!out_num_elements) {
-    return  HWC2_ERROR_BAD_PARAMETER;
-  }
-  return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::GetChangedCompositionTypes,
-                                         out_num_elements, out_layers, out_types);
-}
-
-static int32_t GetClientTargetSupport(hwc2_device_t *device, hwc2_display_t display, uint32_t width,
-                                      uint32_t height, int32_t format, int32_t dataspace) {
-  return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::GetClientTargetSupport,
-                                         width, height, format, dataspace);
-}
-
-static int32_t GetColorModes(hwc2_device_t *device, hwc2_display_t display, uint32_t *out_num_modes,
-                             int32_t /*android_color_mode_t*/ *int_out_modes) {
-  auto out_modes = reinterpret_cast<android_color_mode_t *>(int_out_modes);
-  if (out_num_modes == nullptr) {
-    return HWC2_ERROR_BAD_PARAMETER;
-  }
-  return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::GetColorModes, out_num_modes,
-                                         out_modes);
-}
-
-static int32_t GetDisplayAttribute(hwc2_device_t *device, hwc2_display_t display,
-                                   hwc2_config_t config, int32_t int_attribute,
-                                   int32_t *out_value) {
-  if (out_value == nullptr || int_attribute < HWC2_ATTRIBUTE_INVALID ||
-      int_attribute > HWC2_ATTRIBUTE_DPI_Y) {
-    return HWC2_ERROR_BAD_PARAMETER;
-  }
-  auto attribute = static_cast<HWC2::Attribute>(int_attribute);
-  return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::GetDisplayAttribute, config,
-                                         attribute, out_value);
-}
-
-static int32_t GetDisplayConfigs(hwc2_device_t *device, hwc2_display_t display,
-                                 uint32_t *out_num_configs, hwc2_config_t *out_configs) {
-  return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::GetDisplayConfigs,
-                                         out_num_configs, out_configs);
-}
-
-static int32_t GetDisplayName(hwc2_device_t *device, hwc2_display_t display, uint32_t *out_size,
-                              char *out_name) {
-  return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::GetDisplayName, out_size,
-                                         out_name);
-}
-
-static int32_t GetDisplayRequests(hwc2_device_t *device, hwc2_display_t display,
-                                  int32_t *out_display_requests, uint32_t *out_num_elements,
-                                  hwc2_layer_t *out_layers, int32_t *out_layer_requests) {
-  return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::GetDisplayRequests,
-                                         out_display_requests, out_num_elements, out_layers,
-                                         out_layer_requests);
-}
-
-static int32_t GetDisplayType(hwc2_device_t *device, hwc2_display_t display, int32_t *out_type) {
-  return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::GetDisplayType, out_type);
-}
-
-static int32_t GetDozeSupport(hwc2_device_t *device, hwc2_display_t display, int32_t *out_support) {
-  if (!device || !out_support) {
-    return HWC2_ERROR_BAD_PARAMETER;
-  }
-
-  if (display >= HWC_NUM_DISPLAY_TYPES) {
-    return HWC2_ERROR_BAD_DISPLAY;
-  }
-
-  if (display == HWC_DISPLAY_PRIMARY) {
-    *out_support = 1;
-  } else {
-    *out_support = 0;
-  }
-
-  return HWC2_ERROR_NONE;
-}
-
-static int32_t GetHdrCapabilities(hwc2_device_t* device, hwc2_display_t display,
-                                  uint32_t* out_num_types, int32_t* out_types,
-                                  float* out_max_luminance, float* out_max_average_luminance,
-                                  float* out_min_luminance) {
-  return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::GetHdrCapabilities,
-                                         out_num_types, out_types, out_max_luminance,
-                                         out_max_average_luminance, out_min_luminance);
-}
-
-static uint32_t GetMaxVirtualDisplayCount(hwc2_device_t *device) {
-  if (device == nullptr) {
-    return HWC2_ERROR_BAD_PARAMETER;
-  }
-
-  return 1;
-}
-
-static int32_t GetReleaseFences(hwc2_device_t *device, hwc2_display_t display,
-                                uint32_t *out_num_elements, hwc2_layer_t *out_layers,
-                                int32_t *out_fences) {
-  return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::GetReleaseFences,
-                                         out_num_elements, out_layers, out_fences);
-}
-
-int32_t HWCSession::PresentDisplay(hwc2_device_t *device, hwc2_display_t display,
-                                   int32_t *out_retire_fence) {
-  HWCSession *hwc_session = static_cast<HWCSession *>(device);
-  bool notify_hotplug = false;
-  auto status = HWC2::Error::BadDisplay;
-  DTRACE_SCOPED();
-
-  if (display >= HWC_NUM_DISPLAY_TYPES) {
-    return HWC2_ERROR_BAD_DISPLAY;
-  }
-
-  {
-    SEQUENCE_EXIT_SCOPE_LOCK(locker_[display]);
-    if (!device) {
-      return HWC2_ERROR_BAD_DISPLAY;
-    }
-
-    if (out_retire_fence == nullptr) {
-      return HWC2_ERROR_BAD_PARAMETER;
-    }
-
-    // TODO(user): Handle virtual display/HDMI concurrency
-    if (hwc_session->hwc_display_[display]) {
-      status = hwc_session->hwc_display_[display]->Present(out_retire_fence);
-    }
-  }
-
-  if (status != HWC2::Error::None && status != HWC2::Error::NotValidated) {
-    SEQUENCE_CANCEL_SCOPE_LOCK(locker_[display]);
-  }
-
-  // Handle Pending external display connection
-  if (hwc_session->external_pending_connect_ && (display == HWC_DISPLAY_PRIMARY)) {
-    Locker::ScopeLock lock_e(locker_[HWC_DISPLAY_EXTERNAL]);
-    Locker::ScopeLock lock_v(locker_[HWC_DISPLAY_VIRTUAL]);
-
-    if (!hwc_session->hwc_display_[HWC_DISPLAY_VIRTUAL]) {
-      DLOGD("Process pending external display connection");
-      hwc_session->ConnectDisplay(HWC_DISPLAY_EXTERNAL);
-      hwc_session->external_pending_connect_ = false;
-      notify_hotplug = true;
-    }
-  }
-
-  if (notify_hotplug) {
-    hwc_session->HotPlug(HWC_DISPLAY_EXTERNAL, HWC2::Connection::Connected);
-  }
-
-  return INT32(status);
-}
-
-int32_t HWCSession::RegisterCallback(hwc2_device_t *device, int32_t descriptor,
-                                     hwc2_callback_data_t callback_data,
-                                     hwc2_function_pointer_t pointer) {
-  if (!device) {
-    return HWC2_ERROR_BAD_PARAMETER;
-  }
-  HWCSession *hwc_session = static_cast<HWCSession *>(device);
-  SCOPE_LOCK(hwc_session->callbacks_lock_);
-  auto desc = static_cast<HWC2::Callback>(descriptor);
-  auto error = hwc_session->callbacks_.Register(desc, callback_data, pointer);
-  DLOGD("%s callback: %s", pointer ? "Registering" : "Deregistering", to_string(desc).c_str());
-  if (descriptor == HWC2_CALLBACK_HOTPLUG) {
-    if (hwc_session->hwc_display_[HWC_DISPLAY_PRIMARY]) {
-      hwc_session->callbacks_.Hotplug(HWC_DISPLAY_PRIMARY, HWC2::Connection::Connected);
-    }
-  }
-  hwc_session->need_invalidate_ = false;
-  hwc_session->callbacks_lock_.Broadcast();
-  return INT32(error);
-}
-
-static int32_t SetActiveConfig(hwc2_device_t *device, hwc2_display_t display,
-                               hwc2_config_t config) {
-  return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::SetActiveConfig, config);
-}
-
-static int32_t SetClientTarget(hwc2_device_t *device, hwc2_display_t display,
-                               buffer_handle_t target, int32_t acquire_fence,
-                               int32_t dataspace, hwc_region_t damage) {
-  return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::SetClientTarget, target,
-                                         acquire_fence, dataspace, damage);
-}
-
-int32_t HWCSession::SetColorMode(hwc2_device_t *device, hwc2_display_t display,
-                                 int32_t /*android_color_mode_t*/ int_mode) {
-  if (int_mode < HAL_COLOR_MODE_NATIVE || int_mode > HAL_COLOR_MODE_DISPLAY_P3) {
-    return HWC2_ERROR_BAD_PARAMETER;
-  }
-  auto mode = static_cast<android_color_mode_t>(int_mode);
-  return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::SetColorMode, mode);
-}
-
-int32_t HWCSession::SetColorTransform(hwc2_device_t *device, hwc2_display_t display,
-                                      const float *matrix,
-                                      int32_t /*android_color_transform_t*/ hint) {
-  if (!matrix || hint < HAL_COLOR_TRANSFORM_IDENTITY ||
-       hint > HAL_COLOR_TRANSFORM_CORRECT_TRITANOPIA) {
-    return HWC2_ERROR_BAD_PARAMETER;
-  }
-  android_color_transform_t transform_hint = static_cast<android_color_transform_t>(hint);
-  return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::SetColorTransform, matrix,
-                                         transform_hint);
-}
-
-static int32_t SetCursorPosition(hwc2_device_t *device, hwc2_display_t display, hwc2_layer_t layer,
-                                 int32_t x, int32_t y) {
-  auto status = INT32(HWC2::Error::None);
-  status = HWCSession::CallDisplayFunction(device, display, &HWCDisplay::SetCursorPosition,
-                                           layer, x, y);
-  if (status == INT32(HWC2::Error::None)) {
-    // Update cursor position
-    HWCSession::CallLayerFunction(device, display, layer, &HWCLayer::SetCursorPosition, x, y);
-  }
-  return status;
-}
-
-static int32_t SetLayerBlendMode(hwc2_device_t *device, hwc2_display_t display, hwc2_layer_t layer,
-                                 int32_t int_mode) {
-  if (int_mode < HWC2_BLEND_MODE_INVALID || int_mode > HWC2_BLEND_MODE_COVERAGE) {
-    return HWC2_ERROR_BAD_PARAMETER;
-  }
-  auto mode = static_cast<HWC2::BlendMode>(int_mode);
-  return HWCSession::CallLayerFunction(device, display, layer, &HWCLayer::SetLayerBlendMode, mode);
-}
-
-static int32_t SetLayerBuffer(hwc2_device_t *device, hwc2_display_t display, hwc2_layer_t layer,
-                              buffer_handle_t buffer, int32_t acquire_fence) {
-  return HWCSession::CallLayerFunction(device, display, layer, &HWCLayer::SetLayerBuffer, buffer,
-                                       acquire_fence);
-}
-
-static int32_t SetLayerColor(hwc2_device_t *device, hwc2_display_t display, hwc2_layer_t layer,
-                             hwc_color_t color) {
-  return HWCSession::CallLayerFunction(device, display, layer, &HWCLayer::SetLayerColor, color);
-}
-
-static int32_t SetLayerCompositionType(hwc2_device_t *device, hwc2_display_t display,
-                                       hwc2_layer_t layer, int32_t int_type) {
-  auto type = static_cast<HWC2::Composition>(int_type);
-  return HWCSession::CallLayerFunction(device, display, layer, &HWCLayer::SetLayerCompositionType,
-                                       type);
-}
-
-static int32_t SetLayerDataspace(hwc2_device_t *device, hwc2_display_t display, hwc2_layer_t layer,
-                                 int32_t dataspace) {
-  return HWCSession::CallLayerFunction(device, display, layer, &HWCLayer::SetLayerDataspace,
-                                       dataspace);
-}
-
-static int32_t SetLayerDisplayFrame(hwc2_device_t *device, hwc2_display_t display,
-                                    hwc2_layer_t layer, hwc_rect_t frame) {
-  return HWCSession::CallLayerFunction(device, display, layer, &HWCLayer::SetLayerDisplayFrame,
-                                       frame);
-}
-
-static int32_t SetLayerPlaneAlpha(hwc2_device_t *device, hwc2_display_t display, hwc2_layer_t layer,
-                                  float alpha) {
-  return HWCSession::CallLayerFunction(device, display, layer, &HWCLayer::SetLayerPlaneAlpha,
-                                       alpha);
-}
-
-static int32_t SetLayerSourceCrop(hwc2_device_t *device, hwc2_display_t display, hwc2_layer_t layer,
-                                  hwc_frect_t crop) {
-  return HWCSession::CallLayerFunction(device, display, layer, &HWCLayer::SetLayerSourceCrop, crop);
-}
-
-static int32_t SetLayerSurfaceDamage(hwc2_device_t *device, hwc2_display_t display,
-                                     hwc2_layer_t layer, hwc_region_t damage) {
-  return HWCSession::CallLayerFunction(device, display, layer, &HWCLayer::SetLayerSurfaceDamage,
-                                       damage);
-}
-
-static int32_t SetLayerTransform(hwc2_device_t *device, hwc2_display_t display, hwc2_layer_t layer,
-                                 int32_t int_transform) {
-  auto transform = static_cast<HWC2::Transform>(int_transform);
-  return HWCSession::CallLayerFunction(device, display, layer, &HWCLayer::SetLayerTransform,
-                                       transform);
-}
-
-static int32_t SetLayerVisibleRegion(hwc2_device_t *device, hwc2_display_t display,
-                                     hwc2_layer_t layer, hwc_region_t visible) {
-  return HWCSession::CallLayerFunction(device, display, layer, &HWCLayer::SetLayerVisibleRegion,
-                                       visible);
-}
-
-static int32_t SetLayerZOrder(hwc2_device_t *device, hwc2_display_t display, hwc2_layer_t layer,
-                              uint32_t z) {
-  return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::SetLayerZOrder, layer, z);
-}
-
-int32_t HWCSession::SetOutputBuffer(hwc2_device_t *device, hwc2_display_t display,
-                                    buffer_handle_t buffer, int32_t releaseFence) {
-  if (!device) {
-    return HWC2_ERROR_BAD_PARAMETER;
-  }
-
-  if (display != HWC_DISPLAY_VIRTUAL) {
-    return HWC2_ERROR_UNSUPPORTED;
-  }
-
-  SCOPE_LOCK(locker_[display]);
-  auto *hwc_session = static_cast<HWCSession *>(device);
-  if (hwc_session->hwc_display_[display]) {
-    auto vds = reinterpret_cast<HWCDisplayVirtual *>(hwc_session->hwc_display_[display]);
-    auto status = vds->SetOutputBuffer(buffer, releaseFence);
-    return INT32(status);
-  } else {
-    return HWC2_ERROR_BAD_DISPLAY;
-  }
-}
-
-int32_t HWCSession::SetPowerMode(hwc2_device_t *device, hwc2_display_t display, int32_t int_mode) {
-  if (display >= HWC_NUM_DISPLAY_TYPES) {
-    return HWC2_ERROR_BAD_DISPLAY;
-  }
-
-  //  validate device and also avoid undefined behavior in cast to HWC2::PowerMode
-  if (!device || int_mode < HWC2_POWER_MODE_OFF || int_mode > HWC2_POWER_MODE_DOZE_SUSPEND) {
-    return HWC2_ERROR_BAD_PARAMETER;
-  }
-
-  auto mode = static_cast<HWC2::PowerMode>(int_mode);
-
-  //  all displays support on/off. Check for doze modes
-  int support = 0;
-  GetDozeSupport(device, display, &support);
-  if (!support && (mode == HWC2::PowerMode::Doze || mode == HWC2::PowerMode::DozeSuspend)) {
-    return HWC2_ERROR_UNSUPPORTED;
-  }
-
-  return CallDisplayFunction(device, display, &HWCDisplay::SetPowerMode, mode);
-}
-
-static int32_t SetVsyncEnabled(hwc2_device_t *device, hwc2_display_t display, int32_t int_enabled) {
-  //  avoid undefined behavior in cast to HWC2::Vsync
-  if (int_enabled < HWC2_VSYNC_INVALID || int_enabled > HWC2_VSYNC_DISABLE) {
-    return HWC2_ERROR_BAD_PARAMETER;
-  }
-
-  auto enabled = static_cast<HWC2::Vsync>(int_enabled);
-  return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::SetVsyncEnabled, enabled);
-}
-
-int32_t HWCSession::ValidateDisplay(hwc2_device_t *device, hwc2_display_t display,
-                                    uint32_t *out_num_types, uint32_t *out_num_requests) {
-  //  out_num_types and out_num_requests will be non-NULL
-  if (!device) {
-    return HWC2_ERROR_BAD_PARAMETER;
-  }
-
-  if (display >= HWC_NUM_DISPLAY_TYPES) {
-    return HWC2_ERROR_BAD_DISPLAY;
-  }
-
-  DTRACE_SCOPED();
-  HWCSession *hwc_session = static_cast<HWCSession *>(device);
-  // TODO(user): Handle secure session, handle QDCM solid fill
-  // Handle external_pending_connect_ in CreateVirtualDisplay
-  auto status = HWC2::Error::BadDisplay;
-  {
-    SEQUENCE_ENTRY_SCOPE_LOCK(locker_[display]);
-    if (hwc_session->hwc_display_[display]) {
-      if (display == HWC_DISPLAY_PRIMARY) {
-        // TODO(user): This can be moved to HWCDisplayPrimary
-        if (hwc_session->reset_panel_) {
-          DLOGW("panel is in bad state, resetting the panel");
-          hwc_session->ResetPanel();
-        }
-
-        if (hwc_session->need_invalidate_) {
-          hwc_session->Refresh(display);
-          hwc_session->need_invalidate_ = false;
-        }
-
-        if (hwc_session->color_mgr_) {
-          hwc_session->color_mgr_->SetColorModeDetailEnhancer(hwc_session->hwc_display_[display]);
-        }
-      }
-
-      status = hwc_session->hwc_display_[display]->Validate(out_num_types, out_num_requests);
-    }
-  }
-
-  // Sequence locking currently begins on Validate, so cancel the sequence lock on failures
-  if (status != HWC2::Error::None && status != HWC2::Error::HasChanges) {
-    SEQUENCE_CANCEL_SCOPE_LOCK(locker_[display]);
-  }
-
-  return INT32(status);
-}
-
-hwc2_function_pointer_t HWCSession::GetFunction(struct hwc2_device *device,
-                                                int32_t int_descriptor) {
-  auto descriptor = static_cast<HWC2::FunctionDescriptor>(int_descriptor);
-
-  switch (descriptor) {
-    case HWC2::FunctionDescriptor::AcceptDisplayChanges:
-      return AsFP<HWC2_PFN_ACCEPT_DISPLAY_CHANGES>(HWCSession::AcceptDisplayChanges);
-    case HWC2::FunctionDescriptor::CreateLayer:
-      return AsFP<HWC2_PFN_CREATE_LAYER>(CreateLayer);
-    case HWC2::FunctionDescriptor::CreateVirtualDisplay:
-      return AsFP<HWC2_PFN_CREATE_VIRTUAL_DISPLAY>(HWCSession::CreateVirtualDisplay);
-    case HWC2::FunctionDescriptor::DestroyLayer:
-      return AsFP<HWC2_PFN_DESTROY_LAYER>(DestroyLayer);
-    case HWC2::FunctionDescriptor::DestroyVirtualDisplay:
-      return AsFP<HWC2_PFN_DESTROY_VIRTUAL_DISPLAY>(HWCSession::DestroyVirtualDisplay);
-    case HWC2::FunctionDescriptor::Dump:
-      return AsFP<HWC2_PFN_DUMP>(HWCSession::Dump);
-    case HWC2::FunctionDescriptor::GetActiveConfig:
-      return AsFP<HWC2_PFN_GET_ACTIVE_CONFIG>(GetActiveConfig);
-    case HWC2::FunctionDescriptor::GetChangedCompositionTypes:
-      return AsFP<HWC2_PFN_GET_CHANGED_COMPOSITION_TYPES>(GetChangedCompositionTypes);
-    case HWC2::FunctionDescriptor::GetClientTargetSupport:
-      return AsFP<HWC2_PFN_GET_CLIENT_TARGET_SUPPORT>(GetClientTargetSupport);
-    case HWC2::FunctionDescriptor::GetColorModes:
-      return AsFP<HWC2_PFN_GET_COLOR_MODES>(GetColorModes);
-    case HWC2::FunctionDescriptor::GetDisplayAttribute:
-      return AsFP<HWC2_PFN_GET_DISPLAY_ATTRIBUTE>(GetDisplayAttribute);
-    case HWC2::FunctionDescriptor::GetDisplayConfigs:
-      return AsFP<HWC2_PFN_GET_DISPLAY_CONFIGS>(GetDisplayConfigs);
-    case HWC2::FunctionDescriptor::GetDisplayName:
-      return AsFP<HWC2_PFN_GET_DISPLAY_NAME>(GetDisplayName);
-    case HWC2::FunctionDescriptor::GetDisplayRequests:
-      return AsFP<HWC2_PFN_GET_DISPLAY_REQUESTS>(GetDisplayRequests);
-    case HWC2::FunctionDescriptor::GetDisplayType:
-      return AsFP<HWC2_PFN_GET_DISPLAY_TYPE>(GetDisplayType);
-    case HWC2::FunctionDescriptor::GetHdrCapabilities:
-      return AsFP<HWC2_PFN_GET_HDR_CAPABILITIES>(GetHdrCapabilities);
-    case HWC2::FunctionDescriptor::GetDozeSupport:
-      return AsFP<HWC2_PFN_GET_DOZE_SUPPORT>(GetDozeSupport);
-    case HWC2::FunctionDescriptor::GetMaxVirtualDisplayCount:
-      return AsFP<HWC2_PFN_GET_MAX_VIRTUAL_DISPLAY_COUNT>(GetMaxVirtualDisplayCount);
-    case HWC2::FunctionDescriptor::GetReleaseFences:
-      return AsFP<HWC2_PFN_GET_RELEASE_FENCES>(GetReleaseFences);
-    case HWC2::FunctionDescriptor::PresentDisplay:
-      return AsFP<HWC2_PFN_PRESENT_DISPLAY>(PresentDisplay);
-    case HWC2::FunctionDescriptor::RegisterCallback:
-      return AsFP<HWC2_PFN_REGISTER_CALLBACK>(RegisterCallback);
-    case HWC2::FunctionDescriptor::SetActiveConfig:
-      return AsFP<HWC2_PFN_SET_ACTIVE_CONFIG>(SetActiveConfig);
-    case HWC2::FunctionDescriptor::SetClientTarget:
-      return AsFP<HWC2_PFN_SET_CLIENT_TARGET>(SetClientTarget);
-    case HWC2::FunctionDescriptor::SetColorMode:
-      return AsFP<HWC2_PFN_SET_COLOR_MODE>(SetColorMode);
-    case HWC2::FunctionDescriptor::SetColorTransform:
-      return AsFP<HWC2_PFN_SET_COLOR_TRANSFORM>(SetColorTransform);
-    case HWC2::FunctionDescriptor::SetCursorPosition:
-      return AsFP<HWC2_PFN_SET_CURSOR_POSITION>(SetCursorPosition);
-    case HWC2::FunctionDescriptor::SetLayerBlendMode:
-      return AsFP<HWC2_PFN_SET_LAYER_BLEND_MODE>(SetLayerBlendMode);
-    case HWC2::FunctionDescriptor::SetLayerBuffer:
-      return AsFP<HWC2_PFN_SET_LAYER_BUFFER>(SetLayerBuffer);
-    case HWC2::FunctionDescriptor::SetLayerColor:
-      return AsFP<HWC2_PFN_SET_LAYER_COLOR>(SetLayerColor);
-    case HWC2::FunctionDescriptor::SetLayerCompositionType:
-      return AsFP<HWC2_PFN_SET_LAYER_COMPOSITION_TYPE>(SetLayerCompositionType);
-    case HWC2::FunctionDescriptor::SetLayerDataspace:
-      return AsFP<HWC2_PFN_SET_LAYER_DATASPACE>(SetLayerDataspace);
-    case HWC2::FunctionDescriptor::SetLayerDisplayFrame:
-      return AsFP<HWC2_PFN_SET_LAYER_DISPLAY_FRAME>(SetLayerDisplayFrame);
-    case HWC2::FunctionDescriptor::SetLayerPlaneAlpha:
-      return AsFP<HWC2_PFN_SET_LAYER_PLANE_ALPHA>(SetLayerPlaneAlpha);
-    // Sideband stream is not supported
-    // case HWC2::FunctionDescriptor::SetLayerSidebandStream:
-    case HWC2::FunctionDescriptor::SetLayerSourceCrop:
-      return AsFP<HWC2_PFN_SET_LAYER_SOURCE_CROP>(SetLayerSourceCrop);
-    case HWC2::FunctionDescriptor::SetLayerSurfaceDamage:
-      return AsFP<HWC2_PFN_SET_LAYER_SURFACE_DAMAGE>(SetLayerSurfaceDamage);
-    case HWC2::FunctionDescriptor::SetLayerTransform:
-      return AsFP<HWC2_PFN_SET_LAYER_TRANSFORM>(SetLayerTransform);
-    case HWC2::FunctionDescriptor::SetLayerVisibleRegion:
-      return AsFP<HWC2_PFN_SET_LAYER_VISIBLE_REGION>(SetLayerVisibleRegion);
-    case HWC2::FunctionDescriptor::SetLayerZOrder:
-      return AsFP<HWC2_PFN_SET_LAYER_Z_ORDER>(SetLayerZOrder);
-    case HWC2::FunctionDescriptor::SetOutputBuffer:
-      return AsFP<HWC2_PFN_SET_OUTPUT_BUFFER>(SetOutputBuffer);
-    case HWC2::FunctionDescriptor::SetPowerMode:
-      return AsFP<HWC2_PFN_SET_POWER_MODE>(SetPowerMode);
-    case HWC2::FunctionDescriptor::SetVsyncEnabled:
-      return AsFP<HWC2_PFN_SET_VSYNC_ENABLED>(SetVsyncEnabled);
-    case HWC2::FunctionDescriptor::ValidateDisplay:
-      return AsFP<HWC2_PFN_VALIDATE_DISPLAY>(HWCSession::ValidateDisplay);
-    default:
-      DLOGD("Unknown/Unimplemented function descriptor: %d (%s)", int_descriptor,
-            to_string(descriptor).c_str());
-      return nullptr;
-  }
-  return nullptr;
-}
-
-HWC2::Error HWCSession::CreateVirtualDisplayObject(uint32_t width, uint32_t height,
-                                                   int32_t *format) {
-  {
-    SCOPE_LOCK(locker_[HWC_DISPLAY_VIRTUAL]);
-    if (hwc_display_[HWC_DISPLAY_VIRTUAL]) {
-      return HWC2::Error::NoResources;
-    }
-
-    auto status = HWCDisplayVirtual::Create(core_intf_, &buffer_allocator_, &callbacks_, width,
-                                            height, format, &hwc_display_[HWC_DISPLAY_VIRTUAL]);
-    // TODO(user): validate width and height support
-    if (status) {
-      return HWC2::Error::Unsupported;
-    }
-  }
-
-  SEQUENCE_WAIT_SCOPE_LOCK(locker_[HWC_DISPLAY_PRIMARY]);
-  hwc_display_[HWC_DISPLAY_PRIMARY]->ResetValidation();
-
-  return HWC2::Error::None;
-}
-
-int32_t HWCSession::ConnectDisplay(int disp) {
-  DLOGI("Display = %d", disp);
-
-  int status = 0;
-  uint32_t primary_width = 0;
-  uint32_t primary_height = 0;
-
-  hwc_display_[HWC_DISPLAY_PRIMARY]->GetFrameBufferResolution(&primary_width, &primary_height);
-
-  if (disp == HWC_DISPLAY_EXTERNAL) {
-    status = CreateExternalDisplay(disp, primary_width, primary_height, false);
-  } else {
-    DLOGE("Invalid display type");
-    return -1;
-  }
-
-  if (!status) {
-    hwc_display_[disp]->SetSecureDisplay(secure_display_active_);
-  }
-
-  return status;
-}
-
-int HWCSession::DisconnectDisplay(int disp) {
-  DLOGI("Display = %d", disp);
-
-  if (disp == HWC_DISPLAY_EXTERNAL) {
-    DisplayError error = hwc_display_[disp]->Flush();
-    if (error != kErrorNone) {
-        DLOGW("Flush failed. Error = %d", error);
-    }
-    HWCDisplayExternal::Destroy(hwc_display_[disp]);
-  } else if (disp == HWC_DISPLAY_VIRTUAL) {
-    HWCDisplayVirtual::Destroy(hwc_display_[disp]);
-  } else {
-    DLOGE("Invalid display type");
-    return -1;
-  }
-
-  hwc_display_[disp] = NULL;
-
-  return 0;
-}
-
-// Qclient methods
-android::status_t HWCSession::notifyCallback(uint32_t command, const android::Parcel *input_parcel,
-                                             android::Parcel *output_parcel) {
-  android::status_t status = -EINVAL;
-
-  switch (command) {
-    case qService::IQService::DYNAMIC_DEBUG:
-      if (!input_parcel) {
-        DLOGE("QService command = %d: input_parcel needed.", command);
-        break;
-      }
-      status = 0;
-      DynamicDebug(input_parcel);
-      break;
-
-    case qService::IQService::SCREEN_REFRESH:
-      status = refreshScreen();
-      break;
-
-    case qService::IQService::SET_IDLE_TIMEOUT:
-      if (!input_parcel) {
-        DLOGE("QService command = %d: input_parcel needed.", command);
-        break;
-      }
-      status = setIdleTimeout(UINT32(input_parcel->readInt32()));
-      break;
-
-    case qService::IQService::SET_FRAME_DUMP_CONFIG:
-      if (!input_parcel) {
-        DLOGE("QService command = %d: input_parcel needed.", command);
-        break;
-      }
-      status = SetFrameDumpConfig(input_parcel);
-      break;
-
-    case qService::IQService::SET_MAX_PIPES_PER_MIXER:
-      if (!input_parcel) {
-        DLOGE("QService command = %d: input_parcel needed.", command);
-        break;
-      }
-      status = SetMaxMixerStages(input_parcel);
-      break;
-
-    case qService::IQService::SET_DISPLAY_MODE:
-      if (!input_parcel) {
-        DLOGE("QService command = %d: input_parcel needed.", command);
-        break;
-      }
-      status = SetDisplayMode(input_parcel);
-      break;
-
-    case qService::IQService::SET_SECONDARY_DISPLAY_STATUS: {
-        if (!input_parcel || !output_parcel) {
-          DLOGE("QService command = %d: input_parcel and output_parcel needed.", command);
-          break;
-        }
-        int disp_id = INT(input_parcel->readInt32());
-        HWCDisplay::DisplayStatus disp_status =
-              static_cast<HWCDisplay::DisplayStatus>(input_parcel->readInt32());
-        status = SetSecondaryDisplayStatus(disp_id, disp_status);
-        output_parcel->writeInt32(status);
-      }
-      break;
-
-    case qService::IQService::CONFIGURE_DYN_REFRESH_RATE:
-      if (!input_parcel) {
-        DLOGE("QService command = %d: input_parcel needed.", command);
-        break;
-      }
-      status = ConfigureRefreshRate(input_parcel);
-      break;
-
-    case qService::IQService::SET_VIEW_FRAME:
-      status = 0;
-      break;
-
-    case qService::IQService::TOGGLE_SCREEN_UPDATES: {
-        if (!input_parcel || !output_parcel) {
-          DLOGE("QService command = %d: input_parcel and output_parcel needed.", command);
-          break;
-        }
-        int32_t input = input_parcel->readInt32();
-        status = toggleScreenUpdate(input == 1);
-        output_parcel->writeInt32(status);
-      }
-      break;
-
-    case qService::IQService::QDCM_SVC_CMDS:
-      if (!input_parcel || !output_parcel) {
-        DLOGE("QService command = %d: input_parcel and output_parcel needed.", command);
-        break;
-      }
-      status = QdcmCMDHandler(input_parcel, output_parcel);
-      break;
-
-    case qService::IQService::MIN_HDCP_ENCRYPTION_LEVEL_CHANGED: {
-        if (!input_parcel || !output_parcel) {
-          DLOGE("QService command = %d: input_parcel and output_parcel needed.", command);
-          break;
-        }
-        int disp_id = input_parcel->readInt32();
-        uint32_t min_enc_level = UINT32(input_parcel->readInt32());
-        status = MinHdcpEncryptionLevelChanged(disp_id, min_enc_level);
-        output_parcel->writeInt32(status);
-      }
-      break;
-
-    case qService::IQService::CONTROL_PARTIAL_UPDATE: {
-        if (!input_parcel || !output_parcel) {
-          DLOGE("QService command = %d: input_parcel and output_parcel needed.", command);
-          break;
-        }
-        int disp_id = input_parcel->readInt32();
-        uint32_t enable = UINT32(input_parcel->readInt32());
-        status = ControlPartialUpdate(disp_id, enable == 1);
-        output_parcel->writeInt32(status);
-      }
-      break;
-
-    case qService::IQService::SET_ACTIVE_CONFIG: {
-        if (!input_parcel) {
-          DLOGE("QService command = %d: input_parcel needed.", command);
-          break;
-        }
-        uint32_t config = UINT32(input_parcel->readInt32());
-        int disp_id = input_parcel->readInt32();
-        status = SetActiveConfigIndex(disp_id, config);
-      }
-      break;
-
-    case qService::IQService::GET_ACTIVE_CONFIG: {
-        if (!input_parcel || !output_parcel) {
-          DLOGE("QService command = %d: input_parcel and output_parcel needed.", command);
-          break;
-        }
-        int disp_id = input_parcel->readInt32();
-        uint32_t config = 0;
-        status = GetActiveConfigIndex(disp_id, &config);
-        output_parcel->writeInt32(INT(config));
-      }
-      break;
-
-    case qService::IQService::GET_CONFIG_COUNT: {
-        if (!input_parcel || !output_parcel) {
-          DLOGE("QService command = %d: input_parcel and output_parcel needed.", command);
-          break;
-        }
-        int disp_id = input_parcel->readInt32();
-        uint32_t count = 0;
-        status = GetConfigCount(disp_id, &count);
-        output_parcel->writeInt32(INT(count));
-      }
-      break;
-
-    case qService::IQService::GET_DISPLAY_ATTRIBUTES_FOR_CONFIG:
-      if (!input_parcel || !output_parcel) {
-        DLOGE("QService command = %d: input_parcel and output_parcel needed.", command);
-        break;
-      }
-      status = HandleGetDisplayAttributesForConfig(input_parcel, output_parcel);
-      break;
-
-    case qService::IQService::GET_PANEL_BRIGHTNESS: {
-        if (!output_parcel) {
-          DLOGE("QService command = %d: output_parcel needed.", command);
-          break;
-        }
-        int level = 0;
-        status = GetPanelBrightness(&level);
-        output_parcel->writeInt32(level);
-      }
-      break;
-
-    case qService::IQService::SET_PANEL_BRIGHTNESS: {
-        if (!input_parcel || !output_parcel) {
-          DLOGE("QService command = %d: input_parcel and output_parcel needed.", command);
-          break;
-        }
-        uint32_t level = UINT32(input_parcel->readInt32());
-        status = setPanelBrightness(level);
-        output_parcel->writeInt32(status);
-      }
-      break;
-
-    case qService::IQService::GET_DISPLAY_VISIBLE_REGION:
-      if (!input_parcel || !output_parcel) {
-        DLOGE("QService command = %d: input_parcel and output_parcel needed.", command);
-        break;
-      }
-      status = GetVisibleDisplayRect(input_parcel, output_parcel);
-      break;
-
-    case qService::IQService::SET_CAMERA_STATUS: {
-        if (!input_parcel) {
-          DLOGE("QService command = %d: input_parcel needed.", command);
-          break;
-        }
-        uint32_t camera_status = UINT32(input_parcel->readInt32());
-        status = setCameraLaunchStatus(camera_status);
-      }
-      break;
-
-    case qService::IQService::GET_BW_TRANSACTION_STATUS: {
-        if (!output_parcel) {
-          DLOGE("QService command = %d: output_parcel needed.", command);
-          break;
-        }
-        bool state = true;
-        status = DisplayBWTransactionPending(&state);
-        output_parcel->writeInt32(state);
-      }
-      break;
-
-    case qService::IQService::SET_LAYER_MIXER_RESOLUTION:
-      if (!input_parcel) {
-        DLOGE("QService command = %d: input_parcel needed.", command);
-        break;
-      }
-      status = SetMixerResolution(input_parcel);
-      break;
-
-    case qService::IQService::SET_COLOR_MODE:
-      if (!input_parcel) {
-        DLOGE("QService command = %d: input_parcel needed.", command);
-        break;
-      }
-      status = SetColorModeOverride(input_parcel);
-      break;
-
-    case qService::IQService::SET_COLOR_MODE_BY_ID:
-      if (!input_parcel) {
-        DLOGE("QService command = %d: input_parcel needed.", command);
-        break;
-      }
-      status = SetColorModeById(input_parcel);
-      break;
-
-    case qService::IQService::GET_COMPOSER_STATUS:
-      if (!output_parcel) {
-        DLOGE("QService command = %d: output_parcel needed.", command);
-        break;
-      }
-      status = 0;
-      output_parcel->writeInt32(getComposerStatus());
-      break;
-
-    default:
-      DLOGW("QService command = %d is not supported.", command);
-      break;
-  }
-
-  return status;
-}
-
-android::status_t HWCSession::getComposerStatus() {
-  return is_composer_up_;
-}
-
-android::status_t HWCSession::HandleGetDisplayAttributesForConfig(const android::Parcel
-                                                                  *input_parcel,
-                                                                  android::Parcel *output_parcel) {
-  int config = input_parcel->readInt32();
-  int dpy = input_parcel->readInt32();
-  int error = android::BAD_VALUE;
-  DisplayConfigVariableInfo display_attributes;
-
-  if (dpy < HWC_DISPLAY_PRIMARY || dpy >= HWC_NUM_DISPLAY_TYPES || config < 0) {
-    return android::BAD_VALUE;
-  }
-
-  SEQUENCE_WAIT_SCOPE_LOCK(locker_[dpy]);
-  if (hwc_display_[dpy]) {
-    error = hwc_display_[dpy]->GetDisplayAttributesForConfig(config, &display_attributes);
-    if (error == 0) {
-      output_parcel->writeInt32(INT(display_attributes.vsync_period_ns));
-      output_parcel->writeInt32(INT(display_attributes.x_pixels));
-      output_parcel->writeInt32(INT(display_attributes.y_pixels));
-      output_parcel->writeFloat(display_attributes.x_dpi);
-      output_parcel->writeFloat(display_attributes.y_dpi);
-      output_parcel->writeInt32(0);  // Panel type, unsupported.
-    }
-  }
-
-  return error;
-}
-
-android::status_t HWCSession::ConfigureRefreshRate(const android::Parcel *input_parcel) {
-  SEQUENCE_WAIT_SCOPE_LOCK(locker_[HWC_DISPLAY_PRIMARY]);
-
-  uint32_t operation = UINT32(input_parcel->readInt32());
-  HWCDisplay *hwc_display = hwc_display_[HWC_DISPLAY_PRIMARY];
-
-  if (!hwc_display) {
-    DLOGW("Display = %d is not connected.", HWC_DISPLAY_PRIMARY);
-    return -ENODEV;
-  }
-
-  switch (operation) {
-    case qdutils::DISABLE_METADATA_DYN_REFRESH_RATE:
-      return hwc_display->Perform(HWCDisplayPrimary::SET_METADATA_DYN_REFRESH_RATE, false);
-
-    case qdutils::ENABLE_METADATA_DYN_REFRESH_RATE:
-      return hwc_display->Perform(HWCDisplayPrimary::SET_METADATA_DYN_REFRESH_RATE, true);
-
-    case qdutils::SET_BINDER_DYN_REFRESH_RATE: {
-      uint32_t refresh_rate = UINT32(input_parcel->readInt32());
-      return hwc_display->Perform(HWCDisplayPrimary::SET_BINDER_DYN_REFRESH_RATE, refresh_rate);
-    }
-
-    default:
-      DLOGW("Invalid operation %d", operation);
-      return -EINVAL;
-  }
-
-  return 0;
-}
-
-android::status_t HWCSession::SetDisplayMode(const android::Parcel *input_parcel) {
-  SEQUENCE_WAIT_SCOPE_LOCK(locker_[HWC_DISPLAY_PRIMARY]);
-
-  if (!hwc_display_[HWC_DISPLAY_PRIMARY]) {
-    DLOGW("Display = %d is not connected.", HWC_DISPLAY_PRIMARY);
-    return -ENODEV;
-  }
-
-  uint32_t mode = UINT32(input_parcel->readInt32());
-  return hwc_display_[HWC_DISPLAY_PRIMARY]->Perform(HWCDisplayPrimary::SET_DISPLAY_MODE, mode);
-}
-
-android::status_t HWCSession::SetMaxMixerStages(const android::Parcel *input_parcel) {
-  DisplayError error = kErrorNone;
-  std::bitset<32> bit_mask_display_type = UINT32(input_parcel->readInt32());
-  uint32_t max_mixer_stages = UINT32(input_parcel->readInt32());
-  android::status_t status = 0;
-
-  for (uint32_t disp_id = HWC_DISPLAY_PRIMARY; disp_id < HWC_NUM_DISPLAY_TYPES; disp_id++) {
-    if (bit_mask_display_type[disp_id]) {
-      SEQUENCE_WAIT_SCOPE_LOCK(locker_[disp_id]);
-      if (hwc_display_[disp_id]) {
-        error = hwc_display_[disp_id]->SetMaxMixerStages(max_mixer_stages);
-        if (error != kErrorNone) {
-          status = -EINVAL;
-          continue;
-        }
-      } else {
-        DLOGW("Display = %d is not connected.", disp_id);
-        status = (status)? status : -ENODEV;  // Return higher priority error.
-        continue;
-      }
-    }
-  }
-
-  return status;
-}
-
-android::status_t HWCSession::SetFrameDumpConfig(const android::Parcel *input_parcel) {
-  uint32_t frame_dump_count = UINT32(input_parcel->readInt32());
-  std::bitset<32> bit_mask_display_type = UINT32(input_parcel->readInt32());
-  uint32_t bit_mask_layer_type = UINT32(input_parcel->readInt32());
-  android::status_t status = 0;
-
-  for (uint32_t disp_id = HWC_DISPLAY_PRIMARY; disp_id < HWC_NUM_DISPLAY_TYPES; disp_id++) {
-    if (bit_mask_display_type[disp_id]) {
-      SEQUENCE_WAIT_SCOPE_LOCK(locker_[disp_id]);
-      if (hwc_display_[disp_id]) {
-        HWC2::Error error;
-        error = hwc_display_[disp_id]->SetFrameDumpConfig(frame_dump_count, bit_mask_layer_type);
-        if (HWC2::Error::None != error) {
-          if (HWC2::Error::NoResources == error)
-            status = -ENOMEM;
-          else
-            status = -EINVAL;
-          continue;
-        }
-      } else {
-        DLOGW("Display = %d is not connected.", disp_id);
-        status = (status)? status : -ENODEV;  // Return higher priority error.
-        continue;
-      }
-    }
-  }
-
-  return status;
-}
-
-android::status_t HWCSession::SetMixerResolution(const android::Parcel *input_parcel) {
-  DisplayError error = kErrorNone;
-  uint32_t dpy = UINT32(input_parcel->readInt32());
-
-  if (dpy != HWC_DISPLAY_PRIMARY) {
-    DLOGW("Resolution change not supported for this display = %d", dpy);
-    return -EINVAL;
-  }
-
-  SEQUENCE_WAIT_SCOPE_LOCK(locker_[HWC_DISPLAY_PRIMARY]);
-  if (!hwc_display_[HWC_DISPLAY_PRIMARY]) {
-    DLOGW("Primary display is not initialized");
-    return -ENODEV;
-  }
-
-  uint32_t width = UINT32(input_parcel->readInt32());
-  uint32_t height = UINT32(input_parcel->readInt32());
-
-  error = hwc_display_[HWC_DISPLAY_PRIMARY]->SetMixerResolution(width, height);
-  if (error != kErrorNone) {
-    return -EINVAL;
-  }
-
-  return 0;
-}
-
-android::status_t HWCSession::SetColorModeOverride(const android::Parcel *input_parcel) {
-  auto display = static_cast<hwc2_display_t >(input_parcel->readInt32());
-  auto mode = static_cast<android_color_mode_t>(input_parcel->readInt32());
-  auto device = static_cast<hwc2_device_t *>(this);
-
-  auto err = CallDisplayFunction(device, display, &HWCDisplay::SetColorMode, mode);
-  if (err != HWC2_ERROR_NONE)
-    return -EINVAL;
-
-  return 0;
-}
-
-android::status_t HWCSession::SetColorModeById(const android::Parcel *input_parcel) {
-  auto display = static_cast<hwc2_display_t >(input_parcel->readInt32());
-  auto mode = input_parcel->readInt32();
-  auto device = static_cast<hwc2_device_t *>(this);
-
-  auto err = CallDisplayFunction(device, display, &HWCDisplay::SetColorModeById, mode);
-  if (err != HWC2_ERROR_NONE)
-    return -EINVAL;
-
-  return 0;
-}
-
-void HWCSession::DynamicDebug(const android::Parcel *input_parcel) {
-  int type = input_parcel->readInt32();
-  bool enable = (input_parcel->readInt32() > 0);
-  DLOGI("type = %d enable = %d", type, enable);
-  int verbose_level = input_parcel->readInt32();
-
-  switch (type) {
-    case qService::IQService::DEBUG_ALL:
-      HWCDebugHandler::DebugAll(enable, verbose_level);
-      break;
-
-    case qService::IQService::DEBUG_MDPCOMP:
-      HWCDebugHandler::DebugStrategy(enable, verbose_level);
-      HWCDebugHandler::DebugCompManager(enable, verbose_level);
-      break;
-
-    case qService::IQService::DEBUG_PIPE_LIFECYCLE:
-      HWCDebugHandler::DebugResources(enable, verbose_level);
-      break;
-
-    case qService::IQService::DEBUG_DRIVER_CONFIG:
-      HWCDebugHandler::DebugDriverConfig(enable, verbose_level);
-      break;
-
-    case qService::IQService::DEBUG_ROTATOR:
-      HWCDebugHandler::DebugResources(enable, verbose_level);
-      HWCDebugHandler::DebugDriverConfig(enable, verbose_level);
-      HWCDebugHandler::DebugRotator(enable, verbose_level);
-      break;
-
-    case qService::IQService::DEBUG_QDCM:
-      HWCDebugHandler::DebugQdcm(enable, verbose_level);
-      break;
-
-    case qService::IQService::DEBUG_SCALAR:
-      HWCDebugHandler::DebugScalar(enable, verbose_level);
-      break;
-
-    case qService::IQService::DEBUG_CLIENT:
-      HWCDebugHandler::DebugClient(enable, verbose_level);
-      break;
-
-    case qService::IQService::DEBUG_DISPLAY:
-      HWCDebugHandler::DebugDisplay(enable, verbose_level);
-      break;
-
-    default:
-      DLOGW("type = %d is not supported", type);
-  }
-}
-
-android::status_t HWCSession::QdcmCMDHandler(const android::Parcel *input_parcel,
-                                             android::Parcel *output_parcel) {
-  int ret = 0;
-  int32_t *brightness_value = NULL;
-  uint32_t display_id(0);
-  PPPendingParams pending_action;
-  PPDisplayAPIPayload resp_payload, req_payload;
-
-  if (!color_mgr_) {
-    DLOGW("color_mgr_ not initialized.");
-    return -ENOENT;
-  }
-
-  pending_action.action = kNoAction;
-  pending_action.params = NULL;
-
-  // Read display_id, payload_size and payload from in_parcel.
-  ret = HWCColorManager::CreatePayloadFromParcel(*input_parcel, &display_id, &req_payload);
-  if (!ret) {
-    if ((display_id >= HWC_NUM_DISPLAY_TYPES) || !hwc_display_[display_id]) {
-      DLOGW("Invalid display id or display = %d is not connected.", display_id);
-      ret = -ENODEV;
-    }
-  }
-
-  if (!ret) {
-    if ((HWC_DISPLAY_PRIMARY == display_id) || (HWC_DISPLAY_EXTERNAL == display_id)) {
-      ret = hwc_display_[display_id]->ColorSVCRequestRoute(req_payload, &resp_payload,
-                                                           &pending_action);
-    } else {
-      // Virtual, Tertiary etc. not supported.
-      DLOGW("Operation not supported on display = %d.", display_id);
-      ret = -EINVAL;
-    }
-  }
-
-  if (ret) {
-    output_parcel->writeInt32(ret);  // first field in out parcel indicates return code.
-    req_payload.DestroyPayload();
-    resp_payload.DestroyPayload();
-    return ret;
-  }
-
-  if (kNoAction != pending_action.action) {
-    // Restrict pending actions to primary display.
-    if (HWC_DISPLAY_PRIMARY != display_id) {
-      DLOGW("Skipping pending action %d on display = %d.", pending_action.action, display_id);
-      pending_action.action = kNoAction;
-    }
-
-    int32_t action = pending_action.action;
-    int count = -1;
-    while (action > 0) {
-      count++;
-      int32_t bit = (action & 1);
-      action = action >> 1;
-
-      if (!bit)
-        continue;
-
-      DLOGV_IF(kTagQDCM, "pending action = %d", BITMAP(count));
-      switch (BITMAP(count)) {
-        case kInvalidating:
-          Refresh(HWC_DISPLAY_PRIMARY);
-          break;
-        case kEnterQDCMMode:
-          ret = color_mgr_->EnableQDCMMode(true, hwc_display_[HWC_DISPLAY_PRIMARY]);
-          break;
-        case kExitQDCMMode:
-          ret = color_mgr_->EnableQDCMMode(false, hwc_display_[HWC_DISPLAY_PRIMARY]);
-          break;
-        case kApplySolidFill:
-          {
-            SCOPE_LOCK(locker_[HWC_DISPLAY_PRIMARY]);
-            ret = color_mgr_->SetSolidFill(pending_action.params,
-                                            true, hwc_display_[HWC_DISPLAY_PRIMARY]);
-          }
-          Refresh(HWC_DISPLAY_PRIMARY);
-          usleep(kSolidFillDelay);
-          break;
-        case kDisableSolidFill:
-          {
-            SCOPE_LOCK(locker_[HWC_DISPLAY_PRIMARY]);
-            ret = color_mgr_->SetSolidFill(pending_action.params,
-                                            false, hwc_display_[HWC_DISPLAY_PRIMARY]);
-          }
-          Refresh(HWC_DISPLAY_PRIMARY);
-          usleep(kSolidFillDelay);
-          break;
-        case kSetPanelBrightness:
-          brightness_value = reinterpret_cast<int32_t *>(resp_payload.payload);
-          if (brightness_value == NULL) {
-            DLOGE("Brightness value is Null");
-            ret = -EINVAL;
-          } else {
-            ret = hwc_display_[HWC_DISPLAY_PRIMARY]->SetPanelBrightness(*brightness_value);
-          }
-          break;
-        case kEnableFrameCapture:
-          ret = color_mgr_->SetFrameCapture(pending_action.params, true,
-                                        hwc_display_[HWC_DISPLAY_PRIMARY]);
-          Refresh(HWC_DISPLAY_PRIMARY);
-          break;
-        case kDisableFrameCapture:
-          ret = color_mgr_->SetFrameCapture(pending_action.params, false,
-                                        hwc_display_[HWC_DISPLAY_PRIMARY]);
-          break;
-        case kConfigureDetailedEnhancer:
-          ret = color_mgr_->SetDetailedEnhancer(pending_action.params,
-                                            hwc_display_[HWC_DISPLAY_PRIMARY]);
-          Refresh(HWC_DISPLAY_PRIMARY);
-          break;
-        case kModeSet:
-          ret = static_cast<int>
-                 (hwc_display_[HWC_DISPLAY_PRIMARY]->RestoreColorTransform());
-          Refresh(HWC_DISPLAY_PRIMARY);
-          break;
-        case kNoAction:
-          break;
-        default:
-          DLOGW("Invalid pending action = %d!", pending_action.action);
-          break;
-      }
-    }
-  }
-  // for display API getter case, marshall returned params into out_parcel.
-  output_parcel->writeInt32(ret);
-  HWCColorManager::MarshallStructIntoParcel(resp_payload, output_parcel);
-  req_payload.DestroyPayload();
-  resp_payload.DestroyPayload();
-  hwc_display_[display_id]->ResetValidation();
-
-  return ret;
-}
-
-void HWCSession::UEventHandler(const char *uevent_data, int length) {
-  if (strcasestr(uevent_data, HWC_UEVENT_SWITCH_HDMI)) {
-    DLOGI("Uevent HDMI = %s", uevent_data);
-    int connected = GetEventValue(uevent_data, length, "SWITCH_STATE=");
-    if (connected >= 0) {
-      DLOGI("HDMI = %s", connected ? "connected" : "disconnected");
-      if (HotPlugHandler(connected) == -1) {
-        DLOGE("Failed handling Hotplug = %s", connected ? "connected" : "disconnected");
-      }
-    }
-  } else if (strcasestr(uevent_data, HWC_UEVENT_GRAPHICS_FB0)) {
-    DLOGI("Uevent FB0 = %s", uevent_data);
-    int panel_reset = GetEventValue(uevent_data, length, "PANEL_ALIVE=");
-    if (panel_reset == 0) {
-      Refresh(0);
-      reset_panel_ = true;
-    }
-  } else if (strcasestr(uevent_data, HWC_UEVENT_DRM_EXT_HOTPLUG)) {
-    HandleExtHPD(uevent_data, length);
-  }
-}
-
-const char *GetTokenValue(const char *uevent_data, int length, const char *token) {
-  const char *iterator_str = uevent_data;
-  const char *pstr = NULL;
-  while (((iterator_str - uevent_data) <= length) && (*iterator_str)) {
-    pstr = strstr(iterator_str, token);
-    if (pstr) {
-      break;
-    }
-    iterator_str += strlen(iterator_str) + 1;
-  }
-
-  if (pstr)
-    pstr = pstr+strlen(token);
-
-  return pstr;
-}
-
-void HWCSession::HandleExtHPD(const char *uevent_data, int length) {
-  const char *pstr = GetTokenValue(uevent_data, length, "name=");
-  if (!pstr || (strncmp(pstr, "DP-1", strlen("DP-1")) != 0)) {
-    return;
-  }
-
-  pstr = GetTokenValue(uevent_data, length, "status=");
-  if (pstr) {
-    bool connected = false;
-    hpd_bpp_ = 0;
-    hpd_pattern_ = 0;
-    if (strncmp(pstr, "connected", strlen("connected")) == 0) {
-      connected = true;
-    }
-    int bpp = GetEventValue(uevent_data, length, "bpp=");
-    int pattern = GetEventValue(uevent_data, length, "pattern=");
-    if (bpp >=0 && pattern >= 0) {
-      hpd_bpp_ = bpp;
-      hpd_pattern_ = pattern;
-    }
-
-    DLOGI("Recived Ext HPD, connected:%d  status=%s  bpp = %d pattern =%d ",
-          connected, pstr, hpd_bpp_, hpd_pattern_);
-    HotPlugHandler(connected);
-  }
-}
-
-int HWCSession::GetEventValue(const char *uevent_data, int length, const char *event_info) {
-  const char *iterator_str = uevent_data;
-  while (((iterator_str - uevent_data) <= length) && (*iterator_str)) {
-    const char *pstr = strstr(iterator_str, event_info);
-    if (pstr != NULL) {
-      return (atoi(iterator_str + strlen(event_info)));
-    }
-    iterator_str += strlen(iterator_str) + 1;
-  }
-
-  return -1;
-}
-
-void HWCSession::ResetPanel() {
-  HWC2::Error status;
-
-  DLOGI("Powering off primary");
-  status = hwc_display_[HWC_DISPLAY_PRIMARY]->SetPowerMode(HWC2::PowerMode::Off);
-  if (status != HWC2::Error::None) {
-    DLOGE("power-off on primary failed with error = %d", status);
-  }
-
-  DLOGI("Restoring power mode on primary");
-  HWC2::PowerMode mode = hwc_display_[HWC_DISPLAY_PRIMARY]->GetLastPowerMode();
-  status = hwc_display_[HWC_DISPLAY_PRIMARY]->SetPowerMode(mode);
-  if (status != HWC2::Error::None) {
-    DLOGE("Setting power mode = %d on primary failed with error = %d", mode, status);
-  }
-
-  status = hwc_display_[HWC_DISPLAY_PRIMARY]->SetVsyncEnabled(HWC2::Vsync::Enable);
-  if (status != HWC2::Error::None) {
-    DLOGE("enabling vsync failed for primary with error = %d", status);
-  }
-
-  reset_panel_ = false;
-}
-
-int HWCSession::HotPlugHandler(bool connected) {
-  int status = 0;
-  bool notify_hotplug = false;
-
-  // To prevent sending events to client while a lock is held, acquire scope locks only within
-  // below scope so that those get automatically unlocked after the scope ends.
-  do {
-    // If HDMI is primary but not created yet (first time), create it and notify surfaceflinger.
-    //    if it is already created, but got disconnected/connected again,
-    //    just toggle display status and do not notify surfaceflinger.
-    // If HDMI is not primary, create/destroy external display normally.
-    if (hdmi_is_primary_) {
-      SCOPE_LOCK(locker_[HWC_DISPLAY_PRIMARY]);
-      if (hwc_display_[HWC_DISPLAY_PRIMARY]) {
-        status = hwc_display_[HWC_DISPLAY_PRIMARY]->SetState(connected);
-      } else {
-        status = CreateExternalDisplay(HWC_DISPLAY_PRIMARY, 0, 0, false);
-        notify_hotplug = true;
-      }
-
-      break;
-    }
-
-    {
-      SCOPE_LOCK(locker_[HWC_DISPLAY_PRIMARY]);
-      // Primary display must be connected for HDMI as secondary cases.
-      if (!hwc_display_[HWC_DISPLAY_PRIMARY]) {
-        DLOGE("Primary display is not connected.");
-        return -1;
-      }
-
-      hwc_display_[HWC_DISPLAY_PRIMARY]->ResetValidation();
-    }
-
-    if (connected) {
-      SCOPE_LOCK(locker_[HWC_DISPLAY_EXTERNAL]);
-      Locker::ScopeLock lock_v(locker_[HWC_DISPLAY_VIRTUAL]);
-      // Connect external display if virtual display is not connected.
-      // Else, defer external display connection and process it when virtual display
-      // tears down; Do not notify SurfaceFlinger since connection is deferred now.
-      if (!hwc_display_[HWC_DISPLAY_VIRTUAL]) {
-        status = ConnectDisplay(HWC_DISPLAY_EXTERNAL);
-        if (status) {
-          return status;
-        }
-        notify_hotplug = true;
-      } else {
-        DLOGI("Virtual display is connected, pending connection");
-        external_pending_connect_ = true;
-      }
-    } else {
-      SEQUENCE_WAIT_SCOPE_LOCK(locker_[HWC_DISPLAY_EXTERNAL]);
-      if (hwc_display_[HWC_DISPLAY_EXTERNAL]) {
-        notify_hotplug = true;
-      }
-      external_pending_connect_ = false;
-    }
-  } while (0);
-
-  if (connected) {
-    // In connect case, we send hotplug after we create display
-    Refresh(0);
-
-    if (!hdmi_is_primary_) {
-      // wait for sufficient time to ensure sufficient resources are available to process new
-      // new display connection.
-      uint32_t vsync_period = UINT32(GetVsyncPeriod(HWC_DISPLAY_PRIMARY));
-      usleep(vsync_period * 2 / 1000);
-    }
-    if (notify_hotplug) {
-      HotPlug(hdmi_is_primary_ ? HWC_DISPLAY_PRIMARY : HWC_DISPLAY_EXTERNAL,
-              HWC2::Connection::Connected);
-    }
-  } else {
-    // In disconnect case, we notify hotplug first to let the listener state update happen first
-    // Then we can destroy the underlying display object
-    if (notify_hotplug) {
-      HotPlug(hdmi_is_primary_ ? HWC_DISPLAY_PRIMARY : HWC_DISPLAY_EXTERNAL,
-              HWC2::Connection::Disconnected);
-    }
-    Refresh(0);
-    if (!hdmi_is_primary_) {
-      uint32_t vsync_period = UINT32(GetVsyncPeriod(HWC_DISPLAY_PRIMARY));
-      usleep(vsync_period * 2 / 1000);
-    }
-    // Now disconnect the display
-    {
-      SEQUENCE_WAIT_SCOPE_LOCK(locker_[HWC_DISPLAY_EXTERNAL]);
-      // Do not return error if external display is not in connected status.
-      // Due to virtual display concurrency, external display connection might be still pending
-      // but hdmi got disconnected before pending connection could be processed.
-      if (hwc_display_[HWC_DISPLAY_EXTERNAL]) {
-        status = DisconnectDisplay(HWC_DISPLAY_EXTERNAL);
-      }
-    }
-  }
-
-  // notify client
-
-  qservice_->onHdmiHotplug(INT(connected));
-
-  return 0;
-}
-
-int HWCSession::GetVsyncPeriod(int disp) {
-  SCOPE_LOCK(locker_[disp]);
-  // default value
-  int32_t vsync_period = 1000000000l / 60;
-  auto attribute = HWC2::Attribute::VsyncPeriod;
-
-  if (hwc_display_[disp]) {
-    hwc_display_[disp]->GetDisplayAttribute(0, attribute, &vsync_period);
-  }
-
-  return vsync_period;
-}
-
-android::status_t HWCSession::GetVisibleDisplayRect(const android::Parcel *input_parcel,
-                                                    android::Parcel *output_parcel) {
-  int dpy = input_parcel->readInt32();
-  if (dpy < HWC_DISPLAY_PRIMARY || dpy >= HWC_NUM_DISPLAY_TYPES) {
-    return android::BAD_VALUE;
-  }
-
-  SEQUENCE_WAIT_SCOPE_LOCK(locker_[dpy]);
-  if (!hwc_display_[dpy]) {
-    return android::NO_INIT;
-  }
-
-  hwc_rect_t visible_rect = {0, 0, 0, 0};
-  int error = hwc_display_[dpy]->GetVisibleDisplayRect(&visible_rect);
-  if (error < 0) {
-    return error;
-  }
-
-  output_parcel->writeInt32(visible_rect.left);
-  output_parcel->writeInt32(visible_rect.top);
-  output_parcel->writeInt32(visible_rect.right);
-  output_parcel->writeInt32(visible_rect.bottom);
-
-  return android::NO_ERROR;
-}
-
-void HWCSession::Refresh(hwc2_display_t display) {
-  SCOPE_LOCK(callbacks_lock_);
-  HWC2::Error err = callbacks_.Refresh(display);
-  while (err != HWC2::Error::None) {
-    callbacks_lock_.Wait();
-    err = callbacks_.Refresh(display);
-  }
-}
-
-void HWCSession::HotPlug(hwc2_display_t display, HWC2::Connection state) {
-  SCOPE_LOCK(callbacks_lock_);
-  HWC2::Error err = callbacks_.Hotplug(display, state);
-  while (err != HWC2::Error::None) {
-    callbacks_lock_.Wait();
-    err = callbacks_.Hotplug(display, state);
-  }
-}
-
-int HWCSession::CreateExternalDisplay(int disp_id, uint32_t primary_width,
-                                      uint32_t primary_height, bool use_primary_res) {
-  uint32_t panel_bpp = 0;
-  uint32_t pattern_type = 0;
-
-  if (GetDriverType() == DriverType::FB) {
-    qdutils::getDPTestConfig(&panel_bpp, &pattern_type);
-  } else {
-    panel_bpp = static_cast<uint32_t>(hpd_bpp_);
-    pattern_type = static_cast<uint32_t>(hpd_pattern_);
-  }
-
-  if (panel_bpp && pattern_type) {
-    return HWCDisplayExternalTest::Create(core_intf_, &buffer_allocator_, &callbacks_,
-                                          qservice_, panel_bpp, pattern_type,
-                                          &hwc_display_[disp_id]);
-  }
-
-  return  HWCDisplayExternal::Create(core_intf_, &buffer_allocator_, &callbacks_,
-                                     primary_width, primary_height, qservice_,
-                                     use_primary_res, &hwc_display_[disp_id]);
-}
-
-#ifdef DISPLAY_CONFIG_1_1
-// Methods from ::vendor::hardware::display::config::V1_1::IDisplayConfig follow.
-Return<int32_t> HWCSession::setDisplayAnimating(uint64_t display_id, bool animating ) {
-  return CallDisplayFunction(static_cast<hwc2_device_t *>(this), display_id,
-                             &HWCDisplay::SetDisplayAnimating, animating);
-}
-#endif
-
-}  // namespace sdm
diff --git a/sdm/libs/hwc2/hwc_session.h b/sdm/libs/hwc2/hwc_session.h
deleted file mode 100644
index 8d25989..0000000
--- a/sdm/libs/hwc2/hwc_session.h
+++ /dev/null
@@ -1,274 +0,0 @@
-/*
- * Copyright (c) 2014-2017, The Linux Foundation. All rights reserved.
- * Not a Contribution.
- *
- * Copyright 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.
- */
-
-#ifndef __HWC_SESSION_H__
-#define __HWC_SESSION_H__
-
-#ifdef DISPLAY_CONFIG_1_1
-#include <vendor/display/config/1.1/IDisplayConfig.h>
-#else
-#include <vendor/display/config/1.0/IDisplayConfig.h>
-#endif
-
-#include <core/core_interface.h>
-#include <utils/locker.h>
-
-#include "hwc_callbacks.h"
-#include "hwc_layers.h"
-#include "hwc_display.h"
-#include "hwc_display_primary.h"
-#include "hwc_display_external.h"
-#include "hwc_display_virtual.h"
-#include "hwc_color_manager.h"
-#include "hwc_socket_handler.h"
-
-namespace sdm {
-
-#ifdef DISPLAY_CONFIG_1_1
-using vendor::display::config::V1_1::IDisplayConfig;
-#else
-using ::vendor::display::config::V1_0::IDisplayConfig;
-#endif
-using ::android::hardware::Return;
-
-// Create a singleton uevent listener thread valid for life of hardware composer process.
-// This thread blocks on uevents poll inside uevent library implementation. This poll exits
-// only when there is a valid uevent, it can not be interrupted otherwise. Tieing life cycle
-// of this thread with HWC session cause HWC deinitialization to wait infinitely for the
-// thread to exit.
-class HWCUEventListener {
- public:
-  virtual ~HWCUEventListener() {}
-  virtual void UEventHandler(const char *uevent_data, int length) = 0;
-};
-
-class HWCUEvent {
- public:
-  HWCUEvent();
-  static void UEventThread(HWCUEvent *hwc_event);
-  void Register(HWCUEventListener *uevent_listener);
-  inline bool InitDone() { return init_done_; }
-
- private:
-  std::mutex mutex_;
-  std::condition_variable caller_cv_;
-  HWCUEventListener *uevent_listener_ = nullptr;
-  bool init_done_ = false;
-};
-
-class HWCSession : hwc2_device_t, HWCUEventListener, IDisplayConfig, public qClient::BnQClient {
- public:
-  struct HWCModuleMethods : public hw_module_methods_t {
-    HWCModuleMethods() { hw_module_methods_t::open = HWCSession::Open; }
-  };
-
-  explicit HWCSession(const hw_module_t *module);
-  int Init();
-  int Deinit();
-  HWC2::Error CreateVirtualDisplayObject(uint32_t width, uint32_t height, int32_t *format);
-
-  template <typename... Args>
-  static int32_t CallDisplayFunction(hwc2_device_t *device, hwc2_display_t display,
-                                     HWC2::Error (HWCDisplay::*member)(Args...), Args... args) {
-    if (!device) {
-      return HWC2_ERROR_BAD_PARAMETER;
-    }
-
-    if (display >= HWC_NUM_DISPLAY_TYPES) {
-      return HWC2_ERROR_BAD_DISPLAY;
-    }
-
-    SCOPE_LOCK(locker_[display]);
-    HWCSession *hwc_session = static_cast<HWCSession *>(device);
-    auto status = HWC2::Error::BadDisplay;
-    if (hwc_session->hwc_display_[display]) {
-      auto hwc_display = hwc_session->hwc_display_[display];
-      status = (hwc_display->*member)(std::forward<Args>(args)...);
-    }
-    return INT32(status);
-  }
-
-  template <typename... Args>
-  static int32_t CallLayerFunction(hwc2_device_t *device, hwc2_display_t display,
-                                   hwc2_layer_t layer, HWC2::Error (HWCLayer::*member)(Args...),
-                                   Args... args) {
-    if (!device) {
-      return HWC2_ERROR_BAD_PARAMETER;
-    }
-
-    if (display >= HWC_NUM_DISPLAY_TYPES) {
-      return HWC2_ERROR_BAD_DISPLAY;
-    }
-
-    SCOPE_LOCK(locker_[display]);
-    HWCSession *hwc_session = static_cast<HWCSession *>(device);
-    auto status = HWC2::Error::BadDisplay;
-    if (hwc_session->hwc_display_[display]) {
-      status = HWC2::Error::BadLayer;
-      auto hwc_layer = hwc_session->hwc_display_[display]->GetHWCLayer(layer);
-      if (hwc_layer != nullptr) {
-        status = (hwc_layer->*member)(std::forward<Args>(args)...);
-        if (hwc_session->hwc_display_[display]->GetGeometryChanges()) {
-          hwc_session->hwc_display_[display]->ResetValidation();
-        }
-      }
-    }
-    return INT32(status);
-  }
-
-  // HWC2 Functions that require a concrete implementation in hwc session
-  // and hence need to be member functions
-  static int32_t AcceptDisplayChanges(hwc2_device_t *device, hwc2_display_t display);
-  static int32_t CreateLayer(hwc2_device_t *device, hwc2_display_t display,
-                             hwc2_layer_t *out_layer_id);
-  static int32_t CreateVirtualDisplay(hwc2_device_t *device, uint32_t width, uint32_t height,
-                                      int32_t *format, hwc2_display_t *out_display_id);
-  static int32_t DestroyLayer(hwc2_device_t *device, hwc2_display_t display, hwc2_layer_t layer);
-  static int32_t DestroyVirtualDisplay(hwc2_device_t *device, hwc2_display_t display);
-  static void Dump(hwc2_device_t *device, uint32_t *out_size, char *out_buffer);
-  static int32_t PresentDisplay(hwc2_device_t *device, hwc2_display_t display,
-                                int32_t *out_retire_fence);
-  static int32_t RegisterCallback(hwc2_device_t *device, int32_t descriptor,
-                                  hwc2_callback_data_t callback_data,
-                                  hwc2_function_pointer_t pointer);
-  static int32_t SetOutputBuffer(hwc2_device_t *device, hwc2_display_t display,
-                                 buffer_handle_t buffer, int32_t releaseFence);
-  static int32_t SetPowerMode(hwc2_device_t *device, hwc2_display_t display, int32_t int_mode);
-  static int32_t ValidateDisplay(hwc2_device_t *device, hwc2_display_t display,
-                                 uint32_t *out_num_types, uint32_t *out_num_requests);
-  static int32_t SetColorMode(hwc2_device_t *device, hwc2_display_t display,
-                              int32_t /*android_color_mode_t*/ int_mode);
-  static int32_t SetColorTransform(hwc2_device_t *device, hwc2_display_t display,
-                                   const float *matrix, int32_t /*android_color_transform_t*/ hint);
-
-  static Locker locker_[HWC_NUM_DISPLAY_TYPES];
-
- private:
-  static const int kExternalConnectionTimeoutMs = 500;
-  static const int kPartialUpdateControlTimeoutMs = 100;
-
-  // hwc methods
-  static int Open(const hw_module_t *module, const char *name, hw_device_t **device);
-  static int Close(hw_device_t *device);
-  static void GetCapabilities(struct hwc2_device *device, uint32_t *outCount,
-                              int32_t *outCapabilities);
-  static hwc2_function_pointer_t GetFunction(struct hwc2_device *device, int32_t descriptor);
-
-  // Uevent handler
-  virtual void UEventHandler(const char *uevent_data, int length);
-  int GetEventValue(const char *uevent_data, int length, const char *event_info);
-  void HandleExtHPD(const char *uevent_data, int length);
-  int HotPlugHandler(bool connected);
-  void ResetPanel();
-  int32_t ConnectDisplay(int disp);
-  int DisconnectDisplay(int disp);
-  int GetVsyncPeriod(int disp);
-  int32_t GetConfigCount(int disp_id, uint32_t *count);
-  int32_t GetActiveConfigIndex(int disp_id, uint32_t *config);
-  int32_t SetActiveConfigIndex(int disp_id, uint32_t config);
-  int32_t ControlPartialUpdate(int dpy, bool enable);
-  int32_t DisplayBWTransactionPending(bool *status);
-  int32_t SetSecondaryDisplayStatus(int disp_id, HWCDisplay::DisplayStatus status);
-  int32_t GetPanelBrightness(int *level);
-  int32_t MinHdcpEncryptionLevelChanged(int disp_id, uint32_t min_enc_level);
-  int32_t CreateExternalDisplay(int disp_id, uint32_t primary_width, uint32_t primary_height,
-                                bool use_primary_res);
-
-  // service methods
-  void StartServices();
-
-  // Methods from ::android::hardware::display::config::V1_0::IDisplayConfig follow.
-  Return<void> isDisplayConnected(IDisplayConfig::DisplayType dpy,
-                                  isDisplayConnected_cb _hidl_cb) override;
-  Return<int32_t> setSecondayDisplayStatus(IDisplayConfig::DisplayType dpy,
-                                  IDisplayConfig::DisplayExternalStatus status) override;
-  Return<int32_t> configureDynRefeshRate(IDisplayConfig::DisplayDynRefreshRateOp op,
-                                  uint32_t refreshRate) override;
-  Return<void> getConfigCount(IDisplayConfig::DisplayType dpy,
-                              getConfigCount_cb _hidl_cb) override;
-  Return<void> getActiveConfig(IDisplayConfig::DisplayType dpy,
-                               getActiveConfig_cb _hidl_cb) override;
-  Return<int32_t> setActiveConfig(IDisplayConfig::DisplayType dpy, uint32_t config) override;
-  Return<void> getDisplayAttributes(uint32_t configIndex, IDisplayConfig::DisplayType dpy,
-                                    getDisplayAttributes_cb _hidl_cb) override;
-  Return<int32_t> setPanelBrightness(uint32_t level) override;
-  Return<void> getPanelBrightness(getPanelBrightness_cb _hidl_cb) override;
-  Return<int32_t> minHdcpEncryptionLevelChanged(IDisplayConfig::DisplayType dpy,
-                                                uint32_t min_enc_level) override;
-  Return<int32_t> refreshScreen() override;
-  Return<int32_t> controlPartialUpdate(IDisplayConfig::DisplayType dpy, bool enable) override;
-  Return<int32_t> toggleScreenUpdate(bool on) override;
-  Return<int32_t> setIdleTimeout(uint32_t value) override;
-  Return<void> getHDRCapabilities(IDisplayConfig::DisplayType dpy,
-                                  getHDRCapabilities_cb _hidl_cb) override;
-  Return<int32_t> setCameraLaunchStatus(uint32_t on) override;
-  Return<void> displayBWTransactionPending(displayBWTransactionPending_cb _hidl_cb) override;
-
-  // Methods from ::android::hardware::display::config::V1_1::IDisplayConfig follow.
-#ifdef DISPLAY_CONFIG_1_1
-  Return<int32_t> setDisplayAnimating(uint64_t display_id, bool animating) override;
-#endif
-
-  // QClient methods
-  virtual android::status_t notifyCallback(uint32_t command, const android::Parcel *input_parcel,
-                                           android::Parcel *output_parcel);
-  void DynamicDebug(const android::Parcel *input_parcel);
-  android::status_t SetFrameDumpConfig(const android::Parcel *input_parcel);
-  android::status_t SetMaxMixerStages(const android::Parcel *input_parcel);
-  android::status_t SetDisplayMode(const android::Parcel *input_parcel);
-  android::status_t ConfigureRefreshRate(const android::Parcel *input_parcel);
-  android::status_t QdcmCMDHandler(const android::Parcel *input_parcel,
-                                   android::Parcel *output_parcel);
-  android::status_t HandleGetDisplayAttributesForConfig(const android::Parcel *input_parcel,
-                                                        android::Parcel *output_parcel);
-  android::status_t GetVisibleDisplayRect(const android::Parcel *input_parcel,
-                                          android::Parcel *output_parcel);
-  android::status_t SetMixerResolution(const android::Parcel *input_parcel);
-  android::status_t SetColorModeOverride(const android::Parcel *input_parcel);
-
-  android::status_t SetColorModeById(const android::Parcel *input_parcel);
-  android::status_t getComposerStatus();
-
-  void Refresh(hwc2_display_t display);
-  void HotPlug(hwc2_display_t display, HWC2::Connection state);
-
-  CoreInterface *core_intf_ = nullptr;
-  HWCDisplay *hwc_display_[HWC_NUM_DISPLAY_TYPES] = {nullptr};
-  HWCCallbacks callbacks_;
-  HWCBufferAllocator buffer_allocator_;
-  HWCBufferSyncHandler buffer_sync_handler_;
-  HWCColorManager *color_mgr_ = nullptr;
-  bool reset_panel_ = false;
-  bool secure_display_active_ = false;
-  bool external_pending_connect_ = false;
-  bool new_bw_mode_ = false;
-  bool need_invalidate_ = false;
-  int bw_mode_release_fd_ = -1;
-  qService::QService *qservice_ = nullptr;
-  HWCSocketHandler socket_handler_;
-  bool hdmi_is_primary_ = false;
-  bool is_composer_up_ = false;
-  Locker callbacks_lock_;
-  int hpd_bpp_ = 0;
-  int hpd_pattern_ = 0;
-};
-
-}  // namespace sdm
-
-#endif  // __HWC_SESSION_H__
diff --git a/sdm/libs/hwc2/hwc_session_services.cpp b/sdm/libs/hwc2/hwc_session_services.cpp
deleted file mode 100644
index 57a5dac..0000000
--- a/sdm/libs/hwc2/hwc_session_services.cpp
+++ /dev/null
@@ -1,511 +0,0 @@
-/*
-* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without
-* modification, are permitted provided that the following conditions are
-* met:
-*    * Redistributions of source code must retain the above copyright
-*      notice, this list of conditions and the following disclaimer.
-*    * Redistributions in binary form must reproduce the above
-*      copyright notice, this list of conditions and the following
-*      disclaimer in the documentation and/or other materials provided
-*      with the distribution.
-*    * Neither the name of The Linux Foundation. nor the names of its
-*      contributors may be used to endorse or promote products derived
-*      from this software without specific prior written permission.
-*
-* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
-* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
-* ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
-* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
-* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#include <core/buffer_allocator.h>
-#include <utils/debug.h>
-#include <sync/sync.h>
-
-#include "hwc_buffer_sync_handler.h"
-#include "hwc_session.h"
-
-#define __CLASS__ "HWCSession"
-
-namespace sdm {
-
-using ::android::hardware::Void;
-
-void HWCSession::StartServices() {
-  android::status_t status = IDisplayConfig::registerAsService();
-  if (status != android::OK) {
-    DLOGW("Could not register IDisplayConfig as service (%d).", status);
-  } else {
-    DLOGI("IDisplayConfig service registration completed.");
-  }
-}
-
-int MapDisplayType(IDisplayConfig::DisplayType dpy) {
-  switch (dpy) {
-    case IDisplayConfig::DisplayType::DISPLAY_PRIMARY:
-      return HWC_DISPLAY_PRIMARY;
-
-    case IDisplayConfig::DisplayType::DISPLAY_EXTERNAL:
-      return HWC_DISPLAY_EXTERNAL;
-
-    case IDisplayConfig::DisplayType::DISPLAY_VIRTUAL:
-      return HWC_DISPLAY_VIRTUAL;
-
-    default:
-      break;
-  }
-
-  return -EINVAL;
-}
-
-HWCDisplay::DisplayStatus MapExternalStatus(IDisplayConfig::DisplayExternalStatus status) {
-  switch (status) {
-    case IDisplayConfig::DisplayExternalStatus::EXTERNAL_OFFLINE:
-      return HWCDisplay::kDisplayStatusOffline;
-
-    case IDisplayConfig::DisplayExternalStatus::EXTERNAL_ONLINE:
-      return HWCDisplay::kDisplayStatusOnline;
-
-    case IDisplayConfig::DisplayExternalStatus::EXTERNAL_PAUSE:
-      return HWCDisplay::kDisplayStatusPause;
-
-    case IDisplayConfig::DisplayExternalStatus::EXTERNAL_RESUME:
-      return HWCDisplay::kDisplayStatusResume;
-
-    default:
-      break;
-  }
-
-  return HWCDisplay::kDisplayStatusInvalid;
-}
-
-// Methods from ::vendor::hardware::display::config::V1_0::IDisplayConfig follow.
-Return<void> HWCSession::isDisplayConnected(IDisplayConfig::DisplayType dpy,
-                                            isDisplayConnected_cb _hidl_cb) {
-  int32_t error = -EINVAL;
-  bool connected = false;
-  int disp_id = MapDisplayType(dpy);
-
-  if (disp_id < HWC_DISPLAY_PRIMARY || disp_id >= HWC_NUM_DISPLAY_TYPES) {
-    _hidl_cb(error, connected);
-    return Void();
-  }
-
-  SEQUENCE_WAIT_SCOPE_LOCK(locker_[disp_id]);
-
-  connected = hwc_display_[disp_id];
-  error = 0;
-
-  _hidl_cb(error, connected);
-  return Void();
-}
-
-int32_t HWCSession::SetSecondaryDisplayStatus(int disp_id, HWCDisplay::DisplayStatus status) {
-  if (disp_id < HWC_DISPLAY_PRIMARY || disp_id >= HWC_NUM_DISPLAY_TYPES) {
-    DLOGE("Invalid display = %d", disp_id);
-    return -EINVAL;
-  }
-
-  SEQUENCE_WAIT_SCOPE_LOCK(locker_[disp_id]);
-  DLOGI("Display = %d, Status = %d", disp_id, status);
-
-  if (disp_id == HWC_DISPLAY_PRIMARY) {
-    DLOGE("Not supported for this display");
-  } else if (!hwc_display_[disp_id]) {
-    DLOGW("Display is not connected");
-  } else {
-    return hwc_display_[disp_id]->SetDisplayStatus(status);
-  }
-
-  return -EINVAL;
-}
-
-Return<int32_t> HWCSession::setSecondayDisplayStatus(IDisplayConfig::DisplayType dpy,
-                                                  IDisplayConfig::DisplayExternalStatus status) {
-  return SetSecondaryDisplayStatus(MapDisplayType(dpy), MapExternalStatus(status));
-}
-
-Return<int32_t> HWCSession::configureDynRefeshRate(IDisplayConfig::DisplayDynRefreshRateOp op,
-                                                   uint32_t refreshRate) {
-  SEQUENCE_WAIT_SCOPE_LOCK(locker_[HWC_DISPLAY_PRIMARY]);
-  HWCDisplay *hwc_display = hwc_display_[HWC_DISPLAY_PRIMARY];
-
-  switch (op) {
-    case IDisplayConfig::DisplayDynRefreshRateOp::DISABLE_METADATA_DYN_REFRESH_RATE:
-      return hwc_display->Perform(HWCDisplayPrimary::SET_METADATA_DYN_REFRESH_RATE, false);
-
-    case IDisplayConfig::DisplayDynRefreshRateOp::ENABLE_METADATA_DYN_REFRESH_RATE:
-      return hwc_display->Perform(HWCDisplayPrimary::SET_METADATA_DYN_REFRESH_RATE, true);
-
-    case IDisplayConfig::DisplayDynRefreshRateOp::SET_BINDER_DYN_REFRESH_RATE:
-      return hwc_display->Perform(HWCDisplayPrimary::SET_BINDER_DYN_REFRESH_RATE, refreshRate);
-
-    default:
-      DLOGW("Invalid operation %d", op);
-      return -EINVAL;
-  }
-
-  return 0;
-}
-
-int32_t HWCSession::GetConfigCount(int disp_id, uint32_t *count) {
-  if (disp_id < 0) {
-    return -EINVAL;
-  }
-
-  SEQUENCE_WAIT_SCOPE_LOCK(locker_[disp_id]);
-
-  if (hwc_display_[disp_id]) {
-    return hwc_display_[disp_id]->GetDisplayConfigCount(count);
-  }
-
-  return -EINVAL;
-}
-
-Return<void> HWCSession::getConfigCount(IDisplayConfig::DisplayType dpy,
-                                        getConfigCount_cb _hidl_cb) {
-  uint32_t count = 0;
-  int32_t error = GetConfigCount(MapDisplayType(dpy), &count);
-
-  _hidl_cb(error, count);
-
-  return Void();
-}
-
-int32_t HWCSession::GetActiveConfigIndex(int disp_id, uint32_t *config) {
-  if (disp_id < 0) {
-    return -EINVAL;
-  }
-
-  SEQUENCE_WAIT_SCOPE_LOCK(locker_[disp_id]);
-
-  if (hwc_display_[disp_id]) {
-    return hwc_display_[disp_id]->GetActiveDisplayConfig(config);
-  }
-
-  return -EINVAL;
-}
-
-Return<void> HWCSession::getActiveConfig(IDisplayConfig::DisplayType dpy,
-                                         getActiveConfig_cb _hidl_cb) {
-  uint32_t config = 0;
-  int32_t error = GetActiveConfigIndex(MapDisplayType(dpy), &config);
-
-  _hidl_cb(error, config);
-
-  return Void();
-}
-
-int32_t HWCSession::SetActiveConfigIndex(int disp_id, uint32_t config) {
-  if (disp_id < 0) {
-    return -EINVAL;
-  }
-
-  SEQUENCE_WAIT_SCOPE_LOCK(locker_[disp_id]);
-  int32_t error = -EINVAL;
-  if (hwc_display_[disp_id]) {
-    error = hwc_display_[disp_id]->SetActiveDisplayConfig(config);
-    if (!error) {
-      Refresh(0);
-    }
-  }
-
-  return error;
-}
-
-Return<int32_t> HWCSession::setActiveConfig(IDisplayConfig::DisplayType dpy, uint32_t config) {
-  return SetActiveConfigIndex(MapDisplayType(dpy), config);
-}
-
-Return<void> HWCSession::getDisplayAttributes(uint32_t configIndex,
-                                              IDisplayConfig::DisplayType dpy,
-                                              getDisplayAttributes_cb _hidl_cb) {
-  int32_t error = -EINVAL;
-  IDisplayConfig::DisplayAttributes display_attributes = {};
-  int disp_id = MapDisplayType(dpy);
-
-  if (disp_id >= HWC_DISPLAY_PRIMARY && disp_id < HWC_NUM_DISPLAY_TYPES) {
-    SEQUENCE_WAIT_SCOPE_LOCK(locker_[disp_id]);
-    if (hwc_display_[disp_id]) {
-      DisplayConfigVariableInfo hwc_display_attributes;
-      error = hwc_display_[disp_id]->GetDisplayAttributesForConfig(static_cast<int>(configIndex),
-                                                                   &hwc_display_attributes);
-      if (!error) {
-        display_attributes.vsyncPeriod = hwc_display_attributes.vsync_period_ns;
-        display_attributes.xRes = hwc_display_attributes.x_pixels;
-        display_attributes.yRes = hwc_display_attributes.y_pixels;
-        display_attributes.xDpi = hwc_display_attributes.x_dpi;
-        display_attributes.yDpi = hwc_display_attributes.y_dpi;
-        display_attributes.panelType = IDisplayConfig::DisplayPortType::DISPLAY_PORT_DEFAULT;
-        display_attributes.isYuv = hwc_display_attributes.is_yuv;
-      }
-    }
-  }
-  _hidl_cb(error, display_attributes);
-
-  return Void();
-}
-
-Return<int32_t> HWCSession::setPanelBrightness(uint32_t level) {
-  SEQUENCE_WAIT_SCOPE_LOCK(locker_[HWC_DISPLAY_PRIMARY]);
-  int32_t error = -EINVAL;
-
-  if (hwc_display_[HWC_DISPLAY_PRIMARY]) {
-    error = hwc_display_[HWC_DISPLAY_PRIMARY]->SetPanelBrightness(static_cast<int>(level));
-    if (error) {
-      DLOGE("Failed to set the panel brightness = %d. Error = %d", level, error);
-    }
-  }
-
-  return error;
-}
-
-int32_t HWCSession::GetPanelBrightness(int *level) {
-  SEQUENCE_WAIT_SCOPE_LOCK(locker_[HWC_DISPLAY_PRIMARY]);
-  int32_t error = -EINVAL;
-
-  if (hwc_display_[HWC_DISPLAY_PRIMARY]) {
-    error = hwc_display_[HWC_DISPLAY_PRIMARY]->GetPanelBrightness(level);
-    if (error) {
-      DLOGE("Failed to get the panel brightness. Error = %d", error);
-    }
-  }
-
-  return error;
-}
-
-Return<void> HWCSession::getPanelBrightness(getPanelBrightness_cb _hidl_cb) {
-  int level = 0;
-  int32_t error = GetPanelBrightness(&level);
-
-  _hidl_cb(error, static_cast<uint32_t>(level));
-
-  return Void();
-}
-
-int32_t HWCSession::MinHdcpEncryptionLevelChanged(int disp_id, uint32_t min_enc_level) {
-  DLOGI("Display %d", disp_id);
-
-  if (disp_id < 0) {
-    return -EINVAL;
-  }
-
-  SEQUENCE_WAIT_SCOPE_LOCK(locker_[disp_id]);
-  if (disp_id != HWC_DISPLAY_EXTERNAL) {
-    DLOGE("Not supported for display");
-  } else if (!hwc_display_[disp_id]) {
-    DLOGW("Display is not connected");
-  } else {
-    return hwc_display_[disp_id]->OnMinHdcpEncryptionLevelChange(min_enc_level);
-  }
-
-  return -EINVAL;
-}
-
-Return<int32_t> HWCSession::minHdcpEncryptionLevelChanged(IDisplayConfig::DisplayType dpy,
-                                                          uint32_t min_enc_level) {
-  return MinHdcpEncryptionLevelChanged(MapDisplayType(dpy), min_enc_level);
-}
-
-Return<int32_t> HWCSession::refreshScreen() {
-  SEQUENCE_WAIT_SCOPE_LOCK(locker_[HWC_DISPLAY_PRIMARY]);
-  Refresh(HWC_DISPLAY_PRIMARY);
-
-  return 0;
-}
-
-int32_t HWCSession::ControlPartialUpdate(int disp_id, bool enable) {
-  if (disp_id < 0) {
-    return -EINVAL;
-  }
-
-  if (disp_id != HWC_DISPLAY_PRIMARY) {
-    DLOGW("CONTROL_PARTIAL_UPDATE is not applicable for display = %d", disp_id);
-    return -EINVAL;
-  }
-
-  SEQUENCE_WAIT_SCOPE_LOCK(locker_[disp_id]);
-  HWCDisplay *hwc_display = hwc_display_[HWC_DISPLAY_PRIMARY];
-  if (!hwc_display) {
-    DLOGE("primary display object is not instantiated");
-    return -EINVAL;
-  }
-
-  uint32_t pending = 0;
-  DisplayError hwc_error = hwc_display->ControlPartialUpdate(enable, &pending);
-
-  if (hwc_error == kErrorNone) {
-    if (!pending) {
-      return 0;
-    }
-  } else if (hwc_error == kErrorNotSupported) {
-    return 0;
-  } else {
-    return -EINVAL;
-  }
-
-  // Todo(user): Unlock it before sending events to client. It may cause deadlocks in future.
-  Refresh(HWC_DISPLAY_PRIMARY);
-
-  // Wait until partial update control is complete
-  int32_t error = locker_[disp_id].WaitFinite(kPartialUpdateControlTimeoutMs);
-
-  return error;
-}
-
-Return<int32_t> HWCSession::controlPartialUpdate(IDisplayConfig::DisplayType dpy, bool enable) {
-  return ControlPartialUpdate(MapDisplayType(dpy), enable);
-}
-
-Return<int32_t> HWCSession::toggleScreenUpdate(bool on) {
-  SEQUENCE_WAIT_SCOPE_LOCK(locker_[HWC_DISPLAY_PRIMARY]);
-
-  int32_t error = -EINVAL;
-  if (hwc_display_[HWC_DISPLAY_PRIMARY]) {
-    error = hwc_display_[HWC_DISPLAY_PRIMARY]->ToggleScreenUpdates(on);
-    if (error) {
-      DLOGE("Failed to toggle screen updates = %d. Error = %d", on, error);
-    }
-  }
-
-  return error;
-}
-
-Return<int32_t> HWCSession::setIdleTimeout(uint32_t value) {
-  SEQUENCE_WAIT_SCOPE_LOCK(locker_[HWC_DISPLAY_PRIMARY]);
-
-  if (hwc_display_[HWC_DISPLAY_PRIMARY]) {
-    hwc_display_[HWC_DISPLAY_PRIMARY]->SetIdleTimeoutMs(value);
-    return 0;
-  }
-
-  DLOGW("Display = %d is not connected.", HWC_DISPLAY_PRIMARY);
-  return -ENODEV;
-}
-
-Return<void> HWCSession::getHDRCapabilities(IDisplayConfig::DisplayType dpy,
-                                            getHDRCapabilities_cb _hidl_cb) {
-  int32_t error = -EINVAL;
-  IDisplayConfig::DisplayHDRCapabilities hdr_caps = {};
-
-  if (!_hidl_cb) {
-    DLOGE("_hidl_cb callback not provided.");
-    return Void();
-  }
-
-  do {
-    int disp_id = MapDisplayType(dpy);
-    if ((disp_id < 0) || (disp_id >= HWC_NUM_DISPLAY_TYPES)) {
-      DLOGE("Invalid display id = %d", disp_id);
-      break;
-    }
-
-    SEQUENCE_WAIT_SCOPE_LOCK(locker_[disp_id]);
-    HWCDisplay *hwc_display = hwc_display_[disp_id];
-    if (!hwc_display) {
-      DLOGW("Display = %d is not connected.", disp_id);
-      error = -ENODEV;
-      break;
-    }
-
-    // query number of hdr types
-    uint32_t out_num_types = 0;
-    if (hwc_display->GetHdrCapabilities(&out_num_types, nullptr, nullptr, nullptr, nullptr)
-        != HWC2::Error::None) {
-      break;
-    }
-
-    if (!out_num_types) {
-      error = 0;
-      break;
-    }
-
-    // query hdr caps
-    hdr_caps.supportedHdrTypes.resize(out_num_types);
-
-    float out_max_luminance = 0.0f;
-    float out_max_average_luminance = 0.0f;
-    float out_min_luminance = 0.0f;
-    if (hwc_display->GetHdrCapabilities(&out_num_types, hdr_caps.supportedHdrTypes.data(),
-                                        &out_max_luminance, &out_max_average_luminance,
-                                        &out_min_luminance)
-        == HWC2::Error::None) {
-      error = 0;
-    }
-  } while (false);
-
-  _hidl_cb(error, hdr_caps);
-
-  return Void();
-}
-
-Return<int32_t> HWCSession::setCameraLaunchStatus(uint32_t on) {
-  SEQUENCE_WAIT_SCOPE_LOCK(locker_[HWC_DISPLAY_PRIMARY]);
-
-  if (!core_intf_) {
-    DLOGW("core_intf_ not initialized.");
-    return -ENOENT;
-  }
-
-  if (!hwc_display_[HWC_DISPLAY_PRIMARY]) {
-    DLOGW("Display = %d is not connected.", HWC_DISPLAY_PRIMARY);
-    return -ENODEV;
-  }
-
-  HWBwModes mode = on > 0 ? kBwCamera : kBwDefault;
-
-  // trigger invalidate to apply new bw caps.
-  Refresh(HWC_DISPLAY_PRIMARY);
-
-  if (core_intf_->SetMaxBandwidthMode(mode) != kErrorNone) {
-    return -EINVAL;
-  }
-
-  new_bw_mode_ = true;
-  need_invalidate_ = true;
-  hwc_display_[HWC_DISPLAY_PRIMARY]->ResetValidation();
-
-  return 0;
-}
-
-int32_t HWCSession::DisplayBWTransactionPending(bool *status) {
-  SEQUENCE_WAIT_SCOPE_LOCK(locker_[HWC_DISPLAY_PRIMARY]);
-
-  if (hwc_display_[HWC_DISPLAY_PRIMARY]) {
-    if (sync_wait(bw_mode_release_fd_, 0) < 0) {
-      DLOGI("bw_transaction_release_fd is not yet signaled: err= %s", strerror(errno));
-      *status = false;
-    }
-
-    return 0;
-  }
-
-  DLOGW("Display = %d is not connected.", HWC_DISPLAY_PRIMARY);
-  return -ENODEV;
-}
-
-Return<void> HWCSession::displayBWTransactionPending(displayBWTransactionPending_cb _hidl_cb) {
-  bool status = true;
-
-  if (!_hidl_cb) {
-      DLOGE("_hidl_cb callback not provided.");
-      return Void();
-  }
-
-  int32_t error = DisplayBWTransactionPending(&status);
-
-  _hidl_cb(error, status);
-
-  return Void();
-}
-
-}  // namespace sdm
diff --git a/sdm/libs/hwc2/hwc_socket_handler.cpp b/sdm/libs/hwc2/hwc_socket_handler.cpp
deleted file mode 100644
index 7ebaab4..0000000
--- a/sdm/libs/hwc2/hwc_socket_handler.cpp
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
-* Copyright (c) 2016, The Linux Foundation. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without
-* modification, are permitted provided that the following conditions are
-* met:
-*  * Redistributions of source code must retain the above copyright
-*    notice, this list of conditions and the following disclaimer.
-*  * Redistributions in binary form must reproduce the above
-*    copyright notice, this list of conditions and the following
-*    disclaimer in the documentation and/or other materials provided
-*    with the distribution.
-*  * Neither the name of The Linux Foundation nor the names of its
-*    contributors may be used to endorse or promote products derived
-*    from this software without specific prior written permission.
-*
-* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
-* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
-* ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
-* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
-* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#include <cutils/sockets.h>
-#include "hwc_socket_handler.h"
-
-#define __CLASS__ "HWCSocketHandler"
-
-#define DPPS_SOCKET "pps"
-
-namespace sdm {
-
-int HWCSocketHandler::GetSocketFd(SocketType socket_type) {
-  switch (socket_type) {
-  case kDpps:
-    return socket_local_client(DPPS_SOCKET, ANDROID_SOCKET_NAMESPACE_RESERVED, SOCK_STREAM);
-  default:
-    return -1;
-  }
-}
-
-}  // namespace sdm
diff --git a/sdm/libs/hwc2/hwc_socket_handler.h b/sdm/libs/hwc2/hwc_socket_handler.h
deleted file mode 100644
index 5b2292a..0000000
--- a/sdm/libs/hwc2/hwc_socket_handler.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
-* Copyright (c) 2016, The Linux Foundation. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without
-* modification, are permitted provided that the following conditions are
-* met:
-*  * Redistributions of source code must retain the above copyright
-*    notice, this list of conditions and the following disclaimer.
-*  * Redistributions in binary form must reproduce the above
-*    copyright notice, this list of conditions and the following
-*    disclaimer in the documentation and/or other materials provided
-*    with the distribution.
-*  * Neither the name of The Linux Foundation nor the names of its
-*    contributors may be used to endorse or promote products derived
-*    from this software without specific prior written permission.
-*
-* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
-* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
-* ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
-* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
-* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-
-#ifndef __HWC_SOCKET_HANDLER_H__
-#define __HWC_SOCKET_HANDLER_H__
-
-#include <core/socket_handler.h>
-
-namespace sdm {
-
-class HWCSocketHandler : public SocketHandler {
- public:
-  HWCSocketHandler() { }
-
-  virtual int GetSocketFd(SocketType socket_type);
-};
-
-}  // namespace sdm
-
-#endif  // __HWC_SOCKET_HANDLER_H__
diff --git a/sdm/libs/hwc2/hwc_tonemapper.cpp b/sdm/libs/hwc2/hwc_tonemapper.cpp
deleted file mode 100644
index 22896f9..0000000
--- a/sdm/libs/hwc2/hwc_tonemapper.cpp
+++ /dev/null
@@ -1,387 +0,0 @@
-/*
-* Copyright (c) 2016 - 2017, The Linux Foundation. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without
-* modification, are permitted provided that the following conditions are
-* met:
-*  * Redistributions of source code must retain the above copyright
-*    notice, this list of conditions and the following disclaimer.
-*  * Redistributions in binary form must reproduce the above
-*    copyright notice, this list of conditions and the following
-*    disclaimer in the documentation and/or other materials provided
-*    with the distribution.
-*  * Neither the name of The Linux Foundation nor the names of its
-*    contributors may be used to endorse or promote products derived
-*    from this software without specific prior written permission.
-*
-* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
-* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
-* ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
-* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
-* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#include <gralloc_priv.h>
-#include <sync/sync.h>
-
-#include <TonemapFactory.h>
-
-#include <core/buffer_allocator.h>
-
-#include <utils/constants.h>
-#include <utils/debug.h>
-#include <utils/formats.h>
-#include <utils/rect.h>
-#include <utils/utils.h>
-
-#include <vector>
-
-#include "hwc_debugger.h"
-#include "hwc_tonemapper.h"
-
-#define __CLASS__ "HWCToneMapper"
-
-namespace sdm {
-
-ToneMapSession::ToneMapSession(HWCBufferAllocator *buffer_allocator)
-  : tone_map_task_(*this), buffer_allocator_(buffer_allocator) {
-  buffer_info_.resize(kNumIntermediateBuffers);
-}
-
-ToneMapSession::~ToneMapSession() {
-  tone_map_task_.PerformTask(ToneMapTaskCode::kCodeDestroy, nullptr);
-  FreeIntermediateBuffers();
-  buffer_info_.clear();
-}
-
-void ToneMapSession::OnTask(const ToneMapTaskCode &task_code,
-                            SyncTask<ToneMapTaskCode>::TaskContext *task_context) {
-  switch (task_code) {
-    case ToneMapTaskCode::kCodeGetInstance: {
-        ToneMapGetInstanceContext *ctx = static_cast<ToneMapGetInstanceContext *>(task_context);
-        Lut3d &lut_3d = ctx->layer->lut_3d;
-        Color10Bit *grid_entries = NULL;
-        int grid_size = 0;
-        if (lut_3d.validGridEntries) {
-          grid_entries = lut_3d.gridEntries;
-          grid_size = INT(lut_3d.gridSize);
-        }
-        gpu_tone_mapper_ = TonemapperFactory_GetInstance(tone_map_config_.type,
-                                                         lut_3d.lutEntries, lut_3d.dim,
-                                                         grid_entries, grid_size,
-                                                         tone_map_config_.secure);
-      }
-      break;
-
-    case ToneMapTaskCode::kCodeBlit: {
-        ToneMapBlitContext *ctx = static_cast<ToneMapBlitContext *>(task_context);
-        uint8_t buffer_index = current_buffer_index_;
-        const void *dst_hnd = reinterpret_cast<const void *>
-                                (buffer_info_[buffer_index].private_data);
-        const void *src_hnd = reinterpret_cast<const void *>
-                                (ctx->layer->input_buffer.buffer_id);
-        ctx->fence_fd = gpu_tone_mapper_->blit(dst_hnd, src_hnd, ctx->merged_fd);
-      }
-      break;
-
-    case ToneMapTaskCode::kCodeDestroy: {
-        delete gpu_tone_mapper_;
-      }
-      break;
-
-    default:
-      break;
-  }
-}
-
-DisplayError ToneMapSession::AllocateIntermediateBuffers(const Layer *layer) {
-  DisplayError error = kErrorNone;
-  for (uint8_t i = 0; i < kNumIntermediateBuffers; i++) {
-    BufferInfo &buffer_info = buffer_info_[i];
-    buffer_info.buffer_config.width = layer->request.width;
-    buffer_info.buffer_config.height = layer->request.height;
-    buffer_info.buffer_config.format = layer->request.format;
-    buffer_info.buffer_config.secure = layer->request.flags.secure;
-    buffer_info.buffer_config.gfx_client = true;
-    error = buffer_allocator_->AllocateBuffer(&buffer_info);
-    if (error != kErrorNone) {
-      FreeIntermediateBuffers();
-      return error;
-    }
-  }
-
-  return kErrorNone;
-}
-
-void ToneMapSession::FreeIntermediateBuffers() {
-  for (uint8_t i = 0; i < kNumIntermediateBuffers; i++) {
-    // Free the valid fence
-    if (release_fence_fd_[i] >= 0) {
-      CloseFd(&release_fence_fd_[i]);
-    }
-    BufferInfo &buffer_info = buffer_info_[i];
-    if (buffer_info.private_data) {
-      buffer_allocator_->FreeBuffer(&buffer_info);
-    }
-  }
-}
-
-void ToneMapSession::UpdateBuffer(int acquire_fence, LayerBuffer *buffer) {
-  // Acquire fence will be closed by HWC Display.
-  // Fence returned by GPU will be closed in PostCommit.
-  buffer->acquire_fence_fd = acquire_fence;
-  buffer->size = buffer_info_[current_buffer_index_].alloc_buffer_info.size;
-  buffer->planes[0].fd = buffer_info_[current_buffer_index_].alloc_buffer_info.fd;
-}
-
-void ToneMapSession::SetReleaseFence(int fd) {
-  CloseFd(&release_fence_fd_[current_buffer_index_]);
-  // Used to give to GPU tonemapper along with input layer fd
-  release_fence_fd_[current_buffer_index_] = dup(fd);
-}
-
-void ToneMapSession::SetToneMapConfig(Layer *layer, PrimariesTransfer blend_cs) {
-  // HDR -> SDR is FORWARD and SDR - > HDR is INVERSE
-  tone_map_config_.type = layer->input_buffer.flags.hdr ? TONEMAP_FORWARD : TONEMAP_INVERSE;
-  tone_map_config_.blend_cs = blend_cs;
-  tone_map_config_.transfer = layer->input_buffer.color_metadata.transfer;
-  tone_map_config_.secure = layer->request.flags.secure;
-  tone_map_config_.format = layer->request.format;
-}
-
-bool ToneMapSession::IsSameToneMapConfig(Layer *layer, PrimariesTransfer blend_cs) {
-  LayerBuffer& buffer = layer->input_buffer;
-  private_handle_t *handle = static_cast<private_handle_t *>(buffer_info_[0].private_data);
-  int tonemap_type = buffer.flags.hdr ? TONEMAP_FORWARD : TONEMAP_INVERSE;
-
-  return ((tonemap_type == tone_map_config_.type) &&
-          (blend_cs == tone_map_config_.blend_cs) &&
-          (buffer.color_metadata.transfer == tone_map_config_.transfer) &&
-          (layer->request.flags.secure == tone_map_config_.secure) &&
-          (layer->request.format == tone_map_config_.format) &&
-          (layer->request.width == UINT32(handle->unaligned_width)) &&
-          (layer->request.height == UINT32(handle->unaligned_height)));
-}
-
-int HWCToneMapper::HandleToneMap(LayerStack *layer_stack) {
-  uint32_t gpu_count = 0;
-  DisplayError error = kErrorNone;
-
-  for (uint32_t i = 0; i < layer_stack->layers.size(); i++) {
-    uint32_t session_index = 0;
-    Layer *layer = layer_stack->layers.at(i);
-    if (layer->composition == kCompositionGPU) {
-      gpu_count++;
-    }
-
-    if (layer->request.flags.tone_map) {
-      DLOGV_IF(kTagClient, "Tonemapping for layer at index %d", i);
-      switch (layer->composition) {
-      case kCompositionGPUTarget:
-        if (!gpu_count) {
-          // When all layers are on FrameBuffer and if they do not update in the next draw cycle,
-          // then SDM marks them for SDE Composition because the cached FB layer gets displayed.
-          // GPU count will be 0 in this case. Try to use the existing tone-mapped frame buffer.
-          // No ToneMap/Blit is required. Just update the buffer & acquire fence fd of FB layer.
-          if (!tone_map_sessions_.empty() && (fb_session_index_ >= 0)) {
-            ToneMapSession *fb_tone_map_session = tone_map_sessions_.at(UINT32(fb_session_index_));
-            fb_tone_map_session->UpdateBuffer(-1 /* acquire_fence */, &layer->input_buffer);
-            fb_tone_map_session->layer_index_ = INT(i);
-            fb_tone_map_session->acquired_ = true;
-            return 0;
-          }
-        }
-        error = AcquireToneMapSession(layer, &session_index, layer_stack->blend_cs);
-        fb_session_index_ = INT(session_index);
-        break;
-      default:
-        error = AcquireToneMapSession(layer, &session_index, layer_stack->blend_cs);
-        break;
-      }
-
-      if (error != kErrorNone) {
-        Terminate();
-        return -1;
-      }
-
-      ToneMapSession *session = tone_map_sessions_.at(session_index);
-      ToneMap(layer, session);
-      DLOGI_IF(kTagClient, "Layer %d associated with session index %d", i, session_index);
-      session->layer_index_ = INT(i);
-    }
-  }
-
-  return 0;
-}
-
-void HWCToneMapper::ToneMap(Layer* layer, ToneMapSession *session) {
-  ToneMapBlitContext ctx = {};
-  ctx.layer = layer;
-
-  uint8_t buffer_index = session->current_buffer_index_;
-  int &release_fence_fd = session->release_fence_fd_[buffer_index];
-
-  // use and close the layer->input_buffer acquire fence fd.
-  int acquire_fd = layer->input_buffer.acquire_fence_fd;
-  buffer_sync_handler_.SyncMerge(release_fence_fd, acquire_fd, &ctx.merged_fd);
-
-  if (acquire_fd >= 0) {
-    CloseFd(&acquire_fd);
-  }
-
-  if (release_fence_fd >= 0) {
-    CloseFd(&release_fence_fd);
-  }
-
-  DTRACE_BEGIN("GPU_TM_BLIT");
-  session->tone_map_task_.PerformTask(ToneMapTaskCode::kCodeBlit, &ctx);
-  DTRACE_END();
-
-  DumpToneMapOutput(session, &ctx.fence_fd);
-  session->UpdateBuffer(ctx.fence_fd, &layer->input_buffer);
-}
-
-void HWCToneMapper::PostCommit(LayerStack *layer_stack) {
-  auto it = tone_map_sessions_.begin();
-  while (it != tone_map_sessions_.end()) {
-    uint32_t session_index = UINT32(std::distance(tone_map_sessions_.begin(), it));
-    ToneMapSession *session = tone_map_sessions_.at(session_index);
-    if (session->acquired_) {
-      Layer *layer = layer_stack->layers.at(UINT32(session->layer_index_));
-      // Close the fd returned by GPU ToneMapper and set release fence.
-      LayerBuffer &layer_buffer = layer->input_buffer;
-      CloseFd(&layer_buffer.acquire_fence_fd);
-      session->SetReleaseFence(layer_buffer.release_fence_fd);
-      session->acquired_ = false;
-      it++;
-    } else {
-      DLOGI_IF(kTagClient, "Tone map session %d closed.", session_index);
-      delete session;
-      it = tone_map_sessions_.erase(it);
-      int deleted_session = INT(session_index);
-      // If FB tonemap session gets deleted, reset fb_session_index_, else update it.
-      if (deleted_session == fb_session_index_) {
-        fb_session_index_ = -1;
-      } else if (deleted_session < fb_session_index_) {
-        fb_session_index_--;
-      }
-    }
-  }
-}
-
-void HWCToneMapper::Terminate() {
-  if (tone_map_sessions_.size()) {
-    while (!tone_map_sessions_.empty()) {
-      delete tone_map_sessions_.back();
-      tone_map_sessions_.pop_back();
-    }
-    fb_session_index_ = -1;
-  }
-}
-
-void HWCToneMapper::SetFrameDumpConfig(uint32_t count) {
-  DLOGI("Dump FrameConfig count = %d", count);
-  dump_frame_count_ = count;
-  dump_frame_index_ = 0;
-}
-
-void HWCToneMapper::DumpToneMapOutput(ToneMapSession *session, int *acquire_fd) {
-  DisplayError error = kErrorNone;
-  if (!dump_frame_count_) {
-    return;
-  }
-
-  BufferInfo &buffer_info = session->buffer_info_[session->current_buffer_index_];
-  private_handle_t *target_buffer = static_cast<private_handle_t *>(buffer_info.private_data);
-
-  if (*acquire_fd >= 0) {
-    int error = sync_wait(*acquire_fd, 1000);
-    if (error < 0) {
-      DLOGW("sync_wait error errno = %d, desc = %s", errno, strerror(errno));
-      return;
-    }
-  }
-
-  error = buffer_allocator_->MapBuffer(target_buffer, *acquire_fd);
-  if (error != kErrorNone) {
-    DLOGE("MapBuffer failed, base addr = %x", target_buffer->base);
-    return;
-  }
-
-  size_t result = 0;
-  char dump_file_name[PATH_MAX];
-  snprintf(dump_file_name, sizeof(dump_file_name), "%s/frame_dump_primary"
-           "/tonemap_%dx%d_frame%d.raw", HWCDebugHandler::DumpDir(), target_buffer->width,
-           target_buffer->height, dump_frame_index_);
-
-  FILE* fp = fopen(dump_file_name, "w+");
-  if (fp) {
-    DLOGI("base addr = %x", target_buffer->base);
-    result = fwrite(reinterpret_cast<void *>(target_buffer->base), target_buffer->size, 1, fp);
-    fclose(fp);
-  }
-  dump_frame_count_--;
-  dump_frame_index_++;
-  CloseFd(acquire_fd);
-}
-
-DisplayError HWCToneMapper::AcquireToneMapSession(Layer *layer, uint32_t *session_index,
-                                                  PrimariesTransfer blend_cs) {
-  // When the property vendor.display.disable_hdr_lut_gen is set, the lutEntries and gridEntries in
-  // the Lut3d will be NULL, clients needs to allocate the memory and set correct 3D Lut
-  // for Tonemapping.
-  if (!layer->lut_3d.lutEntries || !layer->lut_3d.dim) {
-    // Atleast lutEntries must be valid for GPU Tonemapper.
-    DLOGE("Invalid Lut Entries or lut dimension = %d", layer->lut_3d.dim);
-    return kErrorParameters;
-  }
-
-  // Check if we can re-use an existing tone map session.
-  for (uint32_t i = 0; i < tone_map_sessions_.size(); i++) {
-    ToneMapSession *tonemap_session = tone_map_sessions_.at(i);
-    if (!tonemap_session->acquired_ && tonemap_session->IsSameToneMapConfig(layer, blend_cs)) {
-      tonemap_session->current_buffer_index_ = (tonemap_session->current_buffer_index_ + 1) %
-                                                ToneMapSession::kNumIntermediateBuffers;
-      tonemap_session->acquired_ = true;
-      *session_index = i;
-      return kErrorNone;
-    }
-  }
-
-  ToneMapSession *session = new ToneMapSession(buffer_allocator_);
-  if (!session) {
-    return kErrorMemory;
-  }
-
-  session->SetToneMapConfig(layer, blend_cs);
-
-  ToneMapGetInstanceContext ctx;
-  ctx.layer = layer;
-  session->tone_map_task_.PerformTask(ToneMapTaskCode::kCodeGetInstance, &ctx);
-
-  if (session->gpu_tone_mapper_ == NULL) {
-    DLOGE("Get Tonemapper failed!");
-    delete session;
-    return kErrorNotSupported;
-  }
-  DisplayError error = session->AllocateIntermediateBuffers(layer);
-  if (error != kErrorNone) {
-    DLOGE("Allocation of Intermediate Buffers failed!");
-    delete session;
-    return error;
-  }
-
-  session->acquired_ = true;
-  tone_map_sessions_.push_back(session);
-  *session_index = UINT32(tone_map_sessions_.size() - 1);
-
-  return kErrorNone;
-}
-
-}  // namespace sdm
diff --git a/sdm/libs/hwc2/hwc_tonemapper.h b/sdm/libs/hwc2/hwc_tonemapper.h
deleted file mode 100644
index e400d29..0000000
--- a/sdm/libs/hwc2/hwc_tonemapper.h
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
-* Copyright (c) 2016 - 2017, The Linux Foundation. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without
-* modification, are permitted provided that the following conditions are
-* met:
-*  * Redistributions of source code must retain the above copyright
-*    notice, this list of conditions and the following disclaimer.
-*  * Redistributions in binary form must reproduce the above
-*    copyright notice, this list of conditions and the following
-*    disclaimer in the documentation and/or other materials provided
-*    with the distribution.
-*  * Neither the name of The Linux Foundation nor the names of its
-*    contributors may be used to endorse or promote products derived
-*    from this software without specific prior written permission.
-*
-* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
-* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
-* ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
-* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
-* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#ifndef __HWC_TONEMAPPER_H__
-#define __HWC_TONEMAPPER_H__
-
-#include <fcntl.h>
-#include <sys/mman.h>
-
-#include <hardware/hwcomposer.h>
-
-#include <core/layer_stack.h>
-#include <utils/sys.h>
-#include <utils/sync_task.h>
-#include <vector>
-#include "hwc_buffer_sync_handler.h"
-#include "hwc_buffer_allocator.h"
-
-class Tonemapper;
-
-namespace sdm {
-
-enum class ToneMapTaskCode : int32_t {
-  kCodeGetInstance,
-  kCodeBlit,
-  kCodeDestroy,
-};
-
-struct ToneMapGetInstanceContext : public SyncTask<ToneMapTaskCode>::TaskContext {
-  Layer *layer = nullptr;
-};
-
-struct ToneMapBlitContext : public SyncTask<ToneMapTaskCode>::TaskContext {
-  Layer *layer = nullptr;
-  int merged_fd = -1;
-  int fence_fd = -1;
-};
-
-struct ToneMapConfig {
-  int type = 0;
-  PrimariesTransfer blend_cs = {ColorPrimaries_BT709_5, Transfer_sRGB};
-  GammaTransfer transfer = Transfer_Max;
-  LayerBufferFormat format = kFormatRGBA8888;
-  bool secure = false;
-};
-
-class ToneMapSession : public SyncTask<ToneMapTaskCode>::TaskHandler {
- public:
-  explicit ToneMapSession(HWCBufferAllocator *buffer_allocator);
-  ~ToneMapSession();
-  DisplayError AllocateIntermediateBuffers(const Layer *layer);
-  void FreeIntermediateBuffers();
-  void UpdateBuffer(int acquire_fence, LayerBuffer *buffer);
-  void SetReleaseFence(int fd);
-  void SetToneMapConfig(Layer *layer, PrimariesTransfer blend_cs);
-  bool IsSameToneMapConfig(Layer *layer, PrimariesTransfer blend_cs);
-
-  // TaskHandler methods implementation.
-  virtual void OnTask(const ToneMapTaskCode &task_code,
-                      SyncTask<ToneMapTaskCode>::TaskContext *task_context);
-
-  static const uint8_t kNumIntermediateBuffers = 2;
-  SyncTask<ToneMapTaskCode> tone_map_task_;
-  Tonemapper *gpu_tone_mapper_ = nullptr;
-  HWCBufferAllocator *buffer_allocator_ = nullptr;
-  ToneMapConfig tone_map_config_ = {};
-  uint8_t current_buffer_index_ = 0;
-  std::vector<BufferInfo> buffer_info_ = {};
-  int release_fence_fd_[kNumIntermediateBuffers] = {-1, -1};
-  bool acquired_ = false;
-  int layer_index_ = -1;
-};
-
-class HWCToneMapper {
- public:
-  explicit HWCToneMapper(HWCBufferAllocator *allocator) : buffer_allocator_(allocator) {}
-  ~HWCToneMapper() {}
-
-  int HandleToneMap(LayerStack *layer_stack);
-  bool IsActive() { return !tone_map_sessions_.empty(); }
-  void PostCommit(LayerStack *layer_stack);
-  void SetFrameDumpConfig(uint32_t count);
-  void Terminate();
-
- private:
-  void ToneMap(Layer *layer, ToneMapSession *session);
-  DisplayError AcquireToneMapSession(Layer *layer, uint32_t *sess_idx, PrimariesTransfer blend_cs);
-  void DumpToneMapOutput(ToneMapSession *session, int *acquire_fence);
-
-  std::vector<ToneMapSession*> tone_map_sessions_;
-  HWCBufferSyncHandler buffer_sync_handler_ = {};
-  HWCBufferAllocator *buffer_allocator_ = nullptr;
-  uint32_t dump_frame_count_ = 0;
-  uint32_t dump_frame_index_ = 0;
-  int fb_session_index_ = -1;
-};
-
-}  // namespace sdm
-#endif  // __HWC_TONEMAPPER_H__
diff --git a/sdm/libs/utils/Android.mk b/sdm/libs/utils/Android.mk
deleted file mode 100644
index a9d705c..0000000
--- a/sdm/libs/utils/Android.mk
+++ /dev/null
@@ -1,34 +0,0 @@
-LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-include $(LOCAL_PATH)/../../../common.mk
-
-LOCAL_MODULE                  := libsdmutils
-LOCAL_VENDOR_MODULE           := true
-LOCAL_MODULE_TAGS             := optional
-LOCAL_C_INCLUDES              := $(common_includes)
-LOCAL_HEADER_LIBRARIES        := display_headers
-LOCAL_CFLAGS                  := -DLOG_TAG=\"SDM\" $(common_flags)
-LOCAL_SRC_FILES               := debug.cpp \
-                                 rect.cpp \
-                                 sys.cpp \
-                                 formats.cpp \
-                                 utils.cpp
-
-LOCAL_SHARED_LIBRARIES        := libdisplaydebug
-include $(BUILD_SHARED_LIBRARY)
-
-SDM_HEADER_PATH := ../../include
-include $(CLEAR_VARS)
-LOCAL_VENDOR_MODULE           := true
-LOCAL_COPY_HEADERS_TO         := $(common_header_export_path)/sdm/utils
-LOCAL_COPY_HEADERS             = $(SDM_HEADER_PATH)/utils/constants.h \
-                                 $(SDM_HEADER_PATH)/utils/debug.h \
-                                 $(SDM_HEADER_PATH)/utils/formats.h \
-                                 $(SDM_HEADER_PATH)/utils/locker.h \
-                                 $(SDM_HEADER_PATH)/utils/rect.h \
-                                 $(SDM_HEADER_PATH)/utils/sys.h \
-                                 $(SDM_HEADER_PATH)/utils/sync_task.h \
-                                 $(SDM_HEADER_PATH)/utils/utils.h \
-                                 $(SDM_HEADER_PATH)/utils/factory.h
-
-include $(BUILD_COPY_HEADERS)
diff --git a/sdm/libs/utils/Makefile.am b/sdm/libs/utils/Makefile.am
deleted file mode 100644
index d8d8dc5..0000000
--- a/sdm/libs/utils/Makefile.am
+++ /dev/null
@@ -1,12 +0,0 @@
-cpp_sources = debug.cpp \
-              rect.cpp \
-              sys.cpp \
-              formats.cpp \
-              utils.cpp
-
-lib_LTLIBRARIES = libsdmutils.la
-libsdmutils_la_CC = @CC@
-libsdmutils_la_SOURCES = $(cpp_sources)
-libsdmutils_la_CFLAGS = $(COMMON_CFLAGS) -DLOG_TAG=\"SDM\"
-libsdmutils_la_CPPFLAGS = $(AM_CPPFLAGS)
-libsdmutils_la_LDFLAGS = -shared -avoid-version
diff --git a/sdm/libs/utils/debug.cpp b/sdm/libs/utils/debug.cpp
deleted file mode 100644
index cf8abb0..0000000
--- a/sdm/libs/utils/debug.cpp
+++ /dev/null
@@ -1,237 +0,0 @@
-/*
-* Copyright (c) 2014 - 2018, The Linux Foundation. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without
-* modification, are permitted provided that the following conditions are
-* met:
-*     * Redistributions of source code must retain the above copyright
-*       notice, this list of conditions and the following disclaimer.
-*     * Redistributions in binary form must reproduce the above
-*       copyright notice, this list of conditions and the following
-*       disclaimer in the documentation and/or other materials provided
-*       with the distribution.
-*     * Neither the name of The Linux Foundation nor the names of its
-*       contributors may be used to endorse or promote products derived
-*       from this software without specific prior written permission.
-*
-* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
-* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
-* ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
-* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
-* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#include <stdlib.h>
-#include <utils/debug.h>
-#include <utils/constants.h>
-#include <string>
-#include <algorithm>
-
-namespace sdm {
-
-int Debug::GetSimulationFlag() {
-  int value = 0;
-  DebugHandler::Get()->GetProperty(COMPOSITION_MASK_PROP, &value);
-
-  return value;
-}
-
-bool Debug::GetExternalResolution(char *value) {
-  uint32_t retval = 0;
-  DebugHandler::Get()->GetProperty(HDMI_CONFIG_INDEX_PROP, value);
-  if (value[0]) {
-    retval = 1;
-  }
-
-  return retval;
-}
-
-void Debug::GetIdleTimeoutMs(uint32_t *active_ms, uint32_t *inactive_ms) {
-  int active_val = IDLE_TIMEOUT_ACTIVE_MS;
-  int inactive_val = IDLE_TIMEOUT_INACTIVE_MS;
-
-  DebugHandler::Get()->GetProperty(IDLE_TIME_PROP, &active_val);
-  DebugHandler::Get()->GetProperty(IDLE_TIME_INACTIVE_PROP, &inactive_val);
-
-  *active_ms = UINT32(active_val);
-  *inactive_ms = UINT32(inactive_val);
-}
-
-int Debug::GetBootAnimLayerCount() {
-  int value = 0;
-  DebugHandler::Get()->GetProperty(BOOT_ANIMATION_LAYER_COUNT_PROP, &value);
-
-  return value;
-}
-
-bool Debug::IsRotatorDownScaleDisabled() {
-  int value = 0;
-  DebugHandler::Get()->GetProperty(DISABLE_ROTATOR_DOWNSCALE_PROP, &value);
-
-  return (value == 1);
-}
-
-bool Debug::IsDecimationDisabled() {
-  int value = 0;
-  DebugHandler::Get()->GetProperty(DISABLE_DECIMATION_PROP, &value);
-
-  return (value == 1);
-}
-
-int Debug::GetMaxPipesPerMixer(DisplayType display_type) {
-  int value = -1;
-  switch (display_type) {
-  case kPrimary:
-    DebugHandler::Get()->GetProperty(PRIMARY_MIXER_STAGES_PROP, &value);
-    break;
-  case kHDMI:
-    DebugHandler::Get()->GetProperty(EXTERNAL_MIXER_STAGES_PROP, &value);
-    break;
-  case kVirtual:
-    DebugHandler::Get()->GetProperty(VIRTUAL_MIXER_STAGES_PROP, &value);
-    break;
-  default:
-    break;
-  }
-
-  return value;
-}
-
-int Debug::GetMaxUpscale() {
-  int value = 0;
-  DebugHandler::Get()->GetProperty(MAX_UPSCALE_PROP, &value);
-
-  return value;
-}
-
-bool Debug::IsVideoModeEnabled() {
-  int value = 0;
-  DebugHandler::Get()->GetProperty(VIDEO_MODE_PANEL_PROP, &value);
-
-  return (value == 1);
-}
-
-bool Debug::IsRotatorUbwcDisabled() {
-  int value = 0;
-  DebugHandler::Get()->GetProperty(DISABLE_ROTATOR_UBWC_PROP, &value);
-
-  return (value == 1);
-}
-
-bool Debug::IsRotatorSplitDisabled() {
-  int value = 0;
-  DebugHandler::Get()->GetProperty(DISABLE_ROTATOR_SPLIT_PROP, &value);
-
-  return (value == 1);
-}
-
-bool Debug::IsScalarDisabled() {
-  int value = 0;
-  DebugHandler::Get()->GetProperty(DISABLE_SCALER_PROP, &value);
-
-  return (value == 1);
-}
-
-bool Debug::IsUbwcTiledFrameBuffer() {
-  int ubwc_disabled = 0;
-  int ubwc_framebuffer = 0;
-
-  DebugHandler::Get()->GetProperty(DISABLE_UBWC_PROP, &ubwc_disabled);
-
-  if (!ubwc_disabled) {
-    DebugHandler::Get()->GetProperty(ENABLE_FB_UBWC_PROP, &ubwc_framebuffer);
-  }
-
-  return (ubwc_framebuffer == 1);
-}
-
-bool Debug::IsAVRDisabled() {
-  int value = 0;
-  DebugHandler::Get()->GetProperty(DISABLE_AVR_PROP, &value);
-
-  return (value == 1);
-}
-
-bool Debug::IsExtAnimDisabled() {
-  int value = 0;
-  DebugHandler::Get()->GetProperty(DISABLE_EXTERNAL_ANIMATION_PROP, &value);
-
-  return (value == 1);
-}
-
-bool Debug::IsPartialSplitDisabled() {
-  int value = 0;
-  DebugHandler::Get()->GetProperty(DISABLE_PARTIAL_SPLIT_PROP, &value);
-
-  return (value == 1);
-}
-
-bool Debug::IsSrcSplitPreferred() {
-  int value = 0;
-  DebugHandler::Get()->GetProperty(PREFER_SOURCE_SPLIT_PROP, &value);
-
-  return (value == 1);
-}
-
-DisplayError Debug::GetMixerResolution(uint32_t *width, uint32_t *height) {
-  char value[64] = {};
-
-  int error = DebugHandler::Get()->GetProperty(MIXER_RESOLUTION_PROP, value);
-  if (error != 0) {
-    return kErrorUndefined;
-  }
-
-  std::string str(value);
-
-  *width = UINT32(stoi(str));
-  *height = UINT32(stoi(str.substr(str.find('x') + 1)));
-
-  return kErrorNone;
-}
-
-DisplayError Debug::GetReducedConfig(uint32_t *num_vig_pipes, uint32_t *num_dma_pipes) {
-  char value[64] = {};
-
-  int error = DebugHandler::Get()->GetProperty(SIMULATED_CONFIG_PROP, value);
-  if (error != 0) {
-    return kErrorUndefined;
-  }
-
-  std::string str(value);
-
-  *num_vig_pipes = UINT32(stoi(str));
-  *num_dma_pipes = UINT32(stoi(str.substr(str.find('x') + 1)));
-
-  return kErrorNone;
-}
-
-int Debug::GetExtMaxlayers() {
-  int max_external_layers = 0;
-  DebugHandler::Get()->GetProperty(MAX_EXTERNAL_LAYERS_PROP, &max_external_layers);
-
-  return std::max(max_external_layers, 2);
-}
-
-DisplayError Debug::GetProperty(const char *property_name, char *value) {
-  if (DebugHandler::Get()->GetProperty(property_name, value)) {
-    return kErrorUndefined;
-  }
-
-  return kErrorNone;
-}
-
-DisplayError Debug::GetProperty(const char *property_name, int *value) {
-  if (DebugHandler::Get()->GetProperty(property_name, value)) {
-    return kErrorUndefined;
-  }
-
-  return kErrorNone;
-}
-
-}  // namespace sdm
diff --git a/sdm/libs/utils/formats.cpp b/sdm/libs/utils/formats.cpp
deleted file mode 100644
index 42dfea9..0000000
--- a/sdm/libs/utils/formats.cpp
+++ /dev/null
@@ -1,216 +0,0 @@
-/*
-* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without
-* modification, are permitted provided that the following conditions are
-* met:
-*   * Redistributions of source code must retain the above copyright
-*     notice, this list of conditions and the following disclaimer.
-*   * Redistributions in binary form must reproduce the above
-*     copyright notice, this list of conditions and the following
-*     disclaimer in the documentation and/or other materials provided
-*     with the distribution.
-*   * Neither the name of The Linux Foundation nor the names of its
-*     contributors may be used to endorse or promote products derived
-*     from this software without specific prior written permission.
-*
-* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
-* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
-* ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
-* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
-* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#include <utils/formats.h>
-
-#define __CLASS__ "FormatsUtils"
-
-namespace sdm {
-
-bool IsUBWCFormat(LayerBufferFormat format) {
-  switch (format) {
-  case kFormatRGBA8888Ubwc:
-  case kFormatRGBX8888Ubwc:
-  case kFormatBGR565Ubwc:
-  case kFormatYCbCr420SPVenusUbwc:
-  case kFormatRGBA1010102Ubwc:
-  case kFormatRGBX1010102Ubwc:
-  case kFormatYCbCr420TP10Ubwc:
-  case kFormatYCbCr420P010Ubwc:
-    return true;
-  default:
-    return false;
-  }
-}
-
-bool Is10BitFormat(LayerBufferFormat format) {
-  switch (format) {
-  case kFormatRGBA1010102:
-  case kFormatARGB2101010:
-  case kFormatRGBX1010102:
-  case kFormatXRGB2101010:
-  case kFormatBGRA1010102:
-  case kFormatABGR2101010:
-  case kFormatBGRX1010102:
-  case kFormatXBGR2101010:
-  case kFormatRGBA1010102Ubwc:
-  case kFormatRGBX1010102Ubwc:
-  case kFormatYCbCr420P010:
-  case kFormatYCbCr420TP10Ubwc:
-  case kFormatYCbCr420P010Ubwc:
-  case kFormatYCbCr420P010Venus:
-    return true;
-  default:
-    return false;
-  }
-}
-
-const char *GetFormatString(const LayerBufferFormat &format) {
-  switch (format) {
-  case kFormatARGB8888:                 return "ARGB_8888";
-  case kFormatRGBA8888:                 return "RGBA_8888";
-  case kFormatBGRA8888:                 return "BGRA_8888";
-  case kFormatXRGB8888:                 return "XRGB_8888";
-  case kFormatRGBX8888:                 return "RGBX_8888";
-  case kFormatBGRX8888:                 return "BGRX_8888";
-  case kFormatRGBA5551:                 return "RGBA_5551";
-  case kFormatRGBA4444:                 return "RGBA_4444";
-  case kFormatRGB888:                   return "RGB_888";
-  case kFormatBGR888:                   return "BGR_888";
-  case kFormatRGB565:                   return "RGB_565";
-  case kFormatBGR565:                   return "BGR_565";
-  case kFormatRGBA8888Ubwc:             return "RGBA_8888_UBWC";
-  case kFormatRGBX8888Ubwc:             return "RGBX_8888_UBWC";
-  case kFormatBGR565Ubwc:               return "BGR_565_UBWC";
-  case kFormatYCbCr420Planar:           return "Y_CB_CR_420";
-  case kFormatYCrCb420Planar:           return "Y_CR_CB_420";
-  case kFormatYCrCb420PlanarStride16:   return "Y_CR_CB_420_STRIDE16";
-  case kFormatYCbCr420SemiPlanar:       return "Y_CBCR_420";
-  case kFormatYCrCb420SemiPlanar:       return "Y_CRCB_420";
-  case kFormatYCbCr420SemiPlanarVenus:  return "Y_CBCR_420_VENUS";
-  case kFormatYCrCb420SemiPlanarVenus:  return "Y_CRCB_420_VENUS";
-  case kFormatYCbCr422H1V2SemiPlanar:   return "Y_CBCR_422_H1V2";
-  case kFormatYCrCb422H1V2SemiPlanar:   return "Y_CRCB_422_H1V2";
-  case kFormatYCbCr422H2V1SemiPlanar:   return "Y_CBCR_422_H2V1";
-  case kFormatYCrCb422H2V1SemiPlanar:   return "Y_CRCB_422_H2V2";
-  case kFormatYCbCr420SPVenusUbwc:      return "Y_CBCR_420_VENUS_UBWC";
-  case kFormatYCbCr422H2V1Packed:       return "YCBYCR_422_H2V1";
-  case kFormatCbYCrY422H2V1Packed:      return "CBYCRY_422_H2V1";
-  case kFormatRGBA1010102:              return "RGBA_1010102";
-  case kFormatARGB2101010:              return "ARGB_2101010";
-  case kFormatRGBX1010102:              return "RGBX_1010102";
-  case kFormatXRGB2101010:              return "XRGB_2101010";
-  case kFormatBGRA1010102:              return "BGRA_1010102";
-  case kFormatABGR2101010:              return "ABGR_2101010";
-  case kFormatBGRX1010102:              return "BGRX_1010102";
-  case kFormatXBGR2101010:              return "XBGR_2101010";
-  case kFormatRGBA1010102Ubwc:          return "RGBA_1010102_UBWC";
-  case kFormatRGBX1010102Ubwc:          return "RGBX_1010102_UBWC";
-  case kFormatYCbCr420P010:             return "Y_CBCR_420_P010";
-  case kFormatYCbCr420TP10Ubwc:         return "Y_CBCR_420_TP10_UBWC";
-  case kFormatYCbCr420P010Ubwc:         return "Y_CBCR_420_P010_UBWC";
-  case kFormatYCbCr420P010Venus:        return "Y_CBCR_420_P010_VENUS";
-  default:                              return "UNKNOWN";
-  }
-}
-
-BufferLayout GetBufferLayout(LayerBufferFormat format) {
-  switch (format) {
-  case kFormatYCbCr420TP10Ubwc:
-    return kTPTiled;
-  default:
-    return (IsUBWCFormat(format) ? kUBWC : kLinear);
-  }
-}
-
-float GetBufferFormatBpp(LayerBufferFormat format) {
-  float bpp = 0.0f;
-  switch (format) {
-    case kFormatARGB8888:
-    case kFormatRGBA8888:
-    case kFormatBGRA8888:
-    case kFormatXRGB8888:
-    case kFormatRGBX8888:
-    case kFormatBGRX8888:
-    case kFormatRGBA8888Ubwc:
-    case kFormatRGBX8888Ubwc:
-    case kFormatRGBA1010102:
-    case kFormatARGB2101010:
-    case kFormatRGBX1010102:
-    case kFormatXRGB2101010:
-    case kFormatBGRA1010102:
-    case kFormatABGR2101010:
-    case kFormatBGRX1010102:
-    case kFormatXBGR2101010:
-    case kFormatRGBA1010102Ubwc:
-    case kFormatRGBX1010102Ubwc:
-      return 4.0f;
-    case kFormatRGB888:
-    case kFormatBGR888:
-    case kFormatYCbCr420P010:
-    case kFormatYCbCr420P010Ubwc:
-    case kFormatYCbCr420P010Venus:
-      return 3.0f;
-    case kFormatRGB565:
-    case kFormatBGR565:
-    case kFormatRGBA5551:
-    case kFormatRGBA4444:
-    case kFormatBGR565Ubwc:
-    case kFormatYCbCr422H2V1Packed:
-    case kFormatCbYCrY422H2V1Packed:
-    case kFormatYCrCb422H2V1SemiPlanar:
-    case kFormatYCbCr422H2V1SemiPlanar:
-    case kFormatYCbCr420TP10Ubwc:
-    case kFormatYCbCr422H1V2SemiPlanar:
-    case kFormatYCrCb422H1V2SemiPlanar:
-      return 2.0f;
-    case kFormatYCbCr420Planar:
-    case kFormatYCrCb420Planar:
-    case kFormatYCrCb420PlanarStride16:
-    case kFormatYCbCr420SemiPlanar:
-    case kFormatYCrCb420SemiPlanar:
-    case kFormatYCbCr420SemiPlanarVenus:
-    case kFormatYCrCb420SemiPlanarVenus:
-    case kFormatYCbCr420SPVenusUbwc:
-      return 1.5f;
-    default:
-      return 0.0f;
-  }
-
-  return bpp;
-}
-
-DisplayError GetBufferFormatTileSize(LayerBufferFormat format, FormatTileSize *tile_size) {
-  switch (format) {
-  case kFormatYCbCr420SPVenusUbwc:
-    tile_size->tile_width = 32;
-    tile_size->tile_height = 8;
-    tile_size->uv_tile_width = 16;
-    tile_size->uv_tile_height = 8;
-    break;
-  case kFormatYCbCr420TP10Ubwc:
-    tile_size->tile_width = 48;
-    tile_size->tile_height = 4;
-    tile_size->uv_tile_width = 24;
-    tile_size->uv_tile_height = 4;
-    break;
-  case kFormatYCbCr420P010Ubwc:
-    tile_size->tile_width = 32;
-    tile_size->tile_height = 4;
-    tile_size->uv_tile_width = 16;
-    tile_size->uv_tile_height = 4;
-    break;
-  default:
-    return kErrorNotSupported;
-  }
-  return kErrorNone;
-}
-
-}  // namespace sdm
-
diff --git a/sdm/libs/utils/rect.cpp b/sdm/libs/utils/rect.cpp
deleted file mode 100644
index a830542..0000000
--- a/sdm/libs/utils/rect.cpp
+++ /dev/null
@@ -1,312 +0,0 @@
-/*
-* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without
-* modification, are permitted provided that the following conditions are
-* met:
-*   * Redistributions of source code must retain the above copyright
-*     notice, this list of conditions and the following disclaimer.
-*   * Redistributions in binary form must reproduce the above
-*     copyright notice, this list of conditions and the following
-*     disclaimer in the documentation and/or other materials provided
-*     with the distribution.
-*   * Neither the name of The Linux Foundation nor the names of its
-*     contributors may be used to endorse or promote products derived
-*     from this software without specific prior written permission.
-*
-* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
-* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
-* ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
-* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
-* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#include <math.h>
-#include <utils/rect.h>
-#include <utils/constants.h>
-#include <algorithm>
-
-#define __CLASS__ "RectUtils"
-
-namespace sdm {
-
-bool IsValid(const LayerRect &rect) {
-  return ((rect.bottom > rect.top) && (rect.right > rect.left));
-}
-
-bool IsCongruent(const LayerRect &rect1, const LayerRect &rect2) {
-  return ((rect1.left == rect2.left) &&
-          (rect1.top == rect2.top) &&
-          (rect1.right == rect2.right) &&
-          (rect1.bottom == rect2.bottom));
-}
-
-void LogI(DebugTag debug_tag, const char *prefix, const LayerRect &roi) {
-  DLOGI_IF(debug_tag, "%s: left = %.0f, top = %.0f, right = %.0f, bottom = %.0f",
-           prefix, roi.left, roi.top, roi.right, roi.bottom);
-}
-
-void Log(DebugTag debug_tag, const char *prefix, const LayerRect &roi) {
-  DLOGV_IF(debug_tag, "%s: left = %.0f, top = %.0f, right = %.0f, bottom = %.0f",
-           prefix, roi.left, roi.top, roi.right, roi.bottom);
-}
-
-void Normalize(const uint32_t &align_x, const uint32_t &align_y, LayerRect *rect) {
-    rect->left = ROUND_UP_ALIGN_UP(rect->left, align_x);
-    rect->right = ROUND_UP_ALIGN_DOWN(rect->right, align_x);
-    rect->top = ROUND_UP_ALIGN_UP(rect->top, align_y);
-    rect->bottom = ROUND_UP_ALIGN_DOWN(rect->bottom, align_y);
-}
-
-LayerRect Intersection(const LayerRect &rect1, const LayerRect &rect2) {
-  LayerRect res;
-
-  if (!IsValid(rect1) || !IsValid(rect2)) {
-    return LayerRect();
-  }
-
-  res.left = std::max(rect1.left, rect2.left);
-  res.top = std::max(rect1.top, rect2.top);
-  res.right = std::min(rect1.right, rect2.right);
-  res.bottom = std::min(rect1.bottom, rect2.bottom);
-
-  if (!IsValid(res)) {
-    return LayerRect();
-  }
-
-  return res;
-}
-
-LayerRect Reposition(const LayerRect &rect, const int &x_offset, const int &y_offset) {
-  LayerRect res;
-
-  if (!IsValid(rect)) {
-    return LayerRect();
-  }
-
-  res.left = rect.left + FLOAT(x_offset);
-  res.top = rect.top + FLOAT(y_offset);
-  res.right = rect.right + FLOAT(x_offset);
-  res.bottom = rect.bottom + FLOAT(y_offset);
-
-  return res;
-}
-
-// Not a geometrical rect deduction. Deducts rect2 from rect1 only if it results a single rect
-LayerRect Subtract(const LayerRect &rect1, const LayerRect &rect2) {
-  LayerRect res;
-
-  res = rect1;
-
-  if ((rect1.left == rect2.left) && (rect1.right == rect2.right)) {
-    if ((rect1.top == rect2.top) && (rect2.bottom <= rect1.bottom)) {
-      res.top = rect2.bottom;
-    } else if ((rect1.bottom == rect2.bottom) && (rect2.top >= rect1.top)) {
-      res.bottom = rect2.top;
-    }
-  } else if ((rect1.top == rect2.top) && (rect1.bottom == rect2.bottom)) {
-    if ((rect1.left == rect2.left) && (rect2.right <= rect1.right)) {
-      res.left = rect2.right;
-    } else if ((rect1.right == rect2.right) && (rect2.left >= rect1.left)) {
-      res.right = rect2.left;
-    }
-  }
-
-  return res;
-}
-
-LayerRect Union(const LayerRect &rect1, const LayerRect &rect2) {
-  LayerRect res;
-
-  if (!IsValid(rect1) && !IsValid(rect2)) {
-    return LayerRect();
-  }
-
-  if (!IsValid(rect1)) {
-    return rect2;
-  }
-
-  if (!IsValid(rect2)) {
-    return rect1;
-  }
-
-  res.left = std::min(rect1.left, rect2.left);
-  res.top = std::min(rect1.top, rect2.top);
-  res.right = std::max(rect1.right, rect2.right);
-  res.bottom = std::max(rect1.bottom, rect2.bottom);
-
-  return res;
-}
-
-void SplitLeftRight(const LayerRect &in_rect, uint32_t split_count, uint32_t align_x,
-                    bool flip_horizontal, LayerRect *out_rects) {
-  LayerRect rect_temp = in_rect;
-
-  uint32_t split_width = UINT32(rect_temp.right - rect_temp.left) / split_count;
-  float aligned_width = FLOAT(CeilToMultipleOf(split_width, align_x));
-
-  for (uint32_t count = 0; count < split_count; count++) {
-    float aligned_right = rect_temp.left + aligned_width;
-    out_rects[count].left = rect_temp.left;
-    out_rects[count].right = std::min(rect_temp.right, aligned_right);
-    out_rects[count].top = rect_temp.top;
-    out_rects[count].bottom = rect_temp.bottom;
-
-    rect_temp.left = out_rects[count].right;
-
-    Log(kTagRotator, "SplitLeftRight", out_rects[count]);
-  }
-
-  // If we have a horizontal flip, then we should be splitting the source from right to left
-  // to ensure that the right split will have an aligned width that matches the alignment on the
-  // destination.
-  if (flip_horizontal && split_count > 1) {
-    out_rects[0].right = out_rects[0].left + (out_rects[1].right - out_rects[1].left);
-    out_rects[1].left = out_rects[0].right;
-    Log(kTagRotator, "Adjusted Left", out_rects[0]);
-    Log(kTagRotator, "Adjusted Right", out_rects[1]);
-  }
-}
-
-void SplitTopBottom(const LayerRect &in_rect, uint32_t split_count, uint32_t align_y,
-                    bool flip_horizontal, LayerRect *out_rects) {
-  LayerRect rect_temp = in_rect;
-
-  uint32_t split_height = UINT32(rect_temp.bottom - rect_temp.top) / split_count;
-  float aligned_height = FLOAT(CeilToMultipleOf(split_height, align_y));
-
-  for (uint32_t count = 0; count < split_count; count++) {
-    float aligned_bottom = rect_temp.top + aligned_height;
-    out_rects[count].top = rect_temp.top;
-    out_rects[count].bottom = std::min(rect_temp.bottom, aligned_bottom);
-    out_rects[count].left = rect_temp.left;
-    out_rects[count].right = rect_temp.right;
-
-    rect_temp.top = out_rects[count].bottom;
-
-    Log(kTagRotator, "SplitTopBottom", out_rects[count]);
-  }
-
-  // If we have a horizontal flip, then we should be splitting the destination from bottom to top
-  // to ensure that the bottom split's y-offset is aligned correctly after we swap the destinations
-  // while accounting for the flip.
-  if (flip_horizontal && split_count > 1) {
-    out_rects[0].bottom = out_rects[0].top + (out_rects[1].bottom - out_rects[1].top);
-    out_rects[1].top = out_rects[0].bottom;
-    Log(kTagRotator, "Adjusted Top", out_rects[0]);
-    Log(kTagRotator, "Adjusted Bottom", out_rects[1]);
-  }
-}
-
-void MapRect(const LayerRect &src_domain, const LayerRect &dst_domain, const LayerRect &in_rect,
-             LayerRect *out_rect) {
-  if (!IsValid(src_domain) || !IsValid(dst_domain) || !IsValid(in_rect)) {
-    return;
-  }
-
-  int x_offset = INT(src_domain.left);
-  int y_offset = INT(src_domain.top);
-
-  LayerRect modified_in_rect = Reposition(in_rect, -x_offset, -y_offset);
-  float src_domain_width = src_domain.right - src_domain.left;
-  float src_domain_height = src_domain.bottom - src_domain.top;
-  float dst_domain_width = dst_domain.right - dst_domain.left;
-  float dst_domain_height = dst_domain.bottom - dst_domain.top;
-
-  float width_ratio = dst_domain_width / src_domain_width;
-  float height_ratio = dst_domain_height / src_domain_height;
-
-  out_rect->left = dst_domain.left + (width_ratio * modified_in_rect.left);
-  out_rect->top = dst_domain.top + (height_ratio * modified_in_rect.top);
-  out_rect->right = dst_domain.left + (width_ratio * modified_in_rect.right);
-  out_rect->bottom = dst_domain.top + (height_ratio * modified_in_rect.bottom);
-}
-
-void TransformHV(const LayerRect &src_domain, const LayerRect &in_rect,
-                 const LayerTransform &transform, LayerRect *out_rect) {
-  if (!IsValid(src_domain) || !IsValid(in_rect)) {
-    return;
-  }
-
-  float in_width = in_rect.right - in_rect.left;
-  float in_height = in_rect.bottom - in_rect.top;
-  float x_offset = in_rect.left - src_domain.left;
-  float y_offset = in_rect.top - src_domain.top;
-  *out_rect = in_rect;
-
-  if (transform.flip_horizontal) {
-    out_rect->right = src_domain.right - x_offset;
-    out_rect->left = out_rect->right - in_width;
-  }
-
-  if (transform.flip_vertical) {
-    out_rect->bottom = src_domain.bottom - y_offset;
-    out_rect->top = out_rect->bottom - in_height;
-  }
-}
-
-RectOrientation GetOrientation(const LayerRect &in_rect) {
-  if (!IsValid(in_rect)) {
-    return kOrientationUnknown;
-  }
-
-  float input_width = in_rect.right - in_rect.left;
-  float input_height = in_rect.bottom - in_rect.top;
-
-  if (input_width < input_height) {
-    return kOrientationPortrait;
-  }
-
-  return kOrientationLandscape;
-}
-
-DisplayError GetCropAndDestination(const LayerRect &crop, const LayerRect &dst,
-                                   const bool rotated90, float *crop_width,
-                                   float *crop_height, float *dst_width,
-                                   float *dst_height) {
-  if (!IsValid(crop)) {
-    Log(kTagResources, "Invalid crop rect", crop);
-    return kErrorNotSupported;
-  }
-
-  if (!IsValid(dst)) {
-    Log(kTagResources, "Invalid dst rect", dst);
-    return kErrorNotSupported;
-  }
-
-  *crop_width = crop.right - crop.left;
-  *crop_height = crop.bottom - crop.top;
-  if (rotated90) {
-    std::swap(*crop_width, *crop_height);
-  }
-
-  *dst_width = dst.right - dst.left;
-  *dst_height = dst.bottom - dst.top;
-
-  return kErrorNone;
-}
-
-DisplayError GetScaleFactor(const LayerRect &crop, const LayerRect &dst,
-                            bool rotated90, float *scale_x, float *scale_y) {
-  float crop_width = 1.0f, crop_height = 1.0f, dst_width = 1.0f, dst_height = 1.0f;
-
-  DisplayError error = GetCropAndDestination(crop, dst, rotated90, &crop_width, &crop_height,
-                                             &dst_width, &dst_height);
-  if (error != kErrorNone) {
-    return error;
-  }
-
-  *scale_x = crop_width / dst_width;
-  *scale_y = crop_height / dst_height;
-
-  return kErrorNone;
-}
-
-}  // namespace sdm
-
diff --git a/sdm/libs/utils/sys.cpp b/sdm/libs/utils/sys.cpp
deleted file mode 100644
index f5e0f29..0000000
--- a/sdm/libs/utils/sys.cpp
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
-* Copyright (c) 2015, The Linux Foundation. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without
-* modification, are permitted provided that the following conditions are
-* met:
-*     * Redistributions of source code must retain the above copyright
-*       notice, this list of conditions and the following disclaimer.
-*     * Redistributions in binary form must reproduce the above
-*       copyright notice, this list of conditions and the following
-*       disclaimer in the documentation and/or other materials provided
-*       with the distribution.
-*     * Neither the name of The Linux Foundation nor the names of its
-*       contributors may be used to endorse or promote products derived
-*       from this software without specific prior written permission.
-*
-* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
-* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
-* ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
-* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
-* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#include <utils/sys.h>
-#include <sys/ioctl.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <string>
-
-#define __CLASS__ "Sys"
-
-namespace sdm {
-
-#ifndef SDM_VIRTUAL_DRIVER
-
-int PthreadCancel(pthread_t /* thread */) {
-  return 0;
-}
-
-// Pointer to actual driver interfaces.
-Sys::ioctl Sys::ioctl_ = ::ioctl;
-Sys::access Sys::access_ = ::access;
-Sys::open Sys::open_ = ::open;
-Sys::close Sys::close_ = ::close;
-Sys::poll Sys::poll_ = ::poll;
-Sys::pread Sys::pread_ = ::pread;
-Sys::pwrite Sys::pwrite_ = ::pwrite;
-Sys::pthread_cancel Sys::pthread_cancel_ = PthreadCancel;
-Sys::dup Sys::dup_ = ::dup;
-Sys::read Sys::read_ = ::read;
-Sys::write Sys::write_ = ::write;
-Sys::eventfd Sys::eventfd_ = ::eventfd;
-
-bool Sys::getline_(fstream &fs, std::string &line) {
-  return std::getline(fs, line) ? true : false;
-}
-
-#endif  // SDM_VIRTUAL_DRIVER
-
-DynLib::~DynLib() {
-  Close();
-}
-
-bool DynLib::Open(const char *lib_name) {
-  Close();
-  lib_ = ::dlopen(lib_name, RTLD_NOW);
-
-  return (lib_ != NULL);
-}
-
-bool DynLib::Sym(const char *func_name, void **func_ptr) {
-  if (lib_) {
-    *func_ptr = ::dlsym(lib_, func_name);
-  } else {
-    *func_ptr = NULL;
-  }
-
-  return (*func_ptr != NULL);
-}
-
-void DynLib::Close() {
-  if (lib_) {
-    ::dlclose(lib_);
-    lib_ = NULL;
-  }
-}
-
-}  // namespace sdm
-
diff --git a/sdm/libs/utils/utils.cpp b/sdm/libs/utils/utils.cpp
deleted file mode 100644
index 07211a1..0000000
--- a/sdm/libs/utils/utils.cpp
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
-* Copyright (c) 2016 - 2017, The Linux Foundation. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without
-* modification, are permitted provided that the following conditions are
-* met:
-*   * Redistributions of source code must retain the above copyright
-*     notice, this list of conditions and the following disclaimer.
-*   * Redistributions in binary form must reproduce the above
-*     copyright notice, this list of conditions and the following
-*     disclaimer in the documentation and/or other materials provided
-*     with the distribution.
-*   * Neither the name of The Linux Foundation nor the names of its
-*     contributors may be used to endorse or promote products derived
-*     from this software without specific prior written permission.
-*
-* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
-* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
-* ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
-* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
-* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#include <unistd.h>
-#include <math.h>
-#include <utils/sys.h>
-#include <utils/utils.h>
-
-#include <algorithm>
-
-#define __CLASS__ "Utils"
-
-namespace sdm {
-
-float gcd(float a, float b) {
-  if (a < b) {
-    std::swap(a, b);
-  }
-
-  while (b != 0) {
-    float tmp = b;
-    b = fmodf(a, b);
-    a = tmp;
-  }
-
-  return a;
-}
-
-float lcm(float a, float b) {
-  return (a * b) / gcd(a, b);
-}
-
-void CloseFd(int *fd) {
-  if (*fd >= 0) {
-    Sys::close_(*fd);
-    *fd = -1;
-  }
-}
-
-DriverType GetDriverType() {
-    const char *fb_caps = "/sys/devices/virtual/graphics/fb0/mdp/caps";
-    // 0 - File exists
-    return Sys::access_(fb_caps, F_OK) ? DriverType::DRM : DriverType::FB;
-}
-}  // namespace sdm
