summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2021-10-25 04:04:30 +0000
committerAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2021-10-25 04:04:30 +0000
commit5d27ee161bb31cc0afb296921539b8899538dba2 (patch)
tree29a7d2d7c1fa3ab90aba38c1172ee0d2cedf5feb
parentfc442ab2a0ede707735cd643754024f09edbb80c (diff)
parentf5ed7ff5784748374ea4516a7cf3808eb2e560ea (diff)
downloadcommon-android12-qpr1-d-s3-release.tar.gz
Change-Id: Iafe218d605b1210215f8b7fbc932ad108cbc4cd6
-rw-r--r--libhwc2.1/libdevice/ExynosDisplay.h2
-rw-r--r--libhwc2.1/libdisplayinterface/ExynosDisplayDrmInterface.cpp7
-rw-r--r--libhwc2.1/libmaindisplay/ExynosPrimaryDisplay.cpp93
-rw-r--r--libhwc2.1/libmaindisplay/ExynosPrimaryDisplay.h8
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_;