aboutsummaryrefslogtreecommitdiffstats
path: root/src/quick/scenegraph
diff options
context:
space:
mode:
authorYoann Lopes <yoann.lopes@digia.com>2013-11-08 15:55:15 +0100
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-11-09 10:42:49 +0100
commit4f63f43cf2da59c2e87ae96e8bd84950490a070b (patch)
tree5a5fbda4a422faac38c8cd3bd023d2257a392fc0 /src/quick/scenegraph
parent040c835dca2fdf56d7ff37da8b72a52b69be0284 (diff)
Workaround for glyph upload bug with the Mali-400 GPU.
Uploading unaligned and alpha-only data seems to be broken with that GPU, uploading line by line does the trick. Task-number: QTBUG-33951 Change-Id: I2790990ca1d3a3016ec3d9fefaea7002b92faeb7 Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@digia.com> Reviewed-by: Shawn Rutledge <shawn.rutledge@digia.com>
Diffstat (limited to 'src/quick/scenegraph')
-rw-r--r--src/quick/scenegraph/qsgdefaultdistancefieldglyphcache.cpp55
-rw-r--r--src/quick/scenegraph/qsgdefaultdistancefieldglyphcache_p.h3
2 files changed, 50 insertions, 8 deletions
diff --git a/src/quick/scenegraph/qsgdefaultdistancefieldglyphcache.cpp b/src/quick/scenegraph/qsgdefaultdistancefieldglyphcache.cpp
index 635f07f2ea..25ff98bc67 100644
--- a/src/quick/scenegraph/qsgdefaultdistancefieldglyphcache.cpp
+++ b/src/quick/scenegraph/qsgdefaultdistancefieldglyphcache.cpp
@@ -167,7 +167,7 @@ void QSGDefaultDistanceFieldGlyphCache::storeGlyphs(const QList<QDistanceField>
if (glyph.width() != expectedWidth)
glyph = glyph.copy(0, 0, expectedWidth, glyph.height());
- if (useWorkaround()) {
+ if (useTextureResizeWorkaround()) {
uchar *inBits = glyph.scanLine(0);
uchar *outBits = texInfo->image.scanLine(int(c.y)) + int(c.x);
for (int y = 0; y < glyph.height(); ++y) {
@@ -177,7 +177,19 @@ void QSGDefaultDistanceFieldGlyphCache::storeGlyphs(const QList<QDistanceField>
}
}
- glTexSubImage2D(GL_TEXTURE_2D, 0, c.x, c.y, glyph.width(), glyph.height(), GL_ALPHA, GL_UNSIGNED_BYTE, glyph.constBits());
+ if (useTextureUploadWorkaround()) {
+ for (int i = 0; i < glyph.height(); ++i) {
+ glTexSubImage2D(GL_TEXTURE_2D, 0,
+ c.x, c.y + i, glyph.width(),1,
+ GL_ALPHA, GL_UNSIGNED_BYTE,
+ glyph.scanLine(i));
+ }
+ } else {
+ glTexSubImage2D(GL_TEXTURE_2D, 0,
+ c.x, c.y, glyph.width(), glyph.height(),
+ GL_ALPHA, GL_UNSIGNED_BYTE,
+ glyph.constBits());
+ }
}
// restore to previous alignment
@@ -204,7 +216,7 @@ void QSGDefaultDistanceFieldGlyphCache::releaseGlyphs(const QSet<glyph_t> &glyph
void QSGDefaultDistanceFieldGlyphCache::createTexture(TextureInfo *texInfo, int width, int height)
{
- if (useWorkaround() && texInfo->image.isNull())
+ if (useTextureResizeWorkaround() && texInfo->image.isNull())
texInfo->image = QDistanceField(width, height);
while (glGetError() != GL_NO_ERROR) { }
@@ -255,12 +267,24 @@ void QSGDefaultDistanceFieldGlyphCache::resizeTexture(TextureInfo *texInfo, int
updateTexture(oldTexture, texInfo->texture, texInfo->size);
- if (useWorkaround()) {
+ if (useTextureResizeWorkaround()) {
GLint alignment = 4; // default value
glGetIntegerv(GL_UNPACK_ALIGNMENT, &alignment);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
- glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, oldWidth, oldHeight, GL_ALPHA, GL_UNSIGNED_BYTE, texInfo->image.constBits());
+ if (useTextureUploadWorkaround()) {
+ for (int i = 0; i < texInfo->image.height(); ++i) {
+ glTexSubImage2D(GL_TEXTURE_2D, 0,
+ 0, i, oldWidth, 1,
+ GL_ALPHA, GL_UNSIGNED_BYTE,
+ texInfo->image.scanLine(i));
+ }
+ } else {
+ glTexSubImage2D(GL_TEXTURE_2D, 0,
+ 0, 0, oldWidth, oldHeight,
+ GL_ALPHA, GL_UNSIGNED_BYTE,
+ texInfo->image.constBits());
+ }
glPixelStorei(GL_UNPACK_ALIGNMENT, alignment); // restore to previous value
@@ -334,7 +358,12 @@ void QSGDefaultDistanceFieldGlyphCache::resizeTexture(TextureInfo *texInfo, int
glBindTexture(GL_TEXTURE_2D, texInfo->texture);
- glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, oldWidth, oldHeight);
+ if (useTextureUploadWorkaround()) {
+ for (int i = 0; i < oldHeight; ++i)
+ glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, i, 0, i, oldWidth, 1);
+ } else {
+ glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, oldWidth, oldHeight);
+ }
ctx->functions()->glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
GL_RENDERBUFFER, 0);
@@ -359,7 +388,7 @@ void QSGDefaultDistanceFieldGlyphCache::resizeTexture(TextureInfo *texInfo, int
m_blitProgram->disableAttributeArray(int(QT_TEXTURE_COORDS_ATTR));
}
-bool QSGDefaultDistanceFieldGlyphCache::useWorkaround() const
+bool QSGDefaultDistanceFieldGlyphCache::useTextureResizeWorkaround() const
{
static bool set = false;
static bool useWorkaround = false;
@@ -372,6 +401,18 @@ bool QSGDefaultDistanceFieldGlyphCache::useWorkaround() const
return useWorkaround;
}
+bool QSGDefaultDistanceFieldGlyphCache::useTextureUploadWorkaround() const
+{
+ static bool set = false;
+ static bool useWorkaround = false;
+ if (!set) {
+ useWorkaround = qstrcmp(reinterpret_cast<const char*>(glGetString(GL_RENDERER)),
+ "Mali-400 MP") == 0;
+ set = true;
+ }
+ return useWorkaround;
+}
+
int QSGDefaultDistanceFieldGlyphCache::maxTextureSize() const
{
if (!m_maxTextureSize)
diff --git a/src/quick/scenegraph/qsgdefaultdistancefieldglyphcache_p.h b/src/quick/scenegraph/qsgdefaultdistancefieldglyphcache_p.h
index 54b0bcb889..3fee6c9ef3 100644
--- a/src/quick/scenegraph/qsgdefaultdistancefieldglyphcache_p.h
+++ b/src/quick/scenegraph/qsgdefaultdistancefieldglyphcache_p.h
@@ -62,7 +62,8 @@ public:
void referenceGlyphs(const QSet<glyph_t> &glyphs);
void releaseGlyphs(const QSet<glyph_t> &glyphs);
- bool useWorkaround() const;
+ bool useTextureResizeWorkaround() const;
+ bool useTextureUploadWorkaround() const;
int maxTextureSize() const;
void setMaxTextureCount(int max) { m_maxTextureCount = max; }