diff --git a/Makefile.am b/Makefile.am
index 781b836..8ecc86b 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -2,4 +2,4 @@
 
 ACLOCAL_AMFLAGS = -I m4
 
-SUBDIRS = libqservice libqdutils libgralloc sdm/libs/utils sdm/libs/core
+SUBDIRS = libqservice libqdutils sdm/libs/utils sdm/libs/core
diff --git a/configure.ac b/configure.ac
index 6fe7d0a..24c41fd 100644
--- a/configure.ac
+++ b/configure.ac
@@ -50,8 +50,7 @@
         Makefile \
         libqservice/Makefile \
         libqdutils/Makefile \
-        libgralloc/Makefile \
         sdm/libs/utils/Makefile \
         sdm/libs/core/Makefile
         ])
-AC_OUTPUT
\ No newline at end of file
+AC_OUTPUT
diff --git a/gpu_tonemapper/Tonemapper.cpp b/gpu_tonemapper/Tonemapper.cpp
index 981863d..811e091 100644
--- a/gpu_tonemapper/Tonemapper.cpp
+++ b/gpu_tonemapper/Tonemapper.cpp
@@ -45,7 +45,6 @@
 Tonemapper::~Tonemapper()
 //-----------------------------------------------------------------------------
 {
-  void* caller_context = engine_backup();
   engine_bind(engineContext);
   engine_deleteInputBuffer(tonemapTexture);
   engine_deleteInputBuffer(lutXformTexture);
@@ -58,9 +57,6 @@
   }
 
   engine_shutdown(engineContext);
-  // restore the caller context
-  engine_bind(caller_context);
-  engine_free_backup(caller_context);
 }
 
 //-----------------------------------------------------------------------------
@@ -78,7 +74,6 @@
 
   tonemapper->engineContext = engine_initialize(isSecure);
 
-  void* caller_context = engine_backup();
   engine_bind(tonemapper->engineContext);
 
   // load the 3d lut
@@ -117,10 +112,6 @@
   tonemapper->programID =
       engine_loadProgram(1, &fullscreen_vertex_shader, fragmentShaderCount, fragmentShaders);
 
-  // restore the caller context
-  engine_bind(caller_context);
-  engine_free_backup(caller_context);
-
   return tonemapper;
 }
 
@@ -128,7 +119,6 @@
 int Tonemapper::blit(const void *dst, const void *src, int srcFenceFd)
 //-----------------------------------------------------------------------------
 {
-  void* caller_context = engine_backup();
   // make current
   engine_bind(engineContext);
 
@@ -159,10 +149,5 @@
   // perform
   int fenceFD = engine_blit(srcFenceFd);
 
-  // restore the caller context
-  engine_bind(caller_context);
-  engine_free_backup(caller_context);
-
-
   return fenceFD;
 }
diff --git a/gpu_tonemapper/engine.h b/gpu_tonemapper/engine.h
index e0bf2aa..8fb9452 100644
--- a/gpu_tonemapper/engine.h
+++ b/gpu_tonemapper/engine.h
@@ -22,8 +22,6 @@
 
 void* engine_initialize(bool isSecure);
 void engine_bind(void*);
-void* engine_backup();
-void engine_free_backup(void*);
 void engine_shutdown(void*);
 
 unsigned int engine_loadProgram(int, const char **, int, const char **);
diff --git a/gpu_tonemapper/glengine.cpp b/gpu_tonemapper/glengine.cpp
index 6cfe15f..6c94c23 100644
--- a/gpu_tonemapper/glengine.cpp
+++ b/gpu_tonemapper/glengine.cpp
@@ -47,27 +47,6 @@
 }
 
 //-----------------------------------------------------------------------------
-// store the current context(caller)
-void* engine_backup()
-{
-  EngineContext* callerContext = new EngineContext();
-  // store the previous display/context
-  callerContext->eglDisplay = eglGetCurrentDisplay();
-  callerContext->eglContext = eglGetCurrentContext();
-  callerContext->eglSurface = eglGetCurrentSurface(EGL_DRAW);
-
-  return (void*)callerContext;
-}
-//-----------------------------------------------------------------------------
-// frees the backed up caller context
-void engine_free_backup(void* context)
-{
-  EngineContext* callerContext = (EngineContext*)(context);
-
-  delete callerContext;
-}
-
-//-----------------------------------------------------------------------------
 // initialize GL
 //
 void* engine_initialize(bool isSecure)
diff --git a/libdrmutils/drm_interface.h b/libdrmutils/drm_interface.h
index 8fddb43..35285ee 100644
--- a/libdrmutils/drm_interface.h
+++ b/libdrmutils/drm_interface.h
@@ -230,6 +230,12 @@
    */
   CRTC_SET_SECURITY_LEVEL,
   /*
+   * Op: sets solid fill stages
+   * Arg: uint32_t - CRTC ID
+   *      Vector of DRMSolidfillStage
+   */
+  CRTC_SET_SOLIDFILL_STAGES,
+  /*
    * Op: Returns retire fence for this commit. Should be called after Commit() on
    * DRMAtomicReqInterface.
    * Arg: uint32_t - Connector ID
@@ -321,6 +327,7 @@
 struct DRMCrtcInfo {
   bool has_src_split;
   uint32_t max_blend_stages;
+  uint32_t max_solidfill_stages;
   QSEEDVersion qseed_version;
   SmartDMARevision smart_dma_rev;
   float ib_fudge_factor;
@@ -471,6 +478,14 @@
   SECURE_ONLY,
 };
 
+struct DRMSolidfillStage {
+ DRMRect bounding_rect {};
+ bool is_exclusion_rect = false;
+ uint32_t color = 0xff000000; // in 8bit argb
+ 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
diff --git a/libgralloc/Android.mk b/libgralloc/Android.mk
deleted file mode 100644
index 86c0f04..0000000
--- a/libgralloc/Android.mk
+++ /dev/null
@@ -1,52 +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.
-
-# 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) $(kernel_includes)
-LOCAL_HEADER_LIBRARIES        := display_headers
-LOCAL_SHARED_LIBRARIES        := $(common_libs) libmemalloc libqdMetaData libqdutils
-ifneq ($(TARGET_IS_HEADLESS), true)
-LOCAL_SHARED_LIBRARIES        += libGLESv1_CM
-endif
-LOCAL_CFLAGS                  := $(common_flags) -DLOG_TAG=\"qdgralloc\" -Wno-sign-conversion
-LOCAL_ADDITIONAL_DEPENDENCIES := $(common_deps) $(kernel_deps)
-LOCAL_SRC_FILES               := gpu.cpp gralloc.cpp framebuffer.cpp mapper.cpp
-LOCAL_COPY_HEADERS_TO         := $(common_header_export_path)
-LOCAL_COPY_HEADERS            := gralloc_priv.h gr.h adreno_utils.h
-
-include $(BUILD_SHARED_LIBRARY)
-
-# MemAlloc Library
-include $(CLEAR_VARS)
-
-LOCAL_MODULE                  := libmemalloc
-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) libqdutils libdl
-LOCAL_CFLAGS                  := $(common_flags) -DLOG_TAG=\"qdmemalloc\" -Wno-sign-conversion
-LOCAL_ADDITIONAL_DEPENDENCIES := $(common_deps) $(kernel_deps)
-LOCAL_SRC_FILES               := ionalloc.cpp alloc_controller.cpp
-LOCAL_COPY_HEADERS            := alloc_controller.h memalloc.h
-
-include $(BUILD_SHARED_LIBRARY)
diff --git a/libgralloc/Makefile.am b/libgralloc/Makefile.am
deleted file mode 100644
index 3cf3960..0000000
--- a/libgralloc/Makefile.am
+++ /dev/null
@@ -1,42 +0,0 @@
-HEADER_PATH := ${WORKSPACE}/display/display-hal/include
-h_sources = alloc_controller.h \
-            memalloc.h
-
-cpp_sources = ionalloc.cpp \
-              alloc_controller.cpp
-
-memalloc_includedir = $(pkgincludedir)
-memalloc_include_HEADERS = $(h_sources)
-
-lib_LTLIBRARIES = libmemalloc.la
-libmemalloc_la_CC = @CC@
-libmemalloc_la_SOURCES = $(cpp_sources)
-libmemalloc_la_CFLAGS = $(COMMON_CFLAGS) -DLOG_TAG=\"qdmemalloc\"
-libmemalloc_la_CPPFLAGS = $(AM_CPPFLAGS)
-libmemalloc_la_LIBADD = ../libqdutils/libqdutils.la
-libmemalloc_la_LIBADD += -lhardware -lcutils -llog -lutils -ldl
-libmemalloc_la_LDFLAGS = -shared -avoid-version
-
-header_sources = gralloc_priv.h \
-                 gr.h \
-                 adreno_utils.h \
-                 $(HEADER_PATH)/color_metadata.h
-
-c_sources = gpu.cpp \
-            gralloc.cpp \
-            framebuffer.cpp \
-            mapper.cpp
-
-library_includedir = $(pkgincludedir)
-library_include_HEADERS = $(header_sources)
-
-lib_LTLIBRARIES += libgralloc.la
-libgralloc_la_CC = @CC@
-libgralloc_la_SOURCES = $(c_sources)
-libgralloc_la_CFLAGS = $(COMMON_CFLAGS) -DLOG_TAG=\"qdgralloc\"
-libgralloc_la_CPPFLAGS = $(AM_CPPFLAGS)
-libgralloc_la_LIBADD = ../libqdutils/libqdutils.la
-libgralloc_la_LIBADD += ../libqdutils/libqdMetaData.la
-libgralloc_la_LIBADD += -lhardware -lcutils -llog -lutils -lbinder
-libgralloc_la_LIBADD += libmemalloc.la
-libgralloc_la_LDFLAGS = -shared -avoid-version
diff --git a/libgralloc/adreno_utils.h b/libgralloc/adreno_utils.h
deleted file mode 100644
index baecef9..0000000
--- a/libgralloc/adreno_utils.h
+++ /dev/null
@@ -1,59 +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.
-*/
-
-// Adreno Pixel Formats
-typedef enum {
-
-    ADRENO_PIXELFORMAT_UNKNOWN       = 0,
-    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;
diff --git a/libgralloc/alloc_controller.cpp b/libgralloc/alloc_controller.cpp
deleted file mode 100644
index d2a522e..0000000
--- a/libgralloc/alloc_controller.cpp
+++ /dev/null
@@ -1,1223 +0,0 @@
-/*
- * Copyright (c) 2011 - 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/log.h>
-#include <fcntl.h>
-#include <dlfcn.h>
-#include <media/msm_media_info.h>
-#include <qdMetaData.h>
-#include <utils/Singleton.h>
-#include <utils/Mutex.h>
-#include <algorithm>
-
-#include "gralloc_priv.h"
-#include "alloc_controller.h"
-#include "memalloc.h"
-#include "ionalloc.h"
-#include "gr.h"
-#include "qd_utils.h"
-
-#define ASTC_BLOCK_SIZE 16
-
-#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
-
-#ifndef COLOR_FMT_P010_UBWC
-#define COLOR_FMT_P010_UBWC 9
-#endif
-
-using namespace gralloc;
-using namespace qdutils;
-using namespace android;
-
-ANDROID_SINGLETON_STATIC_INSTANCE(AdrenoMemInfo);
-ANDROID_SINGLETON_STATIC_INSTANCE(MDPCapabilityInfo);
-
-static void getYuvUBwcWidthHeight(int, int, int, int&, int&);
-static unsigned int getUBwcSize(int, int, int, const int, const int);
-
-//Common functions
-
-/* 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. Any combination with a _RARELY_ flag will be
- * treated as uncached. */
-static bool useUncached(const int& usage) {
-    if ((usage & GRALLOC_USAGE_PROTECTED) or
-        (usage & GRALLOC_USAGE_PRIVATE_UNCACHED) or
-        ((usage & GRALLOC_USAGE_SW_WRITE_MASK) == GRALLOC_USAGE_SW_WRITE_RARELY) or
-        ((usage & GRALLOC_USAGE_SW_READ_MASK) ==  GRALLOC_USAGE_SW_READ_RARELY))
-        return true;
-
-    return false;
-}
-
-//------------- MDPCapabilityInfo-----------------------//
-MDPCapabilityInfo :: MDPCapabilityInfo() {
-  qdutils::querySDEInfo(HAS_UBWC, &isUBwcSupported);
-  qdutils::querySDEInfo(HAS_WB_UBWC, &isWBUBWCSupported);
-}
-
-//------------- AdrenoMemInfo-----------------------//
-AdrenoMemInfo::AdrenoMemInfo()
-{
-    LINK_adreno_compute_aligned_width_and_height = NULL;
-    LINK_adreno_compute_padding = NULL;
-    LINK_adreno_compute_compressedfmt_aligned_width_and_height = NULL;
-    LINK_adreno_isUBWCSupportedByGpu = NULL;
-    LINK_adreno_get_gpu_pixel_alignment = NULL;
-
-    libadreno_utils = ::dlopen("libadreno_utils.so", RTLD_NOW);
-    if (libadreno_utils) {
-        *(void **)&LINK_adreno_compute_aligned_width_and_height =
-                ::dlsym(libadreno_utils, "compute_aligned_width_and_height");
-        *(void **)&LINK_adreno_compute_padding =
-                ::dlsym(libadreno_utils, "compute_surface_padding");
-        *(void **)&LINK_adreno_compute_compressedfmt_aligned_width_and_height =
-                ::dlsym(libadreno_utils,
-                        "compute_compressedfmt_aligned_width_and_height");
-        *(void **)&LINK_adreno_isUBWCSupportedByGpu =
-                ::dlsym(libadreno_utils, "isUBWCSupportedByGpu");
-        *(void **)&LINK_adreno_get_gpu_pixel_alignment =
-                ::dlsym(libadreno_utils, "get_gpu_pixel_alignment");
-    }
-
-    // Check if the overriding property debug.gralloc.gfx_ubwc_disable
-    // that disables UBWC allocations for the graphics stack is set
-    gfx_ubwc_disable = 0;
-    char property[PROPERTY_VALUE_MAX];
-    property_get("debug.gralloc.gfx_ubwc_disable", property, "0");
-    if(!(strncmp(property, "1", PROPERTY_VALUE_MAX)) ||
-       !(strncmp(property, "true", PROPERTY_VALUE_MAX))) {
-        gfx_ubwc_disable = 1;
-    }
-}
-
-AdrenoMemInfo::~AdrenoMemInfo()
-{
-    if (libadreno_utils) {
-        ::dlclose(libadreno_utils);
-    }
-}
-
-void AdrenoMemInfo::getAlignedWidthAndHeight(const private_handle_t *hnd, int& aligned_w,
-                          int& aligned_h) {
-    MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
-    if(metadata && metadata->operation & UPDATE_BUFFER_GEOMETRY) {
-        int w = metadata->bufferDim.sliceWidth;
-        int h = metadata->bufferDim.sliceHeight;
-        int f = hnd->format;
-        int usage = 0;
-
-        if (hnd->flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED) {
-            usage = GRALLOC_USAGE_PRIVATE_ALLOC_UBWC;
-        }
-
-        getAlignedWidthAndHeight(w, h, f, usage, aligned_w, aligned_h);
-    } else {
-        aligned_w = hnd->width;
-        aligned_h = hnd->height;
-    }
-
-}
-
-void AdrenoMemInfo::getUnalignedWidthAndHeight(const private_handle_t *hnd, int& unaligned_w,
-                                               int& unaligned_h) {
-    MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
-    if(metadata && metadata->operation & UPDATE_BUFFER_GEOMETRY) {
-        unaligned_w = metadata->bufferDim.sliceWidth;
-        unaligned_h = metadata->bufferDim.sliceHeight;
-    } else {
-        unaligned_w = hnd->unaligned_width;
-        unaligned_h = hnd->unaligned_height;
-    }
-}
-
-bool isUncompressedRgbFormat(int format)
-{
-    bool is_rgb_format = false;
-
-    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_BGR_888:
-        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:    // Intentional fallthrough
-            is_rgb_format = true;
-            break;
-        default:
-            break;
-    }
-
-    return is_rgb_format;
-}
-
-void AdrenoMemInfo::getAlignedWidthAndHeight(int width, int height, int format,
-                            int usage, int& aligned_w, int& aligned_h)
-{
-    bool ubwc_enabled = isUBwcEnabled(format, usage);
-
-    // Currently surface padding is only computed for RGB* surfaces.
-    if (isUncompressedRgbFormat(format) == true) {
-        int tileEnabled = ubwc_enabled;
-        getGpuAlignedWidthHeight(width, height, format, tileEnabled, aligned_w, aligned_h);
-    } else if (ubwc_enabled) {
-        getYuvUBwcWidthHeight(width, height, format, aligned_w, aligned_h);
-    } else {
-        aligned_w = width;
-        aligned_h = height;
-        int alignment = 32;
-        switch (format)
-        {
-            case HAL_PIXEL_FORMAT_YCrCb_420_SP:
-            case HAL_PIXEL_FORMAT_YCbCr_420_SP:
-                if (LINK_adreno_get_gpu_pixel_alignment) {
-                  alignment = LINK_adreno_get_gpu_pixel_alignment();
-                }
-                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, 8);
-                break;
-            case HAL_PIXEL_FORMAT_RAW10:
-                aligned_w = ALIGN(width * 10 / 8, 8);
-                break;
-            case HAL_PIXEL_FORMAT_RAW8:
-                aligned_w = ALIGN(width, 8);
-                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:
-            case HAL_PIXEL_FORMAT_CbYCrY_422_I:
-                aligned_w = ALIGN(width, 16);
-                break;
-            case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
-            case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
-                aligned_w = VENUS_Y_STRIDE(COLOR_FMT_NV12, width);
-                aligned_h = VENUS_Y_SCANLINES(COLOR_FMT_NV12, height);
-                break;
-            case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS:
-                aligned_w = VENUS_Y_STRIDE(COLOR_FMT_NV21, width);
-                aligned_h = 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;
-            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:
-                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,
-                        &aligned_w, &aligned_h, &bytesPerPixel);
-                } else {
-                    ALOGW("%s: Warning!! Symbols" \
-                          " compute_compressedfmt_aligned_width_and_height" \
-                          " not found", __FUNCTION__);
-                }
-                break;
-            default: break;
-        }
-    }
-}
-
-void AdrenoMemInfo::getGpuAlignedWidthHeight(int width, int height, int format,
-                            int tile_enabled, int& aligned_w, int& aligned_h)
-{
-    aligned_w = ALIGN(width, 32);
-    aligned_h = ALIGN(height, 32);
-
-    // Don't add any additional padding if debug.gralloc.map_fb_memory
-    // is enabled
-    char property[PROPERTY_VALUE_MAX];
-    if((property_get("debug.gralloc.map_fb_memory", property, NULL) > 0) &&
-       (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
-       (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
-        return;
-    }
-
-    int bpp = 4;
-    switch(format)
-    {
-        case HAL_PIXEL_FORMAT_RGB_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;
-    }
-
-    if (libadreno_utils) {
-        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_aligned_width_and_height) {
-            LINK_adreno_compute_aligned_width_and_height(width,
-                                 height, bpp, tile_enabled,
-                                 raster_mode, padding_threshold,
-                                 &aligned_w, &aligned_h);
-
-        } else if(LINK_adreno_compute_padding) {
-            int surface_tile_height = 1;   // Linear surface
-            aligned_w = 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_aligned_width_and_height not found", __FUNCTION__);
-        }
-   }
-}
-
-int AdrenoMemInfo::isUBWCSupportedByGPU(int format)
-{
-    if (!gfx_ubwc_disable && libadreno_utils) {
-        if (LINK_adreno_isUBWCSupportedByGpu) {
-            ADRENOPIXELFORMAT gpu_format = getGpuPixelFormat(format);
-            return LINK_adreno_isUBWCSupportedByGpu(gpu_format);
-        }
-    }
-    return 0;
-}
-
-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_RGB_565:
-            return ADRENO_PIXELFORMAT_B5G6R5;
-        case HAL_PIXEL_FORMAT_BGR_565:
-            return ADRENO_PIXELFORMAT_R5G6B5;
-        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:
-            return ADRENO_PIXELFORMAT_P010;
-        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;
-        default:
-            ALOGE("%s: No map for format: 0x%x", __FUNCTION__, hal_format);
-            break;
-    }
-    return ADRENO_PIXELFORMAT_UNKNOWN;
-}
-
-//-------------- IAllocController-----------------------//
-IAllocController* IAllocController::sController = NULL;
-IAllocController* IAllocController::getInstance(void)
-{
-    if(sController == NULL) {
-        sController = new IonController();
-    }
-    return sController;
-}
-
-
-//-------------- IonController-----------------------//
-IonController::IonController()
-{
-    allocateIonMem();
-
-    char property[PROPERTY_VALUE_MAX];
-    property_get("video.disable.ubwc", property, "0");
-    mDisableUBWCForEncode = atoi(property);
-}
-
-void IonController::allocateIonMem()
-{
-   mIonAlloc = new IonAlloc();
-}
-
-int IonController::allocate(alloc_data& data, int usage)
-{
-    int ionFlags = 0;
-    int ionHeapId = 0;
-    int ret;
-
-    data.uncached = useUncached(usage);
-    data.allocType = 0;
-
-    if(usage & GRALLOC_USAGE_PROTECTED) {
-        if (usage & GRALLOC_USAGE_PRIVATE_SECURE_DISPLAY) {
-            ionHeapId = ION_HEAP(SD_HEAP_ID);
-            /*
-             * There is currently no flag in ION for Secure Display
-             * VM. Please add it to the define once available.
-             */
-            ionFlags |= ION_SD_FLAGS;
-        } else if (usage & GRALLOC_USAGE_HW_CAMERA_MASK) {
-            ionHeapId = ION_HEAP(SD_HEAP_ID);
-            ionFlags |= (usage & GRALLOC_USAGE_HW_COMPOSER) ? ION_SC_PREVIEW_FLAGS : ION_SC_FLAGS;
-        } else {
-            ionHeapId = ION_HEAP(CP_HEAP_ID);
-            ionFlags |= ION_CP_FLAGS;
-        }
-    } else if(usage & GRALLOC_USAGE_PRIVATE_MM_HEAP) {
-        //MM Heap is exclusively a secure heap.
-        //If it is used for non secure cases, fallback to IOMMU heap
-        ALOGW("GRALLOC_USAGE_PRIVATE_MM_HEAP \
-                                cannot be used as an insecure heap!\
-                                trying to use system heap instead !!");
-        ionHeapId |= ION_HEAP(ION_SYSTEM_HEAP_ID);
-    }
-
-    if(usage & GRALLOC_USAGE_PRIVATE_CAMERA_HEAP)
-        ionHeapId |= ION_HEAP(ION_CAMERA_HEAP_ID);
-
-    if(usage & GRALLOC_USAGE_PRIVATE_ADSP_HEAP)
-        ionHeapId |= ION_HEAP(ION_ADSP_HEAP_ID);
-
-    if(ionFlags & ION_SECURE)
-         data.allocType |= private_handle_t::PRIV_FLAGS_SECURE_BUFFER;
-
-    // if no ion heap flags are set, default to system heap
-    if(!ionHeapId)
-        ionHeapId = ION_HEAP(ION_SYSTEM_HEAP_ID);
-
-    //At this point we should have the right heap set, there is no fallback
-    data.flags = ionFlags;
-    data.heapId = ionHeapId;
-    ret = mIonAlloc->alloc_buffer(data);
-
-    if(ret >= 0 ) {
-        data.allocType |= private_handle_t::PRIV_FLAGS_USES_ION;
-    } else {
-        ALOGE("%s: Failed to allocate buffer - heap: 0x%x flags: 0x%x",
-                __FUNCTION__, ionHeapId, ionFlags);
-    }
-
-    return ret;
-}
-
-IMemAlloc* IonController::getAllocator(int flags)
-{
-    IMemAlloc* memalloc = NULL;
-    if (flags & private_handle_t::PRIV_FLAGS_USES_ION) {
-        memalloc = mIonAlloc;
-    } else {
-        ALOGE("%s: Invalid flags passed: 0x%x", __FUNCTION__, flags);
-    }
-
-    return memalloc;
-}
-
-// helper function
-unsigned int getSize(int format, int width, int height, int usage,
-        const int alignedw, const int alignedh) {
-
-    if (isUBwcEnabled(format, usage)) {
-        return getUBwcSize(width, height, format, alignedw, alignedh);
-    }
-
-    unsigned int size = 0;
-    switch (format) {
-        case HAL_PIXEL_FORMAT_RGBA_8888:
-        case HAL_PIXEL_FORMAT_RGBX_8888:
-        case HAL_PIXEL_FORMAT_BGRA_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:
-            size = alignedw * alignedh * 4;
-            break;
-        case HAL_PIXEL_FORMAT_RGB_888:
-            size = alignedw * alignedh * 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:
-        case HAL_PIXEL_FORMAT_RAW16:
-        case HAL_PIXEL_FORMAT_Y16:
-            size = alignedw * alignedh * 2;
-            break;
-        case HAL_PIXEL_FORMAT_RAW12:
-            size = ALIGN(alignedw * alignedh, 4096);
-            break;
-        case HAL_PIXEL_FORMAT_RAW10:
-            size = ALIGN(alignedw * alignedh, 4096);
-            break;
-        case HAL_PIXEL_FORMAT_RAW8:
-        case HAL_PIXEL_FORMAT_Y8:
-            size = alignedw * alignedh;
-            break;
-            // adreno formats
-        case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO:  // NV21
-            size  = ALIGN(alignedw*alignedh, 4096);
-            size += ALIGN(2 * ALIGN(width/2, 32) * ALIGN(height/2, 32), 4096);
-            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, 8192);
-            size += ALIGN( alignedw * ALIGN(height/2, 32), 8192);
-            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)4096);
-            break;
-        case HAL_PIXEL_FORMAT_YCbCr_420_SP:
-        case HAL_PIXEL_FORMAT_YCrCb_420_SP:
-            size = ALIGN((alignedw*alignedh) + (alignedw* alignedh)/2 + 1, 4096);
-            break;
-        case HAL_PIXEL_FORMAT_YCbCr_420_P010:
-            size = ALIGN((alignedw * alignedh * 2) + (alignedw * alignedh) + 1, 4096);
-            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, 4096);
-            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 format HAL_PIXEL_FORMAT_BLOB \
-                      must have height==1 ", __FUNCTION__);
-                return 0;
-            }
-            size = width;
-            break;
-        case HAL_PIXEL_FORMAT_NV21_ZSL:
-            size = ALIGN((alignedw*alignedh) + (alignedw* alignedh)/2, 4096);
-            break;
-        case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_4x4_KHR:
-        case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_5x4_KHR:
-        case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_5x5_KHR:
-        case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_6x5_KHR:
-        case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_6x6_KHR:
-        case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x5_KHR:
-        case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x6_KHR:
-        case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x8_KHR:
-        case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x5_KHR:
-        case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x6_KHR:
-        case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x8_KHR:
-        case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x10_KHR:
-        case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_12x10_KHR:
-        case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_12x12_KHR:
-        case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR:
-        case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR:
-        case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR:
-        case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR:
-        case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR:
-        case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR:
-        case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR:
-        case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR:
-        case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR:
-        case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR:
-        case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR:
-        case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR:
-        case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR:
-        case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR:
-            size = alignedw * alignedh * ASTC_BLOCK_SIZE;
-            break;
-        default:
-            ALOGE("%s: Unrecognized pixel format: 0x%x", __FUNCTION__, format);
-            return 0;
-    }
-    return size;
-}
-
-unsigned int getBufferSizeAndDimensions(int width, int height, int format,
-        int& alignedw, int &alignedh)
-{
-    unsigned int size;
-
-    AdrenoMemInfo::getInstance().getAlignedWidthAndHeight(width,
-            height,
-            format,
-            0,
-            alignedw,
-            alignedh);
-
-    size = getSize(format, width, height, 0 /* usage */, alignedw, alignedh);
-
-    return size;
-}
-
-
-unsigned int getBufferSizeAndDimensions(int width, int height, int format,
-        int usage, int& alignedw, int &alignedh)
-{
-    unsigned int size;
-
-    AdrenoMemInfo::getInstance().getAlignedWidthAndHeight(width,
-            height,
-            format,
-            usage,
-            alignedw,
-            alignedh);
-
-    size = getSize(format, width, height, usage, alignedw, alignedh);
-
-    return size;
-}
-
-void getYuvUbwcSPPlaneInfo(uint64_t base, int width, int 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, width);
-    y_meta_height = VENUS_Y_META_SCANLINES(color_format, height);
-    y_meta_size = ALIGN((y_meta_stride * y_meta_height), alignment);
-
-    y_stride = VENUS_Y_STRIDE(color_format, width);
-    y_height = VENUS_Y_SCANLINES(color_format, height);
-    y_size = ALIGN((y_stride * y_height), alignment);
-
-    c_meta_stride = VENUS_UV_META_STRIDE(color_format, width);
-    c_meta_height = VENUS_UV_META_SCANLINES(color_format, height);
-    c_meta_size = ALIGN((c_meta_stride * c_meta_height), alignment);
-
-    ycbcr->y  = (void*)(base + y_meta_size);
-    ycbcr->cb = (void*)(base + y_meta_size + y_size + c_meta_size);
-    ycbcr->cr = (void*)(base + y_meta_size + y_size +
-                        c_meta_size + 1);
-    ycbcr->ystride = y_stride;
-    ycbcr->cstride = VENUS_UV_STRIDE(color_format, width);
-}
-
-void getYuvSPPlaneInfo(uint64_t base, int width, int height, int bpp,
-                       struct android_ycbcr* ycbcr)
-{
-    unsigned int ystride, cstride;
-
-    ystride = cstride = width * bpp;
-    ycbcr->y  = (void*)base;
-    ycbcr->cb = (void*)(base + ystride * height);
-    ycbcr->cr = (void*)(base + ystride * height + 1);
-    ycbcr->ystride = ystride;
-    ycbcr->cstride = cstride;
-    ycbcr->chroma_step = 2 * bpp;
-}
-
-int getYUVPlaneInfo(private_handle_t* hnd, struct android_ycbcr* ycbcr)
-{
-    int err = 0;
-    int width = hnd->width;
-    int height = hnd->height;
-    int format = hnd->format;
-
-    unsigned int ystride, cstride;
-
-    memset(ycbcr->reserved, 0, sizeof(ycbcr->reserved));
-    MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
-
-    // Check if UBWC buffer has been rendered in linear format.
-    if (metadata && (metadata->operation & LINEAR_FORMAT)) {
-        format = metadata->linearFormat;
-    }
-
-    // Check metadata if the geometry has been updated.
-    if(metadata && metadata->operation & UPDATE_BUFFER_GEOMETRY) {
-        int usage = 0;
-
-        if (hnd->flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED) {
-            usage = GRALLOC_USAGE_PRIVATE_ALLOC_UBWC;
-        }
-
-        AdrenoMemInfo::getInstance().getAlignedWidthAndHeight(metadata->bufferDim.sliceWidth,
-                   metadata->bufferDim.sliceHeight, format, usage, width, height);
-    }
-
-    // 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_P010:
-            getYuvSPPlaneInfo(hnd->base, width, height, 2, ycbcr);
-        break;
-
-        case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
-            getYuvUbwcSPPlaneInfo(hnd->base, width, height,
-                                  COLOR_FMT_NV12_UBWC, ycbcr);
-            ycbcr->chroma_step = 2;
-        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_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_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  = (void*)hnd->base;
-            ycbcr->cr = (void*)(hnd->base + ystride * height);
-            ycbcr->cb = (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  = (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;
-
-}
-
-
-
-// Allocate buffer from width, height and format into a
-// private_handle_t. It is the responsibility of the caller
-// to free the buffer using the free_buffer function
-int alloc_buffer(private_handle_t **pHnd, int w, int h, int format, int usage)
-{
-    alloc_data data;
-    int alignedw, alignedh;
-    gralloc::IAllocController* sAlloc =
-        gralloc::IAllocController::getInstance();
-    data.base = 0;
-    data.fd = -1;
-    data.offset = 0;
-    data.size = getBufferSizeAndDimensions(w, h, format, usage, alignedw,
-                                            alignedh);
-
-    data.align = getpagesize();
-    data.uncached = useUncached(usage);
-    int allocFlags = usage;
-
-    int err = sAlloc->allocate(data, allocFlags);
-    if (0 != err) {
-        ALOGE("%s: allocate failed", __FUNCTION__);
-        return -ENOMEM;
-    }
-
-    if(isUBwcEnabled(format, usage)) {
-      data.allocType |= private_handle_t::PRIV_FLAGS_UBWC_ALIGNED;
-    }
-
-    private_handle_t* hnd = new private_handle_t(data.fd, data.size,
-                                                 data.allocType, 0, format,
-                                                 alignedw, alignedh, -1, 0, 0, w, h);
-    hnd->base = (uint64_t) data.base;
-    hnd->offset = data.offset;
-    hnd->gpuaddr = 0;
-    *pHnd = hnd;
-    return 0;
-}
-
-void free_buffer(private_handle_t *hnd)
-{
-    gralloc::IAllocController* sAlloc =
-        gralloc::IAllocController::getInstance();
-    if (hnd && hnd->fd > 0) {
-        IMemAlloc* memalloc = sAlloc->getAllocator(hnd->flags);
-        memalloc->free_buffer((void*)hnd->base, hnd->size, hnd->offset, hnd->fd);
-    }
-    if(hnd)
-        delete hnd;
-
-}
-
-// UBWC helper functions
-static bool isUBwcFormat(int format)
-{
-    // Explicitly defined UBWC formats
-    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;
-    }
-}
-
-static bool isUBwcSupported(int format)
-{
-    if (MDPCapabilityInfo::getInstance().isUBwcSupportedByMDP()) {
-        // 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, int usage)
-{
-    // Allow UBWC, if client is using an explicitly defined UBWC pixel format.
-    if (isUBwcFormat(format))
-        return true;
-
-    if ((usage & GRALLOC_USAGE_HW_VIDEO_ENCODER) &&
-        gralloc::IAllocController::getInstance()->isDisableUBWCForEncoder()) {
-            return false;
-    }
-
-    // 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 & (GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_HW_RENDER)) {
-            enable = AdrenoMemInfo::getInstance().isUBWCSupportedByGPU(format);
-        }
-        // Allow UBWC, only if CPU usage flags are not set
-        if (enable && !(usage & (GRALLOC_USAGE_SW_READ_MASK |
-            GRALLOC_USAGE_SW_WRITE_MASK))) {
-            return true;
-        }
-    }
-    return false;
-}
-
-static void getYuvUBwcWidthHeight(int width, int height, int format,
-        int& aligned_w, 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;
-    }
-}
-
-static void getRgbUBwcBlockSize(int 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;
-    }
-}
-
-static unsigned int getRgbUBwcMetaBufferSize(int width, int height, int 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 = ALIGN((meta_width * meta_height), 4096);
-    return size;
-}
-
-static unsigned int getUBwcSize(int width, int height, int format,
-        const int alignedw, const int alignedh) {
-
-    unsigned int size = 0;
-    switch (format) {
-        case HAL_PIXEL_FORMAT_BGR_565:
-            size = alignedw * alignedh * 2;
-            size += getRgbUBwcMetaBufferSize(width, height, 2);
-            break;
-        case HAL_PIXEL_FORMAT_RGBA_8888:
-        case HAL_PIXEL_FORMAT_RGBX_8888:
-        case HAL_PIXEL_FORMAT_RGBA_1010102:
-        case HAL_PIXEL_FORMAT_RGBX_1010102:
-            size = alignedw * alignedh * 4;
-            size += getRgbUBwcMetaBufferSize(width, height, 4);
-            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
-    if (!(hnd->flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED)) {
-        *rgb_data = (void*)hnd->base;
-        return err;
-    }
-
-    // Ubwc buffers
-    unsigned int meta_size = 0;
-    switch (hnd->format) {
-        case HAL_PIXEL_FORMAT_BGR_565:
-            meta_size = getRgbUBwcMetaBufferSize(hnd->width, hnd->height, 2);
-            break;
-        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, 4);
-            break;
-        default:
-            ALOGE("%s:Unsupported RGB format: 0x%x", __FUNCTION__, hnd->format);
-            err = -EINVAL;
-            break;
-    }
-
-    *rgb_data = (void*)(hnd->base + meta_size);
-    return err;
-}
-
-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 yuvInfo = {};
-    *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] = hnd->width * 2;
-            break;
-        case HAL_PIXEL_FORMAT_RGB_888:
-            stride[0] = 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] = hnd->width * 4;
-            break;
-    }
-
-    // Format is RGB
-    if (stride[0]) {
-        return 0;
-    }
-
-    (*num_planes)++;
-    int ret = getYUVPlaneInfo(hnd, &yuvInfo);
-    if (ret < 0) {
-        ALOGE("%s failed", __FUNCTION__);
-        return ret;
-    }
-
-    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:
-            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 %s", __FUNCTION__,
-                    qdutils::GetHALPixelFormatString(hnd->format));
-            ret = -EINVAL;
-    }
-
-    if (hnd->flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED) {
-        std::fill(offset, offset + 4, 0);
-    }
-
-    return 0;
-}
diff --git a/libgralloc/gpu.cpp b/libgralloc/gpu.cpp
deleted file mode 100644
index c57ff90..0000000
--- a/libgralloc/gpu.cpp
+++ /dev/null
@@ -1,423 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- * Copyright (c) 2011-2014,2017 The Linux Foundation. All rights reserved.
- *
- * 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 <limits.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <cutils/properties.h>
-#include <sys/mman.h>
-#include <linux/msm_ion.h>
-#include <qdMetaData.h>
-#include <algorithm>
-
-#include "gr.h"
-#include "gpu.h"
-#include "memalloc.h"
-#include "alloc_controller.h"
-
-using namespace gralloc;
-
-gpu_context_t::gpu_context_t(const private_module_t* module,
-                             IAllocController* alloc_ctrl ) :
-    mAllocCtrl(alloc_ctrl)
-{
-    // Zero out the alloc_device_t
-    memset(static_cast<alloc_device_t*>(this), 0, sizeof(alloc_device_t));
-
-    // Initialize the procs
-    common.tag     = HARDWARE_DEVICE_TAG;
-    common.version = 0;
-    common.module  = const_cast<hw_module_t*>(&module->base.common);
-    common.close   = gralloc_close;
-    alloc          = gralloc_alloc;
-    free           = gralloc_free;
-
-}
-
-int gpu_context_t::gralloc_alloc_buffer(unsigned int size, int usage,
-                                        buffer_handle_t* pHandle, int bufferType,
-                                        int format, int width, int height)
-{
-    int err = 0;
-    int flags = 0;
-    int alignedw = 0;
-    int alignedh = 0;
-
-    AdrenoMemInfo::getInstance().getAlignedWidthAndHeight(width,
-            height,
-            format,
-            usage,
-            alignedw,
-            alignedh);
-
-    size = roundUpToPageSize(size);
-    alloc_data data;
-    data.offset = 0;
-    data.fd = -1;
-    data.base = 0;
-    if(format == HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED)
-        data.align = 8192;
-    else
-        data.align = getpagesize();
-
-    if (usage & GRALLOC_USAGE_PROTECTED) {
-            if ((usage & GRALLOC_USAGE_PRIVATE_SECURE_DISPLAY) ||
-                (usage & GRALLOC_USAGE_HW_CAMERA_MASK)) {
-                /* The alignment here reflects qsee mmu V7L/V8L requirement */
-                data.align = SZ_2M;
-            } else {
-                data.align = SECURE_ALIGN;
-            }
-        size = ALIGN(size, data.align);
-    }
-
-    data.size = size;
-    data.pHandle = (uintptr_t) pHandle;
-    err = mAllocCtrl->allocate(data, usage);
-
-    if (!err) {
-        /* allocate memory for enhancement data */
-        alloc_data eData;
-        eData.fd = -1;
-        eData.base = 0;
-        eData.offset = 0;
-        eData.size = ROUND_UP_PAGESIZE(sizeof(MetaData_t));
-        eData.pHandle = data.pHandle;
-        eData.align = getpagesize();
-        int eDataUsage = 0;
-        int eDataErr = mAllocCtrl->allocate(eData, eDataUsage);
-        ALOGE_IF(eDataErr, "gralloc failed for eDataErr=%s",
-                                          strerror(-eDataErr));
-
-        if (usage & GRALLOC_USAGE_PRIVATE_EXTERNAL_ONLY) {
-            flags |= private_handle_t::PRIV_FLAGS_EXTERNAL_ONLY;
-        }
-
-        if (usage & GRALLOC_USAGE_PRIVATE_INTERNAL_ONLY) {
-            flags |= private_handle_t::PRIV_FLAGS_INTERNAL_ONLY;
-        }
-
-        if (usage & GRALLOC_USAGE_HW_VIDEO_ENCODER ) {
-            flags |= private_handle_t::PRIV_FLAGS_VIDEO_ENCODER;
-        }
-
-        if (usage & GRALLOC_USAGE_HW_CAMERA_WRITE) {
-            flags |= private_handle_t::PRIV_FLAGS_CAMERA_WRITE;
-        }
-
-        if (usage & GRALLOC_USAGE_HW_CAMERA_READ) {
-            flags |= private_handle_t::PRIV_FLAGS_CAMERA_READ;
-        }
-
-        if (usage & GRALLOC_USAGE_HW_COMPOSER) {
-            flags |= private_handle_t::PRIV_FLAGS_HW_COMPOSER;
-        }
-
-        if (usage & GRALLOC_USAGE_HW_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 & (GRALLOC_USAGE_SW_READ_MASK | GRALLOC_USAGE_SW_WRITE_MASK)) {
-            flags |= private_handle_t::PRIV_FLAGS_CPU_RENDERED;
-        }
-
-        if (usage & (GRALLOC_USAGE_HW_VIDEO_ENCODER |
-                GRALLOC_USAGE_HW_CAMERA_WRITE |
-                GRALLOC_USAGE_HW_RENDER |
-                GRALLOC_USAGE_HW_FB)) {
-            flags |= private_handle_t::PRIV_FLAGS_NON_CPU_WRITER;
-        }
-
-        if(usage & GRALLOC_USAGE_HW_COMPOSER) {
-            flags |= private_handle_t::PRIV_FLAGS_DISP_CONSUMER;
-        }
-
-        if(false == data.uncached) {
-            flags |= private_handle_t::PRIV_FLAGS_CACHED;
-        }
-
-        flags |= data.allocType;
-        uint64_t eBaseAddr = (uint64_t)(eData.base) + eData.offset;
-        private_handle_t *hnd = new private_handle_t(data.fd, size, flags,
-                bufferType, format, alignedw, alignedh,
-                eData.fd, eData.offset, eBaseAddr, width, height);
-
-        hnd->offset = data.offset;
-        hnd->base = (uint64_t)(data.base) + data.offset;
-        hnd->gpuaddr = 0;
-        ColorSpace_t colorSpace = ITU_R_601;
-        setMetaData(hnd, UPDATE_COLOR_SPACE, (void*) &colorSpace);
-        *pHandle = hnd;
-    }
-
-    ALOGE_IF(err, "gralloc failed err=%s", strerror(-err));
-    return err;
-}
-
-void gpu_context_t::getGrallocInformationFromFormat(int inputFormat,
-                                                    int *bufferType)
-{
-    *bufferType = BUFFER_TYPE_VIDEO;
-
-    if (isUncompressedRgbFormat(inputFormat) == TRUE) {
-        // RGB formats
-        *bufferType = BUFFER_TYPE_UI;
-    }
-}
-
-int gpu_context_t::gralloc_alloc_framebuffer_locked(int usage,
-                                                    buffer_handle_t* pHandle)
-{
-    private_module_t* m = reinterpret_cast<private_module_t*>(common.module);
-
-    // This allocation will only happen when gralloc is in fb mode
-
-    if (m->framebuffer == NULL) {
-        ALOGE("%s: Invalid framebuffer", __FUNCTION__);
-        return -EINVAL;
-    }
-
-    const unsigned int bufferMask = m->bufferMask;
-    const uint32_t numBuffers = m->numBuffers;
-    unsigned int bufferSize = m->finfo.line_length * m->info.yres;
-
-    //adreno needs FB size to be page aligned
-    bufferSize = roundUpToPageSize(bufferSize);
-
-    if (numBuffers == 1) {
-        // If we have only one buffer, we never use page-flipping. Instead,
-        // we return a regular buffer which will be memcpy'ed to the main
-        // screen when post is called.
-        int newUsage = (usage & ~GRALLOC_USAGE_HW_FB) | GRALLOC_USAGE_HW_2D;
-        return gralloc_alloc_buffer(bufferSize, newUsage, pHandle, BUFFER_TYPE_UI,
-                                    m->fbFormat, m->info.xres, m->info.yres);
-    }
-
-    if (bufferMask >= ((1LU<<numBuffers)-1)) {
-        // We ran out of buffers.
-        return -ENOMEM;
-    }
-
-    // create a "fake" handle for it
-    uint64_t vaddr = uint64_t(m->framebuffer->base);
-    // As GPU needs ION FD, the private handle is created
-    // using ION fd and ION flags are set
-    private_handle_t* hnd = new private_handle_t(
-        dup(m->framebuffer->fd), bufferSize,
-        private_handle_t::PRIV_FLAGS_USES_ION |
-        private_handle_t::PRIV_FLAGS_FRAMEBUFFER,
-        BUFFER_TYPE_UI, m->fbFormat, m->info.xres,
-        m->info.yres);
-
-    // find a free slot
-    for (uint32_t i=0 ; i<numBuffers ; i++) {
-        if ((bufferMask & (1LU<<i)) == 0) {
-            m->bufferMask |= (uint32_t)(1LU<<i);
-            break;
-        }
-        vaddr += bufferSize;
-    }
-    hnd->base = vaddr;
-    hnd->offset = (unsigned int)(vaddr - m->framebuffer->base);
-    *pHandle = hnd;
-    return 0;
-}
-
-
-int gpu_context_t::gralloc_alloc_framebuffer(int usage,
-                                             buffer_handle_t* pHandle)
-{
-    private_module_t* m = reinterpret_cast<private_module_t*>(common.module);
-    pthread_mutex_lock(&m->lock);
-    int err = gralloc_alloc_framebuffer_locked(usage, pHandle);
-    pthread_mutex_unlock(&m->lock);
-    return err;
-}
-
-int gpu_context_t::alloc_impl(int w, int h, int format, int usage,
-                              buffer_handle_t* pHandle, int* pStride,
-                              unsigned int bufferSize) {
-    if (!pHandle || !pStride)
-        return -EINVAL;
-
-    unsigned int size;
-    int alignedw, alignedh;
-    int grallocFormat = format;
-    int bufferType;
-
-    //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)
-            grallocFormat = HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC;
-        else if(usage & GRALLOC_USAGE_HW_VIDEO_ENCODER) {
-            if(MDPCapabilityInfo::getInstance().isWBUBWCSupportedByMDP() &&
-               !IAllocController::getInstance()->isDisableUBWCForEncoder() &&
-               usage & GRALLOC_USAGE_HW_COMPOSER)
-              grallocFormat = HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC;
-            else
-              grallocFormat = HAL_PIXEL_FORMAT_NV12_ENCODEABLE; //NV12
-        } else if((usage & GRALLOC_USAGE_HW_CAMERA_MASK)
-                == GRALLOC_USAGE_HW_CAMERA_ZSL)
-            grallocFormat = HAL_PIXEL_FORMAT_NV21_ZSL; //NV21 ZSL
-        else if(usage & GRALLOC_USAGE_HW_CAMERA_READ)
-            grallocFormat = HAL_PIXEL_FORMAT_YCrCb_420_SP; //NV21
-        else if(usage & GRALLOC_USAGE_HW_CAMERA_WRITE) {
-           if (format == HAL_PIXEL_FORMAT_YCbCr_420_888) {
-               grallocFormat = HAL_PIXEL_FORMAT_NV21_ZSL; //NV21
-           } else {
-               grallocFormat = HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS; //NV12 preview
-           }
-        } else if(usage & GRALLOC_USAGE_HW_COMPOSER)
-            //XXX: If we still haven't set a format, default to RGBA8888
-            grallocFormat = 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
-            grallocFormat = HAL_PIXEL_FORMAT_NV21_ZSL;
-        }
-    }
-
-    bool useFbMem = false;
-    char property[PROPERTY_VALUE_MAX];
-    char isUBWC[PROPERTY_VALUE_MAX];
-    if (usage & GRALLOC_USAGE_HW_FB) {
-        if ((property_get("debug.gralloc.map_fb_memory", property, NULL) > 0) &&
-            (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
-            (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
-            useFbMem = true;
-        } else {
-            usage &= ~GRALLOC_USAGE_PRIVATE_ALLOC_UBWC;
-            if (property_get("debug.gralloc.enable_fb_ubwc", isUBWC, NULL) > 0){
-                if ((!strncmp(isUBWC, "1", PROPERTY_VALUE_MAX)) ||
-                    (!strncasecmp(isUBWC, "true", PROPERTY_VALUE_MAX))) {
-                    // Allocate UBWC aligned framebuffer
-                    usage |= GRALLOC_USAGE_PRIVATE_ALLOC_UBWC;
-                }
-            }
-        }
-    }
-
-    getGrallocInformationFromFormat(grallocFormat, &bufferType);
-    size = getBufferSizeAndDimensions(w, h, grallocFormat, usage, alignedw,
-                   alignedh);
-
-    if ((unsigned int)size <= 0)
-        return -EINVAL;
-    size = (bufferSize >= size)? bufferSize : size;
-
-    int err = 0;
-    if(useFbMem) {
-        err = gralloc_alloc_framebuffer(usage, pHandle);
-    } else {
-        err = gralloc_alloc_buffer(size, usage, pHandle, bufferType,
-                                   grallocFormat, w, h);
-    }
-
-    if (err < 0) {
-        return err;
-    }
-
-    *pStride = alignedw;
-    return 0;
-}
-
-int gpu_context_t::free_impl(private_handle_t const* hnd) {
-    private_module_t* m = reinterpret_cast<private_module_t*>(common.module);
-    if (hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER) {
-        const unsigned int bufferSize = m->finfo.line_length * m->info.yres;
-        unsigned int index = (unsigned int) ((hnd->base - m->framebuffer->base)
-                / bufferSize);
-        m->bufferMask &= (uint32_t)~(1LU<<index);
-    } else {
-
-        terminateBuffer(&m->base, const_cast<private_handle_t*>(hnd));
-        IMemAlloc* memalloc = mAllocCtrl->getAllocator(hnd->flags);
-        int err = memalloc->free_buffer((void*)hnd->base, hnd->size,
-                                        hnd->offset, hnd->fd);
-        if(err)
-            return err;
-        // free the metadata space
-        unsigned int size = ROUND_UP_PAGESIZE(sizeof(MetaData_t));
-        err = memalloc->free_buffer((void*)hnd->base_metadata,
-                                    size, hnd->offset_metadata,
-                                    hnd->fd_metadata);
-        if (err)
-            return err;
-    }
-
-    delete hnd;
-    return 0;
-}
-
-int gpu_context_t::gralloc_alloc(alloc_device_t* dev, int w, int h, int format,
-                                 int usage, buffer_handle_t* pHandle,
-                                 int* pStride)
-{
-    if (!dev) {
-        return -EINVAL;
-    }
-    gpu_context_t* gpu = reinterpret_cast<gpu_context_t*>(dev);
-    return gpu->alloc_impl(w, h, format, usage, pHandle, pStride, 0);
-}
-int gpu_context_t::gralloc_alloc_size(alloc_device_t* dev, int w, int h,
-                                      int format, int usage,
-                                      buffer_handle_t* pHandle, int* pStride,
-                                      int bufferSize)
-{
-    if (!dev) {
-        return -EINVAL;
-    }
-    gpu_context_t* gpu = reinterpret_cast<gpu_context_t*>(dev);
-    return gpu->alloc_impl(w, h, format, usage, pHandle, pStride, bufferSize);
-}
-
-
-int gpu_context_t::gralloc_free(alloc_device_t* dev,
-                                buffer_handle_t handle)
-{
-    if (private_handle_t::validate(handle) < 0)
-        return -EINVAL;
-
-    private_handle_t const* hnd = reinterpret_cast<private_handle_t const*>(handle);
-    gpu_context_t* gpu = reinterpret_cast<gpu_context_t*>(dev);
-    return gpu->free_impl(hnd);
-}
-
-/*****************************************************************************/
-
-int gpu_context_t::gralloc_close(struct hw_device_t *dev)
-{
-    gpu_context_t* ctx = reinterpret_cast<gpu_context_t*>(dev);
-    if (ctx) {
-        /* TODO: keep a list of all buffer_handle_t created, and free them
-         * all here.
-         */
-        delete ctx;
-    }
-    return 0;
-}
-
diff --git a/libgralloc/gr.h b/libgralloc/gr.h
deleted file mode 100644
index dad4a38..0000000
--- a/libgralloc/gr.h
+++ /dev/null
@@ -1,218 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- * Copyright (c) 2011 - 2017, The Linux Foundation. All rights reserved.
- *
- * 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_H_
-#define GR_H_
-
-#include <stdint.h>
-#include <limits.h>
-#include <sys/cdefs.h>
-#include <hardware/gralloc.h>
-#include <pthread.h>
-#include <errno.h>
-#include <unistd.h>
-
-#include <cutils/native_handle.h>
-#include <utils/Singleton.h>
-#include "adreno_utils.h"
-
-/*****************************************************************************/
-
-struct private_module_t;
-struct private_handle_t;
-
-inline unsigned int roundUpToPageSize(unsigned int x) {
-    return (x + (getpagesize()-1)) & ~(getpagesize()-1);
-}
-
-template <class Type>
-inline Type ALIGN(Type x, Type align) {
-    return (x + align-1) & ~(align-1);
-}
-
-#define FALSE 0
-#define TRUE  1
-
-int mapFrameBufferLocked(struct private_module_t* module);
-int terminateBuffer(gralloc_module_t const* module, private_handle_t* hnd);
-unsigned int getBufferSizeAndDimensions(int width, int height, int format,
-        int usage, int& alignedw, int &alignedh);
-unsigned int getBufferSizeAndDimensions(int width, int height, int format,
-        int& alignedw, int &alignedh);
-
-int decideBufferHandlingMechanism(int format, const char *compositionUsed,
-                                  int hasBlitEngine, int *needConversion,
-                                  int *useBufferDirectly);
-
-// Allocate buffer from width, height, format into a private_handle_t
-// It is the responsibility of the caller to free the buffer
-int alloc_buffer(private_handle_t **pHnd, int w, int h, int format, int usage);
-void free_buffer(private_handle_t *hnd);
-int getYUVPlaneInfo(private_handle_t* pHnd, struct android_ycbcr* ycbcr);
-int getRgbDataAddress(private_handle_t* pHnd, void** rgb_data);
-
-// To query if UBWC is enabled, based on format and usage flags
-bool isUBwcEnabled(int format, int usage);
-
-// Function to check if the format is an RGB format
-bool isUncompressedRgbFormat(int format);
-
-// Returns number of planes, stride and offset of each plane for a given w,h,f
-int getBufferLayout(private_handle_t *hnd, uint32_t stride[4],
-        uint32_t offset[4], uint32_t *num_planes);
-/*****************************************************************************/
-
-class Locker {
-    pthread_mutex_t mutex;
-    pthread_cond_t cond;
-    public:
-    class Autolock {
-        Locker& locker;
-        public:
-        inline Autolock(Locker& locker) : locker(locker) {  locker.lock(); }
-        inline ~Autolock() { locker.unlock(); }
-    };
-    inline Locker()        {
-        pthread_mutex_init(&mutex, 0);
-        pthread_cond_init(&cond, 0);
-    }
-    inline ~Locker()       {
-        pthread_mutex_destroy(&mutex);
-        pthread_cond_destroy(&cond);
-    }
-    inline void lock()     { pthread_mutex_lock(&mutex); }
-    inline void wait()     { pthread_cond_wait(&cond, &mutex); }
-    inline void unlock()   { pthread_mutex_unlock(&mutex); }
-    inline void signal()   { pthread_cond_signal(&cond); }
-};
-
-
-class AdrenoMemInfo : public android::Singleton <AdrenoMemInfo>
-{
-    public:
-    AdrenoMemInfo();
-
-    ~AdrenoMemInfo();
-
-    /*
-     * 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, int& aligned_w, int& aligned_h);
-
-    /*
-     * Function to compute aligned width and aligned height based on
-     * private handle
-     *
-     * @return aligned width, aligned height
-     */
-    void getAlignedWidthAndHeight(const private_handle_t *hnd, int& aligned_w, 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 getGpuAlignedWidthHeight(int width, int height, int format,
-                            int tileEnabled, int& alignedw, int &alignedh);
-
-    /*
-     * Function to compute unaligned width and unaligned height based on
-     * private handle
-     *
-     * @return unaligned width, unaligned height
-     */
-    void getUnalignedWidthAndHeight(const private_handle_t *hnd, int& unaligned_w,
-                            int& unaligned_h);
-    /*
-     * Function to query whether GPU supports UBWC for given HAL format
-     * @return > 0 : supported
-     *           0 : not supported
-     */
-    int isUBWCSupportedByGPU(int format);
-
-    /*
-     * Function to get the corresponding Adreno format for given HAL format
-     */
-    ADRENOPIXELFORMAT getGpuPixelFormat(int hal_format);
-
-    private:
-        // Overriding flag to disable UBWC alloc for graphics stack
-        int  gfx_ubwc_disable;
-        // Pointer to the padding library.
-        void *libadreno_utils;
-
-        // 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);
-
-        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);
-
-        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);
-
-        int (*LINK_adreno_isUBWCSupportedByGpu) (ADRENOPIXELFORMAT format);
-
-        unsigned int (*LINK_adreno_get_gpu_pixel_alignment) ();
-};
-
-
-class MDPCapabilityInfo : public android::Singleton <MDPCapabilityInfo>
-{
-    int isUBwcSupported = 0;
-    int isWBUBWCSupported = 0;
-
-    public:
-        MDPCapabilityInfo();
-        /*
-        * Function to return whether MDP supports UBWC feature
-        *
-        * @return  1 : supported
-        *          0 : not supported
-        */
-        int isUBwcSupportedByMDP() { return isUBwcSupported; }
-        /*
-        * Function to return whether MDP WB block outputs UBWC format
-        *
-        * @return  1 : supported
-        *          0 : not supported
-        */
-        int isWBUBWCSupportedByMDP() { return isWBUBWCSupported; }
-};
-
-#endif /* GR_H_ */
diff --git a/libgralloc1/gralloc_priv.h b/libgralloc1/gralloc_priv.h
index d8dfbf3..87604c6 100644
--- a/libgralloc1/gralloc_priv.h
+++ b/libgralloc1/gralloc_priv.h
@@ -65,7 +65,7 @@
 #define GRALLOC1_CONSUMER_USAGE_PRIVATE_WFD            0x00200000
 
 /* This flag is used for SECURE display usecase */
-#define GRALLOC1_CONSUMER_USAGE_PRIVATE_SECURE_DISPLAY 0x00800000
+#define GRALLOC1_CONSUMER_USAGE_PRIVATE_SECURE_DISPLAY 0x01000000
 
 /* Unused flag */
 #define GRALLOC1_USAGE_PRIVATE_UNUSED1  0x04000000
diff --git a/sdm/include/private/color_params.h b/sdm/include/private/color_params.h
index 08895ee..14ec40f 100644
--- a/sdm/include/private/color_params.h
+++ b/sdm/include/private/color_params.h
@@ -157,6 +157,7 @@
   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)); }
@@ -327,6 +328,29 @@
   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;
diff --git a/sdm/include/private/hw_info_types.h b/sdm/include/private/hw_info_types.h
index 8cf1922..752d0c4 100644
--- a/sdm/include/private/hw_info_types.h
+++ b/sdm/include/private/hw_info_types.h
@@ -157,6 +157,7 @@
   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;
@@ -460,11 +461,21 @@
   void Reset() { *this = HWPipeInfo(); }
 };
 
+struct HWSolidfillStage {
+  uint32_t z_order = kMaxSDELayers;
+  uint32_t color = 0;
+  LayerRect roi = {};
+  bool is_exclusion_rect = false;
+};
+
 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;
 
   void Reset() { *this = HWLayerConfig(); }
 };
diff --git a/sdm/include/utils/debug.h b/sdm/include/utils/debug.h
index 2bd6a5a..d5974d9 100644
--- a/sdm/include/utils/debug.h
+++ b/sdm/include/utils/debug.h
@@ -63,7 +63,7 @@
   }
   static inline DebugHandler* Get() { return debug_.debug_handler_; }
   static int GetSimulationFlag();
-  static int GetHDMIResolution();
+  static bool GetExternalResolution(char *val);
   static void GetIdleTimeoutMs(uint32_t *active_ms, uint32_t *inactive_ms);
   static int GetBootAnimLayerCount();
   static bool IsRotatorDownScaleDisabled();
@@ -78,6 +78,7 @@
   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();
diff --git a/sdm/libs/core/Android.mk b/sdm/libs/core/Android.mk
index 991cfac..cf3543c 100644
--- a/sdm/libs/core/Android.mk
+++ b/sdm/libs/core/Android.mk
@@ -13,7 +13,7 @@
 LOCAL_SHARED_LIBRARIES        := libdl libsdmutils
 
 ifneq ($(TARGET_IS_HEADLESS), true)
-    LOCAL_CFLAGS              += -DCOMPILE_DRM -isystem external/libdrm
+    LOCAL_CFLAGS              += -isystem external/libdrm
     LOCAL_SHARED_LIBRARIES    += libdrm libdrmutils
     LOCAL_HW_INTF_PATH_2      := drm
 endif
@@ -49,7 +49,7 @@
 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_hdmi_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 \
diff --git a/sdm/libs/core/display_hdmi.cpp b/sdm/libs/core/display_hdmi.cpp
index a6c5c47..2ea2ac2 100644
--- a/sdm/libs/core/display_hdmi.cpp
+++ b/sdm/libs/core/display_hdmi.cpp
@@ -185,37 +185,33 @@
       break;
     }
   }
-  if (index < num_modes) {
-    best_index = UINT32(index);
-    for (size_t index = best_index + 1; index < num_modes; index ++) {
-      if (!attrib[index].s3d_config[s3d_mode])
-        continue;
 
-      // From the available configs, select the best
-      // Ex: 1920x1080@60Hz is better than 1920x1080@30 and 1920x1080@30 is better than 1280x720@60
+  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].x_pixels > attrib[best_index].x_pixels) {
+        if (attrib[index].vsync_period_ns < attrib[best_index].vsync_period_ns) {
           best_index = UINT32(index);
-        } else if (attrib[index].x_pixels == attrib[best_index].x_pixels) {
-          if (attrib[index].vsync_period_ns < attrib[best_index].vsync_period_ns) {
-            best_index = UINT32(index);
-          }
         }
       }
     }
-  } else {
-    DLOGW("%s, could not support S3D mode from EDID info. S3D mode is %d",
-          __FUNCTION__, s3d_mode);
   }
-
+  char val[kPropertyMax]={};
   // Used for changing HDMI Resolution - override the best with user set config
-  uint32_t user_config = UINT32(Debug::GetHDMIResolution());
+  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(user_config, &config_index);
+    DisplayError error = hw_intf_->GetConfigIndex(val, &config_index);
     if (error == kErrorNone)
       return config_index;
   }
diff --git a/sdm/libs/core/display_hdmi.h b/sdm/libs/core/display_hdmi.h
index dfee684..8248840 100644
--- a/sdm/libs/core/display_hdmi.h
+++ b/sdm/libs/core/display_hdmi.h
@@ -61,6 +61,7 @@
   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_;
diff --git a/sdm/libs/core/drm/hw_color_manager_drm.cpp b/sdm/libs/core/drm/hw_color_manager_drm.cpp
index 8c9eb24..2000f9a 100644
--- a/sdm/libs/core/drm/hw_color_manager_drm.cpp
+++ b/sdm/libs/core/drm/hw_color_manager_drm.cpp
@@ -48,6 +48,9 @@
 #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;
 #endif
 
 namespace sdm {
@@ -74,18 +77,28 @@
 
   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 kFeaturePaV2:
+        version = PPFeatureVersion::kSDEPaV17;
       break;
     case kFeatureDither:
+        version = PPFeatureVersion::kSDEDitherV17;
       break;
     case kFeatureGamut:
       if (feature.version == 1)
@@ -94,6 +107,7 @@
         version = PPFeatureVersion::kSDEGamutV4;
       break;
     case kFeaturePADither:
+        version = PPFeatureVersion::kSDEPADitherV17;
       break;
     default:
       break;
@@ -138,12 +152,151 @@
 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;
 }
 
@@ -200,18 +353,49 @@
 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::GetDrmPAV2(const PPFeatureInfo &in_data,
                                            DRMPPFeatureInfo *out_data) {
   DisplayError ret = kErrorNone;
+#ifdef PP_DRM_ENABLE
+  if (!out_data) {
+    DLOGE("Invalid input parameter for PA V2");
+    return kErrorParameters;
+  }
+
+  out_data->id = kPPFeaturesMax;
+  out_data->type = sde_drm::kPropBlob;
+  out_data->version = in_data.feature_version_;
+
+#endif
   return ret;
 }
 
 DisplayError HWColorManagerDrm::GetDrmDither(const PPFeatureInfo &in_data,
                                              DRMPPFeatureInfo *out_data) {
   DisplayError ret = kErrorNone;
+#ifdef PP_DRM_ENABLE
+  if (!out_data) {
+    DLOGE("Invalid input parameter for dither");
+    return kErrorParameters;
+  }
+
+  out_data->id = kPPFeaturesMax;
+  out_data->type = sde_drm::kPropBlob;
+  out_data->version = in_data.feature_version_;
+#endif
   return ret;
 }
 
@@ -294,6 +478,16 @@
 DisplayError HWColorManagerDrm::GetDrmPADither(const PPFeatureInfo &in_data,
                                                DRMPPFeatureInfo *out_data) {
   DisplayError ret = kErrorNone;
+#ifdef PP_DRM_ENABLE
+  if (!out_data) {
+    DLOGE("Invalid input parameter for PA dither");
+    return kErrorParameters;
+  }
+
+  out_data->id = kPPFeaturesMax;
+  out_data->type = sde_drm::kPropBlob;
+  out_data->version = in_data.feature_version_;
+#endif
   return ret;
 }
 
diff --git a/sdm/libs/core/drm/hw_color_manager_drm.h b/sdm/libs/core/drm/hw_color_manager_drm.h
index a10d00b..290c606 100644
--- a/sdm/libs/core/drm/hw_color_manager_drm.h
+++ b/sdm/libs/core/drm/hw_color_manager_drm.h
@@ -38,6 +38,8 @@
 
 namespace sdm {
 
+static const uint32_t kMaxPCCChanel = 3;
+
 class HWColorManagerDrm {
  public:
   static DisplayError (*GetDrmFeature[kMaxNumPPFeatures])(const PPFeatureInfo &in_data,
diff --git a/sdm/libs/core/drm/hw_device_drm.cpp b/sdm/libs/core/drm/hw_device_drm.cpp
index 29ac44e..1ed9042 100644
--- a/sdm/libs/core/drm/hw_device_drm.cpp
+++ b/sdm/libs/core/drm/hw_device_drm.cpp
@@ -444,6 +444,13 @@
        topology == DRMTopology::DUAL_LM_DSCMERGE);
   display_attributes_.h_total += display_attributes_.is_device_split ? h_blanking : 0;
 
+  // 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_.x_dpi = (FLOAT(mode.hdisplay) * 25.4f) / FLOAT(mm_width);
   display_attributes_.y_dpi = (FLOAT(mode.vdisplay) * 25.4f) / FLOAT(mm_height);
 
@@ -606,7 +613,7 @@
   return kErrorNotSupported;
 }
 
-DisplayError HWDeviceDRM::GetConfigIndex(uint32_t mode, uint32_t *index) {
+DisplayError HWDeviceDRM::GetConfigIndex(char *mode, uint32_t *index) {
   return kErrorNone;
 }
 
@@ -668,6 +675,8 @@
   HWQosData &qos_data = hw_layers->qos_data;
   DRMSecurityLevel crtc_security_level = DRMSecurityLevel::SECURE_NON_SECURE;
 
+  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;
@@ -703,6 +712,11 @@
     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) {
+      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];
@@ -769,6 +783,7 @@
     }
   }
 
+  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);
@@ -785,6 +800,28 @@
            qos_data.rot_clock_hz);
 }
 
+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;
+  solidfill.color = sf.color;
+  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();
 
diff --git a/sdm/libs/core/drm/hw_device_drm.h b/sdm/libs/core/drm/hw_device_drm.h
index e754cfa..965ff3b 100644
--- a/sdm/libs/core/drm/hw_device_drm.h
+++ b/sdm/libs/core/drm/hw_device_drm.h
@@ -65,7 +65,7 @@
   virtual DisplayError GetHWPanelInfo(HWPanelInfo *panel_info);
   virtual DisplayError SetDisplayAttributes(uint32_t index);
   virtual DisplayError SetDisplayAttributes(const HWDisplayAttributes &display_attributes);
-  virtual DisplayError GetConfigIndex(uint32_t mode, uint32_t *index);
+  virtual DisplayError GetConfigIndex(char *mode, uint32_t *index);
   virtual DisplayError PowerOn();
   virtual DisplayError PowerOff();
   virtual DisplayError Doze();
@@ -118,6 +118,8 @@
   void ResetDisplayParams();
   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, uint32_t *config);
   void SetRect(const LayerRect &source, sde_drm::DRMRect *target);
@@ -165,6 +167,7 @@
   HWResourceInfo hw_resource_ = {};
   HWPanelInfo hw_panel_info_ = {};
   HWDeviceType device_type_ = {};
+  HWScaleDRM *hw_scale_ = {};
   sde_drm::DRMManagerInterface *drm_mgr_intf_ = {};
   sde_drm::DRMAtomicReqInterface *drm_atomic_intf_ = {};
   sde_drm::DRMConnectorInfo connector_info_ = {};
@@ -175,7 +178,7 @@
   bool synchronous_commit_ = false;
   HWMixerAttributes mixer_attributes_ = {};
   std::string interface_str_ = "DSI";
-  HWScaleDRM *hw_scale_ = {};
+  std::vector<sde_drm::DRMSolidfillStage> solid_fills_ {};
 };
 
 }  // namespace sdm
diff --git a/sdm/libs/core/drm/hw_hdmi_drm.cpp b/sdm/libs/core/drm/hw_hdmi_drm.cpp
deleted file mode 100644
index 27419c7..0000000
--- a/sdm/libs/core/drm/hw_hdmi_drm.cpp
+++ /dev/null
@@ -1,163 +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 <drm_lib_loader.h>
-#include <drm_master.h>
-#include <drm_res_mgr.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <string.h>
-#include <utils/debug.h>
-#include <utils/sys.h>
-#include <utils/formats.h>
-
-#include <vector>
-#include <map>
-#include <utility>
-
-#include "hw_hdmi_drm.h"
-
-#define __CLASS__ "HWHDMIDRM"
-
-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;
-
-namespace sdm {
-
-HWHDMIDRM::HWHDMIDRM(BufferSyncHandler *buffer_sync_handler, BufferAllocator *buffer_allocator,
-                     HWInfoInterface *hw_info_intf)
-  : HWDeviceDRM(buffer_sync_handler, buffer_allocator, hw_info_intf),
-  active_config_index_(0) {
-  HWDeviceDRM::device_type_ = kDeviceHDMI;
-  HWDeviceDRM::device_name_ = "HDMI Display Device";
-}
-
-// TODO(user) : split function in base class and avoid code duplicacy
-// by using base implementation for this basic stuff
-DisplayError HWHDMIDRM::Init() {
-  DisplayError error = kErrorNone;
-
-  default_mode_ = (DRMLibLoader::GetInstance()->IsLoaded() == false);
-
-  if (!default_mode_) {
-    DRMMaster *drm_master = {};
-    int dev_fd = -1;
-    DRMMaster::GetInstance(&drm_master);
-    drm_master->GetHandle(&dev_fd);
-    DRMLibLoader::GetInstance()->FuncGetDRMManager()(dev_fd, &drm_mgr_intf_);
-    if (drm_mgr_intf_->RegisterDisplay(DRMDisplayType::TV, &token_)) {
-      DLOGE("RegisterDisplay failed");
-      return kErrorResources;
-    }
-
-    drm_mgr_intf_->CreateAtomicReq(token_, &drm_atomic_intf_);
-    drm_mgr_intf_->GetConnectorInfo(token_.conn_id, &connector_info_);
-    InitializeConfigs();
-    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 (drm_atomic_intf_->Commit(true /* synchronous */)) {
-      DLOGE("Setting up CRTC %d, Connector %d for %s failed", token_.crtc_id, token_.conn_id,
-            device_name_);
-      return kErrorResources;
-    }
-
-    // Reload connector info for updated info after 1st commit
-    drm_mgr_intf_->GetConnectorInfo(token_.conn_id, &connector_info_);
-    DLOGI("Setup CRTC %d, Connector %d for %s", token_.crtc_id, token_.conn_id, device_name_);
-  }
-
-  PopulateDisplayAttributes();
-  PopulateHWPanelInfo();
-  UpdateMixerAttributes();
-
-  return error;
-}
-
-DisplayError HWHDMIDRM::GetNumDisplayAttributes(uint32_t *count) {
-  *count = connector_info_.num_modes;
-  if (*count <= 0) {
-    return kErrorHardware;
-  }
-
-  return kErrorNone;
-}
-
-DisplayError HWHDMIDRM::GetActiveConfig(uint32_t *active_config_index) {
-  *active_config_index = active_config_index_;
-  return kErrorNone;
-}
-
-DisplayError HWHDMIDRM::SetDisplayAttributes(uint32_t index) {
-  DTRACE_SCOPED();
-
-  if (index >= connector_info_.num_modes) {
-    return kErrorNotSupported;
-  }
-
-  active_config_index_ = index;
-
-  // TODO(user): fix this hard coding
-  frame_rate_ = 60;
-
-  // Get the display attributes for current active config index
-  GetDisplayAttributes(active_config_index_, &display_attributes_);
-  UpdateMixerAttributes();
-
-  return kErrorNone;
-}
-
-DisplayError HWHDMIDRM::GetConfigIndex(uint32_t mode, uint32_t *index) {
-  *index = mode;
-
-  return kErrorNone;
-}
-
-DisplayError HWHDMIDRM::Validate(HWLayers *hw_layers) {
-  HWDeviceDRM::ResetDisplayParams();
-
-  return HWDeviceDRM::Validate(hw_layers);
-}
-
-DisplayError HWHDMIDRM::Commit(HWLayers *hw_layers) {
-  return HWDeviceDRM::Commit(hw_layers);
-}
-
-}  // namespace sdm
-
diff --git a/sdm/libs/core/drm/hw_info_drm.cpp b/sdm/libs/core/drm/hw_info_drm.cpp
index 7b632e8..69af1bd 100644
--- a/sdm/libs/core/drm/hw_info_drm.cpp
+++ b/sdm/libs/core/drm/hw_info_drm.cpp
@@ -254,6 +254,7 @@
   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;
diff --git a/sdm/libs/core/drm/hw_tv_drm.cpp b/sdm/libs/core/drm/hw_tv_drm.cpp
new file mode 100644
index 0000000..0262915
--- /dev/null
+++ b/sdm/libs/core/drm/hw_tv_drm.cpp
@@ -0,0 +1,183 @@
+/*
+* 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 "hw_tv_drm.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 <string>
+#include <vector>
+#include <map>
+#include <utility>
+
+
+#define __CLASS__ "HWTVDRM"
+
+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;
+
+namespace sdm {
+
+HWTVDRM::HWTVDRM(BufferSyncHandler *buffer_sync_handler, BufferAllocator *buffer_allocator,
+                     HWInfoInterface *hw_info_intf)
+  : HWDeviceDRM(buffer_sync_handler, buffer_allocator, hw_info_intf), active_config_index_(0) {
+  disp_type_ = DRMDisplayType::TV;
+  device_name_ = "TV Display Device";
+}
+
+// TODO(user) : split function in base class and avoid code duplicacy
+// by using base implementation for this basic stuff
+DisplayError HWTVDRM::Init() {
+  DisplayError error = kErrorNone;
+
+  default_mode_ = (DRMLibLoader::GetInstance()->IsLoaded() == false);
+
+  if (!default_mode_) {
+    DRMMaster *drm_master = {};
+    int dev_fd = -1;
+    DRMMaster::GetInstance(&drm_master);
+    drm_master->GetHandle(&dev_fd);
+    DRMLibLoader::GetInstance()->FuncGetDRMManager()(dev_fd, &drm_mgr_intf_);
+    if (drm_mgr_intf_->RegisterDisplay(DRMDisplayType::TV, &token_)) {
+      DLOGE("RegisterDisplay failed");
+      return kErrorResources;
+    }
+
+    drm_mgr_intf_->CreateAtomicReq(token_, &drm_atomic_intf_);
+    drm_mgr_intf_->GetConnectorInfo(token_.conn_id, &connector_info_);
+    InitializeConfigs();
+  }
+
+  hw_info_intf_->GetHWResourceInfo(&hw_resource_);
+
+  // 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);
+  }
+
+  if (error != kErrorNone) {
+    return error;
+  }
+
+  return error;
+}
+
+DisplayError HWTVDRM::GetNumDisplayAttributes(uint32_t *count) {
+  *count = connector_info_.num_modes;
+  if (*count <= 0) {
+    return kErrorHardware;
+  }
+
+  return kErrorNone;
+}
+
+DisplayError HWTVDRM::GetActiveConfig(uint32_t *active_config_index) {
+  *active_config_index = active_config_index_;
+  return kErrorNone;
+}
+
+DisplayError HWTVDRM::SetDisplayAttributes(uint32_t index) {
+  if (index >= connector_info_.num_modes) {
+    return kErrorNotSupported;
+  }
+
+  active_config_index_ = index;
+  current_mode_ = connector_info_.modes[index];
+
+  drm_atomic_intf_->Perform(DRMOps::CRTC_SET_MODE, token_.crtc_id, &connector_info_.modes[index]);
+  drm_atomic_intf_->Perform(DRMOps::CRTC_SET_ACTIVE, token_.crtc_id, 1);
+
+  // Commit to setup pipeline with mode, which then tells us the topology etc
+  if (drm_atomic_intf_->Commit(true /* synchronous */)) {
+    DLOGE("Setting up CRTC %d, Connector %d for %s failed", token_.crtc_id,
+          token_.conn_id, device_name_);
+    return kErrorResources;
+  }
+
+  // Reload connector info for updated info after 1st commit
+  drm_mgr_intf_->GetConnectorInfo(token_.conn_id, &connector_info_);
+  DLOGI("Setup CRTC %d, Connector %d for %s", token_.crtc_id, token_.conn_id, device_name_);
+
+  frame_rate_ = display_attributes_.fps;
+  PopulateDisplayAttributes();
+  PopulateHWPanelInfo();
+  UpdateMixerAttributes();
+
+  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_.num_modes; idex ++) {
+    if ((height == connector_info_.modes[idex].vdisplay) &&
+        (width == connector_info_.modes[idex].hdisplay) &&
+        (fps == connector_info_.modes[idex].vrefresh)) {
+      if ((format >> 1) & (connector_info_.modes[idex].flags >> kBitYUV)) {
+        *index = UINT32(idex);
+      }
+
+      if (format & (connector_info_.modes[idex].flags >> kBitRGB)) {
+        *index = UINT32(idex);
+      }
+    }
+  }
+
+  return kErrorNone;
+}
+
+}  // namespace sdm
+
diff --git a/sdm/libs/core/drm/hw_hdmi_drm.h b/sdm/libs/core/drm/hw_tv_drm.h
similarity index 84%
rename from sdm/libs/core/drm/hw_hdmi_drm.h
rename to sdm/libs/core/drm/hw_tv_drm.h
index 7e11e5e..7991ae3 100644
--- a/sdm/libs/core/drm/hw_hdmi_drm.h
+++ b/sdm/libs/core/drm/hw_tv_drm.h
@@ -22,8 +22,8 @@
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
 
-#ifndef __HW_HDMI_DRM_H__
-#define __HW_HDMI_DRM_H__
+#ifndef __HW_TV_DRM_H__
+#define __HW_TV_DRM_H__
 
 #include <map>
 #include <vector>
@@ -34,9 +34,9 @@
 
 using std::vector;
 
-class HWHDMIDRM : public HWDeviceDRM {
+class HWTVDRM : public HWDeviceDRM {
  public:
-  explicit HWHDMIDRM(BufferSyncHandler *buffer_sync_handler, BufferAllocator *buffer_allocator,
+  explicit HWTVDRM(BufferSyncHandler *buffer_sync_handler, BufferAllocator *buffer_allocator,
                      HWInfoInterface *hw_info_intf);
 
  protected:
@@ -45,16 +45,17 @@
   // Requirement to call this only after the first config has been explicitly set by client
   virtual DisplayError GetActiveConfig(uint32_t *active_config);
   virtual DisplayError SetDisplayAttributes(uint32_t index);
-  virtual DisplayError GetConfigIndex(uint32_t mode, uint32_t *index);
-  virtual DisplayError Validate(HWLayers *hw_layers);
-  virtual DisplayError Commit(HWLayers *hw_layers);
+  virtual DisplayError GetConfigIndex(char *mode, uint32_t *index);
 
  private:
+  static const int kBitRGB  = 20;
+  static const int kBitYUV  = 21;
+
   uint32_t active_config_index_;
   uint32_t frame_rate_ = 0;
 };
 
 }  // namespace sdm
 
-#endif  // __HW_HDMI_DRM_H__
+#endif  // __HW_TV_DRM_H__
 
diff --git a/sdm/libs/core/fb/hw_device.cpp b/sdm/libs/core/fb/hw_device.cpp
index ff19753..4931e1b 100644
--- a/sdm/libs/core/fb/hw_device.cpp
+++ b/sdm/libs/core/fb/hw_device.cpp
@@ -146,7 +146,7 @@
   return kErrorNotSupported;
 }
 
-DisplayError HWDevice::GetConfigIndex(uint32_t mode, uint32_t *index) {
+DisplayError HWDevice::GetConfigIndex(char *mode, uint32_t *index) {
   return kErrorNone;
 }
 
diff --git a/sdm/libs/core/fb/hw_device.h b/sdm/libs/core/fb/hw_device.h
index 2c0593a..f32c5bd 100644
--- a/sdm/libs/core/fb/hw_device.h
+++ b/sdm/libs/core/fb/hw_device.h
@@ -69,7 +69,7 @@
   virtual DisplayError GetHWPanelInfo(HWPanelInfo *panel_info);
   virtual DisplayError SetDisplayAttributes(uint32_t index);
   virtual DisplayError SetDisplayAttributes(const HWDisplayAttributes &display_attributes);
-  virtual DisplayError GetConfigIndex(uint32_t mode, uint32_t *index);
+  virtual DisplayError GetConfigIndex(char *mode, uint32_t *index);
   virtual DisplayError PowerOn();
   virtual DisplayError PowerOff();
   virtual DisplayError Doze();
diff --git a/sdm/libs/core/fb/hw_hdmi.cpp b/sdm/libs/core/fb/hw_hdmi.cpp
index 334a043..0602b12 100644
--- a/sdm/libs/core/fb/hw_hdmi.cpp
+++ b/sdm/libs/core/fb/hw_hdmi.cpp
@@ -38,6 +38,7 @@
 #include <utils/sys.h>
 #include <utils/formats.h>
 
+#include <string>
 #include <vector>
 #include <map>
 #include <utility>
@@ -407,17 +408,20 @@
   return kErrorNone;
 }
 
-DisplayError HWHDMI::GetConfigIndex(uint32_t mode, uint32_t *index) {
+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] == mode) {
+    if (hdmi_modes_[i] == value) {
       *index = i;
-      DLOGI("Index = %d for config = %d", *index, mode);
+      DLOGI("Index = %d for config = %d", *index, value);
       return kErrorNone;
     }
   }
 
-  DLOGE("Config = %d not supported", mode);
+  DLOGE("Config = %d not supported", value);
   return kErrorNotSupported;
 }
 
@@ -864,7 +868,9 @@
     return kErrorNotSupported;
   }
 
-  GetConfigIndex(dst->video_format, config_index);
+  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;
diff --git a/sdm/libs/core/fb/hw_hdmi.h b/sdm/libs/core/fb/hw_hdmi.h
index 625782e..83025fa 100644
--- a/sdm/libs/core/fb/hw_hdmi.h
+++ b/sdm/libs/core/fb/hw_hdmi.h
@@ -83,7 +83,7 @@
   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(uint32_t mode, 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);
@@ -109,6 +109,7 @@
   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_;
diff --git a/sdm/libs/core/fb/hw_primary.cpp b/sdm/libs/core/fb/hw_primary.cpp
index 8102e5f..5ee8121 100644
--- a/sdm/libs/core/fb/hw_primary.cpp
+++ b/sdm/libs/core/fb/hw_primary.cpp
@@ -329,7 +329,7 @@
   return kErrorNone;
 }
 
-DisplayError HWPrimary::GetConfigIndex(uint32_t mode, uint32_t *index) {
+DisplayError HWPrimary::GetConfigIndex(char *mode, uint32_t *index) {
   return HWDevice::GetConfigIndex(mode, index);
 }
 
diff --git a/sdm/libs/core/fb/hw_primary.h b/sdm/libs/core/fb/hw_primary.h
index 38b3b9a..69b5445 100644
--- a/sdm/libs/core/fb/hw_primary.h
+++ b/sdm/libs/core/fb/hw_primary.h
@@ -44,7 +44,7 @@
   virtual DisplayError GetDisplayAttributes(uint32_t index,
                                             HWDisplayAttributes *display_attributes);
   virtual DisplayError SetDisplayAttributes(uint32_t index);
-  virtual DisplayError GetConfigIndex(uint32_t mode, uint32_t *index);
+  virtual DisplayError GetConfigIndex(char *mode, uint32_t *index);
   virtual DisplayError PowerOff();
   virtual DisplayError Doze();
   virtual DisplayError DozeSuspend();
diff --git a/sdm/libs/core/hw_events_interface.cpp b/sdm/libs/core/hw_events_interface.cpp
index 5817cdb..84a7dab 100644
--- a/sdm/libs/core/hw_events_interface.cpp
+++ b/sdm/libs/core/hw_events_interface.cpp
@@ -32,9 +32,7 @@
 
 #include "hw_events_interface.h"
 #include "fb/hw_events.h"
-#ifdef COMPILE_DRM
 #include "drm/hw_events_drm.h"
-#endif
 
 #define __CLASS__ "HWEventsInterface"
 
@@ -48,9 +46,7 @@
   if (GetDriverType() == DriverType::FB) {
     hw_events = new HWEvents();
   } else {
-#ifdef COMPILE_DRM
     hw_events = new HWEventsDRM();
-#endif
   }
 
   error = hw_events->Init(display_type, event_handler, event_list, hw_intf);
diff --git a/sdm/libs/core/hw_info_interface.cpp b/sdm/libs/core/hw_info_interface.cpp
index 1773fe5..79bc79a 100644
--- a/sdm/libs/core/hw_info_interface.cpp
+++ b/sdm/libs/core/hw_info_interface.cpp
@@ -31,9 +31,7 @@
 
 #include "hw_info_interface.h"
 #include "fb/hw_info.h"
-#ifdef COMPILE_DRM
 #include "drm/hw_info_drm.h"
-#endif
 
 #define __CLASS__ "HWInfoInterface"
 
@@ -43,9 +41,7 @@
   if (GetDriverType() == DriverType::FB) {
     *intf = new HWInfo();
   } else {
-#ifdef COMPILE_DRM
     *intf = new HWInfoDRM();
-#endif
   }
 
   return kErrorNone;
diff --git a/sdm/libs/core/hw_interface.cpp b/sdm/libs/core/hw_interface.cpp
index f05aa0c..2d8d41e 100644
--- a/sdm/libs/core/hw_interface.cpp
+++ b/sdm/libs/core/hw_interface.cpp
@@ -35,11 +35,9 @@
 #include "fb/hw_primary.h"
 #include "fb/hw_hdmi.h"
 #include "fb/hw_virtual.h"
-#ifdef COMPILE_DRM
 #include "drm/hw_device_drm.h"
 #include "drm/hw_virtual_drm.h"
-#include "drm/hw_hdmi_drm.h"
-#endif
+#include "drm/hw_tv_drm.h"
 
 #define __CLASS__ "HWInterface"
 
@@ -57,27 +55,21 @@
       if (driver_type == DriverType::FB) {
         hw = new HWPrimary(buffer_sync_handler, hw_info_intf);
       } else {
-#ifdef COMPILE_DRM
         hw = new HWDeviceDRM(buffer_sync_handler, buffer_allocator, hw_info_intf);
-#endif
       }
       break;
     case kHDMI:
       if (driver_type == DriverType::FB) {
         hw = new HWHDMI(buffer_sync_handler, hw_info_intf);
       } else {
-#ifdef COMPILE_DRM
-        hw = new HWHDMIDRM(buffer_sync_handler, buffer_allocator, hw_info_intf);
-#endif
+        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 {
-#ifdef COMPILE_DRM
         hw = new HWVirtualDRM(buffer_sync_handler, buffer_allocator, hw_info_intf);
-#endif
       }
       break;
     default:
diff --git a/sdm/libs/core/hw_interface.h b/sdm/libs/core/hw_interface.h
index 616e3fb..6774159 100644
--- a/sdm/libs/core/hw_interface.h
+++ b/sdm/libs/core/hw_interface.h
@@ -83,7 +83,7 @@
   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(uint32_t mode, uint32_t *index) = 0;
+  virtual DisplayError GetConfigIndex(char *mode, uint32_t *index) = 0;
   virtual DisplayError PowerOn() = 0;
   virtual DisplayError PowerOff() = 0;
   virtual DisplayError Doze() = 0;
diff --git a/sdm/libs/hwc/Android.mk b/sdm/libs/hwc/Android.mk
deleted file mode 100644
index a2142e3..0000000
--- a/sdm/libs/hwc/Android.mk
+++ /dev/null
@@ -1,39 +0,0 @@
-LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-include $(LOCAL_PATH)/../../../common.mk
-ifeq ($(use_hwc2),false)
-
-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                  := $(common_flags) -Wno-missing-field-initializers -Wno-unused-parameter \
-                                 -std=c++11 -fcolor-diagnostics -Wno-sign-conversion -DLOG_TAG=\"SDM\"
-LOCAL_CLANG                   := true
-
-LOCAL_SHARED_LIBRARIES        := libsdmcore libqservice libbinder libhardware libhardware_legacy \
-                                 libutils libcutils libsync libmemalloc libqdutils libdl \
-                                 libpowermanager libsdmutils libgpu_tonemapper  libc++ liblog \
-                                 libdrmutils libui
-
-LOCAL_SRC_FILES               := hwc_session.cpp \
-                                 hwc_display.cpp \
-                                 hwc_display_null.cpp \
-                                 hwc_display_primary.cpp \
-                                 hwc_display_external.cpp \
-                                 hwc_display_virtual.cpp \
-                                 hwc_debugger.cpp \
-                                 hwc_buffer_allocator.cpp \
-                                 hwc_buffer_sync_handler.cpp \
-                                 hwc_color_manager.cpp \
-                                 blit_engine_c2d.cpp \
-                                 cpuhint.cpp \
-                                 hwc_tonemapper.cpp \
-                                 hwc_socket_handler.cpp \
-                                 hwc_display_external_test.cpp
-
-include $(BUILD_SHARED_LIBRARY)
-endif
diff --git a/sdm/libs/hwc/hwc_buffer_allocator.cpp b/sdm/libs/hwc/hwc_buffer_allocator.cpp
deleted file mode 100644
index 25f366f..0000000
--- a/sdm/libs/hwc/hwc_buffer_allocator.cpp
+++ /dev/null
@@ -1,330 +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 <gralloc_priv.h>
-#include <memalloc.h>
-#include <gr.h>
-#include <alloc_controller.h>
-#include <utils/constants.h>
-#include <utils/debug.h>
-#include <core/buffer_allocator.h>
-
-#include "hwc_debugger.h"
-#include "hwc_buffer_allocator.h"
-
-#define __CLASS__ "HWCBufferAllocator"
-
-namespace sdm {
-
-HWCBufferAllocator::HWCBufferAllocator() {
-  alloc_controller_ = gralloc::IAllocController::getInstance();
-}
-
-DisplayError HWCBufferAllocator::AllocateBuffer(BufferInfo *buffer_info) {
-  gralloc::alloc_data data;
-
-  const BufferConfig &buffer_config = buffer_info->buffer_config;
-  AllocatedBufferInfo *alloc_buffer_info = &buffer_info->alloc_buffer_info;
-  MetaBufferInfo *meta_buffer_info = new MetaBufferInfo();
-
-  if (!meta_buffer_info) {
-    return kErrorMemory;
-  }
-
-  int alloc_flags = INT(GRALLOC_USAGE_PRIVATE_IOMMU_HEAP);
-  int error = 0;
-
-  int width = INT(buffer_config.width);
-  int height = INT(buffer_config.height);
-  int format;
-
-  if (buffer_config.secure_camera) {
-    alloc_flags = GRALLOC_USAGE_HW_CAMERA_WRITE;
-    alloc_flags |= (GRALLOC_USAGE_PROTECTED | GRALLOC_USAGE_HW_COMPOSER);
-    data.align = SZ_2M;
-  } else if (buffer_config.secure) {
-    alloc_flags = INT(GRALLOC_USAGE_PRIVATE_MM_HEAP);
-    alloc_flags |= INT(GRALLOC_USAGE_PROTECTED);
-    data.align = SECURE_ALIGN;
-  } else {
-    data.align = UINT32(getpagesize());
-  }
-
-  if (buffer_config.cache == false) {
-    // Allocate uncached buffers
-    alloc_flags |= GRALLOC_USAGE_PRIVATE_UNCACHED;
-  }
-
-  error = SetBufferInfo(buffer_config.format, &format, &alloc_flags);
-  if (error != 0) {
-    delete meta_buffer_info;
-    return kErrorParameters;
-  }
-
-  int aligned_width = 0, aligned_height = 0;
-  uint32_t buffer_size = getBufferSizeAndDimensions(width, height, format, alloc_flags,
-                                                    aligned_width, aligned_height);
-
-  buffer_size = ROUND_UP(buffer_size, data.align) * buffer_config.buffer_count;
-
-  data.base = 0;
-  data.fd = -1;
-  data.offset = 0;
-  data.size = buffer_size;
-  data.uncached = !buffer_config.cache;
-
-  error = alloc_controller_->allocate(data, alloc_flags);
-  if (error != 0) {
-    DLOGE("Error allocating memory size %d uncached %d", data.size, data.uncached);
-    delete meta_buffer_info;
-    return kErrorMemory;
-  }
-
-  alloc_buffer_info->fd = data.fd;
-  // TODO(user): define stride for all planes and fix stride in bytes
-  alloc_buffer_info->stride = UINT32(aligned_width);
-  alloc_buffer_info->aligned_width = UINT32(aligned_width);
-  alloc_buffer_info->aligned_height = UINT32(aligned_height);
-  alloc_buffer_info->size = buffer_size;
-
-  meta_buffer_info->base_addr = data.base;
-  meta_buffer_info->alloc_type = data.allocType;
-
-  buffer_info->private_data = meta_buffer_info;
-
-  return kErrorNone;
-}
-
-DisplayError HWCBufferAllocator::FreeBuffer(BufferInfo *buffer_info) {
-  int ret = 0;
-  AllocatedBufferInfo *alloc_buffer_info = &buffer_info->alloc_buffer_info;
-
-  // Deallocate the buffer, only if the buffer fd is valid.
-  if (alloc_buffer_info->fd > 0) {
-    MetaBufferInfo *meta_buffer_info = static_cast<MetaBufferInfo *> (buffer_info->private_data);
-    gralloc::IMemAlloc *memalloc = alloc_controller_->getAllocator(meta_buffer_info->alloc_type);
-    if (memalloc == NULL) {
-      DLOGE("Memalloc handle is NULL, alloc type %d", meta_buffer_info->alloc_type);
-      return kErrorResources;
-    }
-
-    ret = memalloc->free_buffer(meta_buffer_info->base_addr, alloc_buffer_info->size, 0,
-                                alloc_buffer_info->fd);
-    if (ret != 0) {
-      DLOGE("Error freeing buffer base_addr %p size %d fd %d", meta_buffer_info->base_addr,
-            alloc_buffer_info->size, alloc_buffer_info->fd);
-      return kErrorMemory;
-    }
-
-    alloc_buffer_info->fd = -1;
-    alloc_buffer_info->stride = 0;
-    alloc_buffer_info->aligned_width = 0;
-    alloc_buffer_info->aligned_height = 0;
-    alloc_buffer_info->size = 0;
-
-    meta_buffer_info->base_addr = NULL;
-    meta_buffer_info->alloc_type = 0;
-
-    delete meta_buffer_info;
-    meta_buffer_info = NULL;
-  }
-
-  return kErrorNone;
-}
-
-uint32_t HWCBufferAllocator::GetBufferSize(BufferInfo *buffer_info) {
-  uint32_t align = UINT32(getpagesize());
-
-  const BufferConfig &buffer_config = buffer_info->buffer_config;
-
-  int alloc_flags = INT(GRALLOC_USAGE_PRIVATE_IOMMU_HEAP);
-
-  int width = INT(buffer_config.width);
-  int height = INT(buffer_config.height);
-  int format;
-
-  if (buffer_config.secure_camera) {
-    alloc_flags = GRALLOC_USAGE_HW_CAMERA_WRITE;
-    alloc_flags |= (GRALLOC_USAGE_PROTECTED | GRALLOC_USAGE_HW_COMPOSER);
-    align = SZ_2M;
-  } else if (buffer_config.secure) {
-    alloc_flags = INT(GRALLOC_USAGE_PRIVATE_MM_HEAP);
-    alloc_flags |= INT(GRALLOC_USAGE_PROTECTED);
-    align = SECURE_ALIGN;
-  }
-
-  if (buffer_config.cache == false) {
-    // Allocate uncached buffers
-    alloc_flags |= GRALLOC_USAGE_PRIVATE_UNCACHED;
-  }
-
-  if (SetBufferInfo(buffer_config.format, &format, &alloc_flags) < 0) {
-    return 0;
-  }
-
-  int aligned_width = 0;
-  int aligned_height = 0;
-  uint32_t buffer_size = getBufferSizeAndDimensions(width, height, format, alloc_flags,
-                                                    aligned_width, aligned_height);
-
-  buffer_size = ROUND_UP(buffer_size, align) * buffer_config.buffer_count;
-
-  return buffer_size;
-}
-
-int HWCBufferAllocator::SetBufferInfo(LayerBufferFormat format, int *target, int *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 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 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) {
-  int width = INT(buffer_config.width);
-  int height = INT(buffer_config.height);
-  int alloc_flags = INT(GRALLOC_USAGE_PRIVATE_IOMMU_HEAP);
-
-  if (buffer_config.secure) {
-    alloc_flags = INT(GRALLOC_USAGE_PRIVATE_MM_HEAP);
-    alloc_flags |= INT(GRALLOC_USAGE_PROTECTED);
-  }
-
-  if (buffer_config.cache == false) {
-    // Allocate uncached buffers
-    alloc_flags |= GRALLOC_USAGE_PRIVATE_UNCACHED;
-  }
-
-  int format;
-  int error = SetBufferInfo(buffer_config.format, &format, &alloc_flags);
-  if (error) {
-    DLOGE("Failed: format = %d or width = %d height = %d", buffer_config.format, width, height);
-    return kErrorNotSupported;
-  }
-
-  int width_aligned = 0, height_aligned = 0;
-  uint32_t buffer_size = 0;
-  buffer_size = getBufferSizeAndDimensions(width, height, format, alloc_flags,
-                                           width_aligned, height_aligned);
-
-  allocated_buffer_info->stride = UINT32(width_aligned);
-  allocated_buffer_info->aligned_width = UINT32(width_aligned);
-  allocated_buffer_info->aligned_height = UINT32(height_aligned);
-  allocated_buffer_info->size = UINT32(buffer_size);
-  allocated_buffer_info->format = buffer_config.format;
-
-  return kErrorNone;
-}
-
-DisplayError HWCBufferAllocator::GetBufferLayout(const AllocatedBufferInfo &buf_info,
-                                                 uint32_t stride[4], uint32_t offset[4],
-                                                 uint32_t *num_planes) {
-  private_handle_t hnd(-1, 0, 0, 0, 0, 0, 0);
-  int format = HAL_PIXEL_FORMAT_RGBA_8888;
-  int flags = 0;
-
-  SetBufferInfo(buf_info.format, &format, &flags);
-  // Setup only the required stuff, skip rest
-  hnd.format = format;
-  hnd.width = buf_info.aligned_width;
-  hnd.height = buf_info.aligned_height;
-  if (flags & GRALLOC_USAGE_PRIVATE_ALLOC_UBWC) {
-    hnd.flags = private_handle_t::PRIV_FLAGS_UBWC_ALIGNED;
-  }
-
-  int ret = getBufferLayout(&hnd, stride, offset, num_planes);
-  if (ret < 0) {
-    DLOGE("getBufferLayout failed");
-    return kErrorParameters;
-  }
-
-  return kErrorNone;
-}
-
-}  // namespace sdm
diff --git a/sdm/libs/hwc/hwc_buffer_allocator.h b/sdm/libs/hwc/hwc_buffer_allocator.h
deleted file mode 100644
index a8cf462..0000000
--- a/sdm/libs/hwc/hwc_buffer_allocator.h
+++ /dev/null
@@ -1,70 +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 __HWC_BUFFER_ALLOCATOR_H__
-#define __HWC_BUFFER_ALLOCATOR_H__
-
-#include <sys/mman.h>
-#include <fcntl.h>
-
-namespace gralloc {
-
-class IAllocController;
-
-}  // namespace gralloc
-
-namespace sdm {
-
-class HWCBufferAllocator : public BufferAllocator {
- public:
-  HWCBufferAllocator();
-
-  DisplayError AllocateBuffer(BufferInfo *buffer_info);
-  DisplayError FreeBuffer(BufferInfo *buffer_info);
-  uint32_t GetBufferSize(BufferInfo *buffer_info);
-  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, int *flags);
-
- private:
-  struct MetaBufferInfo {
-    int alloc_type;              //!< Specifies allocation type set by the buffer allocator.
-    void *base_addr;             //!< Specifies the base address of the allocated output buffer.
-  };
-
-  gralloc::IAllocController *alloc_controller_;
-};
-
-}  // namespace sdm
-#endif  // __HWC_BUFFER_ALLOCATOR_H__
-
diff --git a/sdm/libs/hwc/hwc_display.cpp b/sdm/libs/hwc/hwc_display.cpp
deleted file mode 100644
index 2c5c885..0000000
--- a/sdm/libs/hwc/hwc_display.cpp
+++ /dev/null
@@ -1,1536 +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 <math.h>
-#include <errno.h>
-#include <gralloc_priv.h>
-#include <gr.h>
-#include <utils/constants.h>
-#include <utils/formats.h>
-#include <utils/rect.h>
-#include <utils/debug.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sync/sync.h>
-#include <cutils/properties.h>
-#include <qd_utils.h>
-#include <map>
-#include <utility>
-#include <vector>
-#include <string>
-
-#include "blit_engine_c2d.h"
-#include "hwc_debugger.h"
-#include "hwc_display.h"
-#include "hwc_tonemapper.h"
-
-#ifdef QTI_BSP
-#include <hardware/display_defs.h>
-#endif
-
-#define __CLASS__ "HWCDisplay"
-
-namespace sdm {
-
-void HWCColorMode::Init() {
-  int ret = PopulateColorModes();
-  if (ret != 0) {
-    DLOGW("Failed!!");
-  }
-  return;
-}
-
-int HWCColorMode::SetColorMode(const std::string &color_mode) {
-  if (color_modes_.empty()) {
-    DLOGW("No Color Modes supported");
-    return -1;
-  }
-
-  std::vector<std::string>::iterator it = std::find(color_modes_.begin(), color_modes_.end(),
-                                                    color_mode);
-  if (it == color_modes_.end()) {
-    DLOGE("Invalid colorMode request: %s", color_mode.c_str());
-    return -1;
-  }
-
-  DisplayError error = display_intf_->SetColorMode(color_mode);
-  if (error != kErrorNone) {
-    DLOGE("Failed to set color_mode = %s", color_mode.c_str());
-    return -1;
-  }
-  current_color_mode_ = color_mode;
-
-  return 0;
-}
-
-const std::vector<std::string> &HWCColorMode::GetColorModes() {
-  return color_modes_;
-}
-
-int HWCColorMode::SetColorTransform(uint32_t matrix_count, const float *matrix) {
-  if (matrix_count > kColorTransformMatrixCount) {
-    DLOGE("Transform matrix count = %d, exceeds max = %d", matrix_count,
-          kColorTransformMatrixCount);
-    return -1;
-  }
-
-  double color_matrix[kColorTransformMatrixCount] = {0};
-  CopyColorTransformMatrix(matrix, color_matrix);
-  DisplayError error = display_intf_->SetColorTransform(matrix_count, color_matrix);
-  if (error != kErrorNone) {
-    DLOGE("Failed!");
-    return -1;
-  }
-
-  return 0;
-}
-
-int HWCColorMode::PopulateColorModes() {
-  uint32_t color_mode_count = 0;
-  DisplayError error = display_intf_->GetColorModeCount(&color_mode_count);
-  if (error != kErrorNone || (color_mode_count == 0)) {
-    return -1;
-  }
-
-  DLOGI("Color Mode count = %d", color_mode_count);
-
-  color_modes_.resize(color_mode_count);
-
-  // SDM returns modes which is string
-  error = display_intf_->GetColorModes(&color_mode_count, &color_modes_);
-  if (error != kErrorNone) {
-    DLOGE("GetColorModes Failed for count = %d", color_mode_count);
-    return -1;
-  }
-
-  return 0;
-}
-
-HWCDisplay::HWCDisplay(CoreInterface *core_intf, hwc_procs_t const **hwc_procs, DisplayType type,
-                       int id, bool needs_blit, qService::QService *qservice,
-                       DisplayClass display_class)
-  : core_intf_(core_intf), hwc_procs_(hwc_procs), type_(type), id_(id), needs_blit_(needs_blit),
-    qservice_(qservice), display_class_(display_class) {
-}
-
-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;
-  }
-
-  HWCDebugHandler::Get()->GetProperty("sys.hwc_disable_hdr", &disable_hdr_handling_);
-  if (disable_hdr_handling_) {
-    DLOGI("HDR Handling disabled");
-  }
-
-  int property_swap_interval = 1;
-  HWCDebugHandler::Get()->GetProperty("debug.egl.swapinterval", &property_swap_interval);
-  if (property_swap_interval == 0) {
-    swap_interval_zero_ = true;
-  }
-
-  int blit_enabled = 0;
-  HWCDebugHandler::Get()->GetProperty("persist.hwc.blit.comp", &blit_enabled);
-  if (needs_blit_ && blit_enabled) {
-    blit_engine_ = new BlitEngineC2d();
-    if (!blit_engine_) {
-      DLOGI("Create Blit Engine C2D failed");
-    } else {
-      if (blit_engine_->Init() < 0) {
-        DLOGI("Blit Engine Init failed, Blit Composition will not be used!!");
-        delete blit_engine_;
-        blit_engine_ = NULL;
-      }
-    }
-  }
-
-  tone_mapper_ = new HWCToneMapper();
-
-  display_intf_->GetRefreshRateRange(&min_refresh_rate_, &max_refresh_rate_);
-  current_refresh_rate_ = max_refresh_rate_;
-
-  s3d_format_hwc_to_sdm_.insert(std::pair<int, LayerBufferS3DFormat>(HAL_NO_3D, kS3dFormatNone));
-  s3d_format_hwc_to_sdm_.insert(std::pair<int, LayerBufferS3DFormat>(HAL_3D_SIDE_BY_SIDE_L_R,
-                                kS3dFormatLeftRight));
-  s3d_format_hwc_to_sdm_.insert(std::pair<int, LayerBufferS3DFormat>(HAL_3D_SIDE_BY_SIDE_R_L,
-                                kS3dFormatRightLeft));
-  s3d_format_hwc_to_sdm_.insert(std::pair<int, LayerBufferS3DFormat>(HAL_3D_TOP_BOTTOM,
-                                kS3dFormatTopBottom));
-
-  disable_animation_ = Debug::IsExtAnimDisabled();
-
-  return 0;
-}
-
-int HWCDisplay::Deinit() {
-  DisplayError error = core_intf_->DestroyDisplay(display_intf_);
-  if (error != kErrorNone) {
-    DLOGE("Display destroy failed. Error = %d", error);
-    return -EINVAL;
-  }
-
-  if (blit_engine_) {
-    blit_engine_->DeInit();
-    delete blit_engine_;
-    blit_engine_ = NULL;
-  }
-
-  delete tone_mapper_;
-  tone_mapper_ = NULL;
-
-  return 0;
-}
-
-int HWCDisplay::EventControl(int event, int enable) {
-  DisplayError error = kErrorNone;
-
-  if (shutdown_pending_) {
-    return 0;
-  }
-
-  switch (event) {
-  case HWC_EVENT_VSYNC:
-    error = display_intf_->SetVSyncState(enable);
-    break;
-  default:
-    DLOGW("Unsupported event = %d", event);
-  }
-
-  if (error != kErrorNone) {
-    if (error == kErrorShutDown) {
-      shutdown_pending_ = true;
-      return 0;
-    }
-    DLOGE("Failed. event = %d, enable = %d, error = %d", event, enable, error);
-    return -EINVAL;
-  }
-
-  return 0;
-}
-
-int HWCDisplay::SetPowerMode(int mode) {
-  DLOGI("display = %d, mode = %d", id_, mode);
-  DisplayState state = kStateOff;
-  bool flush_on_error = flush_on_error_;
-
-  if (shutdown_pending_) {
-    return 0;
-  }
-
-  switch (mode) {
-  case HWC_POWER_MODE_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;
-    tone_mapper_->Terminate();
-    break;
-
-  case HWC_POWER_MODE_NORMAL:
-    state = kStateOn;
-    last_power_mode_ = HWC_POWER_MODE_NORMAL;
-    break;
-
-  case HWC_POWER_MODE_DOZE:
-    state = kStateDoze;
-    last_power_mode_ = HWC_POWER_MODE_DOZE;
-    break;
-
-  case HWC_POWER_MODE_DOZE_SUSPEND:
-    state = kStateDozeSuspend;
-    last_power_mode_ = HWC_POWER_MODE_DOZE_SUSPEND;
-    break;
-
-  default:
-    return -EINVAL;
-  }
-
-  DisplayError error = display_intf_->SetDisplayState(state);
-  if (error == kErrorNone) {
-    flush_on_error_ = flush_on_error;
-  } else {
-    if (error == kErrorShutDown) {
-      shutdown_pending_ = true;
-      return 0;
-    }
-    DLOGE("Set state failed. Error = %d", error);
-    return -EINVAL;
-  }
-
-  return 0;
-}
-
-int HWCDisplay::GetDisplayConfigs(uint32_t *configs, size_t *num_configs) {
-  if (*num_configs > 0) {
-    configs[0] = 0;
-    *num_configs = 1;
-  }
-
-  return 0;
-}
-
-int HWCDisplay::GetDisplayAttributes(uint32_t config, const uint32_t *display_attributes,
-                                     int32_t *values) {
-  DisplayConfigVariableInfo variable_config;
-  DisplayError error = display_intf_->GetFrameBufferConfig(&variable_config);
-  if (error != kErrorNone) {
-    DLOGV("Get variable config failed. Error = %d", error);
-    return -EINVAL;
-  }
-
-  for (int i = 0; display_attributes[i] != HWC_DISPLAY_NO_ATTRIBUTE; i++) {
-    switch (display_attributes[i]) {
-    case HWC_DISPLAY_VSYNC_PERIOD:
-      values[i] = INT32(variable_config.vsync_period_ns);
-      break;
-    case HWC_DISPLAY_WIDTH:
-      values[i] = INT32(variable_config.x_pixels);
-      break;
-    case HWC_DISPLAY_HEIGHT:
-      values[i] = INT32(variable_config.y_pixels);
-      break;
-    case HWC_DISPLAY_DPI_X:
-      values[i] = INT32(variable_config.x_dpi * 1000.0f);
-      break;
-    case HWC_DISPLAY_DPI_Y:
-      values[i] = INT32(variable_config.y_dpi * 1000.0f);
-      break;
-    default:
-      DLOGW("Spurious attribute type = %d", display_attributes[i]);
-      return -EINVAL;
-    }
-  }
-
-  return 0;
-}
-
-int HWCDisplay::GetActiveConfig() {
-  return 0;
-}
-
-int HWCDisplay::SetActiveConfig(int index) {
-  return -1;
-}
-
-DisplayError HWCDisplay::SetMixerResolution(uint32_t width, uint32_t height) {
-  return kErrorNotSupported;
-}
-
-void 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 (blit_engine_) {
-    blit_engine_->SetFrameDumpConfig(count);
-  }
-
-  if (tone_mapper_) {
-    tone_mapper_->SetFrameDumpConfig(count);
-  }
-
-  DLOGI("num_frame_dump %d, input_layer_dump_enable %d", dump_frame_count_, dump_input_layers_);
-}
-
-uint32_t HWCDisplay::GetLastPowerMode() {
-  return last_power_mode_;
-}
-
-DisplayError HWCDisplay::VSync(const DisplayEventVSync &vsync) {
-  const hwc_procs_t *hwc_procs = *hwc_procs_;
-
-  if (!hwc_procs) {
-    return kErrorParameters;
-  }
-
-  hwc_procs->vsync(hwc_procs, 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;
-}
-
-int HWCDisplay::AllocateLayerStack(hwc_display_contents_1_t *content_list) {
-  if (!content_list || !content_list->numHwLayers) {
-    DLOGW("Invalid content list");
-    return -EINVAL;
-  }
-
-  size_t num_hw_layers = content_list->numHwLayers;
-  uint32_t blit_target_count = 0;
-
-  if (blit_engine_) {
-    blit_target_count = kMaxBlitTargetLayers;
-  }
-
-  FreeLayerStack();
-
-  for (size_t i = 0; i < num_hw_layers + blit_target_count; i++) {
-    Layer *layer = new Layer();
-    layer_stack_.layers.push_back(layer);
-  }
-
-  return 0;
-}
-
-void HWCDisplay::FreeLayerStack() {
-  for (Layer *layer : layer_stack_.layers) {
-    delete layer;
-  }
-  layer_stack_ = {};
-}
-
-int HWCDisplay::PrepareLayerParams(hwc_layer_1_t *hwc_layer, Layer* layer) {
-  const private_handle_t *pvt_handle = static_cast<const private_handle_t *>(hwc_layer->handle);
-
-  LayerBuffer &layer_buffer = layer->input_buffer;
-
-  if (pvt_handle) {
-    layer_buffer.planes[0].fd = pvt_handle->fd;
-    layer_buffer.format = GetSDMFormat(pvt_handle->format, pvt_handle->flags);
-    int aligned_width, aligned_height;
-    int unaligned_width, unaligned_height;
-
-    AdrenoMemInfo::getInstance().getAlignedWidthAndHeight(pvt_handle, aligned_width,
-                                                          aligned_height);
-    AdrenoMemInfo::getInstance().getUnalignedWidthAndHeight(pvt_handle, unaligned_width,
-                                                            unaligned_height);
-
-    layer_buffer.width = UINT32(aligned_width);
-    layer_buffer.height = UINT32(aligned_height);
-    layer_buffer.unaligned_width = UINT32(unaligned_width);
-    layer_buffer.unaligned_height = UINT32(unaligned_height);
-
-    if (SetMetaData(pvt_handle, layer) != kErrorNone) {
-      return -EINVAL;
-    }
-
-    if (pvt_handle->bufferType == BUFFER_TYPE_VIDEO) {
-      layer_stack_.flags.video_present = true;
-      layer_buffer.flags.video = true;
-    }
-    // TZ Protected Buffer - L1
-    if (pvt_handle->flags & private_handle_t::PRIV_FLAGS_SECURE_BUFFER) {
-      layer_stack_.flags.secure_present = true;
-      layer_buffer.flags.secure = true;
-      if (pvt_handle->flags & private_handle_t::PRIV_FLAGS_CAMERA_WRITE) {
-        layer_buffer.flags.secure_camera = true;
-      }
-    }
-    // Gralloc Usage Protected Buffer - L3 - which needs to be treated as Secure & avoid fallback
-    if (pvt_handle->flags & private_handle_t::PRIV_FLAGS_PROTECTED_BUFFER) {
-      layer_stack_.flags.secure_present = true;
-    }
-    if (pvt_handle->flags & private_handle_t::PRIV_FLAGS_SECURE_DISPLAY) {
-      layer_buffer.flags.secure_display = true;
-    }
-
-    // check if this is special solid_fill layer without input_buffer.
-    if (solid_fill_enable_ && pvt_handle->fd == -1) {
-      layer->flags.solid_fill = true;
-      layer->solid_fill_color = solid_fill_color_;
-    }
-  } else {
-    // for FBT layer
-    if (hwc_layer->compositionType == HWC_FRAMEBUFFER_TARGET) {
-      uint32_t x_pixels;
-      uint32_t y_pixels;
-      int aligned_width;
-      int aligned_height;
-      int usage = GRALLOC_USAGE_HW_FB;
-      int format = HAL_PIXEL_FORMAT_RGBA_8888;
-      int ubwc_enabled = 0;
-      int flags = 0;
-      HWCDebugHandler::Get()->GetProperty("debug.gralloc.enable_fb_ubwc", &ubwc_enabled);
-      bool linear = layer_stack_.output_buffer && !IsUBWCFormat(layer_stack_.output_buffer->format);
-      if ((ubwc_enabled == 1) && !linear) {
-        usage |= GRALLOC_USAGE_PRIVATE_ALLOC_UBWC;
-        flags |= private_handle_t::PRIV_FLAGS_UBWC_ALIGNED;
-      }
-
-      GetFrameBufferResolution(&x_pixels, &y_pixels);
-
-      AdrenoMemInfo::getInstance().getAlignedWidthAndHeight(INT(x_pixels), INT(y_pixels), format,
-                                                            usage, aligned_width, aligned_height);
-      layer_buffer.width = UINT32(aligned_width);
-      layer_buffer.height = UINT32(aligned_height);
-      layer_buffer.unaligned_width = x_pixels;
-      layer_buffer.unaligned_height = y_pixels;
-      layer_buffer.format = GetSDMFormat(format, flags);
-    }
-  }
-
-  return 0;
-}
-
-void HWCDisplay::CommitLayerParams(hwc_layer_1_t *hwc_layer, Layer *layer) {
-  const private_handle_t *pvt_handle = static_cast<const private_handle_t *>(hwc_layer->handle);
-  LayerBuffer &layer_buffer = layer->input_buffer;
-
-  if (pvt_handle) {
-    layer_buffer.planes[0].fd = pvt_handle->fd;
-    layer_buffer.planes[0].offset = pvt_handle->offset;
-    layer_buffer.planes[0].stride = UINT32(pvt_handle->width);
-    layer_buffer.size = pvt_handle->size;
-  }
-
-  // if swapinterval property is set to 0 then close and reset the acquireFd
-  if (swap_interval_zero_ && hwc_layer->acquireFenceFd >= 0) {
-    close(hwc_layer->acquireFenceFd);
-    hwc_layer->acquireFenceFd = -1;
-  }
-  layer_buffer.acquire_fence_fd = hwc_layer->acquireFenceFd;
-}
-
-int HWCDisplay::PrePrepareLayerStack(hwc_display_contents_1_t *content_list) {
-  if (shutdown_pending_) {
-    return 0;
-  }
-
-  size_t num_hw_layers = content_list->numHwLayers;
-
-  use_blit_comp_ = false;
-  metadata_refresh_rate_ = 0;
-  display_rect_ = LayerRect();
-
-  // Configure each layer
-  for (size_t i = 0; i < num_hw_layers; i++) {
-    hwc_layer_1_t &hwc_layer = content_list->hwLayers[i];
-
-    const private_handle_t *pvt_handle = static_cast<const private_handle_t *>(hwc_layer.handle);
-    Layer *layer = layer_stack_.layers.at(i);
-    int ret = PrepareLayerParams(&content_list->hwLayers[i], layer);
-
-    if (ret != kErrorNone) {
-      return ret;
-    }
-
-    layer->flags.skip = ((hwc_layer.flags & HWC_SKIP_LAYER) > 0);
-    layer->flags.solid_fill = (hwc_layer.flags & kDimLayer) || solid_fill_enable_;
-    if (layer->flags.skip || layer->flags.solid_fill) {
-      layer->dirty_regions.clear();
-    }
-
-    hwc_rect_t scaled_display_frame = hwc_layer.displayFrame;
-    ApplyScanAdjustment(&scaled_display_frame);
-
-    SetRect(scaled_display_frame, &layer->dst_rect);
-    if (pvt_handle) {
-        bool NonIntegralSourceCrop =  IsNonIntegralSourceCrop(hwc_layer.sourceCropf);
-        bool secure = (pvt_handle->flags & private_handle_t::PRIV_FLAGS_SECURE_BUFFER) ||
-                (pvt_handle->flags & private_handle_t::PRIV_FLAGS_PROTECTED_BUFFER) ||
-                (pvt_handle->flags & private_handle_t::PRIV_FLAGS_SECURE_DISPLAY);
-        if (NonIntegralSourceCrop && (!secure && pvt_handle->bufferType != BUFFER_TYPE_VIDEO)) {
-            layer->flags.skip = true;
-        }
-    }
-    SetRect(hwc_layer.sourceCropf, &layer->src_rect);
-
-    uint32_t num_visible_rects = UINT32(hwc_layer.visibleRegionScreen.numRects);
-    uint32_t num_dirty_rects = UINT32(hwc_layer.surfaceDamage.numRects);
-
-    for (uint32_t j = 0; j < num_visible_rects; j++) {
-      LayerRect visible_rect = {};
-      SetRect(hwc_layer.visibleRegionScreen.rects[j], &visible_rect);
-      layer->visible_regions.push_back(visible_rect);
-    }
-
-    for (uint32_t j = 0; j < num_dirty_rects; j++) {
-      LayerRect dirty_rect = {};
-      SetRect(hwc_layer.surfaceDamage.rects[j], &dirty_rect);
-      layer->dirty_regions.push_back(dirty_rect);
-    }
-
-    if (blit_engine_) {
-      for (uint32_t j = 0; j < kMaxBlitTargetLayers; j++) {
-        LayerRect blit_rect = {};
-        layer->blit_regions.push_back(blit_rect);
-      }
-    }
-
-    SetComposition(hwc_layer.compositionType, &layer->composition);
-    if (hwc_layer.compositionType != HWC_FRAMEBUFFER_TARGET) {
-      display_rect_ = Union(display_rect_, layer->dst_rect);
-    }
-
-    // For dim layers, SurfaceFlinger
-    //    - converts planeAlpha to per pixel alpha,
-    //    - sets appropriate RGB color,
-    //    - sets planeAlpha to 0xff,
-    //    - blending to Premultiplied.
-    // This can be achieved at hardware by
-    //    - solid fill ARGB to appropriate value,
-    //    - incoming planeAlpha,
-    //    - blending to Coverage.
-    if (hwc_layer.flags & kDimLayer) {
-      layer->input_buffer.format = kFormatARGB8888;
-      layer->solid_fill_color = 0xff000000;
-#ifdef QTI_BSP
-      // Get ARGB color from HWC Dim Layer color
-      uint32_t a = UINT32(hwc_layer.color.a) << 24;
-      uint32_t r = UINT32(hwc_layer.color.r) << 16;
-      uint32_t g = UINT32(hwc_layer.color.g) << 8;
-      uint32_t b = UINT32(hwc_layer.color.b);
-      layer->solid_fill_color = a | r | g | b;
-#endif
-      SetBlending(HWC_BLENDING_COVERAGE, &layer->blending);
-    } else {
-      SetBlending(hwc_layer.blending, &layer->blending);
-      LayerTransform &layer_transform = layer->transform;
-      uint32_t &hwc_transform = hwc_layer.transform;
-      layer_transform.flip_horizontal = ((hwc_transform & HWC_TRANSFORM_FLIP_H) > 0);
-      layer_transform.flip_vertical = ((hwc_transform & HWC_TRANSFORM_FLIP_V) > 0);
-      layer_transform.rotation = ((hwc_transform & HWC_TRANSFORM_ROT_90) ? 90.0f : 0.0f);
-    }
-
-    // TODO(user): Remove below block.
-    // For solid fill, only dest rect need to be specified.
-    if (layer->flags.solid_fill) {
-      LayerBuffer &input_buffer = layer->input_buffer;
-      input_buffer.width = UINT32(layer->dst_rect.right - layer->dst_rect.left);
-      input_buffer.height = UINT32(layer->dst_rect.bottom - layer->dst_rect.top);
-      input_buffer.unaligned_width = input_buffer.width;
-      input_buffer.unaligned_height = input_buffer.height;
-      layer->src_rect.left = 0;
-      layer->src_rect.top = 0;
-      layer->src_rect.right = input_buffer.width;
-      layer->src_rect.bottom = input_buffer.height;
-    }
-
-    layer->plane_alpha = hwc_layer.planeAlpha;
-    layer->flags.cursor = ((hwc_layer.flags & HWC_IS_CURSOR_LAYER) > 0);
-    layer->flags.updating = true;
-
-    if (num_hw_layers <= kMaxLayerCount) {
-      layer->flags.updating = IsLayerUpdating(content_list, layer);
-    }
-#ifdef QTI_BSP
-    if (hwc_layer.flags & HWC_SCREENSHOT_ANIMATOR_LAYER) {
-      layer_stack_.flags.animating = true;
-    }
-#endif
-    if (layer->flags.skip) {
-      layer_stack_.flags.skip_present = true;
-    }
-
-    if (layer->flags.cursor) {
-      layer_stack_.flags.cursor_present = true;
-    }
-
-    PrepareDynamicRefreshRate(layer);
-
-    layer->input_buffer.buffer_id = reinterpret_cast<uint64_t>(hwc_layer.handle);
-  }
-
-  // Prepare the Blit Target
-  if (blit_engine_) {
-  // TODO(user): Fix this to enable BLIT
-#if 0
-    int ret = blit_engine_->Prepare(&layer_stack_);
-    if (ret) {
-      // Blit engine cannot handle this layer stack, hence set the layer stack
-      // count to num_hw_layers
-      layer_stack_.layer_count -= kMaxBlitTargetLayers;
-    } else {
-      use_blit_comp_ = true;
-    }
-#endif
-  }
-
-  // Configure layer stack
-  layer_stack_.flags.geometry_changed = ((content_list->flags & HWC_GEOMETRY_CHANGED) > 0);
-
-  return 0;
-}
-
-void HWCDisplay::SetLayerS3DMode(const LayerBufferS3DFormat &source, uint32_t *target) {
-#ifdef QTI_BSP
-    switch (source) {
-    case kS3dFormatNone: *target = HWC_S3DMODE_NONE; break;
-    case kS3dFormatLeftRight: *target = HWC_S3DMODE_LR; break;
-    case kS3dFormatRightLeft: *target = HWC_S3DMODE_RL; break;
-    case kS3dFormatTopBottom: *target = HWC_S3DMODE_TB; break;
-    case kS3dFormatFramePacking: *target = HWC_S3DMODE_FP; break;
-    default: *target = HWC_S3DMODE_MAX; break;
-    }
-#endif
-}
-
-int HWCDisplay::PrepareLayerStack(hwc_display_contents_1_t *content_list) {
-  if (shutdown_pending_) {
-    return 0;
-  }
-
-  size_t num_hw_layers = content_list->numHwLayers;
-
-  if (!skip_prepare_cnt) {
-    DisplayError error = display_intf_->Prepare(&layer_stack_);
-    if (error != kErrorNone) {
-      if (error == kErrorShutDown) {
-        shutdown_pending_ = true;
-      } else if ((error != kErrorPermission) && (error != kErrorNoAppLayers)) {
-        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;
-      } else {
-        DLOGV("Prepare failed for Display = %d Error = %d", type_, error);
-      }
-      return 0;
-    }
-  } else {
-    // Skip is not set
-    MarkLayersForGPUBypass(content_list);
-    skip_prepare_cnt = skip_prepare_cnt - 1;
-    DLOGI("SecureDisplay %s, Skip Prepare/Commit and Flush", secure_display_active_ ? "Starting" :
-          "Stopping");
-    flush_ = true;
-  }
-
-  for (size_t i = 0; i < num_hw_layers; i++) {
-    hwc_layer_1_t &hwc_layer = content_list->hwLayers[i];
-    Layer *layer = layer_stack_.layers.at(i);
-    LayerComposition composition = layer->composition;
-    private_handle_t* pvt_handle  = static_cast<private_handle_t*>
-      (const_cast<native_handle_t*>(hwc_layer.handle));
-    MetaData_t *meta_data = pvt_handle ?
-      reinterpret_cast<MetaData_t *>(pvt_handle->base_metadata) : NULL;
-
-    if ((composition == kCompositionSDE) || (composition == kCompositionHybrid) ||
-        (composition == kCompositionBlit)) {
-      hwc_layer.hints |= HWC_HINT_CLEAR_FB;
-    }
-    SetComposition(composition, &hwc_layer.compositionType);
-
-    if (meta_data != NULL) {
-      if (composition == kCompositionGPUS3D) {
-        // Align HWC and client's dispaly ID in case of HDMI as primary
-        meta_data->s3dComp.displayId =
-          display_intf_->IsPrimaryDisplay() ? HWC_DISPLAY_PRIMARY: id_;
-        SetLayerS3DMode(layer->input_buffer.s3d_format,
-            &meta_data->s3dComp.s3dMode);
-      }
-    }
-  }
-
-  return 0;
-}
-
-int HWCDisplay::CommitLayerStack(hwc_display_contents_1_t *content_list) {
-  if (!content_list || !content_list->numHwLayers) {
-    DLOGW("Invalid content list");
-    return -EINVAL;
-  }
-
-  if (shutdown_pending_) {
-    return 0;
-  }
-
-  int status = 0;
-
-  size_t num_hw_layers = content_list->numHwLayers;
-
-  DumpInputBuffers(content_list);
-
-  if (!flush_) {
-    for (size_t i = 0; i < num_hw_layers; i++) {
-      CommitLayerParams(&content_list->hwLayers[i], layer_stack_.layers.at(i));
-    }
-
-    if (use_blit_comp_) {
-      status = blit_engine_->PreCommit(content_list, &layer_stack_);
-      if (status == 0) {
-        status = blit_engine_->Commit(content_list, &layer_stack_);
-        if (status != 0) {
-          DLOGE("Blit Comp Failed!");
-        }
-      }
-    }
-
-    if (layer_stack_.flags.hdr_present) {
-      status = tone_mapper_->HandleToneMap(content_list, &layer_stack_);
-      if (status != 0) {
-        DLOGE("Error handling HDR in ToneMapper");
-      }
-    } else {
-      tone_mapper_->Terminate();
-    }
-
-    DisplayError error = kErrorUndefined;
-    if (status == 0) {
-      error = display_intf_->Commit(&layer_stack_);
-      status = 0;
-    }
-
-    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 status;
-      } 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;
-      } else {
-        DLOGI("Commit failed for Display = %d Error = %d", type_, error);
-      }
-    }
-  }
-
-  return status;
-}
-
-int HWCDisplay::PostCommitLayerStack(hwc_display_contents_1_t *content_list) {
-  size_t num_hw_layers = content_list->numHwLayers;
-  int status = 0;
-
-  // Do no call flush on errors, if a successful buffer is never submitted.
-  if (flush_ && flush_on_error_) {
-    display_intf_->Flush();
-  }
-
-
-  if (tone_mapper_ && tone_mapper_->IsActive()) {
-     tone_mapper_->PostCommit(&layer_stack_);
-  }
-
-  // Set the release fence fd to the blit engine
-  if (use_blit_comp_ && blit_engine_->BlitActive()) {
-    blit_engine_->PostCommit(&layer_stack_);
-  }
-
-  for (size_t i = 0; i < num_hw_layers; i++) {
-    hwc_layer_1_t &hwc_layer = content_list->hwLayers[i];
-    Layer *layer = layer_stack_.layers.at(i);
-    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) {
-        hwc_layer.releaseFenceFd = -1;
-        close(layer_buffer.release_fence_fd);
-        layer_buffer.release_fence_fd = -1;
-      } else if (layer->composition != kCompositionGPU) {
-        hwc_layer.releaseFenceFd = layer_buffer.release_fence_fd;
-      }
-
-      // During animation on external/virtual display, SDM will use the cached
-      // framebuffer layer throughout animation and do not allow framework to do eglswapbuffer on
-      // framebuffer target. So graphics doesn't close the release fence fd of framebuffer target,
-      // Hence close the release fencefd of framebuffer target here.
-      if (disable_animation_) {
-        if (layer->composition == kCompositionGPUTarget && animating_) {
-          close(hwc_layer.releaseFenceFd);
-          hwc_layer.releaseFenceFd = -1;
-        }
-      }
-    }
-
-    if (hwc_layer.acquireFenceFd >= 0) {
-      close(hwc_layer.acquireFenceFd);
-      hwc_layer.acquireFenceFd = -1;
-    }
-  }
-
-  if (!flush_) {
-    animating_ = layer_stack_.flags.animating;
-    // 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;
-    }
-    content_list->retireFenceFd = layer_stack_.retire_fence_fd;
-
-    if (dump_frame_count_) {
-      dump_frame_count_--;
-      dump_frame_index_++;
-    }
-  }
-
-  flush_ = false;
-
-  return status;
-}
-
-bool HWCDisplay::IsLayerUpdating(hwc_display_contents_1_t *content_list, 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
-  return (layer->flags.single_buffer || IsSurfaceUpdated(layer->dirty_regions) ||
-         (layer_stack_.flags.geometry_changed));
-}
-
-bool HWCDisplay::IsNonIntegralSourceCrop(const hwc_frect_t &source) {
-     if ((source.left != roundf(source.left)) ||
-         (source.top != roundf(source.top)) ||
-         (source.right != roundf(source.right)) ||
-         (source.bottom != roundf(source.bottom))) {
-         return true;
-     } else {
-         return false;
-     }
-}
-
-void HWCDisplay::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 HWCDisplay::SetRect(const hwc_frect_t &source, LayerRect *target) {
-  target->left = floorf(source.left);
-  target->top = floorf(source.top);
-  target->right = ceilf(source.right);
-  target->bottom = ceilf(source.bottom);
-}
-
-void HWCDisplay::SetComposition(const int32_t &source, LayerComposition *target) {
-  switch (source) {
-  case HWC_FRAMEBUFFER_TARGET:  *target = kCompositionGPUTarget;  break;
-  default:                      *target = kCompositionGPU;        break;
-  }
-}
-
-void HWCDisplay::SetComposition(const LayerComposition &source, int32_t *target) {
-  switch (source) {
-  case kCompositionGPUTarget:   *target = HWC_FRAMEBUFFER_TARGET; break;
-  case kCompositionGPU:         *target = HWC_FRAMEBUFFER;        break;
-  case kCompositionGPUS3D:      *target = HWC_FRAMEBUFFER;        break;
-  case kCompositionCursor:      *target = HWC_CURSOR_OVERLAY;     break;
-  default:                      *target = HWC_OVERLAY;            break;
-  }
-}
-
-void HWCDisplay::SetBlending(const int32_t &source, LayerBlending *target) {
-  switch (source) {
-  case HWC_BLENDING_PREMULT:    *target = kBlendingPremultiplied;   break;
-  case HWC_BLENDING_COVERAGE:   *target = kBlendingCoverage;        break;
-  default:                      *target = kBlendingOpaque;          break;
-  }
-}
-
-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);
-  }
-
-  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_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;
-  default:
-    DLOGW("Unsupported format type = %d", source);
-    return kFormatInvalid;
-  }
-
-  return format;
-}
-
-void HWCDisplay::DumpInputBuffers(hwc_display_contents_1_t *content_list) {
-  size_t num_hw_layers = content_list->numHwLayers;
-  char dir_path[PATH_MAX];
-
-  if (!dump_frame_count_ || flush_ || !dump_input_layers_) {
-    return;
-  }
-
-  snprintf(dir_path, sizeof(dir_path), "/data/misc/display/frame_dump_%s", 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 < num_hw_layers; i++) {
-    hwc_layer_1_t &hwc_layer = content_list->hwLayers[i];
-    const private_handle_t *pvt_handle = static_cast<const private_handle_t *>(hwc_layer.handle);
-
-    if (hwc_layer.acquireFenceFd >= 0) {
-      int error = sync_wait(hwc_layer.acquireFenceFd, 1000);
-      if (error < 0) {
-        DLOGW("sync_wait error errno = %d, desc = %s", errno, strerror(errno));
-        return;
-      }
-    }
-
-    if (pvt_handle && pvt_handle->base) {
-      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);
-      }
-
-      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), "/data/misc/display/frame_dump_%s", 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.alloc_buffer_info.aligned_width,
-             buffer_info.alloc_buffer_info.aligned_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) {
-  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;
-  }
-
-  DLOGI("New framebuffer resolution (%dx%d)", x_pixels, 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(uint32_t display_status) {
-  int status = 0;
-  const hwc_procs_t *hwc_procs = *hwc_procs_;
-
-  switch (display_status) {
-  case kDisplayStatusResume:
-    display_paused_ = false;
-  case kDisplayStatusOnline:
-    status = SetPowerMode(HWC_POWER_MODE_NORMAL);
-    break;
-  case kDisplayStatusPause:
-    display_paused_ = true;
-  case kDisplayStatusOffline:
-    status = SetPowerMode(HWC_POWER_MODE_OFF);
-    break;
-  default:
-    DLOGW("Invalid display status %d", display_status);
-    return -EINVAL;
-  }
-
-  if (display_status == kDisplayStatusResume ||
-      display_status == kDisplayStatusPause) {
-    hwc_procs->invalidate(hwc_procs);
-  }
-
-  return status;
-}
-
-int HWCDisplay::SetCursorPosition(int x, int y) {
-  DisplayError error = kErrorNone;
-
-  if (shutdown_pending_) {
-    return 0;
-  }
-
-  error = display_intf_->SetCursorPosition(x, y);
-  if (error != kErrorNone) {
-    if (error == kErrorShutDown) {
-      shutdown_pending_ = true;
-      return 0;
-    }
-    DLOGE("Failed for x = %d y = %d, Error = %d", x, y, error);
-    return -1;
-  }
-
-  return 0;
-}
-
-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;
-  }
-
-  return 0;
-}
-
-void HWCDisplay::MarkLayersForGPUBypass(hwc_display_contents_1_t *content_list) {
-  for (size_t i = 0 ; i < (content_list->numHwLayers - 1); i++) {
-    hwc_layer_1_t *layer = &content_list->hwLayers[i];
-    layer->compositionType = HWC_OVERLAY;
-  }
-}
-
-void HWCDisplay::ApplyScanAdjustment(hwc_rect_t *display_frame) {
-}
-
-DisplayError HWCDisplay::SetCSC(const MetaData_t *meta_data, ColorMetaData *color_metadata) {
-  if (meta_data->operation & COLOR_METADATA) {
-#ifdef USE_COLOR_METADATA
-    *color_metadata = meta_data->color;
-#endif
-  } else if (meta_data->operation & UPDATE_COLOR_SPACE) {
-    ColorSpace_t csc = meta_data->colorSpace;
-    color_metadata->range = Range_Limited;
-
-    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:
-      // display driver uses 601 irrespective of 525 or 625
-      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;
-    }
-  }
-
-  return kErrorNone;
-}
-
-DisplayError HWCDisplay::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;
-}
-
-DisplayError HWCDisplay::SetMetaData(const private_handle_t *pvt_handle, Layer *layer) {
-  const MetaData_t *meta_data = reinterpret_cast<MetaData_t *>(pvt_handle->base_metadata);
-  LayerBuffer &layer_buffer = layer->input_buffer;
-
-  if (!meta_data) {
-    return kErrorNone;
-  }
-
-  if (SetCSC(meta_data, &layer_buffer.color_metadata) != kErrorNone) {
-    return kErrorNotSupported;
-  }
-
-  bool hdr_layer = layer_buffer.color_metadata.colorPrimaries == ColorPrimaries_BT2020 &&
-                   (layer_buffer.color_metadata.transfer == Transfer_SMPTE_ST2084 ||
-                   layer_buffer.color_metadata.transfer == Transfer_HLG);
-  if (hdr_layer && !disable_hdr_handling_) {
-    // dont honor HDR when its handling is disabled
-    layer_buffer.flags.hdr = true;
-    layer_stack_.flags.hdr_present = true;
-  }
-
-  if (meta_data->operation & SET_IGC) {
-    if (SetIGC(meta_data->igc, &layer_buffer.igc) != kErrorNone) {
-      return kErrorNotSupported;
-    }
-  }
-
-  if (meta_data->operation & UPDATE_REFRESH_RATE) {
-    layer->frame_rate = RoundToStandardFPS(meta_data->refreshrate);
-  }
-
-  if ((meta_data->operation & PP_PARAM_INTERLACED) && meta_data->interlaced) {
-    layer_buffer.flags.interlace = true;
-  }
-
-  if (meta_data->operation & LINEAR_FORMAT) {
-    layer_buffer.format = GetSDMFormat(INT32(meta_data->linearFormat), 0);
-  }
-
-  if (meta_data->operation & SET_SINGLE_BUFFER_MODE) {
-    layer->flags.single_buffer = meta_data->isSingleBufferMode;
-    // Graphics can set this operation on all types of layers including FB and set the actual value
-    // to 0. To protect against SET operations of 0 value, we need to do a logical OR.
-    layer_stack_.flags.single_buffered_layer_present |= meta_data->isSingleBufferMode;
-  }
-
-  if (meta_data->operation & S3D_FORMAT) {
-    std::map<int, LayerBufferS3DFormat>::iterator it =
-        s3d_format_hwc_to_sdm_.find(INT32(meta_data->s3dFormat));
-    if (it != s3d_format_hwc_to_sdm_.end()) {
-      layer->input_buffer.s3d_format = it->second;
-    } else {
-      DLOGW("Invalid S3D format %d", meta_data->s3dFormat);
-    }
-  }
-
-  return kErrorNone;
-}
-
-int HWCDisplay::SetPanelBrightness(int level) {
-  int ret = 0;
-  if (display_intf_)
-    ret = display_intf_->SetPanelBrightness(level);
-  else
-    ret = -EINVAL;
-
-  return ret;
-}
-
-int HWCDisplay::GetPanelBrightness(int *level) {
-  return display_intf_->GetPanelBrightness(level);
-}
-
-int HWCDisplay::CachePanelBrightness(int level) {
-  int ret = 0;
-  if (display_intf_)
-    ret = display_intf_->CachePanelBrightness(level);
-  else
-    ret = -EINVAL;
-
-  return ret;
-}
-
-int HWCDisplay::ToggleScreenUpdates(bool enable) {
-  const hwc_procs_t *hwc_procs = *hwc_procs_;
-  display_paused_ = enable ? false : true;
-  hwc_procs->invalidate(hwc_procs);
-  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;
-}
-
-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, bool force_flush) {
-  secure_display_active_ = secure_display_active;
-  return;
-}
-
-int HWCDisplay::SetActiveDisplayConfig(int config) {
-  return display_intf_->SetActiveConfig(UINT32(config)) == kErrorNone ? 0 : -1;
-}
-
-int HWCDisplay::GetActiveDisplayConfig(uint32_t *config) {
-  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;
-}
-
-int HWCDisplay::GetDisplayFixedConfig(DisplayConfigFixedInfo *fixed_info) {
-  return display_intf_->GetConfig(fixed_info) == kErrorNone ? 0 : -1;
-}
-
-// TODO(user): HWC needs to know updating for dyn_fps, cpu hint features,
-// once the features are moved to SDM, the two functions below can be removed.
-uint32_t HWCDisplay::GetUpdatingLayersCount(uint32_t app_layer_count) {
-  uint32_t updating_count = 0;
-
-  for (uint i = 0; i < app_layer_count; i++) {
-    Layer *layer = layer_stack_.layers.at(i);
-    if (layer->flags.updating) {
-      updating_count++;
-    }
-  }
-
-  return updating_count;
-}
-
-bool HWCDisplay::SingleVideoLayerUpdating(uint32_t app_layer_count) {
-  uint32_t updating_count = 0;
-
-  for (uint i = 0; i < app_layer_count; i++) {
-    Layer *layer = layer_stack_.layers[i];
-    // TODO(user): disable DRC feature in S3D playbacl case.S3D video
-    // need play in dedicate resolution and fps, if DRC switch the
-    // mode to an non S3D supported mode, it would break S3D playback.
-    // Need figure out a way to make S3D and DRC co-exist.
-    if (layer->flags.updating && (layer->input_buffer.flags.video == true) &&
-       (layer->input_buffer.s3d_format == kS3dFormatNone)) {
-      updating_count++;
-    }
-  }
-
-  return (updating_count == 1);
-}
-
-uint32_t HWCDisplay::RoundToStandardFPS(float fps) {
-  static const uint32_t standard_fps[4] = {30, 24, 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;
-}
-
-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_;
-}
-
-void HWCDisplay::PrepareDynamicRefreshRate(Layer *layer) {
-  if (layer->frame_rate > metadata_refresh_rate_) {
-    metadata_refresh_rate_ = SanitizeRefreshRate(layer->frame_rate);
-  } else {
-    layer->frame_rate = current_refresh_rate_;
-  }
-}
-
-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)));
-}
-
-int HWCDisplay::GetDisplayPort(DisplayPort *port) {
-  return display_intf_->GetDisplayPort(port) == kErrorNone ? 0 : -1;
-}
-
-
-}  // namespace sdm
diff --git a/sdm/libs/hwc/hwc_display_external.cpp b/sdm/libs/hwc/hwc_display_external.cpp
deleted file mode 100644
index da216f7..0000000
--- a/sdm/libs/hwc/hwc_display_external.cpp
+++ /dev/null
@@ -1,335 +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 <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, hwc_procs_t const **hwc_procs,
-                               qService::QService *qservice, HWCDisplay **hwc_display) {
-  return Create(core_intf, hwc_procs, 0, 0, qservice, false, hwc_display);
-}
-
-int HWCDisplayExternal::Create(CoreInterface *core_intf, hwc_procs_t const **hwc_procs,
-                               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;
-  int drc_enabled = 0;
-  int drc_reset_fps_enabled = 0;
-  DisplayError error = kErrorNone;
-
-  HWCDisplay *hwc_display_external = new HWCDisplayExternal(core_intf, hwc_procs, 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) {
-    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("sdm.debug.downscale_external", &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;
-  }
-
-  HWCDebugHandler::Get()->GetProperty("sdm.hdmi.drc_enabled", &(drc_enabled));
-  reinterpret_cast<HWCDisplayExternal *>(hwc_display_external)->drc_enabled_ = drc_enabled;
-
-  HWCDebugHandler::Get()->GetProperty("sdm.hdmi.drc_reset_fps", &(drc_reset_fps_enabled));
-  reinterpret_cast<HWCDisplayExternal *>(hwc_display_external)->drc_reset_fps_enabled_ =
-                                                                drc_reset_fps_enabled;
-
-  *hwc_display = hwc_display_external;
-
-  return status;
-}
-
-void HWCDisplayExternal::Destroy(HWCDisplay *hwc_display) {
-  hwc_display->Deinit();
-  delete hwc_display;
-}
-
-HWCDisplayExternal::HWCDisplayExternal(CoreInterface *core_intf, hwc_procs_t const **hwc_procs,
-                                       qService::QService *qservice)
-  : HWCDisplay(core_intf, hwc_procs, kHDMI, HWC_DISPLAY_EXTERNAL, false, qservice,
-               DISPLAY_CLASS_EXTERNAL) {
-}
-
-int HWCDisplayExternal::Prepare(hwc_display_contents_1_t *content_list) {
-  int status = 0;
-  DisplayError error = kErrorNone;
-
-  if (secure_display_active_) {
-    MarkLayersForGPUBypass(content_list);
-    return status;
-  }
-
-  status = AllocateLayerStack(content_list);
-  if (status) {
-    return status;
-  }
-
-  status = PrePrepareLayerStack(content_list);
-  if (status) {
-    return status;
-  }
-
-  if (content_list->numHwLayers <= 1) {
-    flush_ = true;
-    return 0;
-  }
-
-  bool one_video_updating_layer = SingleVideoLayerUpdating(UINT32(content_list->numHwLayers - 1));
-
-  uint32_t refresh_rate = GetOptimalRefreshRate(one_video_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;
-  }
-
-  status = PrepareLayerStack(content_list);
-  if (status) {
-    return status;
-  }
-
-  return 0;
-}
-
-int HWCDisplayExternal::Commit(hwc_display_contents_1_t *content_list) {
-  int status = 0;
-
-  if (secure_display_active_) {
-    return status;
-  }
-
-  status = HWCDisplay::CommitLayerStack(content_list);
-  if (status) {
-    return status;
-  }
-
-  status = HWCDisplay::PostCommitLayerStack(content_list);
-  if (status) {
-    return status;
-  }
-
-  return 0;
-}
-
-void HWCDisplayExternal::ApplyScanAdjustment(hwc_rect_t *display_frame) {
-  if (display_intf_->IsUnderscanSupported()) {
-    return;
-  }
-
-  // Read user defined width and height ratio
-  int width = 0, height = 0;
-  HWCDebugHandler::Get()->GetProperty("sdm.external_action_safe_width", &width);
-  float width_ratio = FLOAT(width) / 100.0f;
-  HWCDebugHandler::Get()->GetProperty("sdm.external_action_safe_height", &height);
-  float height_ratio = FLOAT(height) / 100.0f;
-
-  if (width_ratio == 0.0f ||  height_ratio == 0.0f) {
-    return;
-  }
-
-  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, bool force_flush) {
-  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;
-}
-
-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);
-  }
-}
-
-uint32_t HWCDisplayExternal::RoundToStandardFPS(float fps) {
-  static const uint32_t standard_fps[] = {23976, 24000, 25000, 29970, 30000, 50000, 59940, 60000};
-  static const uint32_t mapping_fps[] = {59940, 60000, 60000, 59940, 60000, 50000, 59940, 60000};
-  uint32_t frame_rate = (uint32_t)(fps * 1000);
-
-  // process non valid
-  if (frame_rate == 0) {
-    return current_refresh_rate_;
-  }
-
-  int count = INT(sizeof(standard_fps) / sizeof(standard_fps[0]));
-  for (int i = 0; i < count; i++) {
-    // Most likely used for video, the fps for frames should be stable from video side.
-    if (standard_fps[i] > frame_rate) {
-      if (i > 0) {
-        if ((standard_fps[i] - frame_rate) > (frame_rate - standard_fps[i-1])) {
-          return mapping_fps[i-1];
-        } else {
-          return mapping_fps[i];
-        }
-      } else {
-        return mapping_fps[i];
-      }
-    }
-  }
-
-  return standard_fps[count - 1];
-}
-
-void HWCDisplayExternal::PrepareDynamicRefreshRate(Layer *layer) {
-  if (layer->input_buffer.flags.video) {
-    if (layer->frame_rate != 0) {
-      metadata_refresh_rate_ = SanitizeRefreshRate(layer->frame_rate);
-    } else {
-      metadata_refresh_rate_ = current_refresh_rate_;
-    }
-    layer->frame_rate = current_refresh_rate_;
-  } else if (!layer->frame_rate) {
-    layer->frame_rate = current_refresh_rate_;
-  }
-}
-
-void HWCDisplayExternal::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;
-}
-
-uint32_t HWCDisplayExternal::GetOptimalRefreshRate(bool one_updating_layer) {
-  if (force_refresh_rate_) {
-    return force_refresh_rate_;
-  } else if (one_updating_layer && drc_enabled_) {
-    return metadata_refresh_rate_;
-  }
-
-  if (drc_reset_fps_enabled_) {
-    DisplayConfigVariableInfo fb_config;
-    display_intf_->GetFrameBufferConfig(&fb_config);
-    return (fb_config.fps * 1000);
-  }
-
-  return current_refresh_rate_;
-}
-
-int HWCDisplayExternal::Perform(uint32_t operation, ...) {
-  va_list args;
-  va_start(args, operation);
-  int val = va_arg(args, int32_t);
-  va_end(args);
-  switch (operation) {
-    case SET_BINDER_DYN_REFRESH_RATE:
-      ForceRefreshRate(UINT32(val));
-      break;
-    default:
-      DLOGW("Invalid operation %d", operation);
-      return -EINVAL;
-  }
-
-  return 0;
-}
-
-}  // namespace sdm
-
diff --git a/sdm/libs/hwc/hwc_display_external_test.cpp b/sdm/libs/hwc/hwc_display_external_test.cpp
deleted file mode 100644
index e629cd6..0000000
--- a/sdm/libs/hwc/hwc_display_external_test.cpp
+++ /dev/null
@@ -1,764 +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, hwc_procs_t const **hwc_procs,
-                                   qService::QService *qservice, uint32_t panel_bpp,
-                                   uint32_t pattern_type, HWCDisplay **hwc_display) {
-  HWCDisplay *hwc_external_test = new HWCDisplayExternalTest(core_intf, hwc_procs, 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;
-
-  DLOGI("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,
-                                               hwc_procs_t const **hwc_procs,
-                                               qService::QService *qservice, uint32_t panel_bpp,
-                                               uint32_t pattern_type)
-  : HWCDisplay(core_intf, hwc_procs, kHDMI, HWC_DISPLAY_EXTERNAL, false, qservice,
-               DISPLAY_CLASS_EXTERNAL), 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) {
-    return status;
-  }
-
-  buffer_allocator_ = new HWCBufferAllocator();
-
-  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();
-    return status;
-  }
-
-  return status;
-}
-
-int HWCDisplayExternalTest::Deinit() {
-  DestroyLayerStack();
-
-  delete buffer_allocator_;
-  buffer_allocator_ = NULL;
-
-  return HWCDisplay::Deinit();
-}
-
-
-int HWCDisplayExternalTest::Prepare(hwc_display_contents_1_t *content_list) {
-  int status = 0;
-
-  if (secure_display_active_) {
-    MarkLayersForGPUBypass(content_list);
-    return status;
-  }
-
-  if (!content_list || !content_list->numHwLayers) {
-    DLOGW("Invalid content list");
-    return -EINVAL;
-  }
-
-  if (shutdown_pending_) {
-    return 0;
-  }
-
-  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(content_list);
-
-  return 0;
-}
-
-int HWCDisplayExternalTest::Commit(hwc_display_contents_1_t *content_list) {
-  int status = 0;
-
-  if (secure_display_active_) {
-    return status;
-  }
-
-  if (!content_list || !content_list->numHwLayers) {
-    DLOGW("Invalid content list");
-    return -EINVAL;
-  }
-
-  if (shutdown_pending_) {
-    return 0;
-  }
-
-  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;
-        return status;
-      } 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;
-      }
-    }
-  }
-
-  return PostCommit(content_list);
-}
-
-void HWCDisplayExternalTest::SetSecureDisplay(bool secure_display_active, bool force_flush) {
-  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/misc/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;
-    }
-
-    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;
-}
-
-int HWCDisplayExternalTest::PostCommit(hwc_display_contents_1_t *content_list) {
-  int status = 0;
-
-  // 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;
-    content_list->retireFenceFd = -1;
-  }
-
-  flush_ = false;
-
-  return status;
-}
-
-}  // namespace sdm
-
diff --git a/sdm/libs/hwc/hwc_display_primary.cpp b/sdm/libs/hwc/hwc_display_primary.cpp
deleted file mode 100644
index 8d6f31b..0000000
--- a/sdm/libs/hwc/hwc_display_primary.cpp
+++ /dev/null
@@ -1,563 +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 <cutils/properties.h>
-#include <sync/sync.h>
-#include <utils/constants.h>
-#include <utils/debug.h>
-#include <stdarg.h>
-#include <sys/mman.h>
-
-#include <gr.h>
-#include "hwc_display_primary.h"
-#include "hwc_debugger.h"
-
-#define __CLASS__ "HWCDisplayPrimary"
-
-namespace sdm {
-
-int HWCDisplayPrimary::Create(CoreInterface *core_intf, BufferAllocator *buffer_allocator,
-                              hwc_procs_t const **hwc_procs, 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,
-                                                          hwc_procs, 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("sdm.fb_size_width", &width);
-  HWCDebugHandler::Get()->GetProperty("sdm.fb_size_height", &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,
-                                     hwc_procs_t const **hwc_procs,
-                                     qService::QService *qservice)
-  : HWCDisplay(core_intf, hwc_procs, kPrimary, HWC_DISPLAY_PRIMARY, true, qservice,
-               DISPLAY_CLASS_PRIMARY), buffer_allocator_(buffer_allocator) {
-}
-
-int HWCDisplayPrimary::Init() {
-  cpu_hint_.Init(static_cast<HWCDebugHandler*>(HWCDebugHandler::Get()));
-
-  use_metadata_refresh_rate_ = true;
-  int disable_metadata_dynfps = 0;
-  HWCDebugHandler::Get()->GetProperty("persist.metadata_dynfps.disable", &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();
-
-  return status;
-}
-
-int HWCDisplayPrimary::Deinit() {
-  color_mode_->DeInit();
-  delete color_mode_;
-  color_mode_ = NULL;
-
-  return HWCDisplay::Deinit();
-}
-
-
-void HWCDisplayPrimary::ProcessBootAnimCompleted(hwc_display_contents_1_t *list) {
-  uint32_t numBootUpLayers = 0;
-
-  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 cryptoState[PROPERTY_VALUE_MAX];
-  char voldDecryptState[PROPERTY_VALUE_MAX];
-  bool isEncrypted = false;
-  bool main_class_services_started = false;
-  if (property_get("ro.crypto.state", cryptoState, "unencrypted")) {
-    if (!strcmp(cryptoState, "encrypted")) {
-      isEncrypted = true;
-      if (property_get("vold.decrypt", voldDecryptState, "") &&
-            !strcmp(voldDecryptState, "trigger_restart_framework"))
-        main_class_services_started = true;
-    }
-  }
-  if ((!isEncrypted ||(isEncrypted && main_class_services_started)) &&
-    (list->numHwLayers > numBootUpLayers)) {
-    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();
-  }
-}
-
-int HWCDisplayPrimary::Prepare(hwc_display_contents_1_t *content_list) {
-  int status = 0;
-  DisplayError error = kErrorNone;
-
-  if (!boot_animation_completed_)
-    ProcessBootAnimCompleted(content_list);
-
-  if (display_paused_) {
-    MarkLayersForGPUBypass(content_list);
-    return status;
-  }
-
-  status = AllocateLayerStack(content_list);
-  if (status) {
-    return status;
-  }
-
-  status = PrePrepareLayerStack(content_list);
-  if (status) {
-    return status;
-  }
-
-  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(UINT32(content_list->numHwLayers - 1));
-  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 (content_list->numHwLayers <= 1) {
-    flush_ = true;
-  }
-
-  status = PrepareLayerStack(content_list);
-  if (status) {
-    return status;
-  }
-
-  return 0;
-}
-
-int HWCDisplayPrimary::Commit(hwc_display_contents_1_t *content_list) {
-  int status = 0;
-
-  DisplayConfigFixedInfo display_config;
-  display_intf_->GetConfig(&display_config);
-  if (content_list->numHwLayers <= 1 && display_config.is_cmdmode) {
-    DLOGV("Skipping null commit on cmd mode panel");
-    flush_ = false;
-    return 0;
-  }
-
-  if (display_paused_) {
-    if (content_list->outbufAcquireFenceFd >= 0) {
-      // If we do not handle the frame set retireFenceFd to outbufAcquireFenceFd,
-      // which will make sure the framework waits on it and closes it.
-      content_list->retireFenceFd = dup(content_list->outbufAcquireFenceFd);
-      close(content_list->outbufAcquireFenceFd);
-      content_list->outbufAcquireFenceFd = -1;
-    }
-
-    DisplayError error = display_intf_->Flush();
-    if (error != kErrorNone) {
-      DLOGE("Flush failed. Error = %d", error);
-    }
-    return status;
-  }
-
-  status = HWCDisplay::CommitLayerStack(content_list);
-  if (status) {
-    return status;
-  }
-
-  HandleFrameOutput();
-
-  status = HWCDisplay::PostCommitLayerStack(content_list);
-  if (status) {
-    return status;
-  }
-
-  return 0;
-}
-
-int HWCDisplayPrimary::Perform(uint32_t operation, ...) {
-  va_list args;
-  va_start(args, operation);
-  int val = va_arg(args, int32_t);
-  va_end(args);
-  switch (operation) {
-    case SET_METADATA_DYN_REFRESH_RATE:
-      SetMetaDataRefreshRateFlag(val);
-      break;
-    case SET_BINDER_DYN_REFRESH_RATE:
-      ForceRefreshRate(UINT32(val));
-      break;
-    case SET_DISPLAY_MODE:
-      SetDisplayMode(UINT32(val));
-      break;
-    case SET_QDCM_SOLID_FILL_INFO:
-      SetQDCMSolidFillInfo(true, UINT32(val));
-      break;
-    case UNSET_QDCM_SOLID_FILL_INFO:
-      SetQDCMSolidFillInfo(false, UINT32(val));
-      break;
-    default:
-      DLOGW("Invalid operation %d", operation);
-      return -EINVAL;
-  }
-
-  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("persist.metadata_dynfps.disable", &disable_metadata_dynfps);
-  if (disable_metadata_dynfps) {
-    return;
-  }
-  use_metadata_refresh_rate_ = enable;
-}
-
-void HWCDisplayPrimary::SetQDCMSolidFillInfo(bool enable, uint32_t color) {
-  solid_fill_enable_ = enable;
-  solid_fill_color_  = color;
-}
-
-void HWCDisplayPrimary::ToggleCPUHint(bool set) {
-  if (set) {
-    cpu_hint_.Set();
-  } else {
-    cpu_hint_.Reset();
-  }
-}
-
-void HWCDisplayPrimary::SetSecureDisplay(bool secure_display_active, bool force_flush) {
-  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;
-    skip_prepare_cnt = 1;
-
-    // Issue two null commits for command mode panels when external displays are connected.
-    // Two null commits are required to handle non secure to secure transitions at 30fps.
-    // TODO(user): Need two null commits on video mode also to handle transition cases of
-    // primary at higher fps (ex60) and external at lower fps.
-
-    // Avoid flush for command mode panels when no external displays are connected.
-    // This is to avoid flicker/blink on primary during transitions.
-    DisplayConfigFixedInfo display_config;
-    display_intf_->GetConfig(&display_config);
-    if (display_config.is_cmdmode) {
-      if (force_flush) {
-        DLOGI("Issue two null commits for command mode panels");
-        skip_prepare_cnt = 2;
-      } else {
-        DLOGI("Avoid flush for command mode panel when no external displays are connected");
-        skip_prepare_cnt = 0;
-      }
-    }
-  }
-}
-
-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;
-  }
-
-  const hwc_procs_t *hwc_procs = *hwc_procs_;
-  force_refresh_rate_ = refresh_rate;
-
-  hwc_procs->invalidate(hwc_procs);
-
-  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() {
-  const hwc_procs_t *hwc_procs = *hwc_procs_;
-  DisplayError error = kErrorNone;
-
-  if (!hwc_procs) {
-    return kErrorParameters;
-  }
-
-  hwc_procs->invalidate(hwc_procs);
-
-  return error;
-}
-
-void HWCDisplayPrimary::SetIdleTimeoutMs(uint32_t timeout_ms) {
-  display_intf_->SetIdleTimeoutMs(timeout_ms);
-}
-
-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;
-  }
-}
-
-void 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;
-  }
-
-  // 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;
-  }
-
-  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;
-  }
-
-  output_buffer_base_ = buffer;
-  post_processed_output_ = true;
-  DisablePartialUpdateOneFrame();
-}
-
-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);
-  }
-  return error;
-}
-
-DisplayError HWCDisplayPrimary::ControlPartialUpdate(bool enable, uint32_t *pending) {
-  DisplayError error = kErrorNone;
-
-  if (display_intf_) {
-    error = display_intf_->ControlPartialUpdate(enable, pending);
-  }
-
-  return error;
-}
-
-DisplayError HWCDisplayPrimary::DisablePartialUpdateOneFrame() {
-  DisplayError error = kErrorNone;
-
-  if (display_intf_) {
-    error = display_intf_->DisablePartialUpdateOneFrame();
-  }
-
-  return error;
-}
-
-DisplayError HWCDisplayPrimary::SetMixerResolution(uint32_t width, uint32_t height) {
-  return display_intf_->SetMixerResolution(width, height);
-}
-
-DisplayError HWCDisplayPrimary::GetMixerResolution(uint32_t *width, uint32_t *height) {
-  return display_intf_->GetMixerResolution(width, height);
-}
-
-}  // namespace sdm
-
diff --git a/sdm/libs/hwc/hwc_display_primary.h b/sdm/libs/hwc/hwc_display_primary.h
deleted file mode 100644
index e937980..0000000
--- a/sdm/libs/hwc/hwc_display_primary.h
+++ /dev/null
@@ -1,90 +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 __HWC_DISPLAY_PRIMARY_H__
-#define __HWC_DISPLAY_PRIMARY_H__
-
-#include "cpuhint.h"
-#include "hwc_display.h"
-
-namespace sdm {
-
-class HWCDisplayPrimary : public HWCDisplay {
- public:
-  static int Create(CoreInterface *core_intf, BufferAllocator *buffer_allocator,
-                    hwc_procs_t const **hwc_procs, qService::QService *qservice,
-                    HWCDisplay **hwc_display);
-  static void Destroy(HWCDisplay *hwc_display);
-  virtual int Init();
-  virtual int Deinit();
-  virtual int Prepare(hwc_display_contents_1_t *content_list);
-  virtual int Commit(hwc_display_contents_1_t *content_list);
-  virtual int Perform(uint32_t operation, ...);
-  virtual void SetSecureDisplay(bool secure_display_active, bool force_flush);
-  virtual DisplayError Refresh();
-  virtual void SetIdleTimeoutMs(uint32_t timeout_ms);
-  virtual void 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,
-                    hwc_procs_t const **hwc_procs, qService::QService *qservice);
-  void SetMetaDataRefreshRateFlag(bool enable);
-  virtual DisplayError SetDisplayMode(uint32_t mode);
-  virtual DisplayError DisablePartialUpdateOneFrame();
-  void ProcessBootAnimCompleted(hwc_display_contents_1_t *content_list);
-  void SetQDCMSolidFillInfo(bool enable, uint32_t 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_;
-
-  // 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;
-};
-
-}  // namespace sdm
-
-#endif  // __HWC_DISPLAY_PRIMARY_H__
-
diff --git a/sdm/libs/hwc/hwc_session.cpp b/sdm/libs/hwc/hwc_session.cpp
deleted file mode 100644
index 98e14ee..0000000
--- a/sdm/libs/hwc/hwc_session.cpp
+++ /dev/null
@@ -1,1743 +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 <core/dump_interface.h>
-#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 <gr.h>
-#include <gralloc_priv.h>
-#include <display_config.h>
-#include <utils/debug.h>
-#include <sync/sync.h>
-#include <profiler.h>
-#include <bitset>
-#include <vector>
-
-#include "hwc_buffer_allocator.h"
-#include "hwc_buffer_sync_handler.h"
-#include "hwc_session.h"
-#include "hwc_debugger.h"
-#include "hwc_display_null.h"
-#include "hwc_display_primary.h"
-#include "hwc_display_virtual.h"
-#include "hwc_display_external_test.h"
-#include "qd_utils.h"
-
-#define __CLASS__ "HWCSession"
-
-#define HWC_UEVENT_SWITCH_HDMI "change@/devices/virtual/switch/hdmi"
-#define HWC_UEVENT_GRAPHICS_FB0 "change@/devices/virtual/graphics/fb0"
-
-static sdm::HWCSession::HWCModuleMethods g_hwc_module_methods;
-
-hwc_module_t HAL_MODULE_INFO_SYM = {
-  .common = {
-    .tag = HARDWARE_MODULE_TAG,
-    .version_major = 2,
-    .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 {
-
-Locker HWCSession::locker_;
-
-static void Invalidate(const struct hwc_procs *procs) {
-}
-
-static void VSync(const struct hwc_procs* procs, int disp, int64_t timestamp) {
-}
-
-static void Hotplug(const struct hwc_procs* procs, int disp, int connected) {
-}
-
-HWCSession::HWCSession(const hw_module_t *module) {
-  // By default, drop any events. Calls will be routed to SurfaceFlinger after registerProcs.
-  hwc_procs_default_.invalidate = Invalidate;
-  hwc_procs_default_.vsync = VSync;
-  hwc_procs_default_.hotplug = Hotplug;
-
-  hwc_composer_device_1_t::common.tag = HARDWARE_DEVICE_TAG;
-  hwc_composer_device_1_t::common.version = HWC_DEVICE_API_VERSION_1_5;
-  hwc_composer_device_1_t::common.module = const_cast<hw_module_t*>(module);
-  hwc_composer_device_1_t::common.close = Close;
-  hwc_composer_device_1_t::prepare = Prepare;
-  hwc_composer_device_1_t::set = Set;
-  hwc_composer_device_1_t::eventControl = EventControl;
-  hwc_composer_device_1_t::setPowerMode = SetPowerMode;
-  hwc_composer_device_1_t::query = Query;
-  hwc_composer_device_1_t::registerProcs = RegisterProcs;
-  hwc_composer_device_1_t::dump = Dump;
-  hwc_composer_device_1_t::getDisplayConfigs = GetDisplayConfigs;
-  hwc_composer_device_1_t::getDisplayAttributes = GetDisplayAttributes;
-  hwc_composer_device_1_t::getActiveConfig = GetActiveConfig;
-  hwc_composer_device_1_t::setActiveConfig = SetActiveConfig;
-  hwc_composer_device_1_t::setCursorPositionAsync = SetCursorPositionAsync;
-}
-
-int HWCSession::Init() {
-  int status = -EINVAL;
-  const char *qservice_name = "display.qservice";
-
-  // 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;
-  }
-
-  DisplayError error = CoreInterface::CreateCore(HWCDebugHandler::Get(), &buffer_allocator_,
-                                                 &buffer_sync_handler_, &socket_handler_,
-                                                 &core_intf_);
-  if (error != kErrorNone) {
-    DLOGE("Display core initialization failed. Error = %d", error);
-    return -EINVAL;
-  }
-
-  SCOPE_LOCK(uevent_locker_);
-
-  if (pthread_create(&uevent_thread_, NULL, &HWCUeventThread, this) < 0) {
-    DLOGE("Failed to start = %s, error = %s", uevent_thread_name_, strerror(errno));
-    CoreInterface::DestroyCore();
-    return -errno;
-  }
-
-  // Wait for uevent_init() to happen and let the uevent thread wait for uevents, so that hdmi
-  // connect/disconnect events won't be missed
-  uevent_locker_.Wait();
-
-  // Read which display is first, and create it and store it in primary slot
-  HWDisplayInterfaceInfo hw_disp_info;
-  error = core_intf_->GetFirstDisplayInterfaceType(&hw_disp_info);
-  if (error == kErrorNone) {
-    if (hw_disp_info.type == kHDMI) {
-      // HDMI is primary display. If already connected, then create it and store in
-      // primary display slot. If not connected, create a NULL display for now.
-      HWCDebugHandler::Get()->SetProperty("persist.sys.is_hdmi_primary", "1");
-      is_hdmi_primary_ = true;
-      if (hw_disp_info.is_connected) {
-        status = CreateExternalDisplay(HWC_DISPLAY_PRIMARY, 0, 0, false);
-        is_hdmi_yuv_ = IsDisplayYUV(HWC_DISPLAY_PRIMARY);
-      } else {
-        // NullDisplay simply closes all its fences, and advertizes a standard
-        // resolution to SurfaceFlinger
-        status = HWCDisplayNull::Create(core_intf_, &hwc_procs_,
-                                        &hwc_display_[HWC_DISPLAY_PRIMARY]);
-      }
-    } else {
-      // Create and power on primary display
-      status = HWCDisplayPrimary::Create(core_intf_, &buffer_allocator_, &hwc_procs_, qservice_,
-                                         &hwc_display_[HWC_DISPLAY_PRIMARY]);
-    }
-  } else {
-    // Create and power on primary display
-    status = HWCDisplayPrimary::Create(core_intf_, &buffer_allocator_, &hwc_procs_, qservice_,
-                                       &hwc_display_[HWC_DISPLAY_PRIMARY]);
-  }
-
-  if (status) {
-    CoreInterface::DestroyCore();
-    uevent_thread_exit_ = true;
-    pthread_join(uevent_thread_, NULL);
-    return status;
-  }
-
-  color_mgr_ = HWCColorManager::CreateColorManager();
-  if (!color_mgr_) {
-    DLOGW("Failed to load HWCColorManager.");
-  }
-
-  connected_displays_[HWC_DISPLAY_PRIMARY] = 1;
-  struct rlimit fd_limit = {};
-  getrlimit(RLIMIT_NOFILE, &fd_limit);
-  fd_limit.rlim_cur = fd_limit.rlim_cur * 2;
-  auto err = setrlimit(RLIMIT_NOFILE, &fd_limit);
-  if (err) {
-    DLOGW("Unable to increase fd limit -  err: %d, %s", errno, strerror(errno));
-  }
-  return 0;
-}
-
-int HWCSession::Deinit() {
-  HWCDisplayPrimary::Destroy(hwc_display_[HWC_DISPLAY_PRIMARY]);
-  hwc_display_[HWC_DISPLAY_PRIMARY] = 0;
-  if (color_mgr_) {
-    color_mgr_->DestroyColorManager();
-  }
-  uevent_thread_exit_ = true;
-  pthread_join(uevent_thread_, NULL);
-
-  DisplayError error = CoreInterface::DestroyCore();
-  if (error != kErrorNone) {
-    DLOGE("Display core de-initialization failed. Error = %d", error);
-  }
-
-  connected_displays_[HWC_DISPLAY_PRIMARY] = 0;
-  return 0;
-}
-
-int HWCSession::Open(const hw_module_t *module, const char *name, hw_device_t **device) {
-  SEQUENCE_WAIT_SCOPE_LOCK(locker_);
-
-  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;
-      return status;
-    }
-
-    hwc_composer_device_1_t *composer_device = hwc_session;
-    *device = reinterpret_cast<hw_device_t *>(composer_device);
-  }
-
-  return 0;
-}
-
-int HWCSession::Close(hw_device_t *device) {
-  SEQUENCE_WAIT_SCOPE_LOCK(locker_);
-
-  if (!device) {
-    return -EINVAL;
-  }
-
-  hwc_composer_device_1_t *composer_device = reinterpret_cast<hwc_composer_device_1_t *>(device);
-  HWCSession *hwc_session = static_cast<HWCSession *>(composer_device);
-
-  hwc_session->Deinit();
-  delete hwc_session;
-
-  return 0;
-}
-
-int HWCSession::Prepare(hwc_composer_device_1 *device, size_t num_displays,
-                        hwc_display_contents_1_t **displays) {
-  DTRACE_SCOPED();
-
-  if (!device || !displays || num_displays > HWC_NUM_DISPLAY_TYPES) {
-    return -EINVAL;
-  }
-
-  HWCSession *hwc_session = static_cast<HWCSession *>(device);
-  hwc_procs_t const *hwc_procs = NULL;
-  bool hotplug_connect = false;
-
-  // Hold mutex only in this scope.
-  {
-    SEQUENCE_ENTRY_SCOPE_LOCK(locker_);
-
-    hwc_procs = hwc_session->hwc_procs_;
-
-    if (hwc_session->reset_panel_) {
-      DLOGW("panel is in bad state, resetting the panel");
-      hwc_session->ResetPanel();
-    }
-
-    if (hwc_session->need_invalidate_) {
-      hwc_session->AsyncRefresh();
-      hwc_session->need_invalidate_ = false;
-    }
-
-    hwc_session->HandleSecureDisplaySession(displays);
-
-    if (hwc_session->color_mgr_) {
-      HWCDisplay *primary_display = hwc_session->hwc_display_[HWC_DISPLAY_PRIMARY];
-      if (primary_display && !hwc_session->is_hdmi_primary_) {
-        int ret = hwc_session->color_mgr_->SolidFillLayersPrepare(displays, primary_display);
-        if (ret)
-          return 0;
-      }
-    }
-
-    for (ssize_t dpy = static_cast<ssize_t>(num_displays - 1); dpy >= 0; dpy--) {
-      hwc_display_contents_1_t *content_list = displays[dpy];
-      // If external display is connected, ignore virtual display content list.
-      // If virtual display content list is valid, connect virtual display if not connected.
-      // If virtual display content list is invalid, disconnect virtual display if connected.
-      // If external display connection is pending, connect external display when virtual
-      // display is destroyed.
-      // If HDMI is primary and the output format is YUV then ignore the virtual display
-      // content list.
-      if (dpy == HWC_DISPLAY_VIRTUAL) {
-        if (hwc_session->hwc_display_[HWC_DISPLAY_EXTERNAL] ||
-                (hwc_session->is_hdmi_primary_ && hwc_session->is_hdmi_yuv_)) {
-          continue;
-        }
-
-        bool valid_content = HWCDisplayVirtual::IsValidContentList(content_list);
-        bool connected = (hwc_session->hwc_display_[HWC_DISPLAY_VIRTUAL] != NULL);
-
-        if (valid_content && !connected) {
-          hwc_session->ConnectDisplay(HWC_DISPLAY_VIRTUAL, content_list);
-        } else if (!valid_content && connected) {
-          hwc_session->DisconnectDisplay(HWC_DISPLAY_VIRTUAL);
-
-          if (hwc_session->external_pending_connect_) {
-            DLOGI("Process pending external display connection");
-            hwc_session->ConnectDisplay(HWC_DISPLAY_EXTERNAL, NULL);
-            hwc_session->external_pending_connect_ = false;
-            hotplug_connect = true;
-          }
-        }
-      }
-
-      if (hwc_session->hwc_display_[dpy]) {
-        if (!content_list) {
-          DLOGI("Display[%d] connected. content_list is null", dpy);
-        } else if (!content_list->numHwLayers) {
-          DLOGE("Display[%d] connected. numHwLayers is zero", dpy);
-        } else {
-          hwc_session->hwc_display_[dpy]->Prepare(content_list);
-        }
-      }
-    }
-  }
-
-  if (hotplug_connect) {
-    // notify client
-    hwc_procs->hotplug(hwc_procs, HWC_DISPLAY_EXTERNAL, true);
-  }
-  // Return 0, else client will go into bad state
-  return 0;
-}
-
-int HWCSession::GetVsyncPeriod(int disp) {
-  SCOPE_LOCK(locker_);
-  // default value
-  int32_t vsync_period = 1000000000l / 60;
-  const uint32_t attribute = HWC_DISPLAY_VSYNC_PERIOD;
-
-  if (hwc_display_[disp]) {
-    hwc_display_[disp]->GetDisplayAttributes(0, &attribute, &vsync_period);
-  }
-
-  return vsync_period;
-}
-
-int HWCSession::Set(hwc_composer_device_1 *device, size_t num_displays,
-                    hwc_display_contents_1_t **displays) {
-  DTRACE_SCOPED();
-
-  SEQUENCE_EXIT_SCOPE_LOCK(locker_);
-
-  if (!device || !displays || num_displays > HWC_NUM_DISPLAY_TYPES) {
-    return -EINVAL;
-  }
-
-  HWCSession *hwc_session = static_cast<HWCSession *>(device);
-
-  if (hwc_session->color_mgr_) {
-    HWCDisplay *primary_display = hwc_session->hwc_display_[HWC_DISPLAY_PRIMARY];
-    if (primary_display) {
-      int ret = hwc_session->color_mgr_->SolidFillLayersSet(displays, primary_display);
-      if (ret)
-        return 0;
-      hwc_session->color_mgr_->SetColorModeDetailEnhancer(primary_display);
-    }
-  }
-
-  for (size_t dpy = 0; dpy < num_displays; dpy++) {
-    hwc_display_contents_1_t *content_list = displays[dpy];
-
-    // Drop virtual display composition if virtual display object could not be created
-    // due to HDMI concurrency.
-    if (dpy == HWC_DISPLAY_VIRTUAL && !hwc_session->hwc_display_[HWC_DISPLAY_VIRTUAL]) {
-      CloseAcquireFds(content_list);
-      if (content_list) {
-        content_list->retireFenceFd = -1;
-      }
-
-      continue;
-    }
-
-    if (hwc_session->hwc_display_[dpy]) {
-      hwc_session->hwc_display_[dpy]->Commit(content_list);
-    }
-    CloseAcquireFds(content_list);
-  }
-
-  if (hwc_session->new_bw_mode_) {
-    hwc_display_contents_1_t *content_list = displays[HWC_DISPLAY_PRIMARY];
-    hwc_session->new_bw_mode_ = false;
-    if (hwc_session->bw_mode_release_fd_ >= 0) {
-      close(hwc_session->bw_mode_release_fd_);
-    }
-    hwc_session->bw_mode_release_fd_ = dup(content_list->retireFenceFd);
-  }
-
-  locker_.Signal();
-
-  // This is only indicative of how many times SurfaceFlinger posts
-  // frames to the display.
-  CALC_FPS();
-
-  // Return 0, else client will go into bad state
-  return 0;
-}
-
-void HWCSession::CloseAcquireFds(hwc_display_contents_1_t *content_list) {
-  if (content_list) {
-    for (size_t i = 0; i < content_list->numHwLayers; i++) {
-      int &acquireFenceFd = content_list->hwLayers[i].acquireFenceFd;
-      if (acquireFenceFd >= 0) {
-        close(acquireFenceFd);
-        acquireFenceFd = -1;
-      }
-    }
-
-    int &outbufAcquireFenceFd = content_list->outbufAcquireFenceFd;
-    if (outbufAcquireFenceFd >= 0) {
-      close(outbufAcquireFenceFd);
-      outbufAcquireFenceFd = -1;
-    }
-  }
-}
-
-bool HWCSession::IsDisplayYUV(int disp) {
-  int error = -EINVAL;
-  bool is_yuv = false;
-  DisplayConfigVariableInfo attributes = {};
-
-  if (disp < 0 || disp >= HWC_NUM_DISPLAY_TYPES || !hwc_display_[disp]) {
-    DLOGE("Invalid input parameters. Display = %d", disp);
-    return is_yuv;
-  }
-
-  uint32_t active_config = 0;
-  error = hwc_display_[disp]->GetActiveDisplayConfig(&active_config);
-  if (!error) {
-    error = hwc_display_[disp]->GetDisplayAttributesForConfig(INT(active_config), &attributes);
-    if (error == 0) {
-      is_yuv = attributes.is_yuv;
-    } else {
-      DLOGW("Error querying display attributes. Display = %d, Config = %d", disp, active_config);
-    }
-  }
-
-  return is_yuv;
-}
-
-int HWCSession::EventControl(hwc_composer_device_1 *device, int disp, int event, int enable) {
-  SCOPE_LOCK(locker_);
-
-  if (!device) {
-    return -EINVAL;
-  }
-
-  HWCSession *hwc_session = static_cast<HWCSession *>(device);
-  int status = -EINVAL;
-  if (hwc_session->hwc_display_[disp]) {
-    status = hwc_session->hwc_display_[disp]->EventControl(event, enable);
-  }
-
-  return status;
-}
-
-int HWCSession::SetPowerMode(hwc_composer_device_1 *device, int disp, int mode) {
-  SEQUENCE_WAIT_SCOPE_LOCK(locker_);
-
-  if (!device) {
-    return -EINVAL;
-  }
-
-  HWCSession *hwc_session = static_cast<HWCSession *>(device);
-  int status = -EINVAL;
-  if (hwc_session->hwc_display_[disp]) {
-    status = hwc_session->hwc_display_[disp]->SetPowerMode(mode);
-  }
-
-  return status;
-}
-
-int HWCSession::Query(hwc_composer_device_1 *device, int param, int *value) {
-  SCOPE_LOCK(locker_);
-
-  if (!device || !value) {
-    return -EINVAL;
-  }
-
-  int status = 0;
-
-  switch (param) {
-  case HWC_BACKGROUND_LAYER_SUPPORTED:
-    value[0] = 1;
-    break;
-
-  default:
-    status = -EINVAL;
-  }
-
-  return status;
-}
-
-void HWCSession::RegisterProcs(hwc_composer_device_1 *device, hwc_procs_t const *procs) {
-  SCOPE_LOCK(locker_);
-
-  if (!device || !procs) {
-    return;
-  }
-
-  HWCSession *hwc_session = static_cast<HWCSession *>(device);
-  hwc_session->hwc_procs_ = procs;
-}
-
-void HWCSession::Dump(hwc_composer_device_1 *device, char *buffer, int length) {
-  SEQUENCE_WAIT_SCOPE_LOCK(locker_);
-
-  if (!device || !buffer || !length) {
-    return;
-  }
-
-  DumpInterface::GetDump(buffer, UINT32(length));
-}
-
-int HWCSession::GetDisplayConfigs(hwc_composer_device_1 *device, int disp, uint32_t *configs,
-                                  size_t *num_configs) {
-  SCOPE_LOCK(locker_);
-
-  if (!device || !configs || !num_configs) {
-    return -EINVAL;
-  }
-
-  if (disp < HWC_DISPLAY_PRIMARY || disp >  HWC_NUM_PHYSICAL_DISPLAY_TYPES) {
-    return -EINVAL;
-  }
-
-  HWCSession *hwc_session = static_cast<HWCSession *>(device);
-  int status = -EINVAL;
-  if (hwc_session->hwc_display_[disp]) {
-    status = hwc_session->hwc_display_[disp]->GetDisplayConfigs(configs, num_configs);
-  }
-
-  return status;
-}
-
-int HWCSession::GetDisplayAttributes(hwc_composer_device_1 *device, int disp, uint32_t config,
-                                     const uint32_t *display_attributes, int32_t *values) {
-  SCOPE_LOCK(locker_);
-
-  if (!device || !display_attributes || !values) {
-    return -EINVAL;
-  }
-
-  if (disp < HWC_DISPLAY_PRIMARY || disp >  HWC_NUM_PHYSICAL_DISPLAY_TYPES) {
-    return -EINVAL;
-  }
-
-  HWCSession *hwc_session = static_cast<HWCSession *>(device);
-  int status = -EINVAL;
-  if (hwc_session->hwc_display_[disp]) {
-    status = hwc_session->hwc_display_[disp]->GetDisplayAttributes(config, display_attributes,
-                                                                   values);
-  }
-
-  return status;
-}
-
-int HWCSession::GetActiveConfig(hwc_composer_device_1 *device, int disp) {
-  SCOPE_LOCK(locker_);
-
-  if (!device) {
-    return -EINVAL;
-  }
-
-  if (disp < HWC_DISPLAY_PRIMARY || disp >  HWC_NUM_PHYSICAL_DISPLAY_TYPES) {
-    return -EINVAL;
-  }
-
-  HWCSession *hwc_session = static_cast<HWCSession *>(device);
-  int active_config = -1;
-  if (hwc_session->hwc_display_[disp]) {
-    active_config = hwc_session->hwc_display_[disp]->GetActiveConfig();
-  }
-
-  return active_config;
-}
-
-int HWCSession::SetActiveConfig(hwc_composer_device_1 *device, int disp, int index) {
-  SEQUENCE_WAIT_SCOPE_LOCK(locker_);
-
-  if (!device) {
-    return -EINVAL;
-  }
-
-  if (disp < HWC_DISPLAY_PRIMARY || disp >  HWC_NUM_PHYSICAL_DISPLAY_TYPES) {
-    return -EINVAL;
-  }
-
-  HWCSession *hwc_session = static_cast<HWCSession *>(device);
-  int status = -EINVAL;
-
-  if (hwc_session->hwc_display_[disp]) {
-    status = hwc_session->hwc_display_[disp]->SetActiveConfig(index);
-  }
-
-  return status;
-}
-
-int HWCSession::SetCursorPositionAsync(hwc_composer_device_1 *device, int disp, int x, int y) {
-  DTRACE_SCOPED();
-
-  SCOPE_LOCK(locker_);
-
-  if (!device || (disp < HWC_DISPLAY_PRIMARY) || (disp > HWC_DISPLAY_VIRTUAL)) {
-    return -EINVAL;
-  }
-
-  int status = -EINVAL;
-  HWCSession *hwc_session = static_cast<HWCSession *>(device);
-  if (hwc_session->hwc_display_[disp]) {
-    status = hwc_session->hwc_display_[disp]->SetCursorPosition(x, y);
-  }
-
-  return status;
-}
-
-int HWCSession::ConnectDisplay(int disp, hwc_display_contents_1_t *content_list) {
-  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);
-    connected_displays_[HWC_DISPLAY_EXTERNAL] = 1;
-  } else if (disp == HWC_DISPLAY_VIRTUAL) {
-    status = HWCDisplayVirtual::Create(core_intf_, &hwc_procs_, primary_width, primary_height,
-                                       content_list, &hwc_display_[disp]);
-    connected_displays_[HWC_DISPLAY_VIRTUAL] = 1;
-  } else {
-    DLOGE("Invalid display type");
-    return -1;
-  }
-
-  if (!status) {
-    hwc_display_[disp]->SetSecureDisplay(secure_display_active_, true);
-  }
-
-  return status;
-}
-
-int HWCSession::DisconnectDisplay(int disp) {
-  DLOGI("Display = %d", disp);
-
-  if (disp == HWC_DISPLAY_EXTERNAL) {
-    HWCDisplayExternal::Destroy(hwc_display_[disp]);
-    connected_displays_[HWC_DISPLAY_EXTERNAL] = 0;
-  } else if (disp == HWC_DISPLAY_VIRTUAL) {
-    HWCDisplayVirtual::Destroy(hwc_display_[disp]);
-    connected_displays_[HWC_DISPLAY_VIRTUAL] = 0;
-  } else {
-    DLOGE("Invalid display type");
-    return -1;
-  }
-
-  hwc_display_[disp] = NULL;
-
-  return 0;
-}
-
-static void PostRefresh(hwc_procs_t const *hwc_procs) {
-  hwc_procs->invalidate(hwc_procs);
-}
-
-void HWCSession::AsyncRefresh() {
-  future_ = std::async(PostRefresh, hwc_procs_);
-}
-
-android::status_t HWCSession::notifyCallback(uint32_t command, const android::Parcel *input_parcel,
-                                             android::Parcel *output_parcel) {
-  SEQUENCE_WAIT_SCOPE_LOCK(locker_);
-
-  android::status_t status = 0;
-
-  switch (command) {
-  case qService::IQService::DYNAMIC_DEBUG:
-    DynamicDebug(input_parcel);
-    break;
-
-  case qService::IQService::SCREEN_REFRESH:
-    AsyncRefresh();
-    break;
-
-  case qService::IQService::SET_IDLE_TIMEOUT:
-    if (hwc_display_[HWC_DISPLAY_PRIMARY]) {
-      uint32_t timeout = UINT32(input_parcel->readInt32());
-      hwc_display_[HWC_DISPLAY_PRIMARY]->SetIdleTimeoutMs(timeout);
-    }
-    break;
-
-  case qService::IQService::SET_FRAME_DUMP_CONFIG:
-    SetFrameDumpConfig(input_parcel);
-    break;
-
-  case qService::IQService::SET_MAX_PIPES_PER_MIXER:
-    status = SetMaxMixerStages(input_parcel);
-    break;
-
-  case qService::IQService::SET_DISPLAY_MODE:
-    status = SetDisplayMode(input_parcel);
-    break;
-
-  case qService::IQService::SET_SECONDARY_DISPLAY_STATUS:
-    status = SetSecondaryDisplayStatus(input_parcel, output_parcel);
-    break;
-
-  case qService::IQService::CONFIGURE_DYN_REFRESH_RATE:
-    status = ConfigureRefreshRate(input_parcel);
-    break;
-
-  case qService::IQService::SET_VIEW_FRAME:
-    break;
-
-  case qService::IQService::TOGGLE_SCREEN_UPDATES:
-    status = ToggleScreenUpdates(input_parcel, output_parcel);
-    break;
-
-  case qService::IQService::QDCM_SVC_CMDS:
-    status = QdcmCMDHandler(input_parcel, output_parcel);
-    break;
-
-  case qService::IQService::MIN_HDCP_ENCRYPTION_LEVEL_CHANGED:
-    status = OnMinHdcpEncryptionLevelChange(input_parcel, output_parcel);
-    break;
-
-  case qService::IQService::CONTROL_PARTIAL_UPDATE:
-    status = ControlPartialUpdate(input_parcel, output_parcel);
-    break;
-
-  case qService::IQService::SET_ACTIVE_CONFIG:
-    status = HandleSetActiveDisplayConfig(input_parcel, output_parcel);
-    break;
-
-  case qService::IQService::GET_ACTIVE_CONFIG:
-    status = HandleGetActiveDisplayConfig(input_parcel, output_parcel);
-    break;
-
-  case qService::IQService::GET_CONFIG_COUNT:
-    status = HandleGetDisplayConfigCount(input_parcel, output_parcel);
-    break;
-
-  case qService::IQService::GET_DISPLAY_ATTRIBUTES_FOR_CONFIG:
-    status = HandleGetDisplayAttributesForConfig(input_parcel, output_parcel);
-    break;
-
-  case qService::IQService::GET_PANEL_BRIGHTNESS:
-    status = GetPanelBrightness(input_parcel, output_parcel);
-    break;
-
-  case qService::IQService::SET_PANEL_BRIGHTNESS:
-    status = SetPanelBrightness(input_parcel, output_parcel);
-    break;
-
-  case qService::IQService::GET_DISPLAY_VISIBLE_REGION:
-    status = GetVisibleDisplayRect(input_parcel, output_parcel);
-    break;
-
-  case qService::IQService::SET_CAMERA_STATUS:
-    status = SetDynamicBWForCamera(input_parcel, output_parcel);
-    break;
-
-  case qService::IQService::GET_BW_TRANSACTION_STATUS:
-    status = GetBWTransactionStatus(input_parcel, output_parcel);
-    break;
-
-  case qService::IQService::SET_LAYER_MIXER_RESOLUTION:
-    status = SetMixerResolution(input_parcel);
-    break;
-
-  case qService::IQService::GET_HDR_CAPABILITIES:
-    status = GetHdrCapabilities(input_parcel, output_parcel);
-    break;
-
-  default:
-    DLOGW("QService command = %d is not supported", command);
-    return -EINVAL;
-  }
-
-  return status;
-}
-
-android::status_t HWCSession::ToggleScreenUpdates(const android::Parcel *input_parcel,
-                                                  android::Parcel *output_parcel) {
-  int input = input_parcel->readInt32();
-  int error = android::BAD_VALUE;
-
-  if (hwc_display_[HWC_DISPLAY_PRIMARY] && (input <= 1) && (input >= 0)) {
-    error = hwc_display_[HWC_DISPLAY_PRIMARY]->ToggleScreenUpdates(input == 1);
-    if (error != 0) {
-      DLOGE("Failed to toggle screen updates = %d. Error = %d", input, error);
-    }
-  }
-  output_parcel->writeInt32(error);
-
-  return error;
-}
-
-android::status_t HWCSession::SetPanelBrightness(const android::Parcel *input_parcel,
-                                                 android::Parcel *output_parcel) {
-  int level = input_parcel->readInt32();
-  int error = android::BAD_VALUE;
-
-  if (hwc_display_[HWC_DISPLAY_PRIMARY]) {
-    error = hwc_display_[HWC_DISPLAY_PRIMARY]->SetPanelBrightness(level);
-    if (error != 0) {
-      DLOGE("Failed to set the panel brightness = %d. Error = %d", level, error);
-    }
-  }
-  output_parcel->writeInt32(error);
-
-  return error;
-}
-
-android::status_t HWCSession::GetPanelBrightness(const android::Parcel *input_parcel,
-                                                 android::Parcel *output_parcel) {
-  int error = android::BAD_VALUE;
-  int ret = error;
-
-  if (hwc_display_[HWC_DISPLAY_PRIMARY]) {
-    error = hwc_display_[HWC_DISPLAY_PRIMARY]->GetPanelBrightness(&ret);
-    if (error != 0) {
-      ret = error;
-      DLOGE("Failed to get the panel brightness. Error = %d", error);
-    }
-  }
-  output_parcel->writeInt32(ret);
-
-  return error;
-}
-
-android::status_t HWCSession::ControlPartialUpdate(const android::Parcel *input_parcel,
-                                                   android::Parcel *output_parcel) {
-  DisplayError error = kErrorNone;
-  int ret = 0;
-  uint32_t disp_id = UINT32(input_parcel->readInt32());
-  uint32_t enable = UINT32(input_parcel->readInt32());
-
-  if (disp_id != HWC_DISPLAY_PRIMARY) {
-    DLOGW("CONTROL_PARTIAL_UPDATE is not applicable for display = %d", disp_id);
-    ret = -EINVAL;
-    output_parcel->writeInt32(ret);
-    return ret;
-  }
-
-  if (!hwc_display_[HWC_DISPLAY_PRIMARY]) {
-    DLOGE("primary display object is not instantiated");
-    ret = -EINVAL;
-    output_parcel->writeInt32(ret);
-    return ret;
-  }
-
-  uint32_t pending = 0;
-  error = hwc_display_[HWC_DISPLAY_PRIMARY]->ControlPartialUpdate(enable, &pending);
-
-  if (error == kErrorNone) {
-    if (!pending) {
-      output_parcel->writeInt32(ret);
-      return ret;
-    }
-  } else if (error == kErrorNotSupported) {
-    output_parcel->writeInt32(ret);
-    return ret;
-  } else {
-    ret = -EINVAL;
-    output_parcel->writeInt32(ret);
-    return ret;
-  }
-
-  AsyncRefresh();
-
-  // Wait until partial update control is complete
-  ret = locker_.WaitFinite(kPartialUpdateControlTimeoutMs);
-
-  output_parcel->writeInt32(ret);
-
-  return ret;
-}
-
-android::status_t HWCSession::HandleSetActiveDisplayConfig(const android::Parcel *input_parcel,
-                                                           android::Parcel *output_parcel) {
-  int config = input_parcel->readInt32();
-  int dpy = input_parcel->readInt32();
-  int error = android::BAD_VALUE;
-
-  if (dpy > HWC_DISPLAY_VIRTUAL) {
-    return android::BAD_VALUE;
-  }
-
-  if (hwc_display_[dpy]) {
-    error = hwc_display_[dpy]->SetActiveDisplayConfig(config);
-    if (error == 0) {
-      AsyncRefresh();
-    }
-  }
-
-  return error;
-}
-
-android::status_t HWCSession::HandleGetActiveDisplayConfig(const android::Parcel *input_parcel,
-                                                           android::Parcel *output_parcel) {
-  int dpy = input_parcel->readInt32();
-  int error = android::BAD_VALUE;
-
-  if (dpy > HWC_DISPLAY_VIRTUAL) {
-    return android::BAD_VALUE;
-  }
-
-  if (hwc_display_[dpy]) {
-    uint32_t config = 0;
-    error = hwc_display_[dpy]->GetActiveDisplayConfig(&config);
-    if (error == 0) {
-      output_parcel->writeInt32(INT(config));
-    }
-  }
-
-  return error;
-}
-
-android::status_t HWCSession::HandleGetDisplayConfigCount(const android::Parcel *input_parcel,
-                                                          android::Parcel *output_parcel) {
-  int dpy = input_parcel->readInt32();
-  int error = android::BAD_VALUE;
-
-  if (dpy > HWC_DISPLAY_VIRTUAL) {
-    return android::BAD_VALUE;
-  }
-
-  uint32_t count = 0;
-  if (hwc_display_[dpy]) {
-    error = hwc_display_[dpy]->GetDisplayConfigCount(&count);
-    if (error == 0) {
-      output_parcel->writeInt32(INT(count));
-    }
-  }
-
-  return error;
-}
-
-android::status_t HWCSession::SetDisplayPort(DisplayPort sdm_disp_port, int *hwc_disp_port) {
-  if (!hwc_disp_port) {
-    return -EINVAL;
-  }
-
-  switch (sdm_disp_port) {
-    case kPortDSI:
-      *hwc_disp_port = qdutils::DISPLAY_PORT_DSI;
-      break;
-    case kPortDTV:
-      *hwc_disp_port = qdutils::DISPLAY_PORT_DTV;
-      break;
-    case kPortLVDS:
-      *hwc_disp_port = qdutils::DISPLAY_PORT_LVDS;
-      break;
-    case kPortEDP:
-      *hwc_disp_port = qdutils::DISPLAY_PORT_EDP;
-      break;
-    case kPortWriteBack:
-      *hwc_disp_port = qdutils::DISPLAY_PORT_WRITEBACK;
-      break;
-    case kPortDP:
-      *hwc_disp_port = qdutils::DISPLAY_PORT_DP;
-      break;
-    case kPortDefault:
-      *hwc_disp_port = qdutils::DISPLAY_PORT_DEFAULT;
-      break;
-    default:
-      DLOGE("Invalid sdm display port %d", sdm_disp_port);
-      return -EINVAL;
-  }
-
-  return 0;
-}
-
-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;
-  DisplayPort sdm_disp_port = kPortDefault;
-  int hwc_disp_port = qdutils::DISPLAY_PORT_DEFAULT;
-
-  if (dpy > HWC_DISPLAY_VIRTUAL) {
-    return android::BAD_VALUE;
-  }
-
-  if (hwc_display_[dpy]) {
-    error = hwc_display_[dpy]->GetDisplayAttributesForConfig(config, &display_attributes);
-    if (error == 0) {
-      hwc_display_[dpy]->GetDisplayPort(&sdm_disp_port);
-
-      SetDisplayPort(sdm_disp_port, &hwc_disp_port);
-
-      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(hwc_disp_port);
-      output_parcel->writeInt32(display_attributes.is_yuv);
-    }
-  }
-
-  return error;
-}
-
-android::status_t HWCSession::SetSecondaryDisplayStatus(const android::Parcel *input_parcel,
-                                                        android::Parcel *output_parcel) {
-  int ret = -EINVAL;
-
-  uint32_t display_id = UINT32(input_parcel->readInt32());
-  uint32_t display_status = UINT32(input_parcel->readInt32());
-
-  DLOGI("Display = %d, Status = %d", display_id, display_status);
-
-  if (display_id >= HWC_NUM_DISPLAY_TYPES) {
-    DLOGE("Invalid display_id");
-  } else if (display_id == HWC_DISPLAY_PRIMARY) {
-    DLOGE("Not supported for this display");
-  } else if (!hwc_display_[display_id]) {
-    DLOGW("Display is not connected");
-  } else {
-    ret = hwc_display_[display_id]->SetDisplayStatus(display_status);
-  }
-
-  output_parcel->writeInt32(ret);
-
-  return ret;
-}
-
-android::status_t HWCSession::ConfigureRefreshRate(const android::Parcel *input_parcel) {
-  uint32_t operation = UINT32(input_parcel->readInt32());
-  switch (operation) {
-    case qdutils::DISABLE_METADATA_DYN_REFRESH_RATE:
-      return hwc_display_[HWC_DISPLAY_PRIMARY]->Perform(
-          HWCDisplayPrimary::SET_METADATA_DYN_REFRESH_RATE, false);
-    case qdutils::ENABLE_METADATA_DYN_REFRESH_RATE:
-      return hwc_display_[HWC_DISPLAY_PRIMARY]->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_[HWC_DISPLAY_PRIMARY]->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) {
-  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());
-
-  if (bit_mask_display_type[HWC_DISPLAY_PRIMARY]) {
-    if (hwc_display_[HWC_DISPLAY_PRIMARY]) {
-      error = hwc_display_[HWC_DISPLAY_PRIMARY]->SetMaxMixerStages(max_mixer_stages);
-      if (error != kErrorNone) {
-        return -EINVAL;
-      }
-    }
-  }
-
-  if (bit_mask_display_type[HWC_DISPLAY_EXTERNAL]) {
-    if (hwc_display_[HWC_DISPLAY_EXTERNAL]) {
-      error = hwc_display_[HWC_DISPLAY_EXTERNAL]->SetMaxMixerStages(max_mixer_stages);
-      if (error != kErrorNone) {
-        return -EINVAL;
-      }
-    }
-  }
-
-  if (bit_mask_display_type[HWC_DISPLAY_VIRTUAL]) {
-    if (hwc_display_[HWC_DISPLAY_VIRTUAL]) {
-      error = hwc_display_[HWC_DISPLAY_VIRTUAL]->SetMaxMixerStages(max_mixer_stages);
-      if (error != kErrorNone) {
-        return -EINVAL;
-      }
-    }
-  }
-
-  return 0;
-}
-
-android::status_t HWCSession::SetDynamicBWForCamera(const android::Parcel *input_parcel,
-                                                    android::Parcel *output_parcel) {
-  DisplayError error = kErrorNone;
-  uint32_t camera_status = UINT32(input_parcel->readInt32());
-  HWBwModes mode = camera_status > 0 ? kBwCamera : kBwDefault;
-
-  // trigger invalidate to apply new bw caps.
-  AsyncRefresh();
-
-    error = core_intf_->SetMaxBandwidthMode(mode);
-  if (error != kErrorNone) {
-      return -EINVAL;
-  }
-
-  new_bw_mode_ = true;
-  need_invalidate_ = true;
-
-  return 0;
-}
-
-android::status_t HWCSession::GetBWTransactionStatus(const android::Parcel *input_parcel,
-                                                     android::Parcel *output_parcel)  {
-  bool state = true;
-
-  if (hwc_display_[HWC_DISPLAY_PRIMARY]) {
-    if (sync_wait(bw_mode_release_fd_, 0) < 0) {
-      DLOGI("bw_transaction_release_fd is not yet signalled: err= %s", strerror(errno));
-      state = false;
-    }
-    output_parcel->writeInt32(state);
-  }
-
-  return 0;
-}
-
-void 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());
-
-  if (bit_mask_display_type[HWC_DISPLAY_PRIMARY]) {
-    if (hwc_display_[HWC_DISPLAY_PRIMARY]) {
-      hwc_display_[HWC_DISPLAY_PRIMARY]->SetFrameDumpConfig(frame_dump_count, bit_mask_layer_type);
-    }
-  }
-
-  if (bit_mask_display_type[HWC_DISPLAY_EXTERNAL]) {
-    if (hwc_display_[HWC_DISPLAY_EXTERNAL]) {
-      hwc_display_[HWC_DISPLAY_EXTERNAL]->SetFrameDumpConfig(frame_dump_count, bit_mask_layer_type);
-    }
-  }
-
-  if (bit_mask_display_type[HWC_DISPLAY_VIRTUAL]) {
-    if (hwc_display_[HWC_DISPLAY_VIRTUAL]) {
-      hwc_display_[HWC_DISPLAY_VIRTUAL]->SetFrameDumpConfig(frame_dump_count, bit_mask_layer_type);
-    }
-  }
-}
-
-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) {
-    DLOGI("Resoulution change not supported for this display %d", dpy);
-    return -EINVAL;
-  }
-
-  if (!hwc_display_[HWC_DISPLAY_PRIMARY]) {
-    DLOGI("Primary display is not initialized");
-    return -EINVAL;
-  }
-
-  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::GetHdrCapabilities(const android::Parcel *input_parcel,
-                                                 android::Parcel *output_parcel) {
-  uint32_t display_id = UINT32(input_parcel->readInt32());
-  if (display_id >= HWC_NUM_DISPLAY_TYPES) {
-    DLOGE("Invalid display id = %d", display_id);
-    return -EINVAL;
-  }
-
-  if (hwc_display_[display_id] == NULL) {
-    DLOGW("Display = %d not initialized", display_id);
-    return -EINVAL;
-  }
-
-  DisplayConfigFixedInfo fixed_info = {};
-  int ret = hwc_display_[display_id]->GetDisplayFixedConfig(&fixed_info);
-  if (ret) {
-    DLOGE("Failed");
-    return ret;
-  }
-
-  if (!fixed_info.hdr_supported) {
-    DLOGI("HDR is not supported");
-    return 0;
-  }
-
-  std::vector<int32_t> supported_hdr_types;
-  // Only HDR10 supported now, in future add other supported HDR formats(HLG, DolbyVision)
-  supported_hdr_types.push_back(HAL_HDR_HDR10);
-
-  static const float kLuminanceFactor = 10000.0;
-  // luminance is expressed in the unit of 0.0001 cd/m2, convert it to 1cd/m2.
-  float max_luminance = FLOAT(fixed_info.max_luminance)/kLuminanceFactor;
-  float max_average_luminance = FLOAT(fixed_info.average_luminance)/kLuminanceFactor;
-  float min_luminance = FLOAT(fixed_info.min_luminance)/kLuminanceFactor;
-
-  if (output_parcel != nullptr) {
-    output_parcel->writeInt32Vector(supported_hdr_types);
-    output_parcel->writeFloat(max_luminance);
-    output_parcel->writeFloat(max_average_luminance);
-    output_parcel->writeFloat(min_luminance);
-  }
-
-  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;
-
-  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_) {
-    return -1;
-  }
-
-  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 (HWC_DISPLAY_PRIMARY == display_id && hwc_display_[HWC_DISPLAY_PRIMARY])
-      ret = hwc_display_[HWC_DISPLAY_PRIMARY]->ColorSVCRequestRoute(req_payload,
-                                                                  &resp_payload, &pending_action);
-
-    if (HWC_DISPLAY_EXTERNAL == display_id && hwc_display_[HWC_DISPLAY_EXTERNAL])
-      ret = hwc_display_[HWC_DISPLAY_EXTERNAL]->ColorSVCRequestRoute(req_payload, &resp_payload,
-                                                                  &pending_action);
-  }
-
-  if (ret) {
-    output_parcel->writeInt32(ret);  // first field in out parcel indicates return code.
-    req_payload.DestroyPayload();
-    resp_payload.DestroyPayload();
-    return ret;
-  }
-
-  switch (pending_action.action) {
-    case kInvalidating:
-      AsyncRefresh();
-      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:
-      ret = color_mgr_->SetSolidFill(pending_action.params,
-                                     true, hwc_display_[HWC_DISPLAY_PRIMARY]);
-      AsyncRefresh();
-      break;
-    case kDisableSolidFill:
-      ret = color_mgr_->SetSolidFill(pending_action.params,
-                                     false, hwc_display_[HWC_DISPLAY_PRIMARY]);
-      AsyncRefresh();
-      break;
-    case kSetPanelBrightness:
-      brightness_value = reinterpret_cast<int32_t*>(resp_payload.payload);
-      if (brightness_value == NULL) {
-        DLOGE("Brightness value is Null");
-        return -EINVAL;
-      }
-      if (HWC_DISPLAY_PRIMARY == display_id)
-        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]);
-      AsyncRefresh();
-      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]);
-      AsyncRefresh();
-      break;
-    case kInvalidatingAndkSetPanelBrightness:
-      brightness_value = reinterpret_cast<int32_t*>(resp_payload.payload);
-      if (brightness_value == NULL) {
-        DLOGE("Brightness value is Null");
-        return -EINVAL;
-      }
-      if (HWC_DISPLAY_PRIMARY == display_id)
-        ret = hwc_display_[HWC_DISPLAY_PRIMARY]->CachePanelBrightness(*brightness_value);
-      AsyncRefresh();
-      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();
-
-  return (ret? -EINVAL : 0);
-}
-
-android::status_t HWCSession::OnMinHdcpEncryptionLevelChange(const android::Parcel *input_parcel,
-                                                             android::Parcel *output_parcel) {
-  int ret = -EINVAL;
-  uint32_t display_id = UINT32(input_parcel->readInt32());
-  uint32_t min_enc_level = UINT32(input_parcel->readInt32());
-
-  DLOGI("Display %d", display_id);
-
-  if (display_id >= HWC_NUM_DISPLAY_TYPES) {
-    DLOGE("Invalid display_id");
-  } else if (display_id != HWC_DISPLAY_EXTERNAL) {
-    DLOGE("Not supported for display");
-  } else if (!hwc_display_[display_id]) {
-    DLOGW("Display is not connected");
-  } else {
-    ret = hwc_display_[display_id]->OnMinHdcpEncryptionLevelChange(min_enc_level);
-  }
-
-  output_parcel->writeInt32(ret);
-
-  return ret;
-}
-
-void* HWCSession::HWCUeventThread(void *context) {
-  if (context) {
-    return reinterpret_cast<HWCSession *>(context)->HWCUeventThreadHandler();
-  }
-
-  return NULL;
-}
-
-void* HWCSession::HWCUeventThreadHandler() {
-  static char uevent_data[PAGE_SIZE];
-  int length = 0;
-
-  uevent_locker_.Lock();
-  prctl(PR_SET_NAME, uevent_thread_name_, 0, 0, 0);
-  setpriority(PRIO_PROCESS, 0, HAL_PRIORITY_URGENT_DISPLAY);
-  if (!uevent_init()) {
-    DLOGE("Failed to init uevent");
-    pthread_exit(0);
-    uevent_locker_.Signal();
-    uevent_locker_.Unlock();
-    return NULL;
-  }
-
-  uevent_locker_.Signal();
-  uevent_locker_.Unlock();
-
-  while (!uevent_thread_exit_) {
-    // keep last 2 zeroes to ensure double 0 termination
-    length = uevent_next_event(uevent_data, INT32(sizeof(uevent_data)) - 2);
-
-    if (strcasestr(HWC_UEVENT_SWITCH_HDMI, uevent_data)) {
-      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(HWC_UEVENT_GRAPHICS_FB0, uevent_data)) {
-      DLOGI("Uevent FB0 = %s", uevent_data);
-      int panel_reset = GetEventValue(uevent_data, length, "PANEL_ALIVE=");
-      if (panel_reset == 0) {
-        if (hwc_procs_) {
-          reset_panel_ = true;
-          AsyncRefresh();
-        } else {
-          DLOGW("Ignore resetpanel - hwc_proc not registered");
-        }
-      }
-    }
-  }
-  pthread_exit(0);
-
-  return NULL;
-}
-
-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() {
-  int status = -EINVAL;
-
-  DLOGI("Powering off primary");
-  status = hwc_display_[HWC_DISPLAY_PRIMARY]->SetPowerMode(HWC_POWER_MODE_OFF);
-  if (status) {
-    DLOGE("power-off on primary failed with error = %d", status);
-  }
-
-  DLOGI("Restoring power mode on primary");
-  int32_t mode = INT(hwc_display_[HWC_DISPLAY_PRIMARY]->GetLastPowerMode());
-  status = hwc_display_[HWC_DISPLAY_PRIMARY]->SetPowerMode(mode);
-  if (status) {
-    DLOGE("Setting power mode = %d on primary failed with error = %d", mode, status);
-  }
-
-  status = hwc_display_[HWC_DISPLAY_PRIMARY]->EventControl(HWC_EVENT_VSYNC, 1);
-  if (status) {
-    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;
-  bool refresh_screen = 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.
-  {
-    SEQUENCE_WAIT_SCOPE_LOCK(locker_);
-
-    if (!hwc_display_[HWC_DISPLAY_PRIMARY]) {
-      DLOGE("Primay display is not connected.");
-      return -1;
-    }
-
-
-    HWCDisplay *primary_display = hwc_display_[HWC_DISPLAY_PRIMARY];
-    HWCDisplay *external_display = NULL;
-    HWCDisplay *null_display = NULL;
-
-    if (primary_display->GetDisplayClass() == DISPLAY_CLASS_EXTERNAL) {
-      external_display = static_cast<HWCDisplayExternal *>(hwc_display_[HWC_DISPLAY_PRIMARY]);
-    } else if (primary_display->GetDisplayClass() == DISPLAY_CLASS_NULL) {
-      null_display = static_cast<HWCDisplayNull *>(hwc_display_[HWC_DISPLAY_PRIMARY]);
-    }
-
-    // If primary display connected is a NULL display, then replace it with the external display
-    if (connected) {
-      // If we are in HDMI as primary and the primary display just got plugged in
-      if (is_hdmi_primary_ && null_display) {
-        uint32_t primary_width, primary_height;
-        int status = 0;
-        null_display->GetFrameBufferResolution(&primary_width, &primary_height);
-        delete null_display;
-        hwc_display_[HWC_DISPLAY_PRIMARY] = NULL;
-
-        // Create external display with a forced framebuffer resolution to that of what the NULL
-        // display had. This is necessary because SurfaceFlinger does not dynamically update
-        // framebuffer resolution once it reads it at bootup. So we always have to have the NULL
-        // display/external display both at the bootup resolution.
-        status = CreateExternalDisplay(HWC_DISPLAY_PRIMARY, primary_width, primary_height, true);
-        if (status) {
-          DLOGE("Could not create external display");
-          return -1;
-        }
-
-        status = hwc_display_[HWC_DISPLAY_PRIMARY]->SetPowerMode(HWC_POWER_MODE_NORMAL);
-        if (status) {
-          DLOGE("power-on on primary failed with error = %d", status);
-        }
-
-        is_hdmi_yuv_ = IsDisplayYUV(HWC_DISPLAY_PRIMARY);
-
-        // Next, go ahead and enable vsync on external display. This is expliclity required
-        // because in HDMI as primary case, SurfaceFlinger may not be aware of underlying
-        // changing display. and thus may not explicitly enable vsync
-
-        status = hwc_display_[HWC_DISPLAY_PRIMARY]->EventControl(HWC_EVENT_VSYNC, true);
-        if (status) {
-          DLOGE("Error enabling vsync for HDMI as primary case");
-        }
-        // Don't do hotplug notification for HDMI as primary case for now
-        notify_hotplug = false;
-        refresh_screen = true;
-      } else {
-        if (hwc_display_[HWC_DISPLAY_EXTERNAL]) {
-          DLOGE("HDMI is already connected");
-          return -1;
-        }
-
-        // 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, NULL);
-          if (status) {
-            return status;
-          }
-          notify_hotplug = true;
-        } else {
-          DLOGI("Virtual display is connected, pending connection");
-          external_pending_connect_ = true;
-        }
-      }
-    } else {
-      // 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 (is_hdmi_primary_ && external_display) {
-        uint32_t x_res, y_res;
-        external_display->GetFrameBufferResolution(&x_res, &y_res);
-        // Need to manually disable VSYNC as SF is not aware of connect/disconnect cases
-        // for HDMI as primary
-        external_display->EventControl(HWC_EVENT_VSYNC, false);
-        HWCDisplayExternal::Destroy(external_display);
-
-        HWCDisplayNull *null_display;
-
-        int status = HWCDisplayNull::Create(core_intf_, &hwc_procs_,
-                                            reinterpret_cast<HWCDisplay **>(&null_display));
-
-        if (status) {
-          DLOGE("Could not create Null display when primary got disconnected");
-          return -1;
-        }
-
-        null_display->SetResolution(x_res, y_res);
-        hwc_display_[HWC_DISPLAY_PRIMARY] = null_display;
-
-        // Don't do hotplug notification for HDMI as primary case for now
-        notify_hotplug = false;
-      } else {
-        if (hwc_display_[HWC_DISPLAY_EXTERNAL]) {
-          status = DisconnectDisplay(HWC_DISPLAY_EXTERNAL);
-          notify_hotplug = true;
-        }
-        external_pending_connect_ = false;
-      }
-    }
-  }
-
-  if (connected && (notify_hotplug || refresh_screen)) {
-    // trigger screen refresh to ensure sufficient resources are available to process new
-    // new display connection.
-    hwc_procs_->invalidate(hwc_procs_);
-    uint32_t vsync_period = UINT32(GetVsyncPeriod(HWC_DISPLAY_PRIMARY));
-    usleep(vsync_period * 2 / 1000);
-  }
-  // notify client
-  if (notify_hotplug) {
-    hwc_procs_->hotplug(hwc_procs_, HWC_DISPLAY_EXTERNAL, connected);
-  }
-
-  qservice_->onHdmiHotplug(INT(connected));
-
-  return 0;
-}
-
-void HWCSession::HandleSecureDisplaySession(hwc_display_contents_1_t **displays) {
-  secure_display_active_ = false;
-  if (!*displays) {
-    DLOGW("Invalid display contents");
-    return;
-  }
-
-  hwc_display_contents_1_t *content_list = displays[HWC_DISPLAY_PRIMARY];
-  if (!content_list) {
-    DLOGW("Invalid primary content list");
-    return;
-  }
-  size_t num_hw_layers = content_list->numHwLayers;
-
-  for (size_t i = 0; i < num_hw_layers - 1; i++) {
-    hwc_layer_1_t &hwc_layer = content_list->hwLayers[i];
-    const private_handle_t *pvt_handle = static_cast<const private_handle_t *>(hwc_layer.handle);
-    if (pvt_handle && pvt_handle->flags & private_handle_t::PRIV_FLAGS_SECURE_DISPLAY) {
-      secure_display_active_ = true;
-    }
-  }
-
-  // Force flush on primary during transitions(secure<->non secure)
-  // when external displays are connected.
-  bool force_flush = false;
-  if ((connected_displays_[HWC_DISPLAY_PRIMARY] == 1) &&
-     ((connected_displays_[HWC_DISPLAY_EXTERNAL] == 1) ||
-      (connected_displays_[HWC_DISPLAY_VIRTUAL] == 1))) {
-    force_flush = true;
-  }
-
-  for (ssize_t dpy = static_cast<ssize_t>(HWC_NUM_DISPLAY_TYPES - 1); dpy >= 0; dpy--) {
-    if (hwc_display_[dpy]) {
-      hwc_display_[dpy]->SetSecureDisplay(secure_display_active_, force_flush);
-    }
-  }
-}
-
-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_DISPLAY_VIRTUAL) {
-    return android::BAD_VALUE;;
-  }
-
-  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;
-}
-
-int HWCSession::CreateExternalDisplay(int disp, uint32_t primary_width, uint32_t primary_height,
-                                      bool use_primary_res) {
-  uint32_t panel_bpp = 0;
-  uint32_t pattern_type = 0;
-
-  if (qdutils::isDPConnected()) {
-    qdutils::getDPTestConfig(&panel_bpp, &pattern_type);
-  }
-
-  if (panel_bpp && pattern_type) {
-    return HWCDisplayExternalTest::Create(core_intf_, &hwc_procs_, qservice_, panel_bpp,
-                                          pattern_type, &hwc_display_[disp]);
-  }
-
-  return HWCDisplayExternal::Create(core_intf_, &hwc_procs_, primary_width, primary_height,
-                                    qservice_, use_primary_res, &hwc_display_[disp]);
-}
-
-}  // namespace sdm
-
diff --git a/sdm/libs/hwc/hwc_session.h b/sdm/libs/hwc/hwc_session.h
deleted file mode 100644
index ce21c46..0000000
--- a/sdm/libs/hwc/hwc_session.h
+++ /dev/null
@@ -1,166 +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_SESSION_H__
-#define __HWC_SESSION_H__
-
-#include <hardware/hwcomposer.h>
-#include <core/core_interface.h>
-#include <utils/locker.h>
-#include <future>   // NOLINT
-
-#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 {
-
-class HWCSession : hwc_composer_device_1_t, 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();
-
- 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 int Prepare(hwc_composer_device_1 *device, size_t num_displays,
-                     hwc_display_contents_1_t **displays);
-  static int Set(hwc_composer_device_1 *device, size_t num_displays,
-                 hwc_display_contents_1_t **displays);
-  static int EventControl(hwc_composer_device_1 *device, int disp, int event, int enable);
-  static int SetPowerMode(hwc_composer_device_1 *device, int disp, int mode);
-  static int Query(hwc_composer_device_1 *device, int param, int *value);
-  static void RegisterProcs(hwc_composer_device_1 *device, hwc_procs_t const *procs);
-  static void Dump(hwc_composer_device_1 *device, char *buffer, int length);
-  // These config functions always return FB params, the actual display params may differ.
-  static int GetDisplayConfigs(hwc_composer_device_1 *device, int disp, uint32_t *configs,
-                               size_t *numConfigs);
-  static int GetDisplayAttributes(hwc_composer_device_1 *device, int disp, uint32_t config,
-                                  const uint32_t *display_attributes, int32_t *values);
-  static int GetActiveConfig(hwc_composer_device_1 *device, int disp);
-  static int SetActiveConfig(hwc_composer_device_1 *device, int disp, int index);
-  static int SetCursorPositionAsync(hwc_composer_device_1 *device, int disp, int x, int y);
-  static void CloseAcquireFds(hwc_display_contents_1_t *content_list);
-  bool IsDisplayYUV(int disp);
-
-  // Uevent thread
-  static void* HWCUeventThread(void *context);
-  void* HWCUeventThreadHandler();
-  int GetEventValue(const char *uevent_data, int length, const char *event_info);
-  int HotPlugHandler(bool connected);
-  void ResetPanel();
-  int ConnectDisplay(int disp, hwc_display_contents_1_t *content_list);
-  int DisconnectDisplay(int disp);
-  void HandleSecureDisplaySession(hwc_display_contents_1_t **displays);
-  int GetVsyncPeriod(int disp);
-  int CreateExternalDisplay(int disp, uint32_t primary_width, uint32_t primary_height,
-                            bool use_primary_res);
-  void AsyncRefresh();
-
-  // 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);
-  void 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 SetSecondaryDisplayStatus(const android::Parcel *input_parcel,
-                                              android::Parcel *output_parcel);
-  android::status_t ToggleScreenUpdates(const android::Parcel *input_parcel,
-                                        android::Parcel *output_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 ControlPartialUpdate(const android::Parcel *input_parcel,
-                                         android::Parcel *output_parcel);
-  android::status_t OnMinHdcpEncryptionLevelChange(const android::Parcel *input_parcel,
-                                                   android::Parcel *output_parcel);
-  android::status_t SetPanelBrightness(const android::Parcel *input_parcel,
-                                       android::Parcel *output_parcel);
-  android::status_t GetPanelBrightness(const android::Parcel *input_parcel,
-                                       android::Parcel *output_parcel);
-  // These functions return the actual display config info as opposed to FB
-  android::status_t HandleSetActiveDisplayConfig(const android::Parcel *input_parcel,
-                                                 android::Parcel *output_parcel);
-  android::status_t HandleGetActiveDisplayConfig(const android::Parcel *input_parcel,
-                                                 android::Parcel *output_parcel);
-  android::status_t HandleGetDisplayConfigCount(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 SetDynamicBWForCamera(const android::Parcel *input_parcel,
-                                          android::Parcel *output_parcel);
-  android::status_t GetBWTransactionStatus(const android::Parcel *input_parcel,
-                                          android::Parcel *output_parcel);
-  android::status_t SetMixerResolution(const android::Parcel *input_parcel);
-  android::status_t SetDisplayPort(DisplayPort sdm_disp_port, int *hwc_disp_port);
-  android::status_t GetHdrCapabilities(const android::Parcel *input_parcel,
-                                       android::Parcel *output_parcel);
-
-  static Locker locker_;
-  CoreInterface *core_intf_ = NULL;
-  hwc_procs_t hwc_procs_default_;
-  hwc_procs_t const *hwc_procs_ = &hwc_procs_default_;
-  HWCDisplay *hwc_display_[HWC_NUM_DISPLAY_TYPES] = { NULL };
-  pthread_t uevent_thread_;
-  bool uevent_thread_exit_ = false;
-  const char *uevent_thread_name_ = "HWC_UeventThread";
-  HWCBufferAllocator buffer_allocator_;
-  HWCBufferSyncHandler buffer_sync_handler_;
-  HWCColorManager *color_mgr_ = NULL;
-  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_ = NULL;
-  bool is_hdmi_primary_ = false;
-  bool is_hdmi_yuv_ = false;
-  std::future<void> future_;
-  std::bitset<HWC_NUM_DISPLAY_TYPES> connected_displays_;  // Bit mask of connected displays
-  HWCSocketHandler socket_handler_;
-  Locker uevent_locker_;
-};
-
-}  // namespace sdm
-
-#endif  // __HWC_SESSION_H__
-
diff --git a/sdm/libs/hwc2/hwc_display.cpp b/sdm/libs/hwc2/hwc_display.cpp
index 6b0af2c..f7a9dec 100644
--- a/sdm/libs/hwc2/hwc_display.cpp
+++ b/sdm/libs/hwc2/hwc_display.cpp
@@ -161,7 +161,7 @@
 
   // 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) {
+  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) {
@@ -169,6 +169,7 @@
       // failure to force client composition
       return HWC2::Error::Unsupported;
     }
+    DLOGI("Setting Color Mode = %d Transform Hint = %d Success", mode, hint);
   }
 
   if (use_matrix) {
@@ -183,7 +184,6 @@
   current_color_mode_ = mode;
   current_color_transform_ = hint;
   CopyColorTransformMatrix(matrix, color_matrix_);
-  DLOGI("Setting Color Mode = %d Transform Hint = %d Success", mode, hint);
 
   return HWC2::Error::None;
 }
@@ -363,11 +363,18 @@
     // 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_;
   DLOGI("Display created with id: %d", id_);
+
   return 0;
 }
 
@@ -454,12 +461,11 @@
       layer->flags.solid_fill = true;
     }
 
+    if (!hwc_layer->ValidateAndSetCSC()) {
 #ifdef FEATURE_WIDE_COLOR
-    if (!hwc_layer->SupportedDataspace()) {
-        layer->flags.skip = true;
-        DLOGW_IF(kTagStrategy, "Unsupported dataspace: 0x%x", hwc_layer->GetLayerDataspace());
-    }
+      layer->flags.skip = true;
 #endif
+    }
 
     working_primaries = WidestPrimaries(working_primaries,
                                         layer->input_buffer.color_metadata.colorPrimaries);
@@ -717,12 +723,15 @@
 }
 
 HWC2::Error HWCDisplay::GetDisplayConfigs(uint32_t *out_num_configs, hwc2_config_t *out_configs) {
-  // TODO(user): Actually handle multiple configs
   if (out_configs == nullptr) {
-    *out_num_configs = 1;
-  } else {
-    *out_num_configs = 1;
-    out_configs[0] = 0;
+    *out_num_configs = num_configs_;
+    return HWC2::Error::None;
+  }
+
+  *out_num_configs = num_configs_;
+
+  for (uint32_t i = 0; i < num_configs_; i++) {
+    out_configs[i] = i;
   }
 
   return HWC2::Error::None;
@@ -731,16 +740,11 @@
 HWC2::Error HWCDisplay::GetDisplayAttribute(hwc2_config_t config, HWC2::Attribute attribute,
                                             int32_t *out_value) {
   DisplayConfigVariableInfo variable_config;
-  DisplayError error = display_intf_->GetFrameBufferConfig(&variable_config);
-  if (error != kErrorNone) {
-    DLOGV("Get variable config failed. Error = %d", error);
+  if (GetDisplayAttributesForConfig(INT(config), &variable_config) != kErrorNone) {
+    DLOGE("Get variable config failed");
     return HWC2::Error::BadDisplay;
   }
 
-  if (config != 0) {  // We only use config[0] - see TODO above
-      return HWC2::Error::BadConfig;
-  }
-
   switch (attribute) {
     case HWC2::Attribute::VsyncPeriod:
       *out_value = INT32(variable_config.vsync_period_ns);
@@ -805,14 +809,19 @@
   }
 }
 
-// TODO(user): Store configurations and hook them up here
 HWC2::Error HWCDisplay::GetActiveConfig(hwc2_config_t *out_config) {
-  if (out_config != nullptr) {
-    *out_config = 0;
-    return HWC2::Error::None;
-  } else {
-    return HWC2::Error::BadParameter;
+  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,
@@ -837,10 +846,10 @@
 }
 
 HWC2::Error HWCDisplay::SetActiveConfig(hwc2_config_t config) {
-  if (config != 0) {
+  if (SetActiveDisplayConfig(config) != kErrorNone) {
     return HWC2::Error::BadConfig;
   }
-  // We have only one config right now - do nothing
+
   return HWC2::Error::None;
 }
 
diff --git a/sdm/libs/hwc2/hwc_display.h b/sdm/libs/hwc2/hwc_display.h
index b70f160..e773e91 100644
--- a/sdm/libs/hwc2/hwc_display.h
+++ b/sdm/libs/hwc2/hwc_display.h
@@ -299,6 +299,7 @@
   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.
 
  private:
diff --git a/sdm/libs/hwc2/hwc_layers.cpp b/sdm/libs/hwc2/hwc_layers.cpp
index f485ac6..6b5d470 100644
--- a/sdm/libs/hwc2/hwc_layers.cpp
+++ b/sdm/libs/hwc2/hwc_layers.cpp
@@ -255,6 +255,7 @@
     }
   }
 
+  // cache the dataspace, to be used later to update SDM ColorMetaData
   if (dataspace_ != dataspace) {
     geometry_changes_ |= kDataspace;
     dataspace_ = dataspace;
@@ -573,19 +574,6 @@
 
 DisplayError HWCLayer::SetMetaData(const private_handle_t *pvt_handle, Layer *layer) {
   LayerBuffer *layer_buffer = &layer->input_buffer;
-  bool use_color_metadata = true;
-
-#ifdef FEATURE_WIDE_COLOR
-  // Only use color metadata if Android framework metadata is not set
-  use_color_metadata = (dataspace_ == HAL_DATASPACE_UNKNOWN);
-#endif
-
-  if (use_color_metadata) {
-    if (sdm::SetCSC(pvt_handle, &layer_buffer->color_metadata) != kErrorNone) {
-      return kErrorNotSupported;
-    }
-  }
-
   private_handle_t *handle = const_cast<private_handle_t *>(pvt_handle);
   IGC_t igc = {};
   if (getMetaData(handle, GET_IGC, &igc) == 0) {
@@ -655,84 +643,106 @@
   return false;
 }
 
-bool HWCLayer::SupportedDataspace() {
-  if (dataspace_ == HAL_DATASPACE_UNKNOWN) {
-    // Pick values from metadata
+bool HWCLayer::ValidateAndSetCSC() {
+  if (client_requested_ != HWC2::Composition::Device &&
+      client_requested_ != HWC2::Composition::Cursor) {
+    // Check the layers which are configured to Device
     return true;
   }
 
+  // Retrieve ColorMetaData from android_data_space_t (STANDARD|TRANSFER|RANGE)
   LayerBuffer *layer_buffer = &layer_->input_buffer;
+  bool use_color_metadata = true;
 
+#ifdef FEATURE_WIDE_COLOR
   GammaTransfer sdm_transfer = {};
   ColorPrimaries sdm_primaries = {};
   ColorRange sdm_range = {};
+  if (dataspace_ != HAL_DATASPACE_UNKNOWN) {
+    use_color_metadata = false;  // avoid using color_metadata
+    auto transfer = dataspace_ & HAL_DATASPACE_TRANSFER_MASK;
+    // Handle transfer
+    switch (transfer) {
+      case HAL_DATASPACE_TRANSFER_SRGB:
+        sdm_transfer = Transfer_sRGB;
+        break;
+      case HAL_DATASPACE_TRANSFER_SMPTE_170M:
+        sdm_transfer = Transfer_SMPTE_170M;
+        break;
+      case HAL_DATASPACE_TRANSFER_ST2084:
+        sdm_transfer = Transfer_SMPTE_ST2084;
+        break;
+      case HAL_DATASPACE_TRANSFER_HLG:
+        sdm_transfer = Transfer_HLG;
+        break;
+      case HAL_DATASPACE_TRANSFER_LINEAR:
+        sdm_transfer = Transfer_Linear;
+        break;
+      case HAL_DATASPACE_TRANSFER_GAMMA2_2:
+        sdm_transfer = Transfer_Gamma2_2;
+        break;
+      default:
+        DLOGV_IF(kTagStrategy, "Unsupported Transfer Request = %d", transfer);
+        return false;
+    }
 
-  auto transfer = dataspace_ & HAL_DATASPACE_TRANSFER_MASK;
-  // Handle transfer
-  switch (transfer) {
-    case HAL_DATASPACE_TRANSFER_SRGB:
-      sdm_transfer = Transfer_sRGB;
-      break;
-    case HAL_DATASPACE_TRANSFER_SMPTE_170M:
-      sdm_transfer = Transfer_SMPTE_170M;
-      break;
-    case HAL_DATASPACE_TRANSFER_ST2084:
-      sdm_transfer = Transfer_SMPTE_ST2084;
-      break;
-    case HAL_DATASPACE_TRANSFER_HLG:
-      sdm_transfer = Transfer_HLG;
-      break;
-    case HAL_DATASPACE_TRANSFER_LINEAR:
-      sdm_transfer = Transfer_Linear;
-      break;
-    case HAL_DATASPACE_TRANSFER_GAMMA2_2:
-      sdm_transfer = Transfer_Gamma2_2;
-      break;
-    default:
+    // Handle standard
+    auto standard = dataspace_ & HAL_DATASPACE_STANDARD_MASK;
+    switch (standard) {
+      case  HAL_DATASPACE_STANDARD_BT709:
+        sdm_primaries = ColorPrimaries_BT709_5;
+        break;
+      case HAL_DATASPACE_STANDARD_BT601_525:
+      case HAL_DATASPACE_STANDARD_BT601_525_UNADJUSTED:
+        sdm_primaries = ColorPrimaries_BT601_6_525;
+        break;
+      case HAL_DATASPACE_STANDARD_BT601_625:
+      case HAL_DATASPACE_STANDARD_BT601_625_UNADJUSTED:
+        sdm_primaries = ColorPrimaries_BT601_6_625;
+        break;
+      case HAL_DATASPACE_STANDARD_DCI_P3:
+        sdm_primaries = ColorPrimaries_DCIP3;
+        break;
+      case HAL_DATASPACE_STANDARD_BT2020:
+        sdm_primaries = ColorPrimaries_BT2020;
+        // android_dataspace_t doesnt support mastering display and light levels
+        // so retrieve it from metadata
+        use_color_metadata = true;
+        break;
+      default:
+        DLOGV_IF(kTagStrategy, "Unsupported Standard Request = %d", standard);
+        return false;
+    }
+    // TODO(user): Check transfer + primary combination
+
+    // Handle range
+    auto range = dataspace_ & HAL_DATASPACE_RANGE_MASK;
+    switch (range) {
+      case HAL_DATASPACE_RANGE_FULL:
+        sdm_range = Range_Full;
+        break;
+      case HAL_DATASPACE_RANGE_LIMITED:
+        sdm_range = Range_Limited;
+        break;
+      default:
+        DLOGV_IF(kTagStrategy, "Unsupported Range Request = %d", range);
+        break;
+    }
+    // If we got here, the value is supported, update the layer
+    layer_buffer->color_metadata.transfer = sdm_transfer;
+    layer_buffer->color_metadata.colorPrimaries = sdm_primaries;
+    layer_buffer->color_metadata.range = sdm_range;
+  }
+#endif
+
+  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;
+    }
   }
 
-  // Handle standard
-  auto standard = dataspace_ & HAL_DATASPACE_STANDARD_MASK;
-  switch (standard) {
-    case  HAL_DATASPACE_STANDARD_BT709:
-      sdm_primaries = ColorPrimaries_BT709_5;
-      break;
-    case HAL_DATASPACE_STANDARD_BT601_525:
-    case HAL_DATASPACE_STANDARD_BT601_525_UNADJUSTED:
-      sdm_primaries = ColorPrimaries_BT601_6_525;
-      break;
-    case HAL_DATASPACE_STANDARD_BT601_625:
-    case HAL_DATASPACE_STANDARD_BT601_625_UNADJUSTED:
-      sdm_primaries = ColorPrimaries_BT601_6_625;
-      break;
-    case HAL_DATASPACE_STANDARD_DCI_P3:
-      sdm_primaries = ColorPrimaries_DCIP3;
-      break;
-    case HAL_DATASPACE_STANDARD_BT2020:
-      sdm_primaries = ColorPrimaries_BT2020;
-      break;
-    default:
-      return false;
-  }
-  // TODO(user): Check transfer + primary combination
-
-  // Handle range
-  auto range = dataspace_ & HAL_DATASPACE_RANGE_MASK;
-  switch (range) {
-    case HAL_DATASPACE_RANGE_FULL:
-      sdm_range = Range_Full;
-      break;
-    case HAL_DATASPACE_RANGE_LIMITED:
-    default:
-      sdm_range = Range_Limited;
-      break;
-  }
-
-  // If we got here, the value is supported, update the layer
-  layer_buffer->color_metadata.transfer = sdm_transfer;
-  layer_buffer->color_metadata.colorPrimaries = sdm_primaries;
-  layer_buffer->color_metadata.range = sdm_range;
   return true;
 }
 
diff --git a/sdm/libs/hwc2/hwc_layers.h b/sdm/libs/hwc2/hwc_layers.h
index c566655..30fc362 100644
--- a/sdm/libs/hwc2/hwc_layers.h
+++ b/sdm/libs/hwc2/hwc_layers.h
@@ -85,7 +85,7 @@
   void ResetGeometryChanges() { geometry_changes_ = GeometryChanges::kNone; }
   void PushReleaseFence(int32_t fence);
   int32_t PopReleaseFence(void);
-  bool SupportedDataspace();
+  bool ValidateAndSetCSC();
   bool SupportLocalConversion(ColorPrimaries working_primaries);
 
  private:
diff --git a/sdm/libs/hwc2/hwc_session.cpp b/sdm/libs/hwc2/hwc_session.cpp
index d13958d..df15404 100644
--- a/sdm/libs/hwc2/hwc_session.cpp
+++ b/sdm/libs/hwc2/hwc_session.cpp
@@ -1140,8 +1140,6 @@
 }
 
 android::status_t HWCSession::SetColorModeOverride(const android::Parcel *input_parcel) {
-  SCOPE_LOCK(locker_);
-
   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);
@@ -1208,8 +1206,6 @@
 
 android::status_t HWCSession::QdcmCMDHandler(const android::Parcel *input_parcel,
                                              android::Parcel *output_parcel) {
-  SCOPE_LOCK(locker_);
-
   int ret = 0;
   int32_t *brightness_value = NULL;
   uint32_t display_id(0);
diff --git a/sdm/libs/hwc2/hwc_tonemapper.cpp b/sdm/libs/hwc2/hwc_tonemapper.cpp
index 3086fb4..2626d93 100644
--- a/sdm/libs/hwc2/hwc_tonemapper.cpp
+++ b/sdm/libs/hwc2/hwc_tonemapper.cpp
@@ -188,8 +188,8 @@
           // 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()) {
-            ToneMapSession *fb_tone_map_session = tone_map_sessions_.at(fb_session_index_);
+          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;
@@ -197,7 +197,7 @@
           }
         }
         error = AcquireToneMapSession(layer, &session_index);
-        fb_session_index_ = session_index;
+        fb_session_index_ = INT(session_index);
         break;
       default:
         error = AcquireToneMapSession(layer, &session_index);
@@ -261,6 +261,13 @@
     } else {
       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_--;
+      }
     }
   }
 }
@@ -271,7 +278,7 @@
       delete tone_map_sessions_.back();
       tone_map_sessions_.pop_back();
     }
-    fb_session_index_ = 0;
+    fb_session_index_ = -1;
   }
 }
 
diff --git a/sdm/libs/hwc2/hwc_tonemapper.h b/sdm/libs/hwc2/hwc_tonemapper.h
index e2c8ef4..8bef3b1 100644
--- a/sdm/libs/hwc2/hwc_tonemapper.h
+++ b/sdm/libs/hwc2/hwc_tonemapper.h
@@ -118,7 +118,7 @@
   HWCBufferAllocator *buffer_allocator_ = nullptr;
   uint32_t dump_frame_count_ = 0;
   uint32_t dump_frame_index_ = 0;
-  uint32_t fb_session_index_ = 0;
+  int fb_session_index_ = -1;
 };
 
 }  // namespace sdm
diff --git a/sdm/libs/utils/debug.cpp b/sdm/libs/utils/debug.cpp
index 592be68..ee881ef 100644
--- a/sdm/libs/utils/debug.cpp
+++ b/sdm/libs/utils/debug.cpp
@@ -47,11 +47,14 @@
   return value;
 }
 
-int Debug::GetHDMIResolution() {
-  int value = 0;
-  debug_.debug_handler_->GetProperty("hw.hdmi.resolution", &value);
+bool Debug::GetExternalResolution(char *value) {
+  uint32_t retval = 0;
+  debug_.debug_handler_->GetProperty("hw.hdmi.resolution", value);
+  if (value[0]) {
+    retval = 1;
+  }
 
-  return value;
+  return retval;
 }
 
 void Debug::GetIdleTimeoutMs(uint32_t *active_ms, uint32_t *inactive_ms) {
@@ -174,6 +177,13 @@
   return (value == 1);
 }
 
+bool Debug::IsSrcSplitPreferred() {
+  int value = 0;
+  debug_.debug_handler_->GetProperty("sdm.debug.prefersplit", &value);
+
+  return (value == 1);
+}
+
 DisplayError Debug::GetMixerResolution(uint32_t *width, uint32_t *height) {
   char value[64] = {};
 
