summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libhwc2.1/ExynosHWCDebug.h7
-rw-r--r--libhwc2.1/libdevice/ExynosDisplay.cpp37
-rw-r--r--libhwc2.1/libdevice/ExynosDisplay.h13
-rw-r--r--libhwc2.1/libdisplayinterface/ExynosDisplayDrmInterface.cpp54
-rw-r--r--libhwc2.1/libdisplayinterface/ExynosDisplayDrmInterface.h1
-rw-r--r--libhwc2.1/libdisplayinterface/ExynosDisplayInterface.h1
-rw-r--r--libhwc2.1/libmaindisplay/ExynosPrimaryDisplay.cpp131
-rw-r--r--libhwc2.1/libmaindisplay/ExynosPrimaryDisplay.h10
8 files changed, 198 insertions, 56 deletions
diff --git a/libhwc2.1/ExynosHWCDebug.h b/libhwc2.1/ExynosHWCDebug.h
index 25178d1..37d96fd 100644
--- a/libhwc2.1/ExynosHWCDebug.h
+++ b/libhwc2.1/ExynosHWCDebug.h
@@ -114,6 +114,13 @@ int32_t saveFenceTrace(ExynosDisplay *display);
saveErrorLog(saveString, this); \
}
+#define DISPLAY_DRM_LOGI(msg, ...) \
+ ALOGI("[%s] " msg, mExynosDisplay->mDisplayName.string(), ##__VA_ARGS__)
+#define DISPLAY_DRM_LOGW(msg, ...) \
+ ALOGW("[%s] " msg, mExynosDisplay->mDisplayName.string(), ##__VA_ARGS__)
+#define DISPLAY_DRM_LOGE(msg, ...) \
+ ALOGE("[%s] " msg, mExynosDisplay->mDisplayName.string(), ##__VA_ARGS__)
+
#define MPP_LOGV(msg, ...) ALOGV("[%s][%d] " msg, mName.string(), mLogicalIndex, ##__VA_ARGS__)
#define MPP_LOGI(msg, ...) ALOGI("[%s][%d] " msg, mName.string(), mLogicalIndex, ##__VA_ARGS__)
#define MPP_LOGW(msg, ...) ALOGW("[%s][%d] " msg, mName.string(), mLogicalIndex, ##__VA_ARGS__)
diff --git a/libhwc2.1/libdevice/ExynosDisplay.cpp b/libhwc2.1/libdevice/ExynosDisplay.cpp
index d050dee..a29927d 100644
--- a/libhwc2.1/libdevice/ExynosDisplay.cpp
+++ b/libhwc2.1/libdevice/ExynosDisplay.cpp
@@ -4086,6 +4086,12 @@ int32_t ExynosDisplay::setActiveConfigWithConstraints(hwc2_config_t config,
if (isBadConfig(config)) return HWC2_ERROR_BAD_CONFIG;
+ if (!isConfigSettingEnabled()) {
+ mPendingConfig = config;
+ DISPLAY_LOGI("%s: config setting disabled, set pending config=%d", __func__, config);
+ return HWC2_ERROR_NONE;
+ }
+
if (mDisplayConfigs[mActiveConfig].groupId != mDisplayConfigs[config].groupId) {
if (vsyncPeriodChangeConstraints->seamlessRequired) {
DISPLAY_LOGD(eDebugDisplayConfig, "Case : Seamless is not allowed");
@@ -6284,3 +6290,34 @@ void ExynosDisplay::updateRefreshRateIndicator() {
return;
mRefreshRateIndicatorHandler->handleSysfsEvent();
}
+
+uint32_t ExynosDisplay::getPeakRefreshRate() {
+ float opRate = mOperationRateManager ? mOperationRateManager->getOperationRate() : 0;
+ return static_cast<uint32_t>(std::round(opRate ?: mPeakRefreshRate));
+}
+
+VsyncPeriodNanos ExynosDisplay::getVsyncPeriod(const int32_t config) {
+ const auto &it = mDisplayConfigs.find(config);
+ if (it == mDisplayConfigs.end()) return 0;
+ return mDisplayConfigs[config].vsyncPeriod;
+}
+
+uint32_t ExynosDisplay::getRefreshRate(const int32_t config) {
+ VsyncPeriodNanos period = getVsyncPeriod(config);
+ if (!period) return 0;
+ constexpr float nsecsPerSec = std::chrono::nanoseconds(1s).count();
+ return round(nsecsPerSec / period * 0.1f) * 10;
+}
+
+uint32_t ExynosDisplay::getConfigId(const int32_t refreshRate, const int32_t width,
+ const int32_t height) {
+ for (auto entry : mDisplayConfigs) {
+ auto config = entry.first;
+ auto displayCfg = entry.second;
+ if (getRefreshRate(config) == refreshRate && displayCfg.width == width &&
+ displayCfg.height == height) {
+ return config;
+ }
+ }
+ return UINT_MAX;
+}
diff --git a/libhwc2.1/libdevice/ExynosDisplay.h b/libhwc2.1/libdevice/ExynosDisplay.h
index 65dd936..8a12393 100644
--- a/libhwc2.1/libdevice/ExynosDisplay.h
+++ b/libhwc2.1/libdevice/ExynosDisplay.h
@@ -562,6 +562,8 @@ class ExynosDisplay {
hwc2_config_t mDesiredConfig;
hwc2_config_t mActiveConfig = UINT_MAX;
+ hwc2_config_t mPendingConfig = UINT_MAX;
+ int64_t mLastVsyncTimestamp = 0;
void initDisplay();
@@ -1282,14 +1284,17 @@ class ExynosDisplay {
virtual void updateAppliedActiveConfig(const hwc2_config_t /*newConfig*/,
const int64_t /*ts*/) {}
+ virtual bool isConfigSettingEnabled() { return true; }
+ virtual void enableConfigSetting(bool /*en*/) {}
+
// is the hint session both enabled and supported
bool usePowerHintSession();
void setPeakRefreshRate(float rr) { mPeakRefreshRate = rr; }
- uint32_t getPeakRefreshRate() {
- float opRate = mOperationRateManager ? mOperationRateManager->getOperationRate() : 0;
- return static_cast<uint32_t>(std::round(opRate ?: mPeakRefreshRate));
- }
+ uint32_t getPeakRefreshRate();
+ VsyncPeriodNanos getVsyncPeriod(const int32_t config);
+ uint32_t getRefreshRate(const int32_t config);
+ uint32_t getConfigId(const int32_t refreshRate, const int32_t width, const int32_t height);
// check if there are any dimmed layers
bool isMixedComposition();
diff --git a/libhwc2.1/libdisplayinterface/ExynosDisplayDrmInterface.cpp b/libhwc2.1/libdisplayinterface/ExynosDisplayDrmInterface.cpp
index 86ce1c5..27d541b 100644
--- a/libhwc2.1/libdisplayinterface/ExynosDisplayDrmInterface.cpp
+++ b/libhwc2.1/libdisplayinterface/ExynosDisplayDrmInterface.cpp
@@ -747,6 +747,30 @@ void ExynosDisplayDrmInterface::Callback(
if (!mExynosDisplay->mPlugState || !mVsyncCallback.getVSyncEnabled()) {
return;
}
+
+ // Refresh rate during enabling LHBM might be different from the one SF expects.
+ // HWC just reports the SF expected Vsync to make UI smoothness consistent even if
+ // HWC runs at different refresh rate temporarily.
+ if (!mExynosDisplay->isConfigSettingEnabled()) {
+ int64_t pendingPeriodNs =
+ mExynosDisplay->getVsyncPeriod(mExynosDisplay->mPendingConfig);
+ int64_t activePeriodNs = mExynosDisplay->getVsyncPeriod(mExynosDisplay->mActiveConfig);
+ if (pendingPeriodNs && mExynosDisplay->mLastVsyncTimestamp) {
+ if (activePeriodNs > pendingPeriodNs) {
+ DISPLAY_DRM_LOGW("wrong vsync period: %" PRId64 "us (active), %" PRId64
+ "us (pending)",
+ activePeriodNs / 1000, pendingPeriodNs / 1000);
+ } else if (activePeriodNs != pendingPeriodNs) {
+ int64_t deltaNs = timestamp - mExynosDisplay->mLastVsyncTimestamp;
+ if (deltaNs < (pendingPeriodNs - ms2ns(2))) {
+ DISPLAY_DRM_LOGI("skip mismatching Vsync callback, delta=%" PRId64 "us",
+ deltaNs / 1000);
+ return;
+ }
+ }
+ }
+ }
+ mExynosDisplay->mLastVsyncTimestamp = timestamp;
}
ExynosDevice *exynosDevice = mExynosDisplay->mDevice;
@@ -1152,6 +1176,7 @@ int32_t ExynosDisplayDrmInterface::setActiveConfigWithConstraints(
if (mExynosDisplay->mOperationRateManager) {
mExynosDisplay->mOperationRateManager->onConfig(config);
}
+ DISPLAY_DRM_LOGI("%s: config(%d)", __func__, config);
} else {
ALOGD("%s:: same desired mode %d", __func__, config);
}
@@ -1243,9 +1268,9 @@ int32_t ExynosDisplayDrmInterface::setActiveConfig(hwc2_config_t config) {
mExynosDisplay->updateAppliedActiveConfig(config, systemTime(SYSTEM_TIME_MONOTONIC));
if (!setActiveDrmMode(*mode)) {
- ALOGI("%s:: %s config(%d)", __func__, mExynosDisplay->mDisplayName.string(), config);
+ DISPLAY_DRM_LOGI("%s: config(%d)", __func__, config);
} else {
- ALOGE("%s:: %s config(%d) failed", __func__, mExynosDisplay->mDisplayName.string(), config);
+ DISPLAY_DRM_LOGE("%s: config(%d) failed", __func__, config);
}
return 0;
@@ -1838,6 +1863,11 @@ int32_t ExynosDisplayDrmInterface::deliverWinConfigData()
(plane->id() != static_cast<ExynosPrimaryDisplay *>(mExynosDisplay)->mRcdId))
continue;
+ /* If this plane is not supported by the CRTC binded with ExynosDisplay,
+ * it should be disabled by this ExynosDisplay */
+ if (!plane->GetCrtcSupported(*mDrmCrtc))
+ continue;
+
if ((ret = drmReq.atomicAddProperty(plane->id(),
plane->crtc_property(), 0)) < 0)
return ret;
@@ -1970,6 +2000,21 @@ int32_t ExynosDisplayDrmInterface::clearDisplayMode(DrmModeAtomicReq &drmReq)
return NO_ERROR;
}
+int32_t ExynosDisplayDrmInterface::triggerClearDisplayPlanes()
+{
+ ATRACE_CALL();
+ DrmModeAtomicReq drmReq(this);
+
+ clearDisplayPlanes(drmReq);
+ int ret = NO_ERROR;
+ if ((ret = drmReq.commit(0, true))) {
+ HWC_LOGE(mExynosDisplay, "%s:: Failed to commit pset ret=(%d)\n",
+ __func__, ret);
+ return ret;
+ }
+ return ret;
+}
+
int32_t ExynosDisplayDrmInterface::clearDisplayPlanes(DrmModeAtomicReq &drmReq)
{
int ret = NO_ERROR;
@@ -1983,6 +2028,11 @@ int32_t ExynosDisplayDrmInterface::clearDisplayPlanes(DrmModeAtomicReq &drmReq)
(exynosMPP->mReservedDisplay != (int32_t)mExynosDisplay->mDisplayId))
continue;
+ /* If this plane is not supported by the CRTC binded with ExynosDisplay,
+ * it should not be disabled by this ExynosDisplay */
+ if (!plane->GetCrtcSupported(*mDrmCrtc))
+ continue;
+
if ((ret = drmReq.atomicAddProperty(plane->id(),
plane->crtc_property(), 0)) < 0) {
break;
diff --git a/libhwc2.1/libdisplayinterface/ExynosDisplayDrmInterface.h b/libhwc2.1/libdisplayinterface/ExynosDisplayDrmInterface.h
index bf5c9aa..78ed3e4 100644
--- a/libhwc2.1/libdisplayinterface/ExynosDisplayDrmInterface.h
+++ b/libhwc2.1/libdisplayinterface/ExynosDisplayDrmInterface.h
@@ -331,6 +331,7 @@ class ExynosDisplayDrmInterface :
int32_t panelVsize() { return mPanelResolutionVsize; }
int32_t getPanelResolution();
uint32_t getCrtcId() { return mDrmCrtc->id(); }
+ int32_t triggerClearDisplayPlanes();
protected:
enum class HalMipiSyncType : uint32_t {
diff --git a/libhwc2.1/libdisplayinterface/ExynosDisplayInterface.h b/libhwc2.1/libdisplayinterface/ExynosDisplayInterface.h
index d133774..2eabdfc 100644
--- a/libhwc2.1/libdisplayinterface/ExynosDisplayInterface.h
+++ b/libhwc2.1/libdisplayinterface/ExynosDisplayInterface.h
@@ -53,6 +53,7 @@ class ExynosDisplayInterface {
virtual int32_t updateHdrCapabilities();
virtual int32_t deliverWinConfigData() {return NO_ERROR;};
virtual int32_t clearDisplay(bool __unused needModeClear = false) {return NO_ERROR;};
+ virtual int32_t triggerClearDisplayPlanes() { return NO_ERROR; }
virtual int32_t disableSelfRefresh(uint32_t __unused disable) {return NO_ERROR;};
virtual int32_t setForcePanic() {return NO_ERROR;};
virtual int getDisplayFd() {return -1;};
diff --git a/libhwc2.1/libmaindisplay/ExynosPrimaryDisplay.cpp b/libhwc2.1/libmaindisplay/ExynosPrimaryDisplay.cpp
index a6b5582..fb925db 100644
--- a/libhwc2.1/libmaindisplay/ExynosPrimaryDisplay.cpp
+++ b/libhwc2.1/libmaindisplay/ExynosPrimaryDisplay.cpp
@@ -172,7 +172,7 @@ int ExynosPrimaryDisplay::getDDIScalerMode(int width, int height) {
int32_t ExynosPrimaryDisplay::doDisplayConfigInternal(hwc2_config_t config) {
if (!mPowerModeState.has_value() || (*mPowerModeState != HWC2_POWER_MODE_ON) ||
!isConfigSettingEnabled()) {
- mPendActiveConfig = config;
+ mPendingConfig = config;
mConfigRequestState = hwc_request_state_t::SET_CONFIG_STATE_DONE;
DISPLAY_LOGI("%s:: Pending desired Config: %d", __func__, config);
return NO_ERROR;
@@ -181,8 +181,8 @@ int32_t ExynosPrimaryDisplay::doDisplayConfigInternal(hwc2_config_t config) {
}
int32_t ExynosPrimaryDisplay::getActiveConfigInternal(hwc2_config_t *outConfig) {
- if (outConfig && mPendActiveConfig != UINT_MAX) {
- *outConfig = mPendActiveConfig;
+ if (outConfig && mPendingConfig != UINT_MAX) {
+ *outConfig = mPendingConfig;
return HWC2_ERROR_NONE;
}
return ExynosDisplay::getActiveConfigInternal(outConfig);
@@ -198,18 +198,19 @@ int32_t ExynosPrimaryDisplay::setActiveConfigInternal(hwc2_config_t config, bool
}
if (!mPowerModeState.has_value() || (*mPowerModeState != HWC2_POWER_MODE_ON) ||
!isConfigSettingEnabled()) {
- mPendActiveConfig = config;
+ mPendingConfig = config;
return HWC2_ERROR_NONE;
}
return ExynosDisplay::setActiveConfigInternal(config, force);
}
int32_t ExynosPrimaryDisplay::applyPendingConfig() {
- hwc2_config_t config;
+ if (!isConfigSettingEnabled()) return HWC2_ERROR_NONE;
- if (mPendActiveConfig != UINT_MAX) {
- config = mPendActiveConfig;
- mPendActiveConfig = UINT_MAX;
+ hwc2_config_t config;
+ if (mPendingConfig != UINT_MAX) {
+ config = mPendingConfig;
+ mPendingConfig = UINT_MAX;
} else {
getActiveConfigInternal(&config);
}
@@ -276,6 +277,10 @@ int32_t ExynosPrimaryDisplay::setPowerOn() {
updateAppliedActiveConfig(0, 0);
int ret = NO_ERROR;
if (mDisplayId != 0 || !mFirstPowerOn) {
+ if (mDevice->hasOtherDisplayOn(this)) {
+ // TODO: This is useful for cmd mode, and b/282094671 tries to handles video mode
+ mDisplayInterface->triggerClearDisplayPlanes();
+ }
ret = applyPendingConfig();
}
@@ -530,7 +535,7 @@ bool ExynosPrimaryDisplay::isLhbmSupported() {
bool ExynosPrimaryDisplay::isConfigSettingEnabled() {
int64_t msSinceDisabled =
(systemTime(SYSTEM_TIME_MONOTONIC) - mConfigSettingDisabledTimestamp) / 1000000;
- return !mConfigSettingDisabled || msSinceDisabled > kLhbmMaxEnablingDurationMs;
+ return !mConfigSettingDisabled || msSinceDisabled > kConfigDisablingMaxDurationMs;
}
void ExynosPrimaryDisplay::enableConfigSetting(bool en) {
@@ -541,13 +546,41 @@ void ExynosPrimaryDisplay::enableConfigSetting(bool en) {
}
mConfigSettingDisabled = false;
- if (mPendActiveConfig != UINT_MAX) {
- hwc2_config_t config = mPendActiveConfig;
- if (applyPendingConfig() != HWC2_ERROR_NONE) {
- DISPLAY_LOGW("%s: failed to set mPendActiveConfig=%d", __func__, config);
+}
+
+void ExynosPrimaryDisplay::setLhbmDisplayConfig(uint32_t refreshRate) {
+ auto config = getConfigId(refreshRate, mDisplayConfigs[mActiveConfig].width,
+ mDisplayConfigs[mActiveConfig].height);
+
+ if (config == UINT_MAX) {
+ DISPLAY_LOGE("%s: failed to get config for rate=%d", __func__, refreshRate);
+ return;
+ }
+ if (mPendingConfig == UINT_MAX) mPendingConfig = mActiveConfig;
+
+ if (ExynosDisplay::setActiveConfigInternal(config, true) == HWC2_ERROR_NONE) {
+ DISPLAY_LOGI("%s: succeeded to set config=%d rate=%d", __func__, config, refreshRate);
+ } else {
+ DISPLAY_LOGW("%s: failed to set config=%d rate=%d", __func__, config, refreshRate);
+ }
+}
+
+void ExynosPrimaryDisplay::restoreLhbmDisplayConfig() {
+ if (mPendingConfig == UINT_MAX) return;
+
+ hwc2_config_t pendingCfg = mPendingConfig;
+ if (mPendingConfig != mActiveConfig) {
+ if (applyPendingConfig() == HWC2_ERROR_NONE) {
+ DISPLAY_LOGI("%s: succeeded to set config=%d rate=%d", __func__, pendingCfg,
+ getRefreshRate(pendingCfg));
} else {
- DISPLAY_LOGI("%s: succeed to set mPendActiveConfig=%d", __func__, config);
+ DISPLAY_LOGE("%s: failed to set config=%d rate=%d", __func__, pendingCfg,
+ getRefreshRate(pendingCfg));
}
+ } else {
+ mPendingConfig = UINT_MAX;
+ DISPLAY_LOGI("%s: keep config=%d rate=%d", __func__, pendingCfg,
+ getRefreshRate(pendingCfg));
}
}
@@ -594,19 +627,24 @@ int32_t ExynosPrimaryDisplay::setLhbmState(bool enabled) {
std::vector<std::string> checkingValue;
if (!enabled) {
ATRACE_NAME("disable_lhbm");
- checkingValue = {
- std::to_string(static_cast<int>(BrightnessController::LhbmMode::DISABLED))};
+ {
+ ATRACE_NAME("apply_pending_rate");
+ Mutex::Autolock lock(mDisplayMutex);
+ enableConfigSetting(true);
+ restoreLhbmDisplayConfig();
+ }
requestLhbm(false);
- ret = mBrightnessController->checkSysfsStatus(lhbmSysfs, checkingValue,
- ms2ns(kSysfsCheckTimeoutMs));
- if (ret != OK) {
- DISPLAY_LOGW("%s: failed to send lhbm-off cmd", __func__);
- } else if (mDisplayInterface->waitVBlank()) {
- DISPLAY_LOGE("%s: failed to wait vblank of making lhbm-off cmd effective", __func__);
+ {
+ ATRACE_NAME("wait_for_lhbm_off_cmd");
+ checkingValue = {
+ std::to_string(static_cast<int>(BrightnessController::LhbmMode::DISABLED))};
+ ret = mBrightnessController->checkSysfsStatus(lhbmSysfs, checkingValue,
+ ms2ns(kSysfsCheckTimeoutMs));
+ if (ret != OK) {
+ DISPLAY_LOGW("%s: failed to send lhbm-off cmd", __func__);
+ }
}
setLHBMRefreshRateThrottle(0);
- Mutex::Autolock lock(mDisplayMutex);
- enableConfigSetting(true);
mLhbmOn = false;
return NO_ERROR;
}
@@ -617,21 +655,23 @@ int32_t ExynosPrimaryDisplay::setLhbmState(bool enabled) {
uint32_t peakRate;
auto rrSysfs = mBrightnessController->GetPanelRefreshRateSysfile();
lhbmWaitForRrNanos = systemTime(SYSTEM_TIME_MONOTONIC);
- hwc2_config_t curConfig;
{
Mutex::Autolock lock(mDisplayMutex);
peakRate = getPeakRefreshRate();
- getActiveConfigInternal(&curConfig);
- if (curConfig == peakRate) {
- enableConfigSetting(false);
+ if (peakRate < 60) {
+ DISPLAY_LOGE("%s: invalid peak rate=%d", __func__, peakRate);
+ return -EINVAL;
}
+ if (getRefreshRate(mActiveConfig) != peakRate) {
+ ATRACE_NAME("request_peak_rate");
+ setLhbmDisplayConfig(peakRate);
+ }
+ enableConfigSetting(false);
}
if (mBrightnessController->fileExists(rrSysfs)) {
- ATRACE_NAME("wait_for_peak_rate_sent");
- if (peakRate) {
- ret = mBrightnessController->checkSysfsStatus(rrSysfs, {std::to_string(peakRate)},
- ms2ns(kLhbmWaitForPeakRefreshRateMs));
- }
+ ATRACE_NAME("wait_for_peak_rate_cmd");
+ ret = mBrightnessController->checkSysfsStatus(rrSysfs, {std::to_string(peakRate)},
+ ms2ns(kLhbmWaitForPeakRefreshRateMs));
if (ret != OK) {
DISPLAY_LOGW("%s: failed to poll peak refresh rate=%d, ret=%d", __func__, peakRate,
ret);
@@ -650,24 +690,21 @@ int32_t ExynosPrimaryDisplay::setLhbmState(bool enabled) {
}
}
}
- {
- Mutex::Autolock lock(mDisplayMutex);
- if (isConfigSettingEnabled()) {
- enableConfigSetting(false);
- }
- }
setLHBMRefreshRateThrottle(kLhbmRefreshRateThrottleMs);
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);
- ret = mBrightnessController->checkSysfsStatus(lhbmSysfs, checkingValue,
- ms2ns(kSysfsCheckTimeoutMs));
- if (ret != OK) {
- DISPLAY_LOGE("%s: failed to enable lhbm", __func__);
- setLHBMRefreshRateThrottle(0);
- goto enable_err;
+ requestLhbm(true);
+ {
+ ATRACE_NAME("wait_for_lhbm_on_cmd");
+ ret = mBrightnessController->checkSysfsStatus(lhbmSysfs, checkingValue,
+ ms2ns(kSysfsCheckTimeoutMs));
+ if (ret != OK) {
+ DISPLAY_LOGE("%s: failed to enable lhbm", __func__);
+ setLHBMRefreshRateThrottle(0);
+ goto enable_err;
+ }
}
lhbmEnablingDoneNanos = systemTime(SYSTEM_TIME_MONOTONIC);
@@ -710,6 +747,7 @@ int32_t ExynosPrimaryDisplay::setLhbmState(bool enabled) {
enable_err:
Mutex::Autolock lock(mDisplayMutex);
enableConfigSetting(true);
+ restoreLhbmDisplayConfig();
return ret;
}
@@ -1047,6 +1085,7 @@ void ExynosPrimaryDisplay::checkBtsReassignResource(const uint32_t vsyncPeriod,
ATRACE_CALL();
uint32_t refreshRate = static_cast<uint32_t>(round(nsecsPerSec / vsyncPeriod * 0.1f) * 10);
+ Mutex::Autolock lock(mDRMutex);
if (vsyncPeriod < btsVsyncPeriod) {
for (size_t i = 0; i < mLayers.size(); i++) {
if (mLayers[i]->mOtfMPP && mLayers[i]->mM2mMPP == nullptr &&
diff --git a/libhwc2.1/libmaindisplay/ExynosPrimaryDisplay.h b/libhwc2.1/libmaindisplay/ExynosPrimaryDisplay.h
index e111907..796f6ef 100644
--- a/libhwc2.1/libmaindisplay/ExynosPrimaryDisplay.h
+++ b/libhwc2.1/libmaindisplay/ExynosPrimaryDisplay.h
@@ -64,6 +64,8 @@ class ExynosPrimaryDisplay : public ExynosDisplay {
virtual int32_t setBootDisplayConfig(int32_t config) override;
virtual int32_t clearBootDisplayConfig() override;
virtual int32_t getPreferredDisplayConfigInternal(int32_t* outConfig) override;
+ virtual bool isConfigSettingEnabled() override;
+ virtual void enableConfigSetting(bool en) override;
protected:
/* setPowerMode(int32_t mode)
@@ -87,7 +89,6 @@ class ExynosPrimaryDisplay : public ExynosDisplay {
// Prepare multi resolution
ResolutionInfo mResolutionInfo;
std::string getPanelSysfsPath(const displaycolor::DisplayType& type);
- bool isConfigSettingEnabled();
uint32_t mRcdId = -1;
@@ -99,7 +100,6 @@ class ExynosPrimaryDisplay : public ExynosDisplay {
bool checkLhbmMode(bool status, nsecs_t timoutNs);
void setLHBMRefreshRateThrottle(const uint32_t delayMs);
- hwc2_config_t mPendActiveConfig = UINT_MAX;
bool mFirstPowerOn = true;
bool mNotifyPowerOn = false;
std::mutex mPowerModeMutex;
@@ -116,6 +116,8 @@ class ExynosPrimaryDisplay : public ExynosDisplay {
int32_t setDisplayIdleDelayNanos(int32_t delayNanos,
const DispIdleTimerRequester requester);
void initDisplayHandleIdleExit();
+ void setLhbmDisplayConfig(uint32_t refreshRate);
+ void restoreLhbmDisplayConfig();
// LHBM
FILE* mLhbmFd;
@@ -126,9 +128,9 @@ class ExynosPrimaryDisplay : public ExynosDisplay {
// timeout value of waiting for peak refresh rate
static constexpr uint32_t kLhbmWaitForPeakRefreshRateMs = 100U;
static constexpr uint32_t kLhbmRefreshRateThrottleMs = 1000U;
- static constexpr uint32_t kLhbmMaxEnablingDurationMs = 1000U;
+ static constexpr uint32_t kConfigDisablingMaxDurationMs = 1000U;
static constexpr uint32_t kSysfsCheckTimeoutMs = 500U;
- void enableConfigSetting(bool en);
+
int32_t getTimestampDeltaMs(int64_t endNs, int64_t beginNs) {
if (endNs == 0) endNs = systemTime(SYSTEM_TIME_MONOTONIC);
return (endNs - beginNs) / 1000000;