Merge "gpu_tonemapper:Fix uninitialized variables."
diff --git a/common.mk b/common.mk
index fadc5d8..54129bf 100644
--- a/common.mk
+++ b/common.mk
@@ -9,6 +9,14 @@
 common_flags += -DUSE_COLOR_METADATA
 endif
 
+CHECK_VERSION_LE = $(shell if [ $(1) -le $(2) ] ; then echo true ; else echo false ; fi)
+PLATFORM_SDK_NOUGAT = 25
+ifeq "REL" "$(PLATFORM_VERSION_CODENAME)"
+ifeq ($(call CHECK_VERSION_LE, $(PLATFORM_SDK_VERSION), $(PLATFORM_SDK_NOUGAT)), true)
+version_flag := -D__NOUGAT__
+endif
+endif
+
 use_hwc2 := false
 ifeq ($(TARGET_USES_HWC2), true)
     use_hwc2 := true
@@ -52,10 +60,6 @@
     common_flags += -D__ARM_HAVE_NEON
 endif
 
-ifeq ($(call is-board-platform-in-list, $(MSM_VIDC_TARGET_LIST)), true)
-    common_flags += -DVENUS_COLOR_FORMAT
-endif
-
 ifeq ($(call is-board-platform-in-list, $(MASTER_SIDE_CP_TARGET_LIST)), true)
     common_flags += -DMASTER_SIDE_CP
 endif
diff --git a/gpu_tonemapper/Android.mk b/gpu_tonemapper/Android.mk
index 9ae3840..5d1f9a9 100644
--- a/gpu_tonemapper/Android.mk
+++ b/gpu_tonemapper/Android.mk
@@ -10,8 +10,9 @@
 LOCAL_MODULE              := libgpu_tonemapper
 LOCAL_MODULE_TAGS         := optional
 LOCAL_C_INCLUDES          := $(TARGET_OUT_HEADERS)/qcom/display/
+LOCAL_C_INCLUDES          += $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr/include
 
-LOCAL_CFLAGS              := -Wno-missing-field-initializers -Wall \
+LOCAL_CFLAGS              := $(version_flag) -Wno-missing-field-initializers -Wall \
                              -Wno-unused-parameter -std=c++11 -DLOG_TAG=\"GPU_TONEMAPPER\"
 
 LOCAL_SRC_FILES           := TonemapFactory.cpp \
diff --git a/gpu_tonemapper/EGLImageWrapper.cpp b/gpu_tonemapper/EGLImageWrapper.cpp
index 298475f..84f4343 100644
--- a/gpu_tonemapper/EGLImageWrapper.cpp
+++ b/gpu_tonemapper/EGLImageWrapper.cpp
@@ -21,46 +21,134 @@
 #include <cutils/native_handle.h>
 #include <gralloc_priv.h>
 #include <ui/GraphicBuffer.h>
+#include <fcntl.h>
+#include <linux/msm_ion.h>
 
 //-----------------------------------------------------------------------------
-EGLImageBuffer *EGLImageWrapper::wrap(const void *pvt_handle)
+void free_ion_cookie(int ion_fd, int cookie)
 //-----------------------------------------------------------------------------
 {
-  const private_handle_t *src = static_cast<const private_handle_t *>(pvt_handle);
+  if (ion_fd && !ioctl(ion_fd, ION_IOC_FREE, &cookie)) {
+  } else {
+      ALOGE("ION_IOC_FREE failed: ion_fd = %d, cookie = %d", ion_fd, cookie);
+  }
+}
 
-  EGLImageBuffer *result = 0;
-  std::map<int, EGLImageBuffer *>::iterator it = eglImageBufferMap.find(src->fd);
-  if (it == eglImageBufferMap.end()) {
+//-----------------------------------------------------------------------------
+int get_ion_cookie(int ion_fd, int fd)
+//-----------------------------------------------------------------------------
+{
+   int cookie = fd;
+
+   struct ion_fd_data fdData;
+   memset(&fdData, 0, sizeof(fdData));
+   fdData.fd = fd;
+
+   if (ion_fd && !ioctl(ion_fd, ION_IOC_IMPORT, &fdData)) {
+        cookie = fdData.handle;
+   } else {
+        ALOGE("ION_IOC_IMPORT failed: ion_fd = %d, fd = %d", ion_fd, fd);
+   }
+
+   return cookie;
+}
+
+//-----------------------------------------------------------------------------
+EGLImageWrapper::DeleteEGLImageCallback::DeleteEGLImageCallback(int fd)
+//-----------------------------------------------------------------------------
+{
+    ion_fd = fd;
+}
+
+//-----------------------------------------------------------------------------
+void EGLImageWrapper::DeleteEGLImageCallback::operator()(int& k, EGLImageBuffer*& eglImage)
+//-----------------------------------------------------------------------------
+{
+    free_ion_cookie(ion_fd,  k);
+    if( eglImage != 0 )
+    {
+        delete eglImage;
+    }
+}
+
+//-----------------------------------------------------------------------------
+EGLImageWrapper::EGLImageWrapper()
+//-----------------------------------------------------------------------------
+{
+    eglImageBufferMap = new android::LruCache<int, EGLImageBuffer*>(32);
+    ion_fd = open("/dev/ion", O_RDONLY);
+    callback = new DeleteEGLImageCallback(ion_fd);
+    eglImageBufferMap->setOnEntryRemovedListener(callback);
+}
+
+//-----------------------------------------------------------------------------
+EGLImageWrapper::~EGLImageWrapper()
+//-----------------------------------------------------------------------------
+{
+    if( eglImageBufferMap != 0 )
+    {
+        eglImageBufferMap->clear();
+        delete eglImageBufferMap;
+        eglImageBufferMap = 0;
+    }
+
+    if( callback != 0 )
+    {
+        delete callback;
+        callback = 0;
+    }
+
+    if( ion_fd > 0 )
+    {
+        close(ion_fd);
+    }
+    ion_fd = -1;
+}
+//-----------------------------------------------------------------------------
+static EGLImageBuffer* L_wrap(const private_handle_t *src)
+//-----------------------------------------------------------------------------
+{
+    EGLImageBuffer* result = 0;
+
     native_handle_t *native_handle = const_cast<private_handle_t *>(src);
 
     int flags = android::GraphicBuffer::USAGE_HW_TEXTURE |
                 android::GraphicBuffer::USAGE_SW_READ_NEVER |
                 android::GraphicBuffer::USAGE_SW_WRITE_NEVER;
+
     if (src->flags & private_handle_t::PRIV_FLAGS_SECURE_BUFFER) {
       flags |= android::GraphicBuffer::USAGE_PROTECTED;
     }
 
     android::sp<android::GraphicBuffer> graphicBuffer =
-        new android::GraphicBuffer(src->width, src->height, src->format, flags,
-                                   src->width /*src->stride*/, native_handle, false);
+        new android::GraphicBuffer(src->width, src->height, src->format,
+#ifndef __NOUGAT__
+                                   1, // Layer count
+#endif
+                                   flags, src->width /*src->stride*/,
+                                   native_handle, false);
 
     result = new EGLImageBuffer(graphicBuffer);
 
-    eglImageBufferMap[src->fd] = result;
-  } else {
-    result = it->second;
-  }
-
-  return result;
+    return result;
 }
 
 //-----------------------------------------------------------------------------
-void EGLImageWrapper::destroy()
+EGLImageBuffer *EGLImageWrapper::wrap(const void *pvt_handle)
 //-----------------------------------------------------------------------------
 {
-  std::map<int, EGLImageBuffer *>::iterator it = eglImageBufferMap.begin();
-  for (; it != eglImageBufferMap.end(); it++) {
-    delete it->second;
-  }
-  eglImageBufferMap.clear();
+    const private_handle_t *src = static_cast<const private_handle_t *>(pvt_handle);
+
+    int ion_cookie = get_ion_cookie(ion_fd, src->fd);
+    EGLImageBuffer* eglImage = eglImageBufferMap->get(ion_cookie);
+    if( eglImage == 0 )
+    {
+        eglImage = L_wrap(src);
+        eglImageBufferMap->put(ion_cookie, eglImage);
+    }
+    else {
+        free_ion_cookie(ion_fd, ion_cookie);
+    }
+
+    return eglImage;
 }
diff --git a/gpu_tonemapper/EGLImageWrapper.h b/gpu_tonemapper/EGLImageWrapper.h
index 90aaf58..e9a4d68 100644
--- a/gpu_tonemapper/EGLImageWrapper.h
+++ b/gpu_tonemapper/EGLImageWrapper.h
@@ -20,15 +20,28 @@
 #ifndef __TONEMAPPER_EGLIMAGEWRAPPER_H__
 #define __TONEMAPPER_EGLIMAGEWRAPPER_H__
 
-#include <map>
+#include <utils/LruCache.h>
 #include "EGLImageBuffer.h"
 
 class EGLImageWrapper {
-  std::map<int, EGLImageBuffer *> eglImageBufferMap;
+    private:
+        class DeleteEGLImageCallback : public android::OnEntryRemoved<int, EGLImageBuffer*>
+        {
+        private:
+          int ion_fd;
+        public:
+          DeleteEGLImageCallback(int ion_fd);
+          void operator()(int& ion_cookie, EGLImageBuffer*& eglImage);
+        };
 
- public:
-  EGLImageBuffer *wrap(const void *pvt_handle);
-  void destroy();
+        android::LruCache<int, EGLImageBuffer *>* eglImageBufferMap;
+        DeleteEGLImageCallback* callback;
+        int ion_fd;
+
+    public:
+        EGLImageWrapper();
+        ~EGLImageWrapper();
+        EGLImageBuffer* wrap(const void *pvt_handle);
 };
 
 #endif  //__TONEMAPPER_EGLIMAGEWRAPPER_H__
diff --git a/gpu_tonemapper/TonemapFactory.cpp b/gpu_tonemapper/TonemapFactory.cpp
index cffc33a..5aae697 100644
--- a/gpu_tonemapper/TonemapFactory.cpp
+++ b/gpu_tonemapper/TonemapFactory.cpp
@@ -27,19 +27,8 @@
                                           void *lutXform, int lutXformSize)
 //----------------------------------------------------------------------------------------------------------------------------------------------------------
 {
-  // initializes the engine - does nothing if already initialized
-  engine_initialize();
-
   // build the tonemapper
   Tonemapper *tonemapper = Tonemapper::build(type, colorMap, colorMapSize, lutXform, lutXformSize);
 
   return tonemapper;
 }
-
-//------------------------------------------
-void TonemapperFactory_Destroy()
-//------------------------------------------
-{
-  // shutdown the engine
-  engine_shutdown();
-}
diff --git a/gpu_tonemapper/TonemapFactory.h b/gpu_tonemapper/TonemapFactory.h
index 1004170..404f4cd 100644
--- a/gpu_tonemapper/TonemapFactory.h
+++ b/gpu_tonemapper/TonemapFactory.h
@@ -30,9 +30,6 @@
 Tonemapper *TonemapperFactory_GetInstance(int type, void *colorMap, int colorMapSize,
                                           void *lutXform, int lutXformSize);
 
-// destroy tonemap session
-void TonemapperFactory_Destroy();
-
 #ifdef __cplusplus
 }
 #endif
diff --git a/gpu_tonemapper/Tonemapper.cpp b/gpu_tonemapper/Tonemapper.cpp
index bb7ba1b..ec74b80 100644
--- a/gpu_tonemapper/Tonemapper.cpp
+++ b/gpu_tonemapper/Tonemapper.cpp
@@ -39,17 +39,18 @@
 Tonemapper::~Tonemapper()
 //-----------------------------------------------------------------------------
 {
-  engine_bind();
+  engine_bind(engineContext);
   engine_deleteInputBuffer(tonemapTexture);
   engine_deleteInputBuffer(lutXformTexture);
   engine_deleteProgram(programID);
 
   // clear EGLImage mappings
   if (eglImageWrapper != 0) {
-    eglImageWrapper->destroy();
     delete eglImageWrapper;
     eglImageWrapper = 0;
   }
+
+  engine_shutdown(engineContext);
 }
 
 //-----------------------------------------------------------------------------
@@ -61,10 +62,14 @@
       ALOGE("Invalid Color Map size = %d", colorMapSize);
       return NULL;
   }
-  engine_bind();
 
   // build new tonemapper
   Tonemapper *tonemapper = new Tonemapper();
+
+  tonemapper->engineContext = engine_initialize();
+
+  engine_bind(tonemapper->engineContext);
+
   // load the 3d lut
   tonemapper->tonemapTexture = engine_load3DTexture(colorMap, colorMapSize, 0);
   // load the non-uniform xform
@@ -101,7 +106,7 @@
 //-----------------------------------------------------------------------------
 {
   // make current
-  engine_bind();
+  engine_bind(engineContext);
 
   // create eglimages if required
   EGLImageBuffer *dst_buffer = eglImageWrapper->wrap(dst);
diff --git a/gpu_tonemapper/Tonemapper.h b/gpu_tonemapper/Tonemapper.h
index 0f9bd51..1d6f808 100644
--- a/gpu_tonemapper/Tonemapper.h
+++ b/gpu_tonemapper/Tonemapper.h
@@ -24,9 +24,11 @@
 #define TONEMAP_INVERSE 1
 
 #include "EGLImageWrapper.h"
+#include "engine.h"
 
 class Tonemapper {
  private:
+  void* engineContext;
   unsigned int tonemapTexture;
   unsigned int lutXformTexture;
   unsigned int programID;
diff --git a/gpu_tonemapper/engine.h b/gpu_tonemapper/engine.h
index 5635ee3..ca914b2 100644
--- a/gpu_tonemapper/engine.h
+++ b/gpu_tonemapper/engine.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
  * Not a Contribution.
  *
  * Copyright 2015 The Android Open Source Project
@@ -20,9 +20,9 @@
 #ifndef __TONEMAPPER_ENGINE_H__
 #define __TONEMAPPER_ENGINE_H__
 
-bool engine_initialize();
-void engine_bind();
-void engine_shutdown();
+void* engine_initialize();
+void engine_bind(void*);
+void engine_shutdown(void*);
 
 unsigned int engine_loadProgram(int, const char **, int, const char **);
 void engine_setProgram(int);
@@ -39,4 +39,4 @@
 
 int engine_blit(int);
 
-#endif  //__TONEMAPPER_ENGINE_H__
\ No newline at end of file
+#endif  //__TONEMAPPER_ENGINE_H__
diff --git a/gpu_tonemapper/glengine.cpp b/gpu_tonemapper/glengine.cpp
index 2351d56..eda4e6b 100644
--- a/gpu_tonemapper/glengine.cpp
+++ b/gpu_tonemapper/glengine.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
  * Not a Contribution.
  *
  * Copyright 2015 The Android Open Source Project
@@ -24,37 +24,42 @@
 void checkGlError(const char *, int);
 void checkEglError(const char *, int);
 
-static EGLDisplay eglDisplay;
-static EGLContext eglContext;
-static EGLSurface eglSurface;
-
-static bool isEngineInitialized = false;
+class EngineContext {
+    public:
+    EGLDisplay eglDisplay;
+    EGLContext eglContext;
+    EGLSurface eglSurface;
+    EngineContext()
+    {
+        eglDisplay = EGL_NO_DISPLAY;
+        eglContext = EGL_NO_CONTEXT;
+        eglSurface = EGL_NO_SURFACE;
+    }
+};
 
 //-----------------------------------------------------------------------------
 // Make Current
-void engine_bind()
+void engine_bind(void* context)
 //-----------------------------------------------------------------------------
 {
-  EGL(eglMakeCurrent(eglDisplay, eglSurface, eglSurface, eglContext));
+  EngineContext* engineContext = (EngineContext*)(context);
+  EGL(eglMakeCurrent(engineContext->eglDisplay, engineContext->eglSurface, engineContext->eglSurface, engineContext->eglContext));
 }
 
 //-----------------------------------------------------------------------------
 // initialize GL
 //
-bool engine_initialize()
+void* engine_initialize()
 //-----------------------------------------------------------------------------
 {
-  if (isEngineInitialized)
-    return true;
-
-  EGLBoolean result = false;
+  EngineContext* engineContext = new EngineContext();
 
   // display
-  eglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
+  engineContext->eglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
   EGL(eglBindAPI(EGL_OPENGL_ES_API));
 
   // initialize
-  EGL(eglInitialize(eglDisplay, 0, 0));
+  EGL(eglInitialize(engineContext->eglDisplay, 0, 0));
 
   // config
   EGLConfig eglConfig;
@@ -65,38 +70,36 @@
                                   EGL_ALPHA_SIZE,   8,
                                   EGL_NONE};
   int numConfig = 0;
-  EGL(eglChooseConfig(eglDisplay, eglConfigAttribList, &eglConfig, 1, &numConfig));
+  EGL(eglChooseConfig(engineContext->eglDisplay, eglConfigAttribList, &eglConfig, 1, &numConfig));
 
   // context
   EGLint eglContextAttribList[] = {EGL_CONTEXT_CLIENT_VERSION, 3, EGL_NONE};
-  eglContext = eglCreateContext(eglDisplay, eglConfig, NULL, eglContextAttribList);
+  engineContext->eglContext = eglCreateContext(engineContext->eglDisplay, eglConfig, NULL, eglContextAttribList);
 
   // surface
   EGLint eglSurfaceAttribList[] = {EGL_WIDTH, 1, EGL_HEIGHT, 1, EGL_NONE, EGL_NONE};
-  eglSurface = eglCreatePbufferSurface(eglDisplay, eglConfig, eglSurfaceAttribList);
+  engineContext->eglSurface = eglCreatePbufferSurface(engineContext->eglDisplay, eglConfig, eglSurfaceAttribList);
 
-  result = (EGL_TRUE == eglMakeCurrent(eglDisplay, eglSurface, eglSurface, eglContext));
+  eglMakeCurrent(engineContext->eglDisplay, engineContext->eglSurface, engineContext->eglSurface, engineContext->eglContext);
 
-  isEngineInitialized = result;
+  ALOGI("In %s context = %p", __FUNCTION__, (void *)(engineContext->eglContext));
 
-  ALOGI("In %s result = %d context = %p", __FUNCTION__, result, (void *)eglContext);
-
-  return result;
+  return (void*)(engineContext);
 }
 
 //-----------------------------------------------------------------------------
 // Shutdown.
-void engine_shutdown()
+void engine_shutdown(void* context)
 //-----------------------------------------------------------------------------
 {
-  EGL(eglMakeCurrent(eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));
-  EGL(eglDestroySurface(eglDisplay, eglSurface));
-  EGL(eglDestroyContext(eglDisplay, eglContext));
-  EGL(eglTerminate(eglDisplay));
-  eglDisplay = EGL_NO_DISPLAY;
-  eglContext = EGL_NO_CONTEXT;
-  eglSurface = EGL_NO_SURFACE;
-  isEngineInitialized = false;
+  EngineContext* engineContext = (EngineContext*)context;
+  EGL(eglMakeCurrent(engineContext->eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));
+  EGL(eglDestroySurface(engineContext->eglDisplay, engineContext->eglSurface));
+  EGL(eglDestroyContext(engineContext->eglDisplay, engineContext->eglContext));
+  EGL(eglTerminate(engineContext->eglDisplay));
+  engineContext->eglDisplay = EGL_NO_DISPLAY;
+  engineContext->eglContext = EGL_NO_CONTEXT;
+  engineContext->eglSurface = EGL_NO_SURFACE;
 }
 
 //-----------------------------------------------------------------------------
@@ -206,14 +209,14 @@
   if (fd != -1) {
     EGLint attribs[] = {EGL_SYNC_NATIVE_FENCE_FD_ANDROID, fd, EGL_NONE};
 
-    EGLSyncKHR sync = eglCreateSyncKHR(eglDisplay, EGL_SYNC_NATIVE_FENCE_ANDROID, attribs);
+    EGLSyncKHR sync = eglCreateSyncKHR(eglGetCurrentDisplay(), EGL_SYNC_NATIVE_FENCE_ANDROID, attribs);
 
     if (sync == EGL_NO_SYNC_KHR) {
       ALOGE("%s - Failed to Create sync from source fd", __FUNCTION__);
     } else {
       // the gpu will wait for this sync - not this cpu thread.
-      EGL(eglWaitSyncKHR(eglDisplay, sync, 0));
-      EGL(eglDestroySyncKHR(eglDisplay, sync));
+      EGL(eglWaitSyncKHR(eglGetCurrentDisplay(), sync, 0));
+      EGL(eglDestroySyncKHR(eglGetCurrentDisplay(), sync));
     }
   }
 }
@@ -224,16 +227,16 @@
 {
   int fd = -1;
 
-  EGLSyncKHR sync = eglCreateSyncKHR(eglDisplay, EGL_SYNC_NATIVE_FENCE_ANDROID, NULL);
+  EGLSyncKHR sync = eglCreateSyncKHR(eglGetCurrentDisplay(), EGL_SYNC_NATIVE_FENCE_ANDROID, NULL);
   GL(glFlush());
   if (sync == EGL_NO_SYNC_KHR) {
     ALOGE("%s - Failed to Create Native Fence sync", __FUNCTION__);
   } else {
-    fd = eglDupNativeFenceFDANDROID(eglDisplay, sync);
+    fd = eglDupNativeFenceFDANDROID(eglGetCurrentDisplay(), sync);
     if (fd == EGL_NO_NATIVE_FENCE_FD_ANDROID) {
       ALOGE("%s - Failed to dup sync", __FUNCTION__);
     }
-    EGL(eglDestroySyncKHR(eglDisplay, sync));
+    EGL(eglDestroySyncKHR(eglGetCurrentDisplay(), sync));
   }
 
   return fd;
diff --git a/libcopybit/copybit.cpp b/libcopybit/copybit.cpp
index 10f5943..80b3cfe 100644
--- a/libcopybit/copybit.cpp
+++ b/libcopybit/copybit.cpp
@@ -148,6 +148,8 @@
         case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS: return MDP_Y_CBCR_H2V2_VENUS;
         case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS: return MDP_Y_CRCB_H2V2_VENUS;
         case HAL_PIXEL_FORMAT_NV12_ENCODEABLE: return MDP_Y_CBCR_H2V2;
+        case HAL_PIXEL_FORMAT_CbYCrY_422_I: return MDP_CBYCRY_H2V1;
+        case HAL_PIXEL_FORMAT_BGR_888: return MDP_BGR_888;
     }
     return -1;
 }
diff --git a/libgralloc/alloc_controller.cpp b/libgralloc/alloc_controller.cpp
index 583767a..805948b 100644
--- a/libgralloc/alloc_controller.cpp
+++ b/libgralloc/alloc_controller.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011 - 2016, The Linux Foundation. All rights reserved.
+ * 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
@@ -30,24 +30,18 @@
 #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"
-#include <qdMetaData.h>
-#include <utils/Singleton.h>
-#include <utils/Mutex.h>
-#include <algorithm>
-
-#ifdef VENUS_COLOR_FORMAT
-#include <media/msm_media_info.h>
-#else
-#define VENUS_Y_STRIDE(args...) 0
-#define VENUS_Y_SCANLINES(args...) 0
-#define VENUS_BUFFER_SIZE(args...) 0
-#endif
 
 #define ASTC_BLOCK_SIZE 16
 
@@ -107,7 +101,6 @@
 
 //------------- MDPCapabilityInfo-----------------------//
 MDPCapabilityInfo :: MDPCapabilityInfo() {
-  qdutils::querySDEInfo(HAS_MACRO_TILE, &isMacroTileSupported);
   qdutils::querySDEInfo(HAS_UBWC, &isUBwcSupported);
   qdutils::querySDEInfo(HAS_WB_UBWC, &isWBUBWCSupported);
 }
@@ -117,7 +110,6 @@
 {
     LINK_adreno_compute_aligned_width_and_height = NULL;
     LINK_adreno_compute_padding = NULL;
-    LINK_adreno_isMacroTilingSupportedByGpu = NULL;
     LINK_adreno_compute_compressedfmt_aligned_width_and_height = NULL;
     LINK_adreno_isUBWCSupportedByGpu = NULL;
     LINK_adreno_get_gpu_pixel_alignment = NULL;
@@ -128,8 +120,6 @@
                 ::dlsym(libadreno_utils, "compute_aligned_width_and_height");
         *(void **)&LINK_adreno_compute_padding =
                 ::dlsym(libadreno_utils, "compute_surface_padding");
-        *(void **)&LINK_adreno_isMacroTilingSupportedByGpu =
-                ::dlsym(libadreno_utils, "isMacroTilingSupportedByGpu");
         *(void **)&LINK_adreno_compute_compressedfmt_aligned_width_and_height =
                 ::dlsym(libadreno_utils,
                         "compute_compressedfmt_aligned_width_and_height");
@@ -157,16 +147,6 @@
     }
 }
 
-int AdrenoMemInfo::isMacroTilingSupportedByGPU()
-{
-    if ((libadreno_utils)) {
-        if(LINK_adreno_isMacroTilingSupportedByGpu) {
-            return LINK_adreno_isMacroTilingSupportedByGpu();
-        }
-    }
-    return 0;
-}
-
 void AdrenoMemInfo::getAlignedWidthAndHeight(const private_handle_t *hnd, int& aligned_w,
                           int& aligned_h) {
     MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
@@ -217,6 +197,7 @@
         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:
@@ -241,7 +222,7 @@
 
     // Currently surface padding is only computed for RGB* surfaces.
     if (isUncompressedRgbFormat(format) == true) {
-        int tileEnabled = ubwc_enabled || isMacroTileEnabled(format, usage);
+        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);
@@ -276,6 +257,7 @@
             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:
@@ -538,38 +520,6 @@
     return memalloc;
 }
 
-bool isMacroTileEnabled(int format, int usage)
-{
-    bool tileEnabled = false;
-    // Check whether GPU & MDSS supports MacroTiling feature
-    if(AdrenoMemInfo::getInstance().isMacroTilingSupportedByGPU() &&
-       MDPCapabilityInfo::getInstance().isMacroTilingSupportedByMDP())
-    {
-        // check the format
-        switch(format)
-        {
-            case  HAL_PIXEL_FORMAT_RGBA_8888:
-            case  HAL_PIXEL_FORMAT_RGBX_8888:
-            case  HAL_PIXEL_FORMAT_BGRA_8888:
-            case  HAL_PIXEL_FORMAT_RGB_565:
-            case  HAL_PIXEL_FORMAT_BGR_565:
-                {
-                    tileEnabled = true;
-                    // check the usage flags
-                    if (usage & (GRALLOC_USAGE_SW_READ_MASK |
-                                GRALLOC_USAGE_SW_WRITE_MASK)) {
-                        // Application intends to use CPU for rendering
-                        tileEnabled = false;
-                    }
-                    break;
-                }
-            default:
-                break;
-        }
-    }
-    return tileEnabled;
-}
-
 // helper function
 unsigned int getSize(int format, int width, int height, int usage,
         const int alignedw, const int alignedh) {
@@ -639,6 +589,7 @@
         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;
@@ -736,20 +687,6 @@
     return size;
 }
 
-void getBufferAttributes(int width, int height, int format, int usage,
-        int& alignedw, int &alignedh, int& tiled, unsigned int& size)
-{
-    tiled = isUBwcEnabled(format, usage) || isMacroTileEnabled(format, usage);
-
-    AdrenoMemInfo::getInstance().getAlignedWidthAndHeight(width,
-            height,
-            format,
-            usage,
-            alignedw,
-            alignedh);
-    size = getSize(format, width, height, usage, alignedw, alignedh);
-}
-
 void getYuvUbwcSPPlaneInfo(uint64_t base, int width, int height,
                            int color_format, struct android_ycbcr* ycbcr)
 {
@@ -873,6 +810,16 @@
             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:
diff --git a/libgralloc/gpu.cpp b/libgralloc/gpu.cpp
index 5911314..a0339b4 100644
--- a/libgralloc/gpu.cpp
+++ b/libgralloc/gpu.cpp
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2010 The Android Open Source Project
- * Copyright (c) 2011-2014 The Linux Foundation. All rights reserved.
+ * 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.
@@ -134,10 +134,6 @@
             flags |= private_handle_t::PRIV_FLAGS_SECURE_DISPLAY;
         }
 
-        if(isMacroTileEnabled(format, usage)) {
-            flags |= private_handle_t::PRIV_FLAGS_TILE_RENDERED;
-        }
-
         if (isUBwcEnabled(format, usage)) {
             flags |= private_handle_t::PRIV_FLAGS_UBWC_ALIGNED;
         }
diff --git a/libgralloc/gr.h b/libgralloc/gr.h
index 7d055fc..ae26df9 100644
--- a/libgralloc/gr.h
+++ b/libgralloc/gr.h
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2008 The Android Open Source Project
- * Copyright (c) 2011 - 2016, The Linux Foundation. All rights reserved.
+ * 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.
@@ -54,15 +54,6 @@
 unsigned int getBufferSizeAndDimensions(int width, int height, int format,
         int& alignedw, int &alignedh);
 
-
-// Attributes include aligned width, aligned height, tileEnabled and size of the buffer
-void getBufferAttributes(int width, int height, int format, int usage,
-                           int& alignedw, int &alignedh,
-                           int& tileEnabled, unsigned int &size);
-
-
-bool isMacroTileEnabled(int format, int usage);
-
 int decideBufferHandlingMechanism(int format, const char *compositionUsed,
                                   int hasBlitEngine, int *needConversion,
                                   int *useBufferDirectly);
@@ -148,15 +139,6 @@
      */
     void getUnalignedWidthAndHeight(const private_handle_t *hnd, int& unaligned_w,
                             int& unaligned_h);
-
-    /*
-     * Function to return whether GPU support MacroTile feature
-     *
-     * @return >0 : supported
-     *          0 : not supported
-     */
-    int isMacroTilingSupportedByGPU();
-
     /*
      * Function to query whether GPU supports UBWC for given HAL format
      * @return > 0 : supported
@@ -190,8 +172,6 @@
                                                 int *aligned_w,
                                                 int *aligned_h);
 
-        int (*LINK_adreno_isMacroTilingSupportedByGpu) (void);
-
         void(*LINK_adreno_compute_compressedfmt_aligned_width_and_height)(
                                                 int width,
                                                 int height,
@@ -211,20 +191,12 @@
 
 class MDPCapabilityInfo : public android::Singleton <MDPCapabilityInfo>
 {
-    int isMacroTileSupported = 0;
     int isUBwcSupported = 0;
     int isWBUBWCSupported = 0;
 
     public:
         MDPCapabilityInfo();
         /*
-        * Function to return whether MDP support MacroTile feature
-        *
-        * @return  1 : supported
-        *          0 : not supported
-        */
-        int isMacroTilingSupportedByMDP() { return isMacroTileSupported; }
-        /*
         * Function to return whether MDP supports UBWC feature
         *
         * @return  1 : supported
diff --git a/libgralloc/gralloc_priv.h b/libgralloc/gralloc_priv.h
index 738b63f..5797546 100644
--- a/libgralloc/gralloc_priv.h
+++ b/libgralloc/gralloc_priv.h
@@ -118,6 +118,8 @@
 #define HAL_PIXEL_FORMAT_BGRX_1010102            0x11C
 #define HAL_PIXEL_FORMAT_XBGR_2101010            0x11D
 #define HAL_PIXEL_FORMAT_YCbCr_420_P010          0x11F
+#define HAL_PIXEL_FORMAT_CbYCrY_422_I            0x120
+#define HAL_PIXEL_FORMAT_BGR_888                 0x121
 
 #define HAL_PIXEL_FORMAT_INTERLACE               0x180
 
diff --git a/libgralloc/mapper.cpp b/libgralloc/mapper.cpp
index 132c768..acf5e2c 100644
--- a/libgralloc/mapper.cpp
+++ b/libgralloc/mapper.cpp
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2008 The Android Open Source Project
- * Copyright (c) 2011-2016, The Linux Foundation. All rights reserved.
+ * 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.
@@ -397,8 +397,7 @@
                 int *alignedWidth = va_arg(args, int *);
                 int *alignedHeight = va_arg(args, int *);
                 int *tileEnabled = va_arg(args,int *);
-                *tileEnabled = isUBwcEnabled(format, usage) ||
-                               isMacroTileEnabled(format, usage);
+                *tileEnabled = isUBwcEnabled(format, usage);
                 AdrenoMemInfo::getInstance().getAlignedWidthAndHeight(width,
                         height, format, usage, *alignedWidth, *alignedHeight);
                 res = 0;
diff --git a/libgralloc1/gr_adreno_info.cpp b/libgralloc1/gr_adreno_info.cpp
index adb59f0..0692ca6 100644
--- a/libgralloc1/gr_adreno_info.cpp
+++ b/libgralloc1/gr_adreno_info.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2016, The Linux Foundation. All rights reserved.
+ * 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
@@ -47,8 +47,6 @@
         ::dlsym(libadreno_utils_, "compute_aligned_width_and_height");
     *reinterpret_cast<void **>(&LINK_adreno_compute_padding) =
         ::dlsym(libadreno_utils_, "compute_surface_padding");
-    *reinterpret_cast<void **>(&LINK_adreno_isMacroTilingSupportedByGpu) =
-        ::dlsym(libadreno_utils_, "isMacroTilingSupportedByGpu");
     *reinterpret_cast<void **>(&LINK_adreno_compute_compressedfmt_aligned_width_and_height) =
         ::dlsym(libadreno_utils_, "compute_compressedfmt_aligned_width_and_height");
     *reinterpret_cast<void **>(&LINK_adreno_isUBWCSupportedByGpu) =
@@ -84,14 +82,6 @@
   }
 }
 
-bool AdrenoMemInfo::IsMacroTilingSupportedByGPU() {
-  if (LINK_adreno_isMacroTilingSupportedByGpu) {
-    return LINK_adreno_isMacroTilingSupportedByGpu();
-  }
-
-  return false;
-}
-
 void AdrenoMemInfo::AlignUnCompressedRGB(int width, int height, int format, int tile_enabled,
                                          unsigned int *aligned_w, unsigned int *aligned_h) {
   *aligned_w = (unsigned int)ALIGN(width, 32);
diff --git a/libgralloc1/gr_adreno_info.h b/libgralloc1/gr_adreno_info.h
index 7b053ad..7ad6801 100644
--- a/libgralloc1/gr_adreno_info.h
+++ b/libgralloc1/gr_adreno_info.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2016, The Linux Foundation. All rights reserved.
+ * 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
@@ -30,13 +30,7 @@
 #ifndef __GR_ADRENO_INFO_H__
 #define __GR_ADRENO_INFO_H__
 
-#ifdef VENUS_COLOR_FORMAT
 #include <media/msm_media_info.h>
-#else
-#define VENUS_Y_STRIDE(args...) 0
-#define VENUS_Y_SCANLINES(args...) 0
-#define VENUS_BUFFER_SIZE(args...) 0
-#endif
 
 namespace gralloc1 {
 
@@ -112,14 +106,6 @@
   uint32_t GetGpuPixelAlignment();
 
   /*
-   * Function to return whether GPU support MacroTile feature
-   *
-   * @return >0 : supported
-   *          0 : not supported
-   */
-  bool IsMacroTilingSupportedByGPU();
-
-  /*
    * Function to query whether GPU supports UBWC for given HAL format
    * @return > 0 : supported
    *           0 : not supported
@@ -139,7 +125,6 @@
                                                        int tile_mode, int raster_mode,
                                                        int padding_threshold, int *aligned_w,
                                                        int *aligned_h) = NULL;
-  int (*LINK_adreno_isMacroTilingSupportedByGpu)(void) = NULL;
   void (*LINK_adreno_compute_compressedfmt_aligned_width_and_height)(
       int width, int height, int format, int tile_mode, int raster_mode, int padding_threshold,
       int *aligned_w, int *aligned_h, int *bpp) = NULL;
diff --git a/libgralloc1/gr_allocator.cpp b/libgralloc1/gr_allocator.cpp
index 578b2f6..fefd664 100644
--- a/libgralloc1/gr_allocator.cpp
+++ b/libgralloc1/gr_allocator.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2016, The Linux Foundation. All rights reserved.
+ * 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
@@ -84,11 +84,6 @@
     return false;
   }
 
-  gpu_support_macrotile = adreno_helper_->IsMacroTilingSupportedByGPU();
-  int supports_macrotile = 0;
-  qdutils::querySDEInfo(qdutils::HAS_MACRO_TILE, &supports_macrotile);
-  display_support_macrotile = !!supports_macrotile;
-
   return true;
 }
 
@@ -221,34 +216,6 @@
   return true;
 }
 
-bool Allocator::IsMacroTileEnabled(int format, gralloc1_producer_usage_t prod_usage,
-                                   gralloc1_consumer_usage_t cons_usage) {
-  bool tile_enabled = false;
-
-  // Check whether GPU & MDSS supports MacroTiling feature
-  if (!adreno_helper_->IsMacroTilingSupportedByGPU() || !display_support_macrotile) {
-    return tile_enabled;
-  }
-
-  // check the format
-  switch (format) {
-    case HAL_PIXEL_FORMAT_RGBA_8888:
-    case HAL_PIXEL_FORMAT_RGBX_8888:
-    case HAL_PIXEL_FORMAT_BGRA_8888:
-    case HAL_PIXEL_FORMAT_RGB_565:
-    case HAL_PIXEL_FORMAT_BGR_565:
-      if (!CpuCanAccess(prod_usage, cons_usage)) {
-        // not touched by CPU
-        tile_enabled = true;
-      }
-      break;
-    default:
-      break;
-  }
-
-  return tile_enabled;
-}
-
 // helper function
 unsigned int Allocator::GetSize(const BufferDescriptor &descriptor, unsigned int alignedw,
                                 unsigned int alignedh) {
@@ -361,22 +328,6 @@
   *size = GetSize(descriptor, *alignedw, *alignedh);
 }
 
-void Allocator::GetBufferAttributes(const BufferDescriptor &descriptor, unsigned int *alignedw,
-                                    unsigned int *alignedh, int *tiled, unsigned int *size) {
-  int format = descriptor.GetFormat();
-  gralloc1_producer_usage_t prod_usage = descriptor.GetProducerUsage();
-  gralloc1_consumer_usage_t cons_usage = descriptor.GetConsumerUsage();
-
-  *tiled = false;
-  if (IsUBwcEnabled(format, prod_usage, cons_usage) ||
-      IsMacroTileEnabled(format, prod_usage, cons_usage)) {
-    *tiled = true;
-  }
-
-  GetAlignedWidthAndHeight(descriptor, alignedw, alignedh);
-  *size = GetSize(descriptor, *alignedw, *alignedh);
-}
-
 void Allocator::GetYuvUbwcSPPlaneInfo(uint64_t base, uint32_t width, uint32_t height,
                                       int color_format, struct android_ycbcr *ycbcr) {
   // UBWC buffer has these 4 planes in the following sequence:
@@ -820,7 +771,7 @@
 
   // Currently surface padding is only computed for RGB* surfaces.
   bool ubwc_enabled = IsUBwcEnabled(format, prod_usage, cons_usage);
-  int tile = ubwc_enabled || IsMacroTileEnabled(format, prod_usage, cons_usage);
+  int tile = ubwc_enabled;
 
   if (IsUncompressedRGBFormat(format)) {
     adreno_helper_->AlignUnCompressedRGB(width, height, format, tile, alignedw, alignedh);
diff --git a/libgralloc1/gr_allocator.h b/libgralloc1/gr_allocator.h
index 583b2d7..da4fbee 100644
--- a/libgralloc1/gr_allocator.h
+++ b/libgralloc1/gr_allocator.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2016, The Linux Foundation. All rights reserved.
+ * 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
@@ -54,8 +54,6 @@
   int CleanBuffer(void *base, unsigned int size, unsigned int offset, int fd, int op);
   int AllocateMem(AllocData *data, gralloc1_producer_usage_t prod_usage,
                   gralloc1_consumer_usage_t cons_usage);
-  bool IsMacroTileEnabled(int format, gralloc1_producer_usage_t prod_usage,
-                          gralloc1_consumer_usage_t cons_usage);
   // @return : index of the descriptor with maximum buffer size req
   bool CheckForBufferSharing(uint32_t num_descriptors, const BufferDescriptor *descriptors,
                              int *max_index);
@@ -68,8 +66,6 @@
                                   unsigned int *alignedw, unsigned int *alignedh);
   void GetAlignedWidthAndHeight(const BufferDescriptor &d, unsigned int *aligned_w,
                                 unsigned int *aligned_h);
-  void GetBufferAttributes(const BufferDescriptor &d, unsigned int *alignedw,
-                           unsigned int *alignedh, int *tiled, unsigned int *size);
   int GetYUVPlaneInfo(const private_handle_t *hnd, struct android_ycbcr *ycbcr);
   int GetRgbDataAddress(private_handle_t *hnd, void **rgb_data);
   bool UseUncached(gralloc1_producer_usage_t usage);
@@ -92,8 +88,6 @@
   void GetIonHeapInfo(gralloc1_producer_usage_t prod_usage, gralloc1_consumer_usage_t cons_usage,
                       unsigned int *ion_heap_id, unsigned int *alloc_type, unsigned int *ion_flags);
 
-  bool gpu_support_macrotile = false;
-  bool display_support_macrotile = false;
   IonAlloc *ion_allocator_ = NULL;
   AdrenoMemInfo *adreno_helper_ = NULL;
 };
diff --git a/libgralloc1/gr_buf_mgr.cpp b/libgralloc1/gr_buf_mgr.cpp
index 9650583..cea8ac9 100644
--- a/libgralloc1/gr_buf_mgr.cpp
+++ b/libgralloc1/gr_buf_mgr.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2016 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2017 The Linux Foundation. All rights reserved.
  * Not a Contribution
  *
  * Copyright (C) 2010 The Android Open Source Project
@@ -332,10 +332,6 @@
     flags |= private_handle_t::PRIV_FLAGS_SECURE_DISPLAY;
   }
 
-  if (allocator_->IsMacroTileEnabled(format, prod_usage, cons_usage)) {
-    flags |= private_handle_t::PRIV_FLAGS_TILE_RENDERED;
-  }
-
   if (allocator_->IsUBwcEnabled(format, prod_usage, cons_usage)) {
     flags |= private_handle_t::PRIV_FLAGS_UBWC_ALIGNED;
   }
@@ -573,8 +569,7 @@
       int *tile_enabled = va_arg(args, int *);
       unsigned int alignedw, alignedh;
       BufferDescriptor descriptor(width, height, format, prod_usage, cons_usage);
-      *tile_enabled = allocator_->IsUBwcEnabled(format, prod_usage, cons_usage) ||
-                      allocator_->IsMacroTileEnabled(format, prod_usage, cons_usage);
+      *tile_enabled = allocator_->IsUBwcEnabled(format, prod_usage, cons_usage);
 
       allocator_->GetAlignedWidthAndHeight(descriptor, &alignedw, &alignedh);
       *aligned_width = INT(alignedw);
diff --git a/liblight/lights.c b/liblight/lights.c
index 7a3775e..89c27cd 100644
--- a/liblight/lights.c
+++ b/liblight/lights.c
@@ -1,6 +1,7 @@
 /*
+ * Copyright (C) 2014, 2017 The  Linux Foundation. All rights reserved.
+ * Not a contribution
  * Copyright (C) 2008 The Android Open Source Project
- * Copyright (C) 2014 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.
@@ -33,12 +34,17 @@
 
 #include <hardware/lights.h>
 
+#ifndef DEFAULT_LOW_PERSISTENCE_MODE_BRIGHTNESS
+#define DEFAULT_LOW_PERSISTENCE_MODE_BRIGHTNESS 0x80
+#endif
+
 /******************************************************************************/
 
 static pthread_once_t g_init = PTHREAD_ONCE_INIT;
 static pthread_mutex_t g_lock = PTHREAD_MUTEX_INITIALIZER;
 static struct light_state_t g_notification;
 static struct light_state_t g_battery;
+static int g_last_backlight_mode = BRIGHTNESS_MODE_USER;
 static int g_attention = 0;
 
 char const*const RED_LED_FILE
@@ -65,6 +71,9 @@
 char const*const BLUE_BLINK_FILE
         = "/sys/class/leds/blue/blink";
 
+char const*const PERSISTENCE_FILE
+        = "/sys/class/graphics/fb0/msm_fb_persist_mode";
+
 /**
  * device methods
  */
@@ -117,11 +126,32 @@
 {
     int err = 0;
     int brightness = rgb_to_brightness(state);
+    unsigned int lpEnabled =
+        state->brightnessMode == BRIGHTNESS_MODE_LOW_PERSISTENCE;
     if(!dev) {
         return -1;
     }
+
     pthread_mutex_lock(&g_lock);
-    err = write_int(LCD_FILE, brightness);
+    // Toggle low persistence mode state
+    if ((g_last_backlight_mode != state->brightnessMode && lpEnabled) ||
+        (!lpEnabled &&
+         g_last_backlight_mode == BRIGHTNESS_MODE_LOW_PERSISTENCE)) {
+        if ((err = write_int(PERSISTENCE_FILE, lpEnabled)) != 0) {
+            ALOGE("%s: Failed to write to %s: %s\n", __FUNCTION__,
+                   PERSISTENCE_FILE, strerror(errno));
+        }
+        if (lpEnabled != 0) {
+            brightness = DEFAULT_LOW_PERSISTENCE_MODE_BRIGHTNESS;
+        }
+    }
+
+    g_last_backlight_mode = state->brightnessMode;
+
+    if (!err) {
+        err = write_int(LCD_FILE, brightness);
+    }
+
     pthread_mutex_unlock(&g_lock);
     return err;
 }
@@ -307,7 +337,7 @@
     memset(dev, 0, sizeof(*dev));
 
     dev->common.tag = HARDWARE_DEVICE_TAG;
-    dev->common.version = 0;
+    dev->common.version = LIGHTS_DEVICE_API_VERSION_2_0;
     dev->common.module = (struct hw_module_t*)module;
     dev->common.close = (int (*)(struct hw_device_t*))close_lights;
     dev->set_light = set_light;
diff --git a/libqdutils/qd_utils.cpp b/libqdutils/qd_utils.cpp
index b84ae87..170b1d8 100644
--- a/libqdutils/qd_utils.cpp
+++ b/libqdutils/qd_utils.cpp
@@ -27,6 +27,7 @@
  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+#include <unistd.h>
 #include "qd_utils.h"
 
 namespace qdutils {
@@ -81,7 +82,31 @@
     return -1;
 }
 
-int querySDEInfo(HWQueryType type, int *value) {
+static int querySDEInfoDRM(HWQueryType type, int *value) {
+    char property[PROPERTY_VALUE_MAX] = {0};
+
+    // TODO(user): If future targets don't support WB UBWC, add separate
+    // properties in target specific system.prop and have clients like WFD
+    // directly rely on those.
+    switch(type) {
+    case HAS_UBWC:
+    case HAS_WB_UBWC:  // WFD stack still uses this
+        *value = 1;
+        property_get("debug.gralloc.gfx_ubwc_disable", property, "0");
+        if(!(strncmp(property, "1", PROPERTY_VALUE_MAX)) ||
+                !(strncmp(property, "true", PROPERTY_VALUE_MAX))) {
+            *value = 0;
+        }
+        break;
+    default:
+        ALOGE("Invalid query type %d", type);
+        return -EINVAL;
+    }
+
+    return 0;
+}
+
+static int querySDEInfoFB(HWQueryType type, int *value) {
     FILE *fileptr = NULL;
     const char *featureName;
     char stringBuffer[MAX_STRING_LENGTH];
@@ -90,9 +115,6 @@
     char *tokens[maxCount] = { NULL };
 
     switch(type) {
-    case HAS_MACRO_TILE:
-        featureName = "tile_format";
-        break;
     case HAS_UBWC:
         featureName = "ubwc";
         break;
@@ -134,6 +156,18 @@
     return 0;
 }
 
+int querySDEInfo(HWQueryType type, int *value) {
+    if (!value) {
+        return -EINVAL;
+    }
+
+    if (getDriverType() ==  DriverType::DRM) {
+        return querySDEInfoDRM(type, value);
+    }
+
+    return querySDEInfoFB(type, value);
+}
+
 int getHDMINode(void) {
     return getExternalNode("dtv panel");
 }
@@ -241,4 +275,10 @@
     return 0;
 }
 
+DriverType getDriverType() {
+    const char *fb_caps = "/sys/devices/virtual/graphics/fb0/mdp/caps";
+    // 0 - File exists
+    return access(fb_caps, F_OK) ? DriverType::DRM : DriverType::FB;
+}
+
 }; //namespace qdutils
diff --git a/libqdutils/qd_utils.h b/libqdutils/qd_utils.h
index 5e8d1bf..7b3ae40 100644
--- a/libqdutils/qd_utils.h
+++ b/libqdutils/qd_utils.h
@@ -47,7 +47,6 @@
 namespace qdutils {
 
 enum HWQueryType {
-    HAS_MACRO_TILE = 0,
     HAS_UBWC = 1,
     HAS_WB_UBWC = 2
 };
@@ -65,5 +64,11 @@
 bool isDPConnected();
 int getDPTestConfig(uint32_t *panelBpp, uint32_t *patternType);
 
+enum class DriverType {
+    FB = 0,
+    DRM,
+};
+DriverType getDriverType();
+
 }; //namespace qdutils
 #endif
diff --git a/sdm/include/core/layer_buffer.h b/sdm/include/core/layer_buffer.h
index 4b42e7b..0a8a473 100644
--- a/sdm/include/core/layer_buffer.h
+++ b/sdm/include/core/layer_buffer.h
@@ -149,6 +149,7 @@
                                       //!<    y(0), u(0), y(1), v(0), y(2), u(2), y(3), v(2)
                                       //!<    y(n-1), u(n-1), y(n), v(n-1)
 
+  kFormatCbYCrY422H2V1Packed,
   kFormatInvalid = 0xFFFFFFFF,
 };
 
diff --git a/sdm/include/core/sdm_types.h b/sdm/include/core/sdm_types.h
index af7a20b..367ab38 100644
--- a/sdm/include/core/sdm_types.h
+++ b/sdm/include/core/sdm_types.h
@@ -53,6 +53,7 @@
   kErrorHardware,         //!< A hardware error has occured.
   kErrorTimeOut,          //!< The operation has timed out to prevent client from waiting forever.
   kErrorShutDown,         //!< Driver is processing shutdown sequence
+  kErrorPerfValidation,   //!< Bandwidth or Clock requirement validation failure.
 };
 
 /*! @brief This structure is defined for client and library compatibility check purpose only. This
diff --git a/sdm/libs/core/Android.mk b/sdm/libs/core/Android.mk
index f13c862..50f087d 100644
--- a/sdm/libs/core/Android.mk
+++ b/sdm/libs/core/Android.mk
@@ -7,7 +7,7 @@
 LOCAL_C_INCLUDES              := $(common_includes) $(kernel_includes) $(common_header_export_path)
 LOCAL_CFLAGS                  := -Wno-unused-parameter -DLOG_TAG=\"SDM\" $(common_flags)
 LOCAL_HW_INTF_PATH            := fb
-LOCAL_SHARED_LIBRARIES        := libdl liblog libsdmutils
+LOCAL_SHARED_LIBRARIES        := libdl libsdmutils
 LOCAL_ADDITIONAL_DEPENDENCIES := $(common_deps) $(kernel_deps)
 LOCAL_SRC_FILES               := core_interface.cpp \
                                  core_impl.cpp \
diff --git a/sdm/libs/core/comp_manager.cpp b/sdm/libs/core/comp_manager.cpp
index 0592ba4..e770684 100644
--- a/sdm/libs/core/comp_manager.cpp
+++ b/sdm/libs/core/comp_manager.cpp
@@ -245,13 +245,17 @@
   // Set use_cursor constraint to Strategy
   constraints->use_cursor = display_comp_ctx->valid_cursor;
 
-  // Avoid idle fallback, if there is only one app layer.
   // TODO(user): App layer count will change for hybrid composition
   uint32_t app_layer_count = UINT32(hw_layers->info.stack->layers.size()) - 1;
-  if ((app_layer_count > 1 && display_comp_ctx->idle_fallback) || display_comp_ctx->fallback_) {
+  if (display_comp_ctx->idle_fallback || display_comp_ctx->thermal_fallback_) {
     // Handle the idle timeout by falling back
     constraints->safe_mode = true;
   }
+
+  // Avoid safe mode, if there is only one app layer.
+  if (app_layer_count == 1) {
+     constraints->safe_mode = false;
+  }
 }
 
 void CompManager::PrePrepare(Handle display_ctx, HWLayers *hw_layers) {
@@ -413,9 +417,9 @@
           reinterpret_cast<DisplayCompositionContext *>(display_ctx);
 
   if (thermal_level >= kMaxThermalLevel) {
-    display_comp_ctx->fallback_ = true;
+    display_comp_ctx->thermal_fallback_ = true;
   } else {
-    display_comp_ctx->fallback_ = false;
+    display_comp_ctx->thermal_fallback_ = false;
   }
 }
 
diff --git a/sdm/libs/core/comp_manager.h b/sdm/libs/core/comp_manager.h
index f0044ec..3713971 100644
--- a/sdm/libs/core/comp_manager.h
+++ b/sdm/libs/core/comp_manager.h
@@ -92,7 +92,7 @@
     uint32_t max_strategies = 0;
     uint32_t remaining_strategies = 0;
     bool idle_fallback = false;
-    bool fallback_ = false;
+    bool thermal_fallback_ = false;
     // Using primary panel flag of hw panel to configure Constraints. We do not need other hw
     // panel parameters for now.
     bool is_primary_panel = false;
diff --git a/sdm/libs/core/display_base.cpp b/sdm/libs/core/display_base.cpp
index d46e74b..4a31a0f 100644
--- a/sdm/libs/core/display_base.cpp
+++ b/sdm/libs/core/display_base.cpp
@@ -66,9 +66,6 @@
     }
   }
 
-  req_mixer_width_ = mixer_attributes_.width;
-  req_mixer_height_ = mixer_attributes_.height;
-
   // Override x_pixels and y_pixels of frame buffer with mixer width and height
   fb_config_.x_pixels = mixer_attributes_.width;
   fb_config_.y_pixels = mixer_attributes_.height;
@@ -715,8 +712,8 @@
   }
 
   DisplayError error = kErrorNone;
-  // Set client requests when not in HDR Mode.
-  if (!hdr_playback_mode_) {
+  // Set client requests when not in HDR Mode or lut generation is disabled
+  if (disable_hdr_lut_gen_ || !hdr_playback_mode_) {
     error = SetColorModeInternal(color_mode);
     if (error != kErrorNone) {
       return error;
@@ -952,6 +949,13 @@
   uint32_t align_x = display_attributes_.is_device_split ? 4 : 2;
   uint32_t align_y = 2;
 
+  if (req_mixer_width_ && req_mixer_height_) {
+    *new_mixer_width = req_mixer_width_;
+    *new_mixer_height = req_mixer_height_;
+
+    return (req_mixer_width_ != mixer_width || req_mixer_height_ != mixer_height);
+  }
+
   for (uint32_t i = 0; i < layer_count; i++) {
     Layer *layer = layers.at(i);
 
@@ -997,13 +1001,6 @@
     }
 
     return true;
-  } else {
-    if (req_mixer_width_ != mixer_width || req_mixer_height_ != mixer_height) {
-      *new_mixer_width = req_mixer_width_;
-      *new_mixer_height = req_mixer_height_;
-
-      return true;
-    }
   }
 
   return false;
@@ -1197,8 +1194,8 @@
 DisplayError DisplayBase::HandleHDR(LayerStack *layer_stack) {
   DisplayError error = kErrorNone;
 
-  if (disable_hdr_lut_gen_) {
-    // Do not apply HDR Mode when hdr lut generation is disabled
+  if (display_type_ != kPrimary) {
+    // Handling is needed for only primary displays
     return kErrorNone;
   }
 
@@ -1206,8 +1203,10 @@
     //  HDR playback off - set prev mode
     if (hdr_playback_mode_) {
       hdr_playback_mode_ = false;
-      if (color_mgr_) {
+      if (color_mgr_ && !disable_hdr_lut_gen_) {
+        // Do not apply HDR Mode when hdr lut generation is disabled
         DLOGI("Setting color mode = %s", current_color_mode_.c_str());
+        //  HDR playback off - set prev mode
         error = SetColorModeInternal(current_color_mode_);
       }
       comp_manager_->ControlDpps(true);  // Enable Dpps
@@ -1217,7 +1216,7 @@
     if (!hdr_playback_mode_ && !layer_stack->flags.animating) {
       // hdr is starting
       hdr_playback_mode_ = true;
-      if (color_mgr_) {
+      if (color_mgr_ && !disable_hdr_lut_gen_) {
         DLOGI("Setting HDR color mode = %s", hdr_color_mode_.c_str());
         error = SetColorModeInternal(hdr_color_mode_);
       }
diff --git a/sdm/libs/core/fb/hw_device.cpp b/sdm/libs/core/fb/hw_device.cpp
index f6c9ae0..7d97d52 100644
--- a/sdm/libs/core/fb/hw_device.cpp
+++ b/sdm/libs/core/fb/hw_device.cpp
@@ -613,6 +613,7 @@
   case kFormatRGBX8888Ubwc:             *target = MDP_RGBX_8888_UBWC;    break;
   case kFormatBGR565Ubwc:               *target = MDP_RGB_565_UBWC;      break;
   case kFormatYCbCr420SPVenusUbwc:      *target = MDP_Y_CBCR_H2V2_UBWC;  break;
+  case kFormatCbYCrY422H2V1Packed:      *target = MDP_CBYCRY_H2V1;       break;
   case kFormatRGBA1010102:              *target = MDP_RGBA_1010102;      break;
   case kFormatARGB2101010:              *target = MDP_ARGB_2101010;      break;
   case kFormatRGBX1010102:              *target = MDP_RGBX_1010102;      break;
@@ -683,6 +684,7 @@
     *target = width;
     break;
   case kFormatYCbCr422H2V1Packed:
+  case kFormatCbYCrY422H2V1Packed:
   case kFormatYCrCb422H2V1SemiPlanar:
   case kFormatYCrCb422H1V2SemiPlanar:
   case kFormatYCbCr422H2V1SemiPlanar:
diff --git a/sdm/libs/hwc/hwc_buffer_allocator.cpp b/sdm/libs/hwc/hwc_buffer_allocator.cpp
index bda316f..7e32d65 100644
--- a/sdm/libs/hwc/hwc_buffer_allocator.cpp
+++ b/sdm/libs/hwc/hwc_buffer_allocator.cpp
@@ -211,6 +211,7 @@
   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;
diff --git a/sdm/libs/hwc/hwc_display.cpp b/sdm/libs/hwc/hwc_display.cpp
index a87706c..4962c38 100644
--- a/sdm/libs/hwc/hwc_display.cpp
+++ b/sdm/libs/hwc/hwc_display.cpp
@@ -99,6 +99,24 @@
   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);
@@ -135,6 +153,11 @@
     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) {
@@ -991,6 +1014,7 @@
   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;
@@ -1365,9 +1389,11 @@
     return kErrorNotSupported;
   }
 
-  if (layer_buffer.color_metadata.colorPrimaries == ColorPrimaries_BT2020 &&
-     (layer_buffer.color_metadata.transfer == Transfer_SMPTE_ST2084 ||
-      layer_buffer.color_metadata.transfer == Transfer_HLG)) {
+  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;
   }
diff --git a/sdm/libs/hwc/hwc_display.h b/sdm/libs/hwc/hwc_display.h
index aa50c20..8da8516 100644
--- a/sdm/libs/hwc/hwc_display.h
+++ b/sdm/libs/hwc/hwc_display.h
@@ -56,8 +56,16 @@
   void DeInit() {}
   int SetColorMode(const std::string &color_mode);
   const std::vector<std::string> &GetColorModes();
+  int SetColorTransform(uint32_t matrix_count, const float *matrix);
 
  private:
+  static const uint32_t kColorTransformMatrixCount = 16;
+  template <class T>
+  void CopyColorTransformMatrix(const T *input_matrix, double *output_matrix) {
+    for (uint32_t i = 0; i < kColorTransformMatrixCount; i++) {
+      output_matrix[i] = static_cast<double>(input_matrix[i]);
+    }
+  }
   int PopulateColorModes();
   DisplayInterface *display_intf_ = NULL;
   std::vector<std::string> color_modes_ = {};
@@ -237,6 +245,7 @@
   bool animating_ = false;
   HWCToneMapper *tone_mapper_ = NULL;
   HWCColorMode *color_mode_ = NULL;
+  int disable_hdr_handling_ = 0;  // disables HDR handling.
 
  private:
   void DumpInputBuffers(hwc_display_contents_1_t *content_list);
diff --git a/sdm/libs/hwc/hwc_tonemapper.cpp b/sdm/libs/hwc/hwc_tonemapper.cpp
index 93ff452..0ceb2e5 100644
--- a/sdm/libs/hwc/hwc_tonemapper.cpp
+++ b/sdm/libs/hwc/hwc_tonemapper.cpp
@@ -140,11 +140,13 @@
           // then SDM marks them for SDE Composition because the cached FB layer gets displayed.
           // GPU count will be 0 in this case. Try to use the existing tone-mapped frame buffer.
           // No ToneMap/Blit is required. Just update the buffer & acquire fence fd of FB layer.
-          ToneMapSession *fb_tone_map_session = tone_map_sessions_.at(fb_session_index_);
-          fb_tone_map_session->UpdateBuffer(-1 /* acquire_fence */, &layer->input_buffer);
-          fb_tone_map_session->layer_index_ = INT(i);
-          fb_tone_map_session->acquired_ = true;
-          return 0;
+          if (!tone_map_sessions_.empty()) {
+            ToneMapSession *fb_tone_map_session = tone_map_sessions_.at(fb_session_index_);
+            fb_tone_map_session->UpdateBuffer(-1 /* acquire_fence */, &layer->input_buffer);
+            fb_tone_map_session->layer_index_ = INT(i);
+            fb_tone_map_session->acquired_ = true;
+            return 0;
+          }
         }
         error = AcquireToneMapSession(layer, &session_index);
         fb_session_index_ = session_index;
@@ -223,7 +225,6 @@
       delete tone_map_sessions_.back();
       tone_map_sessions_.pop_back();
     }
-    TonemapperFactory_Destroy();
     fb_session_index_ = 0;
   }
 }
diff --git a/sdm/libs/utils/formats.cpp b/sdm/libs/utils/formats.cpp
index 8e9d0b8..43abb63 100644
--- a/sdm/libs/utils/formats.cpp
+++ b/sdm/libs/utils/formats.cpp
@@ -98,6 +98,7 @@
   case kFormatYCrCb422H2V1SemiPlanar:   return "Y_CRCB_422_H2V2";
   case kFormatYCbCr420SPVenusUbwc:      return "Y_CBCR_420_VENUS_UBWC";
   case kFormatYCbCr422H2V1Packed:       return "YCBYCR_422_H2V1";
+  case kFormatCbYCrY422H2V1Packed:      return "CBYCRY_422_H2V1";
   case kFormatRGBA1010102:              return "RGBA_1010102";
   case kFormatARGB2101010:              return "ARGB_2101010";
   case kFormatRGBX1010102:              return "RGBX_1010102";