diff options
author | Samuel Rødal <sroedal@trolltech.com> | 2009-10-15 14:42:10 (GMT) |
---|---|---|
committer | Samuel Rødal <sroedal@trolltech.com> | 2009-10-15 15:15:20 (GMT) |
commit | b5106b1b99a749653c58719c333411b9ce374b67 (patch) | |
tree | 86327ee5e8c6b8ed632981b791a06a2a578e65e4 /src/opengl | |
parent | 08554b7e8e58c685879881b17bdf65c5f4594c3c (diff) | |
download | Qt-b5106b1b99a749653c58719c333411b9ce374b67.zip Qt-b5106b1b99a749653c58719c333411b9ce374b67.tar.gz Qt-b5106b1b99a749653c58719c333411b9ce374b67.tar.bz2 |
Optimized QPixmap::fill for GL backend when pixmap is used as is.
When QGLPixmapData is bound after a fill(), without being painted on in
the mean-time, it's cheaper to directly generate a source image than to
go through convertToGLFormat(), since all the pixels in the image will
have the same value.
Reviewed-by: Trond
Diffstat (limited to 'src/opengl')
-rw-r--r-- | src/opengl/qgl.cpp | 46 | ||||
-rw-r--r-- | src/opengl/qpixmapdata_gl.cpp | 22 |
2 files changed, 43 insertions, 25 deletions
diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp index 1be2073..a8b136d 100644 --- a/src/opengl/qgl.cpp +++ b/src/opengl/qgl.cpp @@ -1978,6 +1978,32 @@ GLuint QGLContext::bindTexture(const QString &fileName) return tx_id; } +static inline QRgb qt_gl_convertToGLFormatHelper(QRgb src_pixel, GLenum texture_format) +{ + if (texture_format == GL_BGRA) { + if (QSysInfo::ByteOrder == QSysInfo::BigEndian) { + return ((src_pixel << 24) & 0xff000000) + | ((src_pixel >> 24) & 0x000000ff) + | ((src_pixel << 8) & 0x00ff0000) + | ((src_pixel >> 8) & 0x0000ff00); + } else { + return src_pixel; + } + } else { // GL_RGBA + if (QSysInfo::ByteOrder == QSysInfo::BigEndian) { + return (src_pixel << 8) | ((src_pixel >> 24) & 0xff); + } else { + return ((src_pixel << 16) & 0xff0000) + | ((src_pixel >> 16) & 0xff) + | (src_pixel & 0xff00ff00); + } + } +} + +QRgb qt_gl_convertToGLFormat(QRgb src_pixel, GLenum texture_format) +{ + return qt_gl_convertToGLFormatHelper(src_pixel, texture_format); +} static void convertToGLFormatHelper(QImage &dst, const QImage &img, GLenum texture_format) { @@ -2006,25 +2032,7 @@ static void convertToGLFormatHelper(QImage &dst, const QImage &img, GLenum textu const uint *src = (const quint32 *) (srcPixels - (srcy >> 16) * sbpl); int srcx = basex; for (int x=0; x<target_width; ++x) { - uint src_pixel = src[srcx >> 16]; - if (texture_format == GL_BGRA) { - if (QSysInfo::ByteOrder == QSysInfo::BigEndian) { - dest[x] = ((src_pixel << 24) & 0xff000000) - | ((src_pixel >> 24) & 0x000000ff) - | ((src_pixel << 8) & 0x00ff0000) - | ((src_pixel >> 8) & 0x0000ff00); - } else { - dest[x] = src_pixel; - } - } else { // GL_RGBA - if (QSysInfo::ByteOrder == QSysInfo::BigEndian) { - dest[x] = (src_pixel << 8) | ((src_pixel >> 24) & 0xff); - } else { - dest[x] = ((src_pixel << 16) & 0xff0000) - | ((src_pixel >> 16) & 0xff) - | (src_pixel & 0xff00ff00); - } - } + dest[x] = qt_gl_convertToGLFormatHelper(src[srcx >> 16], texture_format); srcx += ix; } dest = (quint32 *)(((uchar *) dest) + dbpl); diff --git a/src/opengl/qpixmapdata_gl.cpp b/src/opengl/qpixmapdata_gl.cpp index ba4663f..83ebece 100644 --- a/src/opengl/qpixmapdata_gl.cpp +++ b/src/opengl/qpixmapdata_gl.cpp @@ -568,6 +568,7 @@ QPaintEngine* QGLPixmapData::paintEngine() const return m_source.paintEngine(); } +extern QRgb qt_gl_convertToGLFormat(QRgb src_pixel, GLenum texture_format); // If copyBack is true, bind will copy the contents of the render // FBO to the texture (which is not bound to the texture, as it's @@ -577,17 +578,26 @@ GLuint QGLPixmapData::bind(bool copyBack) const if (m_renderFbo && copyBack) { copyBackFromRenderFbo(true); } else { - if (m_hasFillColor) { - m_dirty = true; - m_source = QImage(w, h, QImage::Format_ARGB32_Premultiplied); - m_source.fill(PREMUL(m_fillColor.rgba())); - m_hasFillColor = false; - } ensureCreated(); } GLuint id = m_texture.id; glBindTexture(GL_TEXTURE_2D, id); + + if (m_hasFillColor) { + if (!useFramebufferObjects()) { + m_source = QImage(w, h, QImage::Format_ARGB32_Premultiplied); + m_source.fill(PREMUL(m_fillColor.rgba())); + } + + m_hasFillColor = false; + + GLenum format = qt_gl_preferredTextureFormat(); + QImage tx(w, h, QImage::Format_ARGB32_Premultiplied); + tx.fill(qt_gl_convertToGLFormat(m_fillColor.rgba(), format)); + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, w, h, format, GL_UNSIGNED_BYTE, tx.bits()); + } + return id; } |