Merge "hwc: Add support to disable animation on WFD(GPU)"
diff --git a/composer/display_null.h b/composer/display_null.h
index a009f02..aa03038 100644
--- a/composer/display_null.h
+++ b/composer/display_null.h
@@ -94,7 +94,7 @@
MAKE_NO_OP(GetDefaultColorMode(string *))
MAKE_NO_OP(ApplyDefaultDisplayMode())
MAKE_NO_OP(SetCursorPosition(int, int))
- MAKE_NO_OP(SetRefreshRate(uint32_t, bool))
+ MAKE_NO_OP(SetRefreshRate(uint32_t, bool, bool))
MAKE_NO_OP(GetPanelBrightness(float *))
MAKE_NO_OP(GetPanelMaxBrightness(uint32_t *))
MAKE_NO_OP(GetRefreshRate(uint32_t *))
diff --git a/composer/hwc_display_builtin.cpp b/composer/hwc_display_builtin.cpp
index 1435f66..0412c85 100644
--- a/composer/hwc_display_builtin.cpp
+++ b/composer/hwc_display_builtin.cpp
@@ -162,6 +162,10 @@
}
}
+ value = 0;
+ DebugHandler::Get()->GetProperty(DISABLE_DYNAMIC_FPS, &value);
+ disable_dyn_fps_ = (value == 1);
+
uint32_t config_index = 0;
GetActiveDisplayConfig(&config_index);
DisplayConfigVariableInfo attr = {};
@@ -170,6 +174,11 @@
DLOGI("active_refresh_rate: %d", active_refresh_rate_);
+ int enhance_idle_time = 0;
+ HWCDebugHandler::Get()->GetProperty(ENHANCE_IDLE_TIME, &enhance_idle_time);
+ enhance_idle_time_ = (enhance_idle_time == 1);
+ DLOGI("enhance_idle_time: %d", enhance_idle_time);
+
return status;
}
@@ -230,14 +239,16 @@
}
uint32_t refresh_rate = GetOptimalRefreshRate(one_updating_layer);
- error = display_intf_->SetRefreshRate(refresh_rate, force_refresh_rate_);
+ bool idle_screen = GetUpdatingAppLayersCount() == 0;
+ error = display_intf_->SetRefreshRate(refresh_rate, force_refresh_rate_, idle_screen);
// Get the refresh rate set.
display_intf_->GetRefreshRate(&refresh_rate);
bool vsync_source = (callbacks_->GetVsyncSource() == id_);
if (error == kErrorNone) {
- if (vsync_source && (current_refresh_rate_ < refresh_rate)) {
+ if (vsync_source && ((current_refresh_rate_ < refresh_rate) ||
+ (enhance_idle_time_ && (current_refresh_rate_ != refresh_rate)))) {
DTRACE_BEGIN("HWC2::Vsync::Enable");
// Display is ramping up from idle.
// Client realizes need for resync upon change in config.
@@ -480,6 +491,15 @@
if (is_cmd_mode_ != command_mode) {
SetPartialUpdate(fixed_info);
}
+
+ // For video mode panel with dynamic fps, update the active mode index.
+ // This is needed to report the correct Vsync period when client queries
+ // using GetDisplayVsyncPeriod API.
+ if (!is_cmd_mode_ && !disable_dyn_fps_) {
+ hwc2_config_t active_config = hwc_config_map_.at(0);
+ GetActiveConfig(&active_config);
+ SetActiveConfigIndex(active_config);
+ }
}
}
@@ -1454,4 +1474,20 @@
return fixed_info.readback_supported;
}
+uint32_t HWCDisplayBuiltIn::GetUpdatingAppLayersCount() {
+ uint32_t updating_count = 0;
+
+ for (uint i = 0; i < layer_stack_.layers.size(); i++) {
+ auto layer = layer_stack_.layers.at(i);
+ if (layer->composition == kCompositionGPUTarget) {
+ break;
+ }
+ if (layer->flags.updating) {
+ updating_count++;
+ }
+ }
+
+ return updating_count;
+}
+
} // namespace sdm
diff --git a/composer/hwc_display_builtin.h b/composer/hwc_display_builtin.h
index a0da3fd..33d3da3 100644
--- a/composer/hwc_display_builtin.h
+++ b/composer/hwc_display_builtin.h
@@ -174,6 +174,7 @@
int GetBwCode(const DisplayConfigVariableInfo &attr);
void SetBwLimitHint(bool enable);
void SetPartialUpdate(DisplayConfigFixedInfo fixed_info);
+ uint32_t GetUpdatingAppLayersCount();
// SyncTask methods.
void OnTask(const LayerStitchTaskCode &task_code,
@@ -224,6 +225,8 @@
bool is_smart_panel_ = false;
const char *kDisplayBwName = "display_bw";
bool enable_bw_limits_ = false;
+ bool disable_dyn_fps_ = false;
+ bool enhance_idle_time_ = false;
};
} // namespace sdm
diff --git a/config/display-product.mk b/config/display-product.mk
index 6d09b8a..fdd2801 100644
--- a/config/display-product.mk
+++ b/config/display-product.mk
@@ -19,6 +19,7 @@
vendor.qti.hardware.display.mapper@4.0.vendor \
modetest
+ifneq ($(TARGET_HAS_LOW_RAM),true)
#QDCM calibration xml file for 2k panel
PRODUCT_COPY_FILES += hardware/qcom/display/config/qdcm_calib_data_nt35597_cmd_mode_dsi_truly_panel_with_DSC.xml:$(TARGET_COPY_OUT_VENDOR)/etc/qdcm_calib_data_nt35597_cmd_mode_dsi_truly_panel_with_DSC.xml
PRODUCT_COPY_FILES += hardware/qcom/display/config/qdcm_calib_data_nt35597_cmd_mode_dsi_truly_panel_with_DSC.xml:$(TARGET_COPY_OUT_VENDOR)/etc/qdcm_calib_data_nt35597_video_mode_dsi_truly_panel_with_DSC.xml
@@ -32,9 +33,6 @@
#QDCM calibration xml file for dual panel
PRODUCT_COPY_FILES += hardware/qcom/display/config/qdcm_calib_data_default.xml:$(TARGET_COPY_OUT_VENDOR)/etc/qdcm_calib_data_sharp_1080p_cmd_mode_dsi_panel.xml
PRODUCT_COPY_FILES += hardware/qcom/display/config/qdcm_calib_data_default.xml:$(TARGET_COPY_OUT_VENDOR)/etc/qdcm_calib_data_nt35695b_truly_fhd_command_mode_dsi_panel.xml
-#QDCM calibration xml file for td4330 panel
-PRODUCT_COPY_FILES += hardware/qcom/display/config/qdcm_calib_data_bengal_default.xml:$(TARGET_COPY_OUT_VENDOR)/etc/qdcm_calib_data_td4330_v2_cmd_mode_dsi_truly_panel.xml
-PRODUCT_COPY_FILES += hardware/qcom/display/config/qdcm_calib_data_bengal_default.xml:$(TARGET_COPY_OUT_VENDOR)/etc/qdcm_calib_data_td4330_v2_video_mode_dsi_truly_panel.xml
#QDCM calibration xml file for Sharp fhd panel
PRODUCT_COPY_FILES += hardware/qcom/display/config/qdcm_calib_data_default.xml:$(TARGET_COPY_OUT_VENDOR)/etc/qdcm_calib_data_Sharp_fhd_cmd_mode_qsync_dsi_panel.xml
PRODUCT_COPY_FILES += hardware/qcom/display/config/qdcm_calib_data_default.xml:$(TARGET_COPY_OUT_VENDOR)/etc/qdcm_calib_data_Sharp_fhd_video_mode_qsync_dsi_panel.xml
@@ -54,6 +52,10 @@
PRODUCT_COPY_FILES += hardware/qcom/display/config/qdcm_calib_data_default.xml:$(TARGET_COPY_OUT_VENDOR)/etc/qdcm_calib_data_rm69299_amoled_fhd+_cmd_mode_dsi_visionox_panel.xml
#QDCM calibration xml file for nt36525 truly panel
PRODUCT_COPY_FILES += hardware/qcom/display/config/qdcm_calib_data_bengal_default.xml:$(TARGET_COPY_OUT_VENDOR)/etc/qdcm_calib_data_nt36525_video_mode_dsi_truly_panel.xml
+endif
+#QDCM calibration xml file for td4330 panel
+PRODUCT_COPY_FILES += hardware/qcom/display/config/qdcm_calib_data_bengal_default.xml:$(TARGET_COPY_OUT_VENDOR)/etc/qdcm_calib_data_td4330_v2_cmd_mode_dsi_truly_panel.xml
+PRODUCT_COPY_FILES += hardware/qcom/display/config/qdcm_calib_data_bengal_default.xml:$(TARGET_COPY_OUT_VENDOR)/etc/qdcm_calib_data_td4330_v2_video_mode_dsi_truly_panel.xml
PRODUCT_PROPERTY_OVERRIDES += \
persist.demo.hdmirotationlock=false \
diff --git a/include/display_properties.h b/include/display_properties.h
index 9945118..b8a8b49 100644
--- a/include/display_properties.h
+++ b/include/display_properties.h
@@ -122,6 +122,7 @@
#define DISABLE_INLINE_ROTATOR_UI_PROP DISPLAY_PROP("disable_inline_rotator_ui")
#define ENABLE_POMS_DURING_DOZE DISPLAY_PROP("enable_poms_during_doze")
#define DISABLE_DYNAMIC_FPS DISPLAY_PROP("disable_dynamic_fps")
+#define ENHANCE_IDLE_TIME DISPLAY_PROP("enhance_idle_time")
// Add all vendor.display properties above
diff --git a/libhistogram/histogram_collector.cpp b/libhistogram/histogram_collector.cpp
index f7da3b4..f52e241 100644
--- a/libhistogram/histogram_collector.cpp
+++ b/libhistogram/histogram_collector.cpp
@@ -67,7 +67,7 @@
} // namespace
std::string histogram::HistogramCollector::Dump() const {
- uint64_t num_frames;
+ uint64_t num_frames = 0;
std::array<uint64_t, HIST_V_SIZE> all_sample_buckets;
std::tie(num_frames, all_sample_buckets) = histogram->collect_cumulative();
std::array<uint64_t, numBuckets> samples = rebucketTo8Buckets(all_sample_buckets);
@@ -101,7 +101,7 @@
out_samples_size[2] = numBuckets;
out_samples_size[3] = 0;
- uint64_t num_frames;
+ uint64_t num_frames = 0;
std::array<uint64_t, HIST_V_SIZE> samples;
if (max_frames == 0 && timestamp == 0) {
@@ -194,7 +194,7 @@
lk.unlock();
drmModePropertyBlobPtr blob = drmModeGetPropertyBlob(work.fd, work.id);
- if (!blob) {
+ if (!blob || !blob->data) {
lk.lock();
continue;
}
diff --git a/libhistogram/ringbuffer.cpp b/libhistogram/ringbuffer.cpp
index b19682f..1c06f76 100644
--- a/libhistogram/ringbuffer.cpp
+++ b/libhistogram/ringbuffer.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2018 The Android Open Source Project
+ * Copyright (C) 2018, 2020 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -125,7 +125,8 @@
return {0, {}};
std::array<uint64_t, HIST_V_SIZE> bins;
bins.fill(0);
- for (auto it = ringbuffer.begin(); it != ringbuffer.begin() + collect_first; it++) {
+ for (auto it = ringbuffer.begin(); it != ringbuffer.end() &&
+ it != ringbuffer.begin() + collect_first; it++) {
nsecs_t end_timestamp = it->end_timestamp;
if (it == ringbuffer.begin()) {
end_timestamp = timekeeper->current_time();
diff --git a/sdm/include/core/display_interface.h b/sdm/include/core/display_interface.h
index c8d1cf6..2f087cf 100644
--- a/sdm/include/core/display_interface.h
+++ b/sdm/include/core/display_interface.h
@@ -544,9 +544,12 @@
@param[in] final_rate indicates whether refresh rate is final rate or can be changed by sdm
+ @param[in] idle_screen indicates whether screen is idle.
+
@return \link DisplayError \endlink
*/
- virtual DisplayError SetRefreshRate(uint32_t refresh_rate, bool final_rate) = 0;
+ virtual DisplayError SetRefreshRate(uint32_t refresh_rate, bool final_rate,
+ bool idle_screen = false) = 0;
/*! @brief Method to get the refresh rate of a display.
diff --git a/sdm/libs/core/comp_manager.cpp b/sdm/libs/core/comp_manager.cpp
index 8f35daa..aad32d7 100644
--- a/sdm/libs/core/comp_manager.cpp
+++ b/sdm/libs/core/comp_manager.cpp
@@ -451,6 +451,7 @@
}
void CompManager::ProcessIdleTimeout(Handle display_ctx) {
+ DTRACE_SCOPED();
SCOPE_LOCK(locker_);
DisplayCompositionContext *display_comp_ctx =
diff --git a/sdm/libs/core/display_builtin.cpp b/sdm/libs/core/display_builtin.cpp
index a73bf2f..9e889fb 100644
--- a/sdm/libs/core/display_builtin.cpp
+++ b/sdm/libs/core/display_builtin.cpp
@@ -57,6 +57,10 @@
DisplayBuiltIn::~DisplayBuiltIn() {
}
+static uint64_t GetTimeInMs(struct timespec ts) {
+ return (ts.tv_sec * 1000 + (ts.tv_nsec + 500000) / 1000000);
+}
+
DisplayError DisplayBuiltIn::Init() {
lock_guard<recursive_mutex> obj(recursive_mutex_);
@@ -121,6 +125,10 @@
DebugHandler::Get()->GetProperty(DISABLE_DYNAMIC_FPS, &value);
disable_dyn_fps_ = (value == 1);
+ value = 0;
+ DebugHandler::Get()->GetProperty(ENHANCE_IDLE_TIME, &value);
+ enhance_idle_time_ = (value == 1);
+
return error;
}
@@ -295,9 +303,11 @@
deferred_config_.Clear();
}
+ clock_gettime(CLOCK_MONOTONIC, &idle_timer_start_);
int idle_time_ms = hw_layers_.info.set_idle_time_ms;
if (idle_time_ms >= 0) {
hw_intf_->SetIdleTimeoutMs(UINT32(idle_time_ms));
+ idle_time_ms_ = idle_time_ms;
}
if (switch_to_cmd_) {
@@ -499,7 +509,8 @@
return hw_intf_->TeardownConcurrentWriteback();
}
-DisplayError DisplayBuiltIn::SetRefreshRate(uint32_t refresh_rate, bool final_rate) {
+DisplayError DisplayBuiltIn::SetRefreshRate(uint32_t refresh_rate, bool final_rate,
+ bool idle_screen) {
lock_guard<recursive_mutex> obj(recursive_mutex_);
if (!active_ || !hw_panel_info_.dynamic_fps || qsync_mode_ != kQSyncModeNone ||
@@ -512,11 +523,11 @@
return kErrorParameters;
}
- if (handle_idle_timeout_ && !final_rate) {
+ if (CanLowerFps(idle_screen) && !final_rate) {
refresh_rate = hw_panel_info_.min_fps;
}
- if ((current_refresh_rate_ != refresh_rate) || handle_idle_timeout_) {
+ if (current_refresh_rate_ != refresh_rate) {
DisplayError error = hw_intf_->SetRefreshRate(refresh_rate);
if (error != kErrorNone) {
// Attempt to update refresh rate can fail if rf interfenence is detected.
@@ -531,6 +542,11 @@
}
}
+ // Set safe mode upon success.
+ if (enhance_idle_time_ && handle_idle_timeout_ && (refresh_rate == hw_panel_info_.min_fps)) {
+ comp_manager_->ProcessIdleTimeout(display_comp_ctx_);
+ }
+
// On success, set current refresh rate to new refresh rate
current_refresh_rate_ = refresh_rate;
handle_idle_timeout_ = false;
@@ -539,6 +555,24 @@
return ReconfigureDisplay();
}
+bool DisplayBuiltIn::CanLowerFps(bool idle_screen) {
+ if (!enhance_idle_time_) {
+ return handle_idle_timeout_;
+ }
+
+ if (!handle_idle_timeout_ || !idle_screen) {
+ return false;
+ }
+
+ struct timespec now;
+ clock_gettime(CLOCK_MONOTONIC, &now);
+ uint64_t elapsed_time_ms = GetTimeInMs(now) - GetTimeInMs(idle_timer_start_);
+ bool can_lower = elapsed_time_ms >= UINT32(idle_time_ms_);
+ DLOGV_IF(kTagDisplay, "lower fps: %d", can_lower);
+
+ return can_lower;
+}
+
DisplayError DisplayBuiltIn::VSync(int64_t timestamp) {
if (vsync_enable_ && !drop_hw_vsync_) {
DisplayEventVSync vsync;
@@ -556,8 +590,10 @@
}
handle_idle_timeout_ = true;
event_handler_->Refresh();
- lock_guard<recursive_mutex> obj(recursive_mutex_);
- comp_manager_->ProcessIdleTimeout(display_comp_ctx_);
+ if (!enhance_idle_time_) {
+ lock_guard<recursive_mutex> obj(recursive_mutex_);
+ comp_manager_->ProcessIdleTimeout(display_comp_ctx_);
+ }
}
}
diff --git a/sdm/libs/core/display_builtin.h b/sdm/libs/core/display_builtin.h
index ddc4bb1..9cf8a5f 100644
--- a/sdm/libs/core/display_builtin.h
+++ b/sdm/libs/core/display_builtin.h
@@ -25,6 +25,8 @@
#ifndef __DISPLAY_BUILTIN_H__
#define __DISPLAY_BUILTIN_H__
+#include <sys/time.h>
+
#include <core/dpps_interface.h>
#include <string>
#include <vector>
@@ -111,7 +113,7 @@
virtual void SetIdleTimeoutMs(uint32_t active_ms);
virtual DisplayError SetDisplayMode(uint32_t mode);
virtual DisplayError GetRefreshRateRange(uint32_t *min_refresh_rate, uint32_t *max_refresh_rate);
- virtual DisplayError SetRefreshRate(uint32_t refresh_rate, bool final_rate);
+ virtual DisplayError SetRefreshRate(uint32_t refresh_rate, bool final_rate, bool idle_screen);
virtual DisplayError SetPanelBrightness(float brightness);
virtual DisplayError GetPanelBrightness(float *brightness);
virtual DisplayError GetPanelMaxBrightness(uint32_t *max_brightness_level);
@@ -156,6 +158,7 @@
void SetDeferredFpsConfig();
void GetFpsConfig(HWDisplayAttributes *display_attributes, HWPanelInfo *panel_info);
void UpdateDisplayModeParams();
+ bool CanLowerFps(bool idle_screen);
const uint32_t kPuTimeOutMs = 1000;
std::vector<HWEvent> event_list_;
@@ -185,6 +188,9 @@
sde_drm::DppsFeaturePayload histogramIRQ;
void initColorSamplingState();
DeferFpsConfig deferred_config_ = {};
+ bool enhance_idle_time_ = false;
+ int idle_time_ms_ = 0;
+ struct timespec idle_timer_start_;
};
} // namespace sdm
diff --git a/sdm/libs/core/display_pluggable.cpp b/sdm/libs/core/display_pluggable.cpp
index 4ac1f01..4254348 100644
--- a/sdm/libs/core/display_pluggable.cpp
+++ b/sdm/libs/core/display_pluggable.cpp
@@ -156,7 +156,8 @@
return error;
}
-DisplayError DisplayPluggable::SetRefreshRate(uint32_t refresh_rate, bool final_rate) {
+DisplayError DisplayPluggable::SetRefreshRate(uint32_t refresh_rate, bool final_rate,
+ bool idle_screen) {
lock_guard<recursive_mutex> obj(recursive_mutex_);
if (!active_) {
diff --git a/sdm/libs/core/display_pluggable.h b/sdm/libs/core/display_pluggable.h
index e2b5c3a..18d6610 100644
--- a/sdm/libs/core/display_pluggable.h
+++ b/sdm/libs/core/display_pluggable.h
@@ -44,7 +44,7 @@
virtual DisplayError Init();
virtual DisplayError Prepare(LayerStack *layer_stack);
virtual DisplayError GetRefreshRateRange(uint32_t *min_refresh_rate, uint32_t *max_refresh_rate);
- virtual DisplayError SetRefreshRate(uint32_t refresh_rate, bool final_rate);
+ virtual DisplayError SetRefreshRate(uint32_t refresh_rate, bool final_rate, bool idle_screen);
virtual bool IsUnderscanSupported();
virtual DisplayError InitializeColorModes();
virtual DisplayError SetColorMode(const std::string &color_mode);
diff --git a/sdm/libs/core/display_virtual.h b/sdm/libs/core/display_virtual.h
index 9cadf60..0ff0180 100644
--- a/sdm/libs/core/display_virtual.h
+++ b/sdm/libs/core/display_virtual.h
@@ -55,7 +55,7 @@
virtual DisplayError SetVSyncState(bool enable) {
return kErrorNotSupported;
}
- virtual DisplayError SetRefreshRate(uint32_t refresh_rate, bool final_rate) {
+ virtual DisplayError SetRefreshRate(uint32_t refresh_rate, bool final_rate, bool idle_screen) {
return kErrorNotSupported;
}
virtual DisplayError SetDetailEnhancerData(const DisplayDetailEnhancerData &de_data) {