Your message dated Mon, 26 Jun 2023 13:25:42 +0200
with message-id <a0094ab1-2f74-72c9-5e65-b05d9719c...@jacekk.info>
and subject line Re: Bug#1036100: Red and blue channels are swapped when 
screencasting in certain applications
has caused the Debian Bug report #1036100,
regarding Red and blue channels are swapped when screencasting in certain 
applications
to be marked as done.

This means that you claim that the problem has been dealt with.
If this is not the case it is now your responsibility to reopen the
Bug report if necessary, and/or fix the problem forthwith.

(NB: If you are a system administrator and have no idea what this
message is talking about, this may indicate a serious mail system
misconfiguration somewhere. Please contact ow...@bugs.debian.org
immediately.)


-- 
1036100: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1036100
Debian Bug Tracking System
Contact ow...@bugs.debian.org with problems
--- Begin Message ---
Package: kwin-wayland
Version: 4:5.27.2-2
Severity: important
Tags: patch

Dear Maintainer,

current version of KWin in bookworm has a bug that causes colors (red and blue) to be inverted when sharing screen (e.g. in the browser) on certain configurations using Wayland, as reported here:
https://bugs.kde.org/show_bug.cgi?id=466655

There is already a patch for that issue upstream (included in 5.27.3, also attached): https://invent.kde.org/plasma/kwin/commit/85b614e75c41cbdeb63b276162ed9777232daf28

It would be great if this problem could be fixed in Debian.

-- System Information:
Debian Release: 12.0
  APT prefers testing-security
APT policy: (500, 'testing-security'), (500, 'stable-security'), (500, 'testing')
Architecture: amd64 (x86_64)

Kernel: Linux 6.1.0-9-amd64 (SMP w/8 CPU threads; PREEMPT)
Kernel taint flags: TAINT_WARN
Locale: LANG=pl_PL.UTF-8, LC_CTYPE=pl_PL.UTF-8 (charmap=UTF-8), LANGUAGE=en_US
Shell: /bin/sh linked to /usr/bin/dash
Init: systemd (via /run/systemd/system)
LSM: AppArmor: enabled

Versions of packages kwin-wayland depends on:
ii  kwayland-integration              5.27.2-1
ii  kwin-common                       4:5.27.2-2
ii  libc6                             2.36-9
ii  libcap2-bin                       1:2.66-3
ii  libepoxy0                         1.5.10-1
ii  libfontconfig1                    2.14.1-4
ii  libfreetype6                      2.12.1+dfsg-5
ii  libkdecorations2-5v5              4:5.27.2-1
ii  libkf5configcore5                 5.103.0-1
ii  libkf5configgui5                  5.103.0-1
ii  libkf5configwidgets5              5.103.0-1
ii  libkf5coreaddons5                 5.103.0-1
ii  libkf5crash5                      5.103.0-1
ii  libkf5dbusaddons5                 5.103.0-1
ii  libkf5globalaccel-bin             5.103.0-1
ii  libkf5globalaccel5                5.103.0-1
ii  libkf5globalaccelprivate5         5.103.0-1
ii  libkf5i18n5                       5.103.0-1
ii  libkf5idletime5                   5.103.0-2
ii  libkf5notifications5              5.103.0-1
ii  libkf5plasma5                     5.103.0-1
ii  libkf5service-bin                 5.103.0-1
ii  libkf5service5                    5.103.0-1
ii  libkf5windowsystem5               5.103.0-1
ii  libkwineffects14                  4:5.27.2-2
ii  libkwinglutils14                  4:5.27.2-2
ii  libpipewire-0.3-0                 0.3.65-3
ii  libqaccessibilityclient-qt5-0     0.4.1-1+b1
ii  libqt5core5a [qtbase-abi-5-15-8]  5.15.8+dfsg-7
ii  libqt5dbus5                       5.15.8+dfsg-7
ii  libqt5gui5                        5.15.8+dfsg-7
ii  libqt5network5                    5.15.8+dfsg-7
ii  libqt5qml5                        5.15.8+dfsg-3
ii  libqt5quick5                      5.15.8+dfsg-3
ii  libqt5widgets5                    5.15.8+dfsg-7
ii  libstdc++6                        12.2.0-14
ii  libxcb-randr0                     1.15-1
ii  libxcb-xfixes0                    1.15-1
ii  libxcb1                           1.15-1
ii  xwayland                          2:22.1.9-1

kwin-wayland recommends no packages.

kwin-wayland suggests no packages.

-- no debconf information
>From 85b614e75c41cbdeb63b276162ed9777232daf28 Mon Sep 17 00:00:00 2001
From: Aleix Pol <aleix...@kde.org>
Date: Fri, 3 Mar 2023 19:34:17 +0100
Subject: [PATCH] screencasting: on memfd, skip the QImage step

We were using QImage as an intermediary step. GL -> QImage -> spa
buffer. While it abstracted things out neatly and eventually helped with
debugging, it was unnecessary and woudl present some handicaps, such as
the lack of a QImage::Format_BGRA.
So we just it out to download right into the buffer.

BUG: 466655
(cherry picked from commit 121454580711c409b612d06865ab9d221dcbac6b)
---
 .../screencast/outputscreencastsource.cpp     |  4 +--
 .../screencast/outputscreencastsource.h       |  2 +-
 .../screencast/regionscreencastsource.cpp     |  4 +--
 .../screencast/regionscreencastsource.h       |  2 +-
 src/plugins/screencast/screencastsource.h     |  4 ++-
 src/plugins/screencast/screencaststream.cpp   | 10 +++---
 src/plugins/screencast/screencastutils.h      | 33 ++++++++++---------
 .../screencast/windowscreencastsource.cpp     |  4 +--
 .../screencast/windowscreencastsource.h       |  2 +-
 9 files changed, 35 insertions(+), 30 deletions(-)

diff --git a/src/plugins/screencast/outputscreencastsource.cpp 
b/src/plugins/screencast/outputscreencastsource.cpp
index 0c0706a2a0d..ac853171da9 100644
--- a/src/plugins/screencast/outputscreencastsource.cpp
+++ b/src/plugins/screencast/outputscreencastsource.cpp
@@ -44,11 +44,11 @@ QSize OutputScreenCastSource::textureSize() const
     return m_output->pixelSize();
 }
 
-void OutputScreenCastSource::render(QImage *image)
+void OutputScreenCastSource::render(spa_data *spa, spa_video_format format)
 {
     const std::shared_ptr<GLTexture> outputTexture = 
Compositor::self()->scene()->textureForOutput(m_output);
     if (outputTexture) {
-        grabTexture(outputTexture.get(), image);
+        grabTexture(outputTexture.get(), spa, format);
     }
 }
 
diff --git a/src/plugins/screencast/outputscreencastsource.h 
b/src/plugins/screencast/outputscreencastsource.h
index 81bf511b18a..1e12eba2005 100644
--- a/src/plugins/screencast/outputscreencastsource.h
+++ b/src/plugins/screencast/outputscreencastsource.h
@@ -27,7 +27,7 @@ public:
     quint32 drmFormat() const override;
 
     void render(GLFramebuffer *target) override;
-    void render(QImage *image) override;
+    void render(spa_data *spa, spa_video_format format) override;
     std::chrono::nanoseconds clock() const override;
 
 private:
diff --git a/src/plugins/screencast/regionscreencastsource.cpp 
b/src/plugins/screencast/regionscreencastsource.cpp
index daeb69d7cbf..8b747f57a62 100644
--- a/src/plugins/screencast/regionscreencastsource.cpp
+++ b/src/plugins/screencast/regionscreencastsource.cpp
@@ -110,10 +110,10 @@ void RegionScreenCastSource::render(GLFramebuffer *target)
     GLFramebuffer::popFramebuffer();
 }
 
-void RegionScreenCastSource::render(QImage *image)
+void RegionScreenCastSource::render(spa_data *spa, spa_video_format format)
 {
     ensureTexture();
-    grabTexture(m_renderedTexture.get(), image);
+    grabTexture(m_renderedTexture.get(), spa, format);
 }
 
 }
diff --git a/src/plugins/screencast/regionscreencastsource.h 
b/src/plugins/screencast/regionscreencastsource.h
index 09ea033248b..560c5d64dc1 100644
--- a/src/plugins/screencast/regionscreencastsource.h
+++ b/src/plugins/screencast/regionscreencastsource.h
@@ -28,7 +28,7 @@ public:
     QSize textureSize() const override;
 
     void render(GLFramebuffer *target) override;
-    void render(QImage *image) override;
+    void render(spa_data *spa, spa_video_format format) override;
     std::chrono::nanoseconds clock() const override;
 
     QRect region() const
diff --git a/src/plugins/screencast/screencastsource.h 
b/src/plugins/screencast/screencastsource.h
index 81d78762c99..6dcafc84c2e 100644
--- a/src/plugins/screencast/screencastsource.h
+++ b/src/plugins/screencast/screencastsource.h
@@ -7,6 +7,8 @@
 #pragma once
 
 #include <QObject>
+#include <spa/buffer/buffer.h>
+#include <spa/param/video/raw.h>
 
 namespace KWin
 {
@@ -25,7 +27,7 @@ public:
     virtual QSize textureSize() const = 0;
 
     virtual void render(GLFramebuffer *target) = 0;
-    virtual void render(QImage *image) = 0;
+    virtual void render(spa_data *spa, spa_video_format format) = 0;
     virtual std::chrono::nanoseconds clock() const = 0;
 
 Q_SIGNALS:
diff --git a/src/plugins/screencast/screencaststream.cpp 
b/src/plugins/screencast/screencaststream.cpp
index fad5114c061..b79c422bd68 100644
--- a/src/plugins/screencast/screencaststream.cpp
+++ b/src/plugins/screencast/screencaststream.cpp
@@ -450,20 +450,20 @@ void ScreenCastStream::recordFrame(const QRegion 
&_damagedRegion)
         const int bpp = data && !hasAlpha ? 3 : 4;
         const uint stride = SPA_ROUND_UP_N(size.width() * bpp, 4);
 
-        QImage dest(data, size.width(), size.height(), stride, hasAlpha ? 
QImage::Format_RGBA8888_Premultiplied : QImage::Format_RGB888);
-        if (dest.sizeInBytes() > spa_data->maxsize) {
+        if ((stride * size.height()) > spa_data->maxsize) {
             qCDebug(KWIN_SCREENCAST) << "Failed to record frame: frame is too 
big";
             pw_stream_queue_buffer(pwStream, buffer);
             return;
         }
 
-        spa_data->chunk->size = dest.sizeInBytes();
-        spa_data->chunk->stride = dest.bytesPerLine();
+        spa_data->chunk->stride = stride;
+        spa_data->chunk->size = stride * size.height();
 
-        m_source->render(&dest);
+        m_source->render(spa_data, videoFormat.format);
 
         auto cursor = Cursors::self()->currentCursor();
         if (m_cursor.mode == KWaylandServer::ScreencastV1Interface::Embedded 
&& exclusiveContains(m_cursor.viewport, cursor->pos())) {
+            QImage dest(data, size.width(), size.height(), stride, hasAlpha ? 
QImage::Format_RGBA8888_Premultiplied : QImage::Format_RGB888);
             QPainter painter(&dest);
             const auto position = (cursor->pos() - m_cursor.viewport.topLeft() 
- cursor->hotspot()) * m_cursor.scale;
             painter.drawImage(QRect{position.toPoint(), 
cursor->image().size()}, cursor->image());
diff --git a/src/plugins/screencast/screencastutils.h 
b/src/plugins/screencast/screencastutils.h
index 55efb604fc4..f20ec322c86 100644
--- a/src/plugins/screencast/screencastutils.h
+++ b/src/plugins/screencast/screencastutils.h
@@ -8,6 +8,8 @@
 
 #include "kwinglplatform.h"
 #include "kwingltexture.h"
+#include <spa/buffer/buffer.h>
+#include <spa/param/video/raw.h>
 
 namespace KWin
 {
@@ -25,28 +27,29 @@ static void mirrorVertically(uchar *data, int height, int 
stride)
     }
 }
 
-static GLenum closestGLType(const QImage &image)
+static GLenum closestGLType(spa_video_format format)
 {
-    switch (image.format()) {
-    case QImage::Format_RGB888:
+    switch (format) {
+    case SPA_VIDEO_FORMAT_RGB:
         return GL_RGB;
-    case QImage::Format_BGR888:
+    case SPA_VIDEO_FORMAT_BGR:
         return GL_BGR;
-    case QImage::Format_RGB32:
-    case QImage::Format_RGBX8888:
-    case QImage::Format_RGBA8888:
-    case QImage::Format_RGBA8888_Premultiplied:
+    case SPA_VIDEO_FORMAT_RGBx:
+    case SPA_VIDEO_FORMAT_RGBA:
         return GL_RGBA;
+    case SPA_VIDEO_FORMAT_BGRA:
+    case SPA_VIDEO_FORMAT_BGRx:
+        return GL_BGRA;
     default:
-        qDebug() << "unknown format" << image.format();
+        qDebug() << "unknown format" << format;
         return GL_RGBA;
     }
 }
 
-static void grabTexture(GLTexture *texture, QImage *image)
+static void grabTexture(GLTexture *texture, spa_data *spa, spa_video_format 
format)
 {
     const bool invert = !texture->isYInverted();
-    Q_ASSERT(texture->size() == image->size());
+    const QSize size = texture->size();
     bool isGLES = GLPlatform::instance()->isGLES();
     bool invertNeeded = isGLES ^ invert;
     const bool invertNeededAndSupported = invertNeeded && 
GLPlatform::instance()->supports(PackInvert);
@@ -58,11 +61,11 @@ static void grabTexture(GLTexture *texture, QImage *image)
 
     texture->bind();
     if (GLPlatform::instance()->isGLES()) {
-        glReadPixels(0, 0, image->width(), image->height(), 
closestGLType(*image), GL_UNSIGNED_BYTE, (GLvoid *)image->bits());
+        glReadPixels(0, 0, size.width(), size.height(), closestGLType(format), 
GL_UNSIGNED_BYTE, spa->data);
     } else if (GLPlatform::instance()->glVersion() >= kVersionNumber(4, 5)) {
-        glGetTextureImage(texture->texture(), 0, closestGLType(*image), 
GL_UNSIGNED_BYTE, image->sizeInBytes(), image->bits());
+        glGetTextureImage(texture->texture(), 0, closestGLType(format), 
GL_UNSIGNED_BYTE, spa->chunk->size, spa->data);
     } else {
-        glGetTexImage(texture->target(), 0, closestGLType(*image), 
GL_UNSIGNED_BYTE, image->bits());
+        glGetTexImage(texture->target(), 0, closestGLType(format), 
GL_UNSIGNED_BYTE, spa->data);
     }
 
     if (invertNeededAndSupported) {
@@ -70,7 +73,7 @@ static void grabTexture(GLTexture *texture, QImage *image)
             glPixelStorei(GL_PACK_INVERT_MESA, prev);
         }
     } else if (invertNeeded) {
-        mirrorVertically(image->bits(), image->height(), 
image->bytesPerLine());
+        mirrorVertically(static_cast<uchar *>(spa->data), size.height(), 
spa->chunk->stride);
     }
 }
 
diff --git a/src/plugins/screencast/windowscreencastsource.cpp 
b/src/plugins/screencast/windowscreencastsource.cpp
index 3c247a3c923..fe651ce8544 100644
--- a/src/plugins/screencast/windowscreencastsource.cpp
+++ b/src/plugins/screencast/windowscreencastsource.cpp
@@ -46,13 +46,13 @@ QSize WindowScreenCastSource::textureSize() const
     return m_window->clientGeometry().size().toSize();
 }
 
-void WindowScreenCastSource::render(QImage *image)
+void WindowScreenCastSource::render(spa_data *spa, spa_video_format format)
 {
     GLTexture offscreenTexture(hasAlphaChannel() ? GL_RGBA8 : GL_RGB8, 
textureSize());
     GLFramebuffer offscreenTarget(&offscreenTexture);
 
     render(&offscreenTarget);
-    grabTexture(&offscreenTexture, image);
+    grabTexture(&offscreenTexture, spa, format);
 }
 
 void WindowScreenCastSource::render(GLFramebuffer *target)
diff --git a/src/plugins/screencast/windowscreencastsource.h 
b/src/plugins/screencast/windowscreencastsource.h
index 69cd989d534..4efb7850a3e 100644
--- a/src/plugins/screencast/windowscreencastsource.h
+++ b/src/plugins/screencast/windowscreencastsource.h
@@ -27,7 +27,7 @@ public:
     QSize textureSize() const override;
 
     void render(GLFramebuffer *target) override;
-    void render(QImage *image) override;
+    void render(spa_data *spa, spa_video_format format) override;
     std::chrono::nanoseconds clock() const override;
 
 private:
-- 
GitLab



--- End Message ---
--- Begin Message ---
Version: 4:5.27.5-3

kwin-wayland 4:5.27.5-3 is now in bookworm and the issue has been fixed.

--
Best regards,
  Jacek Kowalski

--- End Message ---

Reply via email to