[platforms/fbdev] Properly detect a BGR image format

Summary:
If the format of the framebuffer is BGR we cannot create an RGB image
format from it - the rendering is incorrect. Unfortunately QImage does
not support a BGR image format.

To solve this problem we still use an RGB image format but on rendering
the front buffer is rgbSwapped to convert the RGB image to a BGR image.

BUG: 365243
FIXED-IN: 5.7.2

Test Plan: Tested on a neon kvm

Reviewers: #kwin, #plasma_on_wayland

Subscribers: plasma-devel, kwin

Tags: #plasma_on_wayland, #kwin

Differential Revision: https://phabricator.kde.org/D2134
icc-effect-5.14.5
Martin Gräßlin 2016-07-11 10:53:04 +02:00
parent 66174846f1
commit aaf8ce16df
3 changed files with 21 additions and 6 deletions

View File

@ -92,6 +92,7 @@ void FramebufferBackend::openFrameBuffer()
}
m_fd = fd;
queryScreenInfo();
initImageFormat();
setReady(true);
emit screensQueried();
}
@ -153,9 +154,14 @@ void FramebufferBackend::unmap()
}
QImage::Format FramebufferBackend::imageFormat() const
{
return m_imageFormat;
}
void FramebufferBackend::initImageFormat()
{
if (m_fd < 0) {
return QImage::Format_Invalid;
return;
}
qCDebug(KWIN_FB) << "Bits Per Pixel: " << m_bitsPerPixel;
@ -178,7 +184,7 @@ QImage::Format FramebufferBackend::imageFormat() const
m_green.offset == 8 &&
m_red.offset == 16) {
qCDebug(KWIN_FB) << "Framebuffer format is RGB32";
return QImage::Format_RGB32;
m_imageFormat = QImage::Format_RGB32;
} else if (m_bitsPerPixel == 24 &&
m_red.length == 8 &&
m_green.length == 8 &&
@ -187,7 +193,8 @@ QImage::Format FramebufferBackend::imageFormat() const
m_green.offset == 8 &&
m_red.offset == 16) {
qCDebug(KWIN_FB) << "Framebuffer Format is RGB888";
return QImage::Format_RGB888;
m_bgr = true;
m_imageFormat = QImage::Format_RGB888;
} else if (m_bitsPerPixel == 16 &&
m_red.length == 5 &&
m_green.length == 6 &&
@ -196,10 +203,9 @@ QImage::Format FramebufferBackend::imageFormat() const
m_green.offset == 5 &&
m_red.offset == 11) {
qCDebug(KWIN_FB) << "Framebuffer Format is RGB16";
return QImage::Format_RGB16;
m_imageFormat = QImage::Format_RGB16;
}
qCWarning(KWIN_FB) << "Framebuffer format is unknown";
return QImage::Format_Invalid;
}
}

View File

@ -71,10 +71,17 @@ public:
return m_bitsPerPixel;
}
QImage::Format imageFormat() const;
/**
* @returns whether the imageFormat is BGR instead of RGB.
**/
bool isBGR() const {
return m_bgr;
}
private:
void openFrameBuffer();
bool queryScreenInfo();
void initImageFormat();
QSize m_resolution;
QSize m_physicalSize;
QByteArray m_id;
@ -91,6 +98,8 @@ private:
quint32 m_bufferLength = 0;
int m_bytesPerLine = 0;
void *m_memory = nullptr;
QImage::Format m_imageFormat = QImage::Format_Invalid;
bool m_bgr = false;
};
}

View File

@ -79,7 +79,7 @@ void FramebufferQPainterBackend::present(int mask, const QRegion &damage)
return;
}
QPainter p(&m_backBuffer);
p.drawImage(QPoint(0, 0), m_renderBuffer);
p.drawImage(QPoint(0, 0), m_backend->isBGR() ? m_renderBuffer.rgbSwapped() : m_renderBuffer);
}
bool FramebufferQPainterBackend::usesOverlayWindow() const