aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEirik Aavitsland <eirik.aavitsland@qt.io>2020-06-11 13:42:55 +0200
committerEirik Aavitsland <eirik.aavitsland@qt.io>2020-06-12 12:23:21 +0200
commit26c6d776783902e75148d67936cb0c382befd7ef (patch)
tree9740fedfbb6e37d42881b8d40a23a2af8ac73f2e
parentfab48743f0f596afc00faa3bdb68736c594eaf64 (diff)
Port distancefield debugging code from OpenGL to RHI
Task-number: QTBUG-84623 Change-Id: I26941eacf5ad97ed3c7c6e7d7ad3beec7f0c6fa3 Reviewed-by: Laszlo Agocs <laszlo.agocs@qt.io>
-rw-r--r--src/quick/scenegraph/qsgadaptationlayer.cpp159
-rw-r--r--src/quick/scenegraph/qsgadaptationlayer_p.h2
-rw-r--r--src/quick/scenegraph/qsgrhidistancefieldglyphcache.cpp36
-rw-r--r--src/quick/scenegraph/qsgrhidistancefieldglyphcache_p.h4
4 files changed, 42 insertions, 159 deletions
diff --git a/src/quick/scenegraph/qsgadaptationlayer.cpp b/src/quick/scenegraph/qsgadaptationlayer.cpp
index 3ee5d6fdb7..226c580fb2 100644
--- a/src/quick/scenegraph/qsgadaptationlayer.cpp
+++ b/src/quick/scenegraph/qsgadaptationlayer.cpp
@@ -206,7 +206,7 @@ void QSGDistanceFieldGlyphCache::update()
#if defined(QSG_DISTANCEFIELD_CACHE_DEBUG)
for (Texture texture : qAsConst(m_textures))
- saveTexture(texture.textureId, texture.size.width(), texture.size.height());
+ saveTexture(texture.texture, m_referenceFont.familyName());
#endif
if (QSG_LOG_TIME_GLYPH().isDebugEnabled()) {
@@ -315,163 +315,6 @@ void QSGDistanceFieldGlyphCache::updateRhiTexture(QRhiTexture *oldTex, QRhiTextu
}
}
-#if defined(QSG_DISTANCEFIELD_CACHE_DEBUG)
-#include <qopenglfunctions.h>
-
-void QSGDistanceFieldGlyphCache::saveTexture(GLuint textureId, int width, int height) const
-{
- QOpenGLFunctions *functions = QOpenGLContext::currentContext()->functions();
-
- GLuint fboId;
- functions->glGenFramebuffers(1, &fboId);
-
- GLuint tmpTexture = 0;
- functions->glGenTextures(1, &tmpTexture);
- functions->glBindTexture(GL_TEXTURE_2D, tmpTexture);
- functions->glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
- functions->glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- functions->glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- functions->glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- functions->glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- functions->glBindTexture(GL_TEXTURE_2D, 0);
-
- functions->glBindFramebuffer(GL_FRAMEBUFFER_EXT, fboId);
- functions->glFramebufferTexture2D(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D,
- tmpTexture, 0);
-
- functions->glActiveTexture(GL_TEXTURE0);
- functions->glBindTexture(GL_TEXTURE_2D, textureId);
-
- functions->glDisable(GL_STENCIL_TEST);
- functions->glDisable(GL_DEPTH_TEST);
- functions->glDisable(GL_SCISSOR_TEST);
- functions->glDisable(GL_BLEND);
-
- GLfloat textureCoordinateArray[8];
- textureCoordinateArray[0] = 0.0f;
- textureCoordinateArray[1] = 0.0f;
- textureCoordinateArray[2] = 1.0f;
- textureCoordinateArray[3] = 0.0f;
- textureCoordinateArray[4] = 1.0f;
- textureCoordinateArray[5] = 1.0f;
- textureCoordinateArray[6] = 0.0f;
- textureCoordinateArray[7] = 1.0f;
-
- GLfloat vertexCoordinateArray[8];
- vertexCoordinateArray[0] = -1.0f;
- vertexCoordinateArray[1] = -1.0f;
- vertexCoordinateArray[2] = 1.0f;
- vertexCoordinateArray[3] = -1.0f;
- vertexCoordinateArray[4] = 1.0f;
- vertexCoordinateArray[5] = 1.0f;
- vertexCoordinateArray[6] = -1.0f;
- vertexCoordinateArray[7] = 1.0f;
-
- functions->glViewport(0, 0, width, height);
- functions->glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, vertexCoordinateArray);
- functions->glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, textureCoordinateArray);
-
- {
- static const char *vertexShaderSource =
- "attribute vec4 vertexCoordsArray; \n"
- "attribute vec2 textureCoordArray; \n"
- "varying vec2 textureCoords; \n"
- "void main(void) \n"
- "{ \n"
- " gl_Position = vertexCoordsArray; \n"
- " textureCoords = textureCoordArray; \n"
- "} \n";
-
- static const char *fragmentShaderSource =
- "varying vec2 textureCoords; \n"
- "uniform sampler2D texture; \n"
- "void main() \n"
- "{ \n"
- " gl_FragColor = texture2D(texture, textureCoords); \n"
- "} \n";
-
- GLuint vertexShader = functions->glCreateShader(GL_VERTEX_SHADER);
- GLuint fragmentShader = functions->glCreateShader(GL_FRAGMENT_SHADER);
-
- if (vertexShader == 0 || fragmentShader == 0) {
- GLenum error = functions->glGetError();
- qWarning("QSGDistanceFieldGlyphCache::saveTexture: Failed to create shaders. (GL error: %x)",
- error);
- return;
- }
-
- functions->glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);
- functions->glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);
- functions->glCompileShader(vertexShader);
-
- GLint len = 1;
- functions->glGetShaderiv(vertexShader, GL_INFO_LOG_LENGTH, &len);
-
- char infoLog[2048];
- functions->glGetShaderInfoLog(vertexShader, 2048, NULL, infoLog);
- if (qstrlen(infoLog) > 0)
- qWarning("Problems compiling vertex shader:\n %s", infoLog);
-
- functions->glCompileShader(fragmentShader);
- functions->glGetShaderInfoLog(fragmentShader, 2048, NULL, infoLog);
- if (qstrlen(infoLog) > 0)
- qWarning("Problems compiling fragment shader:\n %s", infoLog);
-
- GLuint shaderProgram = functions->glCreateProgram();
- functions->glAttachShader(shaderProgram, vertexShader);
- functions->glAttachShader(shaderProgram, fragmentShader);
-
- functions->glBindAttribLocation(shaderProgram, 0, "vertexCoordsArray");
- functions->glBindAttribLocation(shaderProgram, 1, "textureCoordArray");
-
- functions->glLinkProgram(shaderProgram);
- functions->glGetProgramInfoLog(shaderProgram, 2048, NULL, infoLog);
- if (qstrlen(infoLog) > 0)
- qWarning("Problems linking shaders:\n %s", infoLog);
-
- functions->glUseProgram(shaderProgram);
- functions->glEnableVertexAttribArray(0);
- functions->glEnableVertexAttribArray(1);
-
- int textureUniformLocation = functions->glGetUniformLocation(shaderProgram, "texture");
- functions->glUniform1i(textureUniformLocation, 0);
- }
-
- functions->glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
-
- {
- GLenum error = functions->glGetError();
- if (error != GL_NO_ERROR)
- qWarning("glDrawArrays reported error 0x%x", error);
- }
-
- uchar *data = new uchar[width * height * 4];
-
- functions->glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, data);
-
- QImage image(data, width, height, QImage::Format_ARGB32);
-
- QByteArray fileName = m_referenceFont.familyName().toLatin1() + '_' + QByteArray::number(textureId);
- fileName = fileName.replace('/', '_').replace(' ', '_') + ".png";
-
- image.save(QString::fromLocal8Bit(fileName));
-
- {
- GLenum error = functions->glGetError();
- if (error != GL_NO_ERROR)
- qWarning("glReadPixels reported error 0x%x", error);
- }
-
- functions->glDisableVertexAttribArray(0);
- functions->glDisableVertexAttribArray(1);
-
- functions->glDeleteFramebuffers(1, &fboId);
- functions->glDeleteTextures(1, &tmpTexture);
-
- delete[] data;
-}
-#endif
-
void QSGNodeVisitorEx::visitChildren(QSGNode *node)
{
for (QSGNode *child = node->firstChild(); child; child = child->nextSibling()) {
diff --git a/src/quick/scenegraph/qsgadaptationlayer_p.h b/src/quick/scenegraph/qsgadaptationlayer_p.h
index 31f90bd0b2..657678ec37 100644
--- a/src/quick/scenegraph/qsgadaptationlayer_p.h
+++ b/src/quick/scenegraph/qsgadaptationlayer_p.h
@@ -520,7 +520,7 @@ protected:
GlyphData &emptyData(glyph_t glyph);
#if defined(QSG_DISTANCEFIELD_CACHE_DEBUG)
- void saveTexture(GLuint textureId, int width, int height) const;
+ virtual void saveTexture(QRhiTexture *texture, const QString &nameBase) const = 0;
#endif
bool m_doubleGlyphResolution;
diff --git a/src/quick/scenegraph/qsgrhidistancefieldglyphcache.cpp b/src/quick/scenegraph/qsgrhidistancefieldglyphcache.cpp
index 6e7e2b5118..91eda8ebfc 100644
--- a/src/quick/scenegraph/qsgrhidistancefieldglyphcache.cpp
+++ b/src/quick/scenegraph/qsgrhidistancefieldglyphcache.cpp
@@ -565,4 +565,40 @@ bool QSGRhiDistanceFieldGlyphCache::eightBitFormatIsAlphaSwizzled() const
return !m_rhi->isFeatureSupported(QRhi::RedOrAlpha8IsRed);
}
+#if defined(QSG_DISTANCEFIELD_CACHE_DEBUG)
+void QSGRhiDistanceFieldGlyphCache::saveTexture(QRhiTexture *texture, const QString &nameBase) const
+{
+ quint64 textureId = texture->nativeTexture().object;
+ QString fileName = nameBase + QLatin1Char('_') + QString::number(textureId, 16);
+ fileName.replace(QLatin1Char('/'), QLatin1Char('_'));
+ fileName.replace(QLatin1Char(' '), QLatin1Char('_'));
+ fileName.append(QLatin1String(".png"));
+
+ QRhiReadbackResult *rbResult = new QRhiReadbackResult;
+ rbResult->completed = [rbResult, fileName] {
+ const QSize size = rbResult->pixelSize;
+ const qint64 numPixels = qint64(size.width()) * size.height();
+ if (numPixels == rbResult->data.size()) {
+ // 1 bpp data, may be packed; copy it to ensure QImage scanline alignment
+ QImage image(size, QImage::Format_Grayscale8);
+ const char *p = rbResult->data.constData();
+ for (int i = 0; i < size.height(); i++)
+ memcpy(image.scanLine(i), p + (i * size.width()), size.width());
+ image.save(fileName);
+ } else if (4 * numPixels == rbResult->data.size()) {
+ // 4 bpp data
+ const uchar *p = reinterpret_cast<const uchar *>(rbResult->data.constData());
+ QImage image(p, size.width(), size.height(), QImage::Format_RGBA8888);
+ image.save(fileName);
+ } else {
+ qWarning("Unhandled data format in glyph texture");
+ }
+ delete rbResult;
+ };
+
+ QRhiReadbackDescription rb(texture);
+ m_resourceUpdates->readBackTexture(rb, rbResult);
+}
+#endif
+
QT_END_NAMESPACE
diff --git a/src/quick/scenegraph/qsgrhidistancefieldglyphcache_p.h b/src/quick/scenegraph/qsgrhidistancefieldglyphcache_p.h
index d43b0aa5d4..6441188dfe 100644
--- a/src/quick/scenegraph/qsgrhidistancefieldglyphcache_p.h
+++ b/src/quick/scenegraph/qsgrhidistancefieldglyphcache_p.h
@@ -79,6 +79,10 @@ public:
bool eightBitFormatIsAlphaSwizzled() const override;
+#if defined(QSG_DISTANCEFIELD_CACHE_DEBUG)
+ void saveTexture(QRhiTexture *texture, const QString &nameBase) const override;
+#endif
+
private:
bool loadPregeneratedCache(const QRawFont &font);