diff options
author | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2021-10-25 04:04:30 +0000 |
---|---|---|
committer | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2021-10-25 04:04:30 +0000 |
commit | 5d27ee161bb31cc0afb296921539b8899538dba2 (patch) | |
tree | 29a7d2d7c1fa3ab90aba38c1172ee0d2cedf5feb | |
parent | fc442ab2a0ede707735cd643754024f09edbb80c (diff) | |
parent | f5ed7ff5784748374ea4516a7cf3808eb2e560ea (diff) | |
download | common-android12-qpr1-d-s2-release.tar.gz |
Merge cherrypicks of [16041455] into sc-qpr1-d-release.android-12.0.0_r21android-12.0.0_r20android-12.0.0_r19android-12.0.0_r18android12-qpr1-d-s3-releaseandroid12-qpr1-d-s2-releaseandroid12-qpr1-d-s1-release
Change-Id: Iafe218d605b1210215f8b7fbc932ad108cbc4cd6
-rw-r--r-- | libhwc2.1/libdevice/ExynosDisplay.h | 2 | ||||
-rw-r--r-- | libhwc2.1/libdisplayinterface/ExynosDisplayDrmInterface.cpp | 7 | ||||
-rw-r--r-- | libhwc2.1/libmaindisplay/ExynosPrimaryDisplay.cpp | 93 | ||||
-rw-r--r-- | libhwc2.1/libmaindisplay/ExynosPrimaryDisplay.h | 8 |
4 files changed, 108 insertions, 2 deletions
diff --git a/libhwc2.1/libdevice/ExynosDisplay.h b/libhwc2.1/libdevice/ExynosDisplay.h index c892aab..884e212 100644 --- a/libhwc2.1/libdevice/ExynosDisplay.h +++ b/libhwc2.1/libdevice/ExynosDisplay.h @@ -874,7 +874,7 @@ class ExynosDisplay { * HWC2_ERROR_BAD_PARAMETER when the brightness is invalid, or * HWC2_ERROR_NO_RESOURCES when the brightness cannot be applied. */ - int32_t setDisplayBrightness(float brightness); + virtual int32_t setDisplayBrightness(float brightness); /* getDisplayConnectionType(..., outType) * Descriptor: HWC2_FUNCTION_GET_DISPLAY_CONNECTION_TYPE diff --git a/libhwc2.1/libdisplayinterface/ExynosDisplayDrmInterface.cpp b/libhwc2.1/libdisplayinterface/ExynosDisplayDrmInterface.cpp index 997b3e1..e63c498 100644 --- a/libhwc2.1/libdisplayinterface/ExynosDisplayDrmInterface.cpp +++ b/libhwc2.1/libdisplayinterface/ExynosDisplayDrmInterface.cpp @@ -1654,6 +1654,7 @@ int32_t ExynosDisplayDrmInterface::deliverWinConfigData() if (mBrightnessCtrl.LhbmOn.is_dirty()) { auto dbv = mBrightnessLevel.get(); + auto old_dbv = dbv; if (mBrightnessCtrl.LhbmOn.get()) { uint32_t dbv_adj = 0; if (mExynosDisplay->getColorAdjustedDbv(dbv_adj)) { @@ -1668,7 +1669,7 @@ int32_t ExynosDisplayDrmInterface::deliverWinConfigData() } } - if ((ret = drmReq.atomicAddProperty(mDrmConnector->id(), + if ((dbv != old_dbv) && (ret = drmReq.atomicAddProperty(mDrmConnector->id(), mDrmConnector->brightness_level(), dbv)) < 0) { HWC_LOGE(mExynosDisplay, "%s: Fail to set brightness_level property", __func__); } @@ -1754,6 +1755,10 @@ int32_t ExynosDisplayDrmInterface::deliverWinConfigData() return ret; } drmReq.restorePset(); + if (out_fences[mDrmCrtc->pipe()] >= 0) { + fence_close((int)out_fences[mDrmCrtc->pipe()], mExynosDisplay, FENCE_TYPE_RETIRE, + FENCE_IP_DPP); + } if ((ret = updateColorSettings(drmReq, dqeEnable)) != 0) { HWC_LOGE(mExynosDisplay, "failed to update color settings, ret=%d", ret); return ret; diff --git a/libhwc2.1/libmaindisplay/ExynosPrimaryDisplay.cpp b/libhwc2.1/libmaindisplay/ExynosPrimaryDisplay.cpp index 8a49735..73268d3 100644 --- a/libhwc2.1/libmaindisplay/ExynosPrimaryDisplay.cpp +++ b/libhwc2.1/libmaindisplay/ExynosPrimaryDisplay.cpp @@ -20,6 +20,7 @@ #include "ExynosPrimaryDisplay.h" #include <fstream> +#include <poll.h> #include "ExynosDevice.h" #include "ExynosDisplayDrmInterface.h" @@ -441,6 +442,25 @@ int32_t ExynosPrimaryDisplay::SetCurrentPanelGammaSource(const DisplayType type, return HWC2_ERROR_NONE; } +// Both setDisplayBrightness and setLhbmState will change display brightness and +// each goes different path (sysfs and drm/kms) +// +// case 1: setDisplayBrightness happens before setLhbmState +// Don't care. brightness change by setLhbmState will happen after brightness +// change by setDisplayBrightness. +// +// case 2: setLhbmState happends before setDisplayBrightness +// block current call until brightness change by setLhbmState completes. +int32_t ExynosPrimaryDisplay::setDisplayBrightness(float brightness) { + if (mLhbmStatusPending) { + // This could be done in setLhbmState and block this call on + // mLhbmStatusPending. But it may increase the time for UDFPS path + checkLhbmMode(mLastRequestedLhbm, ms2ns(200)); + mLhbmStatusPending = false; + } + return ExynosDisplay::setDisplayBrightness(brightness); +} + int32_t ExynosPrimaryDisplay::setLhbmState(bool enabled) { ATRACE_CALL(); requestLhbm(enabled); @@ -448,6 +468,10 @@ int32_t ExynosPrimaryDisplay::setLhbmState(bool enabled) { std::unique_lock<std::mutex> lk(lhbm_mutex_); mLhbmChanged = false; + + mLhbmStatusPending = true; + mLastRequestedLhbm = enabled; + if (!lhbm_cond_.wait_for(lk, std::chrono::milliseconds(1000), [this] { return mLhbmChanged; })) { ALOGI("setLhbmState =%d timeout !", enabled); @@ -459,6 +483,75 @@ int32_t ExynosPrimaryDisplay::setLhbmState(bool enabled) { } } +// return immediately if it's already in the status. Otherwise poll the status +bool ExynosPrimaryDisplay::checkLhbmMode(bool status, nsecs_t timeoutNs) { + ATRACE_CALL(); + char buf[1]; + auto startTime = systemTime(SYSTEM_TIME_MONOTONIC); + + UniqueFd fd = open(kLocalHbmModeFileNode, O_RDONLY); + + int size = read(fd.get(), buf, 1); + if (size != 1) { + ALOGE("%s failed to read from %s", __func__, kLocalHbmModeFileNode); + return false; + } + + if (buf[0] == (status ? '1' : '0')) { + return true; + } + + struct pollfd pfds[1]; + int ret = EINVAL; + + pfds[0].fd = fd.get(); + pfds[0].events = POLLPRI; + while (true) { + auto currentTime = systemTime(SYSTEM_TIME_MONOTONIC); + // int64_t for nsecs_t + auto remainTimeNs = timeoutNs - (currentTime - startTime); + if (remainTimeNs <= 0) { + remainTimeNs = ms2ns(1); + } + int pollRet = poll(&pfds[0], 1, ns2ms(remainTimeNs)); + if (pollRet == 0) { + ALOGW("%s poll timeout", __func__); + // time out + ret = ETIMEDOUT; + break; + } else if (pollRet > 0) { + if (!(pfds[0].revents & POLLPRI)) { + continue; + } + + lseek(fd.get(), 0, SEEK_SET); + size = read(fd.get(), buf, 1); + if (size == 1) { + if (buf[0] == (status ? '1' : '0')) { + ret = 0; + } else { + ALOGE("%s status %d expected %d after notified", __func__, buf[0], status); + ret = EINVAL; + } + } else { + ret = EIO; + ALOGE("%s failed to read after notified %d", __func__, errno); + } + break; + } else { + if (errno == EAGAIN || errno == EINTR) { + continue; + } + + ALOGE("%s poll failed %d", __func__, errno); + ret = errno; + break; + } + }; + + return ret == NO_ERROR; +} + bool ExynosPrimaryDisplay::getLhbmState() { return mLhbmOn; } diff --git a/libhwc2.1/libmaindisplay/ExynosPrimaryDisplay.h b/libhwc2.1/libmaindisplay/ExynosPrimaryDisplay.h index c49ae5e..beea5df 100644 --- a/libhwc2.1/libmaindisplay/ExynosPrimaryDisplay.h +++ b/libhwc2.1/libmaindisplay/ExynosPrimaryDisplay.h @@ -37,6 +37,8 @@ class ExynosPrimaryDisplay : public ExynosDisplay { virtual bool isLhbmSupported() { return mLhbmFd ? true : false; } virtual int32_t setLhbmState(bool enabled); + virtual int32_t setDisplayBrightness(float brightness) override; + virtual bool getLhbmState(); virtual void notifyLhbmState(bool enabled); virtual void setWakeupDisplay(); @@ -66,6 +68,8 @@ class ExynosPrimaryDisplay : public ExynosDisplay { static constexpr const char* kPanelGammaCalFilePrefix = "gamma_calib_data"; enum PanelGammaSource currentPanelGammaSource = PanelGammaSource::GAMMA_DEFAULT; + bool checkLhbmMode(bool status, nsecs_t timoutNs); + hwc2_config_t mPendActiveConfig = UINT_MAX; bool mFirstPowerOn = true; @@ -81,6 +85,10 @@ class ExynosPrimaryDisplay : public ExynosDisplay { FILE* mLhbmFd; bool mLhbmOn; bool mLhbmChanged; + + std::atomic<bool> mLastRequestedLhbm; + std::atomic<bool> mLhbmStatusPending; + static constexpr const char *kLocalHbmModeFileNode = "/sys/class/backlight/panel0-backlight/local_hbm_mode"; std::mutex lhbm_mutex_; |