summaryrefslogtreecommitdiff
path: root/sdm
diff options
context:
space:
mode:
authorPadmanabhan Komanduru <pkomandu@codeaurora.org>2020-04-13 14:19:16 +0530
committerBipin Kumar <bipikuma@codeaurora.org>2020-06-18 00:52:21 +0530
commit539f124562f2cf839c9de6fd1b514ba4881e93ff (patch)
tree2a6097e98cfce39e0e2a2a2950d4f1af03f425b1 /sdm
parentaca273d7b5542ede0a19d59f869fb5d8f0ee450e (diff)
sdm: add support for POMS in and out of doze mode transitions
Change-Id: I24c518df4ed38c246c938dea3f064a851c665483
Diffstat (limited to 'sdm')
-rwxr-xr-xsdm/libs/core/display_base.cpp10
-rw-r--r--sdm/libs/core/display_builtin.cpp20
-rw-r--r--sdm/libs/core/display_builtin.h1
-rw-r--r--sdm/libs/core/drm/hw_device_drm.cpp120
-rw-r--r--sdm/libs/core/drm/hw_device_drm.h8
-rw-r--r--sdm/libs/core/drm/hw_peripheral_drm.cpp106
-rw-r--r--sdm/libs/core/drm/hw_peripheral_drm.h4
-rw-r--r--sdm/libs/hwc2/hwc_display_builtin.cpp34
-rw-r--r--sdm/libs/hwc2/hwc_display_builtin.h2
9 files changed, 267 insertions, 38 deletions
diff --git a/sdm/libs/core/display_base.cpp b/sdm/libs/core/display_base.cpp
index 75f61368..cc2855e1 100755
--- a/sdm/libs/core/display_base.cpp
+++ b/sdm/libs/core/display_base.cpp
@@ -617,6 +617,11 @@ DisplayError DisplayBase::SetDisplayState(DisplayState state, bool teardown,
return kErrorParameters;
}
+ error = ReconfigureDisplay();
+ if (error != kErrorNone) {
+ return error;
+ }
+
DisablePartialUpdateOneFrame();
if (error == kErrorNone) {
@@ -2006,6 +2011,11 @@ DisplayError DisplayBase::HandlePendingPowerState(int32_t retire_fence) {
if (pending_doze_) {
state_ = kStateDoze;
+ DisplayError error = ReconfigureDisplay();
+ if (error != kErrorNone) {
+ return error;
+ }
+ event_handler_->Refresh();
}
if (pending_power_on_) {
state_ = kStateOn;
diff --git a/sdm/libs/core/display_builtin.cpp b/sdm/libs/core/display_builtin.cpp
index 5ab5e512..2bd90042 100644
--- a/sdm/libs/core/display_builtin.cpp
+++ b/sdm/libs/core/display_builtin.cpp
@@ -193,6 +193,7 @@ DisplayError DisplayBuiltIn::Commit(LayerStack *layer_stack) {
lock_guard<recursive_mutex> obj(recursive_mutex_);
DisplayError error = kErrorNone;
uint32_t app_layer_count = hw_layers_.info.app_layer_count;
+ HWDisplayMode panel_mode = hw_panel_info_.mode;
DTRACE_SCOPED();
@@ -251,6 +252,9 @@ DisplayError DisplayBuiltIn::Commit(LayerStack *layer_stack) {
ControlPartialUpdate(true /* enable */, &pending);
}
+ if (panel_mode != hw_panel_info_.mode) {
+ UpdateDisplayModeParams();
+ }
dpps_info_.Init(this, hw_panel_info_.panel_name);
if (qsync_mode_ == kQsyncModeOneShot) {
@@ -272,10 +276,22 @@ DisplayError DisplayBuiltIn::Commit(LayerStack *layer_stack) {
return error;
}
+void DisplayBuiltIn::UpdateDisplayModeParams() {
+ if (hw_panel_info_.mode == kModeVideo) {
+ uint32_t pending = 0;
+ ControlPartialUpdate(false /* enable */, &pending);
+ } else if (hw_panel_info_.mode == kModeCommand) {
+ // Flush idle timeout value currently set.
+ comp_manager_->SetIdleTimeoutMs(display_comp_ctx_, 0);
+ switch_to_cmd_ = true;
+ }
+}
+
DisplayError DisplayBuiltIn::SetDisplayState(DisplayState state, bool teardown,
int *release_fence) {
lock_guard<recursive_mutex> obj(recursive_mutex_);
DisplayError error = kErrorNone;
+ HWDisplayMode panel_mode = hw_panel_info_.mode;
if ((state == kStateOn) && deferred_config_.IsDeferredState()) {
SetDeferredFpsConfig();
@@ -286,6 +302,10 @@ DisplayError DisplayBuiltIn::SetDisplayState(DisplayState state, bool teardown,
return error;
}
+ if (hw_panel_info_.mode != panel_mode) {
+ UpdateDisplayModeParams();
+ }
+
// Set vsync enable state to false, as driver disables vsync during display power off.
if (state == kStateOff) {
vsync_enable_ = false;
diff --git a/sdm/libs/core/display_builtin.h b/sdm/libs/core/display_builtin.h
index 8d54df66..6da7a87f 100644
--- a/sdm/libs/core/display_builtin.h
+++ b/sdm/libs/core/display_builtin.h
@@ -145,6 +145,7 @@ class DisplayBuiltIn : public DisplayBase, HWEventHandler, DppsPropIntf {
bool CanDeferFpsConfig(uint32_t fps);
void SetDeferredFpsConfig();
void GetFpsConfig(HWDisplayAttributes *display_attributes, HWPanelInfo *panel_info);
+ void UpdateDisplayModeParams();
std::vector<HWEvent> event_list_;
bool avr_prop_disabled_ = false;
diff --git a/sdm/libs/core/drm/hw_device_drm.cpp b/sdm/libs/core/drm/hw_device_drm.cpp
index e8cea73c..007cb2a9 100644
--- a/sdm/libs/core/drm/hw_device_drm.cpp
+++ b/sdm/libs/core/drm/hw_device_drm.cpp
@@ -572,6 +572,7 @@ void HWDeviceDRM::InitializeConfigs() {
}
PopulateDisplayAttributes(i);
}
+ SetDisplaySwitchMode(current_mode_index_);
}
DisplayError HWDeviceDRM::PopulateDisplayAttributes(uint32_t index) {
@@ -838,22 +839,20 @@ DisplayError HWDeviceDRM::GetHWPanelInfo(HWPanelInfo *panel_info) {
return kErrorNone;
}
-DisplayError HWDeviceDRM::SetDisplayAttributes(uint32_t index) {
- if (index >= display_attributes_.size()) {
- DLOGE("Invalid mode index %d mode size %d", index, UINT32(display_attributes_.size()));
- return kErrorParameters;
- }
-
+void HWDeviceDRM::SetDisplaySwitchMode(uint32_t index) {
uint32_t mode_flag = 0;
- uint32_t curr_mode_flag = 0;
+ uint32_t curr_mode_flag = 0, switch_mode_flag = 0;
drmModeModeInfo to_set = connector_info_.modes[index].mode;
drmModeModeInfo current_mode = connector_info_.modes[current_mode_index_].mode;
uint64_t current_bit_clk = connector_info_.modes[current_mode_index_].bit_clk_rate;
+ uint32_t switch_index = 0;
if (to_set.flags & DRM_MODE_FLAG_CMD_MODE_PANEL) {
mode_flag = DRM_MODE_FLAG_CMD_MODE_PANEL;
+ switch_mode_flag = DRM_MODE_FLAG_VID_MODE_PANEL;
} else if (to_set.flags & DRM_MODE_FLAG_VID_MODE_PANEL) {
mode_flag = DRM_MODE_FLAG_VID_MODE_PANEL;
+ switch_mode_flag = DRM_MODE_FLAG_CMD_MODE_PANEL;
}
if (current_mode.flags & DRM_MODE_FLAG_CMD_MODE_PANEL) {
@@ -878,21 +877,70 @@ DisplayError HWDeviceDRM::SetDisplayAttributes(uint32_t index) {
}
current_mode_index_ = index;
+
+ switch_mode_valid_ = false;
+ for (uint32_t mode_index = 0; mode_index < connector_info_.modes.size(); mode_index++) {
+ if ((to_set.vdisplay == connector_info_.modes[mode_index].mode.vdisplay) &&
+ (to_set.hdisplay == connector_info_.modes[mode_index].mode.hdisplay) &&
+ (to_set.vrefresh == connector_info_.modes[mode_index].mode.vrefresh) &&
+ (switch_mode_flag & connector_info_.modes[mode_index].mode.flags)) {
+ switch_index = mode_index;
+ switch_mode_valid_ = true;
+ break;
+ }
+ }
+
+ if (!switch_mode_valid_) {
+ // in case there is no corresponding switch mode with same fps, try for a switch
+ // mode with lowest fps. This is to handle cases where there are multiple video mode fps
+ // but only one command mode for doze like 30 fps.
+ uint32_t refresh_rate = 0;
+ for (uint32_t mode_index = 0; mode_index < connector_info_.modes.size(); mode_index++) {
+ if ((to_set.vdisplay == connector_info_.modes[mode_index].mode.vdisplay) &&
+ (to_set.hdisplay == connector_info_.modes[mode_index].mode.hdisplay) &&
+ (switch_mode_flag & connector_info_.modes[mode_index].mode.flags)) {
+ if (!refresh_rate || (refresh_rate > connector_info_.modes[mode_index].mode.vrefresh)) {
+ switch_index = mode_index;
+ switch_mode_valid_ = true;
+ refresh_rate = connector_info_.modes[mode_index].mode.vrefresh;
+ }
+ }
+ }
+ }
+
+ if (switch_mode_valid_) {
+ if (mode_flag & DRM_MODE_FLAG_VID_MODE_PANEL) {
+ video_mode_index_ = current_mode_index_;
+ cmd_mode_index_ = switch_index;
+ } else {
+ video_mode_index_ = switch_index;
+ cmd_mode_index_ = current_mode_index_;
+ }
+ }
+}
+
+DisplayError HWDeviceDRM::SetDisplayAttributes(uint32_t index) {
+ if (index >= display_attributes_.size()) {
+ DLOGE("Invalid mode index %d mode size %d", index, UINT32(display_attributes_.size()));
+ return kErrorParameters;
+ }
+
+ SetDisplaySwitchMode(index);
PopulateHWPanelInfo();
UpdateMixerAttributes();
- DLOGI_IF(
- kTagDisplay,
- "Display attributes[%d]: WxH: %dx%d, DPI: %fx%f, FPS: %d, LM_SPLIT: %d, V_BACK_PORCH: %d,"
- " V_FRONT_PORCH: %d, V_PULSE_WIDTH: %d, V_TOTAL: %d, H_TOTAL: %d, CLK: %dKHZ,"
- "TOPOLOGY: %d, PanelMode %s", index, display_attributes_[index].x_pixels,
- display_attributes_[index].y_pixels, display_attributes_[index].x_dpi,
- display_attributes_[index].y_dpi, display_attributes_[index].fps,
- display_attributes_[index].is_device_split, display_attributes_[index].v_back_porch,
- display_attributes_[index].v_front_porch, display_attributes_[index].v_pulse_width,
- display_attributes_[index].v_total, display_attributes_[index].h_total,
- display_attributes_[index].clock_khz, display_attributes_[index].topology,
- (mode_flag & DRM_MODE_FLAG_VID_MODE_PANEL) ? "Video" : "Command");
+ DLOGI_IF(kTagDriverConfig,
+ "Display attributes[%d]: WxH: %dx%d, DPI: %fx%f, FPS: %d, LM_SPLIT: %d, V_BACK_PORCH: %d," \
+ " V_FRONT_PORCH: %d, V_PULSE_WIDTH: %d, V_TOTAL: %d, H_TOTAL: %d, CLK: %dKHZ, " \
+ "TOPOLOGY: %d, PanelMode %s", index, display_attributes_[index].x_pixels,
+ display_attributes_[index].y_pixels, display_attributes_[index].x_dpi,
+ display_attributes_[index].y_dpi, display_attributes_[index].fps,
+ display_attributes_[index].is_device_split, display_attributes_[index].v_back_porch,
+ display_attributes_[index].v_front_porch, display_attributes_[index].v_pulse_width,
+ display_attributes_[index].v_total, display_attributes_[index].h_total,
+ display_attributes_[index].clock_khz, display_attributes_[index].topology,
+ (connector_info_.modes[index].mode.flags & DRM_MODE_FLAG_VID_MODE_PANEL) ?
+ "Video" : "Command");
return kErrorNone;
}
@@ -1479,6 +1527,7 @@ DisplayError HWDeviceDRM::AtomicCommit(HWLayers *hw_layers) {
(current_bit_clk == connector_info_.modes[mode_index].bit_clk_rate) &&
(vrefresh_ == connector_info_.modes[mode_index].mode.vrefresh)) {
current_mode_index_ = mode_index;
+ SetDisplaySwitchMode(mode_index);
break;
}
}
@@ -1494,6 +1543,7 @@ DisplayError HWDeviceDRM::AtomicCommit(HWLayers *hw_layers) {
(current_mode.vrefresh == connector_info_.modes[mode_index].mode.vrefresh) &&
(bit_clk_rate_ == connector_info_.modes[mode_index].bit_clk_rate)) {
current_mode_index_ = mode_index;
+ SetDisplaySwitchMode(mode_index);
break;
}
}
@@ -1715,31 +1765,25 @@ void HWDeviceDRM::SetIdleTimeoutMs(uint32_t timeout_ms) {
}
DisplayError HWDeviceDRM::SetDisplayMode(const HWDisplayMode hw_display_mode) {
- uint32_t mode_flag;
+ if (!switch_mode_valid_) {
+ return kErrorNotSupported;
+ }
+
+ uint32_t mode_flag = 0;
if (hw_display_mode == kModeCommand) {
mode_flag = DRM_MODE_FLAG_CMD_MODE_PANEL;
- DLOGI("switch panel mode to command");
+ current_mode_index_ = cmd_mode_index_;
+ DLOGI_IF(kTagDriverConfig, "switch panel mode to command");
} else if (hw_display_mode == kModeVideo) {
mode_flag = DRM_MODE_FLAG_VID_MODE_PANEL;
- DLOGI("switch panel mode to video");
+ current_mode_index_ = video_mode_index_;
+ DLOGI_IF(kTagDriverConfig, "switch panel mode to video");
}
-
- drmModeModeInfo current_mode = connector_info_.modes[current_mode_index_].mode;
- for (uint32_t mode_index = 0; mode_index < connector_info_.modes.size(); mode_index++) {
- if ((current_mode.vdisplay == connector_info_.modes[mode_index].mode.vdisplay) &&
- (current_mode.hdisplay == connector_info_.modes[mode_index].mode.hdisplay) &&
- (current_mode.vrefresh == connector_info_.modes[mode_index].mode.vrefresh) &&
- (mode_flag & connector_info_.modes[mode_index].mode.flags)) {
- current_mode_index_ = mode_index;
- PopulateHWPanelInfo();
- panel_mode_changed_ = mode_flag;
- synchronous_commit_ = true;
- return kErrorNone;
- }
- }
-
- return kErrorNotSupported;
+ PopulateHWPanelInfo();
+ panel_mode_changed_ = mode_flag;
+ synchronous_commit_ = true;
+ return kErrorNone;
}
DisplayError HWDeviceDRM::SetRefreshRate(uint32_t refresh_rate) {
diff --git a/sdm/libs/core/drm/hw_device_drm.h b/sdm/libs/core/drm/hw_device_drm.h
index 8b8ca5b2..5933347c 100644
--- a/sdm/libs/core/drm/hw_device_drm.h
+++ b/sdm/libs/core/drm/hw_device_drm.h
@@ -227,10 +227,18 @@ class HWDeviceDRM : public HWInterface {
bool reset_output_fence_offset_ = false;
uint64_t bit_clk_rate_ = 0;
bool update_mode_ = false;
+ uint32_t video_mode_index_ = 0;
+ uint32_t cmd_mode_index_ = 0;
+ bool switch_mode_valid_ = false;
+ bool doze_poms_switch_done_ = false;
+ bool pending_poms_switch_ = false;
+ bool active_ = false;
DRMPowerMode last_power_mode_ = DRMPowerMode::OFF;
bool pending_doze_ = false;
private:
+ void SetDisplaySwitchMode(uint32_t index);
+
std::string interface_str_ = "DSI";
bool resolution_switch_enabled_ = false;
bool autorefresh_ = false;
diff --git a/sdm/libs/core/drm/hw_peripheral_drm.cpp b/sdm/libs/core/drm/hw_peripheral_drm.cpp
index 64109ecc..85ec982f 100644
--- a/sdm/libs/core/drm/hw_peripheral_drm.cpp
+++ b/sdm/libs/core/drm/hw_peripheral_drm.cpp
@@ -105,6 +105,10 @@ DisplayError HWPeripheralDRM::SetDynamicDSIClock(uint64_t bit_clk_rate) {
return kErrorNotSupported;
}
+ if (doze_poms_switch_done_ || pending_poms_switch_) {
+ return kErrorNotSupported;
+ }
+
bit_clk_rate_ = bit_clk_rate;
update_mode_ = true;
@@ -118,7 +122,27 @@ DisplayError HWPeripheralDRM::GetDynamicDSIClock(uint64_t *bit_clk_rate) {
return kErrorNone;
}
+
+DisplayError HWPeripheralDRM::SetRefreshRate(uint32_t refresh_rate) {
+ if (doze_poms_switch_done_ || pending_poms_switch_) {
+ // poms switch in progress
+ // Defer any refresh rate setting.
+ return kErrorNotSupported;
+ }
+
+ DisplayError error = HWDeviceDRM::SetRefreshRate(refresh_rate);
+ if (error != kErrorNone) {
+ return error;
+ }
+
+ return kErrorNone;
+}
+
DisplayError HWPeripheralDRM::SetDisplayMode(const HWDisplayMode hw_display_mode) {
+ if (doze_poms_switch_done_ || pending_poms_switch_) {
+ return kErrorNotSupported;
+ }
+
DisplayError error = HWDeviceDRM::SetDisplayMode(hw_display_mode);
if (error != kErrorNone) {
return error;
@@ -156,6 +180,15 @@ DisplayError HWPeripheralDRM::Commit(HWLayers *hw_layers) {
// Initialize to default after successful commit
synchronous_commit_ = false;
+ active_ = true;
+
+ if (pending_poms_switch_) {
+ HWDeviceDRM::SetDisplayMode(kModeCommand);
+ hw_panel_info_.bitclk_rates = bitclk_rates_;
+ doze_poms_switch_done_ = true;
+ pending_poms_switch_ = false;
+ }
+
idle_pc_state_ = sde_drm::DRMIdlePCState::NONE;
return error;
@@ -463,6 +496,12 @@ DisplayError HWPeripheralDRM::PowerOn(const HWQosData &qos_data, int *release_fe
return kErrorDeferred;
}
+ if (switch_mode_valid_ && doze_poms_switch_done_ && (current_mode_index_ == cmd_mode_index_)) {
+ HWDeviceDRM::SetDisplayMode(kModeVideo);
+ hw_panel_info_.bitclk_rates = bitclk_rates_;
+ doze_poms_switch_done_ = false;
+ }
+
if (!idle_pc_enabled_) {
drm_atomic_intf_->Perform(sde_drm::DRMOps::CRTC_SET_IDLE_PC_STATE, token_.crtc_id,
sde_drm::DRMIdlePCState::ENABLE);
@@ -473,11 +512,78 @@ DisplayError HWPeripheralDRM::PowerOn(const HWQosData &qos_data, int *release_fe
}
idle_pc_state_ = sde_drm::DRMIdlePCState::NONE;
idle_pc_enabled_ = true;
+ pending_poms_switch_ = false;
+ active_ = true;
+
+ return kErrorNone;
+}
+
+DisplayError HWPeripheralDRM::PowerOff(bool teardown) {
+ DTRACE_SCOPED();
+
+ DisplayError err = HWDeviceDRM::PowerOff(teardown);
+ if (err != kErrorNone) {
+ return err;
+ }
+
+ pending_poms_switch_ = false;
+ active_ = false;
+
+ return kErrorNone;
+}
+
+DisplayError HWPeripheralDRM::Doze(const HWQosData &qos_data, int *release_fence) {
+ DTRACE_SCOPED();
+
+ if (!first_cycle_ && switch_mode_valid_ && !doze_poms_switch_done_ &&
+ (current_mode_index_ == video_mode_index_)) {
+ if (active_) {
+ HWDeviceDRM::SetDisplayMode(kModeCommand);
+ hw_panel_info_.bitclk_rates = bitclk_rates_;
+ doze_poms_switch_done_ = true;
+ } else {
+ pending_poms_switch_ = true;
+ }
+ }
+
+ DisplayError err = HWDeviceDRM::Doze(qos_data, release_fence);
+ if (err != kErrorNone) {
+ return err;
+ }
+
+ if (first_cycle_) {
+ active_ = true;
+ }
+
+ return kErrorNone;
+}
+
+DisplayError HWPeripheralDRM::DozeSuspend(const HWQosData &qos_data, int *release_fence) {
+ DTRACE_SCOPED();
+
+ if (switch_mode_valid_ && !doze_poms_switch_done_ &&
+ (current_mode_index_ == video_mode_index_)) {
+ HWDeviceDRM::SetDisplayMode(kModeCommand);
+ hw_panel_info_.bitclk_rates = bitclk_rates_;
+ doze_poms_switch_done_ = true;
+ }
+
+ DisplayError err = HWDeviceDRM::DozeSuspend(qos_data, release_fence);
+ if (err != kErrorNone) {
+ return err;
+ }
+
+ pending_poms_switch_ = false;
+ active_ = true;
return kErrorNone;
}
DisplayError HWPeripheralDRM::SetDisplayAttributes(uint32_t index) {
+ if (doze_poms_switch_done_ || pending_poms_switch_) {
+ return kErrorNotSupported;
+ }
+
HWDeviceDRM::SetDisplayAttributes(index);
// update bit clk rates.
hw_panel_info_.bitclk_rates = bitclk_rates_;
diff --git a/sdm/libs/core/drm/hw_peripheral_drm.h b/sdm/libs/core/drm/hw_peripheral_drm.h
index 5800e279..92aa90db 100644
--- a/sdm/libs/core/drm/hw_peripheral_drm.h
+++ b/sdm/libs/core/drm/hw_peripheral_drm.h
@@ -57,11 +57,15 @@ class HWPeripheralDRM : public HWDeviceDRM {
virtual DisplayError HandleSecureEvent(SecureEvent secure_event, HWLayers *hw_layers);
virtual DisplayError ControlIdlePowerCollapse(bool enable, bool synchronous);
virtual DisplayError PowerOn(const HWQosData &qos_data, int *release_fence);
+ virtual DisplayError PowerOff(bool teardown);
+ virtual DisplayError Doze(const HWQosData &qos_data, int *release_fence);
+ virtual DisplayError DozeSuspend(const HWQosData &qos_data, int *release_fence);
virtual DisplayError SetDisplayDppsAdROI(void *payload);
virtual DisplayError SetDynamicDSIClock(uint64_t bit_clk_rate);
virtual DisplayError GetDynamicDSIClock(uint64_t *bit_clk_rate);
virtual DisplayError SetDisplayAttributes(uint32_t index);
virtual DisplayError SetDisplayMode(const HWDisplayMode hw_display_mode);
+ virtual DisplayError SetRefreshRate(uint32_t refresh_rate);
virtual DisplayError TeardownConcurrentWriteback(void);
virtual DisplayError SetPanelBrightness(int level);
virtual DisplayError GetPanelBrightness(int *level);
diff --git a/sdm/libs/hwc2/hwc_display_builtin.cpp b/sdm/libs/hwc2/hwc_display_builtin.cpp
index d440893a..e25e40c5 100644
--- a/sdm/libs/hwc2/hwc_display_builtin.cpp
+++ b/sdm/libs/hwc2/hwc_display_builtin.cpp
@@ -310,6 +310,28 @@ bool HWCDisplayBuiltIn::CanSkipCommit() {
return skip_commit;
}
+void HWCDisplayBuiltIn::SetPartialUpdate(DisplayConfigFixedInfo fixed_info) {
+ partial_update_enabled_ = fixed_info.partial_update || (!fixed_info.is_cmdmode);
+ for (auto hwc_layer : layer_set_) {
+ hwc_layer->SetPartialUpdate(partial_update_enabled_);
+ }
+ client_target_->SetPartialUpdate(partial_update_enabled_);
+}
+
+HWC2::Error HWCDisplayBuiltIn::SetPowerMode(HWC2::PowerMode mode, bool teardown) {
+ DisplayConfigFixedInfo fixed_info = {};
+ display_intf_->GetConfig(&fixed_info);
+ bool command_mode = fixed_info.is_cmdmode;
+
+ display_intf_->GetConfig(&fixed_info);
+ is_cmd_mode_ = fixed_info.is_cmdmode;
+ if (is_cmd_mode_ != command_mode) {
+ SetPartialUpdate(fixed_info);
+ }
+
+ return HWC2::Error::None;
+}
+
HWC2::Error HWCDisplayBuiltIn::Present(int32_t *out_retire_fence) {
auto status = HWC2::Error::None;
@@ -329,12 +351,24 @@ HWC2::Error HWCDisplayBuiltIn::Present(int32_t *out_retire_fence) {
DLOGE("Flush failed. Error = %d", error);
}
} else {
+ DisplayConfigFixedInfo fixed_info = {};
+ display_intf_->GetConfig(&fixed_info);
+ bool command_mode = fixed_info.is_cmdmode;
+
status = CommitLayerStack();
if (status == HWC2::Error::None) {
HandleFrameOutput();
SolidFillCommit();
status = PostCommitLayerStack(out_retire_fence);
}
+
+ if (status == HWC2::Error::None) {
+ display_intf_->GetConfig(&fixed_info);
+ is_cmd_mode_ = fixed_info.is_cmdmode;
+ if (is_cmd_mode_ != command_mode) {
+ SetPartialUpdate(fixed_info);
+ }
+ }
}
CloseFd(&output_buffer_.acquire_fence_fd);
diff --git a/sdm/libs/hwc2/hwc_display_builtin.h b/sdm/libs/hwc2/hwc_display_builtin.h
index 8f812dbe..5c75dc77 100644
--- a/sdm/libs/hwc2/hwc_display_builtin.h
+++ b/sdm/libs/hwc2/hwc_display_builtin.h
@@ -100,6 +100,7 @@ class HWCDisplayBuiltIn : public HWCDisplay {
virtual HWC2::Error UpdatePowerMode(HWC2::PowerMode mode);
virtual HWC2::Error PostCommitLayerStack(int32_t *out_retire_fence);
virtual bool IsSmartPanelConfig(uint32_t config_id);
+ virtual HWC2::Error SetPowerMode(HWC2::PowerMode mode, bool teardown);
private:
HWCDisplayBuiltIn(CoreInterface *core_intf, BufferAllocator *buffer_allocator,
@@ -118,6 +119,7 @@ class HWCDisplayBuiltIn : public HWCDisplay {
bool CanSkipCommit();
DisplayError SetMixerResolution(uint32_t width, uint32_t height);
DisplayError GetMixerResolution(uint32_t *width, uint32_t *height);
+ void SetPartialUpdate(DisplayConfigFixedInfo fixed_info);
class PMICInterface {
public:
PMICInterface() { }