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/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/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__
-
