summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Lu <luchris@google.com>2022-05-29 23:52:02 +0800
committerChris Lu <luchris@google.com>2022-06-01 10:19:08 +0800
commitb9f0ab612686bb322f978da70486f6f3ce1d62f2 (patch)
tree32a7a478ab94971477b7d0ff03f16542cfd5d427
parentb3691f573149d4fb9db061a2c10aa87701df7cbc (diff)
downloadcommon-b9f0ab612686bb322f978da70486f6f3ce1d62f2.tar.gz
libhwc2.1: wait for peak refresh rate before enabling LHBM
We have to switch to the peak refersh rate (e.g. 90/120Hz) before enabling LHBM due to panel constraints. The peak refresh rate is set by the fingerprint but it doesn't make sure we are running at the peak. Wait for the peak according to mConfigRequestState and mVsyncPeriod to guarantee we can enable LHBM. Bug: 233145265 Test: use fingerprint to unlock the device, auto test by QMC team Change-Id: I794ca743101f3463596a25bde0127ec9920a3658
-rw-r--r--libhwc2.1/libdevice/ExynosDisplay.h10
-rw-r--r--libhwc2.1/libdisplayinterface/ExynosDisplayDrmInterface.cpp4
-rw-r--r--libhwc2.1/libmaindisplay/ExynosPrimaryDisplay.cpp16
-rw-r--r--libhwc2.1/libmaindisplay/ExynosPrimaryDisplay.h2
4 files changed, 32 insertions, 0 deletions
diff --git a/libhwc2.1/libdevice/ExynosDisplay.h b/libhwc2.1/libdevice/ExynosDisplay.h
index 028798e..717ef88 100644
--- a/libhwc2.1/libdevice/ExynosDisplay.h
+++ b/libhwc2.1/libdevice/ExynosDisplay.h
@@ -1239,6 +1239,13 @@ class ExynosDisplay {
// is the hint session both enabled and supported
bool usePowerHintSession();
+ void setMinDisplayVsyncPeriod(uint32_t period) { mMinDisplayVsyncPeriod = period; }
+
+ bool isCurrentPeakRefreshRate(void) {
+ return ((mConfigRequestState == hwc_request_state_t::SET_CONFIG_STATE_NONE) &&
+ (mVsyncPeriod == mMinDisplayVsyncPeriod));
+ }
+
private:
bool skipStaticLayerChanged(ExynosCompositionInfo& compositionInfo);
@@ -1253,6 +1260,9 @@ class ExynosDisplay {
static constexpr float kHdrFullScreen = 0.5;
uint32_t mHdrFullScrenAreaThreshold;
+ // vsync period of peak refresh rate
+ uint32_t mMinDisplayVsyncPeriod;
+
/* Display hint to notify power hal */
class PowerHalHintWorker : public Worker {
public:
diff --git a/libhwc2.1/libdisplayinterface/ExynosDisplayDrmInterface.cpp b/libhwc2.1/libdisplayinterface/ExynosDisplayDrmInterface.cpp
index 7ee98a7..303033f 100644
--- a/libhwc2.1/libdisplayinterface/ExynosDisplayDrmInterface.cpp
+++ b/libhwc2.1/libdisplayinterface/ExynosDisplayDrmInterface.cpp
@@ -879,6 +879,7 @@ int32_t ExynosDisplayDrmInterface::getDisplayConfigs(
/* key: (width<<32 | height) */
std::map<uint64_t, uint32_t> groupIds;
uint32_t groupId = 0;
+ uint32_t min_vsync_period = UINT_MAX;
for (const DrmMode &mode : mDrmConnector->modes()) {
displayConfigs_t configs;
@@ -899,11 +900,14 @@ int32_t ExynosDisplayDrmInterface::getDisplayConfigs(
configs.Xdpi = mm_width ? (mode.h_display() * kUmPerInch) / mm_width : -1;
// Dots per 1000 inches
configs.Ydpi = mm_height ? (mode.v_display() * kUmPerInch) / mm_height : -1;
+ // find min vsync period
+ if (configs.vsyncPeriod <= min_vsync_period) min_vsync_period = configs.vsyncPeriod;
mExynosDisplay->mDisplayConfigs.insert(std::make_pair(mode.id(), configs));
ALOGD("config group(%d), w(%d), h(%d), vsync(%d), xdpi(%d), ydpi(%d)",
configs.groupId, configs.width, configs.height,
configs.vsyncPeriod, configs.Xdpi, configs.Ydpi);
}
+ mExynosDisplay->setMinDisplayVsyncPeriod(min_vsync_period);
}
uint32_t num_modes = static_cast<uint32_t>(mDrmConnector->modes().size());
diff --git a/libhwc2.1/libmaindisplay/ExynosPrimaryDisplay.cpp b/libhwc2.1/libmaindisplay/ExynosPrimaryDisplay.cpp
index d20a313..633b1d7 100644
--- a/libhwc2.1/libmaindisplay/ExynosPrimaryDisplay.cpp
+++ b/libhwc2.1/libmaindisplay/ExynosPrimaryDisplay.cpp
@@ -495,6 +495,22 @@ int32_t ExynosPrimaryDisplay::SetCurrentPanelGammaSource(const DisplayType type,
int32_t ExynosPrimaryDisplay::setLhbmState(bool enabled) {
ATRACE_CALL();
+ if (enabled) {
+ ATRACE_NAME("wait for peak refresh rate");
+ for (int32_t i = 0; i <= kLhbmWaitForPeakRefreshRate; i++) {
+ if (!isCurrentPeakRefreshRate()) {
+ if (i == kLhbmWaitForPeakRefreshRate) {
+ ALOGW("setLhbmState(on) wait for peak refresh rate timeout !");
+ return TIMED_OUT;
+ }
+ usleep(mVsyncPeriod / 1000 + 1);
+ } else {
+ ALOGI_IF(i, "waited %d vsync to reach peak refresh rate", i);
+ break;
+ }
+ }
+ }
+
requestLhbm(enabled);
ALOGI("setLhbmState =%d", enabled);
diff --git a/libhwc2.1/libmaindisplay/ExynosPrimaryDisplay.h b/libhwc2.1/libmaindisplay/ExynosPrimaryDisplay.h
index e544749..c4d79ea 100644
--- a/libhwc2.1/libmaindisplay/ExynosPrimaryDisplay.h
+++ b/libhwc2.1/libmaindisplay/ExynosPrimaryDisplay.h
@@ -103,6 +103,8 @@ class ExynosPrimaryDisplay : public ExynosDisplay {
bool mLhbmOn;
bool mLhbmChanged;
int32_t mFramesToReachLhbmPeakBrightness;
+ // wait num of vsync periods for peak refresh rate
+ static constexpr uint32_t kLhbmWaitForPeakRefreshRate = 10;
std::mutex lhbm_mutex_;
std::condition_variable lhbm_cond_;