diff options
author | Joni Poikelin <joni.poikelin@qt.io> | 2016-12-30 11:56:53 +0200 |
---|---|---|
committer | Laszlo Agocs <laszlo.agocs@qt.io> | 2017-06-08 10:31:36 +0000 |
commit | c1c259ea76c4d8c94f6d96c3fd0bbbece25785bf (patch) | |
tree | 2c9657fa07abab5931d2e62835dccda89dbbd94e /src/effects/private | |
parent | 8ffe4cc5244f9d2dfa0f9444f2aa86c74dc593c8 (diff) |
Support OpenGL core profile
[ChangeLog][Qt Graphical Effects] Added QtGraphicalEffects support for
OpenGL Core profile contexts.
Task-number: QTBUG-42107
Change-Id: I7111e2e6fb3a0b0391e76a17a8d091d288bfcc23
Reviewed-by: Laszlo Agocs <laszlo.agocs@qt.io>
Diffstat (limited to 'src/effects/private')
-rw-r--r-- | src/effects/private/FastGlow.qml | 70 | ||||
-rw-r--r-- | src/effects/private/FastInnerShadow.qml | 88 | ||||
-rw-r--r-- | src/effects/private/FastMaskedBlur.qml | 91 | ||||
-rw-r--r-- | src/effects/private/GaussianDirectionalBlur.qml | 7 | ||||
-rw-r--r-- | src/effects/private/GaussianInnerShadow.qml | 36 | ||||
-rw-r--r-- | src/effects/private/qgfxshaderbuilder.cpp | 293 | ||||
-rw-r--r-- | src/effects/private/qgfxshaderbuilder_p.h | 1 |
7 files changed, 253 insertions, 333 deletions
diff --git a/src/effects/private/FastGlow.qml b/src/effects/private/FastGlow.qml index 191c7f5..fb2fa42 100644 --- a/src/effects/private/FastGlow.qml +++ b/src/effects/private/FastGlow.qml @@ -64,42 +64,9 @@ Item { hideSource: visible } - property string __internalBlurVertexShader: " - attribute highp vec4 qt_Vertex; - attribute highp vec2 qt_MultiTexCoord0; - uniform highp mat4 qt_Matrix; - uniform highp float yStep; - uniform highp float xStep; - varying highp vec2 qt_TexCoord0; - varying highp vec2 qt_TexCoord1; - varying highp vec2 qt_TexCoord2; - varying highp vec2 qt_TexCoord3; - - void main() { - qt_TexCoord0 = vec2(qt_MultiTexCoord0.x + xStep, qt_MultiTexCoord0.y + yStep * 0.36); - qt_TexCoord1 = vec2(qt_MultiTexCoord0.x + xStep * 0.36, qt_MultiTexCoord0.y - yStep); - qt_TexCoord2 = vec2(qt_MultiTexCoord0.x - xStep * 0.36, qt_MultiTexCoord0.y + yStep); - qt_TexCoord3 = vec2(qt_MultiTexCoord0.x - xStep, qt_MultiTexCoord0.y - yStep * 0.36); - gl_Position = qt_Matrix * qt_Vertex; - } - " - - property string __internalBlurFragmentShader: " - uniform lowp sampler2D source; - uniform lowp float qt_Opacity; - varying highp vec2 qt_TexCoord0; - varying highp vec2 qt_TexCoord1; - varying highp vec2 qt_TexCoord2; - varying highp vec2 qt_TexCoord3; - - void main() { - highp vec4 sourceColor = (texture2D(source, qt_TexCoord0) + - texture2D(source, qt_TexCoord1) + - texture2D(source, qt_TexCoord2) + - texture2D(source, qt_TexCoord3)) * 0.25; - gl_FragColor = sourceColor * qt_Opacity; - } - " + property string __internalBlurVertexShader: "qrc:/qt-project.org/imports/QtGraphicalEffects/shaders/fastblur_internal.vert" + + property string __internalBlurFragmentShader: "qrc:/qt-project.org/imports/QtGraphicalEffects/shaders/fastblur_internal.frag" ShaderEffect { id: level0 @@ -359,35 +326,6 @@ Item { onLodChanged: calculateWeights() - fragmentShader: " - uniform lowp sampler2D source1; - uniform lowp sampler2D source2; - uniform lowp sampler2D source3; - uniform lowp sampler2D source4; - uniform lowp sampler2D source5; - uniform mediump float weight1; - uniform mediump float weight2; - uniform mediump float weight3; - uniform mediump float weight4; - uniform mediump float weight5; - uniform highp vec4 color; - uniform highp float spread; - uniform lowp float qt_Opacity; - varying mediump vec2 qt_TexCoord0; - - highp float linearstep(highp float e0, highp float e1, highp float x) { - return clamp((x - e0) / (e1 - e0), 0.0, 1.0); - } - - void main() { - lowp vec4 sourceColor = texture2D(source1, qt_TexCoord0) * weight1; - sourceColor += texture2D(source2, qt_TexCoord0) * weight2; - sourceColor += texture2D(source3, qt_TexCoord0) * weight3; - sourceColor += texture2D(source4, qt_TexCoord0) * weight4; - sourceColor += texture2D(source5, qt_TexCoord0) * weight5; - sourceColor = mix(vec4(0), color, linearstep(0.0, spread, sourceColor.a)); - gl_FragColor = sourceColor * qt_Opacity; - } - " + fragmentShader: "qrc:/qt-project.org/imports/QtGraphicalEffects/shaders/fastglow.frag" } } diff --git a/src/effects/private/FastInnerShadow.qml b/src/effects/private/FastInnerShadow.qml index 82690c5..be21d8e 100644 --- a/src/effects/private/FastInnerShadow.qml +++ b/src/effects/private/FastInnerShadow.qml @@ -65,42 +65,9 @@ Item { hideSource: visible } - property string __internalBlurVertexShader: " - attribute highp vec4 qt_Vertex; - attribute highp vec2 qt_MultiTexCoord0; - uniform highp mat4 qt_Matrix; - uniform highp float yStep; - uniform highp float xStep; - varying highp vec2 qt_TexCoord0; - varying highp vec2 qt_TexCoord1; - varying highp vec2 qt_TexCoord2; - varying highp vec2 qt_TexCoord3; - - void main() { - qt_TexCoord0 = vec2(qt_MultiTexCoord0.x + xStep, qt_MultiTexCoord0.y + yStep * 0.36); - qt_TexCoord1 = vec2(qt_MultiTexCoord0.x + xStep * 0.36, qt_MultiTexCoord0.y - yStep); - qt_TexCoord2 = vec2(qt_MultiTexCoord0.x - xStep * 0.36, qt_MultiTexCoord0.y + yStep); - qt_TexCoord3 = vec2(qt_MultiTexCoord0.x - xStep, qt_MultiTexCoord0.y - yStep * 0.36); - gl_Position = qt_Matrix * qt_Vertex; - } - " - - property string __internalBlurFragmentShader: " - uniform lowp sampler2D source; - uniform lowp float qt_Opacity; - varying highp vec2 qt_TexCoord0; - varying highp vec2 qt_TexCoord1; - varying highp vec2 qt_TexCoord2; - varying highp vec2 qt_TexCoord3; - - void main() { - highp vec4 sourceColor = (texture2D(source, qt_TexCoord0) + - texture2D(source, qt_TexCoord1) + - texture2D(source, qt_TexCoord2) + - texture2D(source, qt_TexCoord3)) * 0.25; - gl_FragColor = sourceColor * qt_Opacity; - } - " + property string __internalBlurVertexShader: "qrc:/qt-project.org/imports/QtGraphicalEffects/shaders/fastblur_internal.vert" + + property string __internalBlurFragmentShader: "qrc:/qt-project.org/imports/QtGraphicalEffects/shaders/fastblur_internal.frag" ShaderEffect { id: level0 @@ -112,21 +79,7 @@ Item { anchors.fill: parent visible: false smooth: true - fragmentShader: " - varying highp vec2 qt_TexCoord0; - uniform lowp float qt_Opacity; - uniform highp sampler2D source; - uniform lowp vec4 color; - uniform highp float horizontalOffset; - uniform highp float verticalOffset; - - void main(void) { - highp vec2 pos = qt_TexCoord0 - vec2(horizontalOffset, verticalOffset); - lowp float ea = step(0.0, pos.x) * step(0.0, pos.y) * step(pos.x, 1.0) * step(pos.y, 1.0); - lowp float eb = 1.0 - ea; - gl_FragColor = (eb * color + ea * color * (1.0 - texture2D(source, pos).a)) * qt_Opacity; - } - " + fragmentShader: "qrc:/qt-project.org/imports/QtGraphicalEffects/shaders/fastinnershadow_level0.frag" } ShaderEffectSource { @@ -377,37 +330,6 @@ Item { onLodChanged: calculateWeights() - fragmentShader: " - uniform lowp sampler2D original; - uniform lowp sampler2D source1; - uniform lowp sampler2D source2; - uniform lowp sampler2D source3; - uniform lowp sampler2D source4; - uniform lowp sampler2D source5; - uniform mediump float weight1; - uniform mediump float weight2; - uniform mediump float weight3; - uniform mediump float weight4; - uniform mediump float weight5; - uniform highp vec4 color; - uniform highp float spread; - uniform lowp float qt_Opacity; - varying mediump vec2 qt_TexCoord0; - - highp float linearstep(highp float e0, highp float e1, highp float x) { - return clamp((x - e0) / (e1 - e0), 0.0, 1.0); - } - - void main() { - lowp vec4 shadowColor = texture2D(source1, qt_TexCoord0) * weight1; - shadowColor += texture2D(source2, qt_TexCoord0) * weight2; - shadowColor += texture2D(source3, qt_TexCoord0) * weight3; - shadowColor += texture2D(source4, qt_TexCoord0) * weight4; - shadowColor += texture2D(source5, qt_TexCoord0) * weight5; - lowp vec4 originalColor = texture2D(original, qt_TexCoord0); - shadowColor.rgb = mix(originalColor.rgb, color.rgb * originalColor.a, linearstep(0.0, spread, shadowColor.a)); - gl_FragColor = vec4(shadowColor.rgb, originalColor.a) * originalColor.a * qt_Opacity; - } - " + fragmentShader: "qrc:/qt-project.org/imports/QtGraphicalEffects/shaders/fastinnershadow.frag" } } diff --git a/src/effects/private/FastMaskedBlur.qml b/src/effects/private/FastMaskedBlur.qml index cfdace4..ef26704 100644 --- a/src/effects/private/FastMaskedBlur.qml +++ b/src/effects/private/FastMaskedBlur.qml @@ -68,42 +68,9 @@ Item { smooth: rootItem.blur > 0 } - property string __internalBlurVertexShader: " - attribute highp vec4 qt_Vertex; - attribute highp vec2 qt_MultiTexCoord0; - uniform highp mat4 qt_Matrix; - uniform highp float yStep; - uniform highp float xStep; - varying highp vec2 qt_TexCoord0; - varying highp vec2 qt_TexCoord1; - varying highp vec2 qt_TexCoord2; - varying highp vec2 qt_TexCoord3; + property string __internalBlurVertexShader: "qrc:/qt-project.org/imports/QtGraphicalEffects/shaders/fastblur_internal.vert" - void main() { - qt_TexCoord0 = vec2(qt_MultiTexCoord0.x + xStep, qt_MultiTexCoord0.y + yStep * 0.36); - qt_TexCoord1 = vec2(qt_MultiTexCoord0.x + xStep * 0.36, qt_MultiTexCoord0.y - yStep); - qt_TexCoord2 = vec2(qt_MultiTexCoord0.x - xStep * 0.36, qt_MultiTexCoord0.y + yStep); - qt_TexCoord3 = vec2(qt_MultiTexCoord0.x - xStep, qt_MultiTexCoord0.y - yStep * 0.36); - gl_Position = qt_Matrix * qt_Vertex; - } - " - - property string __internalBlurFragmentShader: " - uniform lowp sampler2D source; - uniform lowp float qt_Opacity; - varying highp vec2 qt_TexCoord0; - varying highp vec2 qt_TexCoord1; - varying highp vec2 qt_TexCoord2; - varying highp vec2 qt_TexCoord3; - - void main() { - highp vec4 sourceColor = (texture2D(source, qt_TexCoord0) + - texture2D(source, qt_TexCoord1) + - texture2D(source, qt_TexCoord2) + - texture2D(source, qt_TexCoord3)) * 0.25; - gl_FragColor = sourceColor * qt_Opacity; - } - " + property string __internalBlurFragmentShader: "qrc:/qt-project.org/imports/QtGraphicalEffects/shaders/fastblur_internal.frag" ShaderEffect { id: mask0 @@ -275,58 +242,6 @@ Item { width: transparentBorder ? parent.width + 128 : parent.width height: transparentBorder ? parent.height + 128 : parent.height - fragmentShader: " - uniform lowp sampler2D mask; - uniform lowp sampler2D source1; - uniform lowp sampler2D source2; - uniform lowp sampler2D source3; - uniform lowp sampler2D source4; - uniform lowp sampler2D source5; - uniform lowp sampler2D source6; - uniform lowp float lod; - uniform lowp float qt_Opacity; - varying mediump vec2 qt_TexCoord0; - - mediump float weight(mediump float v) { - if (v <= 0.0) - return 1.0; - - if (v >= 0.5) - return 0.0; - - return 1.0 - v * 2.0; - } - - void main() { - - lowp vec4 maskColor = texture2D(mask, qt_TexCoord0); - mediump float l = lod * maskColor.a; - - mediump float w1 = weight(abs(l - 0.100)); - mediump float w2 = weight(abs(l - 0.300)); - mediump float w3 = weight(abs(l - 0.500)); - mediump float w4 = weight(abs(l - 0.700)); - mediump float w5 = weight(abs(l - 0.900)); - mediump float w6 = weight(abs(l - 1.100)); - - mediump float sum = w1 + w2 + w3 + w4 + w5 + w6; - mediump float weight1 = w1 / sum; - mediump float weight2 = w2 / sum; - mediump float weight3 = w3 / sum; - mediump float weight4 = w4 / sum; - mediump float weight5 = w5 / sum; - mediump float weight6 = w6 / sum; - - lowp vec4 sourceColor = texture2D(source1, qt_TexCoord0) * weight1; - sourceColor += texture2D(source2, qt_TexCoord0) * weight2; - sourceColor += texture2D(source3, qt_TexCoord0) * weight3; - sourceColor += texture2D(source4, qt_TexCoord0) * weight4; - sourceColor += texture2D(source5, qt_TexCoord0) * weight5; - sourceColor += texture2D(source6, qt_TexCoord0) * weight6; - - gl_FragColor = sourceColor * qt_Opacity; - - } - " + fragmentShader: "qrc:/qt-project.org/imports/QtGraphicalEffects/shaders/fastmaskedblur.frag" } } diff --git a/src/effects/private/GaussianDirectionalBlur.qml b/src/effects/private/GaussianDirectionalBlur.qml index 0a62b80..af1ca70 100644 --- a/src/effects/private/GaussianDirectionalBlur.qml +++ b/src/effects/private/GaussianDirectionalBlur.qml @@ -37,7 +37,7 @@ ** ****************************************************************************/ -import QtQuick 2.0 +import QtQuick 2.8 import QtGraphicalEffects.private 1.0 Item { @@ -180,7 +180,10 @@ Item { "gl_FragColor += texture2D(source, texCoord) * factor_30_31.y; texCoord += shift;" ] - var shader = fragmentShaderBegin + var shader = "" + if (GraphicsInfo.profile == GraphicsInfo.OpenGLCoreProfile) + shader += "#version 150 core\n#define varying in\n#define gl_FragColor fragColor\n#define texture2D texture\nout vec4 fragColor;\n" + shader += fragmentShaderBegin var samples = maxRadius * 2 if (samples > 32) { console.log("DirectionalGaussianBlur.qml WARNING: Maximum of blur radius (16) exceeded!") diff --git a/src/effects/private/GaussianInnerShadow.qml b/src/effects/private/GaussianInnerShadow.qml index f3becae..7207963 100644 --- a/src/effects/private/GaussianInnerShadow.qml +++ b/src/effects/private/GaussianInnerShadow.qml @@ -76,21 +76,7 @@ Item { property real verticalOffset: rootItem.verticalOffset / rootItem.height visible: false - fragmentShader: " - uniform highp sampler2D original; - uniform lowp float qt_Opacity; - uniform lowp vec4 color; - uniform highp float horizontalOffset; - uniform highp float verticalOffset; - varying highp vec2 qt_TexCoord0; - - void main(void) { - highp vec2 pos = qt_TexCoord0 - vec2(horizontalOffset, verticalOffset); - lowp float ea = step(0.0, pos.x) * step(0.0, pos.y) * step(pos.x, 1.0) * step(pos.y, 1.0); - lowp float eb = 1.0 - ea; - gl_FragColor = eb * color + ea * color * (1.0 - texture2D(original, pos).a) * qt_Opacity; - } - " + fragmentShader: "qrc:/qt-project.org/imports/QtGraphicalEffects/shaders/gaussianinnershadow_shadow.frag" } GaussianDirectionalBlur { @@ -132,24 +118,6 @@ Item { property real spread: 1.0 - (rootItem.spread * 0.98) property color color: rootItem.color - fragmentShader: " - uniform highp sampler2D original; - uniform highp sampler2D shadow; - uniform lowp float qt_Opacity; - uniform highp float spread; - uniform lowp vec4 color; - varying highp vec2 qt_TexCoord0; - - highp float linearstep(highp float e0, highp float e1, highp float x) { - return clamp((x - e0) / (e1 - e0), 0.0, 1.0); - } - - void main(void) { - lowp vec4 originalColor = texture2D(original, qt_TexCoord0); - lowp vec4 shadowColor = texture2D(shadow, qt_TexCoord0); - shadowColor.rgb = mix(originalColor.rgb, color.rgb * originalColor.a, linearstep(0.0, spread, shadowColor.a)); - gl_FragColor = vec4(shadowColor.rgb, originalColor.a) * originalColor.a * qt_Opacity; - } - " + fragmentShader: "qrc:/qt-project.org/imports/QtGraphicalEffects/shaders/gaussianinnershadow.frag" } } diff --git a/src/effects/private/qgfxshaderbuilder.cpp b/src/effects/private/qgfxshaderbuilder.cpp index d1902a2..22975b5 100644 --- a/src/effects/private/qgfxshaderbuilder.cpp +++ b/src/effects/private/qgfxshaderbuilder.cpp @@ -60,6 +60,7 @@ #endif QGfxShaderBuilder::QGfxShaderBuilder() + : m_coreProfile(false) { // The following code makes the assumption that an OpenGL context the GUI // thread will get the same capabilities as the render thread's OpenGL @@ -82,6 +83,7 @@ QGfxShaderBuilder::QGfxShaderBuilder() int components; gl->glGetIntegerv(GL_MAX_VARYING_COMPONENTS, &components); m_maxBlurSamples = components / 2.0; + m_coreProfile = context.format().profile() == QSurfaceFormat::CoreProfile; } else { int floats; gl->glGetIntegerv(GL_MAX_VARYING_FLOATS, &floats); @@ -182,6 +184,15 @@ static void qgfx_declareBlurVaryings(QByteArray &shader, QGfxGaussSample *s, int } } +static void qgfx_declareCoreBlur(QByteArray &shader, const QByteArray& direction, QGfxGaussSample *s, int samples) +{ + for (int i=0; i<samples; ++i) { + shader += direction + " vec2 "; + shader += s[i].name; + shader += ";\n"; + } +} + static void qgfx_buildGaussSamplePoints(QGfxGaussSample *p, int samples, int radius, qreal deviation) { @@ -259,6 +270,38 @@ QByteArray qgfx_gaussianVertexShader(QGfxGaussSample *p, int samples) return shader; } +QByteArray qgfx_gaussianVertexCoreShader(QGfxGaussSample *p, int samples) +{ + QByteArray shader; + shader.reserve(1024); + shader += "#version 150 core\n" + "in vec4 qt_Vertex;\n" + "in vec2 qt_MultiTexCoord0;\n\n" + "uniform mat4 qt_Matrix;\n" + "uniform float spread;\n" + "uniform vec2 dirstep;\n\n"; + + qgfx_declareCoreBlur(shader, "out", p, samples); + + shader += "\nvoid main() {\n" + " gl_Position = qt_Matrix * qt_Vertex;\n\n"; + + for (int i=0; i<samples; ++i) { + shader += " "; + shader += p[i].name; + shader += " = qt_MultiTexCoord0"; + if (p[i].pos != 0.0) { + shader += " + spread * dirstep * float("; + shader += QByteArray::number(p[i].pos); + shader += ')'; + } + shader += ";\n"; + } + + shader += "}\n"; + + return shader; +} QByteArray qgfx_gaussianFragmentShader(QGfxGaussSample *p, int samples, bool alphaOnly) { @@ -307,6 +350,182 @@ QByteArray qgfx_gaussianFragmentShader(QGfxGaussSample *p, int samples, bool alp return shader; } +QByteArray qgfx_gaussianFragmentCoreShader(QGfxGaussSample *p, int samples, bool alphaOnly) +{ + QByteArray shader; + shader.reserve(1024); + shader += "#version 150 core\n" + "uniform sampler2D source;\n" + "uniform float qt_Opacity;\n"; + + if (alphaOnly) { + shader += "uniform vec4 color;\n" + "uniform float thickness;\n"; + } + + shader += "out vec4 fragColor;\n"; + + qgfx_declareCoreBlur(shader, "in", p, samples); + + shader += "\nvoid main() {\n" + " fragColor = "; + if (alphaOnly) + shader += "mix(vec4(0), color, clamp(("; + else + shader += "("; + + qreal sum = 0; + for (int i=0; i<samples; ++i) + sum += p[i].weight; + + for (int i=0; i<samples; ++i) { + shader += "\n + float("; + shader += QByteArray::number(p[i].weight / sum); + shader += ") * texture(source, "; + shader += p[i].name; + shader += ")"; + if (alphaOnly) + shader += ".a"; + } + + shader += "\n )"; + if (alphaOnly) + shader += "/thickness, 0.0, 1.0))"; + shader += "* qt_Opacity;\n}"; + + return shader; +} + +static QByteArray qgfx_fallbackVertexShader() +{ + return "attribute highp vec4 qt_Vertex;\n" + "attribute highp vec2 qt_MultiTexCoord0;\n" + "uniform highp mat4 qt_Matrix;\n" + "varying highp vec2 qt_TexCoord0;\n" + "void main() {\n" + " gl_Position = qt_Matrix * qt_Vertex;\n" + " qt_TexCoord0 = qt_MultiTexCoord0;\n" + "}\n"; +} + +static QByteArray qgfx_fallbackCoreVertexShader() +{ + return "#version 150 core\n" + "in vec4 qt_Vertex;\n" + "in vec2 qt_MultiTexCoord0;\n" + "uniform mat4 qt_Matrix;\n" + "out vec2 qt_TexCoord0;\n" + "void main() {\n" + " gl_Position = qt_Matrix * qt_Vertex;\n" + " qt_TexCoord0 = qt_MultiTexCoord0;\n" + "}\n"; +} + +static QByteArray qgfx_fallbackFragmentShader(int requestedRadius, qreal deviation, bool masked, bool alphaOnly) +{ + QByteArray fragShader; + if (masked) + fragShader += "uniform mediump sampler2D mask;\n"; + fragShader += + "uniform highp sampler2D source;\n" + "uniform lowp float qt_Opacity;\n" + "uniform mediump float spread;\n" + "uniform highp vec2 dirstep;\n"; + if (alphaOnly) { + fragShader += "uniform lowp vec4 color;\n" + "uniform lowp float thickness;\n"; + } + fragShader += + "\n" + "varying highp vec2 qt_TexCoord0;\n" + "\n" + "void main() {\n"; + if (alphaOnly) + fragShader += " mediump float result = 0.0;\n"; + else + fragShader += " mediump vec4 result = vec4(0);\n"; + fragShader += " highp vec2 pixelStep = dirstep * spread;\n"; + if (masked) + fragShader += " pixelStep *= texture2D(mask, qt_TexCoord0).a;\n"; + + float wSum = 0; + for (int r=-requestedRadius; r<=requestedRadius; ++r) { + float w = qgfx_gaussian(r, deviation); + wSum += w; + fragShader += " result += float("; + fragShader += QByteArray::number(w); + fragShader += ") * texture2D(source, qt_TexCoord0 + pixelStep * float("; + fragShader += QByteArray::number(r); + fragShader += "))"; + if (alphaOnly) + fragShader += ".a"; + fragShader += ";\n"; + } + fragShader += " const mediump float wSum = float("; + fragShader += QByteArray::number(wSum); + fragShader += ");\n" + " gl_FragColor = "; + if (alphaOnly) + fragShader += "mix(vec4(0), color, clamp((result / wSum) / thickness, 0.0, 1.0)) * qt_Opacity;\n"; + else + fragShader += "(qt_Opacity / wSum) * result;\n"; + fragShader += "}\n"; + + return fragShader; +} + +static QByteArray qgfx_fallbackCoreFragmentShader(int requestedRadius, qreal deviation, bool masked, bool alphaOnly) +{ + QByteArray fragShader = "#version 150 core\n"; + if (masked) + fragShader += "uniform sampler2D mask;\n"; + fragShader += + "uniform sampler2D source;\n" + "uniform float qt_Opacity;\n" + "uniform float spread;\n" + "uniform vec2 dirstep;\n"; + if (alphaOnly) { + fragShader += "uniform vec4 color;\n" + "uniform float thickness;\n"; + } + fragShader += + "out vec4 fragColor;\n" + "in vec2 qt_TexCoord0;\n" + "\n" + "void main() {\n"; + if (alphaOnly) + fragShader += " float result = 0.0;\n"; + else + fragShader += " vec4 result = vec4(0);\n"; + fragShader += " vec2 pixelStep = dirstep * spread;\n"; + if (masked) + fragShader += " pixelStep *= texture(mask, qt_TexCoord0).a;\n"; + + float wSum = 0; + for (int r=-requestedRadius; r<=requestedRadius; ++r) { + float w = qgfx_gaussian(r, deviation); + wSum += w; + fragShader += " result += float("; + fragShader += QByteArray::number(w); + fragShader += ") * texture(source, qt_TexCoord0 + pixelStep * float("; + fragShader += QByteArray::number(r); + fragShader += "))"; + if (alphaOnly) + fragShader += ".a"; + fragShader += ";\n"; + } + fragShader += " const float wSum = float("; + fragShader += QByteArray::number(wSum); + fragShader += ");\n" + " fragColor = "; + if (alphaOnly) + fragShader += "mix(vec4(0), color, clamp((result / wSum) / thickness, 0.0, 1.0)) * qt_Opacity;\n"; + else + fragShader += "(qt_Opacity / wSum) * result;\n"; + fragShader += "}\n"; + + return fragShader; +} QVariantMap QGfxShaderBuilder::gaussianBlur(const QJSValue ¶meters) { @@ -323,73 +542,27 @@ QVariantMap QGfxShaderBuilder::gaussianBlur(const QJSValue ¶meters) QVariantMap result; if (samples > m_maxBlurSamples || masked || fallback) { - QByteArray fragShader; - if (masked) - fragShader += "uniform mediump sampler2D mask;\n"; - fragShader += - "uniform highp sampler2D source;\n" - "uniform lowp float qt_Opacity;\n" - "uniform mediump float spread;\n" - "uniform highp vec2 dirstep;\n"; - if (alphaOnly) { - fragShader += "uniform lowp vec4 color;\n" - "uniform lowp float thickness;\n"; - } - fragShader += - "\n" - "varying highp vec2 qt_TexCoord0;\n" - "\n" - "void main() {\n"; - if (alphaOnly) - fragShader += " mediump float result = 0.0;\n"; - else - fragShader += " mediump vec4 result = vec4(0);\n"; - fragShader += " highp vec2 pixelStep = dirstep * spread;\n"; - if (masked) - fragShader += " pixelStep *= texture2D(mask, qt_TexCoord0).a;\n"; - - float wSum = 0; - for (int r=-requestedRadius; r<=requestedRadius; ++r) { - float w = qgfx_gaussian(r, deviation); - wSum += w; - fragShader += " result += float("; - fragShader += QByteArray::number(w); - fragShader += ") * texture2D(source, qt_TexCoord0 + pixelStep * float("; - fragShader += QByteArray::number(r); - fragShader += "))"; - if (alphaOnly) - fragShader += ".a"; - fragShader += ";\n"; + + if (m_coreProfile) { + result[QStringLiteral("fragmentShader")] = qgfx_fallbackCoreFragmentShader(requestedRadius, deviation, masked, alphaOnly); + result[QStringLiteral("vertexShader")] = qgfx_fallbackCoreVertexShader(); + } else { + result[QStringLiteral("fragmentShader")] = qgfx_fallbackFragmentShader(requestedRadius, deviation, masked, alphaOnly); + result[QStringLiteral("vertexShader")] = qgfx_fallbackVertexShader(); } - fragShader += " const mediump float wSum = float("; - fragShader += QByteArray::number(wSum); - fragShader += ");\n" - " gl_FragColor = "; - if (alphaOnly) - fragShader += "mix(vec4(0), color, clamp((result / wSum) / thickness, 0.0, 1.0)) * qt_Opacity;\n"; - else - fragShader += "(qt_Opacity / wSum) * result;\n"; - fragShader += "}\n"; - result[QStringLiteral("fragmentShader")] = fragShader; - - result[QStringLiteral("vertexShader")] = - "attribute highp vec4 qt_Vertex;\n" - "attribute highp vec2 qt_MultiTexCoord0;\n" - "uniform highp mat4 qt_Matrix;\n" - "varying highp vec2 qt_TexCoord0;\n" - "void main() {\n" - " gl_Position = qt_Matrix * qt_Vertex;\n" - " qt_TexCoord0 = qt_MultiTexCoord0;\n" - "}\n"; return result; } QVarLengthArray<QGfxGaussSample, 64> p(samples); qgfx_buildGaussSamplePoints(p.data(), samples, radius, deviation); - result[QStringLiteral("fragmentShader")] = qgfx_gaussianFragmentShader(p.data(), samples, alphaOnly); - result[QStringLiteral("vertexShader")] = qgfx_gaussianVertexShader(p.data(), samples); - + if (m_coreProfile) { + result[QStringLiteral("fragmentShader")] = qgfx_gaussianFragmentCoreShader(p.data(), samples, alphaOnly); + result[QStringLiteral("vertexShader")] = qgfx_gaussianVertexCoreShader(p.data(), samples); + } else { + result[QStringLiteral("fragmentShader")] = qgfx_gaussianFragmentShader(p.data(), samples, alphaOnly); + result[QStringLiteral("vertexShader")] = qgfx_gaussianVertexShader(p.data(), samples); + } return result; } diff --git a/src/effects/private/qgfxshaderbuilder_p.h b/src/effects/private/qgfxshaderbuilder_p.h index 7061c7d..59aea2c 100644 --- a/src/effects/private/qgfxshaderbuilder_p.h +++ b/src/effects/private/qgfxshaderbuilder_p.h @@ -58,6 +58,7 @@ public: private: int m_maxBlurSamples; + bool m_coreProfile; }; QT_END_NAMESPACE |