[prev in list] [next in list] [prev in thread] [next in thread]
List: kde-commits
Subject: [kwin] /: Added noise blur effect
From: Fredrik_Höglund <null () kde ! org>
Date: 2018-02-13 23:27:37
Message-ID: E1eljz7-0004F1-NR () code ! kde ! org
[Download RAW message or body]
Git commit cc0325af41528b4f68e9f376c4d2d27ed1e28f11 by Fredrik Höglund, on behalf of \
Alex Nemeth. Committed on 13/02/2018 at 23:13.
Pushed by fredrik into branch 'master'.
Added noise blur effect
Summary:
Added the option to turn on noise behind the blurred area.
The lowest strength value disables it completely, so it is optional and is disabled \
by default.
Test Plan:
Edit: this new screenshot shows the updated noise generation.
Edit2: separated the screenshots so you can flick through them to clearly see the \
differences
{F5694024}
{F5694031}
{F5694025}
{F5694028}
Reviewers: #kwin, #vdg, fredrik
Reviewed By: #vdg, fredrik
Subscribers: davidedmundson, matheusm, romangg, ivan, zzag, ngraham, kwin, #kwin
Tags: #kwin
Differential Revision: https://phabricator.kde.org/D10281
M +72 -19 effects/blur/blur.cpp
M +8 -1 effects/blur/blur.h
M +3 -0 effects/blur/blur.kcfg
M +68 -5 effects/blur/blur_config.ui
M +121 -22 effects/blur/blurshader.cpp
M +20 -6 effects/blur/blurshader.h
M +2 -0 libkwineffects/kwingltexture.cpp
https://commits.kde.org/kwin/cc0325af41528b4f68e9f376c4d2d27ed1e28f11
diff --git a/effects/blur/blur.cpp b/effects/blur/blur.cpp
index 000285fb9..cc4734e60 100644
--- a/effects/blur/blur.cpp
+++ b/effects/blur/blur.cpp
@@ -27,12 +27,16 @@
#include <QMatrix4x4>
#include <QLinkedList>
+#include <QScreen> // for QGuiApplication
+#include <QTime>
#include <cmath> // for ceil()
#include <KWayland/Server/surface_interface.h>
#include <KWayland/Server/blur_interface.h>
#include <KWayland/Server/shadow_interface.h>
#include <KWayland/Server/display.h>
+#include <KSharedConfig>
+#include <KConfigGroup>
namespace KWin
{
@@ -143,7 +147,7 @@ void BlurEffect::updateTexture()
// Prepare the stack for the rendering
m_renderTargetStack.clear();
- m_renderTargets.reserve(m_downSampleIterations * 2 - 1);
+ m_renderTargetStack.reserve(m_downSampleIterations * 2);
// Upsample
for (int i = 1; i < m_downSampleIterations; i++) {
@@ -157,6 +161,9 @@ void BlurEffect::updateTexture()
// Copysample
m_renderTargetStack.push(m_renderTargets[0]);
+
+ // Generate the noise helper texture
+ generateNoiseTexture();
}
void BlurEffect::initBlurStrengthValues()
@@ -227,6 +234,9 @@ void BlurEffect::reconfigure(ReconfigureFlags flags)
m_downSampleIterations = blurStrengthValues[blurStrength].iteration;
m_offset = blurStrengthValues[blurStrength].offset;
m_expandSize = blurOffsets[m_downSampleIterations - 1].expandSize;
+ m_noiseStrength = BlurConfig::noiseStrength();
+
+ m_scalingFactor = QGuiApplication::primaryScreen()->logicalDotsPerInch() / 96.0;
updateTexture();
@@ -550,7 +560,7 @@ void BlurEffect::drawWindow(EffectWindow *w, int mask, QRegion \
region, WindowPai }
if (!shape.isEmpty()) {
- doBlur(shape, screen, data.opacity(), data.screenProjectionMatrix(), \
w->isDock()); + doBlur(shape, screen, data.opacity(), \
data.screenProjectionMatrix(), w->isDock(), w->geometry()); }
}
@@ -566,12 +576,39 @@ void BlurEffect::paintEffectFrame(EffectFrame *frame, QRegion \
region, double opa
QRegion shape = frame->geometry().adjusted(-borderSize, -borderSize, borderSize, \
borderSize) & screen;
if (valid && !shape.isEmpty() && region.intersects(shape.boundingRect()) && \
frame->style() != EffectFrameNone) {
- doBlur(shape, screen, opacity * frameOpacity, \
frame->screenProjectionMatrix(), false); + doBlur(shape, screen, opacity * \
frameOpacity, frame->screenProjectionMatrix(), false, frame->geometry()); }
effects->paintEffectFrame(frame, region, opacity, frameOpacity);
}
-void BlurEffect::doBlur(const QRegion& shape, const QRect& screen, const float \
opacity, const QMatrix4x4 &screenProjection, bool isDock) +void \
BlurEffect::generateNoiseTexture() +{
+ if (m_noiseStrength == 0) {
+ return;
+ }
+
+ // Init randomness based on time
+ qsrand((uint)QTime::currentTime().msec());
+
+ QImage noiseImage(QSize(256, 256), QImage::Format_Grayscale8);
+
+ for (int y = 0; y < noiseImage.height(); y++) {
+ uint8_t *noiseImageLine = (uint8_t *) noiseImage.scanLine(y);
+
+ for (int x = 0; x < noiseImage.width(); x++) {
+ noiseImageLine[x] = qrand() % m_noiseStrength + (128 - m_noiseStrength / \
2); + }
+ }
+
+ // The noise texture looks distorted when not scaled with integer
+ noiseImage = noiseImage.scaled(noiseImage.size() * m_scalingFactor);
+
+ m_noiseTexture = GLTexture(noiseImage);
+ m_noiseTexture.setFilter(GL_NEAREST);
+ m_noiseTexture.setWrapMode(GL_REPEAT);
+}
+
+void BlurEffect::doBlur(const QRegion& shape, const QRect& screen, const float \
opacity, const QMatrix4x4 &screenProjection, bool isDock, QRect windowRect) {
QRegion expandedBlurRegion = expand(shape) & expand(screen);
@@ -628,24 +665,40 @@ void BlurEffect::doBlur(const QRegion& shape, const QRect& \
screen, const float o glBlendFunc(GL_CONSTANT_ALPHA, GL_ONE_MINUS_CONSTANT_ALPHA);
}
- //Final upscale to the screen
- m_shader->bind(BlurShader::UpSampleType);
- m_shader->setOffset(m_offset);
+ upscaleRenderToScreen(vbo, blurRectCount * (m_downSampleIterations + 1), \
shape.rectCount() * 6, screenProjection, shape.boundingRect(), windowRect.topLeft()); \
- m_shader->setModelViewProjectionMatrix(screenProjection);
- m_shader->setTargetSize(m_renderTextures[0].size());
+ if (opacity < 1.0) {
+ glDisable(GL_BLEND);
+ }
- //Copy the image from this texture
+ vbo->unbindArrays();
+}
+
+void BlurEffect::upscaleRenderToScreen(GLVertexBuffer *vbo, int vboStart, int \
blurRectCount, QMatrix4x4 screenProjection, QRect windowShape, QPoint windowPosition) \
+{ + glActiveTexture(GL_TEXTURE0);
m_renderTextures[1].bind();
- //Render to the screen
- vbo->draw(GL_TRIANGLES, blurRectCount * (m_downSampleIterations + 1), \
shape.rectCount() * 6); + if (m_noiseStrength > 0) {
+ m_shader->bind(BlurShader::NoiseSampleType);
+ m_shader->setTargetTextureSize(m_renderTextures[0].size());
+ m_shader->setNoiseTextureSize(m_noiseTexture.size());
+ m_shader->setTexturePosition(windowPosition);
- if (opacity < 1.0) {
- glDisable(GL_BLEND);
+ glActiveTexture(GL_TEXTURE1);
+ m_noiseTexture.bind();
+ } else {
+ m_shader->bind(BlurShader::UpSampleType);
+ m_shader->setTargetTextureSize(m_renderTextures[0].size());
}
- vbo->unbindArrays();
+ m_shader->setOffset(m_offset);
+ m_shader->setModelViewProjectionMatrix(screenProjection);
+
+ //Render to the screen
+ vbo->draw(GL_TRIANGLES, vboStart, blurRectCount);
+
+ glActiveTexture(GL_TEXTURE0);
m_shader->unbind();
}
@@ -661,7 +714,7 @@ void BlurEffect::downSampleTexture(GLVertexBuffer *vbo, int \
blurRectCount)
modelViewProjectionMatrix.ortho(0, m_renderTextures[i].width(), \
m_renderTextures[i].height(), 0 , 0, 65535);
m_shader->setModelViewProjectionMatrix(modelViewProjectionMatrix);
- m_shader->setTargetSize(m_renderTextures[i].size());
+ m_shader->setTargetTextureSize(m_renderTextures[i].size());
//Copy the image from this texture
m_renderTextures[i - 1].bind();
@@ -680,12 +733,12 @@ void BlurEffect::upSampleTexture(GLVertexBuffer *vbo, int \
blurRectCount) m_shader->bind(BlurShader::UpSampleType);
m_shader->setOffset(m_offset);
- for (int i = m_downSampleIterations - 1; i > 0; i--) {
+ for (int i = m_downSampleIterations - 1; i >= 1; i--) {
modelViewProjectionMatrix.setToIdentity();
modelViewProjectionMatrix.ortho(0, m_renderTextures[i].width(), \
m_renderTextures[i].height(), 0 , 0, 65535);
m_shader->setModelViewProjectionMatrix(modelViewProjectionMatrix);
- m_shader->setTargetSize(m_renderTextures[i].size());
+ m_shader->setTargetTextureSize(m_renderTextures[i].size());
//Copy the image from this texture
m_renderTextures[i + 1].bind();
@@ -702,7 +755,7 @@ void BlurEffect::copyScreenSampleTexture(GLVertexBuffer *vbo, int \
blurRectCount, m_shader->bind(BlurShader::CopySampleType);
m_shader->setModelViewProjectionMatrix(screenProjection);
- m_shader->setTargetSize(screenSize);
+ m_shader->setTargetTextureSize(screenSize);
/*
* This '1' sized adjustment is necessary do avoid windows affecting the blur \
that are
diff --git a/effects/blur/blur.h b/effects/blur/blur.h
index 334352317..06274e2d3 100644
--- a/effects/blur/blur.h
+++ b/effects/blur/blur.h
@@ -83,10 +83,12 @@ private:
QRegion blurRegion(const EffectWindow *w) const;
bool shouldBlur(const EffectWindow *w, int mask, const WindowPaintData &data) \
const; void updateBlurRegion(EffectWindow *w) const;
- void doBlur(const QRegion &shape, const QRect &screen, const float opacity, \
const QMatrix4x4 &screenProjection, bool isDock); + void doBlur(const QRegion \
&shape, const QRect &screen, const float opacity, const QMatrix4x4 &screenProjection, \
bool isDock, QRect windowRect);
void uploadRegion(QVector2D *&map, const QRegion ®ion, const int \
downSampleIterations);
void uploadGeometry(GLVertexBuffer *vbo, const QRegion &blurRegion, const \
QRegion &windowRegion); + void generateNoiseTexture();
+ void upscaleRenderToScreen(GLVertexBuffer *vbo, int vboStart, int blurRectCount, \
QMatrix4x4 screenProjection, QRect windowShape, QPoint windowPosition); void \
downSampleTexture(GLVertexBuffer *vbo, int blurRectCount); void \
upSampleTexture(GLVertexBuffer *vbo, int blurRectCount);
void copyScreenSampleTexture(GLVertexBuffer *vbo, int blurRectCount, QRegion \
blurShape, QSize screenSize, QMatrix4x4 screenProjection); @@ -96,6 +98,9 @@ private:
QVector <GLRenderTarget*> m_renderTargets;
QVector <GLTexture> m_renderTextures;
QStack <GLRenderTarget*> m_renderTargetStack;
+
+ GLTexture m_noiseTexture;
+
bool m_renderTargetsValid;
long net_wm_blur_region;
QRegion m_damagedArea; // keeps track of the area which has been damaged (from \
bottom to top) @@ -105,6 +110,8 @@ private:
int m_downSampleIterations; // number of times the texture will be downsized to \
half size int m_offset;
int m_expandSize;
+ int m_noiseStrength;
+ int m_scalingFactor;
struct OffsetStruct {
float minOffset;
diff --git a/effects/blur/blur.kcfg b/effects/blur/blur.kcfg
index 7e0c26332..8c215404d 100644
--- a/effects/blur/blur.kcfg
+++ b/effects/blur/blur.kcfg
@@ -8,5 +8,8 @@
<entry name="BlurStrength" type="Int">
<default>10</default>
</entry>
+ <entry name="NoiseStrength" type="Int">
+ <default>5</default>
+ </entry>
</group>
</kcfg>
diff --git a/effects/blur/blur_config.ui b/effects/blur/blur_config.ui
index a5da6ed7c..283fff79a 100644
--- a/effects/blur/blur_config.ui
+++ b/effects/blur/blur_config.ui
@@ -7,14 +7,14 @@
<x>0</x>
<y>0</y>
<width>480</width>
- <height>95</height>
+ <height>184</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
- <widget class="QLabel" name="labelConstantExplanation">
+ <widget class="QLabel" name="labelConstantBlurDescription">
<property name="text">
- <string>Strength of the effect:</string>
+ <string>Blur strength:</string>
</property>
</widget>
</item>
@@ -37,7 +37,7 @@
</spacer>
</item>
<item>
- <widget class="QLabel" name="labelConstantLight">
+ <widget class="QLabel" name="labelConstantBlurLight">
<property name="text">
<string>Light</string>
</property>
@@ -69,7 +69,70 @@
</widget>
</item>
<item>
- <widget class="QLabel" name="labelConstantStrong">
+ <widget class="QLabel" name="labelConstantBlurStrong">
+ <property name="text">
+ <string>Strong</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QLabel" name="labelConstantNoiseDescription">
+ <property name="text">
+ <string>Noise strength:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_2">
+ <item>
+ <spacer name="horizontalSpacer_2">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::Fixed</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QLabel" name="labelConstantNoiseLight">
+ <property name="text">
+ <string>Light</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QSlider" name="kcfg_NoiseStrength">
+ <property name="maximum">
+ <number>14</number>
+ </property>
+ <property name="pageStep">
+ <number>5</number>
+ </property>
+ <property name="value">
+ <number>5</number>
+ </property>
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="tickPosition">
+ <enum>QSlider::TicksBelow</enum>
+ </property>
+ <property name="tickInterval">
+ <number>1</number>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="labelConstantNoiseStrong">
<property name="text">
<string>Strong</string>
</property>
diff --git a/effects/blur/blurshader.cpp b/effects/blur/blurshader.cpp
index c6957a0d9..d16600ef1 100644
--- a/effects/blur/blurshader.cpp
+++ b/effects/blur/blurshader.cpp
@@ -73,6 +73,9 @@ void GLSLBlurShader::reset()
delete m_shaderCopysample;
m_shaderCopysample = nullptr;
+ delete m_shaderNoisesample;
+ m_shaderNoisesample = nullptr;
+
setIsValid(false);
}
@@ -105,6 +108,14 @@ void GLSLBlurShader::setModelViewProjectionMatrix(const \
QMatrix4x4 &matrix) m_matrixDownsample = matrix;
m_shaderDownsample->setUniform(m_mvpMatrixLocationDownsample, matrix);
break;
+
+ case NoiseSampleType:
+ if (matrix == m_matrixNoisesample)
+ return;
+
+ m_matrixNoisesample = matrix;
+ m_shaderNoisesample->setUniform(m_mvpMatrixLocationNoisesample, matrix);
+ break;
}
}
@@ -129,10 +140,18 @@ void GLSLBlurShader::setOffset(float offset)
m_offsetDownsample = offset;
m_shaderDownsample->setUniform(m_offsetLocationDownsample, offset);
break;
+
+ case NoiseSampleType:
+ if (offset == m_offsetNoisesample)
+ return;
+
+ m_offsetNoisesample = offset;
+ m_shaderNoisesample->setUniform(m_offsetLocationNoisesample, offset);
+ break;
}
}
-void GLSLBlurShader::setTargetSize(QSize renderTextureSize)
+void GLSLBlurShader::setTargetTextureSize(QSize renderTextureSize)
{
if (!isValid())
return;
@@ -141,33 +160,41 @@ void GLSLBlurShader::setTargetSize(QSize renderTextureSize)
switch (m_activeSampleType) {
case CopySampleType:
- if (renderTextureSize == m_renderTextureSizeCopysample)
- return;
-
- m_renderTextureSizeCopysample = renderTextureSize;
m_shaderCopysample->setUniform(m_renderTextureSizeLocationCopysample, \
texSize); break;
case UpSampleType:
- if (renderTextureSize == m_renderTextureSizeUpsample)
- return;
-
- m_renderTextureSizeUpsample = renderTextureSize;
m_shaderUpsample->setUniform(m_renderTextureSizeLocationUpsample, \
texSize);
m_shaderUpsample->setUniform(m_halfpixelLocationUpsample, QVector2D(0.5 \
/ texSize.x(), 0.5 / texSize.y())); break;
case DownSampleType:
- if (renderTextureSize == m_renderTextureSizeDownsample)
- return;
-
- m_renderTextureSizeDownsample = renderTextureSize;
m_shaderDownsample->setUniform(m_renderTextureSizeLocationDownsample, \
texSize);
m_shaderDownsample->setUniform(m_halfpixelLocationDownsample, \
QVector2D(0.5 / texSize.x(), 0.5 / texSize.y())); break;
+
+ case NoiseSampleType:
+ m_shaderNoisesample->setUniform(m_renderTextureSizeLocationNoisesample, \
texSize); + \
m_shaderNoisesample->setUniform(m_halfpixelLocationNoisesample, QVector2D(0.5 / \
texSize.x(), 0.5 / texSize.y())); + break;
}
}
+void GLSLBlurShader::setNoiseTextureSize(QSize noiseTextureSize)
+{
+ QVector2D noiseTexSize = QVector2D(noiseTextureSize.width(), \
noiseTextureSize.height()); +
+ if (noiseTexSize != m_noiseTextureSizeNoisesample) {
+ m_noiseTextureSizeNoisesample = noiseTexSize;
+ m_shaderNoisesample->setUniform(m_noiseTextureSizeLocationNoisesample, \
noiseTexSize); + }
+}
+
+void GLSLBlurShader::setTexturePosition(QPoint texPos)
+{
+ m_shaderNoisesample->setUniform(m_texStartPosLocationNoisesample, \
QVector2D(-texPos.x(), texPos.y())); +}
+
void GLSLBlurShader::setBlurRect(QRect blurRect, QSize screenSize)
{
if (!isValid() || blurRect == m_blurRectCopysample)
@@ -177,9 +204,9 @@ void GLSLBlurShader::setBlurRect(QRect blurRect, QSize \
screenSize)
QVector4D rect = QVector4D(
blurRect.bottomLeft().x() / float(screenSize.width()),
- 1.0 - blurRect.bottomLeft().y() / float(screenSize.height()),
- blurRect.topRight().x() / float(screenSize.width()),
- 1.0 - blurRect.topRight().y() / float(screenSize.height())
+ 1.0 - blurRect.bottomLeft().y() / \
float(screenSize.height()), + blurRect.topRight().x() \
/ float(screenSize.width()), + 1.0 - \
blurRect.topRight().y() / float(screenSize.height()) );
m_shaderCopysample->setUniform(m_blurRectLocationCopysample, rect);
@@ -202,6 +229,10 @@ void GLSLBlurShader::bind(SampleType sampleType)
case DownSampleType:
ShaderManager::instance()->pushShader(m_shaderDownsample);
break;
+
+ case NoiseSampleType:
+ ShaderManager::instance()->pushShader(m_shaderNoisesample);
+ break;
}
m_activeSampleType = sampleType;
@@ -222,6 +253,7 @@ void GLSLBlurShader::init()
QByteArray fragmentDownSource;
QByteArray fragmentUpSource;
QByteArray fragmentCopySource;
+ QByteArray fragmentNoiseSource;
const QByteArray attribute = core ? "in" : "attribute";
const QByteArray texture2D = core ? "texture" : "texture2D";
@@ -331,12 +363,46 @@ void GLSLBlurShader::init()
streamFragCopy.flush();
-
- m_shaderDownsample = ShaderManager::instance()->loadShaderFromCode(vertexSource, \
fragmentDownSource);
- m_shaderUpsample = ShaderManager::instance()->loadShaderFromCode(vertexSource, \
fragmentUpSource);
- m_shaderCopysample = ShaderManager::instance()->loadShaderFromCode(vertexSource, \
fragmentCopySource);
-
- bool areShadersValid = m_shaderDownsample->isValid() && \
m_shaderUpsample->isValid() && m_shaderCopysample->isValid(); + // Fragment shader \
- Noise texture + // \
=================================================================== + QTextStream \
streamFragNoise(&fragmentNoiseSource); +
+ streamFragNoise << glHeaderString << glUniformString;
+
+ streamFragNoise << "uniform sampler2D noiseTexUnit;\n";
+ streamFragNoise << "uniform vec2 noiseTextureSize;\n";
+ streamFragNoise << "uniform vec2 texStartPos;\n";
+
+ // Upsampling + Noise
+ streamFragNoise << "void main(void)\n";
+ streamFragNoise << "{\n";
+ streamFragNoise << " vec2 uv = vec2(gl_FragCoord.xy / renderTextureSize);\n";
+ streamFragNoise << " vec2 uvNoise = vec2((texStartPos.xy + gl_FragCoord.xy) / \
noiseTextureSize);\n"; + streamFragNoise << " \n";
+ streamFragNoise << " vec4 sum = " << texture2D << "(texUnit, uv + \
vec2(-halfpixel.x * 2.0, 0.0) * offset);\n"; + streamFragNoise << " sum += " << \
texture2D << "(texUnit, uv + vec2(-halfpixel.x, halfpixel.y) * offset) * 2.0;\n"; + \
streamFragNoise << " sum += " << texture2D << "(texUnit, uv + vec2(0.0, \
halfpixel.y * 2.0) * offset);\n"; + streamFragNoise << " sum += " << texture2D \
<< "(texUnit, uv + vec2(halfpixel.x, halfpixel.y) * offset) * 2.0;\n"; + \
streamFragNoise << " sum += " << texture2D << "(texUnit, uv + vec2(halfpixel.x * \
2.0, 0.0) * offset);\n"; + streamFragNoise << " sum += " << texture2D << \
"(texUnit, uv + vec2(halfpixel.x, -halfpixel.y) * offset) * 2.0;\n"; + \
streamFragNoise << " sum += " << texture2D << "(texUnit, uv + vec2(0.0, \
-halfpixel.y * 2.0) * offset);\n"; + streamFragNoise << " sum += " << texture2D \
<< "(texUnit, uv + vec2(-halfpixel.x, -halfpixel.y) * offset) * 2.0;\n"; + \
streamFragNoise << " \n"; + streamFragNoise << " " << fragColor << " = sum / \
12.0 - (vec4(0.5, 0.5, 0.5, 0) - vec4(" << texture2D << "(noiseTexUnit, uvNoise).rrr, \
0));\n"; + streamFragNoise << "}\n";
+
+ streamFragNoise.flush();
+
+
+ m_shaderDownsample = \
ShaderManager::instance()->loadShaderFromCode(vertexSource, fragmentDownSource); + \
m_shaderUpsample = ShaderManager::instance()->loadShaderFromCode(vertexSource, \
fragmentUpSource); + m_shaderCopysample = \
ShaderManager::instance()->loadShaderFromCode(vertexSource, fragmentCopySource); + \
m_shaderNoisesample = ShaderManager::instance()->loadShaderFromCode(vertexSource, \
fragmentNoiseSource); +
+ bool areShadersValid = m_shaderDownsample->isValid() &&
+ m_shaderUpsample->isValid() &&
+ m_shaderCopysample->isValid() &&
+ m_shaderNoisesample->isValid();
setIsValid(areShadersValid);
if (areShadersValid) {
@@ -354,6 +420,13 @@ void GLSLBlurShader::init()
m_renderTextureSizeLocationCopysample = \
m_shaderCopysample->uniformLocation("renderTextureSize");
m_blurRectLocationCopysample = \
m_shaderCopysample->uniformLocation("blurRect");
+ m_mvpMatrixLocationNoisesample = \
m_shaderNoisesample->uniformLocation("modelViewProjectionMatrix"); + \
m_offsetLocationNoisesample = m_shaderNoisesample->uniformLocation("offset"); + \
m_renderTextureSizeLocationNoisesample = \
m_shaderNoisesample->uniformLocation("renderTextureSize"); + \
m_noiseTextureSizeLocationNoisesample = \
m_shaderNoisesample->uniformLocation("noiseTextureSize"); + \
m_texStartPosLocationNoisesample = \
m_shaderNoisesample->uniformLocation("texStartPos"); + \
m_halfpixelLocationNoisesample = m_shaderNoisesample->uniformLocation("halfpixel"); +
QMatrix4x4 modelViewProjection;
const QSize screenSize = effects->virtualScreenSize();
modelViewProjection.ortho(0, screenSize.width(), screenSize.height(), 0, 0, \
65535); @@ -379,6 +452,32 @@ void GLSLBlurShader::init()
m_shaderCopysample->setUniform(m_blurRectLocationCopysample, QVector4D(1.0, \
1.0, 1.0, 1.0)); ShaderManager::instance()->popShader();
+ ShaderManager::instance()->pushShader(m_shaderNoisesample);
+ m_shaderNoisesample->setUniform(m_mvpMatrixLocationNoisesample, \
modelViewProjection); + \
m_shaderNoisesample->setUniform(m_offsetLocationNoisesample, float(1.0)); + \
m_shaderNoisesample->setUniform(m_renderTextureSizeLocationNoisesample, \
QVector2D(1.0, 1.0)); + \
m_shaderNoisesample->setUniform(m_noiseTextureSizeLocationNoisesample, QVector2D(1.0, \
1.0)); + m_shaderNoisesample->setUniform(m_texStartPosLocationNoisesample, \
QVector2D(1.0, 1.0)); + \
m_shaderNoisesample->setUniform(m_halfpixelLocationNoisesample, QVector2D(1.0, 1.0)); \
+ + glUniform1i(m_shaderNoisesample->uniformLocation("texUnit"), 0);
+ glUniform1i(m_shaderNoisesample->uniformLocation("noiseTexUnit"), 1);
+
+ ShaderManager::instance()->popShader();
+
m_activeSampleType = -1;
+
+ m_offsetDownsample = 0.0;
+ m_matrixDownsample = QMatrix4x4();
+
+ m_offsetUpsample = 0.0;
+ m_matrixUpsample = QMatrix4x4();
+
+ m_matrixCopysample = QMatrix4x4();
+ m_blurRectCopysample = QRect();
+
+ m_offsetNoisesample = 0.0;
+ m_noiseTextureSizeNoisesample = QVector2D();
+ m_matrixNoisesample = QMatrix4x4();
}
}
diff --git a/effects/blur/blurshader.h b/effects/blur/blurshader.h
index a69811a1f..81f4ddee9 100644
--- a/effects/blur/blurshader.h
+++ b/effects/blur/blurshader.h
@@ -45,13 +45,16 @@ public:
virtual void setModelViewProjectionMatrix(const QMatrix4x4 &matrix) = 0;
virtual void setOffset(float offset) = 0;
- virtual void setTargetSize(QSize renderTextureSize) = 0;
+ virtual void setTargetTextureSize(QSize renderTextureSize) = 0;
+ virtual void setNoiseTextureSize(QSize noiseTextureSize) = 0;
+ virtual void setTexturePosition(QPoint texPos) = 0;
virtual void setBlurRect(QRect blurRect, QSize screenSize) = 0;
enum SampleType {
DownSampleType,
UpSampleType,
- CopySampleType
+ CopySampleType,
+ NoiseSampleType
};
virtual void bind(SampleType sampleType) = 0;
@@ -83,7 +86,9 @@ public:
void unbind() override final;
void setModelViewProjectionMatrix(const QMatrix4x4 &matrix) override final;
void setOffset(float offset) override final;
- void setTargetSize(QSize renderTextureSize) override final;
+ void setTargetTextureSize(QSize renderTextureSize) override final;
+ void setNoiseTextureSize(QSize noiseTextureSize) override final;
+ void setTexturePosition(QPoint texPos) override final;
void setBlurRect(QRect blurRect, QSize screenSize) override final;
protected:
@@ -94,6 +99,7 @@ private:
GLShader *m_shaderDownsample = nullptr;
GLShader *m_shaderUpsample = nullptr;
GLShader *m_shaderCopysample = nullptr;
+ GLShader *m_shaderNoisesample = nullptr;
int m_mvpMatrixLocationDownsample;
int m_offsetLocationDownsample;
@@ -109,22 +115,30 @@ private:
int m_renderTextureSizeLocationCopysample;
int m_blurRectLocationCopysample;
+ int m_mvpMatrixLocationNoisesample;
+ int m_offsetLocationNoisesample;
+ int m_renderTextureSizeLocationNoisesample;
+ int m_noiseTextureSizeLocationNoisesample;
+ int m_texStartPosLocationNoisesample;
+ int m_halfpixelLocationNoisesample;
+
//Caching uniform values to aviod unnecessary setUniform calls
int m_activeSampleType;
float m_offsetDownsample;
QMatrix4x4 m_matrixDownsample;
- QSize m_renderTextureSizeDownsample;
float m_offsetUpsample;
QMatrix4x4 m_matrixUpsample;
- QSize m_renderTextureSizeUpsample;
QMatrix4x4 m_matrixCopysample;
- QSize m_renderTextureSizeCopysample;
QRect m_blurRectCopysample;
+ float m_offsetNoisesample;
+ QVector2D m_noiseTextureSizeNoisesample;
+ QMatrix4x4 m_matrixNoisesample;
+
};
} // namespace KWin
diff --git a/libkwineffects/kwingltexture.cpp b/libkwineffects/kwingltexture.cpp
index 0ecce612b..8b9652028 100644
--- a/libkwineffects/kwingltexture.cpp
+++ b/libkwineffects/kwingltexture.cpp
@@ -125,6 +125,8 @@ GLTexture::GLTexture(const QImage& image, GLenum target)
{ GL_RGB10_A2, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV }, // \
QImage::Format_A2BGR30_Premultiplied
{ GL_RGB10, GL_BGRA, GL_UNSIGNED_INT_2_10_10_10_REV }, // \
QImage::Format_RGB30
{ GL_RGB10_A2, GL_BGRA, GL_UNSIGNED_INT_2_10_10_10_REV }, // \
QImage::Format_A2RGB30_Premultiplied + { GL_R8, GL_RED, \
GL_UNSIGNED_BYTE }, // QImage::Format_Alpha8 + { GL_R8, \
GL_RED, GL_UNSIGNED_BYTE }, // QImage::Format_Grayscale8 };
QImage im;
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic