From 67dc0c5c48c3fd3fae45a2fd42d7ccd353ff4235 Mon Sep 17 00:00:00 2001 From: Xaver Hugl Date: Sat, 25 Mar 2023 17:51:52 +0100 Subject: [PATCH] backends/drm: restrict common mode generation to drivers that support scaling Also set the scaling mode property to "full aspect", which should reduce the number of cases where the feature can cause issues --- autotests/drm/drmTest.cpp | 9 +++++++++ src/backends/drm/drm_connector.cpp | 7 +++++-- src/backends/drm/drm_connector.h | 7 +++++++ src/backends/drm/drm_pipeline.cpp | 3 +++ src/backends/drm/drm_pipeline_legacy.cpp | 3 +++ 5 files changed, 27 insertions(+), 2 deletions(-) diff --git a/autotests/drm/drmTest.cpp b/autotests/drm/drmTest.cpp index 5e87ee4ece..068926582c 100644 --- a/autotests/drm/drmTest.cpp +++ b/autotests/drm/drmTest.cpp @@ -266,6 +266,15 @@ void DrmTest::testModeGeneration() conn->addMode(nativeMode.width(), nativeMode.height(), 60); QVERIFY(gpu->updateOutputs()); QCOMPARE(gpu->drmOutputs().size(), 1); + // no mode generation without the scaling property + QCOMPARE(gpu->drmOutputs().front()->modes().size(), 1); + + mockGpu->connectors.removeAll(conn); + QVERIFY(gpu->updateOutputs()); + + conn->props.emplace_back(conn.get(), QStringLiteral("scaling mode"), 0, 0, QVector{"None", "Full", "Center", "Full aspect"}); + mockGpu->connectors.push_back(conn); + QVERIFY(gpu->updateOutputs()); DrmOutput *const output = gpu->drmOutputs().front(); QCOMPARE(output->modes().size(), expectedModes.size()); diff --git a/src/backends/drm/drm_connector.cpp b/src/backends/drm/drm_connector.cpp index 7fa9e0e124..82ee8090ee 100644 --- a/src/backends/drm/drm_connector.cpp +++ b/src/backends/drm/drm_connector.cpp @@ -105,7 +105,8 @@ DrmConnector::DrmConnector(DrmGpu *gpu, uint32_t connectorId) PropertyDefinition(QByteArrayLiteral("content type"), Requirement::Optional, {QByteArrayLiteral("No Data"), QByteArrayLiteral("Graphics"), QByteArrayLiteral("Photo"), QByteArrayLiteral("Cinema"), QByteArrayLiteral("Game")}), PropertyDefinition(QByteArrayLiteral("panel orientation"), Requirement::Optional, {QByteArrayLiteral("Normal"), QByteArrayLiteral("Upside Down"), QByteArrayLiteral("Left Side Up"), QByteArrayLiteral("Right Side Up")}), - PropertyDefinition(QByteArrayLiteral("HDR_OUTPUT_METADATA"), Requirement::Optional)}, + PropertyDefinition(QByteArrayLiteral("HDR_OUTPUT_METADATA"), Requirement::Optional), + PropertyDefinition(QByteArrayLiteral("scaling mode"), Requirement::Optional, {QByteArrayLiteral("None"), QByteArrayLiteral("Full"), QByteArrayLiteral("Center"), QByteArrayLiteral("Full aspect")})}, DRM_MODE_OBJECT_CONNECTOR) , m_pipeline(std::make_unique(this)) , m_conn(drmModeGetConnector(gpu->fd(), connectorId)) @@ -282,7 +283,9 @@ bool DrmConnector::updateProperties() } m_modes.clear(); m_modes.append(m_driverModes); - m_modes.append(generateCommonModes()); + if (auto scaling = getProp(PropertyIndex::ScalingMode); scaling && scaling->hasEnum(ScalingMode::Full_Aspect)) { + m_modes.append(generateCommonModes()); + } if (m_pipeline->mode()) { if (const auto mode = findMode(*m_pipeline->mode()->nativeMode())) { m_pipeline->setMode(mode); diff --git a/src/backends/drm/drm_connector.h b/src/backends/drm/drm_connector.h index 40a51dec85..f40327a848 100644 --- a/src/backends/drm/drm_connector.h +++ b/src/backends/drm/drm_connector.h @@ -67,6 +67,7 @@ public: ContentType = 12, PanelOrientation = 13, HdrMetadata = 14, + ScalingMode = 15, Count }; @@ -92,6 +93,12 @@ public: LeftUp = 2, RightUp = 3 }; + enum class ScalingMode : uint32_t { + None = 0, + Full = 1, + Center = 2, + Full_Aspect = 3 + }; bool init() override; bool updateProperties() override; diff --git a/src/backends/drm/drm_pipeline.cpp b/src/backends/drm/drm_pipeline.cpp index b7462e255c..dcd156ac40 100644 --- a/src/backends/drm/drm_pipeline.cpp +++ b/src/backends/drm/drm_pipeline.cpp @@ -264,6 +264,9 @@ void DrmPipeline::prepareAtomicModeset(DrmAtomicCommit *commit) if (const auto hdr = m_connector->getProp(DrmConnector::PropertyIndex::HdrMetadata)) { commit->addProperty(hdr, 0); } + if (const auto scaling = m_connector->getProp(DrmConnector::PropertyIndex::ScalingMode); scaling && scaling->hasEnum(DrmConnector::ScalingMode::Full_Aspect)) { + commit->addEnum(scaling, DrmConnector::ScalingMode::Full_Aspect); + } commit->addProperty(m_pending.crtc->getProp(DrmCrtc::PropertyIndex::Active), 1); commit->addBlob(m_pending.crtc->getProp(DrmCrtc::PropertyIndex::ModeId), m_pending.mode->blob()); diff --git a/src/backends/drm/drm_pipeline_legacy.cpp b/src/backends/drm/drm_pipeline_legacy.cpp index c17bccd0e8..306d842fd3 100644 --- a/src/backends/drm/drm_pipeline_legacy.cpp +++ b/src/backends/drm/drm_pipeline_legacy.cpp @@ -112,6 +112,9 @@ DrmPipeline::Error DrmPipeline::applyPendingChangesLegacy() m_connector->getProp(DrmConnector::PropertyIndex::Underscan_vborder)->setPropertyLegacy(m_pending.overscan); m_connector->getProp(DrmConnector::PropertyIndex::Underscan_hborder)->setPropertyLegacy(hborder); } + if (const auto scaling = m_connector->getProp(DrmConnector::PropertyIndex::ScalingMode); scaling && scaling->hasEnum(DrmConnector::ScalingMode::Full_Aspect)) { + scaling->setEnumLegacy(DrmConnector::ScalingMode::Full_Aspect); + } if (m_pending.crtc != m_current.crtc || m_pending.mode != m_current.mode) { Error err = legacyModeset(); if (err != Error::None) {