summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/gui/opengl/qopengltexturecache.cpp30
-rw-r--r--src/gui/opengl/qopengltexturecache_p.h3
-rw-r--r--src/opengl/qgl.cpp36
3 files changed, 35 insertions, 34 deletions
diff --git a/src/gui/opengl/qopengltexturecache.cpp b/src/gui/opengl/qopengltexturecache.cpp
index 94b82885ff..4238f63cd8 100644
--- a/src/gui/opengl/qopengltexturecache.cpp
+++ b/src/gui/opengl/qopengltexturecache.cpp
@@ -95,10 +95,9 @@ void QOpenGLTextureCacheWrapper::cleanupTexturesForPixmapData(QPlatformPixmap *p
cleanupTexturesForCacheKey(pmd->cacheKey());
}
-QOpenGLTextureCache::QOpenGLTextureCache(QOpenGLContext *ctx, bool useByteSwapImage)
+QOpenGLTextureCache::QOpenGLTextureCache(QOpenGLContext *ctx)
: QOpenGLSharedResource(ctx->shareGroup())
, m_cache(64 * 1024) // 64 MB cache
- , m_useByteSwapImage(useByteSwapImage)
{
}
@@ -152,38 +151,13 @@ GLuint QOpenGLTextureCache::bindTexture(QOpenGLContext *context, const QImage &i
return id;
}
-static inline void qgl_byteSwapImage(QImage &img)
-{
- const int width = img.width();
- const int height = img.height();
-
- if (QSysInfo::ByteOrder == QSysInfo::LittleEndian)
- {
- for (int i = 0; i < height; ++i) {
- uint *p = (uint *) img.scanLine(i);
- for (int x = 0; x < width; ++x)
- p[x] = ((p[x] << 16) & 0xff0000) | ((p[x] >> 16) & 0xff) | (p[x] & 0xff00ff00);
- }
- } else {
- for (int i = 0; i < height; ++i) {
- uint *p = (uint *) img.scanLine(i);
- for (int x = 0; x < width; ++x)
- p[x] = (p[x] << 8) | (p[x] >> 24);
- }
- }
-}
-
GLuint QOpenGLTextureCache::bindTexture(QOpenGLContext *context, qint64 key, const QImage &image)
{
GLuint id;
glGenTextures(1, &id);
glBindTexture(GL_TEXTURE_2D, id);
- QImage tx = image.convertToFormat(QImage::Format_ARGB32_Premultiplied);
-
- // Performance could be improved by skipping qgl_byteSwapImage().
- if (m_useByteSwapImage)
- qgl_byteSwapImage(tx);
+ QImage tx = image.convertToFormat(QImage::Format_RGBA8888_Premultiplied);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tx.width(), tx.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, const_cast<const QImage &>(tx).bits());
diff --git a/src/gui/opengl/qopengltexturecache_p.h b/src/gui/opengl/qopengltexturecache_p.h
index d4d3f00069..2e82d5f373 100644
--- a/src/gui/opengl/qopengltexturecache_p.h
+++ b/src/gui/opengl/qopengltexturecache_p.h
@@ -78,7 +78,7 @@ class Q_GUI_EXPORT QOpenGLTextureCache : public QOpenGLSharedResource
public:
static QOpenGLTextureCache *cacheForContext(QOpenGLContext *context);
- QOpenGLTextureCache(QOpenGLContext *, bool useByteSwapImage = true);
+ QOpenGLTextureCache(QOpenGLContext *);
~QOpenGLTextureCache();
GLuint bindTexture(QOpenGLContext *context, const QPixmap &pixmap);
@@ -94,7 +94,6 @@ private:
QMutex m_mutex;
QCache<quint64, QOpenGLCachedTexture> m_cache;
- bool m_useByteSwapImage;
};
QT_END_NAMESPACE
diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp
index 8ee0a8b290..16044df8b1 100644
--- a/src/opengl/qgl.cpp
+++ b/src/opengl/qgl.cpp
@@ -2308,10 +2308,18 @@ QGLTexture* QGLContextPrivate::bindTexture(const QImage &image, GLenum target, G
QImage::Format target_format = img.format();
bool premul = options & QGLContext::PremultipliedAlphaBindOption;
+ bool needsbyteswap = true;
GLenum externalFormat;
GLuint pixel_type;
- if (qgl_extensions()->hasOpenGLExtension(QOpenGLExtensions::BGRATextureFormat)) {
+ if (target_format == QImage::Format_RGBA8888
+ || target_format == QImage::Format_RGBA8888_Premultiplied
+ || target_format == QImage::Format_RGBX8888) {
+ externalFormat = GL_RGBA;
+ pixel_type = GL_UNSIGNED_BYTE;
+ needsbyteswap = false;
+ } else if (qgl_extensions()->hasOpenGLExtension(QOpenGLExtensions::BGRATextureFormat)) {
externalFormat = GL_BGRA;
+ needsbyteswap = false;
if (QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_Version_1_2)
pixel_type = GL_UNSIGNED_INT_8_8_8_8_REV;
else
@@ -2338,14 +2346,34 @@ QGLTexture* QGLContextPrivate::bindTexture(const QImage &image, GLenum target, G
#endif
}
break;
+ case QImage::Format_RGBA8888:
+ if (premul) {
+ img = img.convertToFormat(target_format = QImage::Format_RGBA8888_Premultiplied);
+#ifdef QGL_BIND_TEXTURE_DEBUG
+ printf(" - converted RGBA8888 -> RGBA8888_Premultiplied (%d ms) \n", time.elapsed());
+#endif
+ }
+ break;
+ case QImage::Format_RGBA8888_Premultiplied:
+ if (!premul) {
+ img = img.convertToFormat(target_format = QImage::Format_RGBA8888);
+#ifdef QGL_BIND_TEXTURE_DEBUG
+ printf(" - converted RGBA8888_Premultiplied -> RGBA8888 (%d ms) \n", time.elapsed());
+#endif
+ }
+ break;
case QImage::Format_RGB16:
pixel_type = GL_UNSIGNED_SHORT_5_6_5;
externalFormat = GL_RGB;
internalFormat = GL_RGB;
+ needsbyteswap = false;
break;
case QImage::Format_RGB32:
+ case QImage::Format_RGBX8888:
break;
default:
+ // Ideally more formats would be converted directly to an RGBA8888 format,
+ // but we are only guaranteed to have a fast conversion to an ARGB format.
if (img.hasAlphaChannel()) {
img = img.convertToFormat(premul
? QImage::Format_ARGB32_Premultiplied
@@ -2383,10 +2411,10 @@ QGLTexture* QGLContextPrivate::bindTexture(const QImage &image, GLenum target, G
#endif
}
- if (externalFormat == GL_RGBA) {
+ if (needsbyteswap) {
// The only case where we end up with a depth different from
- // 32 in the switch above is for the RGB16 case, where we set
- // the format to GL_RGB
+ // 32 in the switch above is for the RGB16 case, where we do
+ // not need a byteswap.
Q_ASSERT(img.depth() == 32);
qgl_byteSwapImage(img, pixel_type);
#ifdef QGL_BIND_TEXTURE_DEBUG