Merge "hwc: Reset all connected panels during ESD"
diff --git a/composer/Android.mk b/composer/Android.mk
index 733d15c..658a208 100644
--- a/composer/Android.mk
+++ b/composer/Android.mk
@@ -47,7 +47,8 @@
                                  vendor.display.config@1.8 \
                                  vendor.display.config@1.9 \
                                  vendor.display.config@1.10 \
-                                 vendor.display.config@1.11
+                                 vendor.display.config@1.11 \
+                                 vendor.display.config@1.12
 
 LOCAL_SRC_FILES               := QtiComposer.cpp QtiComposerClient.cpp service.cpp \
                                  QtiComposerHandleImporter.cpp \
diff --git a/composer/hwc_display.cpp b/composer/hwc_display.cpp
index 7d6d9b7..38daad0 100644
--- a/composer/hwc_display.cpp
+++ b/composer/hwc_display.cpp
@@ -1786,7 +1786,7 @@
   }
 }
 
-int HWCDisplay::SetFrameBufferResolution(uint32_t x_pixels, uint32_t y_pixels) {
+int HWCDisplay::SetFrameBufferConfig(uint32_t x_pixels, uint32_t y_pixels) {
   if (x_pixels <= 0 || y_pixels <= 0) {
     DLOGW("Unsupported config: x_pixels=%d, y_pixels=%d", x_pixels, y_pixels);
     return -EINVAL;
@@ -1811,12 +1811,25 @@
   // Create rects to represent the new source and destination crops
   LayerRect crop = LayerRect(0, 0, FLOAT(x_pixels), FLOAT(y_pixels));
   hwc_rect_t scaled_display_frame = {0, 0, INT(x_pixels), INT(y_pixels)};
+  auto client_target_layer = client_target_->GetSDMLayer();
+  client_target_layer->src_rect = crop;
   ApplyScanAdjustment(&scaled_display_frame);
   client_target_->SetLayerDisplayFrame(scaled_display_frame);
   client_target_->ResetPerFrameData();
 
+  DLOGI("New framebuffer resolution (%dx%d)", fb_config.x_pixels, fb_config.y_pixels);
+
+  return 0;
+}
+
+int HWCDisplay::SetFrameBufferResolution(uint32_t x_pixels, uint32_t y_pixels) {
+  int error = SetFrameBufferConfig(x_pixels, y_pixels);
+  if (error < 0) {
+    DLOGV("SetFrameBufferConfig failed. Error = %d", error);
+    return error;
+  }
+
   auto client_target_layer = client_target_->GetSDMLayer();
-  client_target_layer->src_rect = crop;
 
   int aligned_width;
   int aligned_height;
@@ -1845,8 +1858,6 @@
   client_target_layer->input_buffer.unaligned_height = y_pixels;
   client_target_layer->plane_alpha = 255;
 
-  DLOGI("New framebuffer resolution (%dx%d)", fb_config.x_pixels, fb_config.y_pixels);
-
   return 0;
 }
 
diff --git a/composer/hwc_display.h b/composer/hwc_display.h
index b9632a2..aec1bc5 100644
--- a/composer/hwc_display.h
+++ b/composer/hwc_display.h
@@ -213,6 +213,10 @@
     return HWC2::Error::Unsupported;
   }
 
+  virtual bool IsSmartPanelConfig(uint32_t config_id) {
+    return false;
+  }
+
   // Display Configurations
   static uint32_t GetThrottlingRefreshRate() { return HWCDisplay::throttling_refresh_rate_; }
   static void SetThrottlingRefreshRate(uint32_t newRefreshRate)
@@ -398,6 +402,7 @@
   uint32_t SanitizeRefreshRate(uint32_t req_refresh_rate);
   virtual void GetUnderScanConfig() { }
   int32_t SetClientTargetDataSpace(int32_t dataspace);
+  int SetFrameBufferConfig(uint32_t x_pixels, uint32_t y_pixels);
 
   bool validated_ = false;
   bool layer_stack_invalid_ = true;
diff --git a/composer/hwc_display_builtin.cpp b/composer/hwc_display_builtin.cpp
index e6f33ba..85cdda6 100644
--- a/composer/hwc_display_builtin.cpp
+++ b/composer/hwc_display_builtin.cpp
@@ -965,9 +965,28 @@
   }
 
   Layer *sdm_layer = client_target_->GetSDMLayer();
-  SetFrameBufferResolution(sdm_layer->input_buffer.unaligned_width,
-                           sdm_layer->input_buffer.unaligned_height);
+  uint32_t fb_width = 0, fb_height = 0;
+
+  GetFrameBufferResolution(&fb_width, &fb_height);
+
+  if (fb_width != sdm_layer->input_buffer.unaligned_width ||
+      fb_height != sdm_layer->input_buffer.unaligned_height) {
+    if (SetFrameBufferConfig(sdm_layer->input_buffer.unaligned_width,
+                             sdm_layer->input_buffer.unaligned_height)) {
+      return HWC2::Error::BadParameter;
+    }
+  }
 
   return HWC2::Error::None;
 }
+
+bool HWCDisplayBuiltIn::IsSmartPanelConfig(uint32_t config_id) {
+  if (config_id < hwc_config_map_.size()) {
+    uint32_t index = hwc_config_map_.at(config_id);
+    return variable_config_map_.at(index).smart_panel;
+  }
+
+  return false;
+}
+
 }  // namespace sdm
diff --git a/composer/hwc_display_builtin.h b/composer/hwc_display_builtin.h
index 6838fda..a3ed162 100644
--- a/composer/hwc_display_builtin.h
+++ b/composer/hwc_display_builtin.h
@@ -100,6 +100,7 @@
   virtual HWC2::Error UpdatePowerMode(HWC2::PowerMode mode);
   virtual HWC2::Error SetClientTarget(buffer_handle_t target, int32_t acquire_fence,
                                       int32_t dataspace, hwc_region_t damage);
+  virtual bool IsSmartPanelConfig(uint32_t config_id);
 
  private:
   HWCDisplayBuiltIn(CoreInterface *core_intf, BufferAllocator *buffer_allocator,
diff --git a/composer/hwc_session.h b/composer/hwc_session.h
index f75d97e..3d6a436 100644
--- a/composer/hwc_session.h
+++ b/composer/hwc_session.h
@@ -20,7 +20,7 @@
 #ifndef __HWC_SESSION_H__
 #define __HWC_SESSION_H__
 
-#include <vendor/display/config/1.11/IDisplayConfig.h>
+#include <vendor/display/config/1.12/IDisplayConfig.h>
 
 #include <core/core_interface.h>
 #include <utils/locker.h>
@@ -47,7 +47,7 @@
 
 namespace sdm {
 
-using vendor::display::config::V1_11::IDisplayConfig;
+using vendor::display::config::V1_12::IDisplayConfig;
 using vendor::display::config::V1_10::IDisplayCWBCallback;
 
 using ::android::hardware::Return;
@@ -393,6 +393,7 @@
                                      uint32_t disp_id, const Rect &rect, bool post_processed,
                                      const hidl_handle& buffer) override;
   Return<int32_t> setQsyncMode(uint32_t disp_id, IDisplayConfig::QsyncMode mode) override;
+  Return<bool> isSmartPanelConfig(uint32_t disp_id, uint32_t config_id) override;
 
   // QClient methods
   virtual android::status_t notifyCallback(uint32_t command, const android::Parcel *input_parcel,
diff --git a/composer/hwc_session_services.cpp b/composer/hwc_session_services.cpp
index d639371..4ff1bdf 100644
--- a/composer/hwc_session_services.cpp
+++ b/composer/hwc_session_services.cpp
@@ -923,6 +923,20 @@
   return cwb_.PostBuffer(callback, post_processed, buffer);
 }
 
+Return<bool> HWCSession::isSmartPanelConfig(uint32_t disp_id, uint32_t config_id) {
+  if (disp_id != qdutils::DISPLAY_PRIMARY) {
+    return false;
+  }
+
+  SCOPE_LOCK(locker_[disp_id]);
+  if (!hwc_display_[disp_id]) {
+    DLOGE("Display %d is not created yet.", disp_id);
+    return false;
+  }
+
+  return hwc_display_[disp_id]->IsSmartPanelConfig(config_id);
+}
+
 int32_t HWCSession::CWB::PostBuffer(const sp<IDisplayCWBCallback> &callback, bool post_processed,
                                     const hidl_handle& buffer) {
   SCOPE_LOCK(queue_lock_);
diff --git a/composer/vendor.qti.hardware.display.composer-service.xml b/composer/vendor.qti.hardware.display.composer-service.xml
index 7789fd3..3f0431a 100644
--- a/composer/vendor.qti.hardware.display.composer-service.xml
+++ b/composer/vendor.qti.hardware.display.composer-service.xml
@@ -48,7 +48,7 @@
     <hal format="hidl">
         <name>vendor.display.config</name>
         <transport>hwbinder</transport>
-        <version>1.11</version>
+        <version>1.12</version>
         <interface>
             <name>IDisplayConfig</name>
             <instance>default</instance>
diff --git a/config/display-product.mk b/config/display-product.mk
index 586b7f7..8a1d367 100644
--- a/config/display-product.mk
+++ b/config/display-product.mk
@@ -26,6 +26,8 @@
     vendor.display.config@1.8.vendor \
     vendor.display.config@1.9.vendor \
     vendor.display.config@1.10.vendor \
+    vendor.display.config@1.11.vendor \
+    vendor.display.config@1.12.vendor \
     vendor.qti.hardware.display.mapper@2.0.vendor \
     vendor.qti.hardware.display.mapper@3.0.vendor \
     modetest
diff --git a/sdm/include/core/display_interface.h b/sdm/include/core/display_interface.h
index 2cfdb40..6506056 100644
--- a/sdm/include/core/display_interface.h
+++ b/sdm/include/core/display_interface.h
@@ -216,11 +216,12 @@
   uint32_t fps = 0;               //!< Frame rate per second.
   uint32_t vsync_period_ns = 0;   //!< VSync period in nanoseconds.
   bool is_yuv = false;            //!< If the display output is in YUV format.
+  bool smart_panel = false;       //!< If the display config has smart panel.
 
   bool operator==(const DisplayConfigVariableInfo& info) const {
     return ((x_pixels == info.x_pixels) && (y_pixels == info.y_pixels) && (x_dpi == info.x_dpi) &&
             (y_dpi == info.y_dpi) && (fps == info.fps) && (vsync_period_ns == info.vsync_period_ns)
-            && (is_yuv == info.is_yuv));
+            && (is_yuv == info.is_yuv) && (smart_panel == info.smart_panel));
   }
 };
 
diff --git a/sdm/libs/core/drm/hw_device_drm.cpp b/sdm/libs/core/drm/hw_device_drm.cpp
index d3fd241..62f5923 100644
--- a/sdm/libs/core/drm/hw_device_drm.cpp
+++ b/sdm/libs/core/drm/hw_device_drm.cpp
@@ -588,6 +588,9 @@
     mm_width = connector_info_.mmWidth;
     mm_height = connector_info_.mmHeight;
     topology = connector_info_.modes[index].topology;
+    if (mode.flags & DRM_MODE_FLAG_CMD_MODE_PANEL) {
+      display_attributes_[index].smart_panel = true;
+    }
   }
 
   display_attributes_[index].x_pixels = mode.hdisplay;