diff options
author | Laszlo Agocs <laszlo.agocs@theqtcompany.com> | 2015-03-26 17:59:39 +0100 |
---|---|---|
committer | Laszlo Agocs <laszlo.agocs@theqtcompany.com> | 2015-03-30 08:41:49 +0000 |
commit | 6fe60cd9f2966b141f70b0a223b93173505b2ecb (patch) | |
tree | f91c80eb62c1983dff60a59b551e259955bb08f2 /src/plugins/platforms/xcb/qxcbbackingstore.cpp | |
parent | 1a542f25447686ab7a5eea759a33f20ce9eeaacc (diff) |
xcb: Fix bgr888 VNC sessions
Introduce a slow path for 24 and 32 bit BGR. We don't care about
performance here but it has to show the correct colors.
Task-number: QTBUG-42776
Change-Id: Ic73e8ca3950b2b956f06643165dcfac51e7540f3
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@theqtcompany.com>
Diffstat (limited to 'src/plugins/platforms/xcb/qxcbbackingstore.cpp')
-rw-r--r-- | src/plugins/platforms/xcb/qxcbbackingstore.cpp | 37 |
1 files changed, 32 insertions, 5 deletions
diff --git a/src/plugins/platforms/xcb/qxcbbackingstore.cpp b/src/plugins/platforms/xcb/qxcbbackingstore.cpp index 5c9293c03d..06db4d83ac 100644 --- a/src/plugins/platforms/xcb/qxcbbackingstore.cpp +++ b/src/plugins/platforms/xcb/qxcbbackingstore.cpp @@ -303,13 +303,16 @@ QXcbBackingStore::~QXcbBackingStore() QPaintDevice *QXcbBackingStore::paintDevice() { - return m_image ? m_image->image() : 0; + if (!m_image) + return 0; + return m_rgbImage.isNull() ? m_image->image() : &m_rgbImage; } void QXcbBackingStore::beginPaint(const QRegion ®ion) { if (!m_image) return; + int dpr = int(m_image->image()->devicePixelRatio()); const int windowDpr = int(window()->devicePixelRatio()); if (windowDpr != dpr) { @@ -317,13 +320,13 @@ void QXcbBackingStore::beginPaint(const QRegion ®ion) dpr = int(m_image->image()->devicePixelRatio()); } - QRegion xRegion = dpr == 1 ? region : QTransform::fromScale(dpr,dpr).map(region); - m_image->preparePaint(xRegion); + m_paintRegion = dpr == 1 ? region : QTransform::fromScale(dpr,dpr).map(region); + m_image->preparePaint(m_paintRegion); if (m_image->image()->hasAlphaChannel()) { - QPainter p(m_image->image()); + QPainter p(paintDevice()); p.setCompositionMode(QPainter::CompositionMode_Source); - const QVector<QRect> rects = xRegion.rects(); + const QVector<QRect> rects = m_paintRegion.rects(); const QColor blank = Qt::transparent; for (QVector<QRect>::const_iterator it = rects.begin(); it != rects.end(); ++it) { p.fillRect(*it, blank); @@ -331,6 +334,24 @@ void QXcbBackingStore::beginPaint(const QRegion ®ion) } } +void QXcbBackingStore::endPaint() +{ + QXcbWindow *platformWindow = static_cast<QXcbWindow *>(window()->handle()); + if (!platformWindow || !platformWindow->imageNeedsRgbSwap()) + return; + + // Slow path: the paint device was m_rgbImage. Now copy with swapping red + // and blue into m_image. + const QVector<QRect> rects = m_paintRegion.rects(); + if (rects.isEmpty()) + return; + QPainter p(m_image->image()); + for (QVector<QRect>::const_iterator it = rects.begin(); it != rects.end(); ++it) { + const QRect rect = *it; + p.drawImage(rect.topLeft(), m_rgbImage.copy(rect).rgbSwapped()); + } +} + #ifndef QT_NO_OPENGL QImage QXcbBackingStore::toImage() const { @@ -426,6 +447,12 @@ void QXcbBackingStore::resize(const QSize &size, const QRegion &) delete m_image; m_image = new QXcbShmImage(screen, xSize, win->depth(), win->imageFormat()); m_image->image()->setDevicePixelRatio(dpr); + // Slow path for bgr888 VNC: Create an additional image, paint into that and + // swap R and B while copying to m_image after each paint. + if (win->imageNeedsRgbSwap()) { + m_rgbImage = QImage(xSize, win->imageFormat()); + m_rgbImage.setDevicePixelRatio(dpr); + } Q_XCB_NOOP(connection()); } |