Commit 4f63f43c by Yoann Lopes Committed by The Qt Project

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: 's avatarEskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@digia.com>
Reviewed-by: 's avatarShawn Rutledge <shawn.rutledge@digia.com>
parent 040c835d
......@@ -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)
......
......@@ -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; }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment