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
parent
c937bbb4fe
commit
29e88fd8f0
|
|
@ -114,7 +114,8 @@ public:
|
|||
GeometryShaders = 0x00080000,
|
||||
MapBufferRange = 0x00100000,
|
||||
Sized8Formats = 0x00200000,
|
||||
DiscardFramebuffer = 0x00400000
|
||||
DiscardFramebuffer = 0x00400000,
|
||||
Sized16Formats = 0x00800000
|
||||
};
|
||||
Q_DECLARE_FLAGS(OpenGLExtensions, OpenGLExtension)
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue