diff options
Diffstat (limited to 'libhwc2.1/libmaindisplay/ExynosPrimaryDisplay.cpp')
-rw-r--r-- | libhwc2.1/libmaindisplay/ExynosPrimaryDisplay.cpp | 111 |
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; +} |