Make OutputConfiguration take OutputMode

OutputMode provides a more robust way to refer to outputs. A mode can
have flags and things as such that are not taken into account with mode
+ refresh rate.
This commit is contained in:
Vlad Zahorodnii 2022-07-26 13:13:20 +03:00
parent 726f97d2a6
commit 3ce24a0cbf
5 changed files with 32 additions and 19 deletions

View file

@ -463,6 +463,19 @@ DrmOutput::Transform toDrmTransform(int rotation)
Q_UNREACHABLE(); Q_UNREACHABLE();
} }
} }
std::shared_ptr<OutputMode> parseMode(Output *output, const QJsonObject &modeInfo)
{
const QJsonObject size = modeInfo["size"].toObject();
const QSize modeSize = QSize(size["width"].toInt(), size["height"].toInt());
const int refreshRate = round(modeInfo["refresh"].toDouble() * 1000);
const auto modes = output->modes();
auto it = std::find_if(modes.begin(), modes.end(), [&modeSize, &refreshRate](const auto &mode) {
return mode->size() == modeSize && mode->refreshRate() == refreshRate;
});
return (it != modes.end()) ? *it : nullptr;
}
} }
bool DrmBackend::readOutputsConfiguration(const QVector<DrmAbstractOutput *> &outputs) bool DrmBackend::readOutputsConfiguration(const QVector<DrmAbstractOutput *> &outputs)
@ -497,10 +510,10 @@ bool DrmBackend::readOutputsConfiguration(const QVector<DrmAbstractOutput *> &ou
props->vrrPolicy = static_cast<RenderLoop::VrrPolicy>(outputInfo["vrrpolicy"].toInt(static_cast<uint32_t>(props->vrrPolicy))); props->vrrPolicy = static_cast<RenderLoop::VrrPolicy>(outputInfo["vrrpolicy"].toInt(static_cast<uint32_t>(props->vrrPolicy)));
props->rgbRange = static_cast<Output::RgbRange>(outputInfo["rgbrange"].toInt(static_cast<uint32_t>(props->rgbRange))); props->rgbRange = static_cast<Output::RgbRange>(outputInfo["rgbrange"].toInt(static_cast<uint32_t>(props->rgbRange)));
if (const QJsonObject mode = outputInfo["mode"].toObject(); !mode.isEmpty()) { if (const QJsonObject modeInfo = outputInfo["mode"].toObject(); !modeInfo.isEmpty()) {
const QJsonObject size = mode["size"].toObject(); if (auto mode = KWinKScreenIntegration::parseMode(output, modeInfo)) {
props->modeSize = QSize(size["width"].toInt(), size["height"].toInt()); props->mode = mode;
props->refreshRate = round(mode["refresh"].toDouble() * 1000); }
} }
} else { } else {
props->enabled = true; props->enabled = true;

View file

@ -397,15 +397,7 @@ bool DrmOutput::queueChanges(const OutputConfiguration &config)
static int envOnlySoftwareRotations = qEnvironmentVariableIntValue("KWIN_DRM_SW_ROTATIONS_ONLY", &valid) == 1 || !valid; static int envOnlySoftwareRotations = qEnvironmentVariableIntValue("KWIN_DRM_SW_ROTATIONS_ONLY", &valid) == 1 || !valid;
const auto props = config.constChangeSet(this); const auto props = config.constChangeSet(this);
const auto modelist = m_connector->modes(); m_pipeline->setMode(std::static_pointer_cast<DrmConnectorMode>(props->mode));
const auto it = std::find_if(modelist.begin(), modelist.end(), [&props](const auto &mode) {
return mode->size() == props->modeSize && mode->refreshRate() == props->refreshRate;
});
if (it == modelist.end()) {
qCWarning(KWIN_DRM).nospace() << "Could not find mode " << props->modeSize << "@" << props->refreshRate << " for output " << this;
return false;
}
m_pipeline->setMode(*it);
m_pipeline->setOverscan(props->overscan); m_pipeline->setOverscan(props->overscan);
m_pipeline->setRgbRange(props->rgbRange); m_pipeline->setRgbRange(props->rgbRange);
m_pipeline->setRenderOrientation(outputToPlaneTransform(props->transform)); m_pipeline->setRenderOrientation(outputToPlaneTransform(props->transform));

View file

@ -25,8 +25,7 @@ std::shared_ptr<OutputChangeSet> OutputConfiguration::constChangeSet(Output *out
props->enabled = output->isEnabled(); props->enabled = output->isEnabled();
props->pos = output->geometry().topLeft(); props->pos = output->geometry().topLeft();
props->scale = output->scale(); props->scale = output->scale();
props->modeSize = output->modeSize(); props->mode = output->currentMode();
props->refreshRate = output->refreshRate();
props->transform = output->transform(); props->transform = output->transform();
props->overscan = output->overscan(); props->overscan = output->overscan();
props->rgbRange = output->rgbRange(); props->rgbRange = output->rgbRange();

View file

@ -20,11 +20,10 @@ namespace KWin
class KWIN_EXPORT OutputChangeSet class KWIN_EXPORT OutputChangeSet
{ {
public: public:
std::shared_ptr<OutputMode> mode;
bool enabled; bool enabled;
QPoint pos; QPoint pos;
float scale; float scale;
QSize modeSize;
uint32_t refreshRate;
Output::Transform transform; Output::Transform transform;
uint32_t overscan; uint32_t overscan;
Output::RgbRange rgbRange; Output::RgbRange rgbRange;

View file

@ -132,12 +132,22 @@ void Platform::requestOutputsChange(KWaylandServer::OutputConfigurationV2Interfa
qCWarning(KWIN_CORE) << "Could NOT find output matching " << it.key()->uuid(); qCWarning(KWIN_CORE) << "Could NOT find output matching " << it.key()->uuid();
continue; continue;
} }
const auto modes = output->modes();
const auto modeIt = std::find_if(modes.begin(), modes.end(), [&changeset](const auto &mode) {
return mode->size() == changeset->size() && mode->refreshRate() == changeset->refreshRate();
});
if (modeIt == modes.end()) {
qCWarning(KWIN_CORE).nospace() << "Could not find mode " << changeset->size() << "@" << changeset->refreshRate() << " for output " << this;
config->setFailed();
return;
}
auto props = cfg.changeSet(output); auto props = cfg.changeSet(output);
props->enabled = changeset->enabled(); props->enabled = changeset->enabled();
props->pos = changeset->position(); props->pos = changeset->position();
props->scale = changeset->scale(); props->scale = changeset->scale();
props->modeSize = changeset->size(); props->mode = *modeIt;
props->refreshRate = changeset->refreshRate();
props->transform = static_cast<Output::Transform>(changeset->transform()); props->transform = static_cast<Output::Transform>(changeset->transform());
props->overscan = changeset->overscan(); props->overscan = changeset->overscan();
props->rgbRange = static_cast<Output::RgbRange>(changeset->rgbRange()); props->rgbRange = static_cast<Output::RgbRange>(changeset->rgbRange());