[plasma/kwin] /: backends/drm: re-allocate for tearing with compositing, too

Xaver Hugl <[email protected]>
Newsgroups gmane.comp.kde.cvs
Message-ID <[email protected]>
Git commit 7e8c82c765024465e6f590568d26a8a9ae3fb136 by Xaver Hugl.
Committed on 18/08/2026 at 18:42.
Pushed by zamundaaa into branch 'master'.

backends/drm: re-allocate for tearing with compositing, too

The format+modifiers normally used may not be compatible with tearing
on the hardware.

CCBUG: 524346

M  +1    -1    autotests/drm/mockDrmTest.cpp
M  +4    -2    src/backends/drm/drm_egl_layer.cpp
M  +1    -1    src/backends/drm/drm_egl_layer.h
M  +1    -1    src/backends/drm/drm_virtual_egl_layer.cpp
M  +1    -1    src/backends/drm/drm_virtual_egl_layer.h
M  +1    -1    src/backends/virtual/virtual_egl_backend.cpp
M  +1    -1    src/backends/virtual/virtual_egl_backend.h
M  +2    -2    src/backends/wayland/wayland_egl_backend.cpp
M  +2    -2    src/backends/wayland/wayland_egl_backend.h
M  +2    -2    src/backends/x11/x11_windowed_egl_backend.cpp
M  +2    -2    src/backends/x11/x11_windowed_egl_backend.h
M  +1    -1    src/compositor.cpp
M  +1    -1    src/core/outputlayer.h
M  +1    -1    src/plugins/colorpicker/colorpicker.cpp
M  +1    -1    src/plugins/colorpicker/colorpickerlayer.cpp
M  +1    -1    src/plugins/colorpicker/colorpickerlayer.h
M  +1    -1    src/plugins/screencast/outputscreencastsource.cpp
M  +1    -1    src/plugins/screencast/regionscreencastsource.cpp
M  +1    -1    src/plugins/screencast/screencastlayer.cpp
M  +1    -1    src/plugins/screencast/screencastlayer.h
M  +2    -2    src/plugins/screenshot/screenshot.cpp
M  +1    -1    src/plugins/screenshot/screenshotlayer.cpp
M  +1    -1    src/plugins/screenshot/screenshotlayer.h

https://invent.kde.org/plasma/kwin/-/commit/7e8c82c765024465e6f590568d26a8a9ae3fb136

diff --git a/autotests/drm/mockDrmTest.cpp b/autotests/drm/mockDrmTest.cpp
index e7709e20107..752665f548c 100644
--- a/autotests/drm/mockDrmTest.cpp
+++ b/autotests/drm/mockDrmTest.cpp
@@ -464,7 +464,7 @@ void DrmTest::testModeset()
     QCOMPARE(gpu->drmOutputs().size(), 1);
     const auto output = gpu->drmOutputs().front();
     const auto layer = renderBackend->compatibleOutputLayers(output).front();
-    layer->beginFrame();
+    layer->beginFrame(nullptr);
     output->renderLoop()->prepareNewFrame();
     const auto frame = std::make_shared<OutputFrame>(output->renderLoop(), std::chrono::nanoseconds(1'000'000'000'000 / output->refreshRate()));
     layer->endFrame(Region::infinite(), Region::infinite(), frame.get());
diff --git a/src/backends/drm/drm_egl_layer.cpp b/src/backends/drm/drm_egl_layer.cpp
index 1cd5ac6d3bf..108911c8187 100644
--- a/src/backends/drm/drm_egl_layer.cpp
+++ b/src/backends/drm/drm_egl_layer.cpp
@@ -50,12 +50,14 @@ EglGbmLayer::EglGbmLayer(EglGbmBackend *eglBackend, DrmGpu *gpu, DrmPlane::TypeI
 {
 }
 
-std::optional<OutputLayerBeginFrameInfo> EglGbmLayer::beginFrame()
+std::optional<OutputLayerBeginFrameInfo> EglGbmLayer::beginFrame(OutputFrame *frame)
 {
     m_scanoutBuffer.reset();
+    const bool tearing = frame && (frame->presentationMode() == PresentationMode::Async || frame->presentationMode() == PresentationMode::AdaptiveAsync);
+    const auto formats = tearing && !supportedAsyncDrmFormats().isEmpty() ? supportedAsyncDrmFormats() : supportedDrmFormats();
     return m_surface.startRendering(targetRect().size(),
                                     drmOutput()->transform().combine(OutputTransform::FlipY),
-                                    supportedDrmFormats(),
+                                    formats,
                                     drmOutput()->blendingColor(),
                                     drmOutput()->layerBlendingColor(),
                                     drmOutput()->needsShadowBuffer() ? pipeline()->iccProfile() : nullptr,
diff --git a/src/backends/drm/drm_egl_layer.h b/src/backends/drm/drm_egl_layer.h
index 13bafb1ab52..78679e94cd9 100644
--- a/src/backends/drm/drm_egl_layer.h
+++ b/src/backends/drm/drm_egl_layer.h
@@ -28,7 +28,7 @@ public:
     explicit EglGbmLayer(EglGbmBackend *eglBackend, DrmPlane *plane);
     explicit EglGbmLayer(EglGbmBackend *eglBackend, DrmGpu *gpu, DrmPlane::TypeIndex type);
 
-    std::optional<OutputLayerBeginFrameInfo> beginFrame() override;
+    std::optional<OutputLayerBeginFrameInfo> beginFrame(OutputFrame *frame) override;
     bool endFrame(const Region &renderedDeviceRegion, const Region &damagedDeviceRegion, OutputFrame *frame) override;
     bool preparePresentationTest() override;
     std::shared_ptr<DrmFramebuffer> currentBuffer() const override;
diff --git a/src/backends/drm/drm_virtual_egl_layer.cpp b/src/backends/drm/drm_virtual_egl_layer.cpp
index 92653d1e7ab..3a8ddf8eee7 100644
--- a/src/backends/drm/drm_virtual_egl_layer.cpp
+++ b/src/backends/drm/drm_virtual_egl_layer.cpp
@@ -38,7 +38,7 @@ VirtualEglGbmLayer::~VirtualEglGbmLayer()
     releaseBuffers();
 }
 
-std::optional<OutputLayerBeginFrameInfo> VirtualEglGbmLayer::beginFrame()
+std::optional<OutputLayerBeginFrameInfo> VirtualEglGbmLayer::beginFrame(OutputFrame *frame)
 {
     m_scanoutBuffer.reset();
 
diff --git a/src/backends/drm/drm_virtual_egl_layer.h b/src/backends/drm/drm_virtual_egl_layer.h
index c698712a5a7..567d0daabe7 100644
--- a/src/backends/drm/drm_virtual_egl_layer.h
+++ b/src/backends/drm/drm_virtual_egl_layer.h
@@ -33,7 +33,7 @@ public:
     VirtualEglGbmLayer(EglGbmBackend *eglBackend, DrmVirtualOutput *output);
     ~VirtualEglGbmLayer() override;
 
-    std::optional<OutputLayerBeginFrameInfo> beginFrame() override;
+    std::optional<OutputLayerBeginFrameInfo> beginFrame(OutputFrame *frame) override;
     bool endFrame(const Region &renderedDeviceRegion, const Region &damagedDeviceRegion, OutputFrame *frame) override;
     void releaseBuffers() override;
     FormatModifierMap supportedDrmFormats() const override;
diff --git a/src/backends/virtual/virtual_egl_backend.cpp b/src/backends/virtual/virtual_egl_backend.cpp
index e8fdb585e7d..b8c0a2cc790 100644
--- a/src/backends/virtual/virtual_egl_backend.cpp
+++ b/src/backends/virtual/virtual_egl_backend.cpp
@@ -36,7 +36,7 @@ VirtualEglLayer::~VirtualEglLayer()
     (void)m_backend->openglContext()->makeCurrent();
 }
 
-std::optional<OutputLayerBeginFrameInfo> VirtualEglLayer::beginFrame()
+std::optional<OutputLayerBeginFrameInfo> VirtualEglLayer::beginFrame(OutputFrame *frame)
 {
     if (!m_backend->openglContext()->makeCurrent()) {
         return std::nullopt;
diff --git a/src/backends/virtual/virtual_egl_backend.h b/src/backends/virtual/virtual_egl_backend.h
index f966f4bd50a..2e69951cc56 100644
--- a/src/backends/virtual/virtual_egl_backend.h
+++ b/src/backends/virtual/virtual_egl_backend.h
@@ -33,7 +33,7 @@ public:
     VirtualEglLayer(BackendOutput *output, VirtualEglBackend *backend);
     ~VirtualEglLayer() override;
 
-    std::optional<OutputLayerBeginFrameInfo> beginFrame() override;
+    std::optional<OutputLayerBeginFrameInfo> beginFrame(OutputFrame *frame) override;
     bool endFrame(const Region &renderedDeviceRegion, const Region &damagedDeviceRegion, OutputFrame *frame) override;
 
     FormatModifierMap supportedDrmFormats() const override;
diff --git a/src/backends/wayland/wayland_egl_backend.cpp b/src/backends/wayland/wayland_egl_backend.cpp
index 2462beab7fe..60d926129ff 100644
--- a/src/backends/wayland/wayland_egl_backend.cpp
+++ b/src/backends/wayland/wayland_egl_backend.cpp
@@ -53,7 +53,7 @@ GLFramebuffer *WaylandEglLayer::fbo() const
     return m_buffer->framebuffer();
 }
 
-std::optional<OutputLayerBeginFrameInfo> WaylandEglLayer::beginFrame()
+std::optional<OutputLayerBeginFrameInfo> WaylandEglLayer::beginFrame(OutputFrame *frame)
 {
     if (!m_backend->openglContext()->makeCurrent()) {
         qCCritical(KWIN_WAYLAND_BACKEND) << "Make Context Current failed";
@@ -156,7 +156,7 @@ WaylandEglCursorLayer::~WaylandEglCursorLayer()
     (void)m_backend->openglContext()->makeCurrent();
 }
 
-std::optional<OutputLayerBeginFrameInfo> WaylandEglCursorLayer::beginFrame()
+std::optional<OutputLayerBeginFrameInfo> WaylandEglCursorLayer::beginFrame(OutputFrame *frame)
 {
     if (!m_backend->openglContext()->makeCurrent()) {
         qCCritical(KWIN_WAYLAND_BACKEND) << "Make Context Current failed";
diff --git a/src/backends/wayland/wayland_egl_backend.h b/src/backends/wayland/wayland_egl_backend.h
index ff99d144cd4..6b66c87a58b 100644
--- a/src/backends/wayland/wayland_egl_backend.h
+++ b/src/backends/wayland/wayland_egl_backend.h
@@ -41,7 +41,7 @@ public:
     ~WaylandEglLayer() override;
 
     GLFramebuffer *fbo() const;
-    std::optional<OutputLayerBeginFrameInfo> beginFrame() override;
+    std::optional<OutputLayerBeginFrameInfo> beginFrame(OutputFrame *frame) override;
     bool endFrame(const Region &renderedDeviceRegion, const Region &damagedDeviceRegion, OutputFrame *frame) override;
     bool earlyScanoutChecks() override;
     bool importScanoutBuffer(GraphicsBuffer *buffer, const std::shared_ptr<OutputFrame> &frame) override;
@@ -66,7 +66,7 @@ public:
     WaylandEglCursorLayer(WaylandOutput *output, WaylandEglBackend *backend);
     ~WaylandEglCursorLayer() override;
 
-    std::optional<OutputLayerBeginFrameInfo> beginFrame() override;
+    std::optional<OutputLayerBeginFrameInfo> beginFrame(OutputFrame *frame) override;
     bool endFrame(const Region &renderedDeviceRegion, const Region &damagedDeviceRegion, OutputFrame *frame) override;
     FormatModifierMap supportedDrmFormats() const override;
     void releaseBuffers() override;
diff --git a/src/backends/x11/x11_windowed_egl_backend.cpp b/src/backends/x11/x11_windowed_egl_backend.cpp
index 13d5bc39b82..4541779565d 100644
--- a/src/backends/x11/x11_windowed_egl_backend.cpp
+++ b/src/backends/x11/x11_windowed_egl_backend.cpp
@@ -32,7 +32,7 @@ X11WindowedEglPrimaryLayer::~X11WindowedEglPrimaryLayer()
 {
 }
 
-std::optional<OutputLayerBeginFrameInfo> X11WindowedEglPrimaryLayer::beginFrame()
+std::optional<OutputLayerBeginFrameInfo> X11WindowedEglPrimaryLayer::beginFrame(OutputFrame *frame)
 {
     if (!m_backend->openglContext()->makeCurrent()) {
         return std::nullopt;
@@ -110,7 +110,7 @@ X11WindowedEglCursorLayer::~X11WindowedEglCursorLayer()
     m_texture.reset();
 }
 
-std::optional<OutputLayerBeginFrameInfo> X11WindowedEglCursorLayer::beginFrame()
+std::optional<OutputLayerBeginFrameInfo> X11WindowedEglCursorLayer::beginFrame(OutputFrame *frame)
 {
     if (!m_backend->openglContext()->makeCurrent()) {
         return std::nullopt;
diff --git a/src/backends/x11/x11_windowed_egl_backend.h b/src/backends/x11/x11_windowed_egl_backend.h
index 6b9bf839218..ed9da1ec452 100644
--- a/src/backends/x11/x11_windowed_egl_backend.h
+++ b/src/backends/x11/x11_windowed_egl_backend.h
@@ -28,7 +28,7 @@ public:
     X11WindowedEglPrimaryLayer(X11WindowedEglBackend *backend, X11WindowedOutput *output);
     ~X11WindowedEglPrimaryLayer() override;
 
-    std::optional<OutputLayerBeginFrameInfo> beginFrame() override;
+    std::optional<OutputLayerBeginFrameInfo> beginFrame(OutputFrame *frame) override;
     bool endFrame(const Region &renderedDeviceRegion, const Region &damagedDeviceRegion, OutputFrame *frame) override;
     FormatModifierMap supportedDrmFormats() const override;
     void releaseBuffers() override;
@@ -49,7 +49,7 @@ public:
     X11WindowedEglCursorLayer(X11WindowedEglBackend *backend, X11WindowedOutput *output);
     ~X11WindowedEglCursorLayer() override;
 
-    std::optional<OutputLayerBeginFrameInfo> beginFrame() override;
+    std::optional<OutputLayerBeginFrameInfo> beginFrame(OutputFrame *frame) override;
     bool endFrame(const Region &renderedDeviceRegion, const Region &damagedDeviceRegion, OutputFrame *frame) override;
     FormatModifierMap supportedDrmFormats() const override;
     void releaseBuffers() override;
diff --git a/src/compositor.cpp b/src/compositor.cpp
index 54df6209e88..3e04496fbbd 100644
--- a/src/compositor.cpp
+++ b/src/compositor.cpp
@@ -523,7 +523,7 @@ static bool prepareRendering(RenderView *view, LogicalOutput *logicalOutput, Bac
 
 static bool renderLayer(RenderView *view, LogicalOutput *logicalOutput, BackendOutput *backendOutput, const std::shared_ptr<OutputFrame> &frame, const Region &surfaceDamage)
 {
-    auto beginInfo = view->layer()->beginFrame();
+    auto beginInfo = view->layer()->beginFrame(frame.get());
     if (!beginInfo) {
         return false;
     }
diff --git a/src/core/outputlayer.h b/src/core/outputlayer.h
index 018d75d8482..252707c570f 100644
--- a/src/core/outputlayer.h
+++ b/src/core/outputlayer.h
@@ -95,7 +95,7 @@ public:
      */
     virtual bool preparePresentationTest();
 
-    virtual std::optional<OutputLayerBeginFrameInfo> beginFrame() = 0;
+    virtual std::optional<OutputLayerBeginFrameInfo> beginFrame(OutputFrame *frame) = 0;
     virtual bool endFrame(const Region &renderedDeviceRegion, const Region &damagedDeviceRegion, OutputFrame *frame) = 0;
 
     /**
diff --git a/src/plugins/colorpicker/colorpicker.cpp b/src/plugins/colorpicker/colorpicker.cpp
index a833f861529..9d4e66d95b3 100644
--- a/src/plugins/colorpicker/colorpicker.cpp
+++ b/src/plugins/colorpicker/colorpicker.cpp
@@ -121,7 +121,7 @@ QColor ColorPickerEffect::pick()
             if (!layer.preparePresentationTest()) {
                 return;
             }
-            const auto beginInfo = layer.beginFrame();
+            const auto beginInfo = layer.beginFrame(nullptr);
             if (!beginInfo) {
                 return;
             }
diff --git a/src/plugins/colorpicker/colorpickerlayer.cpp b/src/plugins/colorpicker/colorpickerlayer.cpp
index d05ec121528..3dc2181e3b8 100644
--- a/src/plugins/colorpicker/colorpickerlayer.cpp
+++ b/src/plugins/colorpicker/colorpickerlayer.cpp
@@ -19,7 +19,7 @@ FormatModifierMap ColorPickerLayer::supportedDrmFormats() const
     return {};
 }
 
-std::optional<OutputLayerBeginFrameInfo> ColorPickerLayer::beginFrame()
+std::optional<OutputLayerBeginFrameInfo> ColorPickerLayer::beginFrame(OutputFrame *frame)
 {
     return OutputLayerBeginFrameInfo{
         .renderTarget = RenderTarget(m_buffer),
diff --git a/src/plugins/colorpicker/colorpickerlayer.h b/src/plugins/colorpicker/colorpickerlayer.h
index 9dd6add972c..a114069b483 100644
--- a/src/plugins/colorpicker/colorpickerlayer.h
+++ b/src/plugins/colorpicker/colorpickerlayer.h
@@ -19,7 +19,7 @@ public:
     FormatModifierMap supportedDrmFormats() const override;
     void releaseBuffers() override;
 
-    std::optional<OutputLayerBeginFrameInfo> beginFrame() override;
+    std::optional<OutputLayerBeginFrameInfo> beginFrame(OutputFrame *frame) override;
     bool endFrame(const Region &renderedRegion, const Region &damagedRegion, OutputFrame *frame) override;
 
 private:
diff --git a/src/plugins/screencast/outputscreencastsource.cpp b/src/plugins/screencast/outputscreencastsource.cpp
index 28e56700d69..43ec1844280 100644
--- a/src/plugins/screencast/outputscreencastsource.cpp
+++ b/src/plugins/screencast/outputscreencastsource.cpp
@@ -82,7 +82,7 @@ Region OutputScreenCastSource::render(GLFramebuffer *target, const Region &buffe
     if (!m_layer->preparePresentationTest()) {
         return Region{};
     }
-    const auto beginInfo = m_layer->beginFrame();
+    const auto beginInfo = m_layer->beginFrame(nullptr);
     if (!beginInfo) {
         return Region{};
     }
diff --git a/src/plugins/screencast/regionscreencastsource.cpp b/src/plugins/screencast/regionscreencastsource.cpp
index a8ee50518cf..f85d65d04f4 100644
--- a/src/plugins/screencast/regionscreencastsource.cpp
+++ b/src/plugins/screencast/regionscreencastsource.cpp
@@ -77,7 +77,7 @@ Region RegionScreenCastSource::render(GLFramebuffer *target, const Region &buffe
     if (!m_layer->preparePresentationTest()) {
         return Region{};
     }
-    const auto beginInfo = m_layer->beginFrame();
+    const auto beginInfo = m_layer->beginFrame(nullptr);
     if (!beginInfo) {
         return Region{};
     }
diff --git a/src/plugins/screencast/screencastlayer.cpp b/src/plugins/screencast/screencastlayer.cpp
index fc2bfce0ed2..0a62933ce97 100644
--- a/src/plugins/screencast/screencastlayer.cpp
+++ b/src/plugins/screencast/screencastlayer.cpp
@@ -28,7 +28,7 @@ FormatModifierMap ScreencastLayer::supportedDrmFormats() const
     return m_formats;
 }
 
-std::optional<OutputLayerBeginFrameInfo> ScreencastLayer::beginFrame()
+std::optional<OutputLayerBeginFrameInfo> ScreencastLayer::beginFrame(OutputFrame *frame)
 {
     return OutputLayerBeginFrameInfo{
         .renderTarget = RenderTarget(m_buffer),
diff --git a/src/plugins/screencast/screencastlayer.h b/src/plugins/screencast/screencastlayer.h
index 3d563bd8299..5300975a87b 100644
--- a/src/plugins/screencast/screencastlayer.h
+++ b/src/plugins/screencast/screencastlayer.h
@@ -19,7 +19,7 @@ public:
     FormatModifierMap supportedDrmFormats() const override;
     void releaseBuffers() override;
 
-    std::optional<OutputLayerBeginFrameInfo> beginFrame() override;
+    std::optional<OutputLayerBeginFrameInfo> beginFrame(OutputFrame *frame) override;
     bool endFrame(const Region &renderedRegion, const Region &damagedRegion, OutputFrame *frame) override;
 
 private:
diff --git a/src/plugins/screenshot/screenshot.cpp b/src/plugins/screenshot/screenshot.cpp
index b34afdfa0f3..b1c975a49a5 100644
--- a/src/plugins/screenshot/screenshot.cpp
+++ b/src/plugins/screenshot/screenshot.cpp
@@ -83,7 +83,7 @@ std::optional<QImage> ScreenShotManager::takeScreenShot(LogicalOutput *screen, S
     if (!layer.preparePresentationTest()) {
         return std::nullopt;
     }
-    const auto beginInfo = layer.beginFrame();
+    const auto beginInfo = layer.beginFrame(nullptr);
     if (!beginInfo) {
         return std::nullopt;
     }
@@ -151,7 +151,7 @@ std::optional<QImage> ScreenShotManager::takeScreenShot(const Rect &area, Screen
     if (!layer.preparePresentationTest()) {
         return std::nullopt;
     }
-    const auto beginInfo = layer.beginFrame();
+    const auto beginInfo = layer.beginFrame(nullptr);
     if (!beginInfo) {
         return std::nullopt;
     }
diff --git a/src/plugins/screenshot/screenshotlayer.cpp b/src/plugins/screenshot/screenshotlayer.cpp
index c1f78e33ead..4b608ff0275 100644
--- a/src/plugins/screenshot/screenshotlayer.cpp
+++ b/src/plugins/screenshot/screenshotlayer.cpp
@@ -19,7 +19,7 @@ FormatModifierMap ScreenshotLayer::supportedDrmFormats() const
     return {};
 }
 
-std::optional<OutputLayerBeginFrameInfo> ScreenshotLayer::beginFrame()
+std::optional<OutputLayerBeginFrameInfo> ScreenshotLayer::beginFrame(OutputFrame *frame)
 {
     return OutputLayerBeginFrameInfo{
         .renderTarget = RenderTarget(m_buffer),
diff --git a/src/plugins/screenshot/screenshotlayer.h b/src/plugins/screenshot/screenshotlayer.h
index 01f69734c06..87cf31115ce 100644
--- a/src/plugins/screenshot/screenshotlayer.h
+++ b/src/plugins/screenshot/screenshotlayer.h
@@ -19,7 +19,7 @@ public:
     FormatModifierMap supportedDrmFormats() const override;
     void releaseBuffers() override;
 
-    std::optional<OutputLayerBeginFrameInfo> beginFrame() override;
+    std::optional<OutputLayerBeginFrameInfo> beginFrame(OutputFrame *frame) override;
     bool endFrame(const Region &renderedRegion, const Region &damagedRegion, OutputFrame *frame) override;
 
 private:
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.