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>
bb10
Laszlo Agocs 2015-06-29 16:55:06 +02:00
parent c937bbb4fe
commit 29e88fd8f0
4 changed files with 75 additions and 17 deletions

View File

@ -114,7 +114,8 @@ public:
GeometryShaders = 0x00080000,
MapBufferRange = 0x00100000,
Sized8Formats = 0x00200000,
DiscardFramebuffer = 0x00400000
DiscardFramebuffer = 0x00400000,
Sized16Formats = 0x00800000
};
Q_DECLARE_FLAGS(OpenGLExtensions, OpenGLExtension)

View File

@ -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;

View File

@ -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

View File

@ -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();