msmcobalt: Update to 07.00.00.253.039

msmcobalt: from hardware/qcom/display
  3c400e5 Merge AU_LINUX_ANDROID_LA.UM.5.7.R1.07.00.00.253.035 on remote branch
  37a0a77 Promotion of display.lnx.3.0-00056.
  e33c1b8 Merge "sdm: Disable destination scalar when layer needs downscale"
  e031af9 Merge "sdm: Destination scalar fixes during rotation and suspend-resume."
  388b479 Merge "sdm: Set FB H/W layer only when Strategy Extension is not present"
  3065a27 sdm: Read has_ppp feature into hw info.
  c18263e display: Add Support for Rec.2020
  9fd4a73 qd_utils: Export qd_utils to TARGET_OUT_HEADERS
  3335e4a sdm: Disable destination scalar when layer needs downscale
  f21df50 sdm: Destination scalar fixes during rotation and suspend-resume.
  d3b4c06 sdm: Add property to enable destination scalar during bootup.
  f2468d6 sdm: Fixes for destination scalar.
  b13750b sdm: Set FB H/W layer only when Strategy Extension is not present

Change-Id: I0e41f676e3df704e1131ca80a201456c975592fe
Signed-off-by: Thierry Strudel <tstrudel@google.com>
diff --git a/msmcobalt/libgralloc/gralloc_priv.h b/msmcobalt/libgralloc/gralloc_priv.h
index 4c059cf..738b63f 100644
--- a/msmcobalt/libgralloc/gralloc_priv.h
+++ b/msmcobalt/libgralloc/gralloc_priv.h
@@ -166,6 +166,13 @@
 #define HAL_IGC_NOT_SPECIFIED     0
 #define HAL_IGC_s_RGB             1
 
+/* Color Space: Values maps to ColorSpace_t in qdMetadata.h */
+#define HAL_CSC_ITU_R_601         0
+#define HAL_CSC_ITU_R_601_FR      1
+#define HAL_CSC_ITU_R_709         2
+#define HAL_CSC_ITU_R_2020        3
+#define HAL_CSC_ITU_R_2020_FR     4
+
 /* possible formats for 3D content*/
 enum {
     HAL_NO_3D                      = 0x0,
diff --git a/msmcobalt/libgralloc1/gralloc_priv.h b/msmcobalt/libgralloc1/gralloc_priv.h
index f282070..0695a60 100644
--- a/msmcobalt/libgralloc1/gralloc_priv.h
+++ b/msmcobalt/libgralloc1/gralloc_priv.h
@@ -159,6 +159,13 @@
 #define HAL_IGC_NOT_SPECIFIED 0
 #define HAL_IGC_s_RGB 1
 
+/* Color Space: Values maps to ColorSpace_t in qdMetadata.h */
+#define HAL_CSC_ITU_R_601         0
+#define HAL_CSC_ITU_R_601_FR      1
+#define HAL_CSC_ITU_R_709         2
+#define HAL_CSC_ITU_R_2020        3
+#define HAL_CSC_ITU_R_2020_FR     4
+
 /* possible formats for 3D content*/
 enum {
   HAL_NO_3D = 0x0,
diff --git a/msmcobalt/libqdutils/Android.mk b/msmcobalt/libqdutils/Android.mk
index db6509c..cc0b013 100644
--- a/msmcobalt/libqdutils/Android.mk
+++ b/msmcobalt/libqdutils/Android.mk
@@ -9,7 +9,7 @@
 LOCAL_CFLAGS                  := $(common_flags) -DLOG_TAG=\"qdutils\" -Wno-sign-conversion
 LOCAL_ADDITIONAL_DEPENDENCIES := $(common_deps)
 LOCAL_COPY_HEADERS_TO         := $(common_header_export_path)
-LOCAL_COPY_HEADERS            := display_config.h
+LOCAL_COPY_HEADERS            := display_config.h qd_utils.h
 LOCAL_SRC_FILES               := profiler.cpp \
                                  qd_utils.cpp \
                                  display_config.cpp
diff --git a/msmcobalt/libqdutils/qdMetaData.h b/msmcobalt/libqdutils/qdMetaData.h
index 725e094..2b0b8c6 100644
--- a/msmcobalt/libqdutils/qdMetaData.h
+++ b/msmcobalt/libqdutils/qdMetaData.h
@@ -38,6 +38,8 @@
     ITU_R_601,
     ITU_R_601_FR,
     ITU_R_709,
+    ITU_R_2020,
+    ITU_R_2020_FR,
 };
 
 enum IGC_t {
diff --git a/msmcobalt/sdm/include/private/hw_info_types.h b/msmcobalt/sdm/include/private/hw_info_types.h
index 93fb81b..e3bd579 100644
--- a/msmcobalt/sdm/include/private/hw_info_types.h
+++ b/msmcobalt/sdm/include/private/hw_info_types.h
@@ -180,6 +180,7 @@
   bool separate_rotator = false;
   bool has_qseed3 = false;
   bool has_concurrent_writeback = false;
+  bool has_ppp = false;
   uint32_t writeback_index = kHWBlockMax;
   HWDynBwLimitInfo dyn_bw_info;
   std::vector<HWPipeCaps> hw_pipes;
diff --git a/msmcobalt/sdm/include/utils/debug.h b/msmcobalt/sdm/include/utils/debug.h
index a0d8967..99254ad 100644
--- a/msmcobalt/sdm/include/utils/debug.h
+++ b/msmcobalt/sdm/include/utils/debug.h
@@ -77,6 +77,7 @@
   static bool IsUbwcTiledFrameBuffer();
   static bool IsAVRDisabled();
   static bool IsExtAnimDisabled();
+  static DisplayError GetMixerResolution(uint32_t *width, uint32_t *height);
   static bool GetProperty(const char *property_name, char *value);
   static bool SetProperty(const char *property_name, const char *value);
 
diff --git a/msmcobalt/sdm/libs/core/display_base.cpp b/msmcobalt/sdm/libs/core/display_base.cpp
index 050167c..d7036e3 100644
--- a/msmcobalt/sdm/libs/core/display_base.cpp
+++ b/msmcobalt/sdm/libs/core/display_base.cpp
@@ -59,11 +59,17 @@
   hw_intf_->GetDisplayAttributes(active_index, &display_attributes_);
   fb_config_ = display_attributes_;
 
-  error = hw_intf_->GetMixerAttributes(&mixer_attributes_);
+  error = Debug::GetMixerResolution(&mixer_attributes_.width, &mixer_attributes_.height);
   if (error != kErrorNone) {
-    return error;
+    error = hw_intf_->GetMixerAttributes(&mixer_attributes_);
+    if (error != kErrorNone) {
+      return error;
+    }
   }
 
+  req_mixer_width_ = mixer_attributes_.width;
+  req_mixer_height_ = mixer_attributes_.height;
+
   // Override x_pixels and y_pixels of frame buffer with mixer width and height
   fb_config_.x_pixels = mixer_attributes_.width;
   fb_config_.y_pixels = mixer_attributes_.height;
@@ -446,6 +452,16 @@
 
   case kStateOn:
     error = hw_intf_->PowerOn();
+    if (error != kErrorNone) {
+      return error;
+    }
+
+    error = comp_manager_->ReconfigureDisplay(display_comp_ctx_, display_attributes_,
+                                              hw_panel_info_, mixer_attributes_, fb_config_);
+    if (error != kErrorNone) {
+      return error;
+    }
+
     active = true;
     break;
 
@@ -893,7 +909,16 @@
 
 DisplayError DisplayBase::SetMixerResolution(uint32_t width, uint32_t height) {
   lock_guard<recursive_mutex> obj(recursive_mutex_);
-  return ReconfigureMixer(width, height);
+
+  DisplayError error = ReconfigureMixer(width, height);
+  if (error != kErrorNone) {
+    return error;
+  }
+
+  req_mixer_width_ = width;
+  req_mixer_height_ = height;
+
+  return kErrorNone;
 }
 
 DisplayError DisplayBase::GetMixerResolution(uint32_t *width, uint32_t *height) {
@@ -912,6 +937,10 @@
   lock_guard<recursive_mutex> obj(recursive_mutex_);
   DisplayError error = kErrorNone;
 
+  if (!width || !height) {
+    return kErrorParameters;
+  }
+
   HWMixerAttributes mixer_attributes;
   mixer_attributes.width = width;
   mixer_attributes.height = height;
@@ -924,6 +953,24 @@
   return ReconfigureDisplay();
 }
 
+bool DisplayBase::NeedsDownScale(const LayerRect &src_rect, const LayerRect &dst_rect,
+                                 bool needs_rotation) {
+  float src_width = FLOAT(src_rect.right - src_rect.left);
+  float src_height = FLOAT(src_rect.bottom - src_rect.top);
+  float dst_width = FLOAT(dst_rect.right - dst_rect.left);
+  float dst_height = FLOAT(dst_rect.bottom - dst_rect.top);
+
+  if (needs_rotation) {
+    std::swap(src_width, src_height);
+  }
+
+  if ((src_width > dst_width) || (src_height > dst_height)) {
+    return true;
+  }
+
+  return false;
+}
+
 bool DisplayBase::NeedsMixerReconfiguration(LayerStack *layer_stack, uint32_t *new_mixer_width,
                                             uint32_t *new_mixer_height) {
   lock_guard<recursive_mutex> obj(recursive_mutex_);
@@ -935,19 +982,18 @@
   LayerRect fb_rect = (LayerRect) {0.0f, 0.0f, FLOAT(fb_width), FLOAT(fb_height)};
   uint32_t mixer_width = mixer_attributes_.width;
   uint32_t mixer_height = mixer_attributes_.height;
+  uint32_t display_width = display_attributes_.x_pixels;
+  uint32_t display_height = display_attributes_.y_pixels;
 
   RectOrientation fb_orientation = GetOrientation(fb_rect);
   uint32_t max_layer_area = 0;
   uint32_t max_area_layer_index = 0;
   std::vector<Layer *> layers = layer_stack->layers;
+  uint32_t align_x = display_attributes_.is_device_split ? 4 : 2;
+  uint32_t align_y = 2;
 
   for (uint32_t i = 0; i < layer_count; i++) {
     Layer *layer = layers.at(i);
-    LayerBuffer *layer_buffer = layer->input_buffer;
-
-    if (!layer_buffer->flags.video) {
-      continue;
-    }
 
     uint32_t layer_width = UINT32(layer->src_rect.right - layer->src_rect.left);
     uint32_t layer_height = UINT32(layer->src_rect.bottom - layer->src_rect.top);
@@ -959,14 +1005,17 @@
     }
   }
 
-  if (max_layer_area > fb_area) {
+  // TODO(user): Mark layer which needs downscaling on GPU fallback as priority layer and use MDP
+  // for composition to avoid quality mismatch between GPU and MDP switch(idle timeout usecase).
+  if (max_layer_area >= fb_area) {
     Layer *layer = layers.at(max_area_layer_index);
+    bool needs_rotation = (layer->transform.rotation == 90.0f);
 
     uint32_t layer_width = UINT32(layer->src_rect.right - layer->src_rect.left);
     uint32_t layer_height = UINT32(layer->src_rect.bottom - layer->src_rect.top);
-    LayerRect layer_rect = (LayerRect){0.0f, 0.0f, FLOAT(layer_width), FLOAT(layer_height)};
+    LayerRect layer_dst_rect = {};
 
-    RectOrientation layer_orientation = GetOrientation(layer_rect);
+    RectOrientation layer_orientation = GetOrientation(layer->src_rect);
     if (layer_orientation != kOrientationUnknown &&
         fb_orientation != kOrientationUnknown) {
       if (layer_orientation != fb_orientation) {
@@ -975,16 +1024,23 @@
     }
 
     // Align the width and height according to fb's aspect ratio
-    layer_width = UINT32((FLOAT(fb_width) / FLOAT(fb_height)) * layer_height);
+    *new_mixer_width = FloorToMultipleOf(UINT32((FLOAT(fb_width) / FLOAT(fb_height)) *
+                                         layer_height), align_x);
+    *new_mixer_height = FloorToMultipleOf(layer_height, align_y);
 
-    *new_mixer_width = layer_width;
-    *new_mixer_height = layer_height;
+    LayerRect dst_domain = {0.0f, 0.0f, FLOAT(*new_mixer_width), FLOAT(*new_mixer_height)};
+
+    MapRect(fb_rect, dst_domain, layer->dst_rect, &layer_dst_rect);
+    if (NeedsDownScale(layer->src_rect, layer_dst_rect, needs_rotation)) {
+      *new_mixer_width = display_width;
+      *new_mixer_height = display_height;
+    }
 
     return true;
   } else {
-    if (fb_width != mixer_width || fb_height != mixer_height) {
-      *new_mixer_width = fb_width;
-      *new_mixer_height = fb_height;
+    if (req_mixer_width_ != mixer_width || req_mixer_height_ != mixer_height) {
+      *new_mixer_width = req_mixer_width_;
+      *new_mixer_height = req_mixer_height_;
 
       return true;
     }
diff --git a/msmcobalt/sdm/libs/core/display_base.h b/msmcobalt/sdm/libs/core/display_base.h
index 2bc94b7..43c5280 100644
--- a/msmcobalt/sdm/libs/core/display_base.h
+++ b/msmcobalt/sdm/libs/core/display_base.h
@@ -125,6 +125,7 @@
   bool NeedsMixerReconfiguration(LayerStack *layer_stack, uint32_t *new_mixer_width,
                                  uint32_t *new_mixer_height);
   DisplayError ReconfigureMixer(uint32_t width, uint32_t height);
+  bool NeedsDownScale(const LayerRect &src_rect, const LayerRect &dst_rect, bool needs_rotation);
 
   recursive_mutex recursive_mutex_;
   DisplayType display_type_;
@@ -156,6 +157,8 @@
   HWDisplayAttributes display_attributes_ = {};
   HWMixerAttributes mixer_attributes_ = {};
   DisplayConfigVariableInfo fb_config_ = {};
+  uint32_t req_mixer_width_ = 0;
+  uint32_t req_mixer_height_ = 0;
 
  private:
   // Unused
diff --git a/msmcobalt/sdm/libs/core/fb/hw_device.cpp b/msmcobalt/sdm/libs/core/fb/hw_device.cpp
index 27168bb..ecb5889 100644
--- a/msmcobalt/sdm/libs/core/fb/hw_device.cpp
+++ b/msmcobalt/sdm/libs/core/fb/hw_device.cpp
@@ -375,9 +375,9 @@
 
     DLOGV_IF(kTagDriverConfig, "************************ DestScalar[%d] **************************",
              dest_scalar_data->dest_scaler_ndx);
-    DLOGV_IF(kTagDriverConfig, "Mixer WxH %dx%d", dest_scalar_data->lm_width,
-             dest_scalar_data->lm_height);
-    DLOGI_IF(kTagDriverConfig, "*****************************************************************");
+    DLOGV_IF(kTagDriverConfig, "Mixer WxH %dx%d flags %x", dest_scalar_data->lm_width,
+             dest_scalar_data->lm_height, dest_scalar_data->flags);
+    DLOGV_IF(kTagDriverConfig, "*****************************************************************");
   }
   mdp_commit.dest_scaler_cnt = UINT32(hw_layer_info.dest_scale_info_map.size());
 
@@ -404,6 +404,12 @@
   DLOGI("mdp_commit: flags = %x, release fence = %x", mdp_commit.flags, mdp_commit.release_fence);
   DLOGI("left_roi: x = %d, y = %d, w = %d, h = %d", l_roi.x, l_roi.y, l_roi.w, l_roi.h);
   DLOGI("right_roi: x = %d, y = %d, w = %d, h = %d", r_roi.x, r_roi.y, r_roi.w, r_roi.h);
+  for (uint32_t i = 0; i < mdp_commit.dest_scaler_cnt; i++) {
+    mdp_destination_scaler_data *dest_scalar_data = &mdp_dest_scalar_data_[i];
+
+    DLOGI("Dest scalar index %d Mixer WxH %dx%d", dest_scalar_data->dest_scaler_ndx,
+          dest_scalar_data->lm_width, dest_scalar_data->lm_height);
+  }
   for (uint32_t i = 0; i < mdp_commit.input_layer_cnt; i++) {
     const mdp_input_layer &layer = mdp_layers[i];
     const mdp_rect &src_rect = layer.src_rect;
@@ -1260,9 +1266,9 @@
 
   if (mixer_attributes.width > display_attributes_.x_pixels ||
       mixer_attributes.height > display_attributes_.y_pixels) {
-    DLOGW("Input resolution exceeds display resolution! input: res %dx%d display: res %dx%d",
-          mixer_attributes.width, mixer_attributes.height, display_attributes_.x_pixels,
-          display_attributes_.y_pixels);
+    DLOGW_IF(kTagDriverConfig, "Input resolution exceeds display resolution! input: res %dx%d "\
+             "display: res %dx%d", mixer_attributes.width, mixer_attributes.height,
+             display_attributes_.x_pixels, display_attributes_.y_pixels);
     return kErrorNotSupported;
   }
 
@@ -1272,8 +1278,8 @@
   }
 
   if (mixer_attributes.width > max_input_width) {
-    DLOGW("Input width exceeds width limit! input_width %d width_limit %d", mixer_attributes.width,
-          max_input_width);
+    DLOGW_IF(kTagDriverConfig, "Input width exceeds width limit! input_width %d width_limit %d",
+             mixer_attributes.width, max_input_width);
     return kErrorNotSupported;
   }
 
@@ -1282,8 +1288,9 @@
     FLOAT(display_attributes_.x_pixels) / FLOAT(display_attributes_.y_pixels);
 
   if (display_aspect_ratio != mixer_aspect_ratio) {
-    DLOGW("Aspect ratio mismatch! input: res %dx%d display: res %dx%d", mixer_attributes.width,
-          mixer_attributes.height, display_attributes_.x_pixels, display_attributes_.y_pixels);
+    DLOGW_IF(kTagDriverConfig, "Aspect ratio mismatch! input: res %dx%d display: res %dx%d",
+             mixer_attributes.width, mixer_attributes.height, display_attributes_.x_pixels,
+             display_attributes_.y_pixels);
     return kErrorNotSupported;
   }
 
@@ -1291,8 +1298,8 @@
   float scale_y = FLOAT(display_attributes_.y_pixels) / FLOAT(mixer_attributes.height);
   float max_scale_up = hw_resource_.hw_dest_scalar_info.max_scale_up;
   if (scale_x > max_scale_up || scale_y > max_scale_up) {
-    DLOGW("Up scaling ratio exceeds for destination scalar upscale limit scale_x %f scale_y %f " \
-          "max_scale_up %f", scale_x, scale_y, max_scale_up);
+    DLOGW_IF(kTagDriverConfig, "Up scaling ratio exceeds for destination scalar upscale " \
+             "limit scale_x %f scale_y %f max_scale_up %f", scale_x, scale_y, max_scale_up);
     return kErrorNotSupported;
   }
 
diff --git a/msmcobalt/sdm/libs/core/fb/hw_info.cpp b/msmcobalt/sdm/libs/core/fb/hw_info.cpp
index 121b7c0..ef450c0 100644
--- a/msmcobalt/sdm/libs/core/fb/hw_info.cpp
+++ b/msmcobalt/sdm/libs/core/fb/hw_info.cpp
@@ -247,6 +247,8 @@
             hw_resource->separate_rotator = true;
           } else if (!strncmp(tokens[i], "qseed3", strlen("qseed3"))) {
             hw_resource->has_qseed3 = true;
+          } else if (!strncmp(tokens[i], "has_ppp", strlen("has_ppp"))) {
+            hw_resource->has_ppp = true;
           } else if (!strncmp(tokens[i], "concurrent_writeback", strlen("concurrent_writeback"))) {
             hw_resource->has_concurrent_writeback = true;
           } else if (!strncmp(tokens[i], "avr", strlen("avr"))) {
diff --git a/msmcobalt/sdm/libs/core/fb/hw_scale.cpp b/msmcobalt/sdm/libs/core/fb/hw_scale.cpp
index 3d175e5..4933412 100644
--- a/msmcobalt/sdm/libs/core/fb/hw_scale.cpp
+++ b/msmcobalt/sdm/libs/core/fb/hw_scale.cpp
@@ -134,14 +134,6 @@
     mdp_scale = &scale_data_v2_.at(index);
   } else {
     mdp_scale_data_v2 mdp_dest_scale;
-    mdp_destination_scaler_data *dest_scalar =
-      reinterpret_cast<mdp_destination_scaler_data *>(mdp_commit->dest_scaler);
-
-    dest_scalar[index].flags = MDP_DESTSCALER_ENABLE;
-
-    if (scale_data.enable.detail_enhance) {
-      dest_scalar[index].flags |= MDP_DESTSCALER_ENHANCER_UPDATE;
-    }
 
     dest_scale_data_v2_.insert(std::make_pair(index, mdp_dest_scale));
     mdp_scale = &dest_scale_data_v2_[index];
@@ -151,6 +143,17 @@
                       (scale_data.enable.direction_detection ? ENABLE_DIRECTION_DETECTION : 0) |
                       (scale_data.enable.detail_enhance ? ENABLE_DETAIL_ENHANCE : 0);
 
+  if (sub_block_type == kHWDestinationScalar) {
+    mdp_destination_scaler_data *mdp_dest_scalar =
+      reinterpret_cast<mdp_destination_scaler_data *>(mdp_commit->dest_scaler);
+
+    mdp_dest_scalar[index].flags = mdp_scale->enable ? MDP_DESTSCALER_ENABLE : 0;
+
+    if (scale_data.enable.detail_enhance) {
+      mdp_dest_scalar[index].flags |= MDP_DESTSCALER_ENHANCER_UPDATE;
+    }
+  }
+
   for (int i = 0; i < MAX_PLANES; i++) {
     const HWPlane &plane = scale_data.plane[i];
     mdp_scale->init_phase_x[i] = plane.init_phase_x;
diff --git a/msmcobalt/sdm/libs/core/strategy.cpp b/msmcobalt/sdm/libs/core/strategy.cpp
index 7a983e5..1734b9c 100644
--- a/msmcobalt/sdm/libs/core/strategy.cpp
+++ b/msmcobalt/sdm/libs/core/strategy.cpp
@@ -26,6 +26,7 @@
 #include <utils/debug.h>
 
 #include "strategy.h"
+#include "utils/rect.h"
 
 #define __CLASS__ "Strategy"
 
@@ -130,17 +131,30 @@
   // Mark all application layers for GPU composition. Find GPU target buffer and store its index for
   // programming the hardware.
   LayerStack *layer_stack = hw_layers_info_->stack;
-  uint32_t &hw_layer_count = hw_layers_info_->count;
-  hw_layer_count = 0;
-
   for (uint32_t i = 0; i < hw_layers_info_->app_layer_count; i++) {
     layer_stack->layers.at(i)->composition = kCompositionGPU;
   }
 
-  Layer *gpu_target_layer = layer_stack->layers.at(hw_layers_info_->gpu_target_index);
-  hw_layers_info_->updated_src_rect[hw_layer_count] = gpu_target_layer->src_rect;
-  hw_layers_info_->updated_dst_rect[hw_layer_count] = gpu_target_layer->dst_rect;
-  hw_layers_info_->index[hw_layer_count++] = hw_layers_info_->gpu_target_index;
+  if (!extn_start_success_) {
+    // When mixer resolution and panel resolutions are same (1600x2560) and FB resolution is
+    // 1080x1920 FB_Target destination coordinates(mapped to FB resolution 1080x1920) need to
+    // be mapped to destination coordinates of mixer resolution(1600x2560).
+    hw_layers_info_->count = 0;
+    uint32_t &hw_layer_count = hw_layers_info_->count;
+    Layer *gpu_target_layer = layer_stack->layers.at(hw_layers_info_->gpu_target_index);
+    float layer_mixer_width = FLOAT(mixer_attributes_.width);
+    float layer_mixer_height = FLOAT(mixer_attributes_.height);
+    float fb_width = FLOAT(fb_config_.x_pixels);
+    float fb_height = FLOAT(fb_config_.y_pixels);
+    LayerRect src_domain = (LayerRect){0.0f, 0.0f, fb_width, fb_height};
+    LayerRect dst_domain = (LayerRect){0.0f, 0.0f, layer_mixer_width, layer_mixer_height};
+
+    hw_layers_info_->updated_src_rect[hw_layer_count] = gpu_target_layer->src_rect;
+    MapRect(src_domain, dst_domain, gpu_target_layer->dst_rect,
+            &hw_layers_info_->updated_dst_rect[hw_layer_count]);
+
+    hw_layers_info_->index[hw_layer_count++] = hw_layers_info_->gpu_target_index;
+  }
 
   tried_default_ = true;
 
@@ -179,9 +193,7 @@
                          const HWDisplayAttributes &display_attributes,
                          const HWMixerAttributes &mixer_attributes,
                          const DisplayConfigVariableInfo &fb_config) {
-  hw_panel_info_ = hw_panel_info;
-  display_attributes_ = display_attributes;
-  mixer_attributes_ = mixer_attributes;
+  DisplayError error = kErrorNone;
 
   if (!extension_intf_) {
     return kErrorNone;
@@ -194,12 +206,22 @@
     partial_update_intf_ = NULL;
   }
 
-  extension_intf_->CreatePartialUpdate(display_type_, hw_resource_info_, hw_panel_info_,
-                                       mixer_attributes_, display_attributes_,
+  extension_intf_->CreatePartialUpdate(display_type_, hw_resource_info_, hw_panel_info,
+                                       mixer_attributes, display_attributes,
                                        &partial_update_intf_);
 
-  return strategy_intf_->Reconfigure(hw_panel_info_.mode, hw_panel_info_.s3d_mode, mixer_attributes,
+  error = strategy_intf_->Reconfigure(hw_panel_info.mode, hw_panel_info.s3d_mode, mixer_attributes,
                                      fb_config);
+  if (error != kErrorNone) {
+    return error;
+  }
+
+  hw_panel_info_ = hw_panel_info;
+  display_attributes_ = display_attributes;
+  mixer_attributes_ = mixer_attributes;
+  fb_config_ = fb_config;
+
+  return kErrorNone;
 }
 
 }  // namespace sdm
diff --git a/msmcobalt/sdm/libs/utils/debug.cpp b/msmcobalt/sdm/libs/utils/debug.cpp
index cf60a37..4a8e070 100644
--- a/msmcobalt/sdm/libs/utils/debug.cpp
+++ b/msmcobalt/sdm/libs/utils/debug.cpp
@@ -30,6 +30,7 @@
 #include <stdlib.h>
 #include <utils/debug.h>
 #include <utils/constants.h>
+#include <string>
 
 namespace sdm {
 
@@ -161,6 +162,22 @@
   return (value == 1);
 }
 
+DisplayError Debug::GetMixerResolution(uint32_t *width, uint32_t *height) {
+  char value[64];
+
+  DisplayError error = debug_.debug_handler_->GetProperty("sdm.mixer_resolution", value);
+  if (error !=kErrorNone) {
+    return error;
+  }
+
+  std::string str(value);
+
+  *width = UINT32(stoi(str));
+  *height = UINT32(stoi(str.substr(str.find('x') + 1)));
+
+  return kErrorNone;
+}
+
 bool Debug::GetProperty(const char* property_name, char* value) {
   if (debug_.debug_handler_->GetProperty(property_name, value) != kErrorNone) {
     return false;