aboutsummaryrefslogtreecommitdiffstats
path: root/src/quick/scenegraph/qsgadaptationlayer.cpp
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@theqtcompany.com>2014-12-09 15:09:20 +0100
committerSimon Hausmann <simon.hausmann@theqtcompany.com>2014-12-09 15:09:26 +0100
commitff466a1881435f927f5df9ce1e5eac07d5591904 (patch)
tree760e068743e6a8e1cc4ec63bb2f8e7dcef88b3e2 /src/quick/scenegraph/qsgadaptationlayer.cpp
parente04822f3c2a6b69b7d75e2039256aa2433c59dd2 (diff)
parent4a3f6e58b591f2fe2204f7cbc1efc8abb0aade74 (diff)
Merge remote-tracking branch 'origin/5.4' into dev
Conflicts: src/qml/jsruntime/qv4arraydata.cpp src/qml/jsruntime/qv4context_p.h src/qml/jsruntime/qv4globalobject.cpp src/qml/jsruntime/qv4internalclass.cpp src/quick/items/qquicktext_p.h src/quick/items/qquicktextedit_p.h src/quick/items/qquicktextinput_p.h Change-Id: If07e483e03197cb997ef47a9c647a479cdb09f4c
Diffstat (limited to 'src/quick/scenegraph/qsgadaptationlayer.cpp')
-rw-r--r--src/quick/scenegraph/qsgadaptationlayer.cpp162
1 files changed, 162 insertions, 0 deletions
diff --git a/src/quick/scenegraph/qsgadaptationlayer.cpp b/src/quick/scenegraph/qsgadaptationlayer.cpp
index e0b96a45b6..7ddfdeb2d4 100644
--- a/src/quick/scenegraph/qsgadaptationlayer.cpp
+++ b/src/quick/scenegraph/qsgadaptationlayer.cpp
@@ -175,6 +175,11 @@ void QSGDistanceFieldGlyphCache::update()
storeGlyphs(distanceFields);
+#if defined(QSG_DISTANCEFIELD_CACHE_DEBUG)
+ foreach (Texture texture, m_textures)
+ saveTexture(texture.textureId, texture.size.width(), texture.size.height());
+#endif
+
if (QSG_LOG_TIME_GLYPH().isDebugEnabled()) {
quint64 now = qsg_render_timer.elapsed();
qCDebug(QSG_LOG_TIME_GLYPH,
@@ -283,6 +288,163 @@ void QSGDistanceFieldGlyphCache::updateTexture(GLuint oldTex, GLuint newTex, con
}
}
+#if defined(QSG_DISTANCEFIELD_CACHE_DEBUG)
+#include <QtGui/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()) {