From 3cafc2098147b7f6f656ba0b4cec5932cddfeed5 Mon Sep 17 00:00:00 2001 From: Xaver Hugl Date: Sat, 16 Dec 2023 22:03:20 +0100 Subject: [PATCH] backensd/drm: directly try presentation with changed properties This optimizes out an unnecessary atomic test - instead of testing the new state and then attempting to present with that new state, this just directly tries to present the full state. If that commit fails, the backend just tries again with the safer presentation mode. --- src/backends/drm/drm_output.cpp | 20 ++++++++++---------- src/backends/drm/drm_pipeline_legacy.cpp | 7 ++----- 2 files changed, 12 insertions(+), 15 deletions(-) diff --git a/src/backends/drm/drm_output.cpp b/src/backends/drm/drm_output.cpp index b54c2b07df..363cbf755a 100644 --- a/src/backends/drm/drm_output.cpp +++ b/src/backends/drm/drm_output.cpp @@ -274,27 +274,27 @@ bool DrmOutput::present(const std::shared_ptr &frame) if (frame->contentType()) { type = DrmConnector::kwinToDrmContentType(*frame->contentType()); } - if (m_pipeline->presentationMode() != frame->presentationMode() || type != m_pipeline->contentType()) { - m_pipeline->setPresentationMode(frame->presentationMode()); - m_pipeline->setContentType(type); - if (DrmPipeline::commitPipelines({m_pipeline}, DrmPipeline::CommitMode::Test) == DrmPipeline::Error::None) { - m_pipeline->applyPendingChanges(); - } else { - m_pipeline->revertPendingChanges(); - } - m_renderLoop->setPresentationMode(m_pipeline->presentationMode()); - } const bool needsModeset = gpu()->needsModeset(); bool success; if (needsModeset) { + m_pipeline->setPresentationMode(PresentationMode::VSync); + m_pipeline->setContentType(DrmConnector::DrmContentType::Graphics); success = m_pipeline->maybeModeset(); } else { + m_pipeline->setPresentationMode(frame->presentationMode()); + m_pipeline->setContentType(type); DrmPipeline::Error err = m_pipeline->present(); + if (err != DrmPipeline::Error::None && frame->presentationMode() != PresentationMode::VSync) { + // retry with a more basic presentation mode + m_pipeline->setPresentationMode(PresentationMode::VSync); + err = m_pipeline->present(); + } success = err == DrmPipeline::Error::None; if (err == DrmPipeline::Error::InvalidArguments) { QTimer::singleShot(0, m_gpu->platform(), &DrmBackend::updateOutputs); } } + m_renderLoop->setPresentationMode(m_pipeline->presentationMode()); if (success) { Q_EMIT outputChange(m_pipeline->primaryLayer()->currentDamage()); return true; diff --git a/src/backends/drm/drm_pipeline_legacy.cpp b/src/backends/drm/drm_pipeline_legacy.cpp index cb471645eb..615e6804ed 100644 --- a/src/backends/drm/drm_pipeline_legacy.cpp +++ b/src/backends/drm/drm_pipeline_legacy.cpp @@ -26,11 +26,8 @@ namespace KWin DrmPipeline::Error DrmPipeline::presentLegacy() { - if (!m_pending.crtc->current()) { - Error err = legacyModeset(); - if (err != Error::None) { - return err; - } + if (Error err = applyPendingChangesLegacy(); err != Error::None) { + return err; } const auto buffer = m_primaryLayer->currentBuffer(); auto commit = std::make_unique(this, buffer);