Merge "sdm: Handle disable partial update and display config change"
diff --git a/sdm/libs/core/display_base.cpp b/sdm/libs/core/display_base.cpp
index 383bdba..136168b 100644
--- a/sdm/libs/core/display_base.cpp
+++ b/sdm/libs/core/display_base.cpp
@@ -488,9 +488,11 @@
 
   default:
     DLOGE("Spurious state = %d transition requested.", state);
-    break;
+    return kErrorParameters;
   }
 
+  DisablePartialUpdateOneFrame();
+
   if (error == kErrorNone) {
     active_ = active;
     state_ = state;
diff --git a/sdm/libs/core/drm/hw_device_drm.cpp b/sdm/libs/core/drm/hw_device_drm.cpp
index f1ebb76..d5bf482 100644
--- a/sdm/libs/core/drm/hw_device_drm.cpp
+++ b/sdm/libs/core/drm/hw_device_drm.cpp
@@ -738,6 +738,7 @@
     return kErrorUndefined;
   }
 
+  SetFullROI();
   drm_atomic_intf_->Perform(DRMOps::CONNECTOR_SET_POWER_MODE, token_.conn_id, DRMPowerMode::OFF);
   drm_atomic_intf_->Perform(DRMOps::CRTC_SET_ACTIVE, token_.crtc_id, 0);
   int ret = drm_atomic_intf_->Commit(true /* synchronous */, false /* retain_planes */);
@@ -1559,4 +1560,17 @@
   }
 }
 
+void HWDeviceDRM::SetFullROI() {
+  // Reset the CRTC ROI and connector ROI only for the panel that supports partial update
+  if (!hw_panel_info_.partial_update) {
+    return;
+  }
+  uint32_t index = current_mode_index_;
+  DRMRect crtc_rects = {0, 0, mixer_attributes_.width, mixer_attributes_.height};
+  DRMRect conn_rects = {0, 0, display_attributes_[index].x_pixels,
+                         display_attributes_[index].y_pixels};
+  drm_atomic_intf_->Perform(DRMOps::CRTC_SET_ROI, token_.crtc_id, 1, &crtc_rects);
+  drm_atomic_intf_->Perform(DRMOps::CONNECTOR_SET_ROI, token_.conn_id, 1, &conn_rects);
+}
+
 }  // namespace sdm
diff --git a/sdm/libs/core/drm/hw_device_drm.h b/sdm/libs/core/drm/hw_device_drm.h
index b08c0e6..3af3b77 100644
--- a/sdm/libs/core/drm/hw_device_drm.h
+++ b/sdm/libs/core/drm/hw_device_drm.h
@@ -133,6 +133,7 @@
   bool IsResolutionSwitchEnabled() const { return resolution_switch_enabled_; }
   void SetTopology(sde_drm::DRMTopology drm_topology, HWTopology *hw_topology);
   void SetMultiRectMode(const uint32_t flags, sde_drm::DRMMultiRectMode *target);
+  void SetFullROI();
 
   class Registry {
    public:
diff --git a/sdm/libs/hwc2/hwc_display.cpp b/sdm/libs/hwc2/hwc_display.cpp
index 142b84b..213230f 100644
--- a/sdm/libs/hwc2/hwc_display.cpp
+++ b/sdm/libs/hwc2/hwc_display.cpp
@@ -1334,6 +1334,7 @@
       dump_frame_index_++;
     }
   }
+  config_pending_ = false;
 
   geometry_changes_ = GeometryChanges::kNone;
   flush_ = false;
@@ -1940,9 +1941,16 @@
 }
 
 int HWCDisplay::SetActiveDisplayConfig(uint32_t config) {
-  int status = (display_intf_->SetActiveConfig(config) == kErrorNone) ? 0 : -1;
+  if (display_config_ == config) {
+    return 0;
+  }
+  display_config_ = config;
+  config_pending_ = true;
   validated_ = false;
-  return status;
+
+  callbacks_->Refresh(id_);
+
+  return 0;
 }
 
 int HWCDisplay::GetActiveDisplayConfig(uint32_t *config) {
diff --git a/sdm/libs/hwc2/hwc_display.h b/sdm/libs/hwc2/hwc_display.h
index 4153600..3977e73 100644
--- a/sdm/libs/hwc2/hwc_display.h
+++ b/sdm/libs/hwc2/hwc_display.h
@@ -304,6 +304,8 @@
   HWCToneMapper *tone_mapper_ = nullptr;
   uint32_t num_configs_ = 0;
   int disable_hdr_handling_ = 0;  // disables HDR handling.
+  uint32_t display_config_ = 0;
+  bool config_pending_ = false;
 
  private:
   void DumpInputBuffers(void);
diff --git a/sdm/libs/hwc2/hwc_display_external.cpp b/sdm/libs/hwc2/hwc_display_external.cpp
index 934ad70..8e00cfd 100644
--- a/sdm/libs/hwc2/hwc_display_external.cpp
+++ b/sdm/libs/hwc2/hwc_display_external.cpp
@@ -115,6 +115,14 @@
     return status;
   }
 
+  if (config_pending_) {
+    if (display_intf_->SetActiveConfig(display_config_) != kErrorNone) {
+      DLOGW("Invalid display config %d", display_config_);
+      // Reset the display config with active config
+      display_intf_->GetActiveConfig(&display_config_);
+    }
+  }
+
   BuildLayerStack();
 
   if (layer_set_.empty()) {
diff --git a/sdm/libs/hwc2/hwc_display_primary.cpp b/sdm/libs/hwc2/hwc_display_primary.cpp
index be05e0a..531f209 100644
--- a/sdm/libs/hwc2/hwc_display_primary.cpp
+++ b/sdm/libs/hwc2/hwc_display_primary.cpp
@@ -178,6 +178,13 @@
     MarkLayersForClientComposition();
   }
 
+  if (config_pending_) {
+    if (display_intf_->SetActiveConfig(display_config_) != kErrorNone) {
+      DLOGW("Invalid display config %d", display_config_);
+      // Reset the display config with active config
+      display_intf_->GetActiveConfig(&display_config_);
+    }
+  }
   // Fill in the remaining blanks in the layers and add them to the SDM layerstack
   BuildLayerStack();
   // Checks and replaces layer stack for solid fill