Merge "hwc: Populate frame rate in rotator set"
diff --git a/libhwcomposer/hwc_mdpcomp.cpp b/libhwcomposer/hwc_mdpcomp.cpp
index 1f16416..77d52dc 100644
--- a/libhwcomposer/hwc_mdpcomp.cpp
+++ b/libhwcomposer/hwc_mdpcomp.cpp
@@ -69,7 +69,8 @@
     return new MDPCompNonSplit(dpy);
 }
 
-MDPComp::MDPComp(int dpy):mDpy(dpy){};
+MDPComp::MDPComp(int dpy) : mDpy(dpy), mModeOn(false), mPrevModeOn(false) {
+};
 
 void MDPComp::dump(android::String8& buf, hwc_context_t *ctx)
 {
@@ -554,6 +555,13 @@
     if(!isEnabled()) {
         ALOGD_IF(isDebug(),"%s: MDP Comp. not enabled.", __FUNCTION__);
         ret = false;
+    } else if (ctx->isDMAStateChanging) {
+        // Bail out if a padding round has been invoked in order to switch DMA
+        // state to block mode. We need this to cater for the case when a layer
+        // requires rotation in the current frame.
+        ALOGD_IF(isDebug(), "%s: padding round invoked to switch DMA state",
+                __FUNCTION__);
+        ret = false;
     } else if(ctx->mVideoTransFlag && isSecondaryConnected(ctx)) {
         //1 Padding round to shift pipes across mixers
         ALOGD_IF(isDebug(),"%s: MDP Comp. video transition padding round",
@@ -583,13 +591,6 @@
                      __FUNCTION__,mDpy);
             ret = false;
         }
-    } else if (ctx->isDMAStateChanging) {
-        // Bail out if a padding round has been invoked in order to switch DMA
-        // state to block mode. We need this to cater for the case when a layer
-        // requires rotation in the current frame.
-        ALOGD_IF(isDebug(), "%s: padding round invoked to switch DMA state",
-                __FUNCTION__);
-        return false;
     }
 
     return ret;
@@ -1808,6 +1809,14 @@
 void MDPComp::updateYUV(hwc_context_t* ctx, hwc_display_contents_1_t* list,
         bool secureOnly, FrameInfo& frame) {
     int nYuvCount = ctx->listStats[mDpy].yuvCount;
+    int nVGpipes = qdutils::MDPVersion::getInstance().getVGPipes();
+
+    /* If number of YUV layers in the layer list is more than the number of
+       VG pipes available in the target (non-split), try to program maximum
+       possible number of YUV layers to MDP, instead of falling back to GPU
+       completely.*/
+    nYuvCount = (nYuvCount > nVGpipes) ? nVGpipes : nYuvCount;
+
     for(int index = 0;index < nYuvCount; index++){
         int nYuvIndex = ctx->listStats[mDpy].yuvIndices[index];
         hwc_layer_1_t* layer = &list->hwLayers[nYuvIndex];
@@ -2172,7 +2181,8 @@
                 __FUNCTION__);
         mCachedFrame.reset();
 #ifdef DYNAMIC_FPS
-        setDynRefreshRate(ctx, list);
+        // Reset refresh rate
+        setRefreshRate(ctx, mDpy, ctx->dpyAttr[mDpy].refreshRate);
 #endif
         freeHwCursor(ctx->dpyAttr[mDpy].fd, mDpy);
         return -1;
@@ -2189,7 +2199,8 @@
         setMDPCompLayerFlags(ctx, list);
         mCachedFrame.updateCounts(mCurrentFrame);
 #ifdef DYNAMIC_FPS
-        setDynRefreshRate(ctx, list);
+        // Reset refresh rate
+        setRefreshRate(ctx, mDpy, ctx->dpyAttr[mDpy].refreshRate);
 #endif
         freeHwCursor(ctx->dpyAttr[mDpy].fd, mDpy);
         ret = -1;
diff --git a/libhwcomposer/hwc_utils.cpp b/libhwcomposer/hwc_utils.cpp
index 7bc4d23..7df7bba 100644
--- a/libhwcomposer/hwc_utils.cpp
+++ b/libhwcomposer/hwc_utils.cpp
@@ -854,7 +854,8 @@
                                ovutils::eTransform& orient) {
     // Swap width and height when there is a 90deg transform
     int extOrient = getExtOrientation(ctx);
-    if(dpy && ctx->mOverlay->isUIScalingOnExternalSupported()) {
+    if ((dpy || ctx->mHDMIDisplay->isHDMIPrimaryDisplay())
+            && ctx->mOverlay->isUIScalingOnExternalSupported()) {
         if(!isYuvBuffer(hnd)) {
             if(extOrient & HWC_TRANSFORM_ROT_90) {
                 int dstWidth = ctx->dpyAttr[dpy].xres;
@@ -1377,8 +1378,9 @@
     // Disable Action safe for 8974 due to HW limitation for downscaling
     // layers with overlapped region
     // Disable Actionsafe for non HDMI displays.
-    if(!(dpy == HWC_DISPLAY_EXTERNAL) ||
-        qdutils::MDPVersion::getInstance().is8x74v2() ||
+    if (!(dpy == HWC_DISPLAY_EXTERNAL ||
+                ctx->mHDMIDisplay->isHDMIPrimaryDisplay()) ||
+            qdutils::MDPVersion::getInstance().is8x74v2() ||
         ctx->mHDMIDisplay->isCEUnderscanSupported()) {
         return false;
     }
diff --git a/sdm/include/core/core_interface.h b/sdm/include/core/core_interface.h
index 882d050..26f6e2f 100644
--- a/sdm/include/core/core_interface.h
+++ b/sdm/include/core/core_interface.h
@@ -42,8 +42,7 @@
 #include "display_interface.h"
 #include "sdm_types.h"
 #include "buffer_allocator.h"
-
-class BufferSyncHandler;
+#include "buffer_sync_handler.h"
 
 /*! @brief Display manager interface version.
 
@@ -77,43 +76,6 @@
 */
 class DebugHandler;
 
-
-/*! @brief Event data associated with hotplug event.
-
-  @sa CoreEventHandler::Hotplug
-*/
-struct CoreEventHotplug {
-  bool connected;   //!< True when device is connected.
-
-  CoreEventHotplug() : connected(false) { }
-};
-
-/*! @brief Display core event handler implemented by the client.
-
-  @details This class declares prototype for display core event handler methods which must be
-  implemented by the client. Display core will use these methods to notify events to the client.
-  Client must post heavy-weight event handling to a separate thread and unblock display core thread
-  instantly.
-
-  @sa CoreInterface::CreateCore
-*/
-class CoreEventHandler {
- public:
-  /*! @brief Event handler for Hotplug event.
-
-    @details Event generated when a display device is connected or disconnected. Applicable to
-    detachable displays only.
-
-    @param[in] \link CoreEventHotplug \endlink
-
-    @return \link DisplayError \endlink
-  */
-  virtual DisplayError Hotplug(const CoreEventHotplug &hotplug) = 0;
-
- protected:
-  virtual ~CoreEventHandler() { }
-};
-
 /*! @brief Display core interface.
 
   @details This class defines display core interfaces. It contains methods which client shall use
@@ -132,7 +94,6 @@
     object of display core is created and handle to this object is returned via output parameter.
     This interface shall be called only once.
 
-    @param[in] event_handler \link CoreEventHandler \endlink
     @param[in] debug_handler \link DebugHandler \endlink
     @param[in] buffer_allocator \link BufferAllocator \endlink
     @param[in] buffer_sync_handler \link BufferSyncHandler \endlink
@@ -143,8 +104,7 @@
 
     @sa DestroyCore
   */
-  static DisplayError CreateCore(CoreEventHandler *event_handler, DebugHandler *debug_handler,
-                                 BufferAllocator *buffer_allocator,
+  static DisplayError CreateCore(DebugHandler *debug_handler, BufferAllocator *buffer_allocator,
                                  BufferSyncHandler *buffer_sync_handler, CoreInterface **interface,
                                  uint32_t version = SDM_VERSION_TAG);
 
diff --git a/sdm/include/core/debug_interface.h b/sdm/include/core/debug_interface.h
index ca6f81a..f8e80b1 100644
--- a/sdm/include/core/debug_interface.h
+++ b/sdm/include/core/debug_interface.h
@@ -38,7 +38,7 @@
 /*! @brief This enum represents different modules/logical unit tags that a log message may
   be associated with. Client may use this to filter messages for dynamic logging.
 
-  @sa DisplayLogHandler
+  @sa DebugHandler
 */
 enum DebugTag {
   kTagNone,             //!< Debug log is not tagged. This type of logs should always be printed.
@@ -101,6 +101,15 @@
   */
   virtual void EndTrace() = 0;
 
+  /*! @brief Method to get property value corresponding to give string.
+
+    @param[in] property_name name of the property
+    @param[out] value value corresponding to the property name
+
+    @return \link DisplayError \endlink
+`  */
+  virtual DisplayError GetProperty(const char *property_name, int *value) = 0;
+
  protected:
   virtual ~DebugHandler() { }
 };
diff --git a/sdm/include/core/display_interface.h b/sdm/include/core/display_interface.h
index b16e43c..68bd5b1 100644
--- a/sdm/include/core/display_interface.h
+++ b/sdm/include/core/display_interface.h
@@ -97,11 +97,9 @@
   float y_dpi;                //!< Dots per inch in Y-direction.
   uint32_t fps;               //!< Frame rate per second.
   uint32_t vsync_period_ns;   //!< VSync period in nanoseconds.
-  uint32_t v_total;           //!< Total height of panel (vActive + vFP + vBP + vPulseWidth).
-  uint32_t h_total;           //!< Total width of panel (hActive + hFP + hBP + hPulseWidth).
 
   DisplayConfigVariableInfo() : x_pixels(0), y_pixels(0), x_dpi(0.0f), y_dpi(0.0f),
-                                fps(0), vsync_period_ns(0), v_total(0), h_total(0) { }
+                                fps(0), vsync_period_ns(0) { }
 };
 
 /*! @brief Event data associated with VSync event.
diff --git a/sdm/include/private/hw_info_types.h b/sdm/include/private/hw_info_types.h
index 3360fb4..fdfc582 100644
--- a/sdm/include/private/hw_info_types.h
+++ b/sdm/include/private/hw_info_types.h
@@ -88,6 +88,11 @@
   uint32_t max_pipe_bw;
   uint32_t max_sde_clk;
   float clk_fudge_factor;
+  uint32_t macrotile_nv12_factor;
+  uint32_t macrotile_factor;
+  uint32_t linear_factor;
+  uint32_t scale_factor;
+  uint32_t extra_fudge_factor;
   bool has_bwc;
   bool has_ubwc;
   bool has_decimation;
@@ -101,9 +106,11 @@
       num_cursor_pipe(0), num_blending_stages(0), num_rotator(0), num_control(0),
       num_mixer_to_disp(0), smp_total(0), smp_size(0), num_smp_per_pipe(0), max_scale_up(1),
       max_scale_down(1), max_bandwidth_low(0), max_bandwidth_high(0), max_mixer_width(2048),
-      max_pipe_width(2048), max_pipe_bw(0), max_sde_clk(0), clk_fudge_factor(1.0f), has_bwc(false),
-      has_ubwc(false), has_decimation(false), has_macrotile(false), has_rotator_downscale(false),
-      has_non_scalar_rgb(false), is_src_split(false) { }
+      max_pipe_width(2048), max_pipe_bw(0), max_sde_clk(0), clk_fudge_factor(1.0f),
+      macrotile_nv12_factor(0), macrotile_factor(0), linear_factor(0), scale_factor(0),
+      extra_fudge_factor(0), has_bwc(false), has_ubwc(false), has_decimation(false),
+      has_macrotile(false), has_rotator_downscale(false), has_non_scalar_rgb(false),
+      is_src_split(false) { }
 
   void Reset() { *this = HWResourceInfo(); }
 };
@@ -198,15 +205,15 @@
 };
 
 struct HWRotateInfo {
-  uint32_t pipe_id;
+  int pipe_id;
+  int writeback_id;
   LayerRect src_roi;
   LayerRect dst_roi;
-  HWBlockType writeback_id;
   bool valid;
   int rotate_id;
 
   HWRotateInfo()
-    : pipe_id(0), writeback_id(kHWWriteback0), valid(false), rotate_id(-1) { }
+    : pipe_id(-1), writeback_id(-1), valid(false), rotate_id(-1) { }
 
   void Reset() { *this = HWRotateInfo(); }
 };
@@ -221,10 +228,11 @@
   int session_id;
   float input_compression;
   float output_compression;
+  bool is_buffer_cached;
 
   HWRotatorSession()
     : hw_block_count(0), downscale_ratio(1.0f), session_id(-1), input_compression(1.0f),
-      output_compression(1.0f) { }
+      output_compression(1.0f), is_buffer_cached(false) { }
 };
 
 struct HWPixelExtension {
@@ -315,8 +323,13 @@
   bool is_device_split;
   uint32_t split_left;
   bool always_src_split;
+  uint32_t v_front_porch;  //!< Vertical front porch of panel
+  uint32_t v_back_porch;   //!< Vertical back porch of panel
+  uint32_t v_pulse_width;  //!< Vertical pulse width of panel
+  uint32_t h_total;        //!< Total width of panel (hActive + hFP + hBP + hPulseWidth)
 
-  HWDisplayAttributes() : is_device_split(false), split_left(0), always_src_split(false) { }
+  HWDisplayAttributes() : is_device_split(false), split_left(0), always_src_split(false),
+                          v_front_porch(0), v_back_porch(0), v_pulse_width(0), h_total(0) { }
 
   void Reset() { *this = HWDisplayAttributes(); }
 
@@ -326,7 +339,10 @@
             (always_src_split != attributes.always_src_split) ||
             (x_pixels != attributes.x_pixels) || (y_pixels != attributes.y_pixels) ||
             (x_dpi != attributes.x_dpi) || (y_dpi != attributes.y_dpi) || (fps != attributes.fps) ||
-            (vsync_period_ns != attributes.vsync_period_ns) || (v_total != attributes.v_total));
+            (vsync_period_ns != attributes.vsync_period_ns) ||
+            (v_front_porch != attributes.v_front_porch) ||
+            (v_back_porch != attributes.v_back_porch) ||
+            (v_pulse_width != attributes.v_pulse_width));
   }
 
   bool operator ==(const HWDisplayAttributes &attributes) {
diff --git a/sdm/include/utils/constants.h b/sdm/include/utils/constants.h
index 75f845b..b68604d 100644
--- a/sdm/include/utils/constants.h
+++ b/sdm/include/utils/constants.h
@@ -26,6 +26,11 @@
 #define __CONSTANTS_H__
 
 #include <stdlib.h>
+#include <inttypes.h>
+
+#ifndef PRIu64
+#define PRIu64 "llu"
+#endif
 
 #define INT(exp) static_cast<int>(exp)
 #define FLOAT(exp) static_cast<float>(exp)
diff --git a/sdm/include/utils/debug.h b/sdm/include/utils/debug.h
index 7f9209e..5b08129 100644
--- a/sdm/include/utils/debug.h
+++ b/sdm/include/utils/debug.h
@@ -33,6 +33,7 @@
 #include <stdint.h>
 #include <core/sdm_types.h>
 #include <core/debug_interface.h>
+#include <core/display_interface.h>
 
 #define DLOG(tag, method, format, ...) Debug::Get()->method(tag, __CLASS__ "::%s: " format, \
                                                             __FUNCTION__, ##__VA_ARGS__)
@@ -59,13 +60,14 @@
     debug_.debug_handler_ = debug_handler;
   }
   static inline DebugHandler* Get() { return debug_.debug_handler_; }
-  static inline bool IsVirtualDriver() { return debug_.virtual_driver_; }
   static uint32_t GetSimulationFlag();
   static uint32_t GetHDMIResolution();
   static uint32_t GetIdleTimeoutMs();
   static bool IsRotatorDownScaleDisabled();
   static bool IsDecimationDisabled();
   static bool IsPartialUpdateEnabled();
+  static int GetMaxPipesPerMixer(DisplayType display_type);
+  static bool IsVideoModeEnabled();
 
  private:
   Debug();
@@ -81,11 +83,13 @@
     virtual void BeginTrace(const char */*class_name*/, const char */*function_name*/,
                             const char */*custom_string*/) { }
     virtual void EndTrace() { }
+    virtual DisplayError GetProperty(const char *property_name, int *value) {
+      return kErrorNotSupported;
+    }
   };
 
   DefaultDebugHandler default_debug_handler_;
   DebugHandler *debug_handler_;
-  bool virtual_driver_;
   static Debug debug_;
 };
 
diff --git a/sdm/include/utils/locker.h b/sdm/include/utils/locker.h
index 3bc92d3..bc24ad5 100644
--- a/sdm/include/utils/locker.h
+++ b/sdm/include/utils/locker.h
@@ -27,6 +27,7 @@
 
 #include <stdint.h>
 #include <pthread.h>
+#include <sys/time.h>
 
 #define SCOPE_LOCK(locker) Locker::ScopeLock lock(locker)
 #define SEQUENCE_ENTRY_SCOPE_LOCK(locker) Locker::SequenceEntryScopeLock lock(locker)
diff --git a/sdm/libs/core/core_impl.cpp b/sdm/libs/core/core_impl.cpp
index f017d8d..5cb1c95 100644
--- a/sdm/libs/core/core_impl.cpp
+++ b/sdm/libs/core/core_impl.cpp
@@ -37,12 +37,11 @@
 
 namespace sdm {
 
-CoreImpl::CoreImpl(CoreEventHandler *event_handler, BufferAllocator *buffer_allocator,
+CoreImpl::CoreImpl(BufferAllocator *buffer_allocator,
                    BufferSyncHandler *buffer_sync_handler)
-  : event_handler_(event_handler), buffer_allocator_(buffer_allocator),
-    buffer_sync_handler_(buffer_sync_handler), hw_resource_(NULL), hw_info_intf_(NULL),
-    rotator_intf_(NULL), extension_lib_(NULL), extension_intf_(NULL),
-    create_extension_intf_(NULL), destroy_extension_intf_(NULL) {
+  : buffer_allocator_(buffer_allocator), buffer_sync_handler_(buffer_sync_handler),
+    hw_resource_(NULL), hw_info_intf_(NULL), rotator_intf_(NULL), extension_lib_(NULL),
+    extension_intf_(NULL), create_extension_intf_(NULL), destroy_extension_intf_(NULL) {
 }
 
 DisplayError CoreImpl::Init() {
@@ -65,7 +64,7 @@
     }
 
     error = create_extension_intf_(EXTENSION_VERSION_TAG, &extension_intf_);
-    if(error != kErrorNone) {
+    if (error != kErrorNone) {
       DLOGE("Unable to create interface");
       ::dlclose(extension_lib_);
       return error;
@@ -99,8 +98,7 @@
     error = extension_intf_->CreateRotator(buffer_allocator_, buffer_sync_handler_,
                                            &rotator_intf_);
     if (error != kErrorNone) {
-      comp_mgr_.Deinit();
-      goto CleanupOnError;
+      DLOGW("rotation is not supported");
     }
   }
 
diff --git a/sdm/libs/core/core_impl.h b/sdm/libs/core/core_impl.h
index bad241c..32fa078 100644
--- a/sdm/libs/core/core_impl.h
+++ b/sdm/libs/core/core_impl.h
@@ -44,8 +44,7 @@
   // This class implements display core interface revision 1.0.
   static const uint16_t kRevision = SET_REVISION(1, 0);
 
-  CoreImpl(CoreEventHandler *event_handler, BufferAllocator *buffer_allocator,
-           BufferSyncHandler *buffer_sync_handler);
+  CoreImpl(BufferAllocator *buffer_allocator, BufferSyncHandler *buffer_sync_handler);
   virtual ~CoreImpl() { }
 
   // This method returns the interface revision for the current display core object.
@@ -61,7 +60,6 @@
 
  protected:
   Locker locker_;
-  CoreEventHandler *event_handler_;
   BufferAllocator *buffer_allocator_;
   BufferSyncHandler *buffer_sync_handler_;
   HWResourceInfo *hw_resource_;
diff --git a/sdm/libs/core/core_interface.cpp b/sdm/libs/core/core_interface.cpp
index 34eceff..177e7bf 100644
--- a/sdm/libs/core/core_interface.cpp
+++ b/sdm/libs/core/core_interface.cpp
@@ -52,13 +52,13 @@
 } g_core;
 
 // TODO(user): Have a single structure handle carries all the interface pointers.
-DisplayError CoreInterface::CreateCore(CoreEventHandler *event_handler, DebugHandler *debug_handler,
+DisplayError CoreInterface::CreateCore(DebugHandler *debug_handler,
                                        BufferAllocator *buffer_allocator,
                                        BufferSyncHandler *buffer_sync_handler,
                                        CoreInterface **interface, uint32_t client_version) {
   SCOPE_LOCK(g_core.locker);
 
-  if (!event_handler || !debug_handler || !buffer_allocator || !buffer_sync_handler || !interface) {
+  if (!debug_handler || !buffer_allocator || !buffer_sync_handler || !interface) {
     return kErrorParameters;
   }
 
@@ -81,7 +81,7 @@
 
   // Create appropriate CoreImpl object based on client version.
   if (GET_REVISION(client_version) == CoreImpl::kRevision) {
-    core_impl = new CoreImpl(event_handler, buffer_allocator, buffer_sync_handler);
+    core_impl = new CoreImpl(buffer_allocator, buffer_sync_handler);
   } else {
     return kErrorNotSupported;
   }
diff --git a/sdm/libs/core/display_base.cpp b/sdm/libs/core/display_base.cpp
index 8dc9b19..fcc69bb 100644
--- a/sdm/libs/core/display_base.cpp
+++ b/sdm/libs/core/display_base.cpp
@@ -27,6 +27,7 @@
 #include <utils/debug.h>
 
 #include "display_base.h"
+#include "hw_info_interface.h"
 
 #define __CLASS__ "DisplayBase"
 
@@ -35,12 +36,14 @@
 // TODO(user): Have a single structure handle carries all the interface pointers and variables.
 DisplayBase::DisplayBase(DisplayType display_type, DisplayEventHandler *event_handler,
                          HWDeviceType hw_device_type, BufferSyncHandler *buffer_sync_handler,
-                         CompManager *comp_manager, RotatorInterface *rotator_intf)
+                         CompManager *comp_manager, RotatorInterface *rotator_intf,
+                         HWInfoInterface *hw_info_intf)
   : display_type_(display_type), event_handler_(event_handler), hw_device_type_(hw_device_type),
     buffer_sync_handler_(buffer_sync_handler), comp_manager_(comp_manager),
     rotator_intf_(rotator_intf), state_(kStateOff), hw_device_(0), display_comp_ctx_(0),
     display_attributes_(NULL), num_modes_(0), active_mode_index_(0), pending_commit_(false),
-    vsync_enable_(false), underscan_supported_(false) {
+    vsync_enable_(false), underscan_supported_(false), max_mixer_stages_(0),
+    hw_info_intf_(hw_info_intf) {
 }
 
 DisplayError DisplayBase::Init() {
@@ -86,6 +89,17 @@
     }
   }
 
+  if (hw_info_intf_) {
+    HWResourceInfo hw_resource_info = HWResourceInfo();
+    hw_info_intf_->GetHWResourceInfo(&hw_resource_info);
+    int max_mixer_stages = hw_resource_info.num_blending_stages;
+    int property_value = Debug::GetMaxPipesPerMixer(display_type_);
+    if (property_value >= 0) {
+      max_mixer_stages = MIN(UINT32(property_value), hw_resource_info.num_blending_stages);
+    }
+    DisplayBase::SetMaxMixerStages(max_mixer_stages);
+  }
+
   return kErrorNone;
 
 CleanupOnError:
@@ -372,6 +386,10 @@
 
   if (comp_manager_) {
     error = comp_manager_->SetMaxMixerStages(display_comp_ctx_, max_mixer_stages);
+
+    if (error == kErrorNone) {
+      max_mixer_stages_ = max_mixer_stages;
+    }
   }
 
   return error;
@@ -389,7 +407,8 @@
 void DisplayBase::AppendDump(char *buffer, uint32_t length) {
   DumpImpl::AppendString(buffer, length, "\n-----------------------");
   DumpImpl::AppendString(buffer, length, "\ndevice type: %u", display_type_);
-  DumpImpl::AppendString(buffer, length, "\nstate: %u, vsync on: %u", state_, INT(vsync_enable_));
+  DumpImpl::AppendString(buffer, length, "\nstate: %u, vsync on: %u, max. mixer stages: %u",
+                         state_, INT(vsync_enable_), max_mixer_stages_);
   DumpImpl::AppendString(buffer, length, "\nnum configs: %u, active config index: %u",
                          num_modes_, active_mode_index_);
 
diff --git a/sdm/libs/core/display_base.h b/sdm/libs/core/display_base.h
index 56e6682..0a2205a 100644
--- a/sdm/libs/core/display_base.h
+++ b/sdm/libs/core/display_base.h
@@ -37,12 +37,14 @@
 namespace sdm {
 
 class RotatorCtrl;
+class HWInfoInterface;
 
 class DisplayBase : public DisplayInterface {
  public:
   DisplayBase(DisplayType display_type, DisplayEventHandler *event_handler,
               HWDeviceType hw_device_type, BufferSyncHandler *buffer_sync_handler,
-              CompManager *comp_manager, RotatorInterface *rotator_intf);
+              CompManager *comp_manager, RotatorInterface *rotator_intf,
+              HWInfoInterface *hw_info_intf);
   virtual ~DisplayBase() { }
   virtual DisplayError Init();
   virtual DisplayError Deinit();
@@ -90,6 +92,8 @@
   bool pending_commit_;
   bool vsync_enable_;
   bool underscan_supported_;
+  uint32_t max_mixer_stages_;
+  HWInfoInterface *hw_info_intf_;
 };
 
 }  // namespace sdm
diff --git a/sdm/libs/core/display_hdmi.cpp b/sdm/libs/core/display_hdmi.cpp
index ef25b90..a5a35a5 100644
--- a/sdm/libs/core/display_hdmi.cpp
+++ b/sdm/libs/core/display_hdmi.cpp
@@ -37,7 +37,7 @@
                          BufferSyncHandler *buffer_sync_handler, CompManager *comp_manager,
                          RotatorInterface *rotator_intf)
   : DisplayBase(kHDMI, event_handler, kDeviceHDMI, buffer_sync_handler, comp_manager,
-                rotator_intf), hw_info_intf_(hw_info_intf) {
+                rotator_intf, hw_info_intf) {
 }
 
 DisplayError DisplayHDMI::Init() {
diff --git a/sdm/libs/core/display_hdmi.h b/sdm/libs/core/display_hdmi.h
index 96b9eea..fb07466 100644
--- a/sdm/libs/core/display_hdmi.h
+++ b/sdm/libs/core/display_hdmi.h
@@ -31,7 +31,6 @@
 namespace sdm {
 
 class HWHDMIInterface;
-class HWInfoInterface;
 
 class DisplayHDMI : public DisplayBase, DumpImpl {
  public:
@@ -67,7 +66,6 @@
 
   Locker locker_;
   HWHDMIInterface *hw_hdmi_intf_;
-  HWInfoInterface *hw_info_intf_;
   HWScanSupport scan_support_;
 };
 
diff --git a/sdm/libs/core/display_primary.cpp b/sdm/libs/core/display_primary.cpp
index 63ee78b..1b0a552 100644
--- a/sdm/libs/core/display_primary.cpp
+++ b/sdm/libs/core/display_primary.cpp
@@ -37,7 +37,7 @@
                                BufferSyncHandler *buffer_sync_handler, CompManager *comp_manager,
                                RotatorInterface *rotator_intf)
   : DisplayBase(kPrimary, event_handler, kDevicePrimary, buffer_sync_handler, comp_manager,
-                rotator_intf), hw_info_intf_(hw_info_intf) {
+                rotator_intf, hw_info_intf) {
 }
 
 DisplayError DisplayPrimary::Init() {
@@ -65,6 +65,14 @@
     hw_primary_intf_->SetIdleTimeoutMs(Debug::GetIdleTimeoutMs());
   }
 
+  if (hw_panel_info_.mode == kModeCommand && Debug::IsVideoModeEnabled()) {
+    error = hw_primary_intf_->SetDisplayMode(kModeVideo);
+    if (error != kErrorNone) {
+      DLOGW("Retaining current display mode. Current = %d, Requested = %d", hw_panel_info_.mode,
+            kModeVideo);
+    }
+  }
+
   return error;
 }
 
@@ -198,7 +206,7 @@
   HWDisplayMode hw_display_mode = kModeDefault;
 
   if (state_ != kStateOn) {
-    DLOGW("Invalid display state (%d). Panel must be on.", state_);
+    DLOGW("Invalid display state = %d. Panel must be on.", state_);
     return kErrorNotSupported;
   }
 
@@ -210,19 +218,19 @@
     hw_display_mode = kModeCommand;
     break;
   default:
-    DLOGW("Invalid panel mode parameters. Requested (%d)", mode);
+    DLOGW("Invalid panel mode parameters. Requested = %d", mode);
     return kErrorParameters;
   }
 
   if (hw_display_mode == hw_panel_info_.mode) {
-    DLOGW("Same display mode requested. Current (%d) Requested (%d)", hw_panel_info_.mode,
+    DLOGW("Same display mode requested. Current = %d, Requested = %d", hw_panel_info_.mode,
           hw_display_mode);
     return kErrorNone;
   }
 
   error = hw_primary_intf_->SetDisplayMode(hw_display_mode);
   if (error != kErrorNone) {
-    DLOGW("Retaining current display mode. Current (%d), Requested (%d)", hw_panel_info_.mode,
+    DLOGW("Retaining current display mode. Current = %d, Requested = %d", hw_panel_info_.mode,
           hw_display_mode);
     return error;
   }
diff --git a/sdm/libs/core/display_primary.h b/sdm/libs/core/display_primary.h
index 2cbae4b..b232d89 100644
--- a/sdm/libs/core/display_primary.h
+++ b/sdm/libs/core/display_primary.h
@@ -31,7 +31,6 @@
 namespace sdm {
 
 class HWPrimaryInterface;
-class HWInfoInterface;
 
 class DisplayPrimary : public DisplayBase, DumpImpl, HWEventHandler {
  public:
@@ -70,7 +69,6 @@
  private:
   Locker locker_;
   HWPrimaryInterface *hw_primary_intf_;
-  HWInfoInterface *hw_info_intf_;
 };
 
 }  // namespace sdm
diff --git a/sdm/libs/core/display_virtual.cpp b/sdm/libs/core/display_virtual.cpp
index 262db7f..f01ff58 100644
--- a/sdm/libs/core/display_virtual.cpp
+++ b/sdm/libs/core/display_virtual.cpp
@@ -37,7 +37,7 @@
                                BufferSyncHandler *buffer_sync_handler, CompManager *comp_manager,
                                RotatorInterface *rotator_intf)
   : DisplayBase(kVirtual, event_handler, kDeviceVirtual, buffer_sync_handler, comp_manager,
-                rotator_intf), hw_info_intf_(hw_info_intf) {
+                rotator_intf, hw_info_intf) {
 }
 
 DisplayError DisplayVirtual::Init() {
diff --git a/sdm/libs/core/display_virtual.h b/sdm/libs/core/display_virtual.h
index 2065534..6152f69 100644
--- a/sdm/libs/core/display_virtual.h
+++ b/sdm/libs/core/display_virtual.h
@@ -31,7 +31,6 @@
 namespace sdm {
 
 class HWVirtualInterface;
-class HWInfoInterface;
 
 class DisplayVirtual : public DisplayBase, DumpImpl {
  public:
@@ -64,7 +63,6 @@
  private:
   Locker locker_;
   HWVirtualInterface *hw_virtual_intf_;
-  HWInfoInterface *hw_info_intf_;
 };
 
 }  // namespace sdm
diff --git a/sdm/libs/core/dump_impl.h b/sdm/libs/core/dump_impl.h
index 123c568..68e7584 100644
--- a/sdm/libs/core/dump_impl.h
+++ b/sdm/libs/core/dump_impl.h
@@ -49,7 +49,7 @@
   static DumpImpl *dump_list_[kMaxDumpObjects];
   static uint32_t dump_count_;
 
-  friend DumpInterface;
+  friend class DumpInterface;
 };
 
 }  // namespace sdm
diff --git a/sdm/libs/core/fb/hw_device.cpp b/sdm/libs/core/fb/hw_device.cpp
index b905c31..31b3da9 100644
--- a/sdm/libs/core/fb/hw_device.cpp
+++ b/sdm/libs/core/fb/hw_device.cpp
@@ -31,6 +31,8 @@
 #include <ctype.h>
 #include <math.h>
 #include <fcntl.h>
+#include <unistd.h>
+#include <string.h>
 #include <inttypes.h>
 #include <sys/types.h>
 #include <sys/stat.h>
@@ -43,23 +45,12 @@
 
 #define __CLASS__ "HWDevice"
 
-#ifdef DISPLAY_CORE_VIRTUAL_DRIVER
-extern int virtual_ioctl(int fd, int cmd, ...);
-extern int virtual_open(const char *file_name, int access, ...);
-extern int virtual_close(int fd);
-extern int virtual_poll(struct pollfd *fds,  nfds_t num, int timeout);
-extern ssize_t virtual_pread(int fd, void *data, size_t count, off_t offset);
-extern ssize_t virtual_pwrite(int fd, const void *data, size_t count, off_t offset);
-extern FILE* virtual_fopen(const char *fname, const char *mode);
-extern int virtual_fclose(FILE* fileptr);
-extern ssize_t virtual_getline(char **lineptr, size_t *linelen, FILE *stream);
-#endif
-
 namespace sdm {
 
 HWDevice::HWDevice(BufferSyncHandler *buffer_sync_handler)
   : fb_node_index_(-1), fb_path_("/sys/devices/virtual/graphics/fb"), hotplug_enabled_(false),
     buffer_sync_handler_(buffer_sync_handler), synchronous_commit_(false) {
+#ifndef SDM_VIRTUAL_DRIVER
   // Pointer to actual driver interfaces.
   ioctl_ = ::ioctl;
   open_ = ::open;
@@ -70,20 +61,27 @@
   fopen_ = ::fopen;
   fclose_ = ::fclose;
   getline_ = ::getline;
+#else
+  // Point to virtual driver interfaces.
+  extern int virtual_ioctl(int fd, int cmd, ...);
+  extern int virtual_open(const char *file_name, int access, ...);
+  extern int virtual_close(int fd);
+  extern int virtual_poll(struct pollfd *fds,  nfds_t num, int timeout);
+  extern ssize_t virtual_pread(int fd, void *data, size_t count, off_t offset);
+  extern ssize_t virtual_pwrite(int fd, const void *data, size_t count, off_t offset);
+  extern FILE* virtual_fopen(const char *fname, const char *mode);
+  extern int virtual_fclose(FILE* fileptr);
+  extern ssize_t virtual_getline(char **lineptr, size_t *linelen, FILE *stream);
 
-#ifdef DISPLAY_CORE_VIRTUAL_DRIVER
-  // If debug property to use virtual driver is set, point to virtual driver interfaces.
-  if (Debug::IsVirtualDriver()) {
-    ioctl_ = virtual_ioctl;
-    open_ = virtual_open;
-    close_ = virtual_close;
-    poll_ = virtual_poll;
-    pread_ = virtual_pread;
-    pwrite_ = virtual_pwrite;
-    fopen_ = virtual_fopen;
-    fclose_ = virtual_fclose;
-    getline_ = virtual_getline;
-  }
+  ioctl_ = virtual_ioctl;
+  open_ = virtual_open;
+  close_ = virtual_close;
+  poll_ = virtual_poll;
+  pread_ = virtual_pread;
+  pwrite_ = virtual_pwrite;
+  fopen_ = virtual_fopen;
+  fclose_ = virtual_fclose;
+  getline_ = virtual_getline;
 #endif
 }
 
@@ -444,23 +442,12 @@
     uint32_t layer_index = hw_layer_info.index[i];
     LayerBuffer *input_buffer = stack->layers[layer_index].input_buffer;
     HWRotatorSession *hw_rotator_session = &hw_layers->config[i].hw_rotator_session;
-    HWRotateInfo *left_rotate = &hw_rotator_session->hw_rotate_info[0];
-    HWRotateInfo *right_rotate = &hw_rotator_session->hw_rotate_info[1];
 
-    if (!left_rotate->valid && !right_rotate->valid) {
-      input_buffer->release_fence_fd = dup(mdp_commit.release_fence);
-      continue;
+    if (hw_rotator_session->hw_block_count) {
+      input_buffer = &hw_rotator_session->output_buffer;
     }
 
-    for (uint32_t count = 0; count < 2; count++) {
-      HWRotateInfo *hw_rotate_info = &hw_rotator_session->hw_rotate_info[count];
-      if (hw_rotate_info->valid) {
-        input_buffer = &hw_rotator_session->output_buffer;
-        input_buffer->release_fence_fd = dup(mdp_commit.release_fence);
-        close_(input_buffer->acquire_fence_fd);
-        input_buffer->acquire_fence_fd = -1;
-      }
-    }
+    input_buffer->release_fence_fd = dup(mdp_commit.release_fence);
   }
   DLOGI_IF(kTagDriverConfig, "*************************** %s Commit Input ************************",
            device_name_);
@@ -725,7 +712,7 @@
       } else if (!strncmp(tokens[0], "min_fps", strlen("min_fps"))) {
         panel_info->min_fps = atoi(tokens[1]);
       } else if (!strncmp(tokens[0], "max_fps", strlen("max_fps"))) {
-        panel_info->max_fps= atoi(tokens[1]);
+        panel_info->max_fps = atoi(tokens[1]);
       } else if (!strncmp(tokens[0], "primary_panel", strlen("primary_panel"))) {
         panel_info->is_primary_panel = atoi(tokens[1]);
       }
diff --git a/sdm/libs/core/fb/hw_hdmi.cpp b/sdm/libs/core/fb/hw_hdmi.cpp
index 1a5c538..3df8e38 100644
--- a/sdm/libs/core/fb/hw_hdmi.cpp
+++ b/sdm/libs/core/fb/hw_hdmi.cpp
@@ -27,6 +27,8 @@
 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
 
+#include <unistd.h>
+#include <string.h>
 #include <sys/ioctl.h>
 #include <ctype.h>
 #include <utils/debug.h>
@@ -221,8 +223,9 @@
   }
   display_attributes->x_pixels = timing_mode->active_h;
   display_attributes->y_pixels = timing_mode->active_v;
-  display_attributes->v_total = timing_mode->active_v + timing_mode->front_porch_v +
-      timing_mode->back_porch_v + timing_mode->pulse_width_v;
+  display_attributes->v_front_porch = timing_mode->front_porch_v;
+  display_attributes->v_back_porch = timing_mode->back_porch_v;
+  display_attributes->v_pulse_width = timing_mode->pulse_width_v;
   uint32_t h_blanking = timing_mode->front_porch_h + timing_mode->back_porch_h +
       timing_mode->pulse_width_h;
   display_attributes->h_total = timing_mode->active_h + h_blanking;
@@ -382,7 +385,7 @@
 void HWHDMI::ReadScanInfo() {
   int scan_info_file = -1;
   ssize_t len = -1;
-  char data[PAGE_SIZE] = {'\0'};
+  char data[4096] = {'\0'};
 
   snprintf(data, sizeof(data), "%s%d/scan_info", fb_path_, fb_node_index_);
   scan_info_file = open_(data, O_RDONLY);
diff --git a/sdm/libs/core/fb/hw_info.cpp b/sdm/libs/core/fb/hw_info.cpp
index b998a46..c3fb41d 100644
--- a/sdm/libs/core/fb/hw_info.cpp
+++ b/sdm/libs/core/fb/hw_info.cpp
@@ -23,6 +23,7 @@
 */
 
 #include "hw_info.h"
+#include <string.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <fcntl.h>
@@ -131,6 +132,16 @@
         hw_resource->max_sde_clk = atoi(tokens[1]);
       } else if (!strncmp(tokens[0], "clk_fudge_factor", strlen("clk_fudge_factor"))) {
         hw_resource->clk_fudge_factor = FLOAT(atoi(tokens[1])) / FLOAT(atoi(tokens[2]));
+      } else if (!strncmp(tokens[0], "fmt_mt_nv12_factor", strlen("fmt_mt_nv12_factor"))) {
+        hw_resource->macrotile_nv12_factor = atoi(tokens[1]);
+      } else if (!strncmp(tokens[0], "fmt_mt_factor", strlen("fmt_mt_factor"))) {
+        hw_resource->macrotile_factor = atoi(tokens[1]);
+      } else if (!strncmp(tokens[0], "fmt_linear_factor", strlen("fmt_linear_factor"))) {
+        hw_resource->linear_factor = atoi(tokens[1]);
+      } else if (!strncmp(tokens[0], "scale_factor", strlen("scale_factor"))) {
+        hw_resource->scale_factor = atoi(tokens[1]);
+      } else if (!strncmp(tokens[0], "xtra_ff_factor", strlen("xtra_ff_factor"))) {
+        hw_resource->extra_fudge_factor = atoi(tokens[1]);
       } else if (!strncmp(tokens[0], "features", strlen("features"))) {
         for (uint32_t i = 0; i < token_count; i++) {
           if (!strncmp(tokens[i], "bwc", strlen("bwc"))) {
@@ -165,6 +176,9 @@
         hw_resource->max_bandwidth_high);
   DLOGI("MaxPipeBw = %"PRIu64" KBps, MaxSDEClock = %"PRIu64" Hz, ClockFudgeFactor = %f",
         hw_resource->max_pipe_bw, hw_resource->max_sde_clk, hw_resource->clk_fudge_factor);
+  DLOGI("Prefill factors: Tiled_NV12 = %d, Tiled = %d, Linear = %d, Scale = %d, Fudge_factor = %d",
+        hw_resource->macrotile_nv12_factor, hw_resource->macrotile_factor,
+        hw_resource->linear_factor, hw_resource->scale_factor, hw_resource->extra_fudge_factor);
 
   return kErrorNone;
 }
diff --git a/sdm/libs/core/fb/hw_info.h b/sdm/libs/core/fb/hw_info.h
index 95f669f..350c6ff 100644
--- a/sdm/libs/core/fb/hw_info.h
+++ b/sdm/libs/core/fb/hw_info.h
@@ -25,7 +25,6 @@
 #ifndef __HW_INFO_H__
 #define __HW_INFO_H__
 
-#include <inttypes.h>
 #include <core/sdm_types.h>
 #include <private/hw_info_types.h>
 #include "hw_info_interface.h"
diff --git a/sdm/libs/core/fb/hw_primary.cpp b/sdm/libs/core/fb/hw_primary.cpp
index cb4d8b2..284cb67 100644
--- a/sdm/libs/core/fb/hw_primary.cpp
+++ b/sdm/libs/core/fb/hw_primary.cpp
@@ -27,11 +27,14 @@
 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
 
+#include <unistd.h>
+#include <string.h>
+#include <pthread.h>
+#include <fcntl.h>
 #include <sys/prctl.h>
 #include <sys/ioctl.h>
-#include <pthread.h>
+#include <sys/time.h>
 #include <sys/resource.h>
-#include <fcntl.h>
 #include <utils/debug.h>
 #include "hw_primary.h"
 
@@ -204,12 +207,12 @@
 
   display_attributes_.x_pixels = var_screeninfo.xres;
   display_attributes_.y_pixels = var_screeninfo.yres;
-  display_attributes_.v_total = var_screeninfo.yres + var_screeninfo.lower_margin +
-      var_screeninfo.upper_margin + var_screeninfo.vsync_len;
+  display_attributes_.v_front_porch = var_screeninfo.lower_margin;
+  display_attributes_.v_back_porch = var_screeninfo.upper_margin;
+  display_attributes_.v_pulse_width = var_screeninfo.vsync_len;
   uint32_t h_blanking = var_screeninfo.right_margin + var_screeninfo.left_margin +
       var_screeninfo.hsync_len;
-  display_attributes_.h_total = var_screeninfo.xres + var_screeninfo.right_margin +
-      var_screeninfo.left_margin + var_screeninfo.hsync_len;
+  display_attributes_.h_total = var_screeninfo.xres + h_blanking;
   display_attributes_.x_dpi =
       (FLOAT(var_screeninfo.xres) * 25.4f) / FLOAT(var_screeninfo.width);
   display_attributes_.y_dpi =
diff --git a/sdm/libs/core/strategy.cpp b/sdm/libs/core/strategy.cpp
index 16e3f63..183384e 100644
--- a/sdm/libs/core/strategy.cpp
+++ b/sdm/libs/core/strategy.cpp
@@ -34,7 +34,7 @@
 Strategy::Strategy(ExtensionInterface *extension_intf, DisplayType type,
                    const HWResourceInfo &hw_resource_info, const HWPanelInfo &hw_panel_info)
   : extension_intf_(extension_intf), strategy_intf_(NULL), partial_update_intf_(NULL),
-    display_type_(type),hw_resource_info_(hw_resource_info), hw_panel_info_(hw_panel_info),
+    display_type_(type), hw_resource_info_(hw_resource_info), hw_panel_info_(hw_panel_info),
     hw_layers_info_(NULL), fb_layer_index_(0), extn_start_success_(false), tried_default_(false) {
 }
 
diff --git a/sdm/libs/hwc/hwc_buffer_allocator.cpp b/sdm/libs/hwc/hwc_buffer_allocator.cpp
index 2d79f0d..d0fdc8c 100644
--- a/sdm/libs/hwc/hwc_buffer_allocator.cpp
+++ b/sdm/libs/hwc/hwc_buffer_allocator.cpp
@@ -115,36 +115,35 @@
   int ret = 0;
 
   AllocatedBufferInfo *alloc_buffer_info = &buffer_info->alloc_buffer_info;
-  MetaBufferInfo *meta_buffer_info = static_cast<MetaBufferInfo *> (buffer_info->private_data);
-  if (alloc_buffer_info->fd < 0) {
-    DLOGE("Invalid parameters: fd %d", alloc_buffer_info->fd);
-    return kErrorParameters;
+
+  // Deallocate the buffer, only if the buffer fd is valid.
+  if (alloc_buffer_info->fd > 0) {
+    MetaBufferInfo *meta_buffer_info = static_cast<MetaBufferInfo *> (buffer_info->private_data);
+    gralloc::IMemAlloc *memalloc = alloc_controller_->getAllocator(meta_buffer_info->alloc_type);
+    if (memalloc == NULL) {
+      DLOGE("Memalloc handle is NULL, alloc type %d", meta_buffer_info->alloc_type);
+      return kErrorResources;
+    }
+
+    ret = memalloc->free_buffer(meta_buffer_info->base_addr, alloc_buffer_info->size, 0,
+                                alloc_buffer_info->fd);
+    if (ret != 0) {
+      DLOGE("Error freeing buffer base_addr %p size %d fd %d", meta_buffer_info->base_addr,
+            alloc_buffer_info->size, alloc_buffer_info->fd);
+      return kErrorMemory;
+    }
+
+    alloc_buffer_info->fd = -1;
+    alloc_buffer_info->stride = 0;
+    alloc_buffer_info->size = 0;
+
+    meta_buffer_info->base_addr = NULL;
+    meta_buffer_info->alloc_type = 0;
+
+    delete meta_buffer_info;
+    meta_buffer_info = NULL;
   }
 
-  gralloc::IMemAlloc *memalloc = alloc_controller_->getAllocator(meta_buffer_info->alloc_type);
-  if (memalloc == NULL) {
-    DLOGE("Memalloc handle is NULL, alloc type %d", meta_buffer_info->alloc_type);
-    return kErrorResources;
-  }
-
-  ret = memalloc->free_buffer(meta_buffer_info->base_addr, alloc_buffer_info->size, 0,
-                              alloc_buffer_info->fd);
-  if (ret != 0) {
-    DLOGE("Error freeing buffer base_addr %p size %d fd %d", meta_buffer_info->base_addr,
-          alloc_buffer_info->size, alloc_buffer_info->fd);
-    return kErrorMemory;
-  }
-
-  alloc_buffer_info->fd = -1;
-  alloc_buffer_info->stride = 0;
-  alloc_buffer_info->size = 0;
-
-  meta_buffer_info->base_addr = NULL;
-  meta_buffer_info->alloc_type = 0;
-
-  delete meta_buffer_info;
-  meta_buffer_info = NULL;
-
   return kErrorNone;
 }
 
diff --git a/sdm/libs/hwc/hwc_debugger.cpp b/sdm/libs/hwc/hwc_debugger.cpp
index ab9309e..6cbce3e 100644
--- a/sdm/libs/hwc/hwc_debugger.cpp
+++ b/sdm/libs/hwc/hwc_debugger.cpp
@@ -28,6 +28,7 @@
 */
 
 #include <utils/constants.h>
+#include <cutils/properties.h>
 
 #include "hwc_debugger.h"
 
@@ -123,5 +124,16 @@
   atrace_end(ATRACE_TAG);
 }
 
+DisplayError HWCDebugHandler::GetProperty(const char *property_name, int *value) {
+  char property[PROPERTY_VALUE_MAX];
+
+  if (property_get(property_name, property, NULL) > 0) {
+    *value = atoi(property);
+    return kErrorNone;
+  }
+
+  return kErrorNotSupported;
+}
+
 }  // namespace sdm
 
diff --git a/sdm/libs/hwc/hwc_debugger.h b/sdm/libs/hwc/hwc_debugger.h
index 61a1b6f..480db22 100644
--- a/sdm/libs/hwc/hwc_debugger.h
+++ b/sdm/libs/hwc/hwc_debugger.h
@@ -68,6 +68,7 @@
   virtual void BeginTrace(const char *class_name, const char *function_name,
                           const char *custom_string);
   virtual void EndTrace();
+  virtual DisplayError GetProperty(const char *property_name, int *value);
 
  private:
   static HWCDebugHandler debug_handler_;
diff --git a/sdm/libs/hwc/hwc_display.cpp b/sdm/libs/hwc/hwc_display.cpp
index 0278c90..24bfcaa 100644
--- a/sdm/libs/hwc/hwc_display.cpp
+++ b/sdm/libs/hwc/hwc_display.cpp
@@ -30,6 +30,7 @@
 #include <math.h>
 #include <errno.h>
 #include <gralloc_priv.h>
+#include <gr.h>
 #include <utils/constants.h>
 #include <qdMetaData.h>
 #include <sync/sync.h>
@@ -45,7 +46,7 @@
 HWCDisplay::HWCDisplay(CoreInterface *core_intf, hwc_procs_t const **hwc_procs, DisplayType type,
                        int id)
   : core_intf_(core_intf), hwc_procs_(hwc_procs), type_(type), id_(id), display_intf_(NULL),
-    flush_(false), output_buffer_(NULL), dump_frame_count_(0), dump_frame_index_(0),
+    flush_(false), dump_frame_count_(0), dump_frame_index_(0),
     dump_input_layers_(false), swap_interval_zero_(false), framebuffer_config_(NULL),
     display_paused_(false), use_metadata_refresh_rate_(false), metadata_refresh_rate_(0) {
 }
@@ -58,9 +59,9 @@
     return -EINVAL;
   }
 
-  char property[PROPERTY_VALUE_MAX];
-  if (property_get("debug.egl.swapinterval", property, "1") > 0) {
-    if (atoi(property) == 0) {
+  int property_swap_interval = 1;
+  if (HWCDebugHandler::Get()->GetProperty("debug.egl.swapinterval", &property_swap_interval)) {
+    if (property_swap_interval == 0) {
       swap_interval_zero_ = true;
     }
   }
@@ -213,10 +214,6 @@
   return index;
 }
 
-int HWCDisplay::SetActiveConfig(hwc_display_contents_1_t *content_list) {
-  return 0;
-}
-
 int HWCDisplay::SetActiveConfig(int index) {
   DisplayError error = kErrorNone;
 
@@ -330,6 +327,87 @@
   return 0;
 }
 
+int HWCDisplay::PrepareLayerParams(hwc_layer_1_t *hwc_layer, Layer *layer, uint32_t fps) {
+  const private_handle_t *pvt_handle = static_cast<const private_handle_t *>(hwc_layer->handle);
+
+  LayerBuffer *layer_buffer = layer->input_buffer;
+
+  if (pvt_handle) {
+    layer_buffer->format = GetSDMFormat(pvt_handle->format, pvt_handle->flags);
+    if (layer_buffer->format == kFormatInvalid) {
+      return -EINVAL;
+    }
+
+    layer_buffer->width = pvt_handle->width;
+    layer_buffer->height = pvt_handle->height;
+    if (pvt_handle->bufferType == BUFFER_TYPE_VIDEO) {
+      layer_stack_.flags.video_present = true;
+      layer_buffer->flags.video = true;
+    }
+    if (pvt_handle->flags & private_handle_t::PRIV_FLAGS_SECURE_BUFFER) {
+      layer_stack_.flags.secure_present = true;
+      layer_buffer->flags.secure = true;
+    }
+
+    layer->frame_rate = fps;
+    MetaData_t *meta_data = reinterpret_cast<MetaData_t *>(pvt_handle->base_metadata);
+    if (meta_data && meta_data->operation & UPDATE_REFRESH_RATE) {
+      layer->frame_rate = RoundToStandardFPS(meta_data->refreshrate);
+    }
+
+    if (meta_data && meta_data->operation == PP_PARAM_INTERLACED && meta_data->interlaced) {
+      layer_buffer->flags.interlace = true;
+    }
+
+    if (pvt_handle->flags & private_handle_t::PRIV_FLAGS_SECURE_DISPLAY) {
+      layer_buffer->flags.secure_display = true;
+    }
+  } else {
+    // for FBT layer
+    if (hwc_layer->compositionType == HWC_FRAMEBUFFER_TARGET) {
+      uint32_t x_pixels;
+      uint32_t y_pixels;
+      int aligned_width;
+      int aligned_height;
+      int usage = GRALLOC_USAGE_HW_FB;
+      int format = HAL_PIXEL_FORMAT_RGBA_8888;
+      int ubwc_enabled = 0;
+      HWCDebugHandler::Get()->GetProperty("debug.gralloc.enable_fb_ubwc", &ubwc_enabled);
+      if (ubwc_enabled == 1) {
+        usage |= GRALLOC_USAGE_PRIVATE_ALLOC_UBWC;
+      }
+
+      GetFrameBufferResolution(&x_pixels, &y_pixels);
+
+      AdrenoMemInfo::getInstance().getAlignedWidthAndHeight(INT(x_pixels), INT(y_pixels), format,
+                                                            usage, aligned_width, aligned_height);
+      layer_buffer->width = aligned_width;
+      layer_buffer->height = aligned_height;
+      layer->frame_rate = fps;
+    }
+  }
+
+  return 0;
+}
+
+void HWCDisplay::CommitLayerParams(hwc_layer_1_t *hwc_layer, Layer *layer) {
+  const private_handle_t *pvt_handle = static_cast<const private_handle_t *>(hwc_layer->handle);
+  LayerBuffer *layer_buffer = layer->input_buffer;
+
+  if (pvt_handle) {
+    layer_buffer->planes[0].fd = pvt_handle->fd;
+    layer_buffer->planes[0].offset = pvt_handle->offset;
+    layer_buffer->planes[0].stride = pvt_handle->width;
+  }
+
+  // if swapinterval property is set to 0 then close and reset the acquireFd
+  if (swap_interval_zero_ && hwc_layer->acquireFenceFd >= 0) {
+    close(hwc_layer->acquireFenceFd);
+    hwc_layer->acquireFenceFd = -1;
+  }
+  layer_buffer->acquire_fence_fd = hwc_layer->acquireFenceFd;
+}
+
 int HWCDisplay::PrepareLayerStack(hwc_display_contents_1_t *content_list) {
   if (!content_list || !content_list->numHwLayers) {
     DLOGW("Invalid content list");
@@ -345,6 +423,7 @@
   DisplayConfigVariableInfo active_config;
   uint32_t active_config_index = 0;
   display_intf_->GetActiveConfig(&active_config_index);
+  int ret;
 
   display_intf_->GetConfig(active_config_index, &active_config);
 
@@ -356,36 +435,11 @@
     Layer &layer = layer_stack_.layers[i];
     LayerBuffer *layer_buffer = layer.input_buffer;
 
-    if (pvt_handle) {
-      layer_buffer->format = GetSDMFormat(pvt_handle->format, pvt_handle->flags);
-      if (layer_buffer->format == kFormatInvalid) {
-        return -EINVAL;
-      }
+    ret = PrepareLayerParams(&content_list->hwLayers[i], &layer_stack_.layers[i],
+                             active_config.fps);
 
-      layer_buffer->width = pvt_handle->width;
-      layer_buffer->height = pvt_handle->height;
-      if (pvt_handle->bufferType == BUFFER_TYPE_VIDEO) {
-        layer_stack_.flags.video_present = true;
-        layer_buffer->flags.video = true;
-      }
-      if (pvt_handle->flags & private_handle_t::PRIV_FLAGS_SECURE_BUFFER) {
-        layer_stack_.flags.secure_present = true;
-        layer_buffer->flags.secure = true;
-      }
-
-      layer.frame_rate = UINT32(active_config.fps);
-      MetaData_t *meta_data = reinterpret_cast<MetaData_t *>(pvt_handle->base_metadata);
-      if (meta_data && meta_data->operation & UPDATE_REFRESH_RATE) {
-        layer.frame_rate = RoundToStandardFPS(meta_data->refreshrate);
-      }
-
-      if (meta_data && meta_data->operation == PP_PARAM_INTERLACED && meta_data->interlaced) {
-        layer_buffer->flags.interlace = true;
-      }
-
-      if (pvt_handle->flags & private_handle_t::PRIV_FLAGS_SECURE_DISPLAY) {
-        layer_buffer->flags.secure_display = true;
-      }
+    if (ret != kErrorNone) {
+      return ret;
     }
 
     hwc_rect_t scaled_display_frame = hwc_layer.displayFrame;
@@ -395,7 +449,7 @@
     SetRect(scaled_display_frame, &layer.dst_rect);
     SetRect(hwc_layer.sourceCropf, &layer.src_rect);
     for (size_t j = 0; j < hwc_layer.visibleRegionScreen.numRects; j++) {
-        SetRect(hwc_layer.visibleRegionScreen.rects[j], &layer.visible_regions.rect[j]);
+      SetRect(hwc_layer.visibleRegionScreen.rects[j], &layer.visible_regions.rect[j]);
     }
     SetRect(hwc_layer.dirtyRect, &layer.dirty_regions.rect[0]);
     SetComposition(hwc_layer.compositionType, &layer.composition);
@@ -409,7 +463,11 @@
 
     layer.plane_alpha = hwc_layer.planeAlpha;
     layer.flags.skip = ((hwc_layer.flags & HWC_SKIP_LAYER) > 0);
-    layer.flags.updating = (layer_stack_cache_.layer_cache[i].handle != hwc_layer.handle);
+    if (num_hw_layers <= kMaxLayerCount) {
+      layer.flags.updating = (layer_stack_cache_.layer_cache[i].handle != hwc_layer.handle);
+    } else {
+      layer.flags.updating = true;
+    }
 
     if (hwc_layer.flags & HWC_SCREENSHOT_ANIMATOR_LAYER) {
       layer_stack_.flags.animating = true;
@@ -480,22 +538,7 @@
 
   if (!flush_) {
     for (size_t i = 0; i < num_hw_layers; i++) {
-      hwc_layer_1_t &hwc_layer = content_list->hwLayers[i];
-      const private_handle_t *pvt_handle = static_cast<const private_handle_t *>(hwc_layer.handle);
-      LayerBuffer *layer_buffer = layer_stack_.layers[i].input_buffer;
-
-      if (pvt_handle) {
-        layer_buffer->planes[0].fd = pvt_handle->fd;
-        layer_buffer->planes[0].offset = pvt_handle->offset;
-        layer_buffer->planes[0].stride = pvt_handle->width;
-      }
-
-      // if swapinterval property is set to 0 then close and reset the acquireFd
-      if (swap_interval_zero_ && hwc_layer.acquireFenceFd >= 0) {
-        close(hwc_layer.acquireFenceFd);
-        hwc_layer.acquireFenceFd = -1;
-      }
-      layer_buffer->acquire_fence_fd = hwc_layer.acquireFenceFd;
+      CommitLayerParams(&content_list->hwLayers[i], &layer_stack_.layers[i]);
     }
 
     DisplayError error = display_intf_->Commit(&layer_stack_);
@@ -617,6 +660,10 @@
 void HWCDisplay::CacheLayerStackInfo(hwc_display_contents_1_t *content_list) {
   uint32_t layer_count = layer_stack_.layer_count;
 
+  if (layer_count > kMaxLayerCount) {
+    return;
+  }
+
   for (uint32_t i = 0; i < layer_count; i++) {
     Layer &layer = layer_stack_.layers[i];
 
diff --git a/sdm/libs/hwc/hwc_display.h b/sdm/libs/hwc/hwc_display.h
index 2df0928..b20b00b 100644
--- a/sdm/libs/hwc/hwc_display.h
+++ b/sdm/libs/hwc/hwc_display.h
@@ -42,7 +42,6 @@
   virtual int GetDisplayAttributes(uint32_t config, const uint32_t *attributes, int32_t *values);
   virtual int GetActiveConfig();
   virtual int SetActiveConfig(int index);
-  virtual int SetActiveConfig(hwc_display_contents_1_t *content_list);
   virtual void SetIdleTimeoutMs(uint32_t timeout_ms);
   virtual void SetFrameDumpConfig(uint32_t count, uint32_t bit_mask_layer_type);
   virtual DisplayError SetMaxMixerStages(uint32_t max_mixer_stages);
@@ -51,6 +50,8 @@
   virtual void GetFrameBufferResolution(uint32_t *x_pixels, uint32_t *y_pixels);
   virtual void GetPanelResolution(uint32_t *x_pixels, uint32_t *y_pixels);
   virtual int SetDisplayStatus(uint32_t display_status);
+  virtual int Perform(uint32_t operation, ...);
+  virtual ~HWCDisplay() { }
 
  protected:
   enum DisplayStatus {
@@ -88,7 +89,6 @@
   };
 
   HWCDisplay(CoreInterface *core_intf, hwc_procs_t const **hwc_procs, DisplayType type, int id);
-  virtual ~HWCDisplay() { }
 
   // DisplayEventHandler methods
   virtual DisplayError VSync(const DisplayEventVSync &vsync);
@@ -98,7 +98,6 @@
   virtual int PrepareLayerStack(hwc_display_contents_1_t *content_list);
   virtual int CommitLayerStack(hwc_display_contents_1_t *content_list);
   virtual int PostCommitLayerStack(hwc_display_contents_1_t *content_list);
-  bool NeedsFrameBufferRefresh(hwc_display_contents_1_t *content_list);
   void CacheLayerStackInfo(hwc_display_contents_1_t *content_list);
   inline void SetRect(const hwc_rect_t &source, LayerRect *target);
   inline void SetRect(const hwc_frect_t &source, LayerRect *target);
@@ -107,11 +106,9 @@
   inline void SetBlending(const int32_t &source, LayerBlending *target);
   int SetFormat(const int32_t &source, const int flags, LayerBufferFormat *target);
   LayerBufferFormat GetSDMFormat(const int32_t &source, const int flags);
-  void DumpInputBuffers(hwc_display_contents_1_t *content_list);
   const char *GetHALPixelFormatString(int format);
   const char *GetDisplayString();
   void ScaleDisplayFrame(hwc_rect_t *display_frame);
-  bool IsFrameBufferScaled();
   void MarkLayersForGPUBypass(hwc_display_contents_1_t *content_list);
   void CloseAcquireFences(hwc_display_contents_1_t *content_list);
   uint32_t RoundToStandardFPS(uint32_t fps);
@@ -131,7 +128,6 @@
   LayerStack layer_stack_;
   LayerStackCache layer_stack_cache_;
   bool flush_;
-  LayerBuffer *output_buffer_;
   uint32_t dump_frame_count_;
   uint32_t dump_frame_index_;
   bool dump_input_layers_;
@@ -141,8 +137,19 @@
   bool display_paused_;
   bool use_metadata_refresh_rate_;
   uint32_t metadata_refresh_rate_;
+
+ private:
+  bool IsFrameBufferScaled();
+  void DumpInputBuffers(hwc_display_contents_1_t *content_list);
+  bool NeedsFrameBufferRefresh(hwc_display_contents_1_t *content_list);
+  int PrepareLayerParams(hwc_layer_1_t *hwc_layer, Layer *layer, uint32_t fps);
+  void CommitLayerParams(hwc_layer_1_t *hwc_layer, Layer *layer);
 };
 
+inline int HWCDisplay::Perform(uint32_t operation, ...) {
+  return 0;
+}
+
 }  // namespace sdm
 
 #endif  // __HWC_DISPLAY_H__
diff --git a/sdm/libs/hwc/hwc_display_external.cpp b/sdm/libs/hwc/hwc_display_external.cpp
index 52c64d1..c3a07e7 100644
--- a/sdm/libs/hwc/hwc_display_external.cpp
+++ b/sdm/libs/hwc/hwc_display_external.cpp
@@ -37,21 +37,63 @@
 
 namespace sdm {
 
-HWCDisplayExternal::HWCDisplayExternal(CoreInterface *core_intf, hwc_procs_t const **hwc_procs)
-  : HWCDisplay(core_intf, hwc_procs, kHDMI, HWC_DISPLAY_EXTERNAL) {
+static void AdjustSourceResolution(uint32_t dst_width, uint32_t dst_height, uint32_t *src_width,
+                                   uint32_t *src_height) {
+  *src_height = (dst_width * (*src_height)) / (*src_width);
+  *src_width = dst_width;
 }
 
-int HWCDisplayExternal::Init() {
-  int status = 0;
+int HWCDisplayExternal::Create(CoreInterface *core_intf, hwc_procs_t const **hwc_procs,
+                               uint32_t primary_width, uint32_t primary_height,
+                               HWCDisplay **hwc_display) {
+  uint32_t external_width = 0;
+  uint32_t external_height = 0;
+  char property[PROPERTY_VALUE_MAX];
 
-  status = HWCDisplay::Init();
-  if (status != 0) {
+  HWCDisplay *hwc_display_external = new HWCDisplayExternal(core_intf, hwc_procs);
+  int status = hwc_display_external->Init();
+  if (status) {
+    delete hwc_display_external;
     return status;
   }
 
+  hwc_display_external->GetPanelResolution(&external_width, &external_height);
+
+  int downscale_enabled = 0;
+  HWCDebugHandler::Get()->GetProperty("sdm.debug.sde_downscale_enabled", &downscale_enabled);
+  if (downscale_enabled == 1) {
+    uint32_t primary_area = primary_width * primary_height;
+    uint32_t external_area = external_width * external_height;
+
+    if (primary_area > external_area) {
+      if (primary_height > primary_width) {
+        Swap(primary_height, primary_width);
+      }
+      AdjustSourceResolution(primary_width, primary_height,
+                             &external_width, &external_height);
+    }
+  }
+
+  status = hwc_display_external->SetFrameBufferResolution(external_width, external_height);
+  if (status) {
+    Destroy(hwc_display_external);
+    return status;
+  }
+
+  *hwc_display = hwc_display_external;
+
   return status;
 }
 
+void HWCDisplayExternal::Destroy(HWCDisplay *hwc_display) {
+  hwc_display->Deinit();
+  delete hwc_display;
+}
+
+HWCDisplayExternal::HWCDisplayExternal(CoreInterface *core_intf, hwc_procs_t const **hwc_procs)
+  : HWCDisplay(core_intf, hwc_procs, kHDMI, HWC_DISPLAY_EXTERNAL) {
+}
+
 int HWCDisplayExternal::Prepare(hwc_display_contents_1_t *content_list) {
   int status = 0;
 
@@ -109,11 +151,11 @@
   }
 
   // Read user defined width and height ratio
-  char property[PROPERTY_VALUE_MAX];
-  property_get("persist.sys.actionsafe.width", property, "0");
-  float width_ratio = FLOAT(atoi(property)) / 100.0f;
-  property_get("persist.sys.actionsafe.height", property, "0");
-  float height_ratio = FLOAT(atoi(property)) / 100.0f;
+  int width = 0, height = 0;
+  HWCDebugHandler::Get()->GetProperty("sdm.external_action_safe_width", &width);
+  float width_ratio = FLOAT(width) / 100.0f;
+  HWCDebugHandler::Get()->GetProperty("sdm.external_action_safe_height", &height);
+  float height_ratio = FLOAT(height) / 100.0f;
 
   if (width_ratio == 0.0f ||  height_ratio == 0.0f) {
     return;
diff --git a/sdm/libs/hwc/hwc_display_external.h b/sdm/libs/hwc/hwc_display_external.h
index 6d3e229..a98ade3 100644
--- a/sdm/libs/hwc/hwc_display_external.h
+++ b/sdm/libs/hwc/hwc_display_external.h
@@ -31,13 +31,16 @@
 
 class HWCDisplayExternal : public HWCDisplay {
  public:
-  explicit HWCDisplayExternal(CoreInterface *core_intf, hwc_procs_t const **hwc_procs);
-  virtual int Init();
+  static int Create(CoreInterface *core_intf, hwc_procs_t const **hwc_procs, uint32_t primary_width,
+                    uint32_t primary_height, HWCDisplay **hwc_display);
+  static void Destroy(HWCDisplay *hwc_display);
   virtual int Prepare(hwc_display_contents_1_t *content_list);
   virtual int Commit(hwc_display_contents_1_t *content_list);
   virtual int GetDisplayConfigs(uint32_t *configs, size_t *num_configs);
+
  private:
-  virtual void ApplyScanAdjustment(hwc_rect_t *display_frame);
+  HWCDisplayExternal(CoreInterface *core_intf, hwc_procs_t const **hwc_procs);
+  void ApplyScanAdjustment(hwc_rect_t *display_frame);
 };
 
 }  // namespace sdm
diff --git a/sdm/libs/hwc/hwc_display_primary.cpp b/sdm/libs/hwc/hwc_display_primary.cpp
index 53110ca..60505b0 100644
--- a/sdm/libs/hwc/hwc_display_primary.cpp
+++ b/sdm/libs/hwc/hwc_display_primary.cpp
@@ -27,7 +27,9 @@
 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
 
+#include <cutils/properties.h>
 #include <utils/constants.h>
+#include <stdarg.h>
 
 #include "hwc_display_primary.h"
 #include "hwc_debugger.h"
@@ -36,6 +38,51 @@
 
 namespace sdm {
 
+int HWCDisplayPrimary::Create(CoreInterface *core_intf, hwc_procs_t const **hwc_procs,
+                              HWCDisplay **hwc_display) {
+  int status = 0;
+  uint32_t primary_width = 0;
+  uint32_t primary_height = 0;
+  char property[PROPERTY_VALUE_MAX];
+
+  HWCDisplay *hwc_display_primary = new HWCDisplayPrimary(core_intf, hwc_procs);
+  status = hwc_display_primary->Init();
+  if (status) {
+    delete hwc_display_primary;
+    return status;
+  }
+
+  status = hwc_display_primary->SetPowerMode(HWC_POWER_MODE_NORMAL);
+  if (status) {
+    Destroy(hwc_display_primary);
+    return status;
+  }
+
+  hwc_display_primary->GetPanelResolution(&primary_width, &primary_height);
+  int width = 0, height = 0;
+  HWCDebugHandler::Get()->GetProperty("sdm.fb_size_width", &width);
+  HWCDebugHandler::Get()->GetProperty("sdm.fb_size_height", &height);
+  if (width > 0 && height > 0) {
+    primary_width = width;
+    primary_height = height;
+  }
+
+  status = hwc_display_primary->SetFrameBufferResolution(primary_width, primary_height);
+  if (status) {
+    Destroy(hwc_display_primary);
+    return status;
+  }
+
+  *hwc_display = hwc_display_primary;
+
+  return status;
+}
+
+void HWCDisplayPrimary::Destroy(HWCDisplay *hwc_display) {
+  hwc_display->Deinit();
+  delete hwc_display;
+}
+
 HWCDisplayPrimary::HWCDisplayPrimary(CoreInterface *core_intf, hwc_procs_t const **hwc_procs)
   : HWCDisplay(core_intf, hwc_procs, kPrimary, HWC_DISPLAY_PRIMARY) {
 }
@@ -76,16 +123,6 @@
   return 0;
 }
 
-DisplayError HWCDisplayPrimary::SetDisplayMode(uint32_t mode) {
-  DisplayError error = kErrorNone;
-
-  if (display_intf_) {
-    error = display_intf_->SetDisplayMode(mode);
-  }
-
-  return error;
-}
-
 int HWCDisplayPrimary::SetActiveConfig(uint32_t index) {
   DisplayError error = kErrorNone;
 
@@ -106,6 +143,39 @@
   return error;
 }
 
+int HWCDisplayPrimary::Perform(uint32_t operation, ...) {
+  va_list args;
+  va_start(args, operation);
+  int val = va_arg(args, uint32_t);
+  va_end(args);
+  switch (operation) {
+    case SET_METADATA_DYN_REFRESH_RATE:
+      SetMetaDataRefreshRateFlag(val);
+      break;
+    case SET_BINDER_DYN_REFRESH_RATE:
+      SetRefreshRate(val);
+      break;
+    case SET_DISPLAY_MODE:
+      SetDisplayMode(val);
+      break;
+    default:
+      DLOGW("Invalid operation %d", operation);
+      return -EINVAL;
+  }
+
+  return 0;
+}
+
+DisplayError HWCDisplayPrimary::SetDisplayMode(uint32_t mode) {
+  DisplayError error = kErrorNone;
+
+  if (display_intf_) {
+    error = display_intf_->SetDisplayMode(mode);
+  }
+
+  return error;
+}
+
 void HWCDisplayPrimary::SetMetaDataRefreshRateFlag(bool enable) {
   use_metadata_refresh_rate_ = enable;
 }
diff --git a/sdm/libs/hwc/hwc_display_primary.h b/sdm/libs/hwc/hwc_display_primary.h
index e862508..2b923a3 100644
--- a/sdm/libs/hwc/hwc_display_primary.h
+++ b/sdm/libs/hwc/hwc_display_primary.h
@@ -31,13 +31,25 @@
 
 class HWCDisplayPrimary : public HWCDisplay {
  public:
-  explicit HWCDisplayPrimary(CoreInterface *core_intf, hwc_procs_t const **hwc_procs);
+  enum {
+    SET_METADATA_DYN_REFRESH_RATE,
+    SET_BINDER_DYN_REFRESH_RATE,
+    SET_DISPLAY_MODE,
+  };
+
+  static int Create(CoreInterface *core_intf, hwc_procs_t const **hwc_procs,
+                    HWCDisplay **hwc_display);
+  static void Destroy(HWCDisplay *hwc_display);
   virtual int Prepare(hwc_display_contents_1_t *content_list);
   virtual int Commit(hwc_display_contents_1_t *content_list);
-  virtual DisplayError SetDisplayMode(uint32_t mode);
   virtual int SetActiveConfig(uint32_t index);
   virtual int SetRefreshRate(uint32_t refresh_rate);
-  virtual void SetMetaDataRefreshRateFlag(bool enable);
+  virtual int Perform(uint32_t operation, ...);
+
+ private:
+  HWCDisplayPrimary(CoreInterface *core_intf, hwc_procs_t const **hwc_procs);
+  void SetMetaDataRefreshRateFlag(bool enable);
+  virtual DisplayError SetDisplayMode(uint32_t mode);
 };
 
 }  // namespace sdm
diff --git a/sdm/libs/hwc/hwc_display_virtual.cpp b/sdm/libs/hwc/hwc_display_virtual.cpp
index d36a171..319c0ee 100644
--- a/sdm/libs/hwc/hwc_display_virtual.cpp
+++ b/sdm/libs/hwc/hwc_display_virtual.cpp
@@ -29,6 +29,8 @@
 
 #include <utils/constants.h>
 #include <sync/sync.h>
+#include <stdarg.h>
+#include <gr.h>
 
 #include "hwc_display_virtual.h"
 #include "hwc_debugger.h"
@@ -37,9 +39,67 @@
 
 namespace sdm {
 
+static int GetWidthFromMetaData(const private_handle_t *handle) {
+  MetaData_t *metadata = reinterpret_cast<MetaData_t *>(handle->base_metadata);
+  if (metadata && metadata->operation & UPDATE_BUFFER_GEOMETRY) {
+    return metadata->bufferDim.sliceWidth;
+  }
+
+  return handle->width;
+}
+
+static int GetHeightFromMetaData(const private_handle_t *handle) {
+  MetaData_t *metadata = reinterpret_cast<MetaData_t *>(handle->base_metadata);
+  if (metadata && metadata->operation & UPDATE_BUFFER_GEOMETRY) {
+    return metadata->bufferDim.sliceHeight;
+  }
+
+  return handle->height;
+}
+
+int HWCDisplayVirtual::Create(CoreInterface *core_intf, hwc_procs_t const **hwc_procs,
+                              hwc_display_contents_1_t *content_list,
+                              HWCDisplay **hwc_display) {
+  int status = 0;
+  HWCDisplay *hwc_display_virtual = new HWCDisplayVirtual(core_intf, hwc_procs);
+
+  status = hwc_display_virtual->Init();
+  if (status) {
+    delete hwc_display_virtual;
+    return status;
+  }
+
+  status = hwc_display_virtual->SetPowerMode(HWC_POWER_MODE_NORMAL);
+  if (status) {
+    Destroy(hwc_display_virtual);
+    return status;
+  }
+
+  const private_handle_t *output_handle =
+    static_cast<const private_handle_t *>(content_list->outbuf);
+  int virtual_width = 0;
+  int virtual_height = 0;
+  getBufferSizeAndDimensions(output_handle->width, output_handle->height, output_handle->format,
+                             virtual_width, virtual_height);
+  status = hwc_display_virtual->SetFrameBufferResolution(virtual_width, virtual_height);
+  if (status) {
+    Destroy(hwc_display_virtual);
+    return status;
+  }
+
+  *hwc_display = hwc_display_virtual;
+
+  return status;
+}
+
+void HWCDisplayVirtual::Destroy(HWCDisplay *hwc_display) {
+  hwc_display->Deinit();
+  delete hwc_display;
+}
+
 HWCDisplayVirtual::HWCDisplayVirtual(CoreInterface *core_intf, hwc_procs_t const **hwc_procs)
   : HWCDisplay(core_intf, hwc_procs, kVirtual, HWC_DISPLAY_VIRTUAL),
-    dump_output_layer_(false) {
+    dump_output_layer_(false), output_buffer_(NULL) {
 }
 
 int HWCDisplayVirtual::Init() {
@@ -70,6 +130,12 @@
 
 int HWCDisplayVirtual::Prepare(hwc_display_contents_1_t *content_list) {
   int status = 0;
+
+  status = SetOutputSliceFromMetadata(content_list);
+  if (status) {
+    return status;
+  }
+
   if (display_paused_) {
     MarkLayersForGPUBypass(content_list);
     return status;
@@ -132,7 +198,7 @@
   return 0;
 }
 
-int HWCDisplayVirtual::SetActiveConfig(hwc_display_contents_1_t *content_list) {
+int HWCDisplayVirtual::SetOutputSliceFromMetadata(hwc_display_contents_1_t *content_list) {
   const private_handle_t *output_handle =
         static_cast<const private_handle_t *>(content_list->outbuf);
   DisplayError error = kErrorNone;
@@ -144,8 +210,8 @@
       return -EINVAL;
     }
 
-    int active_width = GetWidth(output_handle);
-    int active_height = GetHeight(output_handle);
+    int active_width = GetWidthFromMetaData(output_handle);
+    int active_height = GetHeightFromMetaData(output_handle);
 
     if ((active_width != INT(output_buffer_->width)) ||
         (active_height!= INT(output_buffer_->height)) ||
@@ -186,8 +252,8 @@
       return -EINVAL;
     }
 
-    output_buffer_->width = GetWidth(output_handle);
-    output_buffer_->height = GetHeight(output_handle);
+    output_buffer_->width = GetWidthFromMetaData(output_handle);
+    output_buffer_->height = GetHeightFromMetaData(output_handle);
     output_buffer_->flags.secure = 0;
     output_buffer_->flags.video = 0;
 
@@ -256,23 +322,5 @@
   DLOGI("output_layer_dump_enable %d", dump_output_layer_);
 }
 
-int HWCDisplayVirtual::GetWidth(const private_handle_t* handle) {
-  MetaData_t *metadata = reinterpret_cast<MetaData_t *>(handle->base_metadata);
-  if (metadata && metadata->operation & UPDATE_BUFFER_GEOMETRY) {
-    return metadata->bufferDim.sliceWidth;
-  }
-
-  return handle->width;
-}
-
-int HWCDisplayVirtual::GetHeight(const private_handle_t* handle) {
-  MetaData_t *metadata = reinterpret_cast<MetaData_t *>(handle->base_metadata);
-  if (metadata && metadata->operation & UPDATE_BUFFER_GEOMETRY) {
-    return metadata->bufferDim.sliceHeight;
-  }
-
-  return handle->height;
-}
-
 }  // namespace sdm
 
diff --git a/sdm/libs/hwc/hwc_display_virtual.h b/sdm/libs/hwc/hwc_display_virtual.h
index 74285d7..e680f71 100644
--- a/sdm/libs/hwc/hwc_display_virtual.h
+++ b/sdm/libs/hwc/hwc_display_virtual.h
@@ -33,23 +33,30 @@
 
 class HWCDisplayVirtual : public HWCDisplay {
  public:
-  explicit HWCDisplayVirtual(CoreInterface *core_intf, hwc_procs_t const **hwc_procs);
+  static int Create(CoreInterface *core_intf, hwc_procs_t const **hwc_procs,
+                    hwc_display_contents_1_t *content_list, HWCDisplay **hwc_display);
+  static void Destroy(HWCDisplay *hwc_display);
+  static bool IsValidContentList(hwc_display_contents_1_t *content_list);
   virtual int Init();
   virtual int Deinit();
   virtual int Prepare(hwc_display_contents_1_t *content_list);
   virtual int Commit(hwc_display_contents_1_t *content_list);
-  virtual int SetActiveConfig(hwc_display_contents_1_t *content_list);
   virtual void SetFrameDumpConfig(uint32_t count, uint32_t bit_mask_layer_type);
 
  private:
+  HWCDisplayVirtual(CoreInterface *core_intf, hwc_procs_t const **hwc_procs);
   int SetOutputBuffer(hwc_display_contents_1_t *content_list);
   void DumpOutputBuffer(hwc_display_contents_1_t *content_list);
-  int GetWidth(const private_handle_t* handle);
-  int GetHeight(const private_handle_t* handle);
+  int SetOutputSliceFromMetadata(hwc_display_contents_1_t *content_list);
 
   bool dump_output_layer_;
+  LayerBuffer *output_buffer_;
 };
 
+inline bool HWCDisplayVirtual::IsValidContentList(hwc_display_contents_1_t *content_list) {
+  return (content_list && content_list->numHwLayers > 0 && content_list->outbuf);
+}
+
 }  // namespace sdm
 
 #endif  // __HWC_DISPLAY_VIRTUAL_H__
diff --git a/sdm/libs/hwc/hwc_session.cpp b/sdm/libs/hwc/hwc_session.cpp
index e5ffda9..b0ff93d 100644
--- a/sdm/libs/hwc/hwc_session.cpp
+++ b/sdm/libs/hwc/hwc_session.cpp
@@ -45,6 +45,8 @@
 #include "hwc_buffer_sync_handler.h"
 #include "hwc_session.h"
 #include "hwc_debugger.h"
+#include "hwc_display_primary.h"
+#include "hwc_display_virtual.h"
 
 #define __CLASS__ "HWCSession"
 
@@ -73,8 +75,8 @@
 bool HWCSession::reset_panel_ = false;
 
 HWCSession::HWCSession(const hw_module_t *module) : core_intf_(NULL), hwc_procs_(NULL),
-            display_primary_(NULL), display_external_(NULL), display_virtual_(NULL),
             uevent_thread_exit_(false), uevent_thread_name_("HWC_UeventThread") {
+  memset(&hwc_display_, 0, sizeof(hwc_display_));
   hwc_composer_device_1_t::common.tag = HARDWARE_DEVICE_TAG;
   hwc_composer_device_1_t::common.version = HWC_DEVICE_API_VERSION_1_4;
   hwc_composer_device_1_t::common.module = const_cast<hw_module_t*>(module);
@@ -120,7 +122,7 @@
     return -ENOMEM;
   }
 
-  DisplayError error = CoreInterface::CreateCore(this, HWCDebugHandler::Get(), buffer_allocator_,
+  DisplayError error = CoreInterface::CreateCore(HWCDebugHandler::Get(), buffer_allocator_,
                                                  buffer_sync_handler_, &core_intf_);
   if (error != kErrorNone) {
     DLOGE("Display core initialization failed. Error = %d", error);
@@ -128,44 +130,27 @@
   }
 
   // Create and power on primary display
-  display_primary_ = new HWCDisplayPrimary(core_intf_, &hwc_procs_);
-  if (!display_primary_) {
-    CoreInterface::DestroyCore();
-    return -ENOMEM;
-  }
-
-  status = display_primary_->Init();
+  status = HWCDisplayPrimary::Create(core_intf_, &hwc_procs_,
+                                     &hwc_display_[HWC_DISPLAY_PRIMARY]);
   if (status) {
     CoreInterface::DestroyCore();
-    delete display_primary_;
-    return status;
-  }
-
-  status = display_primary_->SetPowerMode(HWC_POWER_MODE_NORMAL);
-  if (status) {
-    display_primary_->Deinit();
-    delete display_primary_;
-    CoreInterface::DestroyCore();
     return status;
   }
 
   if (pthread_create(&uevent_thread_, NULL, &HWCUeventThread, this) < 0) {
     DLOGE("Failed to start = %s, error = %s", uevent_thread_name_);
-    display_primary_->Deinit();
-    delete display_primary_;
+    HWCDisplayPrimary::Destroy(hwc_display_[HWC_DISPLAY_PRIMARY]);
+    hwc_display_[HWC_DISPLAY_PRIMARY] = 0;
     CoreInterface::DestroyCore();
     return -errno;
   }
 
-  SetFrameBufferResolution(HWC_DISPLAY_PRIMARY, NULL);
-
   return 0;
 }
 
 int HWCSession::Deinit() {
-  display_primary_->SetPowerMode(HWC_POWER_MODE_OFF);
-  display_primary_->Deinit();
-  delete display_primary_;
+  HWCDisplayPrimary::Destroy(hwc_display_[HWC_DISPLAY_PRIMARY]);
+  hwc_display_[HWC_DISPLAY_PRIMARY] = 0;
   uevent_thread_exit_ = true;
   pthread_join(uevent_thread_, NULL);
 
@@ -233,34 +218,17 @@
     hwc_session->ResetPanel();
   }
 
-  for (ssize_t i = (num_displays-1); i >= 0; i--) {
-    hwc_display_contents_1_t *content_list = displays[i];
+  for (ssize_t dpy = (num_displays - 1); dpy >= 0; dpy--) {
+    hwc_display_contents_1_t *content_list = displays[dpy];
+    if (dpy == HWC_DISPLAY_VIRTUAL) {
+      if (hwc_session->hwc_display_[HWC_DISPLAY_EXTERNAL]) {
+        continue;
+      }
+      hwc_session->HandleVirtualDisplayLifeCycle(content_list);
+    }
 
-    switch (i) {
-    case HWC_DISPLAY_PRIMARY:
-      hwc_session->display_primary_->Prepare(content_list);
-      break;
-    case HWC_DISPLAY_EXTERNAL:
-      if (hwc_session->display_external_) {
-        hwc_session->display_external_->Prepare(content_list);
-      }
-      break;
-    case HWC_DISPLAY_VIRTUAL:
-      if (hwc_session->display_external_) {
-        break;
-      }
-      if (hwc_session->ValidateContentList(content_list)) {
-        hwc_session->CreateVirtualDisplay(content_list);
-      } else {
-        hwc_session->DestroyVirtualDisplay();
-      }
-
-      if (hwc_session->display_virtual_) {
-        hwc_session->display_virtual_->Prepare(content_list);
-      }
-      break;
-    default:
-      break;
+    if (hwc_session->hwc_display_[dpy]) {
+      hwc_session->hwc_display_[dpy]->Prepare(content_list);
     }
   }
 
@@ -280,20 +248,10 @@
 
   HWCSession *hwc_session = static_cast<HWCSession *>(device);
 
-  for (size_t i = 0; i < num_displays; i++) {
-    hwc_display_contents_1_t *content_list = displays[i];
-
-    switch (i) {
-    case HWC_DISPLAY_PRIMARY:
-      hwc_session->display_primary_->Commit(content_list);
-      break;
-    case HWC_DISPLAY_EXTERNAL:
-      if (hwc_session->display_external_) {
-        hwc_session->display_external_->Commit(content_list);
-      }
-      break;
-    case HWC_DISPLAY_VIRTUAL:
-      if (hwc_session->display_external_) {
+  for (size_t dpy = 0; dpy < num_displays; dpy++) {
+    hwc_display_contents_1_t *content_list = displays[dpy];
+    if (dpy == HWC_DISPLAY_VIRTUAL) {
+      if (hwc_session->hwc_display_[HWC_DISPLAY_EXTERNAL]) {
         if (content_list) {
           for (size_t i = 0; i < content_list->numHwLayers; i++) {
             if (content_list->hwLayers[i].acquireFenceFd >= 0) {
@@ -308,12 +266,10 @@
           content_list->retireFenceFd = -1;
         }
       }
-      if (hwc_session->display_virtual_) {
-        hwc_session->display_virtual_->Commit(content_list);
-      }
-      break;
-    default:
-      break;
+    }
+
+    if (hwc_session->hwc_display_[dpy]) {
+      hwc_session->hwc_display_[dpy]->Commit(content_list);
     }
   }
 
@@ -330,20 +286,8 @@
 
   HWCSession *hwc_session = static_cast<HWCSession *>(device);
   int status = -EINVAL;
-
-  switch (disp) {
-  case HWC_DISPLAY_PRIMARY:
-    status = hwc_session->display_primary_->EventControl(event, enable);
-    break;
-  case HWC_DISPLAY_EXTERNAL:
-    if (hwc_session->display_external_) {
-      status = hwc_session->display_external_->EventControl(event, enable);
-    }
-    break;
-  case HWC_DISPLAY_VIRTUAL:
-    break;
-  default:
-    status = -EINVAL;
+  if (hwc_session->hwc_display_[disp]) {
+    status = hwc_session->hwc_display_[disp]->EventControl(event, enable);
   }
 
   return status;
@@ -358,24 +302,13 @@
 
   HWCSession *hwc_session = static_cast<HWCSession *>(device);
   int status = -EINVAL;
-
-  switch (disp) {
-  case HWC_DISPLAY_PRIMARY:
-    status = hwc_session->display_primary_->SetPowerMode(mode);
-  // Set the power mode for virtual display while setting power mode for primary, as surfaceflinger
-  // does not invoke SetPowerMode() for virtual display.
-  case HWC_DISPLAY_VIRTUAL:
-    if (hwc_session->display_virtual_) {
-      status = hwc_session->display_virtual_->SetPowerMode(mode);
-    }
-    break;
-  case HWC_DISPLAY_EXTERNAL:
-    if (hwc_session->display_external_) {
-      status = hwc_session->display_external_->SetPowerMode(mode);
-    }
-    break;
-  default:
-    status = -EINVAL;
+  if (hwc_session->hwc_display_[disp]) {
+    status = hwc_session->hwc_display_[disp]->SetPowerMode(mode);
+  }
+  if (disp == HWC_DISPLAY_PRIMARY && hwc_session->hwc_display_[HWC_DISPLAY_VIRTUAL]) {
+    // Set the power mode for virtual display while setting power mode for primary, as SF
+    // does not invoke SetPowerMode() for virtual display.
+    status = hwc_session->hwc_display_[HWC_DISPLAY_VIRTUAL]->SetPowerMode(mode);
   }
 
   return status;
@@ -420,23 +353,8 @@
 
   HWCSession *hwc_session = static_cast<HWCSession *>(device);
   int status = -EINVAL;
-
-  switch (disp) {
-  case HWC_DISPLAY_PRIMARY:
-    status = hwc_session->display_primary_->GetDisplayConfigs(configs, num_configs);
-    break;
-  case HWC_DISPLAY_EXTERNAL:
-    if (hwc_session->display_external_) {
-      status = hwc_session->display_external_->GetDisplayConfigs(configs, num_configs);
-    }
-    break;
-  case HWC_DISPLAY_VIRTUAL:
-    if (hwc_session->display_virtual_) {
-      status = hwc_session->display_virtual_->GetDisplayConfigs(configs, num_configs);
-    }
-    break;
-  default:
-    status = -EINVAL;
+  if (hwc_session->hwc_display_[disp]) {
+    status = hwc_session->hwc_display_[disp]->GetDisplayConfigs(configs, num_configs);
   }
 
   return status;
@@ -452,23 +370,8 @@
 
   HWCSession *hwc_session = static_cast<HWCSession *>(device);
   int status = -EINVAL;
-
-  switch (disp) {
-  case HWC_DISPLAY_PRIMARY:
-    status = hwc_session->display_primary_->GetDisplayAttributes(config, attributes, values);
-    break;
-  case HWC_DISPLAY_EXTERNAL:
-    if (hwc_session->display_external_) {
-      status = hwc_session->display_external_->GetDisplayAttributes(config, attributes, values);
-    }
-    break;
-  case HWC_DISPLAY_VIRTUAL:
-    if (hwc_session->display_virtual_) {
-      status = hwc_session->display_virtual_->GetDisplayAttributes(config, attributes, values);
-    }
-    break;
-  default:
-    status = -EINVAL;
+  if (hwc_session->hwc_display_[disp]) {
+    status = hwc_session->hwc_display_[disp]->GetDisplayAttributes(config, attributes, values);
   }
 
   return status;
@@ -483,23 +386,8 @@
 
   HWCSession *hwc_session = static_cast<HWCSession *>(device);
   int active_config = -1;
-
-  switch (disp) {
-  case HWC_DISPLAY_PRIMARY:
-    active_config = hwc_session->display_primary_->GetActiveConfig();
-    break;
-  case HWC_DISPLAY_EXTERNAL:
-    if (hwc_session->display_external_) {
-      active_config = hwc_session->display_external_->GetActiveConfig();
-    }
-    break;
-  case HWC_DISPLAY_VIRTUAL:
-    if (hwc_session->display_virtual_) {
-      active_config = hwc_session->display_virtual_->GetActiveConfig();
-    }
-    break;
-  default:
-    active_config = -1;
+  if (hwc_session->hwc_display_[disp]) {
+    active_config = hwc_session->hwc_display_[disp]->GetActiveConfig();
   }
 
   return active_config;
@@ -514,72 +402,26 @@
 
   HWCSession *hwc_session = static_cast<HWCSession *>(device);
   int status = -EINVAL;
-
-  switch (disp) {
-  case HWC_DISPLAY_PRIMARY:
-    status = hwc_session->display_primary_->SetActiveConfig(index);
-    break;
-  case HWC_DISPLAY_EXTERNAL:
-    if (hwc_session->display_external_) {
-      // TODO(user): Uncomment it. HDMI does not support resolution change currently.
-      status = 0;  // hwc_session->display_external_->SetActiveConfig(index);
-    }
-    break;
-  case HWC_DISPLAY_VIRTUAL:
-    break;
-  default:
-    status = -EINVAL;
+  if (hwc_session->hwc_display_[disp]) {
+    status = hwc_session->hwc_display_[disp]->SetActiveConfig(index);
   }
 
   return status;
 }
 
-bool HWCSession::ValidateContentList(hwc_display_contents_1_t *content_list) {
-  return (content_list && content_list->numHwLayers > 0 && content_list->outbuf);
-}
-
-int HWCSession::CreateVirtualDisplay(hwc_display_contents_1_t *content_list) {
+int HWCSession::HandleVirtualDisplayLifeCycle(hwc_display_contents_1_t *content_list) {
   int status = 0;
 
-  if (!display_virtual_) {
-    // Create virtual display device
-    display_virtual_ = new HWCDisplayVirtual(core_intf_, &hwc_procs_);
-    if (!display_virtual_) {
-      // This is not catastrophic. Leave a warning message for now.
-      DLOGW("Virtual Display creation failed");
-      return -ENOMEM;
+  if (HWCDisplayVirtual::IsValidContentList(content_list)) {
+    if (!hwc_display_[HWC_DISPLAY_VIRTUAL]) {
+      // Create virtual display device
+      status = HWCDisplayVirtual::Create(core_intf_, &hwc_procs_, content_list,
+                                         &hwc_display_[HWC_DISPLAY_VIRTUAL]);
     }
-
-    status = display_virtual_->Init();
-    if (status) {
-      goto CleanupOnError;
-    }
-
-    status = display_virtual_->SetPowerMode(HWC_POWER_MODE_NORMAL);
-    if (status) {
-      goto CleanupOnError;
-    }
-  }
-
-  if (display_virtual_) {
-    SetFrameBufferResolution(HWC_DISPLAY_VIRTUAL, content_list);
-    status = display_virtual_->SetActiveConfig(content_list);
-  }
-
-  return status;
-
-CleanupOnError:
-  return DestroyVirtualDisplay();
-}
-
-int HWCSession::DestroyVirtualDisplay() {
-  int status = 0;
-
-  if (display_virtual_) {
-    status = display_virtual_->Deinit();
-    if (!status) {
-      delete display_virtual_;
-      display_virtual_ = NULL;
+  } else {
+    if (hwc_display_[HWC_DISPLAY_VIRTUAL]) {
+      HWCDisplayVirtual::Destroy(hwc_display_[HWC_DISPLAY_VIRTUAL]);
+      hwc_display_[HWC_DISPLAY_VIRTUAL] = 0;
       // Signal the HotPlug thread to continue with the external display connection
       locker_.Signal();
     }
@@ -588,10 +430,6 @@
   return status;
 }
 
-DisplayError HWCSession::Hotplug(const CoreEventHotplug &hotplug) {
-  return kErrorNone;
-}
-
 android::status_t HWCSession::notifyCallback(uint32_t command, const android::Parcel *input_parcel,
                                              android::Parcel */*output_parcel*/) {
   SEQUENCE_WAIT_SCOPE_LOCK(locker_);
@@ -608,9 +446,9 @@
     break;
 
   case qService::IQService::SET_IDLE_TIMEOUT:
-    if (display_primary_) {
+    if (hwc_display_[HWC_DISPLAY_PRIMARY]) {
       uint32_t timeout = UINT32(input_parcel->readInt32());
-      display_primary_->SetIdleTimeoutMs(timeout);
+      hwc_display_[HWC_DISPLAY_PRIMARY]->SetIdleTimeoutMs(timeout);
     }
     break;
 
@@ -633,6 +471,9 @@
     status = ConfigureRefreshRate(input_parcel);
     break;
 
+  case qService::IQService::SET_VIEW_FRAME:
+    break;
+
   default:
     DLOGW("QService command = %d is not supported", command);
     return -EINVAL;
@@ -644,62 +485,43 @@
 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());
-  HWCDisplay *display = NULL;
 
   DLOGI("Display %d Status %d", display_id, display_status);
-  switch (display_id) {
-  case HWC_DISPLAY_EXTERNAL:
-    display = display_external_;
-    break;
-  case HWC_DISPLAY_VIRTUAL:
-    display = display_virtual_;
-    break;
-  default:
+  if (display_id < HWC_DISPLAY_EXTERNAL || display_id > HWC_DISPLAY_VIRTUAL) {
     DLOGW("Not supported for display %d", display_id);
     return -EINVAL;
   }
 
-  return display->SetDisplayStatus(display_status);
+  return hwc_display_[display_id]->SetDisplayStatus(display_status);
 }
 
 android::status_t HWCSession::ConfigureRefreshRate(const android::Parcel *input_parcel) {
   uint32_t operation = UINT32(input_parcel->readInt32());
-
   switch (operation) {
-  case qdutils::DISABLE_METADATA_DYN_REFRESH_RATE:
-    display_primary_->SetMetaDataRefreshRateFlag(false);
-    break;
-
-  case qdutils::ENABLE_METADATA_DYN_REFRESH_RATE:
-    display_primary_->SetMetaDataRefreshRateFlag(true);
-    break;
-
-  case qdutils::SET_BINDER_DYN_REFRESH_RATE:
-  {
-    uint32_t refresh_rate = UINT32(input_parcel->readInt32());
-
-    display_primary_->SetRefreshRate(refresh_rate);
-    break;
-  }
-
-  default:
-    DLOGW("Invalid operation %d", operation);
-    return -EINVAL;
+    case qdutils::DISABLE_METADATA_DYN_REFRESH_RATE:
+      return hwc_display_[HWC_DISPLAY_PRIMARY]->Perform(
+          HWCDisplayPrimary::SET_METADATA_DYN_REFRESH_RATE, false);
+    case qdutils::ENABLE_METADATA_DYN_REFRESH_RATE:
+      return hwc_display_[HWC_DISPLAY_PRIMARY]->Perform(
+          HWCDisplayPrimary::SET_METADATA_DYN_REFRESH_RATE, true);
+    case qdutils::SET_BINDER_DYN_REFRESH_RATE:
+      {
+        uint32_t refresh_rate = UINT32(input_parcel->readInt32());
+        return hwc_display_[HWC_DISPLAY_PRIMARY]->Perform(
+            HWCDisplayPrimary::SET_BINDER_DYN_REFRESH_RATE,
+            refresh_rate);
+      }
+    default:
+      DLOGW("Invalid operation %d", operation);
+      return -EINVAL;
   }
 
   return 0;
 }
 
 android::status_t HWCSession::SetDisplayMode(const android::Parcel *input_parcel) {
-  DisplayError error = kErrorNone;
   uint32_t mode = UINT32(input_parcel->readInt32());
-
-  error = display_primary_->SetDisplayMode(mode);
-  if (error != kErrorNone) {
-    return -EINVAL;
-  }
-
-  return 0;
+  return hwc_display_[HWC_DISPLAY_PRIMARY]->Perform(HWCDisplayPrimary::SET_DISPLAY_MODE, mode);
 }
 
 android::status_t HWCSession::SetMaxMixerStages(const android::Parcel *input_parcel) {
@@ -708,8 +530,8 @@
   uint32_t max_mixer_stages = UINT32(input_parcel->readInt32());
 
   if (IS_BIT_SET(bit_mask_display_type, HWC_DISPLAY_PRIMARY)) {
-    if (display_primary_) {
-      error = display_primary_->SetMaxMixerStages(max_mixer_stages);
+    if (hwc_display_[HWC_DISPLAY_PRIMARY]) {
+      error = hwc_display_[HWC_DISPLAY_PRIMARY]->SetMaxMixerStages(max_mixer_stages);
       if (error != kErrorNone) {
         return -EINVAL;
       }
@@ -717,8 +539,8 @@
   }
 
   if (IS_BIT_SET(bit_mask_display_type, HWC_DISPLAY_EXTERNAL)) {
-    if (display_external_) {
-      error = display_external_->SetMaxMixerStages(max_mixer_stages);
+    if (hwc_display_[HWC_DISPLAY_EXTERNAL]) {
+      error = hwc_display_[HWC_DISPLAY_EXTERNAL]->SetMaxMixerStages(max_mixer_stages);
       if (error != kErrorNone) {
         return -EINVAL;
       }
@@ -726,8 +548,8 @@
   }
 
   if (IS_BIT_SET(bit_mask_display_type, HWC_DISPLAY_VIRTUAL)) {
-    if (display_virtual_) {
-      error = display_virtual_->SetMaxMixerStages(max_mixer_stages);
+    if (hwc_display_[HWC_DISPLAY_VIRTUAL]) {
+      error = hwc_display_[HWC_DISPLAY_VIRTUAL]->SetMaxMixerStages(max_mixer_stages);
       if (error != kErrorNone) {
         return -EINVAL;
       }
@@ -743,20 +565,20 @@
   uint32_t bit_mask_layer_type = UINT32(input_parcel->readInt32());
 
   if (IS_BIT_SET(bit_mask_display_type, HWC_DISPLAY_PRIMARY)) {
-    if (display_primary_) {
-      display_primary_->SetFrameDumpConfig(frame_dump_count, bit_mask_layer_type);
+    if (hwc_display_[HWC_DISPLAY_PRIMARY]) {
+      hwc_display_[HWC_DISPLAY_PRIMARY]->SetFrameDumpConfig(frame_dump_count, bit_mask_layer_type);
     }
   }
 
   if (IS_BIT_SET(bit_mask_display_type, HWC_DISPLAY_EXTERNAL)) {
-    if (display_external_) {
-      display_external_->SetFrameDumpConfig(frame_dump_count, bit_mask_layer_type);
+    if (hwc_display_[HWC_DISPLAY_EXTERNAL]) {
+      hwc_display_[HWC_DISPLAY_EXTERNAL]->SetFrameDumpConfig(frame_dump_count, bit_mask_layer_type);
     }
   }
 
   if (IS_BIT_SET(bit_mask_display_type, HWC_DISPLAY_VIRTUAL)) {
-    if (display_virtual_) {
-      display_virtual_->SetFrameDumpConfig(frame_dump_count, bit_mask_layer_type);
+    if (hwc_display_[HWC_DISPLAY_VIRTUAL]) {
+      hwc_display_[HWC_DISPLAY_VIRTUAL]->SetFrameDumpConfig(frame_dump_count, bit_mask_layer_type);
     }
   }
 }
@@ -862,19 +684,19 @@
   int status = -EINVAL;
 
   DLOGI("Powering off primary");
-  status = display_primary_->SetPowerMode(HWC_POWER_MODE_OFF);
+  status = hwc_display_[HWC_DISPLAY_PRIMARY]->SetPowerMode(HWC_POWER_MODE_OFF);
   if (status) {
     DLOGE("power-off on primary failed with error = %d", status);
   }
 
   DLOGI("Restoring power mode on primary");
-  uint32_t mode = display_primary_->GetLastPowerMode();
-  status = display_primary_->SetPowerMode(mode);
+  uint32_t mode = hwc_display_[HWC_DISPLAY_PRIMARY]->GetLastPowerMode();
+  status = hwc_display_[HWC_DISPLAY_PRIMARY]->SetPowerMode(mode);
   if (status) {
     DLOGE("Setting power mode = %d on primary failed with error = %d", mode, status);
   }
 
-  status = display_primary_->EventControl(HWC_EVENT_VSYNC, 1);
+  status = hwc_display_[HWC_DISPLAY_PRIMARY]->EventControl(HWC_EVENT_VSYNC, 1);
   if (status) {
     DLOGE("enabling vsync failed for primary with error = %d", status);
   }
@@ -890,7 +712,7 @@
 
   if (connected) {
     SEQUENCE_WAIT_SCOPE_LOCK(locker_);
-    if (display_virtual_) {
+    if (hwc_display_[HWC_DISPLAY_VIRTUAL]) {
       // Wait for the virtual display to tear down
       int status = locker_.WaitFinite(kExternalConnectionTimeoutMs);
       if (status != 0) {
@@ -898,32 +720,28 @@
         return -1;
       }
     }
-    if (display_external_) {
+    if (hwc_display_[HWC_DISPLAY_EXTERNAL]) {
      DLOGE("HDMI already connected");
      return -1;
     }
+
+    uint32_t primary_width = 0;
+    uint32_t primary_height = 0;
+    hwc_display_[HWC_DISPLAY_PRIMARY]->GetFrameBufferResolution(&primary_width, &primary_height);
     // Create hdmi display
-    display_external_ = new HWCDisplayExternal(core_intf_, &hwc_procs_);
-    if (!display_external_) {
-      return -1;
-    }
-    int status = display_external_->Init();
+    int status = HWCDisplayExternal::Create(core_intf_, &hwc_procs_, primary_width,
+                                            primary_height, &hwc_display_[HWC_DISPLAY_EXTERNAL]);
     if (status) {
-      delete display_external_;
-      display_external_ = NULL;
-      return -1;
+      return status;
     }
-    SetFrameBufferResolution(HWC_DISPLAY_EXTERNAL, NULL);
   } else {
     SEQUENCE_WAIT_SCOPE_LOCK(locker_);
-    if (!display_external_) {
+    if (!hwc_display_[HWC_DISPLAY_EXTERNAL]) {
      DLOGE("HDMI not connected");
      return -1;
     }
-    display_external_->SetPowerMode(HWC_POWER_MODE_OFF);
-    display_external_->Deinit();
-    delete display_external_;
-    display_external_ = NULL;
+    HWCDisplayExternal::Destroy(hwc_display_[HWC_DISPLAY_EXTERNAL]);
+    hwc_display_[HWC_DISPLAY_EXTERNAL] = 0;
   }
 
   // notify client and trigger a screen refresh
@@ -933,72 +751,5 @@
   return 0;
 }
 
-void HWCSession::SetFrameBufferResolution(int disp, hwc_display_contents_1_t *content_list) {
-  char property[PROPERTY_VALUE_MAX];
-  uint32_t primary_width = 0;
-  uint32_t primary_height = 0;
-
-  switch (disp) {
-  case HWC_DISPLAY_PRIMARY:
-  {
-    display_primary_->GetPanelResolution(&primary_width, &primary_height);
-    if (property_get("debug.hwc.fbsize", property, NULL) > 0) {
-      char *yptr = strcasestr(property, "x");
-      primary_width = atoi(property);
-      primary_height = atoi(yptr + 1);
-    }
-    display_primary_->SetFrameBufferResolution(primary_width, primary_height);
-    break;
-  }
-
-  case HWC_DISPLAY_EXTERNAL:
-  {
-    uint32_t external_width = 0;
-    uint32_t external_height = 0;
-    display_external_->GetPanelResolution(&external_width, &external_height);
-
-    if (property_get("sys.hwc.mdp_downscale_enabled", property, "false") &&
-        !strcmp(property, "true")) {
-      display_primary_->GetFrameBufferResolution(&primary_width, &primary_height);
-      uint32_t primary_area = primary_width * primary_height;
-      uint32_t external_area = external_width * external_height;
-
-      if (primary_area > external_area) {
-        if (primary_height > primary_width) {
-          Swap(primary_height, primary_width);
-        }
-        AdjustSourceResolution(primary_width, primary_height,
-                               &external_width, &external_height);
-      }
-    }
-    display_external_->SetFrameBufferResolution(external_width, external_height);
-    break;
-  }
-
-  case HWC_DISPLAY_VIRTUAL:
-  {
-    if (ValidateContentList(content_list)) {
-      const private_handle_t *output_handle =
-              static_cast<const private_handle_t *>(content_list->outbuf);
-      int virtual_width = 0;
-      int virtual_height = 0;
-      getBufferSizeAndDimensions(output_handle->width, output_handle->height, output_handle->format,
-                                 virtual_width, virtual_height);
-      display_virtual_->SetFrameBufferResolution(virtual_width, virtual_height);
-    }
-    break;
-  }
-
-  default:
-    break;
-  }
-}
-
-void HWCSession::AdjustSourceResolution(uint32_t dst_width, uint32_t dst_height,
-                                        uint32_t *src_width, uint32_t *src_height) {
-  *src_height = (dst_width * (*src_height)) / (*src_width);
-  *src_width = dst_width;
-}
-
 }  // namespace sdm
 
diff --git a/sdm/libs/hwc/hwc_session.h b/sdm/libs/hwc/hwc_session.h
index 15b762c..5f844eb 100644
--- a/sdm/libs/hwc/hwc_session.h
+++ b/sdm/libs/hwc/hwc_session.h
@@ -36,7 +36,7 @@
 
 namespace sdm {
 
-class HWCSession : hwc_composer_device_1_t, CoreEventHandler, public qClient::BnQClient {
+class HWCSession : hwc_composer_device_1_t, public qClient::BnQClient {
  public:
   struct HWCModuleMethods : public hw_module_methods_t {
     HWCModuleMethods() {
@@ -76,12 +76,7 @@
   int GetEventValue(const char *uevent_data, int length, const char *event_info);
   int HotPlugHandler(bool connected);
   void ResetPanel();
-  bool ValidateContentList(hwc_display_contents_1_t *content_list);
-  int CreateVirtualDisplay(hwc_display_contents_1_t *content_list);
-  int DestroyVirtualDisplay();
-
-  // CoreEventHandler methods
-  virtual DisplayError Hotplug(const CoreEventHotplug &hotplug);
+  int HandleVirtualDisplayLifeCycle(hwc_display_contents_1_t *content_list);
 
   // QClient methods
   virtual android::status_t notifyCallback(uint32_t command, const android::Parcel *input_parcel,
@@ -91,17 +86,12 @@
   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);
-  void SetFrameBufferResolution(int disp, hwc_display_contents_1_t *content_list);
-  void AdjustSourceResolution(uint32_t dst_width, uint32_t dst_height,
-                              uint32_t *src_width, uint32_t *src_height);
   android::status_t ConfigureRefreshRate(const android::Parcel *input_parcel);
 
   static Locker locker_;
   CoreInterface *core_intf_;
   hwc_procs_t const *hwc_procs_;
-  HWCDisplayPrimary *display_primary_;
-  HWCDisplayExternal *display_external_;
-  HWCDisplayVirtual *display_virtual_;
+  HWCDisplay *hwc_display_[HWC_NUM_DISPLAY_TYPES];
   pthread_t uevent_thread_;
   bool uevent_thread_exit_;
   static bool reset_panel_;
diff --git a/sdm/libs/utils/Android.mk b/sdm/libs/utils/Android.mk
index 57c2088..9de5c07 100644
--- a/sdm/libs/utils/Android.mk
+++ b/sdm/libs/utils/Android.mk
@@ -7,7 +7,6 @@
 LOCAL_CFLAGS                  := -Wno-missing-field-initializers -Wno-unused-parameter \
                                  -Wconversion -Wall -Werror \
                                  -DLOG_TAG=\"SDM\"
-LOCAL_SHARED_LIBRARIES        := libcutils
-LOCAL_SRC_FILES               := debug_android.cpp rect.cpp
+LOCAL_SRC_FILES               := debug.cpp rect.cpp
 
 include $(BUILD_SHARED_LIBRARY)
diff --git a/sdm/libs/utils/debug.cpp b/sdm/libs/utils/debug.cpp
new file mode 100644
index 0000000..cd7533b
--- /dev/null
+++ b/sdm/libs/utils/debug.cpp
@@ -0,0 +1,110 @@
+/*
+* Copyright (c) 2014 - 2015, The Linux Foundation. All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are
+* met:
+*     * Redistributions of source code must retain the above copyright
+*       notice, this list of conditions and the following disclaimer.
+*     * Redistributions in binary form must reproduce the above
+*       copyright notice, this list of conditions and the following
+*       disclaimer in the documentation and/or other materials provided
+*       with the distribution.
+*     * Neither the name of The Linux Foundation nor the names of its
+*       contributors may be used to endorse or promote products derived
+*       from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+* ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include <stdlib.h>
+#include <utils/debug.h>
+#include <utils/constants.h>
+
+namespace sdm {
+
+Debug Debug::debug_;
+
+Debug::Debug() : debug_handler_(&default_debug_handler_) {
+}
+
+uint32_t Debug::GetSimulationFlag() {
+  int value = 0;
+  debug_.debug_handler_->GetProperty("sdm.composition_simulation", &value);
+
+  return value;
+}
+
+uint32_t Debug::GetHDMIResolution() {
+  int value = 0;
+  debug_.debug_handler_->GetProperty("hw.hdmi.resolution", &value);
+
+  return value;
+}
+
+uint32_t Debug::GetIdleTimeoutMs() {
+  int value = IDLE_TIMEOUT_DEFAULT_MS;
+  debug_.debug_handler_->GetProperty("sdm.idle_time", &value);
+
+  return value;
+}
+
+bool Debug::IsRotatorDownScaleDisabled() {
+  int value = 0;
+  debug_.debug_handler_->GetProperty("sdm.debug.rotator_downscale", &value);
+
+  return (value == 1);
+}
+
+bool Debug::IsDecimationDisabled() {
+  int value = 0;
+  debug_.debug_handler_->GetProperty("sdm.disable_decimation", &value);
+
+  return (value == 1);
+}
+
+bool Debug::IsPartialUpdateEnabled() {
+  int value = 0;
+  debug_.debug_handler_->GetProperty("sdm.partial_update", &value);
+
+  return (value == 1);
+}
+
+int Debug::GetMaxPipesPerMixer(DisplayType display_type) {
+  int value = -1;
+  switch (display_type) {
+  case kPrimary:
+    debug_.debug_handler_->GetProperty("sdm.primary.mixer_stages", &value);
+    break;
+  case kHDMI:
+    debug_.debug_handler_->GetProperty("sdm.external.mixer_stages", &value);
+    break;
+  case kVirtual:
+    debug_.debug_handler_->GetProperty("sdm.virtual.mixer_stages", &value);
+    break;
+  default:
+    break;
+  }
+
+  return value;
+}
+
+bool Debug::IsVideoModeEnabled() {
+  int value = 0;
+  debug_.debug_handler_->GetProperty("sdm.video_mode_panel", &value);
+
+  return (value == 1);
+}
+
+}  // namespace sdm
+
diff --git a/sdm/libs/utils/debug_android.cpp b/sdm/libs/utils/debug_android.cpp
deleted file mode 100644
index f57d04d..0000000
--- a/sdm/libs/utils/debug_android.cpp
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
-* Copyright (c) 2014 - 2015, The Linux Foundation. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without
-* modification, are permitted provided that the following conditions are
-* met:
-*     * Redistributions of source code must retain the above copyright
-*       notice, this list of conditions and the following disclaimer.
-*     * Redistributions in binary form must reproduce the above
-*       copyright notice, this list of conditions and the following
-*       disclaimer in the documentation and/or other materials provided
-*       with the distribution.
-*     * Neither the name of The Linux Foundation nor the names of its
-*       contributors may be used to endorse or promote products derived
-*       from this software without specific prior written permission.
-*
-* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
-* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
-* ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
-* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
-* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#include <stdlib.h>
-#include <utils/debug.h>
-#include <utils/constants.h>
-#include <cutils/log.h>
-#include <cutils/properties.h>
-
-namespace sdm {
-
-Debug Debug::debug_;
-
-Debug::Debug() : debug_handler_(&default_debug_handler_), virtual_driver_(false) {
-  char property[PROPERTY_VALUE_MAX];
-  if (property_get("displaycore.virtualdriver", property, NULL) > 0) {
-    virtual_driver_ = (atoi(property) == 1);
-  }
-}
-
-uint32_t Debug::GetSimulationFlag() {
-  char property[PROPERTY_VALUE_MAX];
-  if (property_get("debug.hwc.simulate", property, NULL) > 0) {
-    return atoi(property);
-  }
-
-  return 0;
-}
-
-uint32_t Debug::GetHDMIResolution() {
-  char property[PROPERTY_VALUE_MAX];
-  if (property_get("hw.hdmi.resolution", property, NULL) > 0) {
-    return atoi(property);
-  }
-
-  return 0;
-}
-
-uint32_t Debug::GetIdleTimeoutMs() {
-  char property[PROPERTY_VALUE_MAX];
-  if (property_get("debug.mdpcomp.idletime", property, NULL) > 0) {
-    return atoi(property);
-  }
-
-  return IDLE_TIMEOUT_DEFAULT_MS;
-}
-
-bool Debug::IsRotatorDownScaleDisabled() {
-  char property[PROPERTY_VALUE_MAX];
-  if (property_get("sdm.disable_rotator_downscaling", property, NULL) > 0) {
-    return (atoi(property) ? 0 : false, true);
-  }
-
-  return false;
-}
-
-bool Debug::IsDecimationDisabled() {
-  char property[PROPERTY_VALUE_MAX];
-  if (property_get("sdm.disable_decimation", property, NULL) > 0) {
-    return (atoi(property) ? 0 : false, true);
-  }
-
-  return false;
-}
-
-// This property serves to disable/enable partial update
-bool Debug::IsPartialUpdateEnabled() {
-  char property[PROPERTY_VALUE_MAX];
-  if (property_get("sdm.hwc.partial_update", property, NULL) > 0) {
-    return (atoi(property) ? 1 : true, false);
-  }
-
-  return false;
-}
-
-}  // namespace sdm
-