diff options
author | Chris Lu <luchris@google.com> | 2022-05-29 23:52:02 +0800 |
---|---|---|
committer | Chris Lu <luchris@google.com> | 2022-06-01 10:19:08 +0800 |
commit | b9f0ab612686bb322f978da70486f6f3ce1d62f2 (patch) | |
tree | 32a7a478ab94971477b7d0ff03f16542cfd5d427 | |
parent | b3691f573149d4fb9db061a2c10aa87701df7cbc (diff) | |
download | common-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.h | 10 | ||||
-rw-r--r-- | libhwc2.1/libdisplayinterface/ExynosDisplayDrmInterface.cpp | 4 | ||||
-rw-r--r-- | libhwc2.1/libmaindisplay/ExynosPrimaryDisplay.cpp | 16 | ||||
-rw-r--r-- | libhwc2.1/libmaindisplay/ExynosPrimaryDisplay.h | 2 |
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_; |