diff options
author | Shiyong Li <shiyongli@google.com> | 2023-11-20 17:54:11 +0000 |
---|---|---|
committer | Shiyong Li <shiyongli@google.com> | 2023-11-21 17:18:28 +0000 |
commit | 578865993087cbdc7632d1d1035c8f671d745933 (patch) | |
tree | 9ba5fcea5ed2378df0dadb0bd9203e38751f0f83 | |
parent | c5d57b4bd182200878fec0c49b2a28daf7d6776d (diff) | |
download | common-578865993087cbdc7632d1d1035c8f671d745933.tar.gz |
libhwc2.1: support VRR mode searching and boot config
new format for the property persist.vendor.display.primary.boot_config:
<width>x<height>@<refresh rate>:<vsync rate>
e.g. 1008x2244@120:120
Bug: 308095238
Test: check preferred mode and boot config
Change-Id: I51e573959dff491fbfbb02e7352554b1e6fd42aa
Signed-off-by: Shiyong Li <shiyongli@google.com>
-rw-r--r-- | libhwc2.1/libdevice/ExynosDisplay.cpp | 11 | ||||
-rw-r--r-- | libhwc2.1/libdevice/ExynosDisplay.h | 1 | ||||
-rw-r--r-- | libhwc2.1/libdisplayinterface/ExynosDisplayDrmInterface.cpp | 3 | ||||
-rw-r--r-- | libhwc2.1/libexternaldisplay/ExynosExternalDisplay.cpp | 2 | ||||
-rw-r--r-- | libhwc2.1/libmaindisplay/ExynosPrimaryDisplay.cpp | 39 |
5 files changed, 37 insertions, 19 deletions
diff --git a/libhwc2.1/libdevice/ExynosDisplay.cpp b/libhwc2.1/libdevice/ExynosDisplay.cpp index 4565e65..614fc69 100644 --- a/libhwc2.1/libdevice/ExynosDisplay.cpp +++ b/libhwc2.1/libdevice/ExynosDisplay.cpp @@ -6195,21 +6195,22 @@ bool ExynosDisplay::isMixedComposition() { int ExynosDisplay::lookupDisplayConfigs(const int32_t &width, const int32_t &height, const int32_t &fps, + const int32_t &vsyncRate, int32_t *outConfig) { - if (!fps) + if (!fps || !vsyncRate) return HWC2_ERROR_BAD_CONFIG; constexpr auto nsecsPerSec = std::chrono::nanoseconds(1s).count(); constexpr auto nsecsPerMs = std::chrono::nanoseconds(1ms).count(); - const auto vsyncPeriod = nsecsPerSec / fps; + const auto vsyncPeriod = nsecsPerSec / vsyncRate; for (auto const& [config, mode] : mDisplayConfigs) { long delta = abs(vsyncPeriod - mode.vsyncPeriod); if ((width == 0 || width == mode.width) && (height == 0 || height == mode.height) && - (delta < nsecsPerMs)) { - ALOGD("%s: found display config for mode: %dx%d@%d=%d", - __func__, width, height, fps, config); + (delta < nsecsPerMs) && (fps == mode.refreshRate)) { + ALOGD("%s: found display config for mode: %dx%d@%d:%d config=%d", + __func__, width, height, fps, vsyncRate, config); *outConfig = config; return HWC2_ERROR_NONE; } diff --git a/libhwc2.1/libdevice/ExynosDisplay.h b/libhwc2.1/libdevice/ExynosDisplay.h index f347592..08b06c2 100644 --- a/libhwc2.1/libdevice/ExynosDisplay.h +++ b/libhwc2.1/libdevice/ExynosDisplay.h @@ -1363,6 +1363,7 @@ class ExynosDisplay { int lookupDisplayConfigs(const int32_t& width, const int32_t& height, const int32_t& fps, + const int32_t& vsyncRate, int32_t* outConfig); private: diff --git a/libhwc2.1/libdisplayinterface/ExynosDisplayDrmInterface.cpp b/libhwc2.1/libdisplayinterface/ExynosDisplayDrmInterface.cpp index d93485d..c17cba6 100644 --- a/libhwc2.1/libdisplayinterface/ExynosDisplayDrmInterface.cpp +++ b/libhwc2.1/libdisplayinterface/ExynosDisplayDrmInterface.cpp @@ -979,9 +979,10 @@ int32_t ExynosDisplayDrmInterface::choosePreferredConfig() { int32_t config = -1; char modeStr[PROPERTY_VALUE_MAX] = "\0"; int32_t width = 0, height = 0, fps = 0; + // only legacy products use this property, kernel preferred mode will be used going forward if (property_get("vendor.display.preferred_mode", modeStr, "") > 0 && sscanf(modeStr, "%dx%d@%d", &width, &height, &fps) == 3) { - err = mExynosDisplay->lookupDisplayConfigs(width, height, fps, &config); + err = mExynosDisplay->lookupDisplayConfigs(width, height, fps, fps, &config); } else { err = HWC2_ERROR_BAD_CONFIG; } diff --git a/libhwc2.1/libexternaldisplay/ExynosExternalDisplay.cpp b/libhwc2.1/libexternaldisplay/ExynosExternalDisplay.cpp index 7ef4a85..168cc81 100644 --- a/libhwc2.1/libexternaldisplay/ExynosExternalDisplay.cpp +++ b/libhwc2.1/libexternaldisplay/ExynosExternalDisplay.cpp @@ -136,7 +136,7 @@ int ExynosExternalDisplay::getDisplayConfigs(uint32_t* outNumConfigs, hwc2_confi if (property_get("vendor.display.external.preferred_mode", modeStr, "") > 0) { if (sscanf(modeStr, "%dx%d@%d", &width, &height, &fps) == 3) { - err = lookupDisplayConfigs(width, height, fps, &config); + err = lookupDisplayConfigs(width, height, fps, fps, &config); if (err != HWC2_ERROR_NONE) { DISPLAY_LOGW("%s: display does not support preferred mode %dx%d@%d", __func__, width, height, fps); diff --git a/libhwc2.1/libmaindisplay/ExynosPrimaryDisplay.cpp b/libhwc2.1/libmaindisplay/ExynosPrimaryDisplay.cpp index 579e747..672b17f 100644 --- a/libhwc2.1/libmaindisplay/ExynosPrimaryDisplay.cpp +++ b/libhwc2.1/libmaindisplay/ExynosPrimaryDisplay.cpp @@ -305,15 +305,14 @@ int32_t ExynosPrimaryDisplay::setBootDisplayConfig(int32_t config) { if (mode.vsyncPeriod == 0) return HWC2_ERROR_BAD_CONFIG; - int refreshRate = round(nsecsPerSec / mode.vsyncPeriod * 0.1f) * 10; + int vsyncRate = round(static_cast<float>(nsecsPerSec) / mode.vsyncPeriod); char modeStr[PROPERTY_VALUE_MAX]; - int ret = snprintf(modeStr, sizeof(modeStr), "%dx%d@%d", - mode.width, mode.height, refreshRate); + int ret = snprintf(modeStr, sizeof(modeStr), "%dx%d@%d:%d", + mode.width, mode.height, mode.refreshRate, vsyncRate); if (ret <= 0) return HWC2_ERROR_BAD_CONFIG; - ALOGD("%s: mode=%s (%d) vsyncPeriod=%d", __func__, modeStr, config, - mode.vsyncPeriod); + ALOGD("%s: mode=%s (%d)", __func__, modeStr, config); ret = property_set(getPropertyBootModeStr(mDisplayId).c_str(), modeStr); return !ret ? HWC2_ERROR_NONE : HWC2_ERROR_BAD_CONFIG; @@ -335,15 +334,31 @@ int32_t ExynosPrimaryDisplay::getPreferredDisplayConfigInternal(int32_t *outConf } int width, height; - int fps = 0; - - ret = sscanf(modeStr, "%dx%d@%d", &width, &height, &fps); - if ((ret < 3) || !fps) { - ALOGD("%s: unable to find boot config for mode: %s", __func__, modeStr); + int fps = 0, vsyncRate = 0; + + ret = sscanf(modeStr, "%dx%d@%d:%d", &width, &height, &fps, &vsyncRate); + if (ret < 4) { + ret = sscanf(modeStr, "%dx%d@%d", &width, &height, &fps); + if ((ret < 3) || !fps) { + ALOGW("%s: unable to find boot config for mode: %s", __func__, modeStr); + return HWC2_ERROR_BAD_CONFIG; + } + if (lookupDisplayConfigs(width, height, fps, fps, outConfig) != HWC2_ERROR_NONE) { + ALOGE("%s: kernel doesn't support mode: %s", __func__, modeStr); + return HWC2_ERROR_BAD_CONFIG; + } + ret = setBootDisplayConfig(*outConfig); + if (ret == HWC2_ERROR_NONE) + ALOGI("%s: succeeded to replace %s with new format", __func__, modeStr); + else + ALOGE("%s: failed to replace %s with new format", __func__, modeStr); + return ret; + } + if (!fps || !vsyncRate || (fps > vsyncRate)) { + ALOGE("%s: bad boot config: %s", __func__, modeStr); return HWC2_ERROR_BAD_CONFIG; } - - return lookupDisplayConfigs(width, height, fps, outConfig); + return lookupDisplayConfigs(width, height, fps, vsyncRate, outConfig); } int32_t ExynosPrimaryDisplay::setPowerOn() { |