summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShiyong Li <shiyongli@google.com>2023-11-20 17:54:11 +0000
committerShiyong Li <shiyongli@google.com>2023-11-21 17:18:28 +0000
commit578865993087cbdc7632d1d1035c8f671d745933 (patch)
tree9ba5fcea5ed2378df0dadb0bd9203e38751f0f83
parentc5d57b4bd182200878fec0c49b2a28daf7d6776d (diff)
downloadcommon-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.cpp11
-rw-r--r--libhwc2.1/libdevice/ExynosDisplay.h1
-rw-r--r--libhwc2.1/libdisplayinterface/ExynosDisplayDrmInterface.cpp3
-rw-r--r--libhwc2.1/libexternaldisplay/ExynosExternalDisplay.cpp2
-rw-r--r--libhwc2.1/libmaindisplay/ExynosPrimaryDisplay.cpp39
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() {