summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <[email protected]>2016-01-06 11:01:39 +0100
committerAllan Sandfeld Jensen <[email protected]>2016-01-08 19:08:43 +0000
commit1bcfc3de7586ddb9f5d1b778b97b26ae3dc9584d (patch)
tree66571c15008a0978c8b2335d668656075a504086
parentc04cf29b78f3f5747c58dd89ca21523e387ee3ac (diff)
Use backing store formats with alpha
We depend on being able to punch holes in the backing store when integrating with FBO elements. To do that we need a format with an alpha channel. This was only working previously because RGB32 didn't mask when filling or when converting to ARGB32_PM, but other formats didn't. Also unifies the logic for getting alpha versions of QImage formats. Task-number: QTBUG-50281 Change-Id: Ied1325f60e2b67d9ea2dfa9701b06fc2231ebfca Reviewed-by: Laszlo Agocs <[email protected]>
-rw-r--r--src/gui/image/qimage.cpp27
-rw-r--r--src/gui/image/qimage_p.h35
-rw-r--r--src/gui/image/qpixmap_raster.cpp27
-rw-r--r--src/plugins/platforms/xcb/qxcbbackingstore.cpp4
4 files changed, 42 insertions, 51 deletions
diff --git a/src/gui/image/qimage.cpp b/src/gui/image/qimage.cpp
index a992ad6feab..6ec1eecfb14 100644
--- a/src/gui/image/qimage.cpp
+++ b/src/gui/image/qimage.cpp
@@ -4623,32 +4623,7 @@ QImage QImage::transformed(const QTransform &matrix, Qt::TransformationMode mode
if (complex_xform || mode == Qt::SmoothTransformation) {
if (d->format < QImage::Format_RGB32 || !hasAlphaChannel()) {
- switch(d->format) {
- case QImage::Format_RGB16:
- target_format = Format_ARGB8565_Premultiplied;
- break;
- case QImage::Format_RGB555:
- target_format = Format_ARGB8555_Premultiplied;
- break;
- case QImage::Format_RGB666:
- target_format = Format_ARGB6666_Premultiplied;
- break;
- case QImage::Format_RGB444:
- target_format = Format_ARGB4444_Premultiplied;
- break;
- case QImage::Format_RGBX8888:
- target_format = Format_RGBA8888_Premultiplied;
- break;
- case QImage::Format_BGR30:
- target_format = Format_A2BGR30_Premultiplied;
- break;
- case QImage::Format_RGB30:
- target_format = Format_A2RGB30_Premultiplied;
- break;
- default:
- target_format = Format_ARGB32_Premultiplied;
- break;
- }
+ target_format = qt_alphaVersion(d->format);
}
}
diff --git a/src/gui/image/qimage_p.h b/src/gui/image/qimage_p.h
index 3badda08642..f9ad6c0ac0d 100644
--- a/src/gui/image/qimage_p.h
+++ b/src/gui/image/qimage_p.h
@@ -161,10 +161,45 @@ inline int qt_depthForFormat(QImage::Format format)
}
return depth;
}
+
#if defined(_M_ARM)
#pragma optimize("", on)
#endif
+inline QImage::Format qt_alphaVersion(QImage::Format format)
+{
+ switch (format) {
+ case QImage::Format_RGB16:
+ return QImage::Format_ARGB8565_Premultiplied;
+ case QImage::Format_RGB555:
+ return QImage::Format_ARGB8555_Premultiplied;
+ case QImage::Format_RGB666:
+ return QImage::Format_ARGB6666_Premultiplied;
+ case QImage::Format_RGB444:
+ return QImage::Format_ARGB4444_Premultiplied;
+ case QImage::Format_RGBX8888:
+ return QImage::Format_RGBA8888_Premultiplied;
+ case QImage::Format_BGR30:
+ return QImage::Format_A2BGR30_Premultiplied;
+ case QImage::Format_RGB30:
+ return QImage::Format_A2RGB30_Premultiplied;
+ default:
+ break;
+ }
+ return QImage::Format_ARGB32_Premultiplied;
+}
+
+inline QImage::Format qt_alphaVersionForPainting(QImage::Format format)
+{
+ QImage::Format toFormat = qt_alphaVersion(format);
+#if defined(__ARM_NEON__) || defined(__SSE2__)
+ // If we are switching depth anyway and we have optimized ARGB32PM routines, upgrade to that.
+ if (qt_depthForFormat(format) != qt_depthForFormat(toFormat))
+ toFormat = QImage::Format_ARGB32_Premultiplied;
+#endif
+ return toFormat;
+}
+
QT_END_NAMESPACE
#endif // QIMAGE_P_H
diff --git a/src/gui/image/qpixmap_raster.cpp b/src/gui/image/qpixmap_raster.cpp
index a2b84b358e2..bbdf77355e1 100644
--- a/src/gui/image/qpixmap_raster.cpp
+++ b/src/gui/image/qpixmap_raster.cpp
@@ -178,20 +178,7 @@ void QRasterPlatformPixmap::fill(const QColor &color)
int alpha = color.alpha();
if (alpha != 255) {
if (!image.hasAlphaChannel()) {
- QImage::Format toFormat;
-#if !(defined(__ARM_NEON__) || defined(__SSE2__))
- if (image.format() == QImage::Format_RGB16)
- toFormat = QImage::Format_ARGB8565_Premultiplied;
- else if (image.format() == QImage::Format_RGB666)
- toFormat = QImage::Format_ARGB6666_Premultiplied;
- else if (image.format() == QImage::Format_RGB555)
- toFormat = QImage::Format_ARGB8555_Premultiplied;
- else if (image.format() == QImage::Format_RGB444)
- toFormat = QImage::Format_ARGB4444_Premultiplied;
- else
-#endif
- toFormat = QImage::Format_ARGB32_Premultiplied;
-
+ QImage::Format toFormat = qt_alphaVersionForPainting(image.format());
if (!image.isNull() && qt_depthForFormat(image.format()) == qt_depthForFormat(toFormat)) {
image.detach();
image.d->format = toFormat;
@@ -314,17 +301,7 @@ void QRasterPlatformPixmap::createPixmapForImage(QImage &sourceImage, Qt::ImageC
: QImage::Format_RGB32;
} else {
QImage::Format opaqueFormat = QNativeImage::systemFormat();
- QImage::Format alphaFormat = QImage::Format_ARGB32_Premultiplied;
-
-#if !defined(__ARM_NEON__) && !defined(__SSE2__)
- switch (opaqueFormat) {
- case QImage::Format_RGB16:
- alphaFormat = QImage::Format_ARGB8565_Premultiplied;
- break;
- default: // We don't care about the others...
- break;
- }
-#endif
+ QImage::Format alphaFormat = qt_alphaVersionForPainting(opaqueFormat);
if (!sourceImage.hasAlphaChannel()) {
format = opaqueFormat;
diff --git a/src/plugins/platforms/xcb/qxcbbackingstore.cpp b/src/plugins/platforms/xcb/qxcbbackingstore.cpp
index 1825a463d07..006df320feb 100644
--- a/src/plugins/platforms/xcb/qxcbbackingstore.cpp
+++ b/src/plugins/platforms/xcb/qxcbbackingstore.cpp
@@ -51,6 +51,7 @@
#include <qscreen.h>
#include <QtGui/private/qhighdpiscaling_p.h>
#include <qpa/qplatformgraphicsbuffer.h>
+#include <private/qimage_p.h>
#include <algorithm>
QT_BEGIN_NAMESPACE
@@ -172,6 +173,9 @@ QXcbShmImage::QXcbShmImage(QXcbScreen *screen, const QSize &size, uint depth, QI
qWarning() << "QXcbBackingStore: Error while marking the shared memory segment to be destroyed";
}
+ if (QImage::toPixelFormat(format).alphaUsage() == QPixelFormat::IgnoresAlpha)
+ format = qt_alphaVersionForPainting(format);
+
m_qimage = QImage( (uchar*) m_xcb_image->data, m_xcb_image->width, m_xcb_image->height, m_xcb_image->stride, format);
m_graphics_buffer = new QXcbShmGraphicsBuffer(&m_qimage);
}