summaryrefslogtreecommitdiff
path: root/libhwc2.1/libmaindisplay/ExynosPrimaryDisplay.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libhwc2.1/libmaindisplay/ExynosPrimaryDisplay.cpp')
-rw-r--r--libhwc2.1/libmaindisplay/ExynosPrimaryDisplay.cpp111
1 files changed, 78 insertions, 33 deletions
diff --git a/libhwc2.1/libmaindisplay/ExynosPrimaryDisplay.cpp b/libhwc2.1/libmaindisplay/ExynosPrimaryDisplay.cpp
index 6fc7ee9..594495b 100644
--- a/libhwc2.1/libmaindisplay/ExynosPrimaryDisplay.cpp
+++ b/libhwc2.1/libmaindisplay/ExynosPrimaryDisplay.cpp
@@ -38,7 +38,6 @@ extern struct exynos_hwc_control exynosHWCControl;
using namespace SOC_VERSION;
constexpr auto nsecsPerSec = std::chrono::nanoseconds(1s).count();
-constexpr auto nsecsPerMs = std::chrono::nanoseconds(1ms).count();
static const std::map<const DisplayType, const std::string> panelSysfsPath =
{{DisplayType::DISPLAY_PRIMARY, "/sys/devices/platform/exynos-drm/primary-panel/"},
@@ -259,25 +258,16 @@ int32_t ExynosPrimaryDisplay::getPreferredDisplayConfigInternal(int32_t *outConf
return HWC2_ERROR_BAD_CONFIG;
}
- const auto vsyncPeriod = nsecsPerSec / fps;
-
- for (auto const& [config, mode] : mDisplayConfigs) {
- long delta = abs(vsyncPeriod - mode.vsyncPeriod);
- if ((width == mode.width) && (height == mode.height) &&
- (delta < nsecsPerMs)) {
- ALOGD("%s: found preferred display config for mode: %s=%d",
- __func__, modeStr, config);
- *outConfig = config;
- return HWC2_ERROR_NONE;
- }
- }
- return HWC2_ERROR_BAD_CONFIG;
+ return lookupDisplayConfigs(width, height, fps, outConfig);
}
int32_t ExynosPrimaryDisplay::setPowerOn() {
ATRACE_CALL();
updateAppliedActiveConfig(0, 0);
- int ret = applyPendingConfig();
+ int ret = NO_ERROR;
+ if (!mFirstPowerOn) {
+ ret = applyPendingConfig();
+ }
if (!mPowerModeState.has_value() || (*mPowerModeState == HWC2_POWER_MODE_OFF)) {
// check the dynamic recomposition thread by following display
@@ -353,6 +343,11 @@ int32_t ExynosPrimaryDisplay::setPowerDoze(hwc2_power_mode_t mode) {
mPowerModeState = mode;
}
+ // LHBM will be disabled in the kernel while entering AOD mode if it's
+ // already enabled. Reset the state to avoid the sync problem.
+ mBrightnessController->resetLhbmState();
+ mLhbmOn = false;
+
ExynosDisplay::updateRefreshRateHint();
return HWC2_ERROR_NONE;
@@ -564,13 +559,35 @@ int32_t ExynosPrimaryDisplay::setLhbmState(bool enabled) {
setLHBMRefreshRateThrottle(kLhbmRefreshRateThrottleMs);
}
+ bool wasDisabled =
+ mBrightnessController
+ ->checkSysfsStatus(BrightnessController::kLocalHbmModeFileNode,
+ {std::to_string(static_cast<int>(
+ BrightnessController::LhbmMode::DISABLED))},
+ 0);
+ if (!enabled && wasDisabled) {
+ ALOGW("lhbm is at DISABLED state, skip disabling");
+ return NO_ERROR;
+ } else if (enabled && !wasDisabled) {
+ requestLhbm(true);
+ ALOGI("lhbm is at ENABLING or ENABLED state, re-enable to reset timeout timer");
+ return NO_ERROR;
+ }
+
+ int64_t lhbmEnablingNanos;
+ std::vector<std::string> checkingValue = {
+ std::to_string(static_cast<int>(BrightnessController::LhbmMode::DISABLED))};
+ if (enabled) {
+ checkingValue = {std::to_string(static_cast<int>(BrightnessController::LhbmMode::ENABLING)),
+ std::to_string(static_cast<int>(BrightnessController::LhbmMode::ENABLED))};
+ lhbmEnablingNanos = systemTime(SYSTEM_TIME_MONOTONIC);
+ }
requestLhbm(enabled);
constexpr uint32_t kSysfsCheckTimeoutMs = 500;
ALOGI("setLhbmState =%d", enabled);
- bool succeed = mBrightnessController->checkSysfsStatus(
- BrightnessController::kLocalHbmModeFileNode,
- std::to_string(enabled ? 1 : 0),
- ms2ns(kSysfsCheckTimeoutMs));
+ bool succeed =
+ mBrightnessController->checkSysfsStatus(BrightnessController::kLocalHbmModeFileNode,
+ checkingValue, ms2ns(kSysfsCheckTimeoutMs));
if (!succeed) {
ALOGE("failed to update lhbm mode");
if (enabled) {
@@ -579,11 +596,40 @@ int32_t ExynosPrimaryDisplay::setLhbmState(bool enabled) {
return -ENODEV;
}
- if (!enabled) {
+ if (enabled) {
+ int64_t lhbmEnablingDoneNanos = systemTime(SYSTEM_TIME_MONOTONIC);
+ bool enablingStateSupported = !mFramesToReachLhbmPeakBrightness;
+ if (enablingStateSupported) {
+ ATRACE_NAME("lhbm_wait_peak_brightness");
+ if (!mBrightnessController
+ ->checkSysfsStatus(BrightnessController::kLocalHbmModeFileNode,
+ {std::to_string(static_cast<int>(
+ BrightnessController::LhbmMode::ENABLED))},
+ ms2ns(kSysfsCheckTimeoutMs))) {
+ ALOGE("failed to wait for lhbm becoming effective");
+ return -EIO;
+ }
+ } else {
+ // lhbm takes effect at next vblank
+ ATRACE_NAME("lhbm_wait_apply");
+ if (mDisplayInterface->waitVBlank()) {
+ ALOGE("%s failed to wait vblank for taking effect", __func__);
+ return -ENODEV;
+ }
+ ATRACE_NAME("lhbm_wait_peak_brightness");
+ for (int32_t i = mFramesToReachLhbmPeakBrightness; i > 0; i--) {
+ if (mDisplayInterface->waitVBlank()) {
+ ALOGE("%s failed to wait vblank for peak brightness, %d", __func__, i);
+ return -ENODEV;
+ }
+ }
+ }
+ ALOGI("lhbm delay mode: %s, latency(ms): total: %d cmd: %d\n",
+ enablingStateSupported ? "poll" : "fixed",
+ static_cast<int>((systemTime(SYSTEM_TIME_MONOTONIC) - lhbmEnablingNanos) / 1000000),
+ static_cast<int>((lhbmEnablingDoneNanos - lhbmEnablingNanos) / 1000000));
+ } else {
setLHBMRefreshRateThrottle(0);
- }
-
- {
// lhbm takes effect at next vblank
ATRACE_NAME("lhbm_wait_apply");
if (mDisplayInterface->waitVBlank()) {
@@ -592,16 +638,6 @@ int32_t ExynosPrimaryDisplay::setLhbmState(bool enabled) {
}
}
- if (enabled) {
- for (int32_t i = mFramesToReachLhbmPeakBrightness; i > 0; i--) {
- ATRACE_NAME("lhbm_wait_peak_brightness");
- if (mDisplayInterface->waitVBlank()) {
- ALOGE("%s failed to wait vblank for peak brightness, %d", __func__, i);
- return -ENODEV;
- }
- }
- }
-
mLhbmOn = enabled;
if (!mPowerModeState.has_value() || (*mPowerModeState == HWC2_POWER_MODE_OFF && mLhbmOn)) {
mLhbmOn = false;
@@ -968,3 +1004,12 @@ void ExynosPrimaryDisplay::checkBtsReassignResource(const uint32_t vsyncPeriod,
}
}
}
+
+bool ExynosPrimaryDisplay::isDbmSupported() {
+ return mBrightnessController->isDbmSupported();
+}
+
+int32_t ExynosPrimaryDisplay::setDbmState(bool enabled) {
+ mBrightnessController->processDimBrightness(enabled);
+ return NO_ERROR;
+}