summaryrefslogtreecommitdiffstats
path: root/src/gui/opengl/qopenglengineshadermanager.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui/opengl/qopenglengineshadermanager.cpp')
-rw-r--r--src/gui/opengl/qopenglengineshadermanager.cpp199
1 files changed, 106 insertions, 93 deletions
diff --git a/src/gui/opengl/qopenglengineshadermanager.cpp b/src/gui/opengl/qopenglengineshadermanager.cpp
index 1d3e47f93b..dd9e8e9d1e 100644
--- a/src/gui/opengl/qopenglengineshadermanager.cpp
+++ b/src/gui/opengl/qopenglengineshadermanager.cpp
@@ -126,11 +126,65 @@ QOpenGLEngineSharedShaders::QOpenGLEngineSharedShaders(QOpenGLContext* context)
around without having to change the order of the glsl strings. It is hoped this will
make future hard-to-find runtime bugs more obvious and generally give more solid code.
*/
- static bool snippetsPopulated = false;
- if (!snippetsPopulated) {
- const char** code = qShaderSnippets; // shortcut
+ // Check if the user has requested an OpenGL 3.2 Core Profile or higher
+ // and if so use GLSL 1.50 core shaders instead of legacy ones.
+ const QSurfaceFormat &fmt = context->format();
+ const bool isCoreProfile = fmt.profile() == QSurfaceFormat::CoreProfile && fmt.version() >= qMakePair(3,2);
+
+ const char** code = qShaderSnippets; // shortcut
+
+ if (isCoreProfile) {
+ code[MainVertexShader] = qopenglslMainVertexShader_core;
+ code[MainWithTexCoordsVertexShader] = qopenglslMainWithTexCoordsVertexShader_core;
+ code[MainWithTexCoordsAndOpacityVertexShader] = qopenglslMainWithTexCoordsAndOpacityVertexShader_core;
+
+ code[UntransformedPositionVertexShader] = qopenglslUntransformedPositionVertexShader_core;
+ code[PositionOnlyVertexShader] = qopenglslPositionOnlyVertexShader_core;
+ code[ComplexGeometryPositionOnlyVertexShader] = qopenglslComplexGeometryPositionOnlyVertexShader_core;
+ code[PositionWithPatternBrushVertexShader] = qopenglslPositionWithPatternBrushVertexShader_core;
+ code[PositionWithLinearGradientBrushVertexShader] = qopenglslPositionWithLinearGradientBrushVertexShader_core;
+ code[PositionWithConicalGradientBrushVertexShader] = qopenglslPositionWithConicalGradientBrushVertexShader_core;
+ code[PositionWithRadialGradientBrushVertexShader] = qopenglslPositionWithRadialGradientBrushVertexShader_core;
+ code[PositionWithTextureBrushVertexShader] = qopenglslPositionWithTextureBrushVertexShader_core;
+ code[AffinePositionWithPatternBrushVertexShader] = qopenglslAffinePositionWithPatternBrushVertexShader_core;
+ code[AffinePositionWithLinearGradientBrushVertexShader] = qopenglslAffinePositionWithLinearGradientBrushVertexShader_core;
+ code[AffinePositionWithConicalGradientBrushVertexShader] = qopenglslAffinePositionWithConicalGradientBrushVertexShader_core;
+ code[AffinePositionWithRadialGradientBrushVertexShader] = qopenglslAffinePositionWithRadialGradientBrushVertexShader_core;
+ code[AffinePositionWithTextureBrushVertexShader] = qopenglslAffinePositionWithTextureBrushVertexShader_core;
+
+ code[MainFragmentShader_CMO] = qopenglslMainFragmentShader_CMO_core;
+ code[MainFragmentShader_CM] = qopenglslMainFragmentShader_CM_core;
+ code[MainFragmentShader_MO] = qopenglslMainFragmentShader_MO_core;
+ code[MainFragmentShader_M] = qopenglslMainFragmentShader_M_core;
+ code[MainFragmentShader_CO] = qopenglslMainFragmentShader_CO_core;
+ code[MainFragmentShader_C] = qopenglslMainFragmentShader_C_core;
+ code[MainFragmentShader_O] = qopenglslMainFragmentShader_O_core;
+ code[MainFragmentShader] = qopenglslMainFragmentShader_core;
+ code[MainFragmentShader_ImageArrays] = qopenglslMainFragmentShader_ImageArrays_core;
+
+ code[ImageSrcFragmentShader] = qopenglslImageSrcFragmentShader_core;
+ code[ImageSrcWithPatternFragmentShader] = qopenglslImageSrcWithPatternFragmentShader_core;
+ code[NonPremultipliedImageSrcFragmentShader] = qopenglslNonPremultipliedImageSrcFragmentShader_core;
+ code[GrayscaleImageSrcFragmentShader] = qopenglslGrayscaleImageSrcFragmentShader_core;
+ code[AlphaImageSrcFragmentShader] = qopenglslAlphaImageSrcFragmentShader_core;
+ code[CustomImageSrcFragmentShader] = qopenglslCustomSrcFragmentShader_core; // Calls "customShader", which must be appended
+ code[SolidBrushSrcFragmentShader] = qopenglslSolidBrushSrcFragmentShader_core;
+
+ code[TextureBrushSrcFragmentShader] = qopenglslTextureBrushSrcFragmentShader_desktop_core;
+ code[TextureBrushSrcWithPatternFragmentShader] = qopenglslTextureBrushSrcWithPatternFragmentShader_core;
+ code[PatternBrushSrcFragmentShader] = qopenglslPatternBrushSrcFragmentShader_core;
+ code[LinearGradientBrushSrcFragmentShader] = qopenglslLinearGradientBrushSrcFragmentShader_core;
+ code[RadialGradientBrushSrcFragmentShader] = qopenglslRadialGradientBrushSrcFragmentShader_core;
+ code[ConicalGradientBrushSrcFragmentShader] = qopenglslConicalGradientBrushSrcFragmentShader_core;
+ code[ShockingPinkSrcFragmentShader] = qopenglslShockingPinkSrcFragmentShader_core;
+ code[NoMaskFragmentShader] = "";
+ code[MaskFragmentShader] = qopenglslMaskFragmentShader_core;
+ code[RgbMaskFragmentShaderPass1] = qopenglslRgbMaskFragmentShaderPass1_core;
+ code[RgbMaskFragmentShaderPass2] = qopenglslRgbMaskFragmentShaderPass2_core;
+ code[RgbMaskWithGammaFragmentShader] = ""; //###
+ } else {
code[MainVertexShader] = qopenglslMainVertexShader;
code[MainWithTexCoordsVertexShader] = qopenglslMainWithTexCoordsVertexShader;
code[MainWithTexCoordsAndOpacityVertexShader] = qopenglslMainWithTexCoordsAndOpacityVertexShader;
@@ -182,34 +236,34 @@ QOpenGLEngineSharedShaders::QOpenGLEngineSharedShaders(QOpenGLContext* context)
code[RgbMaskFragmentShaderPass1] = qopenglslRgbMaskFragmentShaderPass1;
code[RgbMaskFragmentShaderPass2] = qopenglslRgbMaskFragmentShaderPass2;
code[RgbMaskWithGammaFragmentShader] = ""; //###
+ }
- code[NoCompositionModeFragmentShader] = "";
- code[MultiplyCompositionModeFragmentShader] = ""; //###
- code[ScreenCompositionModeFragmentShader] = ""; //###
- code[OverlayCompositionModeFragmentShader] = ""; //###
- code[DarkenCompositionModeFragmentShader] = ""; //###
- code[LightenCompositionModeFragmentShader] = ""; //###
- code[ColorDodgeCompositionModeFragmentShader] = ""; //###
- code[ColorBurnCompositionModeFragmentShader] = ""; //###
- code[HardLightCompositionModeFragmentShader] = ""; //###
- code[SoftLightCompositionModeFragmentShader] = ""; //###
- code[DifferenceCompositionModeFragmentShader] = ""; //###
- code[ExclusionCompositionModeFragmentShader] = ""; //###
+ // These shaders are not implemented yet and therefore are the same
+ // for all profiles. Implementations should make a version for both
+ // profiles and put the appropriate lines in the if-statement above.
+ code[NoCompositionModeFragmentShader] = "";
+ code[MultiplyCompositionModeFragmentShader] = ""; //###
+ code[ScreenCompositionModeFragmentShader] = ""; //###
+ code[OverlayCompositionModeFragmentShader] = ""; //###
+ code[DarkenCompositionModeFragmentShader] = ""; //###
+ code[LightenCompositionModeFragmentShader] = ""; //###
+ code[ColorDodgeCompositionModeFragmentShader] = ""; //###
+ code[ColorBurnCompositionModeFragmentShader] = ""; //###
+ code[HardLightCompositionModeFragmentShader] = ""; //###
+ code[SoftLightCompositionModeFragmentShader] = ""; //###
+ code[DifferenceCompositionModeFragmentShader] = ""; //###
+ code[ExclusionCompositionModeFragmentShader] = ""; //###
#if defined(QT_DEBUG)
- // Check that all the elements have been filled:
- for (int i = 0; i < TotalSnippetCount; ++i) {
- if (Q_UNLIKELY(!qShaderSnippets[i])) {
- qFatal("Shader snippet for %s (#%d) is missing!",
- snippetNameStr(SnippetName(i)).constData(), i);
- }
+ // Check that all the elements have been filled:
+ for (int i = 0; i < TotalSnippetCount; ++i) {
+ if (Q_UNLIKELY(!qShaderSnippets[i])) {
+ qFatal("Shader snippet for %s (#%d) is missing!",
+ snippetNameStr(SnippetName(i)).constData(), i);
}
-#endif
- snippetsPopulated = true;
}
+#endif
- QOpenGLShader* fragShader;
- QOpenGLShader* vertexShader;
QByteArray vertexSource;
QByteArray fragSource;
@@ -227,19 +281,11 @@ QOpenGLEngineSharedShaders::QOpenGLEngineSharedShaders(QOpenGLContext* context)
bool inCache = simpleShaderCache.load(simpleShaderProg, context);
if (!inCache) {
- vertexShader = new QOpenGLShader(QOpenGLShader::Vertex);
- shaders.append(vertexShader);
- if (!vertexShader->compileSourceCode(vertexSource))
+ if (!simpleShaderProg->addCacheableShaderFromSourceCode(QOpenGLShader::Vertex, vertexSource))
qWarning("Vertex shader for simpleShaderProg (MainVertexShader & PositionOnlyVertexShader) failed to compile");
-
- fragShader = new QOpenGLShader(QOpenGLShader::Fragment);
- shaders.append(fragShader);
- if (!fragShader->compileSourceCode(fragSource))
+ if (!simpleShaderProg->addCacheableShaderFromSourceCode(QOpenGLShader::Fragment, fragSource))
qWarning("Fragment shader for simpleShaderProg (MainFragmentShader & ShockingPinkSrcFragmentShader) failed to compile");
- simpleShaderProg->addShader(vertexShader);
- simpleShaderProg->addShader(fragShader);
-
simpleShaderProg->bindAttributeLocation("vertexCoordsArray", QT_VERTEX_COORDS_ATTR);
simpleShaderProg->bindAttributeLocation("pmvMatrix1", QT_PMV_MATRIX_1_ATTR);
simpleShaderProg->bindAttributeLocation("pmvMatrix2", QT_PMV_MATRIX_2_ATTR);
@@ -271,19 +317,11 @@ QOpenGLEngineSharedShaders::QOpenGLEngineSharedShaders(QOpenGLContext* context)
inCache = blitShaderCache.load(blitShaderProg, context);
if (!inCache) {
- vertexShader = new QOpenGLShader(QOpenGLShader::Vertex);
- shaders.append(vertexShader);
- if (!vertexShader->compileSourceCode(vertexSource))
+ if (!blitShaderProg->addCacheableShaderFromSourceCode(QOpenGLShader::Vertex, vertexSource))
qWarning("Vertex shader for blitShaderProg (MainWithTexCoordsVertexShader & UntransformedPositionVertexShader) failed to compile");
-
- fragShader = new QOpenGLShader(QOpenGLShader::Fragment);
- shaders.append(fragShader);
- if (!fragShader->compileSourceCode(fragSource))
+ if (!blitShaderProg->addCacheableShaderFromSourceCode(QOpenGLShader::Fragment, fragSource))
qWarning("Fragment shader for blitShaderProg (MainFragmentShader & ImageSrcFragmentShader) failed to compile");
- blitShaderProg->addShader(vertexShader);
- blitShaderProg->addShader(fragShader);
-
blitShaderProg->bindAttributeLocation("textureCoordArray", QT_TEXTURE_COORDS_ATTR);
blitShaderProg->bindAttributeLocation("vertexCoordsArray", QT_VERTEX_COORDS_ATTR);
}
@@ -306,9 +344,6 @@ QOpenGLEngineSharedShaders::~QOpenGLEngineSharedShaders()
#ifdef QT_GL_SHARED_SHADER_DEBUG
qDebug(" -> ~QOpenGLEngineSharedShaders() %p for thread %p.", this, QThread::currentThread());
#endif
- qDeleteAll(shaders);
- shaders.clear();
-
qDeleteAll(cachedPrograms);
cachedPrograms.clear();
@@ -370,50 +405,37 @@ QOpenGLEngineShaderProg *QOpenGLEngineSharedShaders::findProgramInCache(const QO
bool inCache = shaderCache.load(shaderProgram.data(), QOpenGLContext::currentContext());
if (!inCache) {
-
- QScopedPointer<QOpenGLShader> fragShader(new QOpenGLShader(QOpenGLShader::Fragment));
- QByteArray description;
+ if (!shaderProgram->addCacheableShaderFromSourceCode(QOpenGLShader::Vertex, vertexSource)) {
+ 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));
+ description.append("Vertex shader: main=");
+ description.append(snippetNameStr(prog.mainVertexShader));
+ description.append(", position=");
+ description.append(snippetNameStr(prog.positionVertexShader));
#endif
- if (!fragShader->compileSourceCode(fragSource)) {
qWarning("Warning: \"%s\" failed to compile!", description.constData());
break;
}
-
- QScopedPointer<QOpenGLShader> vertexShader(new QOpenGLShader(QOpenGLShader::Vertex));
+ if (!shaderProgram->addCacheableShaderFromSourceCode(QOpenGLShader::Fragment, fragSource)) {
+ QByteArray description;
#if defined(QT_DEBUG)
- // 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));
+ 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));
+ }
#endif
- if (!vertexShader->compileSourceCode(vertexSource)) {
qWarning("Warning: \"%s\" failed to compile!", description.constData());
break;
}
- shaders.append(vertexShader.data());
- shaders.append(fragShader.data());
- shaderProgram->addShader(vertexShader.take());
- shaderProgram->addShader(fragShader.take());
-
// We have to bind the vertex attribute names before the program is linked:
shaderProgram->bindAttributeLocation("vertexCoordsArray", QT_VERTEX_COORDS_ATTR);
if (prog.useTextureCoords)
@@ -436,18 +458,9 @@ QOpenGLEngineShaderProg *QOpenGLEngineSharedShaders::findProgramInCache(const QO
shaderCache.store(newProg->program, QOpenGLContext::currentContext());
} else {
QString error;
- error = QLatin1String("Shader program failed to link,");
-#if defined(QT_DEBUG)
- QLatin1String br("\n");
- error += QLatin1String("\n Shaders Used:\n");
- for (int i = 0; i < newProg->program->shaders().count(); ++i) {
- QOpenGLShader *shader = newProg->program->shaders().at(i);
- error += QLatin1String(" ") + shader->objectName() + QLatin1String(": \n")
- + QLatin1String(shader->sourceCode()) + br;
- }
-#endif
- error += QLatin1String(" Error Log:\n")
- + QLatin1String(" ") + newProg->program->log();
+ error = QLatin1String("Shader program failed to link")
+ + QLatin1String(" Error Log:\n")
+ + QLatin1String(" ") + newProg->program->log();
qWarning() << error;
break;
}