summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLouai Al-Khanji <louai.al-khanji@theqtcompany.com>2016-04-13 16:20:40 -0700
committerLouai Al-Khanji <louai.al-khanji@theqtcompany.com>2016-04-15 17:27:14 +0000
commit760b2929a3b268e2edf14a561329bdb78fbdc26e (patch)
tree53186fdfd45dec8d1682e832a076990e79fd7c59
parent224f31c0b5ad86b5ea56025ff08faf7e25e1a82d (diff)
xcb: Fix image scanline padding
Commit b9d386f2ccd69c7f6a766a6d90a6024eeb48e90a neglects to account for the scanline padding requested by the X server. This can result in visual artifacts if padding is required. This commit fixes this by factoring in the X server's requested scanline padding when calculating image stride. Change-Id: I082cb7101ec3a9c554b9b58a76f53f780b87d31e Reviewed-by: Lars Knoll <lars.knoll@theqtcompany.com>
-rw-r--r--src/plugins/platforms/xcb/qxcbbackingstore.cpp37
1 files changed, 22 insertions, 15 deletions
diff --git a/src/plugins/platforms/xcb/qxcbbackingstore.cpp b/src/plugins/platforms/xcb/qxcbbackingstore.cpp
index 844ed8f579..51c6b198e5 100644
--- a/src/plugins/platforms/xcb/qxcbbackingstore.cpp
+++ b/src/plugins/platforms/xcb/qxcbbackingstore.cpp
@@ -305,47 +305,52 @@ static inline void copy_unswapped(char *dst, int dstBytesPerLine, const QImage &
}
template <class Pixel>
-static inline void copy_swapped(Pixel *dst, const QImage &img, const QRect &rect)
+static inline void copy_swapped(char *dst, const int dstStride, const QImage &img, const QRect &rect)
{
const uchar *srcData = img.constBits();
const int srcBytesPerLine = img.bytesPerLine();
const int left = rect.left();
- const int right = rect.right() + 1;
+ const int width = rect.width();
const int bottom = rect.bottom() + 1;
for (int yy = rect.top(); yy < bottom; ++yy) {
- const Pixel *src = reinterpret_cast<const Pixel *>(srcData + yy * srcBytesPerLine) + left;
+ Pixel *dstPixels = reinterpret_cast<Pixel *>(dst);
+ const Pixel *srcPixels = reinterpret_cast<const Pixel *>(srcData + yy * srcBytesPerLine) + left;
- for (int xx = left; xx < right; ++xx)
- *dst++ = qbswap<Pixel>(*src++);
+ for (int i = 0; i < width; ++i)
+ dstPixels[i] = qbswap<Pixel>(*srcPixels++);
+
+ dst += dstStride;
}
}
-static QImage native_sub_image(QByteArray *buffer, const QImage &src, int x, int y, int w, int h, bool swap)
+static QImage native_sub_image(QByteArray *buffer, const int dstStride, const QImage &src, const QRect &rect, bool swap)
{
- const QRect rect(x, y, w, h);
-
- if (!swap && src.rect() == rect)
+ if (!swap && src.rect() == rect && src.bytesPerLine() == dstStride)
return src;
- const int dstStride = w * src.depth() >> 3;
- buffer->resize(h * dstStride);
+ buffer->resize(rect.height() * dstStride);
if (swap) {
switch (src.depth()) {
case 32:
- copy_swapped(reinterpret_cast<quint32 *>(buffer->data()), src, rect);
+ copy_swapped<quint32>(buffer->data(), dstStride, src, rect);
break;
case 16:
- copy_swapped(reinterpret_cast<quint16 *>(buffer->data()), src, rect);
+ copy_swapped<quint16>(buffer->data(), dstStride, src, rect);
break;
}
} else {
copy_unswapped(buffer->data(), dstStride, src, rect);
}
- return QImage(reinterpret_cast<const uchar *>(buffer->constData()), w, h, dstStride, src.format());
+ return QImage(reinterpret_cast<const uchar *>(buffer->constData()), rect.width(), rect.height(), dstStride, src.format());
+}
+
+static inline quint32 round_up_scanline(quint32 base, quint32 pad)
+{
+ return (base + pad - 1) & -pad;
}
void QXcbShmImage::flushPixmap(const QRegion &region)
@@ -390,7 +395,9 @@ void QXcbShmImage::flushPixmap(const QRegion &region)
while (height > 0) {
const int rows = std::min(height, rows_per_put);
- const QImage subImage = native_sub_image(&m_flushBuffer, m_qimage, x, y, width, rows, needsByteSwap);
+ const QRect subRect(x, y, width, rows);
+ const quint32 stride = round_up_scanline(width * m_qimage.depth(), xcb_subimage.scanline_pad) >> 3;
+ const QImage subImage = native_sub_image(&m_flushBuffer, stride, m_qimage, subRect, needsByteSwap);
xcb_subimage.width = width;
xcb_subimage.height = rows;