summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLaszlo Agocs <laszlo.agocs@theqtcompany.com>2015-06-29 16:55:06 +0200
committerLaszlo Agocs <laszlo.agocs@theqtcompany.com>2015-06-29 15:59:06 +0000
commit29e88fd8f066c14a405a52bbfe3715dc3e5e891f (patch)
treebbfbdb5862d6c63fc661f6ed1924782c0c7b2c58
parentc937bbb4fe708f7f873ca630c6ff225f9a3f9ace (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>
-rw-r--r--src/gui/opengl/qopenglextensions_p.h3
-rw-r--r--src/gui/opengl/qopenglfunctions.cpp7
-rw-r--r--src/gui/opengl/qopenglgradientcache.cpp79
-rw-r--r--src/gui/opengl/qopenglgradientcache_p.h3
4 files changed, 75 insertions, 17 deletions
diff --git a/src/gui/opengl/qopenglextensions_p.h b/src/gui/opengl/qopenglextensions_p.h
index efe5421f56..e50ca1a94c 100644
--- a/src/gui/opengl/qopenglextensions_p.h
+++ b/src/gui/opengl/qopenglextensions_p.h
@@ -114,7 +114,8 @@ public:
GeometryShaders = 0x00080000,
MapBufferRange = 0x00100000,
Sized8Formats = 0x00200000,
- DiscardFramebuffer = 0x00400000
+ DiscardFramebuffer = 0x00400000,
+ Sized16Formats = 0x00800000
};
Q_DECLARE_FLAGS(OpenGLExtensions, OpenGLExtension)
diff --git a/src/gui/opengl/qopenglfunctions.cpp b/src/gui/opengl/qopenglfunctions.cpp
index 280430c064..2579f0e77f 100644
--- a/src/gui/opengl/qopenglfunctions.cpp
+++ b/src/gui/opengl/qopenglfunctions.cpp
@@ -419,11 +419,14 @@ static int qt_gl_resolve_extensions()
// We don't match GL_APPLE_texture_format_BGRA8888 here because it has different semantics.
if (extensionMatcher.match("GL_IMG_texture_format_BGRA8888") || extensionMatcher.match("GL_EXT_texture_format_BGRA8888"))
extensions |= QOpenGLExtensions::BGRATextureFormat;
-
if (extensionMatcher.match("GL_EXT_discard_framebuffer"))
extensions |= QOpenGLExtensions::DiscardFramebuffer;
+ if (extensionMatcher.match("GL_EXT_texture_norm16"))
+ extensions |= QOpenGLExtensions::Sized16Formats;
} else {
- extensions |= QOpenGLExtensions::ElementIndexUint | QOpenGLExtensions::MapBuffer;
+ extensions |= QOpenGLExtensions::ElementIndexUint
+ | QOpenGLExtensions::MapBuffer
+ | QOpenGLExtensions::Sized16Formats;
if (format.version() >= qMakePair(1, 2))
extensions |= QOpenGLExtensions::BGRATextureFormat;
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
diff --git a/src/gui/opengl/qopenglgradientcache_p.h b/src/gui/opengl/qopenglgradientcache_p.h
index d368f4bcfc..61949d5b7c 100644
--- a/src/gui/opengl/qopenglgradientcache_p.h
+++ b/src/gui/opengl/qopenglgradientcache_p.h
@@ -86,6 +86,9 @@ private:
inline void generateGradientColorTable(const QGradient& gradient,
QRgba64 *colorTable,
int size, qreal opacity) const;
+ inline void generateGradientColorTable(const QGradient& gradient,
+ uint *colorTable,
+ int size, qreal opacity) const;
GLuint addCacheElement(quint64 hash_val, const QGradient &gradient, qreal opacity);
void cleanCache();