Merge "sdm: Add support to defer Fps config"
diff --git a/include/display_properties.h b/include/display_properties.h
index e2a5436..59b52f7 100644
--- a/include/display_properties.h
+++ b/include/display_properties.h
@@ -116,6 +116,7 @@
#define NORMAL_NOC_EFFICIENCY_FACTOR DISPLAY_PROP("normal_noc_efficiency_factor")
#define CAMERA_NOC_EFFICIENCY_FACTOR DISPLAY_PROP("camera_noc_efficiency_factor")
#define ENABLE_HISTOGRAM_INTR DISPLAY_PROP("enable_hist_intr")
+#define DEFER_FPS_FRAME_COUNT DISPLAY_PROP("defer_fps_frame_count")
// Add all vendor.display properties above
diff --git a/sdm/libs/core/display_base.h b/sdm/libs/core/display_base.h
index 6d0de2b..1aca80d 100644
--- a/sdm/libs/core/display_base.h
+++ b/sdm/libs/core/display_base.h
@@ -164,6 +164,7 @@
virtual DisplayError GetQSyncMode(QSyncMode *qsync_mode) { return kErrorNotSupported; }
virtual DisplayError colorSamplingOn();
virtual DisplayError colorSamplingOff();
+ virtual DisplayError ReconfigureDisplay();
protected:
const char *kBt2020Pq = "bt2020_pq";
@@ -178,7 +179,6 @@
void HwRecovery(const HWRecoveryEvent sdm_event_code);
const char *GetName(const LayerComposition &composition);
- DisplayError ReconfigureDisplay();
bool NeedsMixerReconfiguration(LayerStack *layer_stack, uint32_t *new_mixer_width,
uint32_t *new_mixer_height);
DisplayError ReconfigureMixer(uint32_t width, uint32_t height);
diff --git a/sdm/libs/core/display_builtin.cpp b/sdm/libs/core/display_builtin.cpp
index befdc32..33a244c 100644
--- a/sdm/libs/core/display_builtin.cpp
+++ b/sdm/libs/core/display_builtin.cpp
@@ -116,6 +116,10 @@
initColorSamplingState();
+ int value = 0;
+ Debug::Get()->GetProperty(DEFER_FPS_FRAME_COUNT, &value);
+ deferred_config_.frame_count = (value > 0) ? UINT32(value) : 0;
+
return error;
}
@@ -280,7 +284,14 @@
dpps_info_.DppsNotifyOps(kDppsCommitEvent, &display_type_, sizeof(display_type_));
}
- DisplayBase::ReconfigureDisplay();
+ deferred_config_.UpdateDeferCount();
+
+ ReconfigureDisplay();
+
+ if (deferred_config_.CanApplyDeferredState()) {
+ event_handler_->HandleEvent(kInvalidateDisplay);
+ deferred_config_.Clear();
+ }
int idle_time_ms = hw_layers_.info.set_idle_time_ms;
if (idle_time_ms >= 0) {
@@ -322,6 +333,11 @@
int *release_fence) {
lock_guard<recursive_mutex> obj(recursive_mutex_);
DisplayError error = kErrorNone;
+
+ if ((state == kStateOn) && deferred_config_.IsDeferredState()) {
+ SetDeferredFpsConfig();
+ }
+
error = DisplayBase::SetDisplayState(state, teardown, release_fence);
if (error != kErrorNone) {
return error;
@@ -496,8 +512,9 @@
// On success, set current refresh rate to new refresh rate
current_refresh_rate_ = refresh_rate;
handle_idle_timeout_ = false;
+ deferred_config_.MarkDirty();
- return DisplayBase::ReconfigureDisplay();
+ return ReconfigureDisplay();
}
DisplayError DisplayBuiltIn::VSync(int64_t timestamp) {
@@ -1047,4 +1064,119 @@
return same_roi;
}
+DisplayError DisplayBuiltIn::SetActiveConfig(uint32_t index) {
+ deferred_config_.MarkDirty();
+ return DisplayBase::SetActiveConfig(index);
+}
+
+DisplayError DisplayBuiltIn::ReconfigureDisplay() {
+ lock_guard<recursive_mutex> obj(recursive_mutex_);
+ DisplayError error = kErrorNone;
+ HWDisplayAttributes display_attributes;
+ HWMixerAttributes mixer_attributes;
+ HWPanelInfo hw_panel_info;
+ uint32_t active_index = 0;
+
+ DTRACE_SCOPED();
+
+ error = hw_intf_->GetActiveConfig(&active_index);
+ if (error != kErrorNone) {
+ return error;
+ }
+
+ error = hw_intf_->GetDisplayAttributes(active_index, &display_attributes);
+ if (error != kErrorNone) {
+ return error;
+ }
+
+ error = hw_intf_->GetMixerAttributes(&mixer_attributes);
+ if (error != kErrorNone) {
+ return error;
+ }
+
+ error = hw_intf_->GetHWPanelInfo(&hw_panel_info);
+ if (error != kErrorNone) {
+ return error;
+ }
+
+ const bool dirty = deferred_config_.IsDirty();
+ if (deferred_config_.IsDeferredState()) {
+ if (dirty) {
+ SetDeferredFpsConfig();
+ } else {
+ // In Deferred state, use current config for comparison.
+ GetFpsConfig(&display_attributes, &hw_panel_info);
+ }
+ }
+
+ const bool display_unchanged = (display_attributes == display_attributes_);
+ const bool mixer_unchanged = (mixer_attributes == mixer_attributes_);
+ const bool panel_unchanged = (hw_panel_info == hw_panel_info_);
+ if (!dirty && display_unchanged && mixer_unchanged && panel_unchanged) {
+ return kErrorNone;
+ }
+
+ if (CanDeferFpsConfig(display_attributes.fps)) {
+ deferred_config_.Init(display_attributes.fps, display_attributes.vsync_period_ns,
+ hw_panel_info.transfer_time_us);
+
+ // Apply current config until new Fps is deferred.
+ GetFpsConfig(&display_attributes, &hw_panel_info);
+ }
+
+ error = comp_manager_->ReconfigureDisplay(display_comp_ctx_, display_attributes, hw_panel_info,
+ mixer_attributes, fb_config_,
+ &(default_qos_data_.clock_hz));
+ if (error != kErrorNone) {
+ return error;
+ }
+
+ bool disble_pu = true;
+ if (mixer_unchanged && panel_unchanged) {
+ // Do not disable Partial Update for one frame, if only FPS has changed.
+ // Because if first frame after transition, has a partial Frame-ROI and
+ // is followed by Skip Validate frames, then it can benefit those frames.
+ disble_pu = !display_attributes_.OnlyFpsChanged(display_attributes);
+ }
+
+ if (disble_pu) {
+ DisablePartialUpdateOneFrame();
+ }
+
+ display_attributes_ = display_attributes;
+ mixer_attributes_ = mixer_attributes;
+ hw_panel_info_ = hw_panel_info;
+
+ // TODO(user): Temporary changes, to be removed when DRM driver supports
+ // Partial update with Destination scaler enabled.
+ SetPUonDestScaler();
+
+ return kErrorNone;
+}
+
+bool DisplayBuiltIn::CanDeferFpsConfig(uint32_t fps) {
+ if (deferred_config_.CanApplyDeferredState()) {
+ // Deferred Fps Config needs to be applied.
+ return false;
+ }
+
+ // In case of higher to lower Fps transition on a Builtin display, defer the Fps
+ // (Transfer time) configuration, for the number of frames based on frame_count.
+ return ((deferred_config_.frame_count != 0) && (display_attributes_.fps > fps));
+}
+
+void DisplayBuiltIn::SetDeferredFpsConfig() {
+ // Update with the deferred Fps Config.
+ display_attributes_.fps = deferred_config_.fps;
+ display_attributes_.vsync_period_ns = deferred_config_.vsync_period_ns;
+ hw_panel_info_.transfer_time_us = deferred_config_.transfer_time_us;
+ deferred_config_.Clear();
+}
+
+void DisplayBuiltIn::GetFpsConfig(HWDisplayAttributes *display_attr, HWPanelInfo *panel_info) {
+ display_attr->fps = display_attributes_.fps;
+ display_attr->vsync_period_ns = display_attributes_.vsync_period_ns;
+ panel_info->transfer_time_us = hw_panel_info_.transfer_time_us;
+}
+
} // namespace sdm
diff --git a/sdm/libs/core/display_builtin.h b/sdm/libs/core/display_builtin.h
index 7fe6c6c..abc8a9a 100644
--- a/sdm/libs/core/display_builtin.h
+++ b/sdm/libs/core/display_builtin.h
@@ -35,6 +35,46 @@
namespace sdm {
+struct DeferFpsConfig {
+ uint32_t frame_count = 0;
+ uint32_t frames_to_defer = 0;
+ uint32_t fps = 0;
+ uint32_t vsync_period_ns = 0;
+ uint32_t transfer_time_us = 0;
+ bool dirty = false;
+ bool apply = false;
+
+ void Init(uint32_t refresh_rate, uint32_t vsync_period, uint32_t transfer_time) {
+ fps = refresh_rate;
+ vsync_period_ns = vsync_period;
+ transfer_time_us = transfer_time;
+ frames_to_defer = frame_count;
+ dirty = false;
+ apply = false;
+ }
+
+ bool IsDeferredState() { return (frames_to_defer != 0); }
+
+ bool CanApplyDeferredState() { return apply; }
+
+ bool IsDirty() { return dirty; }
+
+ void MarkDirty() { dirty = IsDeferredState(); }
+
+ void UpdateDeferCount() {
+ if (frames_to_defer > 0) {
+ frames_to_defer--;
+ apply = (frames_to_defer == 0);
+ }
+ }
+
+ void Clear() {
+ frames_to_defer = 0;
+ dirty = false;
+ apply = false;
+ }
+};
+
class DppsInfo {
public:
void Init(DppsPropIntf *intf, const std::string &panel_name);
@@ -106,11 +146,16 @@
// Implement the DppsPropIntf
virtual DisplayError DppsProcessOps(enum DppsOps op, void *payload, size_t size);
void ResetPanel();
+ virtual DisplayError SetActiveConfig(uint32_t index);
+ virtual DisplayError ReconfigureDisplay();
private:
bool CanCompareFrameROI(LayerStack *layer_stack);
bool CanSkipDisplayPrepare(LayerStack *layer_stack);
HWAVRModes GetAvrMode(QSyncMode mode);
+ bool CanDeferFpsConfig(uint32_t fps);
+ void SetDeferredFpsConfig();
+ void GetFpsConfig(HWDisplayAttributes *display_attributes, HWPanelInfo *panel_info);
const uint32_t kPuTimeOutMs = 1000;
std::vector<HWEvent> event_list_;
@@ -138,6 +183,7 @@
sde_drm::DppsFeaturePayload histogramCtrl;
sde_drm::DppsFeaturePayload histogramIRQ;
void initColorSamplingState();
+ DeferFpsConfig deferred_config_ = {};
};
} // namespace sdm