drm_hwcomposer: Add property to force display mode
* Display resolution and refresh rate can be forced using a property.
Other modes reported as supported by the display are ignored when forcing
a specific mode.
* Force resolution and refresh rate for headless mode as well.
This is based on following 4 commits with further updates.
Author: Chih-Wei Huang <cwhuang@linux.org.tw>
Date: Wed Sep 19 22:57:32 2018 +0800
drm_hwcomposer: allow to force mode by a property
The desired resolution could be set by property debug.drm.mode.force.
The other modes are ignored.
Author: Konsta <konsta09@gmail.com>
Date: Sun Dec 5 15:40:40 2021 +0200
drm_hwcomposer: use first refresh rate reported by the display
* Android can switch between different refresh rates which
can lead to display changing modes in some cases.
* Use the first refresh rate reported by the display when
forcing the resolution unless specified otherwise.
Author: Konsta <konsta09@gmail.com>
Date: Tue Jan 25 17:46:33 2022 +0200
drm_hwcomposer: Default to 1920x1080 resolution for headless mode
Author: Konsta <konsta09@gmail.com>
Date: Tue Feb 1 17:40:43 2022 +0200
drm_hwcomposer: Allow setting resolution for headless mode
This commit is contained in:
parent
5ee173b752
commit
e2e9c8cff7
4 changed files with 62 additions and 6 deletions
|
|
@ -29,6 +29,7 @@
|
|||
|
||||
#include "DrmDevice.h"
|
||||
#include "compositor/DisplayInfo.h"
|
||||
#include "utils/properties.h"
|
||||
|
||||
#ifndef DRM_MODE_CONNECTOR_SPI
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
|
||||
|
|
@ -242,6 +243,18 @@ std::string DrmConnector::GetName() const {
|
|||
}
|
||||
|
||||
int DrmConnector::UpdateModes() {
|
||||
std::string force_mode = Properties::GetForceMode();
|
||||
uint32_t xres = 0, yres = 0, rate = 0;
|
||||
// Parse <xres>x<yres>[@<refreshrate>]
|
||||
if (sscanf(force_mode.c_str(), "%dx%d@%d", &xres, &yres, &rate) != 3) {
|
||||
rate = 0;
|
||||
if (sscanf(force_mode.c_str(), "%dx%d", &xres, &yres) != 2) {
|
||||
xres = yres = 0;
|
||||
}
|
||||
}
|
||||
ALOGI_IF(xres && yres, "Force mode %dx%d@%dHz for display in connector %s",
|
||||
xres, yres, rate, GetName().c_str());
|
||||
|
||||
auto conn = MakeDrmModeConnectorUnique(*drm_->GetFd(), GetId());
|
||||
if (!conn) {
|
||||
ALOGE("Failed to get connector %d", GetId());
|
||||
|
|
@ -260,7 +273,25 @@ int DrmConnector::UpdateModes() {
|
|||
}
|
||||
|
||||
if (!exists) {
|
||||
modes_.emplace_back(&connector_->modes[i]);
|
||||
DrmMode m(&connector_->modes[i]);
|
||||
ALOGV("Supported mode %dx%d@%fHz for display in connector %s",
|
||||
m.GetRawMode().hdisplay, m.GetRawMode().vdisplay,
|
||||
m.GetVRefresh(), GetName().c_str());
|
||||
if (xres && yres) {
|
||||
if (!rate && m.GetRawMode().hdisplay == xres
|
||||
&& m.GetRawMode().vdisplay == yres) {
|
||||
rate = m.GetVRefresh();
|
||||
}
|
||||
if (m.GetRawMode().hdisplay != xres
|
||||
|| m.GetRawMode().vdisplay != yres
|
||||
|| m.GetVRefresh() != rate) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
ALOGD("Add mode %dx%d@%fHz for display in connector %s",
|
||||
m.GetRawMode().hdisplay, m.GetRawMode().vdisplay,
|
||||
m.GetVRefresh(), GetName().c_str());
|
||||
modes_.emplace_back(m);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -23,12 +23,8 @@
|
|||
|
||||
#include "compositor/DisplayInfo.h"
|
||||
#include "drm/DrmConnector.h"
|
||||
#include "utils/properties.h"
|
||||
|
||||
constexpr uint32_t kHeadlessModeDisplayWidthMm = 163;
|
||||
constexpr uint32_t kHeadlessModeDisplayHeightMm = 122;
|
||||
constexpr uint32_t kHeadlessModeDisplayWidthPx = 1024;
|
||||
constexpr uint32_t kHeadlessModeDisplayHeightPx = 768;
|
||||
constexpr uint32_t kHeadlessModeDisplayVRefresh = 60;
|
||||
constexpr uint32_t kSyncLen = 10;
|
||||
constexpr uint32_t kBackPorch = 10;
|
||||
constexpr uint32_t kFrontPorch = 10;
|
||||
|
|
@ -37,6 +33,24 @@ constexpr uint32_t kHzInKHz = 1000;
|
|||
namespace android::drm_hwcomposer {
|
||||
|
||||
void HwcDisplayConfigs::GenFakeMode(uint16_t width, uint16_t height) {
|
||||
std::string force_mode = Properties::GetForceMode();
|
||||
uint32_t xres = 0, yres = 0, rate = 0;
|
||||
// Parse <xres>x<yres>[@<refreshrate>]
|
||||
if (sscanf(force_mode.c_str(), "%dx%d@%d", &xres, &yres, &rate) != 3) {
|
||||
rate = 0;
|
||||
if (sscanf(force_mode.c_str(), "%dx%d", &xres, &yres) != 2) {
|
||||
xres = yres = 0;
|
||||
}
|
||||
}
|
||||
ALOGI_IF(xres && yres, "Force mode %dx%d@%dHz for HEADLESS-MODE",
|
||||
xres, yres, rate);
|
||||
|
||||
const uint32_t kHeadlessModeDisplayWidthMm = xres ? xres : 160;
|
||||
const uint32_t kHeadlessModeDisplayHeightMm = yres ? yres : 90;
|
||||
const uint32_t kHeadlessModeDisplayWidthPx = xres ? xres : 1920;
|
||||
const uint32_t kHeadlessModeDisplayHeightPx = yres ? yres : 1080;
|
||||
const uint32_t kHeadlessModeDisplayVRefresh = rate ? rate : 60;
|
||||
|
||||
hwc_configs.clear();
|
||||
|
||||
preferred_config_id = active_config_id = next_config_id++;
|
||||
|
|
@ -81,6 +95,10 @@ void HwcDisplayConfigs::GenFakeMode(uint16_t width, uint16_t height) {
|
|||
|
||||
mm_width = kHeadlessModeDisplayWidthMm;
|
||||
mm_height = kHeadlessModeDisplayHeightMm;
|
||||
|
||||
ALOGI("Add mode %dx%d@%dHz for %s",
|
||||
headless_drm_mode_info.hdisplay, headless_drm_mode_info.vdisplay,
|
||||
headless_drm_mode_info.vrefresh, headless_drm_mode_info.name);
|
||||
}
|
||||
|
||||
bool HwcDisplayConfigs::Init(DrmConnector &connector) {
|
||||
|
|
|
|||
|
|
@ -144,4 +144,10 @@ auto Properties::GetDevicePath() -> std::string {
|
|||
return {path_pattern};
|
||||
}
|
||||
|
||||
auto Properties::GetForceMode() -> std::string {
|
||||
char force_mode[PROPERTY_VALUE_MAX];
|
||||
property_get("vendor.hwc.drm.force_mode", force_mode, "");
|
||||
return {force_mode};
|
||||
}
|
||||
|
||||
} // namespace android::drm_hwcomposer
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ class Properties {
|
|||
static auto GetCtmHandling() -> CtmHandling;
|
||||
static auto GetBackendOverride() -> std::string;
|
||||
static auto GetDevicePath() -> std::string;
|
||||
static auto GetForceMode() -> std::string;
|
||||
};
|
||||
|
||||
} // namespace android::drm_hwcomposer
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue