diff options
author | Laszlo Agocs <laszlo.agocs@theqtcompany.com> | 2015-06-29 16:55:06 +0200 |
---|---|---|
committer | Laszlo Agocs <laszlo.agocs@theqtcompany.com> | 2015-06-29 15:59:06 +0000 |
commit | 29e88fd8f066c14a405a52bbfe3715dc3e5e891f (patch) | |
tree | bbfbdb5862d6c63fc661f6ed1924782c0c7b2c58 /src/gui/opengl/qopenglgradientcache.cpp | |
parent | c937bbb4fe708f7f873ca630c6ff225f9a3f9ace (diff) |
Do not use 16 bits per color on GLES
unless GL_EXT_texture_norm16 (and so GL_RGBA16) is present.
Change-Id: Ic15b81b8134fda147e96301b7f78cabe07a05d9e
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@theqtcompany.com>
Diffstat (limited to 'src/gui/opengl/qopenglgradientcache.cpp')
-rw-r--r-- | src/gui/opengl/qopenglgradientcache.cpp | 79 |
1 files changed, 65 insertions, 14 deletions
diff --git a/src/gui/opengl/qopenglgradientcache.cpp b/src/gui/opengl/qopenglgradientcache.cpp index 6622d4805f..13bad9aabb 100644 --- a/src/gui/opengl/qopenglgradientcache.cpp +++ b/src/gui/opengl/qopenglgradientcache.cpp @@ -39,10 +39,6 @@ #include "qopenglfunctions.h" #include "qopenglextensions_p.h" -#ifndef GL_RGBA8 -#define GL_RGBA8 0x8058 -#endif - #ifndef GL_RGBA16 #define GL_RGBA16 0x805B #endif @@ -147,19 +143,19 @@ GLuint QOpenGL2GradientCache::addCacheElement(quint64 hash_val, const QGradient } CacheInfo cache_entry(gradient.stops(), opacity, gradient.interpolationMode()); - QRgba64 buffer[1024]; - generateGradientColorTable(gradient, buffer, paletteSize(), opacity); funcs->glGenTextures(1, &cache_entry.texId); funcs->glBindTexture(GL_TEXTURE_2D, cache_entry.texId); - GLenum internalFormat = GL_RGBA16; - if (QOpenGLContext::currentContext()->isOpenGLES()) { - if (static_cast<QOpenGLExtensions*>(funcs)->hasOpenGLExtension(QOpenGLExtensions::Sized8Formats)) - internalFormat = GL_RGBA8; - else - internalFormat = GL_RGBA; // Let OpenGLES use whatever it prefers. + if (static_cast<QOpenGLExtensions *>(funcs)->hasOpenGLExtension(QOpenGLExtensions::Sized16Formats)) { + QRgba64 buffer[1024]; + generateGradientColorTable(gradient, buffer, paletteSize(), opacity); + funcs->glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16, paletteSize(), 1, + 0, GL_RGBA, GL_UNSIGNED_SHORT, buffer); + } else { + uint buffer[1024]; + generateGradientColorTable(gradient, buffer, paletteSize(), opacity); + funcs->glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, paletteSize(), 1, + 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer); } - funcs->glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, paletteSize(), 1, - 0, GL_RGBA, GL_UNSIGNED_SHORT, buffer); return cache.insert(hash_val, cache_entry).value().texId; } @@ -220,4 +216,59 @@ void QOpenGL2GradientCache::generateGradientColorTable(const QGradient& gradient colorTable[size-1] = last_color; } +void QOpenGL2GradientCache::generateGradientColorTable(const QGradient& gradient, uint *colorTable, int size, qreal opacity) const +{ + int pos = 0; + QGradientStops s = gradient.stops(); + QVector<uint> colors(s.size()); + + for (int i = 0; i < s.size(); ++i) + colors[i] = s[i].second.rgba(); // Qt LIES! It returns ARGB (on little-endian AND on big-endian) + + bool colorInterpolation = (gradient.interpolationMode() == QGradient::ColorInterpolation); + + uint alpha = qRound(opacity * 256); + uint current_color = ARGB_COMBINE_ALPHA(colors[0], alpha); + qreal incr = 1.0 / qreal(size); + qreal fpos = 1.5 * incr; + colorTable[pos++] = ARGB2RGBA(qPremultiply(current_color)); + + while (fpos <= s.first().first) { + colorTable[pos] = colorTable[pos - 1]; + pos++; + fpos += incr; + } + + if (colorInterpolation) + current_color = qPremultiply(current_color); + + for (int i = 0; i < s.size() - 1; ++i) { + qreal delta = 1/(s[i+1].first - s[i].first); + uint next_color = ARGB_COMBINE_ALPHA(colors[i+1], alpha); + if (colorInterpolation) + next_color = qPremultiply(next_color); + + while (fpos < s[i+1].first && pos < size) { + int dist = int(256 * ((fpos - s[i].first) * delta)); + int idist = 256 - dist; + if (colorInterpolation) + colorTable[pos] = ARGB2RGBA(INTERPOLATE_PIXEL_256(current_color, idist, next_color, dist)); + else + colorTable[pos] = ARGB2RGBA(qPremultiply(INTERPOLATE_PIXEL_256(current_color, idist, next_color, dist))); + ++pos; + fpos += incr; + } + current_color = next_color; + } + + Q_ASSERT(s.size() > 0); + + uint last_color = ARGB2RGBA(qPremultiply(ARGB_COMBINE_ALPHA(colors[s.size() - 1], alpha))); + for (;pos < size; ++pos) + colorTable[pos] = last_color; + + // Make sure the last color stop is represented at the end of the table + colorTable[size-1] = last_color; +} + QT_END_NAMESPACE |