msmcobalt: Update to 07.00.00.253.032

Change-Id: I1b6d6373a9462121f15fe3bf6c0beb4dc1263633
diff --git a/msmcobalt/Makefile.am b/msmcobalt/Makefile.am
new file mode 100644
index 0000000..781b836
--- /dev/null
+++ b/msmcobalt/Makefile.am
@@ -0,0 +1,5 @@
+# Makefile.am - Automake script for sdm
+
+ACLOCAL_AMFLAGS = -I m4
+
+SUBDIRS = libqservice libqdutils libgralloc sdm/libs/utils sdm/libs/core
diff --git a/msmcobalt/common.mk b/msmcobalt/common.mk
index 298e0bf..af72e7b 100644
--- a/msmcobalt/common.mk
+++ b/msmcobalt/common.mk
@@ -1,9 +1,14 @@
 #Common headers
 display_top := $(call my-dir)
 
+#Common C flags
+common_flags := -DDEBUG_CALC_FPS -Wno-missing-field-initializers
+common_flags += -Wconversion -Wall -Werror -std=c++11
+
 use_hwc2 := false
 ifeq ($(TARGET_USES_HWC2), true)
     use_hwc2 := true
+    common_flags += -DVIDEO_MODE_DEFER_RETIRE_FENCE
 endif
 
 common_includes := $(display_top)/libqdutils
@@ -25,9 +30,6 @@
     LOCAL_CLANG := true
 endif
 
-#Common C flags
-common_flags := -DDEBUG_CALC_FPS -Wno-missing-field-initializers
-common_flags += -Wconversion -Wall -Werror -std=c++11
 ifneq ($(TARGET_USES_GRALLOC1), true)
     common_flags += -isystem $(display_top)/libgralloc
 else
diff --git a/msmcobalt/configure.ac b/msmcobalt/configure.ac
new file mode 100644
index 0000000..6fe7d0a
--- /dev/null
+++ b/msmcobalt/configure.ac
@@ -0,0 +1,57 @@
+#                                               -*- Autoconf -*-
+# configure.ac -- Autoconf script for sdm
+#
+
+# Process this file with autoconf to produce a configure script
+
+# Requires autoconf tool later than 2.61
+AC_PREREQ(2.61)
+# Initialize the display package version 1.0.0
+AC_INIT([display],1.0.0)
+# Does not strictly follow GNU Coding standards
+AM_INIT_AUTOMAKE([foreign])
+# Disables auto rebuilding of configure, Makefile.ins
+AM_MAINTAINER_MODE
+# defines some macros variable to be included by source
+AC_CONFIG_HEADERS([config.h])
+AC_CONFIG_MACRO_DIR([m4])
+AC_SUBST([COMMON_CFLAGS], [-Wall -Werror -Wno-sign-conversion -Wconversion -DDEBUG_CALC_FPS])
+AC_SUBST([AM_CPPFLAGS], [--std=c++11])
+
+AC_ARG_WITH([core_includes],
+    AC_HELP_STRING([--with-core-includes=@<:@dir@:>@],
+       [Specify the location of the core headers]),
+    [core_incdir=$withval],
+    with_core_includes=no)
+
+if test "x$with_core_includes" != "xno"; then
+   CFLAGS="${CFLAGS} -I${core_incdir}"
+fi
+
+AC_ARG_WITH(sanitized-headers,
+   AS_HELP_STRING([--with-sanitized-headers=DIR],
+       [Specify the location of the sanitized Linux headers]),
+   [CPPFLAGS="$CPPFLAGS -idirafter $withval"])
+
+# Checks for programs.
+AC_PROG_CC
+AM_PROG_CC_C_O
+AC_PROG_CXX
+AC_PROG_LIBTOOL
+AC_PROG_AWK
+AC_PROG_CPP
+AC_PROG_INSTALL
+AC_PROG_LN_S
+AC_PROG_MAKE_SET
+
+AC_SUBST([CFLAGS])
+AC_SUBST([CC])
+AC_CONFIG_FILES([ \
+        Makefile \
+        libqservice/Makefile \
+        libqdutils/Makefile \
+        libgralloc/Makefile \
+        sdm/libs/utils/Makefile \
+        sdm/libs/core/Makefile
+        ])
+AC_OUTPUT
\ No newline at end of file
diff --git a/msmcobalt/libgralloc/Android.mk b/msmcobalt/libgralloc/Android.mk
index 5e499b3..c1d4d79 100644
--- a/msmcobalt/libgralloc/Android.mk
+++ b/msmcobalt/libgralloc/Android.mk
@@ -29,7 +29,7 @@
 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
+LOCAL_COPY_HEADERS            := gralloc_priv.h gr.h adreno_utils.h
 
 include $(BUILD_SHARED_LIBRARY)
 
diff --git a/msmcobalt/libgralloc/Makefile.am b/msmcobalt/libgralloc/Makefile.am
new file mode 100644
index 0000000..2698df3
--- /dev/null
+++ b/msmcobalt/libgralloc/Makefile.am
@@ -0,0 +1,37 @@
+h_sources = alloc_controller.h \
+            memalloc.h
+
+cpp_sources = ionalloc.cpp \
+              alloc_controller.cpp
+
+library_includedir = $(pkgincludedir)
+library_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_LDADD = -lhardware -lcutils -llog -lutils -ldl
+libmemalloc_la_LIBADD = ../libqdutils/libqdutils.la
+
+header_sources = gralloc_priv.h \
+                 gr.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_LDADD = -lhardware -lcutils -llog -lutils
+libgralloc_la_LIBADD = ../libqdutils/libqdutils.la
+libgralloc_la_LIBADD += ../libqdutils/libqdMetaData.la
+libgralloc_la_LIBADD += libmemalloc.la
\ No newline at end of file
diff --git a/msmcobalt/libgralloc/ionalloc.cpp b/msmcobalt/libgralloc/ionalloc.cpp
index 96e0e3e..329e30f 100644
--- a/msmcobalt/libgralloc/ionalloc.cpp
+++ b/msmcobalt/libgralloc/ionalloc.cpp
@@ -36,6 +36,7 @@
 #include <cutils/log.h>
 #include <errno.h>
 #include <utils/Trace.h>
+#include <cutils/trace.h>
 #include "gralloc_priv.h"
 #include "ionalloc.h"
 
diff --git a/msmcobalt/libqdutils/Makefile.am b/msmcobalt/libqdutils/Makefile.am
new file mode 100644
index 0000000..ef2108d
--- /dev/null
+++ b/msmcobalt/libqdutils/Makefile.am
@@ -0,0 +1,30 @@
+h_sources = qdMetaData.h
+
+cpp_sources = qdMetaData.cpp
+
+library_includedir = $(includedir)
+library_include_HEADERS = $(h_sources)
+
+lib_LTLIBRARIES = libqdMetaData.la
+libqdMetaData_la_CC = @CC@
+libqdMetaData_la_SOURCES = $(cpp_sources)
+libqdMetaData_la_CFLAGS = $(AM_CFLAGS) -DLOG_TAG=\"DisplayMetaData\"
+libqdMetaData_la_CPPFLAGS = $(AM_CPPFLAGS)
+libqdMetaData_LDADD = -lcutils -llog
+
+header_sources = display_config.h
+
+c_sources = profiler.cpp \
+            qd_utils.cpp \
+            display_config.cpp
+
+library_includedir = $(includedir)
+library_include_HEADERS = $(header_sources)
+
+lib_LTLIBRARIES += libqdutils.la
+libqdutils_la_CC = @CC@
+libqdutils_la_SOURCES = $(c_sources)
+libqdutils_la_CFLAGS = $(COMMON_CFLAGS) -DLOG_TAG=\"qdutils\"
+libqdutils_la_CPPFLAGS = $(AM_CPPFLAGS)
+libqdutils_LDADD = -lhardware -lcutils -llog -lbinder
+libqdutils_la_LIBADD = ../libqservice/libqservice.la
\ No newline at end of file
diff --git a/msmcobalt/libqdutils/qdMetaData.cpp b/msmcobalt/libqdutils/qdMetaData.cpp
index 130cf46..51dfa82 100644
--- a/msmcobalt/libqdutils/qdMetaData.cpp
+++ b/msmcobalt/libqdutils/qdMetaData.cpp
@@ -38,18 +38,14 @@
 
 int setMetaData(private_handle_t *handle, DispParamType paramType,
                                                     void *param) {
-    if (!handle) {
-        ALOGE("%s: Private handle is null!", __func__);
+    if (private_handle_t::validate(handle)) {
+        ALOGE("%s: Private handle is invalid! handle=%p", __func__, handle);
         return -1;
     }
     if (handle->fd_metadata == -1) {
         ALOGE("%s: Bad fd for extra data!", __func__);
         return -1;
     }
-    if (!param) {
-        ALOGE("%s: input param is null!", __func__);
-        return -1;
-    }
     unsigned long size = ROUND_UP_PAGESIZE(sizeof(MetaData_t));
     void *base = mmap(NULL, size, PROT_READ|PROT_WRITE, MAP_SHARED,
         handle->fd_metadata, 0);
@@ -58,6 +54,12 @@
         return -1;
     }
     MetaData_t *data = reinterpret_cast <MetaData_t *>(base);
+    // If parameter is NULL reset the specific MetaData Key
+    if (!param) {
+       data->operation &= ~paramType;
+       return munmap(base, size);
+    }
+
     data->operation |= paramType;
     switch (paramType) {
         case PP_PARAM_INTERLACED:
@@ -90,6 +92,9 @@
         case SET_S3D_COMP:
             data->s3dComp = *((S3DGpuComp_t *)param);
             break;
+        case SET_VT_TIMESTAMP:
+            data->vtTimeStamp = *((uint64_t *)param);
+            break;
         default:
             ALOGE("Unknown paramType %d", paramType);
             break;
@@ -188,6 +193,9 @@
         case GET_S3D_COMP:
             *((S3DGpuComp_t *)param) = data->s3dComp;
             break;
+        case GET_VT_TIMESTAMP:
+            *((uint64_t *)param) = data->vtTimeStamp;
+            break;
         default:
             ALOGE("Unknown paramType %d", paramType);
             break;
diff --git a/msmcobalt/libqdutils/qdMetaData.h b/msmcobalt/libqdutils/qdMetaData.h
index 8c0a0b0..725e094 100644
--- a/msmcobalt/libqdutils/qdMetaData.h
+++ b/msmcobalt/libqdutils/qdMetaData.h
@@ -86,38 +86,42 @@
     uint32_t isSingleBufferMode;
     /* Indicate GPU to draw S3D layer on dedicate display device */
     struct S3DGpuComp_t s3dComp;
+
+    /* Set by camera to program the VT Timestamp */
+    uint64_t vtTimeStamp;
 };
 
 enum DispParamType {
-    UNUSED0             = 0x0001,
-    UNUSED1             = 0x0002,
-    PP_PARAM_INTERLACED = 0x0004,
-    UNUSED2             = 0x0008,
-    UNUSED3             = 0x0010,
-    UNUSED4             = 0x0020,
-    UNUSED5             = 0x0040,
-    UPDATE_BUFFER_GEOMETRY = 0x0080,
-    UPDATE_REFRESH_RATE = 0x0100,
-    UPDATE_COLOR_SPACE = 0x0200,
-    MAP_SECURE_BUFFER = 0x400,
-    S3D_FORMAT = 0x800,
-    LINEAR_FORMAT = 0x1000,
-    SET_IGC = 0x2000,
-    SET_SINGLE_BUFFER_MODE = 0x4000,
-    SET_S3D_COMP = 0x8000,
+    SET_VT_TIMESTAMP         = 0x0001,
+    UNUSED1                  = 0x0002,
+    PP_PARAM_INTERLACED      = 0x0004,
+    UNUSED2                  = 0x0008,
+    UNUSED3                  = 0x0010,
+    UNUSED4                  = 0x0020,
+    UNUSED5                  = 0x0040,
+    UPDATE_BUFFER_GEOMETRY   = 0x0080,
+    UPDATE_REFRESH_RATE      = 0x0100,
+    UPDATE_COLOR_SPACE       = 0x0200,
+    MAP_SECURE_BUFFER        = 0x0400,
+    S3D_FORMAT               = 0x0800,
+    LINEAR_FORMAT            = 0x1000,
+    SET_IGC                  = 0x2000,
+    SET_SINGLE_BUFFER_MODE   = 0x4000,
+    SET_S3D_COMP             = 0x8000,
 };
 
 enum DispFetchParamType {
-    GET_PP_PARAM_INTERLACED = 0x0004,
-    GET_BUFFER_GEOMETRY = 0x0080,
-    GET_REFRESH_RATE = 0x0100,
-    GET_COLOR_SPACE = 0x0200,
-    GET_MAP_SECURE_BUFFER = 0x400,
-    GET_S3D_FORMAT = 0x800,
-    GET_LINEAR_FORMAT = 0x1000,
-    GET_IGC = 0x2000,
-    GET_SINGLE_BUFFER_MODE = 0x4000,
-    GET_S3D_COMP = 0x8000,
+    GET_VT_TIMESTAMP         = 0x0001,
+    GET_PP_PARAM_INTERLACED  = 0x0004,
+    GET_BUFFER_GEOMETRY      = 0x0080,
+    GET_REFRESH_RATE         = 0x0100,
+    GET_COLOR_SPACE          = 0x0200,
+    GET_MAP_SECURE_BUFFER    = 0x0400,
+    GET_S3D_FORMAT           = 0x0800,
+    GET_LINEAR_FORMAT        = 0x1000,
+    GET_IGC                  = 0x2000,
+    GET_SINGLE_BUFFER_MODE   = 0x4000,
+    GET_S3D_COMP             = 0x8000,
 };
 
 struct private_handle_t;
diff --git a/msmcobalt/libqservice/Android.mk b/msmcobalt/libqservice/Android.mk
index 252ab94..ea11180 100644
--- a/msmcobalt/libqservice/Android.mk
+++ b/msmcobalt/libqservice/Android.mk
@@ -15,6 +15,7 @@
 LOCAL_COPY_HEADERS_TO         := $(common_header_export_path)
 LOCAL_COPY_HEADERS            := IQService.h \
                                  IQClient.h \
+                                 QService.h \
                                  QServiceUtils.h \
                                  IQHDMIClient.h
 
diff --git a/msmcobalt/libqservice/Makefile.am b/msmcobalt/libqservice/Makefile.am
new file mode 100644
index 0000000..155060d
--- /dev/null
+++ b/msmcobalt/libqservice/Makefile.am
@@ -0,0 +1,17 @@
+h_sources = IQService.h \
+            IQClient.h
+
+cpp_sources = QService.cpp \
+              IQService.cpp \
+              IQClient.cpp \
+              IQHDMIClient.cpp
+
+library_includedir = $(includedir)
+library_include_HEADERS = $(h_sources)
+
+lib_LTLIBRARIES = libqservice.la
+libqservice_la_CC = @CC@
+libqservice_la_SOURCES = $(cpp_sources)
+libqservice_la_CFLAGS = $(COMMON_CFLAGS) -DLOG_TAG=\"qdqservice\"
+libqservice_la_CPPFLAGS = $(AM_CPPFLAGS)
+libqservice_LDADD = -lhardware -lcutils -llog -lbinder
\ No newline at end of file
diff --git a/msmcobalt/sdm/include/private/color_params.h b/msmcobalt/sdm/include/private/color_params.h
index 462d293..fdd0c9e 100644
--- a/msmcobalt/sdm/include/private/color_params.h
+++ b/msmcobalt/sdm/include/private/color_params.h
@@ -50,6 +50,7 @@
   kSetPanelBrightness = BITMAP(5),
   kEnableFrameCapture = BITMAP(6),
   kDisableFrameCapture = BITMAP(7),
+  kConfigureDetailedEnhancer = BITMAP(8),
   kNoAction = BITMAP(31),
 };
 
@@ -199,6 +200,46 @@
   uint32_t buffer_size;
 };
 
+static const uint32_t kDeTuningFlagSharpFactor = 0x01;
+static const uint32_t kDeTuningFlagClip = 0x02;
+static const uint32_t kDeTuningFlagThrQuiet = 0x04;
+static const uint32_t kDeTuningFlagThrDieout = 0x08;
+static const uint32_t kDeTuningFlagThrLow = 0x10;
+static const uint32_t kDeTuningFlagThrHigh = 0x20;
+static const uint32_t kDeTuningFlagContentQualLevel = 0x40;
+
+typedef enum {
+  kDeContentQualUnknown,
+  kDeContentQualLow,
+  kDeContentQualMedium,
+  kDeContentQualHigh,
+  kDeContentQualMax,
+} PPDEContentQualLevel;
+
+typedef enum {
+  kDeContentTypeUnknown,
+  kDeContentTypeVideo,
+  kDeContentTypeGraphics,
+  kDeContentTypeMax,
+} PPDEContentType;
+
+struct PPDETuningCfg {
+  uint32_t flags = 0;
+  int32_t sharp_factor = 0;
+  uint16_t thr_quiet = 0;
+  uint16_t thr_dieout = 0;
+  uint16_t thr_low = 0;
+  uint16_t thr_high = 0;
+  uint16_t clip = 0;
+  PPDEContentQualLevel quality = kDeContentQualUnknown;
+  PPDEContentType content_type = kDeContentTypeUnknown;
+};
+
+struct PPDETuningCfgData {
+  uint32_t cfg_en = 0;
+  PPDETuningCfg params;
+};
+
 struct SDEGamutCfg {
   static const int kGamutTableNum = 4;
   static const int kGamutScaleoffTableNum = 3;
@@ -492,6 +533,7 @@
 
   inline Locker &GetLocker(void) { return locker_; }
   inline PPFrameCaptureData *GetFrameCaptureData(void) { return &frame_capture_data; }
+  inline PPDETuningCfgData *GetDETuningCfgData(void) { return &de_tuning_data_; }
   // Once all features are consumed, destroy/release all TFeatureInfo<T> on the list,
   // then clear dirty_ flag and return the lock to the TFeatureInfo<T> producer.
   void Reset();
@@ -508,6 +550,7 @@
   PPFeatureInfo *feature_[kMaxNumPPFeatures];  // reference to TFeatureInfo<T>.
   uint32_t next_idx_ = 0;
   PPFrameCaptureData frame_capture_data;
+  PPDETuningCfgData de_tuning_data_;
 };
 
 }  // namespace sdm
diff --git a/msmcobalt/sdm/include/private/hw_info_types.h b/msmcobalt/sdm/include/private/hw_info_types.h
index 4ae696d..93fb81b 100644
--- a/msmcobalt/sdm/include/private/hw_info_types.h
+++ b/msmcobalt/sdm/include/private/hw_info_types.h
@@ -226,6 +226,7 @@
   bool needs_roi_merge = false;       // Merge ROI's of both the DSI's
   bool dynamic_fps = false;           // Panel Supports dynamic fps
   bool dfps_porch_mode = false;       // dynamic fps VFP or HFP mode
+  bool ping_pong_split = false;       // Supports Ping pong split
   uint32_t min_fps = 0;               // Min fps supported by panel
   uint32_t max_fps = 0;               // Max fps supported by panel
   bool is_primary_panel = false;      // Panel is primary display
@@ -245,6 +246,7 @@
             (needs_roi_merge != panel_info.needs_roi_merge) ||
             (dynamic_fps != panel_info.dynamic_fps) || (min_fps != panel_info.min_fps) ||
             (dfps_porch_mode != panel_info.dfps_porch_mode) ||
+            (ping_pong_split != panel_info.ping_pong_split) ||
             (max_fps != panel_info.max_fps) || (is_primary_panel != panel_info.is_primary_panel) ||
             (split_info != panel_info.split_info) ||
             (s3d_mode != panel_info.s3d_mode));
diff --git a/msmcobalt/sdm/libs/core/Android.mk b/msmcobalt/sdm/libs/core/Android.mk
index 08d81b4..de314ba 100644
--- a/msmcobalt/sdm/libs/core/Android.mk
+++ b/msmcobalt/sdm/libs/core/Android.mk
@@ -30,3 +30,29 @@
                                  $(LOCAL_HW_INTF_PATH)/hw_events.cpp
 
 include $(BUILD_SHARED_LIBRARY)
+
+SDM_HEADER_PATH := ../../include
+include $(CLEAR_VARS)
+LOCAL_COPY_HEADERS_TO         := $(common_header_export_path)/sdm/core
+LOCAL_COPY_HEADERS             = $(SDM_HEADER_PATH)/core/buffer_allocator.h \
+                                 $(SDM_HEADER_PATH)/core/buffer_sync_handler.h \
+                                 $(SDM_HEADER_PATH)/core/core_interface.h \
+                                 $(SDM_HEADER_PATH)/core/debug_interface.h \
+                                 $(SDM_HEADER_PATH)/core/display_interface.h \
+                                 $(SDM_HEADER_PATH)/core/dump_interface.h \
+                                 $(SDM_HEADER_PATH)/core/layer_buffer.h \
+                                 $(SDM_HEADER_PATH)/core/layer_stack.h \
+                                 $(SDM_HEADER_PATH)/core/sdm_types.h
+include $(BUILD_COPY_HEADERS)
+
+include $(CLEAR_VARS)
+LOCAL_COPY_HEADERS_TO         := $(common_header_export_path)/sdm/private
+LOCAL_COPY_HEADERS             = $(SDM_HEADER_PATH)/private/color_interface.h \
+                                 $(SDM_HEADER_PATH)/private/color_params.h \
+                                 $(SDM_HEADER_PATH)/private/extension_interface.h \
+                                 $(SDM_HEADER_PATH)/private/hw_info_types.h \
+                                 $(SDM_HEADER_PATH)/private/partial_update_interface.h \
+                                 $(SDM_HEADER_PATH)/private/resource_interface.h \
+                                 $(SDM_HEADER_PATH)/private/rotator_interface.h \
+                                 $(SDM_HEADER_PATH)/private/strategy_interface.h
+include $(BUILD_COPY_HEADERS)
diff --git a/msmcobalt/sdm/libs/core/Makefile.am b/msmcobalt/sdm/libs/core/Makefile.am
new file mode 100644
index 0000000..8dbbe2f
--- /dev/null
+++ b/msmcobalt/sdm/libs/core/Makefile.am
@@ -0,0 +1,43 @@
+HEADER_PATH := ${WORKSPACE}/display/display-hal/sdm/include
+
+c_sources = core_interface.cpp \
+            core_impl.cpp \
+            display_base.cpp \
+            display_primary.cpp \
+            display_hdmi.cpp \
+            display_virtual.cpp \
+            comp_manager.cpp \
+            strategy.cpp \
+            resource_default.cpp \
+            dump_impl.cpp \
+            color_manager.cpp \
+            fb/hw_info.cpp \
+            fb/hw_device.cpp \
+            fb/hw_primary.cpp \
+            fb/hw_hdmi.cpp \
+            fb/hw_virtual.cpp \
+            fb/hw_color_manager.cpp \
+            fb/hw_scale.cpp \
+            fb/hw_events.cpp
+
+core_h_sources = $(HEADER_PATH)/core/*.h
+
+core_includedir = $(includedir)/sdm/core
+core_include_HEADERS = $(core_h_sources)
+
+private_h_sources = $(HEADER_PATH)/private/*.h
+
+private_includedir = $(includedir)/sdm/private
+private_include_HEADERS = $(private_h_sources)
+
+utils_h_sources = $(HEADER_PATH)/utils/*.h
+
+utils_includedir = $(includedir)/sdm/utils
+utils_include_HEADERS = $(utils_h_sources)
+
+lib_LTLIBRARIES = libsdmcore.la
+libsdmcore_la_CC = @CC@
+libsdmcore_la_SOURCES = $(c_sources)
+libsdmcore_la_CFLAGS = $(COMMON_CFLAGS) -DLOG_TAG=\"SDM\"
+libsdmcore_la_CPPFLAGS = $(AM_CPPFLAGS)
+libsdmcore_la_LIBADD = ../utils/libsdmutils.la
\ No newline at end of file
diff --git a/msmcobalt/sdm/libs/core/display_base.cpp b/msmcobalt/sdm/libs/core/display_base.cpp
index b1a34d1..bd2d7d3 100644
--- a/msmcobalt/sdm/libs/core/display_base.cpp
+++ b/msmcobalt/sdm/libs/core/display_base.cpp
@@ -697,7 +697,7 @@
     return kErrorNotSupported;
   }
 
-  DLOGI("Number of color modes = %d", num_color_modes_);
+  DLOGV_IF(kTagQDCM, "Number of modes from color manager = %d", num_color_modes_);
   *mode_count = num_color_modes_;
 
   return kErrorNone;
@@ -726,7 +726,15 @@
     for (uint32_t i = 0; i < num_color_modes_; i++) {
       DLOGV_IF(kTagQDCM, "Color Mode[%d]: Name = %s mode_id = %d", i, color_modes_[i].name,
                color_modes_[i].id);
-      color_mode_map_.insert(std::make_pair(color_modes_[i].name, &color_modes_[i]));
+      auto it = color_mode_map_.find(color_modes_[i].name);
+      if (it != color_mode_map_.end()) {
+        if (it->second->id < color_modes_[i].id) {
+          color_mode_map_.erase(it);
+          color_mode_map_.insert(std::make_pair(color_modes_[i].name, &color_modes_[i]));
+        }
+      } else {
+        color_mode_map_.insert(std::make_pair(color_modes_[i].name, &color_modes_[i]));
+      }
     }
   }
 
@@ -755,7 +763,7 @@
 
   SDEDisplayMode *sde_display_mode = it->second;
 
-  DLOGV_IF(kTagQDCM, "Color Mode Name = %s corresponding mode_id = %d", sde_display_mode->name,
+  DLOGD("Color Mode Name = %s corresponding mode_id = %d", sde_display_mode->name,
            sde_display_mode->id);
   DisplayError error = kErrorNone;
   error = color_mgr_->ColorMgrSetMode(sde_display_mode->id);
diff --git a/msmcobalt/sdm/libs/core/fb/hw_device.cpp b/msmcobalt/sdm/libs/core/fb/hw_device.cpp
index 3d5cb78..ca43dd2 100644
--- a/msmcobalt/sdm/libs/core/fb/hw_device.cpp
+++ b/msmcobalt/sdm/libs/core/fb/hw_device.cpp
@@ -501,7 +501,12 @@
   }
 
   stack->retire_fence_fd = mdp_commit.retire_fence;
-
+#ifdef VIDEO_MODE_DEFER_RETIRE_FENCE
+  if (hw_panel_info_.mode == kModeVideo) {
+    stack->retire_fence_fd = stored_retire_fence;
+    stored_retire_fence =  mdp_commit.retire_fence;
+  }
+#endif
   // MDP returns only one release fence for the entire layer stack. Duplicate this fence into all
   // layers being composed by MDP.
 
@@ -780,6 +785,7 @@
         hw_panel_info_.min_roi_width, hw_panel_info_.min_roi_height,
         hw_panel_info_.needs_roi_merge);
   DLOGI("FPS: min = %d, max =%d", hw_panel_info_.min_fps, hw_panel_info_.max_fps);
+  DLOGI("Ping Pong Split = %d",  hw_panel_info_.ping_pong_split);
   DLOGI("Left Split = %d, Right Split = %d", hw_panel_info_.split_info.left_split,
         hw_panel_info_.split_info.right_split);
 }
@@ -842,6 +848,8 @@
         panel_info->dynamic_fps = atoi(tokens[1]);
       } else if (!strncmp(tokens[0], "dfps_porch_mode", strlen("dfps_porch_mode"))) {
         panel_info->dfps_porch_mode = atoi(tokens[1]);
+      } else if (!strncmp(tokens[0], "is_pingpong_split", strlen("is_pingpong_split"))) {
+        panel_info->ping_pong_split = atoi(tokens[1]);
       } else if (!strncmp(tokens[0], "min_fps", strlen("min_fps"))) {
         panel_info->min_fps = UINT32(atoi(tokens[1]));
       } else if (!strncmp(tokens[0], "max_fps", strlen("max_fps"))) {
diff --git a/msmcobalt/sdm/libs/core/fb/hw_device.h b/msmcobalt/sdm/libs/core/fb/hw_device.h
index 5543b48..dce7648 100644
--- a/msmcobalt/sdm/libs/core/fb/hw_device.h
+++ b/msmcobalt/sdm/libs/core/fb/hw_device.h
@@ -139,6 +139,7 @@
   const char *fb_path_;
   BufferSyncHandler *buffer_sync_handler_;
   int device_fd_;
+  int stored_retire_fence = -1;
   HWDeviceType device_type_;
   mdp_layer_commit mdp_disp_commit_;
   mdp_input_layer mdp_in_layers_[kMaxSDELayers * 2];   // split panel (left + right)
diff --git a/msmcobalt/sdm/libs/core/fb/hw_primary.cpp b/msmcobalt/sdm/libs/core/fb/hw_primary.cpp
index 1659625..f3c7639 100644
--- a/msmcobalt/sdm/libs/core/fb/hw_primary.cpp
+++ b/msmcobalt/sdm/libs/core/fb/hw_primary.cpp
@@ -245,7 +245,8 @@
   display_attributes_.vsync_period_ns = UINT32(1000000000L / display_attributes_.fps);
   display_attributes_.is_device_split = (hw_panel_info_.split_info.left_split ||
       (var_screeninfo.xres > hw_resource_.max_mixer_width)) ? true : false;
-  display_attributes_.h_total += display_attributes_.is_device_split ? h_blanking : 0;
+  display_attributes_.h_total += (display_attributes_.is_device_split ||
+    hw_panel_info_.ping_pong_split)? h_blanking : 0;
 
   return kErrorNone;
 }
diff --git a/msmcobalt/sdm/libs/hwc/hwc_color_manager.cpp b/msmcobalt/sdm/libs/hwc/hwc_color_manager.cpp
index 64603ea..acf5f37 100644
--- a/msmcobalt/sdm/libs/hwc/hwc_color_manager.cpp
+++ b/msmcobalt/sdm/libs/hwc/hwc_color_manager.cpp
@@ -53,8 +53,8 @@
 namespace sdm {
 
 uint32_t HWCColorManager::Get8BitsARGBColorValue(const PPColorFillParams &params) {
-  uint32_t argb_color = ((params.color.r << 16) & 0xff0000) | ((params.color.g) & 0xff)
-                        | ((params.color.b << 8) & 0xff00);
+  uint32_t argb_color = ((params.color.r << 16) & 0xff0000) | ((params.color.g << 8) & 0xff00) |
+                        ((params.color.b) & 0xff);
   return argb_color;
 }
 
@@ -417,6 +417,76 @@
   return ret;
 }
 
+int HWCColorManager::SetDetailedEnhancer(void *params, HWCDisplay *hwc_display) {
+  SCOPE_LOCK(locker_);
+  DisplayError err = kErrorNone;
+  DisplayDetailEnhancerData de_data;
+
+  PPDETuningCfgData *de_tuning_cfg_data = reinterpret_cast<PPDETuningCfgData*>(params);
+  if (!de_tuning_cfg_data->cfg_en) {
+    de_data.override_flags = kOverrideDEEnable;
+    de_data.enable = 0;
+  } else {
+    de_data.override_flags = kOverrideDEEnable;
+    de_data.enable = 1;
+
+    if (de_tuning_cfg_data->params.flags & kDeTuningFlagSharpFactor) {
+      de_data.override_flags |= kOverrideDEEnable;
+      de_data.sharp_factor = de_tuning_cfg_data->params.sharp_factor;
+    }
+
+    if (de_tuning_cfg_data->params.flags & kDeTuningFlagClip) {
+      de_data.override_flags |= kOverrideDEEnable;
+      de_data.clip = de_tuning_cfg_data->params.clip;
+    }
+
+    if (de_tuning_cfg_data->params.flags & kDeTuningFlagThrQuiet) {
+      de_data.override_flags |= kOverrideDEEnable;
+      de_data.thr_quiet = de_tuning_cfg_data->params.thr_quiet;
+    }
+
+    if (de_tuning_cfg_data->params.flags & kDeTuningFlagThrDieout) {
+      de_data.override_flags |= kOverrideDEEnable;
+      de_data.thr_dieout = de_tuning_cfg_data->params.thr_dieout;
+    }
+
+    if (de_tuning_cfg_data->params.flags & kDeTuningFlagThrLow) {
+      de_data.override_flags |= kOverrideDEEnable;
+      de_data.thr_low = de_tuning_cfg_data->params.thr_low;
+    }
+
+    if (de_tuning_cfg_data->params.flags & kDeTuningFlagThrHigh) {
+      de_data.override_flags |= kOverrideDEEnable;
+      de_data.thr_high = de_tuning_cfg_data->params.thr_high;
+    }
+
+    if (de_tuning_cfg_data->params.flags & kDeTuningFlagContentQualLevel) {
+      de_data.override_flags |= kOverrideDEEnable;
+      switch (de_tuning_cfg_data->params.quality) {
+        case kDeContentQualLow:
+          de_data.quality_level = kContentQualityLow;
+          break;
+        case kDeContentQualMedium:
+          de_data.quality_level = kContentQualityMedium;
+          break;
+        case kDeContentQualHigh:
+          de_data.quality_level = kContentQualityHigh;
+          break;
+        case kDeContentQualUnknown:
+        default:
+          de_data.quality_level = kContentQualityUnknown;
+          break;
+      }
+    }
+  }
+  err = hwc_display->SetDetailEnhancerConfig(de_data);
+  if (err) {
+    DLOGW("SetDetailEnhancerConfig failed. err = %d", err);
+  }
+
+  return err;
+}
+
 const HWCQDCMModeManager::ActiveFeatureCMD HWCQDCMModeManager::kActiveFeatureCMD[] = {
     HWCQDCMModeManager::ActiveFeatureCMD("cabl:on", "cabl:off", "cabl:status", "running"),
     HWCQDCMModeManager::ActiveFeatureCMD("ad:on", "ad:off", "ad:query:status", "running"),
diff --git a/msmcobalt/sdm/libs/hwc/hwc_color_manager.h b/msmcobalt/sdm/libs/hwc/hwc_color_manager.h
index 981b14a..792d5ca 100644
--- a/msmcobalt/sdm/libs/hwc/hwc_color_manager.h
+++ b/msmcobalt/sdm/libs/hwc/hwc_color_manager.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2015, The Linux Foundataion. All rights reserved.
+/* Copyright (c) 2015-2016, The Linux Foundataion. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
@@ -119,6 +119,7 @@
   bool SolidFillLayersPrepare(hwc_display_contents_1_t **displays, HWCDisplay *hwc_display);
   bool SolidFillLayersSet(hwc_display_contents_1_t **displays, HWCDisplay *hwc_display);
   int SetFrameCapture(void *params, bool enable, HWCDisplay *hwc_display);
+  int SetDetailedEnhancer(void *params, HWCDisplay *hwc_display);
 
  protected:
   int CreateSolidFillLayers(HWCDisplay *hwc_display);
diff --git a/msmcobalt/sdm/libs/hwc/hwc_display.h b/msmcobalt/sdm/libs/hwc/hwc_display.h
index 27f1faa..5b59fb8 100644
--- a/msmcobalt/sdm/libs/hwc/hwc_display.h
+++ b/msmcobalt/sdm/libs/hwc/hwc_display.h
@@ -102,6 +102,10 @@
   // 0 : Success.
   virtual int GetFrameCaptureStatus() { return -EAGAIN; }
 
+  virtual DisplayError SetDetailEnhancerConfig(const DisplayDetailEnhancerData &de_data) {
+    return kErrorNotSupported;
+  }
+
   // Display Configurations
   virtual int SetActiveDisplayConfig(int config);
   virtual int GetActiveDisplayConfig(uint32_t *config);
diff --git a/msmcobalt/sdm/libs/hwc/hwc_display_primary.cpp b/msmcobalt/sdm/libs/hwc/hwc_display_primary.cpp
index 6d23754..50805d4 100644
--- a/msmcobalt/sdm/libs/hwc/hwc_display_primary.cpp
+++ b/msmcobalt/sdm/libs/hwc/hwc_display_primary.cpp
@@ -483,6 +483,15 @@
   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;
 
diff --git a/msmcobalt/sdm/libs/hwc/hwc_display_primary.h b/msmcobalt/sdm/libs/hwc/hwc_display_primary.h
index 7ae5b53..901d856 100644
--- a/msmcobalt/sdm/libs/hwc/hwc_display_primary.h
+++ b/msmcobalt/sdm/libs/hwc/hwc_display_primary.h
@@ -46,6 +46,7 @@
   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:
diff --git a/msmcobalt/sdm/libs/hwc/hwc_session.cpp b/msmcobalt/sdm/libs/hwc/hwc_session.cpp
index b35460a..5cdf7a7 100644
--- a/msmcobalt/sdm/libs/hwc/hwc_session.cpp
+++ b/msmcobalt/sdm/libs/hwc/hwc_session.cpp
@@ -1287,6 +1287,11 @@
       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]);
+      hwc_procs_->invalidate(hwc_procs_);
+      break;
     case kNoAction:
       break;
     default:
diff --git a/msmcobalt/sdm/libs/hwc2/hwc_color_manager.cpp b/msmcobalt/sdm/libs/hwc2/hwc_color_manager.cpp
index a39516c..a5cb821 100644
--- a/msmcobalt/sdm/libs/hwc2/hwc_color_manager.cpp
+++ b/msmcobalt/sdm/libs/hwc2/hwc_color_manager.cpp
@@ -53,8 +53,8 @@
 namespace sdm {
 
 uint32_t HWCColorManager::Get8BitsARGBColorValue(const PPColorFillParams &params) {
-  uint32_t argb_color = ((params.color.r << 16) & 0xff0000) | ((params.color.g) & 0xff) |
-                        ((params.color.b << 8) & 0xff00);
+  uint32_t argb_color = ((params.color.r << 16) & 0xff0000) | ((params.color.g << 8) & 0xff00) |
+                        ((params.color.b) & 0xff);
   return argb_color;
 }
 
@@ -273,6 +273,76 @@
   return ret;
 }
 
+int HWCColorManager::SetDetailedEnhancer(void *params, HWCDisplay *hwc_display) {
+  SCOPE_LOCK(locker_);
+  DisplayError err = kErrorNone;
+  DisplayDetailEnhancerData de_data;
+
+  PPDETuningCfgData *de_tuning_cfg_data = reinterpret_cast<PPDETuningCfgData*>(params);
+  if (!de_tuning_cfg_data->cfg_en) {
+    de_data.override_flags = kOverrideDEEnable;
+    de_data.enable = 0;
+  } else {
+    de_data.override_flags = kOverrideDEEnable;
+    de_data.enable = 1;
+
+    if (de_tuning_cfg_data->params.flags & kDeTuningFlagSharpFactor) {
+      de_data.override_flags |= kOverrideDEEnable;
+      de_data.sharp_factor = de_tuning_cfg_data->params.sharp_factor;
+    }
+
+    if (de_tuning_cfg_data->params.flags & kDeTuningFlagClip) {
+      de_data.override_flags |= kOverrideDEEnable;
+      de_data.clip = de_tuning_cfg_data->params.clip;
+    }
+
+    if (de_tuning_cfg_data->params.flags & kDeTuningFlagThrQuiet) {
+      de_data.override_flags |= kOverrideDEEnable;
+      de_data.thr_quiet = de_tuning_cfg_data->params.thr_quiet;
+    }
+
+    if (de_tuning_cfg_data->params.flags & kDeTuningFlagThrDieout) {
+      de_data.override_flags |= kOverrideDEEnable;
+      de_data.thr_dieout = de_tuning_cfg_data->params.thr_dieout;
+    }
+
+    if (de_tuning_cfg_data->params.flags & kDeTuningFlagThrLow) {
+      de_data.override_flags |= kOverrideDEEnable;
+      de_data.thr_low = de_tuning_cfg_data->params.thr_low;
+    }
+
+    if (de_tuning_cfg_data->params.flags & kDeTuningFlagThrHigh) {
+      de_data.override_flags |= kOverrideDEEnable;
+      de_data.thr_high = de_tuning_cfg_data->params.thr_high;
+    }
+
+    if (de_tuning_cfg_data->params.flags & kDeTuningFlagContentQualLevel) {
+      de_data.override_flags |= kOverrideDEEnable;
+      switch (de_tuning_cfg_data->params.quality) {
+        case kDeContentQualLow:
+          de_data.quality_level = kContentQualityLow;
+          break;
+        case kDeContentQualMedium:
+          de_data.quality_level = kContentQualityMedium;
+          break;
+        case kDeContentQualHigh:
+          de_data.quality_level = kContentQualityHigh;
+          break;
+        case kDeContentQualUnknown:
+        default:
+          de_data.quality_level = kContentQualityUnknown;
+          break;
+      }
+    }
+  }
+  err = hwc_display->SetDetailEnhancerConfig(de_data);
+  if (err) {
+    DLOGW("SetDetailEnhancerConfig failed. err = %d", err);
+  }
+
+  return err;
+}
+
 const HWCQDCMModeManager::ActiveFeatureCMD HWCQDCMModeManager::kActiveFeatureCMD[] = {
     HWCQDCMModeManager::ActiveFeatureCMD("cabl:on", "cabl:off", "cabl:status", "running"),
     HWCQDCMModeManager::ActiveFeatureCMD("ad:on", "ad:off", "ad:query:status", "running"),
diff --git a/msmcobalt/sdm/libs/hwc2/hwc_color_manager.h b/msmcobalt/sdm/libs/hwc2/hwc_color_manager.h
index 130dca9..62b6bce 100644
--- a/msmcobalt/sdm/libs/hwc2/hwc_color_manager.h
+++ b/msmcobalt/sdm/libs/hwc2/hwc_color_manager.h
@@ -116,6 +116,7 @@
   int EnableQDCMMode(bool enable, HWCDisplay *hwc_display);
   int SetSolidFill(const void *params, bool enable, HWCDisplay *hwc_display);
   int SetFrameCapture(void *params, bool enable, HWCDisplay *hwc_display);
+  int SetDetailedEnhancer(void *params, HWCDisplay *hwc_display);
 
  protected:
   int CreateSolidFillLayers(HWCDisplay *hwc_display);
diff --git a/msmcobalt/sdm/libs/hwc2/hwc_display.cpp b/msmcobalt/sdm/libs/hwc2/hwc_display.cpp
index 868b0f7..772d2c7 100644
--- a/msmcobalt/sdm/libs/hwc2/hwc_display.cpp
+++ b/msmcobalt/sdm/libs/hwc2/hwc_display.cpp
@@ -60,7 +60,7 @@
 
 HWC2::Error HWCColorMode::Init() {
   PopulateColorModes();
-  return HWC2::Error::None;
+  return SetColorMode(HAL_COLOR_MODE_NATIVE);
 }
 
 HWC2::Error HWCColorMode::DeInit() {
@@ -169,14 +169,14 @@
     return;
   }
 
-  DLOGI("Color Modes supported count = %d", color_mode_count);
+  DLOGV_IF(kTagQDCM, "Color Modes supported count = %d", color_mode_count);
 
   std::vector<std::string> color_modes(color_mode_count);
   error = display_intf_->GetColorModes(&color_mode_count, &color_modes);
 
   for (uint32_t i = 0; i < color_mode_count; i++) {
     std::string &mode_string = color_modes.at(i);
-    DLOGI("Color Mode[%d] = %s", i, mode_string.c_str());
+    DLOGV_IF(kTagQDCM, "Color Mode[%d] = %s", i, mode_string.c_str());
     if (mode_string.find("hal_native") != std::string::npos) {
       PopulateTransform(HAL_COLOR_MODE_NATIVE, mode_string);
     } else if (mode_string.find("hal_srgb") != std::string::npos) {
@@ -330,6 +330,13 @@
   // TODO(user): Add blit target layers
   for (auto hwc_layer : layer_set_) {
     Layer *layer = hwc_layer->GetSDMLayer();
+    layer->flags = {};   // Reset earlier flags
+    if (hwc_layer->GetClientRequestedCompositionType() == HWC2::Composition::Client) {
+      layer->flags.skip = true;
+    } else if (hwc_layer->GetClientRequestedCompositionType() == HWC2::Composition::SolidColor) {
+      layer->flags.solid_fill = true;
+    }
+
     // set default composition as GPU for SDM
     layer->composition = kCompositionGPU;
 
@@ -360,17 +367,32 @@
       layer_stack_.flags.skip_present = true;
     }
 
-    if (layer->flags.cursor) {
-      layer_stack_.flags.cursor_present = true;
+    if (hwc_layer->GetClientRequestedCompositionType() == HWC2::Composition::Cursor) {
+      // Currently we support only one HWCursor & only at top most z-order
+      if ((*layer_set_.rbegin())->GetId() == hwc_layer->GetId()) {
+        layer->flags.cursor = true;
+        layer_stack_.flags.cursor_present = true;
+      }
     }
+
     // TODO(user): Move to a getter if this is needed at other places
     hwc_rect_t scaled_display_frame = {INT(layer->dst_rect.left), INT(layer->dst_rect.top),
                                        INT(layer->dst_rect.right), INT(layer->dst_rect.bottom)};
     ApplyScanAdjustment(&scaled_display_frame);
     hwc_layer->SetLayerDisplayFrame(scaled_display_frame);
     ApplyDeInterlaceAdjustment(layer);
-    // TODO(user): Verify if we still need to configure the solid fill layerbuffer,
-    // it should already have a valid dst_rect by this point
+    // SDM requires these details even for solid fill
+    if (layer->flags.solid_fill) {
+      LayerBuffer *layer_buffer = layer->input_buffer;
+      layer_buffer->width = UINT32(layer->dst_rect.right - layer->dst_rect.left);
+      layer_buffer->height = UINT32(layer->dst_rect.bottom - layer->dst_rect.top);
+      layer_buffer->acquire_fence_fd = -1;
+      layer_buffer->release_fence_fd = -1;
+      layer->src_rect.left = 0;
+      layer->src_rect.top = 0;
+      layer->src_rect.right = layer_buffer->width;
+      layer->src_rect.bottom = layer_buffer->height;
+    }
 
     if (layer->frame_rate > metadata_refresh_rate_) {
       metadata_refresh_rate_ = SanitizeRefreshRate(layer->frame_rate);
@@ -379,7 +401,11 @@
     }
     display_rect_ = Union(display_rect_, layer->dst_rect);
     geometry_changes_ |= hwc_layer->GetGeometryChanges();
-    layer->flags.updating = IsLayerUpdating(layer);
+
+    layer->flags.updating = true;
+    if (layer_set_.size() <= kMaxLayerCount) {
+      layer->flags.updating = IsLayerUpdating(layer);
+    }
 
     layer_stack_.layers.push_back(layer);
   }
@@ -751,6 +777,12 @@
   if (!validated_ && !layer_set_.empty()) {
     return HWC2::Error::NotValidated;
   }
+
+  for (const auto& change : layer_changes_) {
+    auto hwc_layer = layer_map_[change.first];
+    auto composition = change.second;
+    hwc_layer->UpdateClientCompositionType(composition);
+  }
   return HWC2::Error::None;
 }
 
@@ -884,6 +916,8 @@
       } else if (layer->composition != kCompositionGPU) {
         hwc_layer->PushReleaseFence(layer_buffer->release_fence_fd);
         layer_buffer->release_fence_fd = -1;
+      } else {
+        hwc_layer->PushReleaseFence(-1);
       }
     }
 
@@ -893,22 +927,21 @@
     }
   }
 
-  *out_retire_fence = stored_retire_fence_;
+  *out_retire_fence = -1;
   if (!flush_) {
     // if swapinterval property is set to 0 then close and reset the list retire fence
     if (swap_interval_zero_) {
       close(layer_stack_.retire_fence_fd);
       layer_stack_.retire_fence_fd = -1;
     }
-    stored_retire_fence_ = layer_stack_.retire_fence_fd;
+    *out_retire_fence = layer_stack_.retire_fence_fd;
 
     if (dump_frame_count_) {
       dump_frame_count_--;
       dump_frame_index_++;
     }
-  } else {
-    stored_retire_fence_ = -1;
   }
+
   geometry_changes_ = GeometryChanges::kNone;
   flush_ = false;
 
diff --git a/msmcobalt/sdm/libs/hwc2/hwc_display.h b/msmcobalt/sdm/libs/hwc2/hwc_display.h
index 880fca2..2221027 100644
--- a/msmcobalt/sdm/libs/hwc2/hwc_display.h
+++ b/msmcobalt/sdm/libs/hwc2/hwc_display.h
@@ -118,6 +118,10 @@
   // 0 : Success.
   virtual int GetFrameCaptureStatus() { return -EAGAIN; }
 
+  virtual DisplayError SetDetailEnhancerConfig(const DisplayDetailEnhancerData &de_data) {
+    return kErrorNotSupported;
+  }
+
   // Display Configurations
   virtual int SetActiveDisplayConfig(int config);
   virtual int GetActiveDisplayConfig(uint32_t *config);
@@ -259,7 +263,6 @@
   bool validated_ = false;
   bool color_tranform_failed_ = false;
   HWCColorMode *color_mode_ = NULL;
-  int32_t stored_retire_fence_ = -1;
 
  private:
   void DumpInputBuffers(void);
diff --git a/msmcobalt/sdm/libs/hwc2/hwc_display_primary.cpp b/msmcobalt/sdm/libs/hwc2/hwc_display_primary.cpp
index 7dac376..198eddb 100644
--- a/msmcobalt/sdm/libs/hwc2/hwc_display_primary.cpp
+++ b/msmcobalt/sdm/libs/hwc2/hwc_display_primary.cpp
@@ -159,9 +159,6 @@
   auto status = HWC2::Error::None;
   DisplayError error = kErrorNone;
 
-  if (!boot_animation_completed_)
-    ProcessBootAnimCompleted();
-
   if (display_paused_) {
     MarkLayersForGPUBypass();
     return status;
@@ -535,6 +532,16 @@
   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;
 
diff --git a/msmcobalt/sdm/libs/hwc2/hwc_display_primary.h b/msmcobalt/sdm/libs/hwc2/hwc_display_primary.h
index ab46cde..43673ed 100644
--- a/msmcobalt/sdm/libs/hwc2/hwc_display_primary.h
+++ b/msmcobalt/sdm/libs/hwc2/hwc_display_primary.h
@@ -65,6 +65,7 @@
   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:
diff --git a/msmcobalt/sdm/libs/hwc2/hwc_display_virtual.cpp b/msmcobalt/sdm/libs/hwc2/hwc_display_virtual.cpp
index 8c16e5c..787640c 100644
--- a/msmcobalt/sdm/libs/hwc2/hwc_display_virtual.cpp
+++ b/msmcobalt/sdm/libs/hwc2/hwc_display_virtual.cpp
@@ -148,16 +148,10 @@
       }
 
       status = HWCDisplay::PostCommitLayerStack(out_retire_fence);
-      // On Virtual displays, use the output buffer release fence as the retire fence
-      // Close the layer stack retire fence as it is unused
-      if (layer_stack_.output_buffer) {
-        stored_retire_fence_ = layer_stack_.output_buffer->release_fence_fd;
-        close(layer_stack_.retire_fence_fd);
-        layer_stack_.retire_fence_fd = -1;
-      }
     }
   }
   CloseAcquireFds();
+  close(output_buffer_->acquire_fence_fd);
   return status;
 }
 
@@ -180,6 +174,7 @@
   output_buffer_->acquire_fence_fd = dup(release_fence);
 
   if (output_handle) {
+    output_handle_ = output_handle;
     output_buffer_->buffer_id = reinterpret_cast<uint64_t>(output_handle);
     int output_handle_format = output_handle->format;
 
diff --git a/msmcobalt/sdm/libs/hwc2/hwc_layers.cpp b/msmcobalt/sdm/libs/hwc2/hwc_layers.cpp
index d35523d..a18cb4a 100644
--- a/msmcobalt/sdm/libs/hwc2/hwc_layers.cpp
+++ b/msmcobalt/sdm/libs/hwc2/hwc_layers.cpp
@@ -43,7 +43,7 @@
     close(release_fences_.front());
     release_fences_.pop();
   }
-
+  close(ion_fd_);
   if (layer_) {
     if (layer_->input_buffer) {
       delete (layer_->input_buffer);
@@ -64,6 +64,16 @@
   }
 
   const private_handle_t *handle = static_cast<const private_handle_t *>(buffer);
+
+  // Validate and dup ion fd from surfaceflinger
+  // This works around bug 30281222
+  if (handle->fd < 0) {
+    return HWC2::Error::BadParameter;
+  } else {
+    close(ion_fd_);
+    ion_fd_ = dup(handle->fd);
+  }
+
   LayerBuffer *layer_buffer = layer_->input_buffer;
   layer_buffer->width = UINT32(handle->width);
   layer_buffer->height = UINT32(handle->height);
@@ -83,7 +93,7 @@
     layer_buffer->flags.secure_display = true;
   }
 
-  layer_buffer->planes[0].fd = handle->fd;
+  layer_buffer->planes[0].fd = ion_fd_;
   layer_buffer->planes[0].offset = handle->offset;
   layer_buffer->planes[0].stride = UINT32(handle->width);
   layer_buffer->acquire_fence_fd = acquire_fence;
@@ -128,27 +138,22 @@
 HWC2::Error HWCLayer::SetLayerColor(hwc_color_t color) {
   layer_->solid_fill_color = GetUint32Color(color);
   layer_->input_buffer->format = kFormatARGB8888;
-  DLOGD("Layer color set to: %u", layer_->solid_fill_color);
-  DLOGD("[%" PRIu64 "][%" PRIu64 "] Layer color set to %u  %" PRIu64, display_id_, id_,
-        layer_->solid_fill_color);
+  DLOGV_IF(kTagCompManager, "[%" PRIu64 "][%" PRIu64 "] Layer color set to %x", display_id_, id_,
+           layer_->solid_fill_color);
   return HWC2::Error::None;
 }
 
 HWC2::Error HWCLayer::SetLayerCompositionType(HWC2::Composition type) {
-  layer_->flags = {};   // Reset earlier flags
   client_requested_ = type;
   switch (type) {
     case HWC2::Composition::Client:
-      layer_->flags.skip = true;
       break;
     case HWC2::Composition::Device:
       // We try and default to this in SDM
       break;
     case HWC2::Composition::SolidColor:
-      layer_->flags.solid_fill = true;
       break;
     case HWC2::Composition::Cursor:
-      layer_->flags.cursor = true;
       break;
     case HWC2::Composition::Invalid:
       return HWC2::Error::BadParameter;
@@ -278,7 +283,7 @@
   uint32_t r = UINT32(source.r) << 16;
   uint32_t g = UINT32(source.g) << 8;
   uint32_t b = UINT32(source.b);
-  uint32_t color = a & r & g & b;
+  uint32_t color = a | r | g | b;
   return color;
 }
 
diff --git a/msmcobalt/sdm/libs/hwc2/hwc_layers.h b/msmcobalt/sdm/libs/hwc2/hwc_layers.h
index 56e0336..ed93a5a 100644
--- a/msmcobalt/sdm/libs/hwc2/hwc_layers.h
+++ b/msmcobalt/sdm/libs/hwc2/hwc_layers.h
@@ -72,6 +72,7 @@
   HWC2::Error SetLayerZOrder(uint32_t z);
   void SetComposition(const LayerComposition &sdm_composition);
   HWC2::Composition GetClientRequestedCompositionType() { return client_requested_; }
+  void UpdateClientCompositionType(HWC2::Composition type) { client_requested_ = type; }
   HWC2::Composition GetDeviceSelectedCompositionType() { return device_selected_; }
   uint32_t GetGeometryChanges() { return geometry_changes_; }
   void ResetGeometryChanges() { geometry_changes_ = GeometryChanges::kNone; }
@@ -85,6 +86,7 @@
   const hwc2_display_t display_id_;
   static std::atomic<hwc2_layer_t> next_id_;
   std::queue<int32_t> release_fences_;
+  int ion_fd_ = -1;
 
   // Composition requested by client(SF)
   HWC2::Composition client_requested_ = HWC2::Composition::Device;
diff --git a/msmcobalt/sdm/libs/hwc2/hwc_session.cpp b/msmcobalt/sdm/libs/hwc2/hwc_session.cpp
index 30bc11c..66ab568 100644
--- a/msmcobalt/sdm/libs/hwc2/hwc_session.cpp
+++ b/msmcobalt/sdm/libs/hwc2/hwc_session.cpp
@@ -200,9 +200,10 @@
 
 void HWCSession::GetCapabilities(struct hwc2_device *device, uint32_t *outCount,
                                  int32_t *outCapabilities) {
-  if (outCapabilities == NULL) {
-    *outCount = 0;
+  if (outCapabilities != nullptr && *outCount >= 1) {
+    outCapabilities[0] = HWC2_CAPABILITY_SKIP_CLIENT_COLOR_TRANSFORM;
   }
+  *outCount = 1;
 }
 
 template <typename PFN, typename T>
@@ -234,9 +235,13 @@
 
   HWCSession *hwc_session = static_cast<HWCSession *>(device);
   auto status = hwc_session->CreateVirtualDisplayObject(width, height, format);
-  if (status == HWC2::Error::None)
+  if (status == HWC2::Error::None) {
     *out_display_id = HWC_DISPLAY_VIRTUAL;
-  DLOGI("Created virtual display id:% " PRIu64 " with res: %dx%d", *out_display_id, width, height);
+    DLOGI("Created virtual display id:% " PRIu64 " with res: %dx%d",
+          *out_display_id, width, height);
+  } else {
+    DLOGE("Failed to create virtual display: %s", to_string(status).c_str());
+  }
   return INT32(status);
 }
 
@@ -257,6 +262,7 @@
 
   if (hwc_session->hwc_display_[display]) {
     HWCDisplayVirtual::Destroy(hwc_session->hwc_display_[display]);
+    hwc_session->hwc_display_[display] = nullptr;
     return HWC2_ERROR_NONE;
   } else {
     return HWC2_ERROR_BAD_DISPLAY;
@@ -1324,6 +1330,11 @@
       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]);
+      callbacks_.Refresh(HWC_DISPLAY_PRIMARY);
+      break;
     case kNoAction:
       break;
     default:
diff --git a/msmcobalt/sdm/libs/utils/Android.mk b/msmcobalt/sdm/libs/utils/Android.mk
index 928f3c4..ee95e48 100644
--- a/msmcobalt/sdm/libs/utils/Android.mk
+++ b/msmcobalt/sdm/libs/utils/Android.mk
@@ -12,3 +12,14 @@
                                  formats.cpp
 
 include $(BUILD_SHARED_LIBRARY)
+
+SDM_HEADER_PATH := ../../include
+include $(CLEAR_VARS)
+LOCAL_COPY_HEADERS_TO         := $(common_header_export_path)/sdm/utils
+LOCAL_COPY_HEADERS             = $(SDM_HEADER_PATH)/utils/constants.h \
+                                 $(SDM_HEADER_PATH)/utils/debug.h \
+                                 $(SDM_HEADER_PATH)/utils/formats.h \
+                                 $(SDM_HEADER_PATH)/utils/locker.h \
+                                 $(SDM_HEADER_PATH)/utils/rect.h \
+                                 $(SDM_HEADER_PATH)/utils/sys.h
+include $(BUILD_COPY_HEADERS)
\ No newline at end of file
diff --git a/msmcobalt/sdm/libs/utils/Makefile.am b/msmcobalt/sdm/libs/utils/Makefile.am
new file mode 100644
index 0000000..5b0eaab
--- /dev/null
+++ b/msmcobalt/sdm/libs/utils/Makefile.am
@@ -0,0 +1,10 @@
+cpp_sources = debug.cpp \
+              rect.cpp \
+              sys.cpp \
+              formats.cpp
+
+lib_LTLIBRARIES = libsdmutils.la
+libsdmutils_la_CC = @CC@
+libsdmutils_la_SOURCES = $(cpp_sources)
+libsdmutils_la_CFLAGS = $(COMMON_CFLAGS) -DLOG_TAG=\"SDM\"
+libsdmutils_la_CPPFLAGS = $(AM_CPPFLAGS)
\ No newline at end of file