diff options
-rw-r--r-- | src/gui/opengl/qopengltexturecache.cpp | 30 | ||||
-rw-r--r-- | src/gui/opengl/qopengltexturecache_p.h | 3 | ||||
-rw-r--r-- | src/opengl/qgl.cpp | 36 |
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 |