diff options
Diffstat (limited to 'recipes/qt4/qt-4.6.0/1198-Handle-broken-shaders-better-in-the-GL2-engine-s-sha.patch')
-rw-r--r-- | recipes/qt4/qt-4.6.0/1198-Handle-broken-shaders-better-in-the-GL2-engine-s-sha.patch | 269 |
1 files changed, 269 insertions, 0 deletions
diff --git a/recipes/qt4/qt-4.6.0/1198-Handle-broken-shaders-better-in-the-GL2-engine-s-sha.patch b/recipes/qt4/qt-4.6.0/1198-Handle-broken-shaders-better-in-the-GL2-engine-s-sha.patch new file mode 100644 index 0000000000..d81051dd9b --- /dev/null +++ b/recipes/qt4/qt-4.6.0/1198-Handle-broken-shaders-better-in-the-GL2-engine-s-sha.patch @@ -0,0 +1,269 @@ +From b784d4991b186037ccd2b60ae3101697a2251160 Mon Sep 17 00:00:00 2001 +From: Tom Cooksey <thomas.cooksey@nokia.com> +Date: Tue, 22 Dec 2009 09:10:14 +0100 +Subject: [PATCH 1198/1244] Handle broken shaders better in the GL2 engine's shader manager + +The shader manager will now a) not seg-fault and b) actually tell you +which shader has the error. + +Reviewed-By: Kim +--- + .../gl2paintengineex/qglengineshadermanager.cpp | 191 ++++++++++++-------- + 1 files changed, 114 insertions(+), 77 deletions(-) + +diff --git a/src/opengl/gl2paintengineex/qglengineshadermanager.cpp b/src/opengl/gl2paintengineex/qglengineshadermanager.cpp +index 1187c2d..9d545b9 100644 +--- a/src/opengl/gl2paintengineex/qglengineshadermanager.cpp ++++ b/src/opengl/gl2paintengineex/qglengineshadermanager.cpp +@@ -170,13 +170,15 @@ QGLEngineSharedShaders::QGLEngineSharedShaders(const QGLContext* context) + source.append(qShaderSnippets[MainVertexShader]); + source.append(qShaderSnippets[PositionOnlyVertexShader]); + vertexShader = new QGLShader(QGLShader::Vertex, context, this); +- vertexShader->compileSourceCode(source); ++ if (!vertexShader->compileSourceCode(source)) ++ qWarning("Vertex shader for simpleShaderProg (MainVertexShader & PositionOnlyVertexShader) failed to compile"); + + source.clear(); + source.append(qShaderSnippets[MainFragmentShader]); + source.append(qShaderSnippets[ShockingPinkSrcFragmentShader]); + fragShader = new QGLShader(QGLShader::Fragment, context, this); +- fragShader->compileSourceCode(source); ++ if (!fragShader->compileSourceCode(source)) ++ qWarning("Fragment shader for simpleShaderProg (MainFragmentShader & ShockingPinkSrcFragmentShader) failed to compile"); + + simpleShaderProg = new QGLShaderProgram(context, this); + simpleShaderProg->addShader(vertexShader); +@@ -193,13 +195,15 @@ QGLEngineSharedShaders::QGLEngineSharedShaders(const QGLContext* context) + source.append(qShaderSnippets[MainWithTexCoordsVertexShader]); + source.append(qShaderSnippets[UntransformedPositionVertexShader]); + vertexShader = new QGLShader(QGLShader::Vertex, context, this); +- vertexShader->compileSourceCode(source); ++ if (!vertexShader->compileSourceCode(source)) ++ qWarning("Vertex shader for blitShaderProg (MainWithTexCoordsVertexShader & UntransformedPositionVertexShader) failed to compile"); + + source.clear(); + source.append(qShaderSnippets[MainFragmentShader]); + source.append(qShaderSnippets[ImageSrcFragmentShader]); + fragShader = new QGLShader(QGLShader::Fragment, context, this); +- fragShader->compileSourceCode(source); ++ if (!fragShader->compileSourceCode(source)) ++ qWarning("Fragment shader for blitShaderProg (MainFragmentShader & ImageSrcFragmentShader) failed to compile"); + + blitShaderProg = new QGLShaderProgram(context, this); + blitShaderProg->addShader(vertexShader); +@@ -234,84 +238,95 @@ QGLEngineShaderProg *QGLEngineSharedShaders::findProgramInCache(const QGLEngineS + } + } + +- QByteArray source; +- source.append(qShaderSnippets[prog.mainFragShader]); +- source.append(qShaderSnippets[prog.srcPixelFragShader]); +- if (prog.srcPixelFragShader == CustomImageSrcFragmentShader) +- source.append(prog.customStageSource); +- if (prog.compositionFragShader) +- source.append(qShaderSnippets[prog.compositionFragShader]); +- if (prog.maskFragShader) +- source.append(qShaderSnippets[prog.maskFragShader]); +- QGLShader* fragShader = new QGLShader(QGLShader::Fragment, ctxGuard.context(), this); +- fragShader->compileSourceCode(source); +- +- source.clear(); +- source.append(qShaderSnippets[prog.mainVertexShader]); +- source.append(qShaderSnippets[prog.positionVertexShader]); +- QGLShader* vertexShader = new QGLShader(QGLShader::Vertex, ctxGuard.context(), this); +- vertexShader->compileSourceCode(source); ++ QGLShader *vertexShader = 0; ++ QGLShader *fragShader = 0; ++ QGLEngineShaderProg *newProg = 0; ++ bool success = false; ++ ++ do { ++ QByteArray source; ++ source.append(qShaderSnippets[prog.mainFragShader]); ++ source.append(qShaderSnippets[prog.srcPixelFragShader]); ++ if (prog.srcPixelFragShader == CustomImageSrcFragmentShader) ++ source.append(prog.customStageSource); ++ if (prog.compositionFragShader) ++ source.append(qShaderSnippets[prog.compositionFragShader]); ++ if (prog.maskFragShader) ++ source.append(qShaderSnippets[prog.maskFragShader]); ++ fragShader = new QGLShader(QGLShader::Fragment, ctxGuard.context(), this); ++ QByteArray description; ++#if defined(QT_DEBUG) ++ // Name the shader for easier debugging ++ description.append("Fragment shader: main="); ++ description.append(snippetNameStr(prog.mainFragShader)); ++ description.append(", srcPixel="); ++ description.append(snippetNameStr(prog.srcPixelFragShader)); ++ if (prog.compositionFragShader) { ++ description.append(", composition="); ++ description.append(snippetNameStr(prog.compositionFragShader)); ++ } ++ if (prog.maskFragShader) { ++ description.append(", mask="); ++ description.append(snippetNameStr(prog.maskFragShader)); ++ } ++ fragShader->setObjectName(QString::fromLatin1(description)); ++#endif ++ if (!fragShader->compileSourceCode(source)) { ++ qWarning() << "Warning:" << description << "failed to compile!"; ++ break; ++ } + ++ source.clear(); ++ source.append(qShaderSnippets[prog.mainVertexShader]); ++ source.append(qShaderSnippets[prog.positionVertexShader]); ++ vertexShader = new QGLShader(QGLShader::Vertex, ctxGuard.context(), this); + #if defined(QT_DEBUG) +- // Name the shaders for easier debugging +- QByteArray description; +- description.append("Fragment shader: main="); +- description.append(snippetNameStr(prog.mainFragShader)); +- description.append(", srcPixel="); +- description.append(snippetNameStr(prog.srcPixelFragShader)); +- if (prog.compositionFragShader) { +- description.append(", composition="); +- description.append(snippetNameStr(prog.compositionFragShader)); +- } +- if (prog.maskFragShader) { +- description.append(", mask="); +- description.append(snippetNameStr(prog.maskFragShader)); +- } +- fragShader->setObjectName(QString::fromLatin1(description)); +- +- description.clear(); +- description.append("Vertex shader: main="); +- description.append(snippetNameStr(prog.mainVertexShader)); +- description.append(", position="); +- description.append(snippetNameStr(prog.positionVertexShader)); +- vertexShader->setObjectName(QString::fromLatin1(description)); ++ // Name the shader for easier debugging ++ description.clear(); ++ description.append("Vertex shader: main="); ++ description.append(snippetNameStr(prog.mainVertexShader)); ++ description.append(", position="); ++ description.append(snippetNameStr(prog.positionVertexShader)); ++ vertexShader->setObjectName(QString::fromLatin1(description)); + #endif ++ if (!vertexShader->compileSourceCode(source)) { ++ qWarning() << "Warning:" << description << "failed to compile!"; ++ break; ++ } + +- QGLEngineShaderProg* newProg = new QGLEngineShaderProg(prog); +- +- // If the shader program's not found in the cache, create it now. +- newProg->program = new QGLShaderProgram(ctxGuard.context(), this); +- newProg->program->addShader(vertexShader); +- newProg->program->addShader(fragShader); +- +- // We have to bind the vertex attribute names before the program is linked: +- newProg->program->bindAttributeLocation("vertexCoordsArray", QT_VERTEX_COORDS_ATTR); +- if (newProg->useTextureCoords) +- newProg->program->bindAttributeLocation("textureCoordArray", QT_TEXTURE_COORDS_ATTR); +- if (newProg->useOpacityAttribute) +- newProg->program->bindAttributeLocation("opacityArray", QT_OPACITY_ATTR); +- +- newProg->program->link(); +- if (!newProg->program->isLinked()) { +- QLatin1String none("none"); +- QLatin1String br("\n"); +- QString error; +- error = QLatin1String("Shader program failed to link,") ++ newProg = new QGLEngineShaderProg(prog); ++ ++ // If the shader program's not found in the cache, create it now. ++ newProg->program = new QGLShaderProgram(ctxGuard.context(), this); ++ newProg->program->addShader(vertexShader); ++ newProg->program->addShader(fragShader); ++ ++ // We have to bind the vertex attribute names before the program is linked: ++ newProg->program->bindAttributeLocation("vertexCoordsArray", QT_VERTEX_COORDS_ATTR); ++ if (newProg->useTextureCoords) ++ newProg->program->bindAttributeLocation("textureCoordArray", QT_TEXTURE_COORDS_ATTR); ++ if (newProg->useOpacityAttribute) ++ newProg->program->bindAttributeLocation("opacityArray", QT_OPACITY_ATTR); ++ ++ newProg->program->link(); ++ if (!newProg->program->isLinked()) { ++ QLatin1String none("none"); ++ QLatin1String br("\n"); ++ QString error; ++ error = QLatin1String("Shader program failed to link,") + #if defined(QT_DEBUG) +- + br +- + QLatin1String(" Shaders Used:") + br +- + QLatin1String(" ") + vertexShader->objectName() + QLatin1String(": ") + br +- + QLatin1String(vertexShader->sourceCode()) + br +- + QLatin1String(" ") + fragShader->objectName() + QLatin1String(": ") + br +- + QLatin1String(fragShader->sourceCode()) + br ++ + br ++ + QLatin1String(" Shaders Used:") + br ++ + QLatin1String(" ") + vertexShader->objectName() + QLatin1String(": ") + br ++ + QLatin1String(vertexShader->sourceCode()) + br ++ + QLatin1String(" ") + fragShader->objectName() + QLatin1String(": ") + br ++ + QLatin1String(fragShader->sourceCode()) + br + #endif +- + QLatin1String(" Error Log:\n") +- + QLatin1String(" ") + newProg->program->log(); +- qWarning() << error; +- delete newProg; // Deletes the QGLShaderProgram in it's destructor +- newProg = 0; +- } +- else { ++ + QLatin1String(" Error Log:\n") ++ + QLatin1String(" ") + newProg->program->log(); ++ qWarning() << error; ++ break; ++ } + if (cachedPrograms.count() > 30) { + // The cache is full, so delete the last 5 programs in the list. + // These programs will be least used, as a program us bumped to +@@ -323,6 +338,22 @@ QGLEngineShaderProg *QGLEngineSharedShaders::findProgramInCache(const QGLEngineS + } + + cachedPrograms.insert(0, newProg); ++ ++ success = true; ++ } while (false); ++ ++ // Clean up everything if we weren't successful ++ if (!success) { ++ if (newProg) { ++ delete newProg; // Also deletes the QGLShaderProgram which in turn deletes the QGLShaders ++ newProg = 0; ++ } ++ else { ++ if (vertexShader) ++ delete vertexShader; ++ if (fragShader) ++ delete fragShader; ++ } + } + + return newProg; +@@ -364,6 +395,9 @@ QGLEngineShaderManager::~QGLEngineShaderManager() + + uint QGLEngineShaderManager::getUniformLocation(Uniform id) + { ++ if (!currentShaderProg) ++ return 0; ++ + QVector<uint> &uniformLocations = currentShaderProg->uniformLocations; + if (uniformLocations.isEmpty()) + uniformLocations.fill(GLuint(-1), NumUniforms); +@@ -468,7 +502,10 @@ void QGLEngineShaderManager::removeCustomStage() + + QGLShaderProgram* QGLEngineShaderManager::currentProgram() + { +- return currentShaderProg->program; ++ if (currentShaderProg) ++ return currentShaderProg->program; ++ else ++ return simpleProgram(); + } + + QGLShaderProgram* QGLEngineShaderManager::simpleProgram() +-- +1.6.5 + |