Merge "sdm: Add interface to disable PU for one frame"
diff --git a/sdm/include/core/display_interface.h b/sdm/include/core/display_interface.h
index adb1851..dfea4c8 100644
--- a/sdm/include/core/display_interface.h
+++ b/sdm/include/core/display_interface.h
@@ -341,6 +341,11 @@
   */
   virtual DisplayError ControlPartialUpdate(bool enable, uint32_t *pending) = 0;
 
+  /*! @brief Method to disable partial update for at least 1 frame.
+    @return \link DisplayError \endlink
+  */
+  virtual DisplayError DisablePartialUpdateOneFrame() = 0;
+
   /*! @brief Method to set the mode of the primary display.
 
     @param[in] mode the new display mode.
diff --git a/sdm/libs/core/display_base.cpp b/sdm/libs/core/display_base.cpp
index 5df06f6..5523ff2 100644
--- a/sdm/libs/core/display_base.cpp
+++ b/sdm/libs/core/display_base.cpp
@@ -174,9 +174,12 @@
 }
 
 DisplayError DisplayBase::Prepare(LayerStack *layer_stack) {
+  SCOPE_LOCK(locker_);
+  return PrepareLocked(layer_stack);
+}
+
+DisplayError DisplayBase::PrepareLocked(LayerStack *layer_stack) {
   DisplayError error = kErrorNone;
-  bool disable_partial_update = false;
-  uint32_t pending = 0;
 
   if (!layer_stack) {
     return kErrorParameters;
@@ -193,16 +196,13 @@
     return kErrorPermission;
   }
 
-  // Request to disable partial update only if it is currently enabled.
-  if (color_mgr_ && partial_update_control_) {
-    disable_partial_update = color_mgr_->NeedsPartialUpdateDisable();
-    if (disable_partial_update) {
-      ControlPartialUpdate(false, &pending);
-    }
+  if (color_mgr_ && color_mgr_->NeedsPartialUpdateDisable()) {
+    DisablePartialUpdateOneFrameLocked();
   }
 
-  if (one_frame_full_roi_) {
-    ControlPartialUpdate(false, &pending);
+  if (partial_update_control_ == false || disable_pu_one_frame_) {
+    comp_manager_->ControlPartialUpdate(display_comp_ctx_, false /* enable */);
+    disable_pu_one_frame_ = false;
   }
 
   // Clean hw layers for reuse.
@@ -244,14 +244,6 @@
   }
 
   comp_manager_->PostPrepare(display_comp_ctx_, &hw_layers_);
-  if (disable_partial_update) {
-    ControlPartialUpdate(true, &pending);
-  }
-
-  if (one_frame_full_roi_) {
-    ControlPartialUpdate(true, &pending);
-    one_frame_full_roi_ = false;
-  }
 
   return error;
 }
@@ -314,6 +306,10 @@
     }
   }
 
+  if (partial_update_control_) {
+    comp_manager_->ControlPartialUpdate(display_comp_ctx_, true /* enable */);
+  }
+
   error = comp_manager_->PostCommit(display_comp_ctx_, &hw_layers_);
   if (error != kErrorNone) {
     return error;
@@ -455,6 +451,11 @@
 }
 
 DisplayError DisplayBase::SetActiveConfig(uint32_t index) {
+  SCOPE_LOCK(locker_);
+  return SetActiveConfigLocked(index);
+}
+
+DisplayError DisplayBase::SetActiveConfigLocked(uint32_t index) {
   DisplayError error = kErrorNone;
   uint32_t active_index = 0;
 
@@ -484,13 +485,18 @@
   error = comp_manager_->RegisterDisplay(display_type_, attrib, hw_panel_info_,
                                          &display_comp_ctx_);
 
-  if (error == kErrorNone && partial_update_control_) {
-    one_frame_full_roi_ = true;
+  if (error == kErrorNone) {
+    DisablePartialUpdateOneFrameLocked();
   }
 
   return error;
 }
 
+DisplayError DisplayBase::SetActiveConfig(DisplayConfigVariableInfo *variable_info) {
+  SCOPE_LOCK(locker_);
+  return SetActiveConfigLocked(variable_info);
+}
+
 DisplayError DisplayBase::SetMaxMixerStages(uint32_t max_mixer_stages) {
   DisplayError error = kErrorNone;
 
@@ -504,32 +510,13 @@
 }
 
 DisplayError DisplayBase::ControlPartialUpdate(bool enable, uint32_t *pending) {
-  if (!pending) {
-    return kErrorParameters;
-  }
+  SCOPE_LOCK(locker_);
+  return ControlPartialUpdateLocked(enable, pending);
+}
 
-  if (!hw_panel_info_.partial_update) {
-    // Nothing to be done.
-    DLOGI("partial update is not applicable for display=%d", display_type_);
-    return kErrorNotSupported;
-  }
-
-  *pending = 0;
-  if (enable == partial_update_control_) {
-    DLOGI("Same state transition is requested.");
-    return kErrorNone;
-  }
-
-  partial_update_control_ = enable;
-  comp_manager_->ControlPartialUpdate(display_comp_ctx_, enable);
-
-  if (!enable) {
-    // If the request is to turn off feature, new draw call is required to have
-    // the new setting into effect.
-    *pending = 1;
-  }
-
-  return kErrorNone;
+DisplayError DisplayBase::DisablePartialUpdateOneFrame() {
+  SCOPE_LOCK(locker_);
+  return DisablePartialUpdateOneFrameLocked();
 }
 
 DisplayError DisplayBase::SetDisplayMode(uint32_t mode) {
diff --git a/sdm/libs/core/display_base.h b/sdm/libs/core/display_base.h
index c290e96..0f316fd 100644
--- a/sdm/libs/core/display_base.h
+++ b/sdm/libs/core/display_base.h
@@ -50,7 +50,7 @@
   virtual ~DisplayBase() { }
   virtual DisplayError Init();
   virtual DisplayError Deinit();
-  virtual DisplayError Prepare(LayerStack *layer_stack);
+  DisplayError Prepare(LayerStack *layer_stack) final;
   virtual DisplayError Commit(LayerStack *layer_stack);
   virtual DisplayError Flush();
   virtual DisplayError GetDisplayState(DisplayState *state);
@@ -59,9 +59,11 @@
   virtual DisplayError GetActiveConfig(uint32_t *index);
   virtual DisplayError GetVSyncState(bool *enabled);
   virtual DisplayError SetDisplayState(DisplayState state);
-  virtual DisplayError SetActiveConfig(uint32_t index);
+  DisplayError SetActiveConfig(uint32_t index) final;
+  DisplayError SetActiveConfig(DisplayConfigVariableInfo *variable_info) final;
   virtual DisplayError SetMaxMixerStages(uint32_t max_mixer_stages);
-  virtual DisplayError ControlPartialUpdate(bool enable, uint32_t *pending);
+  DisplayError ControlPartialUpdate(bool enable, uint32_t *pending) final;
+  DisplayError DisablePartialUpdateOneFrame() final;
   virtual DisplayError SetDisplayMode(uint32_t mode);
   virtual DisplayError IsScalingValid(const LayerRect &crop, const LayerRect &dst, bool rotate90);
   virtual bool IsUnderscanSupported();
@@ -77,6 +79,17 @@
   virtual DisplayError SetVSyncState(bool enable);
 
  protected:
+  virtual DisplayError PrepareLocked(LayerStack *layer_stack);
+  virtual DisplayError SetActiveConfigLocked(uint32_t index);
+  virtual DisplayError SetActiveConfigLocked(DisplayConfigVariableInfo *variable_info) {
+    return kErrorNotSupported;
+  }
+  virtual DisplayError ControlPartialUpdateLocked(bool enable, uint32_t *pending) {
+    return kErrorNotSupported;
+  }
+  virtual DisplayError DisablePartialUpdateOneFrameLocked() {
+    return kErrorNotSupported;
+  }
   // DumpImpl method
   void AppendDump(char *buffer, uint32_t length);
 
@@ -84,6 +97,7 @@
   const char *GetName(const LayerComposition &composition);
   DisplayError ValidateGPUTarget(LayerStack *layer_stack);
 
+  Locker locker_;
   DisplayType display_type_;
   DisplayEventHandler *event_handler_ = NULL;
   HWDeviceType hw_device_type_;
@@ -107,9 +121,9 @@
   ColorManagerProxy *color_mgr_ = NULL;  // each display object owns its ColorManagerProxy
   bool partial_update_control_ = true;
   HWEventsInterface *hw_events_intf_ = NULL;
+  bool disable_pu_one_frame_ = false;
 
  private:
-  bool one_frame_full_roi_ = false;
   // Unused
   virtual DisplayError GetConfig(DisplayConfigFixedInfo *variable_info) {
     return kErrorNone;
diff --git a/sdm/libs/core/display_hdmi.cpp b/sdm/libs/core/display_hdmi.cpp
index 9a9628a..9a7f46a 100644
--- a/sdm/libs/core/display_hdmi.cpp
+++ b/sdm/libs/core/display_hdmi.cpp
@@ -106,12 +106,10 @@
   return error;
 }
 
-DisplayError DisplayHDMI::Prepare(LayerStack *layer_stack) {
-  SCOPE_LOCK(locker_);
-
+DisplayError DisplayHDMI::PrepareLocked(LayerStack *layer_stack) {
   SetS3DMode(layer_stack);
 
-  return DisplayBase::Prepare(layer_stack);
+  return DisplayBase::PrepareLocked(layer_stack);
 }
 
 DisplayError DisplayHDMI::Commit(LayerStack *layer_stack) {
@@ -154,16 +152,6 @@
   return DisplayBase::SetDisplayState(state);
 }
 
-DisplayError DisplayHDMI::SetActiveConfig(DisplayConfigVariableInfo *variable_info) {
-  SCOPE_LOCK(locker_);
-  return kErrorNotSupported;
-}
-
-DisplayError DisplayHDMI::SetActiveConfig(uint32_t index) {
-  SCOPE_LOCK(locker_);
-  return DisplayBase::SetActiveConfig(index);
-}
-
 DisplayError DisplayHDMI::SetVSyncState(bool enable) {
   SCOPE_LOCK(locker_);
   return DisplayBase::SetVSyncState(enable);
diff --git a/sdm/libs/core/display_hdmi.h b/sdm/libs/core/display_hdmi.h
index 88e553d..ad96394 100644
--- a/sdm/libs/core/display_hdmi.h
+++ b/sdm/libs/core/display_hdmi.h
@@ -42,7 +42,6 @@
               RotatorInterface *rotator_intf);
   virtual DisplayError Init();
   virtual DisplayError Deinit();
-  virtual DisplayError Prepare(LayerStack *layer_stack);
   virtual DisplayError Commit(LayerStack *layer_stack);
   virtual DisplayError Flush();
   virtual DisplayError GetDisplayState(DisplayState *state);
@@ -51,8 +50,6 @@
   virtual DisplayError GetActiveConfig(uint32_t *index);
   virtual DisplayError GetVSyncState(bool *enabled);
   virtual DisplayError SetDisplayState(DisplayState state);
-  virtual DisplayError SetActiveConfig(DisplayConfigVariableInfo *variable_info);
-  virtual DisplayError SetActiveConfig(uint32_t index);
   virtual DisplayError SetVSyncState(bool enable);
   virtual void SetIdleTimeoutMs(uint32_t timeout_ms);
   virtual DisplayError SetMaxMixerStages(uint32_t max_mixer_stages);
@@ -74,11 +71,11 @@
   virtual void CECMessage(char *message);
 
  private:
+  virtual DisplayError PrepareLocked(LayerStack *layer_stack);
   virtual uint32_t GetBestConfig(HWS3DMode s3d_mode);
   virtual void GetScanSupport();
   virtual void SetS3DMode(LayerStack *layer_stack);
 
-  Locker locker_;
   HWScanSupport scan_support_;
   std::map<LayerBufferS3DFormat, HWS3DMode> s3d_format_to_mode_;
   std::vector<const char *> event_list_ = {"vsync_event", "idle_notify", "cec/rd_msg",
diff --git a/sdm/libs/core/display_primary.cpp b/sdm/libs/core/display_primary.cpp
index e5751df..dc87d5c 100644
--- a/sdm/libs/core/display_primary.cpp
+++ b/sdm/libs/core/display_primary.cpp
@@ -86,11 +86,6 @@
   return error;
 }
 
-DisplayError DisplayPrimary::Prepare(LayerStack *layer_stack) {
-  SCOPE_LOCK(locker_);
-  return DisplayBase::Prepare(layer_stack);
-}
-
 DisplayError DisplayPrimary::Commit(LayerStack *layer_stack) {
   SCOPE_LOCK(locker_);
   DisplayError error = kErrorNone;
@@ -181,16 +176,6 @@
   return kErrorNone;
 }
 
-DisplayError DisplayPrimary::SetActiveConfig(DisplayConfigVariableInfo *variable_info) {
-  SCOPE_LOCK(locker_);
-  return kErrorNotSupported;
-}
-
-DisplayError DisplayPrimary::SetActiveConfig(uint32_t index) {
-  SCOPE_LOCK(locker_);
-  return DisplayBase::SetActiveConfig(index);
-}
-
 DisplayError DisplayPrimary::SetVSyncState(bool enable) {
   SCOPE_LOCK(locker_);
   return DisplayBase::SetVSyncState(enable);
@@ -214,22 +199,16 @@
 DisplayError DisplayPrimary::SetDisplayMode(uint32_t mode) {
   SCOPE_LOCK(locker_);
   DisplayError error = kErrorNone;
-  HWDisplayMode hw_display_mode = kModeDefault;
+  HWDisplayMode hw_display_mode = static_cast<HWDisplayMode>(mode);
+  uint32_t pending = 0;
 
   if (!active_) {
     DLOGW("Invalid display state = %d. Panel must be on.", state_);
     return kErrorNotSupported;
   }
 
-  switch (mode) {
-  case kModeVideo:
-    hw_display_mode = kModeVideo;
-    break;
-  case kModeCommand:
-    hw_display_mode = kModeCommand;
-    break;
-  default:
-    DLOGW("Invalid panel mode parameters. Requested = %d", mode);
+  if (hw_display_mode != kModeCommand && hw_display_mode != kModeVideo) {
+    DLOGW("Invalid panel mode parameters. Requested = %d", hw_display_mode);
     return kErrorParameters;
   }
 
@@ -246,16 +225,11 @@
     return error;
   }
 
-  // Disable PU if the previous PU state is on when switching to video mode, and re-enable PU when
-  // switching back to command mode.
-  bool toggle_partial_update = !(hw_display_mode == kModeVideo);
-  if (partial_update_control_) {
-    comp_manager_->ControlPartialUpdate(display_comp_ctx_, toggle_partial_update);
-  }
-
-  if (hw_display_mode == kModeVideo) {
+  if (mode == kModeVideo) {
+    ControlPartialUpdateLocked(false /* enable */, &pending);
     hw_intf_->SetIdleTimeoutMs(idle_timeout_ms_);
-  } else if (hw_display_mode == kModeCommand) {
+  } else if (mode == kModeCommand) {
+    ControlPartialUpdateLocked(true /* enable */, &pending);
     hw_intf_->SetIdleTimeoutMs(0);
   }
 
@@ -362,5 +336,39 @@
   return hw_intf_->GetPanelBrightness(level);
 }
 
+DisplayError DisplayPrimary::ControlPartialUpdateLocked(bool enable, uint32_t *pending) {
+  if (!pending) {
+    return kErrorParameters;
+  }
+
+  if (!hw_panel_info_.partial_update) {
+    // Nothing to be done.
+    DLOGI("partial update is not applicable for display=%d", display_type_);
+    return kErrorNotSupported;
+  }
+
+  *pending = 0;
+  if (enable == partial_update_control_) {
+    DLOGI("Same state transition is requested.");
+    return kErrorNone;
+  }
+
+  partial_update_control_ = enable;
+
+  if (!enable) {
+    // If the request is to turn off feature, new draw call is required to have
+    // the new setting into effect.
+    *pending = 1;
+  }
+
+  return kErrorNone;
+}
+
+DisplayError DisplayPrimary::DisablePartialUpdateOneFrameLocked() {
+  disable_pu_one_frame_ = true;
+
+  return kErrorNone;
+}
+
 }  // namespace sdm
 
diff --git a/sdm/libs/core/display_primary.h b/sdm/libs/core/display_primary.h
index d3a37cd..09de09a 100644
--- a/sdm/libs/core/display_primary.h
+++ b/sdm/libs/core/display_primary.h
@@ -41,7 +41,6 @@
                  RotatorInterface *rotator_intf);
   virtual DisplayError Init();
   virtual DisplayError Deinit();
-  virtual DisplayError Prepare(LayerStack *layer_stack);
   virtual DisplayError Commit(LayerStack *layer_stack);
   virtual DisplayError Flush();
   virtual DisplayError GetDisplayState(DisplayState *state);
@@ -50,8 +49,6 @@
   virtual DisplayError GetActiveConfig(uint32_t *index);
   virtual DisplayError GetVSyncState(bool *enabled);
   virtual DisplayError SetDisplayState(DisplayState state);
-  virtual DisplayError SetActiveConfig(DisplayConfigVariableInfo *variable_info);
-  virtual DisplayError SetActiveConfig(uint32_t index);
   virtual DisplayError SetVSyncState(bool enable);
   virtual void SetIdleTimeoutMs(uint32_t timeout_ms);
   virtual DisplayError SetMaxMixerStages(uint32_t max_mixer_stages);
@@ -73,7 +70,9 @@
   virtual void CECMessage(char *message) { }
 
  private:
-  Locker locker_;
+  virtual DisplayError ControlPartialUpdateLocked(bool enable, uint32_t *pending);
+  virtual DisplayError DisablePartialUpdateOneFrameLocked();
+
   uint32_t idle_timeout_ms_ = 0;
   std::vector<const char *> event_list_ = {"vsync_event", "show_blank_event", "idle_notify",
                                            "msm_fb_thermal_level", "thread_exit"};
diff --git a/sdm/libs/core/display_virtual.cpp b/sdm/libs/core/display_virtual.cpp
index ff8da68..2d7cd7b 100644
--- a/sdm/libs/core/display_virtual.cpp
+++ b/sdm/libs/core/display_virtual.cpp
@@ -69,11 +69,6 @@
   return error;
 }
 
-DisplayError DisplayVirtual::Prepare(LayerStack *layer_stack) {
-  SCOPE_LOCK(locker_);
-  return DisplayBase::Prepare(layer_stack);
-}
-
 DisplayError DisplayVirtual::Commit(LayerStack *layer_stack) {
   SCOPE_LOCK(locker_);
   return DisplayBase::Commit(layer_stack);
@@ -122,8 +117,7 @@
   return DisplayBase::SetDisplayState(state);
 }
 
-DisplayError DisplayVirtual::SetActiveConfig(DisplayConfigVariableInfo *variable_info) {
-  SCOPE_LOCK(locker_);
+DisplayError DisplayVirtual::SetActiveConfigLocked(DisplayConfigVariableInfo *variable_info) {
   DisplayError error = kErrorNone;
 
   if (!variable_info) {
@@ -149,11 +143,6 @@
   return error;
 }
 
-DisplayError DisplayVirtual::SetActiveConfig(uint32_t index) {
-  SCOPE_LOCK(locker_);
-  return kErrorNotSupported;
-}
-
 DisplayError DisplayVirtual::SetVSyncState(bool enable) {
   SCOPE_LOCK(locker_);
   return kErrorNotSupported;
diff --git a/sdm/libs/core/display_virtual.h b/sdm/libs/core/display_virtual.h
index b26be12..4e26632 100644
--- a/sdm/libs/core/display_virtual.h
+++ b/sdm/libs/core/display_virtual.h
@@ -40,7 +40,6 @@
                  RotatorInterface *rotator_intf);
   virtual DisplayError Init();
   virtual DisplayError Deinit();
-  virtual DisplayError Prepare(LayerStack *layer_stack);
   virtual DisplayError Commit(LayerStack *layer_stack);
   virtual DisplayError Flush();
   virtual DisplayError GetDisplayState(DisplayState *state);
@@ -49,8 +48,6 @@
   virtual DisplayError GetActiveConfig(uint32_t *index);
   virtual DisplayError GetVSyncState(bool *enabled);
   virtual DisplayError SetDisplayState(DisplayState state);
-  virtual DisplayError SetActiveConfig(DisplayConfigVariableInfo *variable_info);
-  virtual DisplayError SetActiveConfig(uint32_t index);
   virtual DisplayError SetVSyncState(bool enable);
   virtual void SetIdleTimeoutMs(uint32_t timeout_ms);
   virtual DisplayError SetMaxMixerStages(uint32_t max_mixer_stages);
@@ -64,7 +61,10 @@
   virtual DisplayError SetCursorPosition(int x, int y);
 
  private:
-  Locker locker_;
+  virtual DisplayError SetActiveConfigLocked(uint32_t index) {
+    return kErrorNotSupported;
+  }
+  virtual DisplayError SetActiveConfigLocked(DisplayConfigVariableInfo *variable_info);
   HWDisplayAttributes display_attributes_;
 };
 
diff --git a/sdm/libs/hwc/hwc_display.cpp b/sdm/libs/hwc/hwc_display.cpp
index f829f68..2945674 100644
--- a/sdm/libs/hwc/hwc_display.cpp
+++ b/sdm/libs/hwc/hwc_display.cpp
@@ -792,16 +792,6 @@
   return error;
 }
 
-DisplayError HWCDisplay::ControlPartialUpdate(bool enable, uint32_t *pending) {
-  DisplayError error = kErrorNone;
-
-  if (display_intf_) {
-    error = display_intf_->ControlPartialUpdate(enable, pending);
-  }
-
-  return error;
-}
-
 LayerBufferFormat HWCDisplay::GetSDMFormat(const int32_t &source, const int flags) {
   LayerBufferFormat format = kFormatInvalid;
   if (flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED) {
diff --git a/sdm/libs/hwc/hwc_display.h b/sdm/libs/hwc/hwc_display.h
index 8bc7a91..d07420f 100644
--- a/sdm/libs/hwc/hwc_display.h
+++ b/sdm/libs/hwc/hwc_display.h
@@ -66,7 +66,9 @@
   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);
-  virtual DisplayError ControlPartialUpdate(bool enable, uint32_t *pending);
+  virtual DisplayError ControlPartialUpdate(bool enable, uint32_t *pending) {
+    return kErrorNotSupported;
+  }
   virtual uint32_t GetLastPowerMode();
   virtual int SetFrameBufferResolution(uint32_t x_pixels, uint32_t y_pixels);
   virtual void GetFrameBufferResolution(uint32_t *x_pixels, uint32_t *y_pixels);
@@ -136,6 +138,9 @@
   virtual uint32_t RoundToStandardFPS(float fps);
   virtual uint32_t SanitizeRefreshRate(uint32_t req_refresh_rate);
   virtual void PrepareDynamicRefreshRate(Layer *layer);
+  virtual DisplayError DisablePartialUpdateOneFrame() {
+    return kErrorNotSupported;
+  }
   inline void SetRect(const hwc_rect_t &source, LayerRect *target);
   inline void SetRect(const hwc_frect_t &source, LayerRect *target);
   inline void SetComposition(const int32_t &source, LayerComposition *target);
diff --git a/sdm/libs/hwc/hwc_display_primary.cpp b/sdm/libs/hwc/hwc_display_primary.cpp
index 32ff73b..4a43e4d 100644
--- a/sdm/libs/hwc/hwc_display_primary.cpp
+++ b/sdm/libs/hwc/hwc_display_primary.cpp
@@ -382,9 +382,6 @@
   frame_capture_buffer_queued_ = false;
   post_processed_output_ = false;
   output_buffer_ = {};
-
-  uint32_t pending = 0;  // Just a temporary to satisfy the API
-  ControlPartialUpdate(true  /* enable */, &pending);
 }
 
 void HWCDisplayPrimary::HandleFrameDump() {
@@ -413,9 +410,6 @@
     output_buffer_ = {};
     output_buffer_info_ = {};
     output_buffer_base_ = nullptr;
-
-    uint32_t pending = 0;  // Just a temporary to satisfy the API
-    ControlPartialUpdate(true  /* enable */, &pending);
   }
 }
 
@@ -454,8 +448,7 @@
 
   output_buffer_base_ = buffer;
   post_processed_output_ = true;
-  uint32_t pending = 0;  // Just a temporary to satisfy the API
-  ControlPartialUpdate(false  /* enable */, &pending);
+  DisablePartialUpdateOneFrame();
 }
 
 int HWCDisplayPrimary::FrameCaptureAsync(const BufferInfo& output_buffer_info,
@@ -489,12 +482,30 @@
   frame_capture_buffer_queued_ = true;
   // Status is only cleared on a new call to dump and remains valid otherwise
   frame_capture_status_ = -EAGAIN;
-
-  uint32_t pending = 0;  // Just a temporary to satisfy the API
-  ControlPartialUpdate(false  /* enable */, &pending);
+  DisablePartialUpdateOneFrame();
 
   return 0;
 }
 
+DisplayError HWCDisplayPrimary::ControlPartialUpdate(bool enable, uint32_t *pending) {
+  DisplayError error = kErrorNone;
+
+  if (display_intf_) {
+    error = display_intf_->ControlPartialUpdate(enable, pending);
+  }
+
+  return error;
+}
+
+DisplayError HWCDisplayPrimary::DisablePartialUpdateOneFrame() {
+  DisplayError error = kErrorNone;
+
+  if (display_intf_) {
+    error = display_intf_->DisablePartialUpdateOneFrame();
+  }
+
+  return error;
+}
+
 }  // namespace sdm
 
diff --git a/sdm/libs/hwc/hwc_display_primary.h b/sdm/libs/hwc/hwc_display_primary.h
index 8c02731..072507b 100644
--- a/sdm/libs/hwc/hwc_display_primary.h
+++ b/sdm/libs/hwc/hwc_display_primary.h
@@ -54,12 +54,14 @@
   virtual void SetFrameDumpConfig(uint32_t count, uint32_t bit_mask_layer_type);
   virtual int FrameCaptureAsync(const BufferInfo& output_buffer_info, bool post_processed);
   virtual int GetFrameCaptureStatus() { return frame_capture_status_; }
+  virtual DisplayError ControlPartialUpdate(bool enable, uint32_t *pending);
 
  private:
   HWCDisplayPrimary(CoreInterface *core_intf, BufferAllocator *buffer_allocator,
                     hwc_procs_t const **hwc_procs, qService::QService *qservice);
   void SetMetaDataRefreshRateFlag(bool enable);
   virtual DisplayError SetDisplayMode(uint32_t mode);
+  virtual DisplayError DisablePartialUpdateOneFrame();
   void ProcessBootAnimCompleted(hwc_display_contents_1_t *content_list);
   void SetQDCMSolidFillInfo(bool enable, uint32_t color);
   void ToggleCPUHint(bool set);