diff options
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()); } |