Merge "sdm: Fix compilation errors."
diff --git a/libgralloc/alloc_controller.cpp b/libgralloc/alloc_controller.cpp
index 4ef4886..98079c2 100644
--- a/libgralloc/alloc_controller.cpp
+++ b/libgralloc/alloc_controller.cpp
@@ -655,21 +655,27 @@
     int err = 0;
     int width = hnd->width;
     int height = hnd->height;
+    int format = hnd->format;
     unsigned int ystride, cstride;
     unsigned int alignment = 4096;
 
     memset(ycbcr->reserved, 0, sizeof(ycbcr->reserved));
+    MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
+
+    // Check if UBWC buffer has been rendered in linear format.
+    if (metadata && (metadata->operation & LINEAR_FORMAT)) {
+        format = metadata->linearFormat;
+    }
 
     // Check metadata if the geometry has been updated.
-    MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
     if(metadata && metadata->operation & UPDATE_BUFFER_GEOMETRY) {
         AdrenoMemInfo::getInstance().getAlignedWidthAndHeight(metadata->bufferDim.sliceWidth,
-                   metadata->bufferDim.sliceHeight, hnd->format, 0, width, height);
+                   metadata->bufferDim.sliceHeight, format, 0, width, height);
     }
 
     // Get the chroma offsets from the handle width/height. We take advantage
     // of the fact the width _is_ the stride
-    switch (hnd->format) {
+    switch (format) {
         //Semiplanar
         case HAL_PIXEL_FORMAT_YCbCr_420_SP:
         case HAL_PIXEL_FORMAT_YCbCr_422_SP:
@@ -745,8 +751,7 @@
         case HAL_PIXEL_FORMAT_YCrCb_422_I:
         case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED:
         default:
-        ALOGD("%s: Invalid format passed: 0x%x", __FUNCTION__,
-                hnd->format);
+        ALOGD("%s: Invalid format passed: 0x%x", __FUNCTION__, format);
         err = -EINVAL;
     }
     return err;
diff --git a/libgralloc/mapper.cpp b/libgralloc/mapper.cpp
index cf365ce..3cfdc55 100644
--- a/libgralloc/mapper.cpp
+++ b/libgralloc/mapper.cpp
@@ -440,6 +440,10 @@
                     return res;
                 }
                 *flag = hnd->flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED;
+                MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
+                if (metadata && (metadata->operation & LINEAR_FORMAT)) {
+                    *flag = 0;
+                }
                 res = 0;
             } break;
 
diff --git a/libqdutils/display_config.cpp b/libqdutils/display_config.cpp
index 087ef0b..3941137 100644
--- a/libqdutils/display_config.cpp
+++ b/libqdutils/display_config.cpp
@@ -281,3 +281,12 @@
 }
 
 }// namespace
+
+// ----------------------------------------------------------------------------
+// Screen refresh for native daemons linking dynamically to libqdutils
+// ----------------------------------------------------------------------------
+extern "C" int refreshScreen() {
+  int ret = 0;
+  ret = screenRefresh();
+  return ret;
+}
diff --git a/libqdutils/qdMetaData.cpp b/libqdutils/qdMetaData.cpp
index aae0a47..2aa4a31 100644
--- a/libqdutils/qdMetaData.cpp
+++ b/libqdutils/qdMetaData.cpp
@@ -96,6 +96,9 @@
         case S3D_FORMAT:
             data->s3dFormat = *((uint32_t *)param);
             break;
+        case LINEAR_FORMAT:
+            data->linearFormat = *((uint32_t *)param);
+            break;
         default:
             ALOGE("Unknown paramType %d", paramType);
             break;
diff --git a/libqdutils/qdMetaData.h b/libqdutils/qdMetaData.h
index a1afa38..7688444 100644
--- a/libqdutils/qdMetaData.h
+++ b/libqdutils/qdMetaData.h
@@ -89,6 +89,8 @@
     /* The supported formats are defined in gralloc_priv.h to
      * support legacy code*/
     uint32_t s3dFormat;
+    /* VENUS output buffer is linear for UBWC Interlaced video */
+    uint32_t linearFormat;
 };
 
 enum DispParamType {
@@ -104,6 +106,7 @@
     UPDATE_COLOR_SPACE = 0x0200,
     MAP_SECURE_BUFFER = 0x400,
     S3D_FORMAT = 0x800,
+    LINEAR_FORMAT = 0x1000,
 };
 
 struct private_handle_t;
diff --git a/libqservice/IQService.h b/libqservice/IQService.h
index 16ea704..c877d06 100644
--- a/libqservice/IQService.h
+++ b/libqservice/IQService.h
@@ -59,7 +59,7 @@
         /* Enable/Disable/Set refresh rate dynamically */
         CONFIGURE_DYN_REFRESH_RATE = 18,
         SET_PARTIAL_UPDATE = 19,   // Preference on partial update feature
-        TOGGLE_SCREEN_UPDATE = 20, // Provides ability to disable screen updates
+        CONTROL_BACKLIGHT = 20, // Provides ability to control backlight
         SET_FRAME_DUMP_CONFIG = 21,  // Provides ability to set the frame dump config
         SET_S3D_MODE = 22, // Set the 3D mode as specified in msm_hdmi_modes.h
         CONNECT_HDMI_CLIENT = 23,  // Connect HDMI CEC HAL Client
diff --git a/libqservice/QServiceUtils.h b/libqservice/QServiceUtils.h
index 62ee0d1..b677188 100644
--- a/libqservice/QServiceUtils.h
+++ b/libqservice/QServiceUtils.h
@@ -74,8 +74,9 @@
     return sendSingleParam(qService::IQService::SCREEN_REFRESH, 1);
 }
 
+// TODO(user): Need to rename this wrapper name
 inline android::status_t toggleScreenUpdate(uint32_t on) {
-    return sendSingleParam(qService::IQService::TOGGLE_SCREEN_UPDATE, on);
+    return sendSingleParam(qService::IQService::CONTROL_BACKLIGHT, on);
 }
 
 inline android::status_t setPartialUpdate(uint32_t enable) {
diff --git a/sdm/include/core/display_interface.h b/sdm/include/core/display_interface.h
index 37d3b32..40ef738 100644
--- a/sdm/include/core/display_interface.h
+++ b/sdm/include/core/display_interface.h
@@ -356,6 +356,14 @@
   */
   virtual bool IsUnderscanSupported() = 0;
 
+  /*! @brief Method to set brightness of the primary display.
+
+    @param[in] level the new backlight level.
+
+    @return \link DisplayError \endlink
+  */
+  virtual DisplayError SetPanelBrightness(int level) = 0;
+
   /*! @brief Method to route display API requests to color service.
 
     @param[in] in_payload \link PPDisplayAPIPayload \endlink
diff --git a/sdm/include/core/layer_stack.h b/sdm/include/core/layer_stack.h
index e5b23cc..6e8b61a 100644
--- a/sdm/include/core/layer_stack.h
+++ b/sdm/include/core/layer_stack.h
@@ -124,6 +124,11 @@
                               //!< updating non-updating. so strategy manager will mark them for
                               //!< SDE/GPU composition respectively when the layer stack qualifies
                               //!< for cache based composition.
+
+      uint32_t solid_fill : 1;
+                              //!< This flag shall be set by client to indicate that this layer
+                              //!< is for solid fill without input buffer. Display Device will
+                              //!< use SDE HW feature to achieve it.
     };
 
     uint32_t flags;   //!< For initialization purpose only. Client shall not refer it directly.
@@ -247,8 +252,11 @@
 
   LayerColorSpace color_space;      //!< Color Space of the layer
 
+  uint32_t solid_fill_color;        //!< Solid color used to fill the layer when no content is
+                                    //!< associated with the layer.
+
   Layer() : input_buffer(NULL), composition(kCompositionGPU), blending(kBlendingOpaque),
-            plane_alpha(0), frame_rate(0), color_space(kLimitedRange601) { }
+            plane_alpha(0), frame_rate(0), color_space(kLimitedRange601), solid_fill_color(0) { }
 };
 
 /*! @brief This structure defines a layer stack that contains layers which need to be composed and
diff --git a/sdm/include/private/color_params.h b/sdm/include/private/color_params.h
index 42945ca..66fd840 100644
--- a/sdm/include/private/color_params.h
+++ b/sdm/include/private/color_params.h
@@ -46,6 +46,7 @@
   kDisableSolidFill = BITMAP(2),
   kEnterQDCMMode = BITMAP(3),
   kExitQDCMMode = BITMAP(4),
+  kSetPanelBrightness = BITMAP(5),
   kNoAction = BITMAP(31),
 };
 
@@ -56,6 +57,7 @@
   kGlobalColorFeaturePcc,
   kGlobalColorFeatureIgc,
   kGlobalColorFeaturePgc,
+  kMixerColorFeatureGc,
   kGlobalColorFeaturePaV2,
   kGlobalColorFeatureDither,
   kGlobalColorFeatureGamut,
@@ -68,6 +70,27 @@
   PPPendingParams() : action(kNoAction), params(NULL) {}
 };
 
+struct PPColorInfo {
+  uint32_t r_bitdepth;
+  uint32_t r;
+  uint32_t g_bitdepth;
+  uint32_t g;
+  uint32_t b_bitdepth;
+  uint32_t b;
+};
+
+struct PPColorFillParams {
+  uint32_t flags;
+  struct {
+    uint32_t width;
+    uint32_t height;
+    int32_t x;
+    int32_t y;
+  } rect;
+
+  PPColorInfo color;
+};
+
 struct PPFeatureVersion {
   // SDE ASIC versioning its PP block at each specific feature level.
   static const uint32_t kSDEIgcV17 = 1;
@@ -83,7 +106,7 @@
 };
 
 struct PPHWAttributes : HWResourceInfo, HWPanelInfo, DisplayConfigVariableInfo {
-  const char *panel_name;  // TODO:  Add into HWPanelInfo to retrieve panel_name from HW.
+  const char *panel_name;  // TODO(user):  Add into HWPanelInfo to retrieve panel_name from HW.
   PPFeatureVersion version;
 
   PPHWAttributes() : panel_name("generic_panel"), version() {}
@@ -364,9 +387,9 @@
   // ColorManager installs one TFeatureInfo<T> to take the output configs computed
   // from ColorManager, containing all physical features to be programmed and also compute
   // metadata/populate into T.
-  inline DisplayError AddFeature(uint32_t feature_id, PPFeatureInfo &feature) {
+  inline DisplayError AddFeature(uint32_t feature_id, PPFeatureInfo *feature) {
     if (feature_id < kMaxNumPPFeatures)
-      feature_[feature_id] = &feature;
+      feature_[feature_id] = feature;
 
     return kErrorNone;
   }
diff --git a/sdm/include/private/hw_info_types.h b/sdm/include/private/hw_info_types.h
index 40022e3..1c78ad9 100644
--- a/sdm/include/private/hw_info_types.h
+++ b/sdm/include/private/hw_info_types.h
@@ -151,7 +151,7 @@
 
   HWPanelInfo() : port(kPortDefault), mode(kModeDefault), partial_update(false), left_align(false),
     width_align(false), top_align(false), height_align(false), min_roi_width(0), min_roi_height(0),
-    needs_roi_merge(false), dynamic_fps(false), min_fps(0), max_fps(0) { }
+    needs_roi_merge(false), dynamic_fps(false), min_fps(0), max_fps(0), is_primary_panel(false) { }
 
   bool operator !=(const HWPanelInfo &panel_info) {
     return ((port != panel_info.port) || (mode != panel_info.mode) ||
diff --git a/sdm/include/utils/debug.h b/sdm/include/utils/debug.h
index 0bd0429..0d64bbf 100644
--- a/sdm/include/utils/debug.h
+++ b/sdm/include/utils/debug.h
@@ -69,6 +69,7 @@
   static int GetMaxPipesPerMixer(DisplayType display_type);
   static bool IsVideoModeEnabled();
   static bool IsRotatorUbwcDisabled();
+  static bool IsRotatorSplitDisabled();
 
  private:
   Debug();
diff --git a/sdm/include/utils/rect.h b/sdm/include/utils/rect.h
index 1b75d40..248b11c 100644
--- a/sdm/include/utils/rect.h
+++ b/sdm/include/utils/rect.h
@@ -45,6 +45,10 @@
   LayerRect Intersection(const LayerRect &rect1, const LayerRect &rect2);
   LayerRect Subtract(const LayerRect &rect1, const LayerRect &rect2);
   LayerRect Reposition(const LayerRect &rect1, const int &x_offset, const int &y_offset);
+  void SplitLeftRight(const LayerRect &in_rect, uint32_t split_count, uint32_t align_x,
+                     LayerRect *out_rects);
+  void SplitTopBottom(const LayerRect &in_rect, uint32_t split_count, uint32_t align_y,
+                       LayerRect *out_rects);
 }  // namespace sdm
 
 #endif  // __RECT_H__
diff --git a/sdm/libs/core/Android.mk b/sdm/libs/core/Android.mk
index 3b3f1e7..3ccb3ea 100644
--- a/sdm/libs/core/Android.mk
+++ b/sdm/libs/core/Android.mk
@@ -4,13 +4,14 @@
 LOCAL_MODULE                  := libsdmcore
 LOCAL_MODULE_TAGS             := optional
 LOCAL_C_INCLUDES              := hardware/qcom/display/sdm/include/ \
-                                 $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr/include
+                                 $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr/include \
+                                 external/libcxx/include/
 LOCAL_CFLAGS                  := -Wno-missing-field-initializers -Wno-unused-parameter \
                                  -Wall -Werror -std=c++11 -fcolor-diagnostics\
                                  -DLOG_TAG=\"SDM\"
 LOCAL_CLANG                   := true
 LOCAL_HW_INTF_PATH            := fb
-LOCAL_SHARED_LIBRARIES        := libdl libsdmutils
+LOCAL_SHARED_LIBRARIES        := libdl libsdmutils libc++
 LOCAL_ADDITIONAL_DEPENDENCIES := $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr
 LOCAL_SRC_FILES               := core_interface.cpp \
                                  core_impl.cpp \
diff --git a/sdm/libs/core/color_manager.cpp b/sdm/libs/core/color_manager.cpp
index 1828d58..b146dd6 100644
--- a/sdm/libs/core/color_manager.cpp
+++ b/sdm/libs/core/color_manager.cpp
@@ -71,14 +71,15 @@
     ::dlclose(color_lib_);
 }
 
-ColorManagerProxy::ColorManagerProxy(DisplayType type, HWInterface *intf, HWDisplayAttributes &attr,
-                                     HWPanelInfo &info)
+ColorManagerProxy::ColorManagerProxy(DisplayType type, HWInterface *intf,
+                                     const HWDisplayAttributes &attr,
+                                     const HWPanelInfo &info)
     : device_type_(type), pp_hw_attributes_(), hw_intf_(intf), color_intf_(NULL), pp_features_() {}
 
 ColorManagerProxy *ColorManagerProxy::CreateColorManagerProxy(DisplayType type,
                                                               HWInterface *hw_intf,
-                                                              HWDisplayAttributes &attribute,
-                                                              HWPanelInfo &panel_info) {
+                                                              const HWDisplayAttributes &attribute,
+                                                              const HWPanelInfo &panel_info) {
   DisplayError error = kErrorNone;
   PPFeatureVersion versions;
 
@@ -149,7 +150,7 @@
 
   DisplayError ret = kErrorNone;
   if (pp_features_.IsDirty()) {
-    ret = hw_intf_->SetPPFeatures(pp_features_);
+    ret = hw_intf_->SetPPFeatures(&pp_features_);
   }
 
   return ret;
diff --git a/sdm/libs/core/color_manager.h b/sdm/libs/core/color_manager.h
index e365254..f9266fb 100644
--- a/sdm/libs/core/color_manager.h
+++ b/sdm/libs/core/color_manager.h
@@ -55,8 +55,8 @@
    * 4. Need get panel name for hw_panel_info_.
    */
   static ColorManagerProxy *CreateColorManagerProxy(DisplayType type, HWInterface *hw_intf,
-                                                    HWDisplayAttributes &attribute,
-                                                    HWPanelInfo &panel_info);
+                                                    const HWDisplayAttributes &attribute,
+                                                    const HWPanelInfo &panel_info);
 
   /* need reverse the effect of CreateColorManagerProxy. */
   ~ColorManagerProxy();
@@ -69,8 +69,8 @@
 
  protected:
   ColorManagerProxy() {}
-  ColorManagerProxy(DisplayType type, HWInterface *intf, HWDisplayAttributes &attr,
-                    HWPanelInfo &info);
+  ColorManagerProxy(DisplayType type, HWInterface *intf, const HWDisplayAttributes &attr,
+                    const HWPanelInfo &info);
 
  private:
   static void *color_lib_;
diff --git a/sdm/libs/core/comp_manager.cpp b/sdm/libs/core/comp_manager.cpp
index bb60542..078b7dc 100644
--- a/sdm/libs/core/comp_manager.cpp
+++ b/sdm/libs/core/comp_manager.cpp
@@ -316,14 +316,14 @@
   resource_intf_->Purge(display_comp_ctx->display_resource_ctx);
 }
 
-bool CompManager::ProcessIdleTimeout(Handle display_ctx) {
+void CompManager::ProcessIdleTimeout(Handle display_ctx) {
   SCOPE_LOCK(locker_);
 
   DisplayCompositionContext *display_comp_ctx =
                              reinterpret_cast<DisplayCompositionContext *>(display_ctx);
 
   if (!display_comp_ctx) {
-    return false;
+    return;
   }
 
   // 1. handle_idle_timeout flag is set to true on start of every draw call, if the current
@@ -335,11 +335,7 @@
   if (display_comp_ctx->handle_idle_timeout) {
     display_comp_ctx->idle_fallback = true;
     display_comp_ctx->handle_idle_timeout = false;
-
-    return true;
   }
-
-  return false;
 }
 
 void CompManager::ProcessThermalEvent(Handle display_ctx, int64_t thermal_level) {
diff --git a/sdm/libs/core/comp_manager.h b/sdm/libs/core/comp_manager.h
index 502c08b..f7143ff 100644
--- a/sdm/libs/core/comp_manager.h
+++ b/sdm/libs/core/comp_manager.h
@@ -53,7 +53,7 @@
   DisplayError ReConfigure(Handle display_ctx, HWLayers *hw_layers);
   DisplayError PostCommit(Handle display_ctx, HWLayers *hw_layers);
   void Purge(Handle display_ctx);
-  bool ProcessIdleTimeout(Handle display_ctx);
+  void ProcessIdleTimeout(Handle display_ctx);
   void ProcessThermalEvent(Handle display_ctx, int64_t thermal_level);
   DisplayError SetMaxMixerStages(Handle display_ctx, uint32_t max_mixer_stages);
   DisplayError ValidateScaling(const LayerRect &crop, const LayerRect &dst, bool rotate90);
diff --git a/sdm/libs/core/display_base.cpp b/sdm/libs/core/display_base.cpp
index 5d83843..c1d2905 100644
--- a/sdm/libs/core/display_base.cpp
+++ b/sdm/libs/core/display_base.cpp
@@ -238,11 +238,11 @@
     }
   }
 
-   // check if feature list cache is dirty and pending.
-   // If dirty, need program to hardware blocks.
+  // check if feature list cache is dirty and pending.
+  // If dirty, need program to hardware blocks.
   if (color_mgr_)
     error = color_mgr_->Commit();
-  if (error != kErrorNone) { // won't affect this execution path.
+  if (error != kErrorNone) {  // won't affect this execution path.
     DLOGW("ColorManager::Commit(...) isn't working");
   }
 
@@ -440,6 +440,10 @@
   return comp_manager_->ValidateScaling(crop, dst, rotate90);
 }
 
+DisplayError DisplayBase::SetPanelBrightness(int level) {
+  return kErrorNotSupported;
+}
+
 void DisplayBase::AppendDump(char *buffer, uint32_t length) {
   DumpImpl::AppendString(buffer, length, "\n-----------------------");
   DumpImpl::AppendString(buffer, length, "\ndevice type: %u", display_type_);
@@ -455,10 +459,8 @@
 
   DumpImpl::AppendString(buffer, length, "\n");
 
-  uint32_t num_layers = 0;
   uint32_t num_hw_layers = 0;
   if (hw_layers_.info.stack) {
-    num_layers = hw_layers_.info.stack->layer_count;
     num_hw_layers = hw_layers_.info.count;
   }
 
diff --git a/sdm/libs/core/display_base.h b/sdm/libs/core/display_base.h
index f8704bf..531217e 100644
--- a/sdm/libs/core/display_base.h
+++ b/sdm/libs/core/display_base.h
@@ -64,6 +64,7 @@
   virtual DisplayError SetDisplayMode(uint32_t mode);
   virtual DisplayError IsScalingValid(const LayerRect &crop, const LayerRect &dst, bool rotate90);
   virtual bool IsUnderscanSupported();
+  virtual DisplayError SetPanelBrightness(int level);
   virtual DisplayError ColorSVCRequestRoute(const PPDisplayAPIPayload &in_payload,
                                             PPDisplayAPIPayload *out_payload,
                                             PPPendingParams *pending_action);
diff --git a/sdm/libs/core/display_hdmi.cpp b/sdm/libs/core/display_hdmi.cpp
index a5a35a5..20a1524 100644
--- a/sdm/libs/core/display_hdmi.cpp
+++ b/sdm/libs/core/display_hdmi.cpp
@@ -171,6 +171,11 @@
   return DisplayBase::IsUnderscanSupported();
 }
 
+DisplayError DisplayHDMI::SetPanelBrightness(int level) {
+  SCOPE_LOCK(locker_);
+  return DisplayBase::SetPanelBrightness(level);
+}
+
 int DisplayHDMI::GetBestConfig() {
   uint32_t best_config_mode = 0;
   HWDisplayAttributes *best = &display_attributes_[0];
diff --git a/sdm/libs/core/display_hdmi.h b/sdm/libs/core/display_hdmi.h
index fb07466..e247eb7 100644
--- a/sdm/libs/core/display_hdmi.h
+++ b/sdm/libs/core/display_hdmi.h
@@ -58,6 +58,7 @@
   virtual DisplayError IsScalingValid(const LayerRect &crop, const LayerRect &dst, bool rotate90);
   virtual DisplayError SetRefreshRate(uint32_t refresh_rate);
   virtual bool IsUnderscanSupported();
+  virtual DisplayError SetPanelBrightness(int level);
   virtual void AppendDump(char *buffer, uint32_t length);
 
  private:
diff --git a/sdm/libs/core/display_primary.cpp b/sdm/libs/core/display_primary.cpp
index dd1beed..c1a2e5c 100644
--- a/sdm/libs/core/display_primary.cpp
+++ b/sdm/libs/core/display_primary.cpp
@@ -58,6 +58,7 @@
   error = DisplayBase::Init();
   if (error != kErrorNone) {
     HWPrimaryInterface::Destroy(hw_primary_intf_);
+    return error;
   }
 
   // Idle fallback feature is supported only for video mode panel.
@@ -237,6 +238,10 @@
 
   return error;
 }
+DisplayError DisplayPrimary::SetPanelBrightness(int level) {
+  SCOPE_LOCK(locker_);
+  return hw_primary_intf_->SetPanelBrightness(level);
+}
 
 DisplayError DisplayPrimary::IsScalingValid(const LayerRect &crop, const LayerRect &dst,
                                             bool rotate90) {
@@ -282,10 +287,8 @@
 }
 
 void DisplayPrimary::IdleTimeout() {
-  SCOPE_LOCK(locker_);
-  bool need_refresh = comp_manager_->ProcessIdleTimeout(display_comp_ctx_);
-  if (need_refresh) {
-    event_handler_->Refresh();
+  if (event_handler_->Refresh() == kErrorNone) {
+    comp_manager_->ProcessIdleTimeout(display_comp_ctx_);
   }
 }
 
diff --git a/sdm/libs/core/display_primary.h b/sdm/libs/core/display_primary.h
index b232d89..f793984 100644
--- a/sdm/libs/core/display_primary.h
+++ b/sdm/libs/core/display_primary.h
@@ -58,6 +58,7 @@
   virtual DisplayError IsScalingValid(const LayerRect &crop, const LayerRect &dst, bool rotate90);
   virtual DisplayError SetRefreshRate(uint32_t refresh_rate);
   virtual bool IsUnderscanSupported();
+  virtual DisplayError SetPanelBrightness(int level);
   virtual void AppendDump(char *buffer, uint32_t length);
 
   // Implement the HWEventHandlers
diff --git a/sdm/libs/core/display_virtual.cpp b/sdm/libs/core/display_virtual.cpp
index f01ff58..3115137 100644
--- a/sdm/libs/core/display_virtual.cpp
+++ b/sdm/libs/core/display_virtual.cpp
@@ -194,6 +194,11 @@
   return kErrorNotSupported;
 }
 
+DisplayError DisplayVirtual::SetPanelBrightness(int level) {
+  SCOPE_LOCK(locker_);
+  return DisplayBase::SetPanelBrightness(level);
+}
+
 void DisplayVirtual::AppendDump(char *buffer, uint32_t length) {
   SCOPE_LOCK(locker_);
   DisplayBase::AppendDump(buffer, length);
diff --git a/sdm/libs/core/display_virtual.h b/sdm/libs/core/display_virtual.h
index 6152f69..4021124 100644
--- a/sdm/libs/core/display_virtual.h
+++ b/sdm/libs/core/display_virtual.h
@@ -58,6 +58,7 @@
   virtual DisplayError IsScalingValid(const LayerRect &crop, const LayerRect &dst, bool rotate90);
   virtual DisplayError SetRefreshRate(uint32_t refresh_rate);
   virtual bool IsUnderscanSupported();
+  virtual DisplayError SetPanelBrightness(int level);
   virtual void AppendDump(char *buffer, uint32_t length);
 
  private:
diff --git a/sdm/libs/core/fb/hw_color_manager.cpp b/sdm/libs/core/fb/hw_color_manager.cpp
index db917b7..872e7a9 100644
--- a/sdm/libs/core/fb/hw_color_manager.cpp
+++ b/sdm/libs/core/fb/hw_color_manager.cpp
@@ -48,6 +48,7 @@
         [kGlobalColorFeaturePcc] = &HWColorManager::SetPCC,
         [kGlobalColorFeatureIgc] = &HWColorManager::SetIGC,
         [kGlobalColorFeaturePgc] = &HWColorManager::SetPGC,
+        [kMixerColorFeatureGc] = &HWColorManager::SetMixerGC,
         [kGlobalColorFeaturePaV2] = &HWColorManager::SetPAV2,
         [kGlobalColorFeatureDither] = &HWColorManager::SetDither,
         [kGlobalColorFeatureGamut] = &HWColorManager::SetGamut,
@@ -96,6 +97,19 @@
   return ret;
 }
 
+DisplayError HWColorManager::SetMixerGC(const PPFeatureInfo &feature, msmfb_mdp_pp *kernel_params) {
+  DisplayError ret = kErrorNone;
+
+  kernel_params->op = mdp_op_lut_cfg;
+  kernel_params->data.lut_cfg_data.lut_type = mdp_lut_pgc;
+  kernel_params->data.lut_cfg_data.data.pgc_lut_data.version = feature.feature_version_;
+  kernel_params->data.lut_cfg_data.data.pgc_lut_data.block =
+      (MDP_LOGICAL_BLOCK_DISP_0 + feature.disp_id_) | MDSS_PP_LM_CFG;
+  kernel_params->data.lut_cfg_data.data.pgc_lut_data.flags = feature.enable_flags_;
+  kernel_params->data.lut_cfg_data.data.pgc_lut_data.cfg_payload = feature.GetConfigData();
+  return ret;
+}
+
 DisplayError HWColorManager::SetPAV2(const PPFeatureInfo &feature, msmfb_mdp_pp *kernel_params) {
   DisplayError ret = kErrorNone;
 
diff --git a/sdm/libs/core/fb/hw_color_manager.h b/sdm/libs/core/fb/hw_color_manager.h
index 27a46ae..ead71d2 100644
--- a/sdm/libs/core/fb/hw_color_manager.h
+++ b/sdm/libs/core/fb/hw_color_manager.h
@@ -42,6 +42,7 @@
   static DisplayError SetPCC(const PPFeatureInfo &feature, msmfb_mdp_pp *kernel_params);
   static DisplayError SetIGC(const PPFeatureInfo &feature, msmfb_mdp_pp *kernel_params);
   static DisplayError SetPGC(const PPFeatureInfo &feature, msmfb_mdp_pp *kernel_params);
+  static DisplayError SetMixerGC(const PPFeatureInfo &feature, msmfb_mdp_pp *kernel_params);
   static DisplayError SetPAV2(const PPFeatureInfo &feature, msmfb_mdp_pp *kernel_params);
   static DisplayError SetDither(const PPFeatureInfo &feature, msmfb_mdp_pp *kernel_params);
   static DisplayError SetGamut(const PPFeatureInfo &feature, msmfb_mdp_pp *kernel_params);
diff --git a/sdm/libs/core/fb/hw_device.cpp b/sdm/libs/core/fb/hw_device.cpp
index 9d08323..5cc0197 100644
--- a/sdm/libs/core/fb/hw_device.cpp
+++ b/sdm/libs/core/fb/hw_device.cpp
@@ -207,11 +207,14 @@
         mdp_buffer.comp_ratio.denom = 1000;
         mdp_buffer.comp_ratio.numer = UINT32(hw_layers->config[i].compression * 1000);
 
-        error = SetFormat(input_buffer->format, &mdp_buffer.format);
-        if (error != kErrorNone) {
-          return error;
+        if (layer.flags.solid_fill) {
+          mdp_buffer.format = MDP_ARGB_8888;
+        } else {
+          error = SetFormat(input_buffer->format, &mdp_buffer.format);
+          if (error != kErrorNone) {
+            return error;
+          }
         }
-
         mdp_layer.alpha = layer.plane_alpha;
         mdp_layer.z_order = UINT16(pipe_info->z_order);
         mdp_layer.transp_mask = 0xffffffff;
@@ -224,6 +227,7 @@
         SetRect(pipe_info->dst_roi, &mdp_layer.dst_rect);
         SetMDPFlags(layer, is_rotator_used, &mdp_layer.flags);
         SetColorSpace(layer.color_space, &mdp_layer.color_space);
+        mdp_layer.bg_color = layer.solid_fill_color;
 
         if (pipe_info->scale_data.enable_pixel_ext) {
           if ((mdp_layer.flags & MDP_LAYER_DEINTERLACE) && (layer.transform.rotation == 90.0f)) {
@@ -301,21 +305,22 @@
 void HWDevice::DumpLayerCommit(const mdp_layer_commit &layer_commit) {
   const mdp_layer_commit_v1 &mdp_commit = layer_commit.commit_v1;
   const mdp_input_layer *mdp_layers = mdp_commit.input_layers;
+  const mdp_rect &l_roi = mdp_commit.left_roi;
+  const mdp_rect &r_roi = mdp_commit.right_roi;
 
-  DLOGE("mdp_commit: flags = %x, release fence = %x", mdp_commit.flags, mdp_commit.release_fence);
-  DLOGE("left_roi: x = %d, y = %d, w = %d, h = %d", mdp_commit.left_roi.x, mdp_commit.left_roi.y,
-         mdp_commit.left_roi.w, mdp_commit.left_roi.h);
-  DLOGE("right_roi: x = %d, y = %d, w = %d, h = %d", mdp_commit.right_roi.x,
-         mdp_commit.right_roi.y, mdp_commit.right_roi.w, mdp_commit.right_roi.h);
+  DLOGI("mdp_commit: flags = %x, release fence = %x", mdp_commit.flags, mdp_commit.release_fence);
+  DLOGI("left_roi: x = %d, y = %d, w = %d, h = %d", l_roi.x, l_roi.y, l_roi.w, l_roi.h);
+  DLOGI("right_roi: x = %d, y = %d, w = %d, h = %d", r_roi.x, r_roi.y, r_roi.w, r_roi.h);
   for (uint32_t i = 0; i < mdp_commit.input_layer_cnt; i++) {
-    DLOGE("mdp_commit: layer_cnt = %d, pipe_ndx = %x, zorder = %d, flags = %x",
-          i, mdp_layers[i].pipe_ndx, mdp_layers[i].z_order, mdp_layers[i].flags);
-    const mdp_rect &src_rect = mdp_layers[i].src_rect;
-    DLOGE("src rect: x = %d, y = %d, w = %d, h = %d",
-          src_rect.x, src_rect.y, src_rect.w, src_rect.h);
-    const mdp_rect &dst_rect = mdp_layers[i].dst_rect;
-    DLOGE("dst rect: x = %d, y = %d, w = %d, h = %d",
-          dst_rect.x, dst_rect.y, dst_rect.w, dst_rect.h);
+    const mdp_input_layer &layer = mdp_layers[i];
+    const mdp_rect &src_rect = layer.src_rect;
+    const mdp_rect &dst_rect = layer.dst_rect;
+    DLOGI("layer = %d, pipe_ndx = %x, z = %d, flags = %x",
+      i, layer.pipe_ndx, layer.z_order, layer.flags);
+    DLOGI("src_rect: x = %d, y = %d, w = %d, h = %d",
+      src_rect.x, src_rect.y, src_rect.w, src_rect.h);
+    DLOGI("dst_rect: x = %d, y = %d, w = %d, h = %d",
+      dst_rect.x, dst_rect.y, dst_rect.w, dst_rect.h);
   }
 }
 
@@ -600,6 +605,10 @@
   if (input_buffer->flags.secure_display) {
     *mdp_flags |= MDP_SECURE_DISPLAY_OVERLAY_SESSION;
   }
+
+  if (layer.flags.solid_fill) {
+    *mdp_flags |= MDP_LAYER_SOLID_FILL;
+  }
 }
 
 void HWDevice::SyncMerge(const int &fd1, const int &fd2, int *target) {
@@ -613,31 +622,30 @@
 }
 
 int HWDevice::GetFBNodeIndex(HWDeviceType device_type) {
-  int fb_node_index = -1;
   for (int i = 0; i <= kDeviceVirtual; i++) {
     HWPanelInfo *panel_info = new HWPanelInfo();
     GetHWPanelInfoByNode(i, panel_info);
     switch (device_type) {
     case kDevicePrimary:
       if (panel_info->is_primary_panel) {
-        fb_node_index = i;
+        return i;
       }
       break;
     case kDeviceHDMI:
       if (panel_info->port == kPortDTv) {
-        fb_node_index = i;
+        return i;
       }
       break;
     case kDeviceVirtual:
       if (panel_info->port == kPortWriteBack) {
-        fb_node_index = i;
+        return i;
       }
       break;
     default:
       break;
     }
   }
-  return fb_node_index;
+  return -1;
 }
 
 void HWDevice::PopulateHWPanelInfo() {
@@ -858,18 +866,24 @@
   bool ret_value = true;
   char hpdpath[kMaxStringLength];
   int hdmi_node_index = GetFBNodeIndex(kDeviceHDMI);
+  if (hdmi_node_index < 0) {
+    return false;
+  }
+
   snprintf(hpdpath , sizeof(hpdpath), "%s%d/hpd", fb_path_, hdmi_node_index);
   int hpdfd = Sys::open_(hpdpath, O_RDWR, 0);
   if (hpdfd < 0) {
-    DLOGE("Open failed = %s", hpdpath);
-    return kErrorHardware;
+    DLOGW("Open failed = %s", hpdpath);
+    return false;
   }
+
   char value = enable ? '1' : '0';
   ssize_t length = Sys::pwrite_(hpdfd, &value, 1, 0);
   if (length <= 0) {
     DLOGE("Write failed 'hpd' = %d", enable);
     ret_value = false;
   }
+
   Sys::close_(hpdfd);
 
   return ret_value;
diff --git a/sdm/libs/core/fb/hw_hdmi.cpp b/sdm/libs/core/fb/hw_hdmi.cpp
index ea49d58..b1dc544 100644
--- a/sdm/libs/core/fb/hw_hdmi.cpp
+++ b/sdm/libs/core/fb/hw_hdmi.cpp
@@ -435,7 +435,7 @@
   return kErrorNotSupported;
 }
 
-DisplayError HWHDMI::SetPPFeatures(PPFeaturesConfig &feature_list) {
+DisplayError HWHDMI::SetPPFeatures(PPFeaturesConfig *feature_list) {
   return kErrorNotSupported;
 }
 
diff --git a/sdm/libs/core/fb/hw_hdmi.h b/sdm/libs/core/fb/hw_hdmi.h
index 6121226..169e9be 100644
--- a/sdm/libs/core/fb/hw_hdmi.h
+++ b/sdm/libs/core/fb/hw_hdmi.h
@@ -56,7 +56,7 @@
   virtual DisplayError Commit(HWLayers *hw_layers);
   virtual DisplayError Flush();
   virtual DisplayError GetPPFeaturesVersion(PPFeatureVersion *vers);
-  virtual DisplayError SetPPFeatures(PPFeaturesConfig &feature_list);
+  virtual DisplayError SetPPFeatures(PPFeaturesConfig *feature_list);
 
  private:
   DisplayError ReadEDIDInfo();
diff --git a/sdm/libs/core/fb/hw_primary.cpp b/sdm/libs/core/fb/hw_primary.cpp
index ee59bae..146360e 100644
--- a/sdm/libs/core/fb/hw_primary.cpp
+++ b/sdm/libs/core/fb/hw_primary.cpp
@@ -175,7 +175,11 @@
   }
 
   if (config_changed_) {
-    PopulateDisplayAttributes();
+    DisplayError error = PopulateDisplayAttributes();
+    if (error != kErrorNone) {
+      return error;
+    }
+
     config_changed_ = false;
   }
 
@@ -500,11 +504,39 @@
   return kErrorNone;
 }
 
+DisplayError HWPrimary::SetPanelBrightness(int level) {
+  char buffer[MAX_SYSFS_COMMAND_LENGTH];
+  int32_t bytes, bl_fd = -1;
+  ssize_t ret;
+
+  memset(buffer, 0, MAX_SYSFS_COMMAND_LENGTH);
+
+  DLOGV_IF(kTagDriverConfig, "Set brightness level to %d", level);
+  bl_fd = Sys::open_("/sys/class/leds/lcd-backlight/brightness", O_RDWR);
+  if (bl_fd < 0) {
+    DLOGI("SetPanelBrightness: open failed out :( %d", level);
+    return kErrorParameters;
+  }
+  bytes = snprintf(buffer, MAX_SYSFS_COMMAND_LENGTH, "%d\n", level);
+  if (bytes < 0) {
+    DLOGE("SetPanelBrightness: snprintf failed out :( %d", level);
+    Sys::close_(bl_fd);
+    return kErrorParameters;
+  }
+  ret = Sys::pwrite_(bl_fd, buffer, bytes, 0);
+  if (ret <= 0) {
+    DLOGE("SetPanelBrightness: write failed out :( %d", level);
+    Sys::close_(bl_fd);
+    return kErrorParameters;
+  }
+  Sys::close_(bl_fd);
+  return kErrorNone;
+}
+
 DisplayError HWPrimary::GetPPFeaturesVersion(PPFeatureVersion *vers) {
   STRUCT_VAR(mdp_pp_feature_version, version);
 
-  // map from core domain to mdp FB driver domain.
-  uint32_t feature_id_mapping[kMaxNumPPFeatures] = { PCC, IGC, GC, PA, DITHER, GAMUT };
+  uint32_t feature_id_mapping[kMaxNumPPFeatures] = { PCC, IGC, GC, GC, PA, DITHER, GAMUT };
 
   for (int i(0); i < kMaxNumPPFeatures; i++) {
     version.pp_feature = feature_id_mapping[i];
@@ -520,13 +552,13 @@
 }
 
 // It was entered with PPFeaturesConfig::locker_ being hold.
-DisplayError HWPrimary::SetPPFeatures(PPFeaturesConfig &feature_list) {
+DisplayError HWPrimary::SetPPFeatures(PPFeaturesConfig *feature_list) {
   STRUCT_VAR(msmfb_mdp_pp, kernel_params);
   int ret = 0;
   PPFeatureInfo *feature = NULL;
 
   while (true) {
-    ret = feature_list.RetrieveNextFeature(&feature);
+    ret = feature_list->RetrieveNextFeature(&feature);
     if (ret)
         break;
 
@@ -534,21 +566,20 @@
       DLOGV_IF(kTagDriverConfig, "feature_id = %d", feature->feature_id_);
 
       if ((feature->feature_id_ < kMaxNumPPFeatures)) {
-
         HWColorManager::SetFeature[feature->feature_id_](*feature, &kernel_params);
         if (Sys::ioctl_(device_fd_, MSMFB_MDP_PP, &kernel_params) < 0) {
           IOCTL_LOGE(MSMFB_MDP_PP, device_type_);
 
-          feature_list.Reset();
+          feature_list->Reset();
           return kErrorHardware;
         }
       }
     }
-  } // while(true)
+  }  // while(true)
 
-   // Once all features were consumed, then destroy all feature instance from feature_list,
-   // Then mark it as non-dirty of PPFeaturesConfig cache.
-  feature_list.Reset();
+  // Once all features were consumed, then destroy all feature instance from feature_list,
+  // Then mark it as non-dirty of PPFeaturesConfig cache.
+  feature_list->Reset();
 
   return kErrorNone;
 }
diff --git a/sdm/libs/core/fb/hw_primary.h b/sdm/libs/core/fb/hw_primary.h
index f4f1521..e46a707 100644
--- a/sdm/libs/core/fb/hw_primary.h
+++ b/sdm/libs/core/fb/hw_primary.h
@@ -31,6 +31,7 @@
 #include "hw_primary_interface.h"
 
 namespace sdm {
+#define MAX_SYSFS_COMMAND_LENGTH 12
 
 class HWPrimary : public HWDevice, public HWPrimaryInterface {
  public:
@@ -57,8 +58,9 @@
   virtual DisplayError SetVSyncState(bool enable);
   virtual DisplayError SetDisplayMode(const HWDisplayMode hw_display_mode);
   virtual DisplayError SetRefreshRate(uint32_t refresh_rate);
+  virtual DisplayError SetPanelBrightness(int level);
   virtual DisplayError GetPPFeaturesVersion(PPFeatureVersion *vers);
-  virtual DisplayError SetPPFeatures(PPFeaturesConfig &feature_list);
+  virtual DisplayError SetPPFeatures(PPFeaturesConfig *feature_list);
 
  private:
   // Panel modes for the MSMFB_LPM_ENABLE ioctl
diff --git a/sdm/libs/core/fb/hw_virtual.cpp b/sdm/libs/core/fb/hw_virtual.cpp
index a9cbb2b..8a355eb 100644
--- a/sdm/libs/core/fb/hw_virtual.cpp
+++ b/sdm/libs/core/fb/hw_virtual.cpp
@@ -139,7 +139,7 @@
   return kErrorNotSupported;
 }
 
-DisplayError HWVirtual::SetPPFeatures(PPFeaturesConfig &feature_list) {
+DisplayError HWVirtual::SetPPFeatures(PPFeaturesConfig *feature_list) {
   return kErrorNotSupported;
 }
 
diff --git a/sdm/libs/core/fb/hw_virtual.h b/sdm/libs/core/fb/hw_virtual.h
index 0d8afef..e7593e6 100644
--- a/sdm/libs/core/fb/hw_virtual.h
+++ b/sdm/libs/core/fb/hw_virtual.h
@@ -52,7 +52,7 @@
   virtual DisplayError Commit(HWLayers *hw_layers);
   virtual DisplayError Flush();
   virtual DisplayError GetPPFeaturesVersion(PPFeatureVersion *vers);
-  virtual DisplayError SetPPFeatures(PPFeaturesConfig &feature_list);
+  virtual DisplayError SetPPFeatures(PPFeaturesConfig *feature_list);
 };
 
 }  // namespace sdm
diff --git a/sdm/libs/core/hw_interface.h b/sdm/libs/core/hw_interface.h
index ac42f8e..7ecac49 100644
--- a/sdm/libs/core/hw_interface.h
+++ b/sdm/libs/core/hw_interface.h
@@ -81,7 +81,7 @@
   virtual DisplayError Commit(HWLayers *hw_layers) = 0;
   virtual DisplayError Flush() = 0;
   virtual DisplayError GetPPFeaturesVersion(PPFeatureVersion *vers) = 0;
-  virtual DisplayError SetPPFeatures(PPFeaturesConfig &feature_list) = 0;
+  virtual DisplayError SetPPFeatures(PPFeaturesConfig *feature_list) = 0;
 
  protected:
   virtual ~HWInterface() { }
diff --git a/sdm/libs/core/hw_primary_interface.h b/sdm/libs/core/hw_primary_interface.h
index 9faa6e5..290f9cb 100644
--- a/sdm/libs/core/hw_primary_interface.h
+++ b/sdm/libs/core/hw_primary_interface.h
@@ -39,6 +39,7 @@
   virtual void SetIdleTimeoutMs(uint32_t timeout_ms) = 0;
   virtual DisplayError SetDisplayMode(const HWDisplayMode hw_display_mode) = 0;
   virtual DisplayError SetRefreshRate(uint32_t refresh_rate) = 0;
+  virtual DisplayError SetPanelBrightness(int level) = 0;
 
  protected:
   virtual ~HWPrimaryInterface() { }
diff --git a/sdm/libs/core/resource_default.cpp b/sdm/libs/core/resource_default.cpp
index 2e19493..9c72ae5 100644
--- a/sdm/libs/core/resource_default.cpp
+++ b/sdm/libs/core/resource_default.cpp
@@ -88,8 +88,11 @@
     hw_res_info_.max_scale_up = 1;
   }
 
+  // TODO(user): clean it up, query from driver for initial pipe status.
+#ifndef SDM_VIRTUAL_DRIVER
   rgb_pipes_[0].owner = kPipeOwnerKernelMode;
   rgb_pipes_[1].owner = kPipeOwnerKernelMode;
+#endif
 
   return error;
 }
diff --git a/sdm/libs/hwc/Android.mk b/sdm/libs/hwc/Android.mk
index 1b199e2..13d832b 100644
--- a/sdm/libs/hwc/Android.mk
+++ b/sdm/libs/hwc/Android.mk
@@ -8,7 +8,8 @@
                                  hardware/qcom/display/libgralloc/ \
                                  hardware/qcom/display/libqservice/ \
                                  hardware/qcom/display/libqdutils/ \
-                                 hardware/qcom/display/libcopybit/
+                                 hardware/qcom/display/libcopybit/ \
+                                 external/libcxx/include/
 
 LOCAL_CFLAGS                  := -Wno-missing-field-initializers -Wno-unused-parameter \
                                  -Wall -Werror -std=c++11 -fcolor-diagnostics\
@@ -22,7 +23,7 @@
 
 LOCAL_SHARED_LIBRARIES        := libsdmcore libqservice libbinder libhardware libhardware_legacy \
                                  libutils libcutils libsync libmemalloc libqdutils libdl \
-                                 libpowermanager libsdmutils
+                                 libpowermanager libsdmutils libc++
 
 LOCAL_SRC_FILES               := hwc_session.cpp \
                                  hwc_display.cpp \
diff --git a/sdm/libs/hwc/blit_engine_c2d.cpp b/sdm/libs/hwc/blit_engine_c2d.cpp
index 0fbe148..2509f53 100644
--- a/sdm/libs/hwc/blit_engine_c2d.cpp
+++ b/sdm/libs/hwc/blit_engine_c2d.cpp
@@ -263,7 +263,7 @@
   }
 
   blit_target_start_index_ = ++i;
-  num_blit_target_= layer_stack->layer_count - blit_target_start_index_;
+  num_blit_target_ = layer_stack->layer_count - blit_target_start_index_;
 
   LayerBuffer *layer_buffer = layer_stack->layers[gpu_target_index].input_buffer;
   int fbwidth = INT(layer_buffer->width);
diff --git a/sdm/libs/hwc/hwc_color_manager.cpp b/sdm/libs/hwc/hwc_color_manager.cpp
index 701448b..463014e 100644
--- a/sdm/libs/hwc/hwc_color_manager.cpp
+++ b/sdm/libs/hwc/hwc_color_manager.cpp
@@ -30,8 +30,12 @@
 #include <dlfcn.h>
 #include <powermanager/IPowerManager.h>
 #include <cutils/sockets.h>
+#include <cutils/native_handle.h>
 #include <utils/String16.h>
 #include <binder/Parcel.h>
+#include <gralloc_priv.h>
+#include <hardware/hwcomposer.h>
+#include <hardware/hwcomposer_defs.h>
 #include <QService.h>
 
 #include <core/dump_interface.h>
@@ -47,6 +51,12 @@
 
 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);
+  return argb_color;
+}
+
 int HWCColorManager::CreatePayloadFromParcel(const android::Parcel &in, uint32_t *disp_id,
                                              PPDisplayAPIPayload *sink) {
   int ret = 0;
@@ -71,10 +81,10 @@
 }
 
 void HWCColorManager::MarshallStructIntoParcel(const PPDisplayAPIPayload &data,
-                                               android::Parcel &out_parcel) {
-  out_parcel.writeInt32(data.size);
+                                               android::Parcel *out_parcel) {
+  out_parcel->writeInt32(data.size);
   if (data.payload)
-    out_parcel.write(data.payload, data.size);
+    out_parcel->write(data.payload, data.size);
 }
 
 HWCColorManager *HWCColorManager::CreateColorManager() {
@@ -87,14 +97,14 @@
     if (color_lib) {
       color_mgr->color_apis_ = ::dlsym(color_lib, DISPLAY_API_FUNC_TABLES);
       if (!color_mgr->color_apis_) {
-        DLOGW("Fail to retrieve = %s from %s", DISPLAY_API_FUNC_TABLES,
+        DLOGE("Fail to retrieve = %s from %s", DISPLAY_API_FUNC_TABLES,
               DISPLAY_API_INTERFACE_LIBRARY_NAME);
         ::dlclose(color_lib);
         delete color_mgr;
         return NULL;
       }
     } else {
-      DLOGW("Fail to load = %s", DISPLAY_API_INTERFACE_LIBRARY_NAME);
+      DLOGW("Unable to load = %s", DISPLAY_API_INTERFACE_LIBRARY_NAME);
       delete color_mgr;
       return NULL;
     }
@@ -110,7 +120,7 @@
           ::dlsym(diag_lib, DEINIT_QDCM_DIAG_CLIENT_NAME);
 
       if (!color_mgr->qdcm_diag_init_ || !color_mgr->qdcm_diag_deinit_) {
-        DLOGW("Fail to retrieve = %s from %s", INIT_QDCM_DIAG_CLIENT_NAME,
+        DLOGE("Fail to retrieve = %s from %s", INIT_QDCM_DIAG_CLIENT_NAME,
               QDCM_DIAG_CLIENT_LIBRARY_NAME);
         ::dlclose(diag_lib);
       } else {
@@ -120,11 +130,11 @@
               QDCM_DIAG_CLIENT_LIBRARY_NAME);
       }
     } else {
-      DLOGW("Fail to load = %s", QDCM_DIAG_CLIENT_LIBRARY_NAME);
+      DLOGW("Unable to load = %s", QDCM_DIAG_CLIENT_LIBRARY_NAME);
       // only QDCM Diag client failed to be loaded and system still should function.
     }
   } else {
-    DLOGW("Unable to create HWCColorManager");
+    DLOGE("Unable to create HWCColorManager");
     return NULL;
   }
 
@@ -143,24 +153,24 @@
   delete this;
 }
 
-int HWCColorManager::EnableQDCMMode(bool enable) {
+int HWCColorManager::EnableQDCMMode(bool enable, HWCDisplay *hwc_display) {
   int ret = 0;
 
   if (enable) {  // entering QDCM mode, disable all active features and acquire Android wakelock
     qdcm_mode_mgr_ = HWCQDCMModeManager::CreateQDCMModeMgr();
     if (!qdcm_mode_mgr_) {
-      DLOGW("failing to create QDCM operating mode manager.");
+      DLOGE("failing to create QDCM operating mode manager.");
       ret = -EFAULT;
     } else {
-      ret = qdcm_mode_mgr_->EnableQDCMMode(enable);
+      ret = qdcm_mode_mgr_->EnableQDCMMode(enable, hwc_display);
     }
   } else {  // exiting QDCM mode, reverse the effect of entering.
     if (!qdcm_mode_mgr_) {
-      DLOGW("failing to disable QDCM operating mode manager.");
+      DLOGE("failing to disable QDCM operating mode manager.");
       ret = -EFAULT;
     } else {  // once exiting from QDCM operating mode, destroy QDCMModeMgr and release the
               // resources
-      ret = qdcm_mode_mgr_->EnableQDCMMode(enable);
+      ret = qdcm_mode_mgr_->EnableQDCMMode(enable, hwc_display);
       delete qdcm_mode_mgr_;
       qdcm_mode_mgr_ = NULL;
     }
@@ -169,6 +179,158 @@
   return ret;
 }
 
+bool HWCColorManager::SolidFillLayersPrepare(hwc_display_contents_1_t **displays,
+                                             HWCDisplay *hwc_display) {
+  SCOPE_LOCK(locker_);
+
+  // Query HWCColorManager if QDCM tool requesting SOLID_FILL mode.
+  uint32_t solid_fill_color = Get8BitsARGBColorValue(solid_fill_params_);
+  hwc_display_contents_1_t *layer_list = displays[HWC_DISPLAY_PRIMARY];
+
+  if (solid_fill_enable_ && solid_fill_layers_ && layer_list) {
+    // 1. shallow copy HWC_FRAMEBUFFER_TARGET layer info solid fill layer list.
+    solid_fill_layers_->hwLayers[1] = layer_list->hwLayers[layer_list->numHwLayers - 1];
+
+    // 2. continue the prepare<> on solid_fill_layers.
+    hwc_display->Perform(HWCDisplayPrimary::SET_QDCM_SOLID_FILL_INFO, solid_fill_color);
+    hwc_display->Prepare(solid_fill_layers_);  // RECT info included.
+
+    // 3. Set HWC_OVERLAY to all SF layers before returning to framework.
+    for (size_t i = 0; i < (layer_list->numHwLayers - 1); i++) {
+      hwc_layer_1_t *layer = &layer_list->hwLayers[i];
+      layer->compositionType = HWC_OVERLAY;
+    }
+
+    return true;
+  } else if (!solid_fill_enable_) {
+    hwc_display->Perform(HWCDisplayPrimary::UNSET_QDCM_SOLID_FILL_INFO, 0);
+  }
+
+  return false;
+}
+
+bool HWCColorManager::SolidFillLayersSet(hwc_display_contents_1_t **displays,
+                                         HWCDisplay *hwc_display) {
+  // Query HWCColorManager if QDCM tool requesting SOLID_FILL mode.
+  SCOPE_LOCK(locker_);
+  hwc_display_contents_1_t *layer_list = displays[HWC_DISPLAY_PRIMARY];
+  if (solid_fill_enable_ && solid_fill_layers_ && layer_list) {
+    hwc_display->Commit(solid_fill_layers_);
+
+    // release SF layers corresponding Fences manually before returning to Framework.
+    for (size_t i = 0; i < (layer_list->numHwLayers - 1); i++) {
+      if (layer_list->hwLayers[i].acquireFenceFd >= 0) {
+        close(layer_list->hwLayers[i].acquireFenceFd);
+        layer_list->hwLayers[i].acquireFenceFd = -1;
+      }
+      layer_list->retireFenceFd = -1;
+    }
+
+    return true;
+  }
+
+  return false;
+}
+
+int HWCColorManager::CreateSolidFillLayers(HWCDisplay *hwc_display) {
+  int ret = 0;
+
+  if (!solid_fill_layers_) {
+    uint32_t size = sizeof(hwc_display_contents_1) + kNumSolidFillLayers * sizeof(hwc_layer_1_t);
+    uint32_t primary_width = 0;
+    uint32_t primary_height = 0;
+
+    hwc_display->GetPanelResolution(&primary_width, &primary_height);
+    uint8_t *buf = new uint8_t[size]();
+    // handle for solid fill layer with fd = -1.
+    private_handle_t *handle =
+        new private_handle_t(-1, 0, private_handle_t::PRIV_FLAGS_FRAMEBUFFER, BUFFER_TYPE_UI,
+                            HAL_PIXEL_FORMAT_RGBA_8888, primary_width, primary_height);
+
+    if (!buf || !handle) {
+      DLOGE("Failed to allocate memory.");
+      if (buf)
+        delete[] buf;
+      if (handle)
+        delete handle;
+
+      return -ENOMEM;
+    }
+
+    solid_fill_layers_ = reinterpret_cast<hwc_display_contents_1 *>(buf);
+    hwc_layer_1_t &layer = solid_fill_layers_->hwLayers[0];
+    layer.handle = handle;
+  }
+
+  solid_fill_layers_->flags = HWC_GEOMETRY_CHANGED;
+  solid_fill_layers_->numHwLayers = kNumSolidFillLayers;
+  solid_fill_layers_->retireFenceFd = -1;
+  solid_fill_layers_->outbuf = NULL;
+  solid_fill_layers_->outbufAcquireFenceFd = -1;
+
+  hwc_layer_1_t &layer = solid_fill_layers_->hwLayers[0];
+  hwc_rect_t solid_fill_rect = {
+      INT(solid_fill_params_.rect.x), INT(solid_fill_params_.rect.y),
+      INT(solid_fill_params_.rect.x + solid_fill_params_.rect.width),
+      INT(solid_fill_params_.rect.y + solid_fill_params_.rect.height),
+  };
+
+  layer.compositionType = HWC_FRAMEBUFFER;
+  layer.blending = HWC_BLENDING_PREMULT;
+  layer.sourceCropf.left = solid_fill_params_.rect.x;
+  layer.sourceCropf.top = solid_fill_params_.rect.y;
+  layer.sourceCropf.right = solid_fill_params_.rect.x + solid_fill_params_.rect.width;
+  layer.sourceCropf.bottom = solid_fill_params_.rect.y + solid_fill_params_.rect.height;
+  layer.acquireFenceFd = -1;
+  layer.releaseFenceFd = -1;
+  layer.flags = 0;
+  layer.transform = 0;
+  layer.hints = 0;
+  layer.planeAlpha = 0xff;
+  layer.displayFrame = solid_fill_rect;
+  layer.visibleRegionScreen.numRects = 1;
+  layer.visibleRegionScreen.rects = &layer.displayFrame;
+
+  return ret;
+}
+
+void HWCColorManager::DestroySolidFillLayers() {
+  if (solid_fill_layers_) {
+    hwc_layer_1_t &layer = solid_fill_layers_->hwLayers[0];
+    uint8_t *buf = reinterpret_cast<uint8_t *>(solid_fill_layers_);
+    private_handle_t const *hnd = reinterpret_cast<private_handle_t const *>(layer.handle);
+
+    if (hnd)
+        delete hnd;
+
+    if (buf)
+        delete[] buf;
+
+    solid_fill_layers_ = NULL;
+  }
+}
+
+int HWCColorManager::SetSolidFill(const void *params, bool enable, HWCDisplay *hwc_display) {
+  SCOPE_LOCK(locker_);
+  int ret = 0;
+
+  if (params) {
+    solid_fill_params_ = *reinterpret_cast<const PPColorFillParams *>(params);
+  } else {
+    solid_fill_params_ = PPColorFillParams();
+  }
+
+  if (enable) {
+    // will create solid fill layers for rendering if not present.
+    ret = CreateSolidFillLayers(hwc_display);
+  } else {
+    DestroySolidFillLayers();
+  }
+  solid_fill_enable_ = enable;
+
+  return ret;
+}
+
 const HWCQDCMModeManager::ActiveFeatureCMD HWCQDCMModeManager::kActiveFeatureCMD[] = {
     HWCQDCMModeManager::ActiveFeatureCMD("cabl:on", "cabl:off", "cabl:status", "running"),
     HWCQDCMModeManager::ActiveFeatureCMD("ad:on", "ad:off", "ad:query:status", "running"),
@@ -193,6 +355,9 @@
       DLOGW("Unable to connect to dpps socket!");
     }
 
+    // retrieve system GPU idle timeout value for later to recover.
+    mode_mgr->entry_timeout_ = HWCDebugHandler::GetIdleTimeoutMs();
+
     // acquire the binder handle to Android system PowerManager for later use.
     android::sp<android::IBinder> binder =
         android::defaultServiceManager()->checkService(android::String16("power"));
@@ -280,13 +445,19 @@
   return ret;
 }
 
-int HWCQDCMModeManager::EnableQDCMMode(bool enable) {
+int HWCQDCMModeManager::EnableQDCMMode(bool enable, HWCDisplay *hwc_display) {
   int ret = 0;
 
   ret = EnableActiveFeatures((enable ? false : true), kActiveFeatureCMD[kCABLFeature],
                              &cabl_was_running_);
   ret = AcquireAndroidWakeLock(enable);
 
+  // if enter QDCM mode, disable GPU fallback idle timeout.
+  if (hwc_display) {
+    uint32_t timeout = enable ? 0 : entry_timeout_;
+    hwc_display->SetIdleTimeoutMs(timeout);
+  }
+
   return ret;
 }
 
diff --git a/sdm/libs/hwc/hwc_color_manager.h b/sdm/libs/hwc/hwc_color_manager.h
index 4c684b2..abf016f 100644
--- a/sdm/libs/hwc/hwc_color_manager.h
+++ b/sdm/libs/hwc/hwc_color_manager.h
@@ -31,11 +31,11 @@
 #define __HWC_COLOR_MANAGER_H__
 
 #include <stdlib.h>
-#include <core/sdm_types.h>
-#include <utils/locker.h>
 #include <binder/Parcel.h>
 #include <powermanager/IPowerManager.h>
 #include <binder/BinderService.h>
+#include <core/sdm_types.h>
+#include <utils/locker.h>
 
 namespace sdm {
 
@@ -83,11 +83,11 @@
  public:
   static HWCQDCMModeManager *CreateQDCMModeMgr();
   ~HWCQDCMModeManager();
-  int EnableQDCMMode(bool enable);
+  int EnableQDCMMode(bool enable, HWCDisplay *hwc_display);
 
  protected:
-  HWCQDCMModeManager()
-      : cabl_was_running_(false), socket_fd_(-1), wakelock_token_(NULL), power_mgr_(NULL) {}
+  HWCQDCMModeManager() : cabl_was_running_(false), socket_fd_(-1), wakelock_token_(NULL),
+        power_mgr_(NULL), entry_timeout_(0) {}
   bool SendSocketCmd();
   int AcquireAndroidWakeLock(bool enable);
   int EnableActiveFeatures(bool enable);
@@ -98,6 +98,7 @@
   int socket_fd_;
   android::sp<android::IBinder> wakelock_token_;
   android::sp<android::IPowerManager> power_mgr_;
+  uint32_t entry_timeout_;
   static const char *const kSocketName;
   static const char *const kTagName;
   static const char *const kPackageName;
@@ -106,19 +107,26 @@
 // Class to encapsulte all HWC/OS specific behaviours for ColorManager.
 class HWCColorManager {
  public:
+  static const int kNumSolidFillLayers = 2;
   static HWCColorManager *CreateColorManager();
   static int CreatePayloadFromParcel(const android::Parcel &in, uint32_t *disp_id,
                                      PPDisplayAPIPayload *sink);
   static void MarshallStructIntoParcel(const PPDisplayAPIPayload &data,
-                                       android::Parcel &out_parcel);
+                                       android::Parcel *out_parcel);
 
   ~HWCColorManager();
   void DestroyColorManager();
-  int EnableQDCMMode(bool enable);
+  int EnableQDCMMode(bool enable, HWCDisplay *hwc_display);
+  int SetSolidFill(const void *params, bool enable, HWCDisplay *hwc_display);
+  bool SolidFillLayersPrepare(hwc_display_contents_1_t **displays, HWCDisplay *hwc_display);
+  bool SolidFillLayersSet(hwc_display_contents_1_t **displays, HWCDisplay *hwc_display);
 
  protected:
-  HWCColorManager()
-      : color_apis_lib_(NULL), diag_client_lib_(NULL), color_apis_(NULL), qdcm_mode_mgr_(NULL) {}
+  HWCColorManager() : color_apis_lib_(NULL), diag_client_lib_(NULL), color_apis_(NULL),
+        qdcm_mode_mgr_(NULL), solid_fill_enable_(false), solid_fill_layers_(NULL) {}
+  int CreateSolidFillLayers(HWCDisplay *hwc_display);
+  void DestroySolidFillLayers();
+  static uint32_t Get8BitsARGBColorValue(const PPColorFillParams &params);
 
  private:
   void *color_apis_lib_, *diag_client_lib_;
@@ -126,6 +134,11 @@
   QDCMDiagInit qdcm_diag_init_;
   QDCMDiagDeInit qdcm_diag_deinit_;
   HWCQDCMModeManager *qdcm_mode_mgr_;
+
+  bool solid_fill_enable_;
+  PPColorFillParams solid_fill_params_;
+  hwc_display_contents_1_t *solid_fill_layers_;
+  Locker locker_;
 };
 
 }  // namespace sdm
diff --git a/sdm/libs/hwc/hwc_debugger.cpp b/sdm/libs/hwc/hwc_debugger.cpp
index 4b5c659..f12eb10 100644
--- a/sdm/libs/hwc/hwc_debugger.cpp
+++ b/sdm/libs/hwc/hwc_debugger.cpp
@@ -155,6 +155,13 @@
   atrace_end(ATRACE_TAG);
 }
 
+int  HWCDebugHandler::GetIdleTimeoutMs() {
+  int value = IDLE_TIMEOUT_DEFAULT_MS;
+  debug_handler_.GetProperty("sdm.idle_time", &value);
+
+  return value;
+}
+
 DisplayError HWCDebugHandler::GetProperty(const char *property_name, int *value) {
   char property[PROPERTY_VALUE_MAX];
 
diff --git a/sdm/libs/hwc/hwc_debugger.h b/sdm/libs/hwc/hwc_debugger.h
index 9fedb80..46f6a25 100644
--- a/sdm/libs/hwc/hwc_debugger.h
+++ b/sdm/libs/hwc/hwc_debugger.h
@@ -63,6 +63,7 @@
   static void DebugDriverConfig(bool enable, int verbose_level);
   static void DebugRotator(bool enable, int verbose_level);
   static void DebugQdcm(bool enable, int verbose_level);
+  static int  GetIdleTimeoutMs();
 
   virtual void Error(DebugTag tag, const char *format, ...);
   virtual void Warning(DebugTag tag, const char *format, ...);
diff --git a/sdm/libs/hwc/hwc_display.cpp b/sdm/libs/hwc/hwc_display.cpp
index c366f4c..c9828d8 100644
--- a/sdm/libs/hwc/hwc_display.cpp
+++ b/sdm/libs/hwc/hwc_display.cpp
@@ -102,7 +102,7 @@
       if (blit_engine_->Init() < 0) {
         DLOGI("Blit Engine Init failed, Blit Composition will not be used!!");
         delete blit_engine_;
-        blit_engine_= NULL;
+        blit_engine_ = NULL;
       }
     }
   }
@@ -127,7 +127,7 @@
   if (blit_engine_) {
     blit_engine_->DeInit();
     delete blit_engine_;
-    blit_engine_= NULL;
+    blit_engine_ = NULL;
   }
 
   return 0;
@@ -317,9 +317,10 @@
 DisplayError HWCDisplay::Refresh() {
   if (*hwc_procs_ && handle_refresh_) {
     (*hwc_procs_)->invalidate(*hwc_procs_);
+    return kErrorNone;
   }
 
-  return kErrorNone;
+  return kErrorNotSupported;
 }
 
 int HWCDisplay::AllocateLayerStack(hwc_display_contents_1_t *content_list) {
@@ -425,7 +426,14 @@
   LayerBuffer *layer_buffer = layer->input_buffer;
 
   if (pvt_handle) {
+    layer->frame_rate = fps;
     layer_buffer->format = GetSDMFormat(pvt_handle->format, pvt_handle->flags);
+
+    const MetaData_t *meta_data = reinterpret_cast<MetaData_t *>(pvt_handle->base_metadata);
+    if (meta_data && (SetMetaData(*meta_data, layer) != kErrorNone)) {
+      return -EINVAL;
+    }
+
     if (layer_buffer->format == kFormatInvalid) {
       return -EINVAL;
     }
@@ -440,16 +448,15 @@
       layer_stack_.flags.secure_present = true;
       layer_buffer->flags.secure = true;
     }
-
-    layer->frame_rate = fps;
-    const MetaData_t *meta_data = reinterpret_cast<MetaData_t *>(pvt_handle->base_metadata);
-    if (meta_data && (SetMetaData(*meta_data, layer) != kErrorNone)) {
-      return -EINVAL;
-    }
-
     if (pvt_handle->flags & private_handle_t::PRIV_FLAGS_SECURE_DISPLAY) {
       layer_buffer->flags.secure_display = true;
     }
+
+    // check if this is special solid_fill layer without input_buffer.
+    if (solid_fill_enable_ && pvt_handle->fd == -1) {
+      layer->flags.solid_fill = true;
+      layer->solid_fill_color = solid_fill_color_;
+    }
   } else {
     // for FBT layer
     if (hwc_layer->compositionType == HWC_FRAMEBUFFER_TARGET) {
@@ -1207,6 +1214,10 @@
     layer->input_buffer->flags.interlace = true;
   }
 
+  if (meta_data.operation & LINEAR_FORMAT) {
+    layer->input_buffer->format = GetSDMFormat(meta_data.linearFormat, 0);
+  }
+
   if (meta_data.operation & UPDATE_COLOR_SPACE) {
     if (SetColorSpace(meta_data.colorSpace, &layer->color_space) != kErrorNone) {
       return kErrorNotSupported;
@@ -1216,8 +1227,19 @@
   return kErrorNone;
 }
 
-int HWCDisplay::ColorSVCRequestRoute(PPDisplayAPIPayload &in_payload,
-                               PPDisplayAPIPayload *out_payload, PPPendingParams *pending_action) {
+int HWCDisplay::SetPanelBrightness(int level) {
+  int ret = 0;
+  if (display_intf_)
+    ret = display_intf_->SetPanelBrightness(level);
+  else
+    ret = -EINVAL;
+
+  return ret;
+}
+
+int HWCDisplay::ColorSVCRequestRoute(const PPDisplayAPIPayload &in_payload,
+                                     PPDisplayAPIPayload *out_payload,
+                                     PPPendingParams *pending_action) {
   int ret = 0;
 
   if (display_intf_)
diff --git a/sdm/libs/hwc/hwc_display.h b/sdm/libs/hwc/hwc_display.h
index 7f6bc7c..7020fce 100644
--- a/sdm/libs/hwc/hwc_display.h
+++ b/sdm/libs/hwc/hwc_display.h
@@ -57,7 +57,9 @@
   virtual int Perform(uint32_t operation, ...);
   virtual ~HWCDisplay() { }
 
-  int ColorSVCRequestRoute(PPDisplayAPIPayload &in_payload, PPDisplayAPIPayload *out_payload,
+  int SetPanelBrightness(int level);
+  int ColorSVCRequestRoute(const PPDisplayAPIPayload &in_payload,
+                           PPDisplayAPIPayload *out_payload,
                            PPPendingParams *pending_action);
 
  protected:
@@ -162,6 +164,9 @@
   bool handle_refresh_;
   bool use_blit_comp_;
 
+  bool solid_fill_enable_;
+  uint32_t solid_fill_color_;
+
  private:
   bool IsFrameBufferScaled();
   void DumpInputBuffers(hwc_display_contents_1_t *content_list);
diff --git a/sdm/libs/hwc/hwc_display_primary.cpp b/sdm/libs/hwc/hwc_display_primary.cpp
index d6af70f..c53f4eb 100644
--- a/sdm/libs/hwc/hwc_display_primary.cpp
+++ b/sdm/libs/hwc/hwc_display_primary.cpp
@@ -30,7 +30,6 @@
 #include <cutils/properties.h>
 #include <utils/constants.h>
 #include <stdarg.h>
-#include <cutils/properties.h>
 #include "hwc_display_primary.h"
 #include "hwc_debugger.h"
 
@@ -91,7 +90,7 @@
 
   // Applying default mode after bootanimation is finished
   property_get("init.svc.bootanim", value, "running");
-  if (!strncmp(value,"stopped",strlen("stopped"))) {
+  if (!strncmp(value, "stopped", strlen("stopped"))) {
     boot_animation_completed_ = true;
 
     // one-shot action check if bootanimation completed then apply default display mode.
@@ -184,6 +183,12 @@
     case SET_DISPLAY_MODE:
       SetDisplayMode(val);
       break;
+    case SET_QDCM_SOLID_FILL_INFO:
+      SetQDCMSolidFillInfo(true, val);
+      break;
+    case UNSET_QDCM_SOLID_FILL_INFO:
+      SetQDCMSolidFillInfo(false, val);
+      break;
     default:
       DLOGW("Invalid operation %d", operation);
       return -EINVAL;
@@ -206,5 +211,10 @@
   use_metadata_refresh_rate_ = enable;
 }
 
+void HWCDisplayPrimary::SetQDCMSolidFillInfo(bool enable, uint32_t color) {
+  solid_fill_enable_ = enable;
+  solid_fill_color_  = color;
+}
+
 }  // namespace sdm
 
diff --git a/sdm/libs/hwc/hwc_display_primary.h b/sdm/libs/hwc/hwc_display_primary.h
index cf9fc57..161dab7 100644
--- a/sdm/libs/hwc/hwc_display_primary.h
+++ b/sdm/libs/hwc/hwc_display_primary.h
@@ -35,6 +35,8 @@
     SET_METADATA_DYN_REFRESH_RATE,
     SET_BINDER_DYN_REFRESH_RATE,
     SET_DISPLAY_MODE,
+    SET_QDCM_SOLID_FILL_INFO,
+    UNSET_QDCM_SOLID_FILL_INFO,
   };
 
   static int Create(CoreInterface *core_intf, hwc_procs_t const **hwc_procs,
@@ -51,6 +53,7 @@
   void SetMetaDataRefreshRateFlag(bool enable);
   virtual DisplayError SetDisplayMode(uint32_t mode);
   void ProcessBootAnimCompleted();
+  void SetQDCMSolidFillInfo(bool enable, uint32_t color);
 };
 
 }  // namespace sdm
diff --git a/sdm/libs/hwc/hwc_display_virtual.cpp b/sdm/libs/hwc/hwc_display_virtual.cpp
index b1a5acd..10a8ec2 100644
--- a/sdm/libs/hwc/hwc_display_virtual.cpp
+++ b/sdm/libs/hwc/hwc_display_virtual.cpp
@@ -112,7 +112,6 @@
 }
 
 int HWCDisplayVirtual::Init() {
-
   output_buffer_ = new LayerBuffer();
   if (!output_buffer_) {
     return -ENOMEM;
diff --git a/sdm/libs/hwc/hwc_session.cpp b/sdm/libs/hwc/hwc_session.cpp
index 878ff4c..058b933 100644
--- a/sdm/libs/hwc/hwc_session.cpp
+++ b/sdm/libs/hwc/hwc_session.cpp
@@ -227,6 +227,13 @@
     hwc_session->ResetPanel();
   }
 
+  HWCDisplay *&primary_display = hwc_session->hwc_display_[HWC_DISPLAY_PRIMARY];
+  if (primary_display) {
+    int ret = hwc_session->color_mgr_->SolidFillLayersPrepare(displays, primary_display);
+    if (ret)
+      return 0;
+  }
+
   for (ssize_t dpy = static_cast<ssize_t>(num_displays - 1); dpy >= 0; dpy--) {
     hwc_display_contents_1_t *content_list = displays[dpy];
     if (dpy == HWC_DISPLAY_VIRTUAL) {
@@ -257,6 +264,13 @@
 
   HWCSession *hwc_session = static_cast<HWCSession *>(device);
 
+  HWCDisplay *&primary_display = hwc_session->hwc_display_[HWC_DISPLAY_PRIMARY];
+  if (primary_display) {
+    int ret = hwc_session->color_mgr_->SolidFillLayersSet(displays, primary_display);
+    if (ret)
+      return 0;
+  }
+
   for (size_t dpy = 0; dpy < num_displays; dpy++) {
     hwc_display_contents_1_t *content_list = displays[dpy];
     if (dpy == HWC_DISPLAY_VIRTUAL) {
@@ -503,6 +517,10 @@
   case qService::IQService::SET_VIEW_FRAME:
     break;
 
+  case qService::IQService::CONTROL_BACKLIGHT:
+    status = ControlBackLight(input_parcel);
+    break;
+
   case qService::IQService::QDCM_SVC_CMDS:
     status = QdcmCMDHandler(*input_parcel, output_parcel);
     break;
@@ -515,6 +533,45 @@
   return status;
 }
 
+android::status_t HWCSession::ControlBackLight(const android::Parcel *input_parcel) {
+  uint32_t display_status = UINT32(input_parcel->readInt32());
+  HWCDisplay *display = hwc_display_[HWC_DISPLAY_PRIMARY];
+
+  DLOGI("Primary Display display_status = %d", display_status);
+
+  int fd = open("/sys/class/leds/lcd-backlight/brightness", O_RDWR);
+  const char *bl_brightness = "0";
+
+  if (fd < 0) {
+    DLOGE("unable to open brightness node err = %d errstr = %s", errno, strerror(errno));
+    return -1;
+  }
+
+  if (display_status == 0) {
+    // Read backlight and store it internally. Set backlight to 0 on primary.
+    if (read(fd, brightness_, sizeof(brightness_)) > 0) {
+      DLOGI("backlight brightness is %s", brightness_);
+      ssize_t ret = write(fd, bl_brightness, sizeof(bl_brightness));
+      if (ret < 0) {
+        DLOGE("Failed to write backlight node err = %d errstr = %s", errno, strerror(errno));
+        close(fd);
+        return -1;
+      }
+    }
+  } else {
+    // Restore backlight to original value.
+    ssize_t ret = write(fd, brightness_, sizeof(brightness_));
+    if (ret < 0) {
+      DLOGE("Failed to write backlight node err = %d errstr = %s", errno, strerror(errno));
+      close(fd);
+      return -1;
+    }
+  }
+  close(fd);
+
+  return display->SetDisplayStatus(display_status);
+}
+
 android::status_t HWCSession::SetSecondaryDisplayStatus(const android::Parcel *input_parcel) {
   uint32_t display_id = UINT32(input_parcel->readInt32());
   uint32_t display_status = UINT32(input_parcel->readInt32());
@@ -657,6 +714,7 @@
 
 android::status_t HWCSession::QdcmCMDHandler(const android::Parcel &in, android::Parcel *out) {
   int ret = 0;
+  int32_t *brightness_value = NULL;
   uint32_t display_id(0);
   PPPendingParams pending_action;
   PPDisplayAPIPayload resp_payload, req_payload;
@@ -685,13 +743,29 @@
       hwc_procs_->invalidate(hwc_procs_);
       break;
     case kEnterQDCMMode:
-      ret = color_mgr_->EnableQDCMMode(true);
+      ret = color_mgr_->EnableQDCMMode(true, hwc_display_[HWC_DISPLAY_PRIMARY]);
       break;
     case kExitQDCMMode:
-      ret = color_mgr_->EnableQDCMMode(false);
+      ret = color_mgr_->EnableQDCMMode(false, hwc_display_[HWC_DISPLAY_PRIMARY]);
       break;
     case kApplySolidFill:
+      ret = color_mgr_->SetSolidFill(pending_action.params,
+                                        true, hwc_display_[HWC_DISPLAY_PRIMARY]);
+      hwc_procs_->invalidate(hwc_procs_);
+      break;
     case kDisableSolidFill:
+      ret = color_mgr_->SetSolidFill(pending_action.params,
+                                        false, hwc_display_[HWC_DISPLAY_PRIMARY]);
+      hwc_procs_->invalidate(hwc_procs_);
+      break;
+    case kSetPanelBrightness:
+      brightness_value = reinterpret_cast<int32_t*>(resp_payload.payload);
+      if (brightness_value == NULL) {
+        DLOGE("Brightness value is Null");
+        return -EINVAL;
+      }
+      if (HWC_DISPLAY_PRIMARY == display_id)
+        ret = hwc_display_[HWC_DISPLAY_PRIMARY]->SetPanelBrightness(*brightness_value);
       break;
     case kNoAction:
       break;
@@ -702,7 +776,7 @@
 
   // for display API getter case, marshall returned params into out_parcel.
   out->writeInt32(ret);
-  HWCColorManager::MarshallStructIntoParcel(resp_payload, *out);
+  HWCColorManager::MarshallStructIntoParcel(resp_payload, out);
   req_payload.DestroyPayload();
   resp_payload.DestroyPayload();
 
diff --git a/sdm/libs/hwc/hwc_session.h b/sdm/libs/hwc/hwc_session.h
index b3cbb70..c8550d5 100644
--- a/sdm/libs/hwc/hwc_session.h
+++ b/sdm/libs/hwc/hwc_session.h
@@ -87,6 +87,7 @@
   android::status_t SetMaxMixerStages(const android::Parcel *input_parcel);
   android::status_t SetDisplayMode(const android::Parcel *input_parcel);
   android::status_t SetSecondaryDisplayStatus(const android::Parcel *input_parcel);
+  android::status_t ControlBackLight(const android::Parcel *input_parcel);
   android::status_t ConfigureRefreshRate(const android::Parcel *input_parcel);
   android::status_t QdcmCMDHandler(const android::Parcel &in, android::Parcel *out);
 
@@ -100,8 +101,8 @@
   const char *uevent_thread_name_;
   HWCBufferAllocator *buffer_allocator_;
   HWCBufferSyncHandler *buffer_sync_handler_;
-
   HWCColorManager *color_mgr_;
+  char brightness_[64];
 };
 
 }  // namespace sdm
diff --git a/sdm/libs/utils/debug.cpp b/sdm/libs/utils/debug.cpp
index ada17cd..f240082 100644
--- a/sdm/libs/utils/debug.cpp
+++ b/sdm/libs/utils/debug.cpp
@@ -113,5 +113,12 @@
   return (value == 1);
 }
 
+bool Debug::IsRotatorSplitDisabled() {
+  int value = 0;
+  debug_.debug_handler_->GetProperty("sdm.debug.disable_rotator_split", &value);
+
+  return (value == 1);
+}
+
 }  // namespace sdm
 
diff --git a/sdm/libs/utils/rect.cpp b/sdm/libs/utils/rect.cpp
index 9edc4f4..8350340 100644
--- a/sdm/libs/utils/rect.cpp
+++ b/sdm/libs/utils/rect.cpp
@@ -138,5 +138,43 @@
   return res;
 }
 
+void SplitLeftRight(const LayerRect &in_rect, uint32_t split_count, uint32_t align_x,
+                   LayerRect *out_rects) {
+  LayerRect rect_temp = in_rect;
+
+  uint32_t split_width = UINT32(rect_temp.right - rect_temp.left) / split_count;
+
+  for (uint32_t count = 0; count < split_count; count++) {
+    float aligned_right = rect_temp.left + FLOAT(CeilToMultipleOf(split_width, align_x));
+    out_rects[count].left = rect_temp.left;
+    out_rects[count].right = MIN(rect_temp.right, aligned_right);
+    out_rects[count].top = rect_temp.top;
+    out_rects[count].bottom = rect_temp.bottom;
+
+    rect_temp.left = out_rects[count].right;
+
+    Log(kTagRotator, "SplitLeftRight", out_rects[count]);
+  }
+}
+
+void SplitTopBottom(const LayerRect &in_rect, uint32_t split_count, uint32_t align_y,
+                     LayerRect *out_rects) {
+  LayerRect rect_temp = in_rect;
+
+  uint32_t split_height = UINT32(rect_temp.bottom - rect_temp.top) / split_count;
+
+  for (uint32_t count = 0; count < split_count; count++) {
+    float aligned_bottom = rect_temp.top + FLOAT(CeilToMultipleOf(split_height, align_y));
+    out_rects[count].top = rect_temp.top;
+    out_rects[count].bottom = MIN(rect_temp.bottom, aligned_bottom);
+    out_rects[count].left = rect_temp.left;
+    out_rects[count].right = rect_temp.right;
+
+    rect_temp.top = out_rects[count].bottom;
+
+    Log(kTagRotator, "SplitTopBottom", out_rects[count]);
+  }
+}
+
 }  // namespace sdm