diff --git a/src/effects/blur/CMakeLists.txt b/src/effects/blur/CMakeLists.txt
index 4bbcdb3ff6..a69b15355b 100644
--- a/src/effects/blur/CMakeLists.txt
+++ b/src/effects/blur/CMakeLists.txt
@@ -3,6 +3,7 @@
set(blur_SOURCES
blur.cpp
+ blur.qrc
blurshader.cpp
main.cpp
)
diff --git a/src/effects/blur/blur.qrc b/src/effects/blur/blur.qrc
new file mode 100644
index 0000000000..3e09aa9c99
--- /dev/null
+++ b/src/effects/blur/blur.qrc
@@ -0,0 +1,14 @@
+
+
+ shaders/copy.frag
+ shaders/copy_core.frag
+ shaders/downsample.frag
+ shaders/downsample_core.frag
+ shaders/noise.frag
+ shaders/noise_core.frag
+ shaders/upsample.frag
+ shaders/upsample_core.frag
+ shaders/vertex.vert
+ shaders/vertex_core.vert
+
+
diff --git a/src/effects/blur/blurshader.cpp b/src/effects/blur/blurshader.cpp
index 8bad250c9e..e609c1e0f4 100644
--- a/src/effects/blur/blurshader.cpp
+++ b/src/effects/blur/blurshader.cpp
@@ -8,10 +8,12 @@
#include "blurshader.h"
#include
-#include
-#include
-#include
+static void ensureResources()
+{
+ // Must initialize resources manually because the effect is a static lib.
+ Q_INIT_RESOURCE(blur);
+}
namespace KWin
{
@@ -19,141 +21,27 @@ namespace KWin
BlurShader::BlurShader(QObject *parent)
: QObject(parent)
{
- const bool gles = GLPlatform::instance()->isGLES();
- const bool glsl_140 = !gles && GLPlatform::instance()->glslVersion() >= kVersionNumber(1, 40);
- const bool core = glsl_140 || (gles && GLPlatform::instance()->glslVersion() >= kVersionNumber(3, 0));
+ ensureResources();
- QByteArray vertexSource;
- QByteArray fragmentDownSource;
- QByteArray fragmentUpSource;
- QByteArray fragmentCopySource;
- QByteArray fragmentNoiseSource;
+ m_shaderDownsample.reset(ShaderManager::instance()->generateShaderFromFile(
+ ShaderTrait::MapTexture,
+ QStringLiteral(":/effects/blur/shaders/vertex.vert"),
+ QStringLiteral(":/effects/blur/shaders/downsample.frag")));
- const QByteArray attribute = core ? "in" : "attribute";
- const QByteArray texture2D = core ? "texture" : "texture2D";
- const QByteArray fragColor = core ? "fragColor" : "gl_FragColor";
+ m_shaderUpsample.reset(ShaderManager::instance()->generateShaderFromFile(
+ ShaderTrait::MapTexture,
+ QStringLiteral(":/effects/blur/shaders/vertex.vert"),
+ QStringLiteral(":/effects/blur/shaders/upsample.frag")));
- QString glHeaderString;
+ m_shaderCopysample.reset(ShaderManager::instance()->generateShaderFromFile(
+ ShaderTrait::MapTexture,
+ QStringLiteral(":/effects/blur/shaders/vertex.vert"),
+ QStringLiteral(":/effects/blur/shaders/copy.frag")));
- if (gles) {
- if (core) {
- glHeaderString += "#version 300 es\n\n";
- }
-
- glHeaderString += "precision highp float;\n";
- } else if (glsl_140) {
- glHeaderString += "#version 140\n\n";
- }
-
- QString glUniformString = "uniform sampler2D texUnit;\n"
- "uniform float offset;\n"
- "uniform vec2 renderTextureSize;\n"
- "uniform vec2 halfpixel;\n";
-
- if (core) {
- glUniformString += "out vec4 fragColor;\n\n";
- }
-
- // Vertex shader
- QTextStream streamVert(&vertexSource);
-
- streamVert << glHeaderString;
-
- streamVert << "uniform mat4 modelViewProjectionMatrix;\n";
- streamVert << attribute << " vec4 vertex;\n\n";
- streamVert << "\n";
- streamVert << "void main(void)\n";
- streamVert << "{\n";
- streamVert << " gl_Position = modelViewProjectionMatrix * vertex;\n";
- streamVert << "}\n";
-
- streamVert.flush();
-
- // Fragment shader (Dual Kawase Blur) - Downsample
- QTextStream streamFragDown(&fragmentDownSource);
-
- streamFragDown << glHeaderString << glUniformString;
-
- streamFragDown << "void main(void)\n";
- streamFragDown << "{\n";
- streamFragDown << " vec2 uv = vec2(gl_FragCoord.xy / renderTextureSize);\n";
- streamFragDown << " \n";
- streamFragDown << " vec4 sum = " << texture2D << "(texUnit, uv) * 4.0;\n";
- streamFragDown << " sum += " << texture2D << "(texUnit, uv - halfpixel.xy * offset);\n";
- streamFragDown << " sum += " << texture2D << "(texUnit, uv + halfpixel.xy * offset);\n";
- streamFragDown << " sum += " << texture2D << "(texUnit, uv + vec2(halfpixel.x, -halfpixel.y) * offset);\n";
- streamFragDown << " sum += " << texture2D << "(texUnit, uv - vec2(halfpixel.x, -halfpixel.y) * offset);\n";
- streamFragDown << " \n";
- streamFragDown << " " << fragColor << " = sum / 8.0;\n";
- streamFragDown << "}\n";
-
- streamFragDown.flush();
-
- // Fragment shader (Dual Kawase Blur) - Upsample
- QTextStream streamFragUp(&fragmentUpSource);
-
- streamFragUp << glHeaderString << glUniformString;
-
- streamFragUp << "void main(void)\n";
- streamFragUp << "{\n";
- streamFragUp << " vec2 uv = vec2(gl_FragCoord.xy / renderTextureSize);\n";
- streamFragUp << " \n";
- streamFragUp << " vec4 sum = " << texture2D << "(texUnit, uv + vec2(-halfpixel.x * 2.0, 0.0) * offset);\n";
- streamFragUp << " sum += " << texture2D << "(texUnit, uv + vec2(-halfpixel.x, halfpixel.y) * offset) * 2.0;\n";
- streamFragUp << " sum += " << texture2D << "(texUnit, uv + vec2(0.0, halfpixel.y * 2.0) * offset);\n";
- streamFragUp << " sum += " << texture2D << "(texUnit, uv + vec2(halfpixel.x, halfpixel.y) * offset) * 2.0;\n";
- streamFragUp << " sum += " << texture2D << "(texUnit, uv + vec2(halfpixel.x * 2.0, 0.0) * offset);\n";
- streamFragUp << " sum += " << texture2D << "(texUnit, uv + vec2(halfpixel.x, -halfpixel.y) * offset) * 2.0;\n";
- streamFragUp << " sum += " << texture2D << "(texUnit, uv + vec2(0.0, -halfpixel.y * 2.0) * offset);\n";
- streamFragUp << " sum += " << texture2D << "(texUnit, uv + vec2(-halfpixel.x, -halfpixel.y) * offset) * 2.0;\n";
- streamFragUp << " \n";
- streamFragUp << " " << fragColor << " = sum / 12.0;\n";
- streamFragUp << "}\n";
-
- streamFragUp.flush();
-
- // Fragment shader - Copy texture
- QTextStream streamFragCopy(&fragmentCopySource);
-
- streamFragCopy << glHeaderString;
-
- streamFragCopy << "uniform sampler2D texUnit;\n";
- streamFragCopy << "uniform vec2 renderTextureSize;\n";
- streamFragCopy << "uniform vec4 blurRect;\n";
-
- if (core) {
- streamFragCopy << "out vec4 fragColor;\n\n";
- }
-
- streamFragCopy << "void main(void)\n";
- streamFragCopy << "{\n";
- streamFragCopy << " vec2 uv = vec2(gl_FragCoord.xy / renderTextureSize);\n";
- streamFragCopy << " " << fragColor << " = " << texture2D << "(texUnit, clamp(uv, blurRect.xy, blurRect.zw));\n";
- streamFragCopy << "}\n";
-
- streamFragCopy.flush();
-
- // Fragment shader - Noise tiling
- QTextStream streamFragNoise(&fragmentNoiseSource);
-
- streamFragNoise << glHeaderString << glUniformString;
-
- streamFragNoise << "uniform vec2 noiseTextureSize;\n";
- streamFragNoise << "uniform vec2 texStartPos;\n";
-
- streamFragNoise << "void main(void)\n";
- streamFragNoise << "{\n";
- streamFragNoise << " vec2 uvNoise = vec2((texStartPos.xy + gl_FragCoord.xy) / noiseTextureSize);\n";
- streamFragNoise << " \n";
- streamFragNoise << " " << fragColor << " = vec4(" << texture2D << "(texUnit, uvNoise).rrr, 0);\n";
- streamFragNoise << "}\n";
-
- streamFragNoise.flush();
-
- m_shaderDownsample.reset(ShaderManager::instance()->loadShaderFromCode(vertexSource, fragmentDownSource));
- m_shaderUpsample.reset(ShaderManager::instance()->loadShaderFromCode(vertexSource, fragmentUpSource));
- m_shaderCopysample.reset(ShaderManager::instance()->loadShaderFromCode(vertexSource, fragmentCopySource));
- m_shaderNoisesample.reset(ShaderManager::instance()->loadShaderFromCode(vertexSource, fragmentNoiseSource));
+ m_shaderNoisesample.reset(ShaderManager::instance()->generateShaderFromFile(
+ ShaderTrait::MapTexture,
+ QStringLiteral(":/effects/blur/shaders/vertex.vert"),
+ QStringLiteral(":/effects/blur/shaders/noise.frag")));
m_valid = m_shaderDownsample->isValid() && m_shaderUpsample->isValid() && m_shaderCopysample->isValid() && m_shaderNoisesample->isValid();
diff --git a/src/effects/blur/shaders/copy.frag b/src/effects/blur/shaders/copy.frag
new file mode 100644
index 0000000000..d2859063c3
--- /dev/null
+++ b/src/effects/blur/shaders/copy.frag
@@ -0,0 +1,9 @@
+uniform sampler2D texUnit;
+uniform vec2 renderTextureSize;
+uniform vec4 blurRect;
+
+void main(void)
+{
+ vec2 uv = vec2(gl_FragCoord.xy / renderTextureSize);
+ gl_FragColor = texture2D(texUnit, clamp(uv, blurRect.xy, blurRect.zw));
+}
diff --git a/src/effects/blur/shaders/copy_core.frag b/src/effects/blur/shaders/copy_core.frag
new file mode 100644
index 0000000000..9bcca7c672
--- /dev/null
+++ b/src/effects/blur/shaders/copy_core.frag
@@ -0,0 +1,13 @@
+#version 140
+
+uniform sampler2D texUnit;
+uniform vec2 renderTextureSize;
+uniform vec4 blurRect;
+
+out vec4 fragColor;
+
+void main(void)
+{
+ vec2 uv = vec2(gl_FragCoord.xy / renderTextureSize);
+ fragColor = texture(texUnit, clamp(uv, blurRect.xy, blurRect.zw));
+}
diff --git a/src/effects/blur/shaders/downsample.frag b/src/effects/blur/shaders/downsample.frag
new file mode 100644
index 0000000000..a17851be1f
--- /dev/null
+++ b/src/effects/blur/shaders/downsample.frag
@@ -0,0 +1,17 @@
+uniform sampler2D texUnit;
+uniform float offset;
+uniform vec2 renderTextureSize;
+uniform vec2 halfpixel;
+
+void main(void)
+{
+ vec2 uv = vec2(gl_FragCoord.xy / renderTextureSize);
+
+ vec4 sum = texture2D(texUnit, uv) * 4.0;
+ sum += texture2D(texUnit, uv - halfpixel.xy * offset);
+ sum += texture2D(texUnit, uv + halfpixel.xy * offset);
+ sum += texture2D(texUnit, uv + vec2(halfpixel.x, -halfpixel.y) * offset);
+ sum += texture2D(texUnit, uv - vec2(halfpixel.x, -halfpixel.y) * offset);
+
+ gl_FragColor = sum / 8.0;
+}
diff --git a/src/effects/blur/shaders/downsample_core.frag b/src/effects/blur/shaders/downsample_core.frag
new file mode 100644
index 0000000000..39dd38a8dc
--- /dev/null
+++ b/src/effects/blur/shaders/downsample_core.frag
@@ -0,0 +1,21 @@
+#version 140
+
+uniform sampler2D texUnit;
+uniform float offset;
+uniform vec2 renderTextureSize;
+uniform vec2 halfpixel;
+
+out vec4 fragColor;
+
+void main(void)
+{
+ vec2 uv = vec2(gl_FragCoord.xy / renderTextureSize);
+
+ vec4 sum = texture(texUnit, uv) * 4.0;
+ sum += texture(texUnit, uv - halfpixel.xy * offset);
+ sum += texture(texUnit, uv + halfpixel.xy * offset);
+ sum += texture(texUnit, uv + vec2(halfpixel.x, -halfpixel.y) * offset);
+ sum += texture(texUnit, uv - vec2(halfpixel.x, -halfpixel.y) * offset);
+
+ fragColor = sum / 8.0;
+}
diff --git a/src/effects/blur/shaders/noise.frag b/src/effects/blur/shaders/noise.frag
new file mode 100644
index 0000000000..ed89e61d51
--- /dev/null
+++ b/src/effects/blur/shaders/noise.frag
@@ -0,0 +1,14 @@
+uniform sampler2D texUnit;
+uniform float offset;
+uniform vec2 renderTextureSize;
+uniform vec2 halfpixel;
+
+uniform vec2 noiseTextureSize;
+uniform vec2 texStartPos;
+
+void main(void)
+{
+ vec2 uvNoise = vec2((texStartPos.xy + gl_FragCoord.xy) / noiseTextureSize);
+
+ gl_FragColor = vec4(texture2D(texUnit, uvNoise).rrr, 0);
+}
diff --git a/src/effects/blur/shaders/noise_core.frag b/src/effects/blur/shaders/noise_core.frag
new file mode 100644
index 0000000000..63a6ede78e
--- /dev/null
+++ b/src/effects/blur/shaders/noise_core.frag
@@ -0,0 +1,18 @@
+#version 140
+
+uniform sampler2D texUnit;
+uniform float offset;
+uniform vec2 renderTextureSize;
+uniform vec2 halfpixel;
+
+uniform vec2 noiseTextureSize;
+uniform vec2 texStartPos;
+
+out vec4 fragColor;
+
+void main(void)
+{
+ vec2 uvNoise = vec2((texStartPos.xy + gl_FragCoord.xy) / noiseTextureSize);
+
+ fragColor = vec4(texture(texUnit, uvNoise).rrr, 0);
+}
diff --git a/src/effects/blur/shaders/upsample.frag b/src/effects/blur/shaders/upsample.frag
new file mode 100644
index 0000000000..2fc6da176c
--- /dev/null
+++ b/src/effects/blur/shaders/upsample.frag
@@ -0,0 +1,20 @@
+uniform sampler2D texUnit;
+uniform float offset;
+uniform vec2 renderTextureSize;
+uniform vec2 halfpixel;
+
+void main(void)
+{
+ vec2 uv = vec2(gl_FragCoord.xy / renderTextureSize);
+
+ vec4 sum = texture2D(texUnit, uv + vec2(-halfpixel.x * 2.0, 0.0) * offset);
+ sum += texture2D(texUnit, uv + vec2(-halfpixel.x, halfpixel.y) * offset) * 2.0;
+ sum += texture2D(texUnit, uv + vec2(0.0, halfpixel.y * 2.0) * offset);
+ sum += texture2D(texUnit, uv + vec2(halfpixel.x, halfpixel.y) * offset) * 2.0;
+ sum += texture2D(texUnit, uv + vec2(halfpixel.x * 2.0, 0.0) * offset);
+ sum += texture2D(texUnit, uv + vec2(halfpixel.x, -halfpixel.y) * offset) * 2.0;
+ sum += texture2D(texUnit, uv + vec2(0.0, -halfpixel.y * 2.0) * offset);
+ sum += texture2D(texUnit, uv + vec2(-halfpixel.x, -halfpixel.y) * offset) * 2.0;
+
+ gl_FragColor = sum / 12.0;
+}
diff --git a/src/effects/blur/shaders/upsample_core.frag b/src/effects/blur/shaders/upsample_core.frag
new file mode 100644
index 0000000000..0494141a3f
--- /dev/null
+++ b/src/effects/blur/shaders/upsample_core.frag
@@ -0,0 +1,24 @@
+#version 140
+
+uniform sampler2D texUnit;
+uniform float offset;
+uniform vec2 renderTextureSize;
+uniform vec2 halfpixel;
+
+out vec4 fragColor;
+
+void main(void)
+{
+ vec2 uv = vec2(gl_FragCoord.xy / renderTextureSize);
+
+ vec4 sum = texture(texUnit, uv + vec2(-halfpixel.x * 2.0, 0.0) * offset);
+ sum += texture(texUnit, uv + vec2(-halfpixel.x, halfpixel.y) * offset) * 2.0;
+ sum += texture(texUnit, uv + vec2(0.0, halfpixel.y * 2.0) * offset);
+ sum += texture(texUnit, uv + vec2(halfpixel.x, halfpixel.y) * offset) * 2.0;
+ sum += texture(texUnit, uv + vec2(halfpixel.x * 2.0, 0.0) * offset);
+ sum += texture(texUnit, uv + vec2(halfpixel.x, -halfpixel.y) * offset) * 2.0;
+ sum += texture(texUnit, uv + vec2(0.0, -halfpixel.y * 2.0) * offset);
+ sum += texture(texUnit, uv + vec2(-halfpixel.x, -halfpixel.y) * offset) * 2.0;
+
+ fragColor = sum / 12.0;
+}
diff --git a/src/effects/blur/shaders/vertex.vert b/src/effects/blur/shaders/vertex.vert
new file mode 100644
index 0000000000..cdee50bc04
--- /dev/null
+++ b/src/effects/blur/shaders/vertex.vert
@@ -0,0 +1,7 @@
+uniform mat4 modelViewProjectionMatrix;
+attribute vec4 vertex;
+
+void main(void)
+{
+ gl_Position = modelViewProjectionMatrix * vertex;
+}
diff --git a/src/effects/blur/shaders/vertex_core.vert b/src/effects/blur/shaders/vertex_core.vert
new file mode 100644
index 0000000000..0a7de7ef3e
--- /dev/null
+++ b/src/effects/blur/shaders/vertex_core.vert
@@ -0,0 +1,9 @@
+#version 140
+
+uniform mat4 modelViewProjectionMatrix;
+in vec4 vertex;
+
+void main(void)
+{
+ gl_Position = modelViewProjectionMatrix * vertex;
+}