kwin: Replace brightness and opacity with a modulation constant
This makes it possible to adjust both brightness and opacity at the same time with one multiplication in the fragment shader.
This commit is contained in:
parent
175b45c5de
commit
73be6657ea
7 changed files with 89 additions and 43 deletions
|
@ -1,8 +1,7 @@
|
|||
uniform sampler2D sample;
|
||||
uniform vec4 modulation;
|
||||
uniform float textureWidth;
|
||||
uniform float textureHeight;
|
||||
uniform float opacity;
|
||||
uniform float brightness;
|
||||
uniform float saturation;
|
||||
uniform int u_forceAlpha;
|
||||
|
||||
|
@ -11,17 +10,19 @@ varying vec2 varyingTexCoords;
|
|||
void main()
|
||||
{
|
||||
vec4 tex = texture2D(sample, varyingTexCoords);
|
||||
|
||||
if (u_forceAlpha > 0) {
|
||||
tex.a = 1.0;
|
||||
}
|
||||
|
||||
if (saturation != 1.0) {
|
||||
vec3 desaturated = tex.rgb * vec3( 0.30, 0.59, 0.11 );
|
||||
desaturated = vec3( dot( desaturated, tex.rgb ));
|
||||
tex.rgb = tex.rgb * vec3( saturation ) + desaturated * vec3( 1.0 - saturation );
|
||||
}
|
||||
tex.rgb = tex.rgb * opacity * vec3( brightness );
|
||||
|
||||
tex *= modulation;
|
||||
tex.rgb = vec3(1.0) - tex.rgb;
|
||||
tex.a = tex.a * opacity;
|
||||
|
||||
gl_FragColor = tex;
|
||||
}
|
||||
|
|
|
@ -324,9 +324,10 @@ void PresentWindowsEffect::paintWindow(EffectWindow *w, int mask, QRegion region
|
|||
m_windowData[w].iconFrame->setPosition(point);
|
||||
#ifdef KWIN_HAVE_OPENGL_COMPOSITING
|
||||
if (effects->compositingType() == KWin::OpenGLCompositing && data.shader) {
|
||||
const float a = 0.9 * data.opacity * m_decalOpacity * 0.75;
|
||||
data.shader->setUniform(GLShader::TextureWidth, 1.0f);
|
||||
data.shader->setUniform(GLShader::TextureHeight, 1.0f);
|
||||
data.shader->setUniform(GLShader::Opacity, 0.9 * data.opacity * m_decalOpacity * 0.75);
|
||||
data.shader->setUniform(GLShader::ModulationConstant, QVector4D(a, a, a, a));
|
||||
}
|
||||
#endif
|
||||
m_windowData[w].iconFrame->render(region, 0.9 * data.opacity * m_decalOpacity, 0.75);
|
||||
|
@ -337,9 +338,10 @@ void PresentWindowsEffect::paintWindow(EffectWindow *w, int mask, QRegion region
|
|||
m_windowData[w].textFrame->setPosition(point);
|
||||
#ifdef KWIN_HAVE_OPENGL_COMPOSITING
|
||||
if (effects->compositingType() == KWin::OpenGLCompositing && data.shader) {
|
||||
const float a = 0.9 * data.opacity * m_decalOpacity * 0.75;
|
||||
data.shader->setUniform(GLShader::TextureWidth, 1.0f);
|
||||
data.shader->setUniform(GLShader::TextureHeight, 1.0f);
|
||||
data.shader->setUniform(GLShader::Opacity, 0.9 * data.opacity * m_decalOpacity * 0.75);
|
||||
data.shader->setUniform(GLShader::ModulationConstant, QVector4D(a, a, a, a));
|
||||
}
|
||||
#endif
|
||||
m_windowData[w].textFrame->render(region, 0.9 * data.opacity * m_decalOpacity, 0.75);
|
||||
|
|
|
@ -207,6 +207,7 @@ void LanczosFilter::performPaint(EffectWindowImpl* w, int mask, QRegion region,
|
|||
|
||||
int sw = width;
|
||||
int sh = height;
|
||||
|
||||
GLTexture *cachedTexture = static_cast< GLTexture*>(w->data(LanczosCacheRole).value<void*>());
|
||||
if (cachedTexture) {
|
||||
if (cachedTexture->width() == tw && cachedTexture->height() == th) {
|
||||
|
@ -214,13 +215,18 @@ void LanczosFilter::performPaint(EffectWindowImpl* w, int mask, QRegion region,
|
|||
if (ShaderManager::instance()->isValid()) {
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
const float rgb = data.brightness * data.opacity;
|
||||
const float a = data.opacity;
|
||||
|
||||
GLShader *shader = ShaderManager::instance()->pushShader(ShaderManager::SimpleShader);
|
||||
shader->setUniform(GLShader::Offset, QVector2D(0, 0));
|
||||
shader->setUniform(GLShader::Opacity, data.opacity);
|
||||
shader->setUniform(GLShader::Brightness, data.brightness);
|
||||
shader->setUniform(GLShader::ModulationConstant, QVector4D(rgb, rgb, rgb, a));
|
||||
shader->setUniform(GLShader::Saturation, data.saturation);
|
||||
shader->setUniform(GLShader::AlphaToOne, 0);
|
||||
|
||||
cachedTexture->render(textureRect, textureRect);
|
||||
|
||||
ShaderManager::instance()->popShader();
|
||||
glDisable(GL_BLEND);
|
||||
} else {
|
||||
|
@ -336,16 +342,22 @@ void LanczosFilter::performPaint(EffectWindowImpl* w, int mask, QRegion region,
|
|||
cache->bind();
|
||||
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, m_offscreenTex->height() - th, tw, th);
|
||||
effects->popRenderTarget();
|
||||
|
||||
if (ShaderManager::instance()->isValid()) {
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
const float rgb = data.brightness * data.opacity;
|
||||
const float a = data.opacity;
|
||||
|
||||
GLShader *shader = ShaderManager::instance()->pushShader(ShaderManager::SimpleShader);
|
||||
shader->setUniform(GLShader::Offset, QVector2D(0, 0));
|
||||
shader->setUniform(GLShader::Opacity, data.opacity);
|
||||
shader->setUniform(GLShader::Brightness, data.brightness);
|
||||
shader->setUniform(GLShader::ModulationConstant, QVector4D(rgb, rgb, rgb, a));
|
||||
shader->setUniform(GLShader::Saturation, data.saturation);
|
||||
shader->setUniform(GLShader::AlphaToOne, 0);
|
||||
|
||||
cache->render(textureRect, textureRect);
|
||||
|
||||
ShaderManager::instance()->popShader();
|
||||
glDisable(GL_BLEND);
|
||||
} else {
|
||||
|
@ -353,6 +365,7 @@ void LanczosFilter::performPaint(EffectWindowImpl* w, int mask, QRegion region,
|
|||
cache->render(textureRect, textureRect);
|
||||
restoreRenderStates(cache, data.opacity, data.brightness, data.saturation);
|
||||
}
|
||||
|
||||
cache->unbind();
|
||||
w->setData(LanczosCacheRole, QVariant::fromValue(static_cast<void*>(cache)));
|
||||
|
||||
|
|
|
@ -870,8 +870,8 @@ void GLShader::resolveLocations()
|
|||
|
||||
mVec2Location[Offset] = uniformLocation("offset");
|
||||
|
||||
mFloatLocation[Opacity] = uniformLocation("opacity");
|
||||
mFloatLocation[Brightness] = uniformLocation("brightness");
|
||||
mVec4Location[ModulationConstant] = uniformLocation("modulation");
|
||||
|
||||
mFloatLocation[Saturation] = uniformLocation("saturation");
|
||||
mFloatLocation[TextureWidth] = uniformLocation("textureWidth");
|
||||
mFloatLocation[TextureHeight] = uniformLocation("textureHeight");
|
||||
|
@ -899,6 +899,12 @@ bool GLShader::setUniform(GLShader::Vec2Uniform uniform, const QVector2D &value)
|
|||
return setUniform(mVec2Location[uniform], value);
|
||||
}
|
||||
|
||||
bool GLShader::setUniform(GLShader::Vec4Uniform uniform, const QVector4D &value)
|
||||
{
|
||||
resolveLocations();
|
||||
return setUniform(mVec4Location[uniform], value);
|
||||
}
|
||||
|
||||
bool GLShader::setUniform(GLShader::FloatUniform uniform, float value)
|
||||
{
|
||||
resolveLocations();
|
||||
|
@ -1329,9 +1335,8 @@ void ShaderManager::resetShader(ShaderType type)
|
|||
shader->setUniform(GLShader::WindowTransformation, identity);
|
||||
|
||||
shader->setUniform(GLShader::Offset, QVector2D(0, 0));
|
||||
shader->setUniform(GLShader::ModulationConstant, QVector4D(1.0, 1.0, 1.0, 1.0));
|
||||
|
||||
shader->setUniform(GLShader::Opacity, 1.0f);
|
||||
shader->setUniform(GLShader::Brightness, 1.0f);
|
||||
shader->setUniform(GLShader::Saturation, 1.0f);
|
||||
shader->setUniform(GLShader::AlphaToOne, 0);
|
||||
|
||||
|
|
|
@ -297,9 +297,12 @@ public:
|
|||
Vec2UniformCount
|
||||
};
|
||||
|
||||
enum Vec4Uniform {
|
||||
ModulationConstant,
|
||||
Vec4UniformCount
|
||||
};
|
||||
|
||||
enum FloatUniform {
|
||||
Opacity,
|
||||
Brightness,
|
||||
Saturation,
|
||||
TextureWidth,
|
||||
TextureHeight,
|
||||
|
@ -313,6 +316,7 @@ public:
|
|||
|
||||
bool setUniform(MatrixUniform uniform, const QMatrix4x4 &matrix);
|
||||
bool setUniform(Vec2Uniform uniform, const QVector2D &value);
|
||||
bool setUniform(Vec4Uniform uniform, const QVector4D &value);
|
||||
bool setUniform(FloatUniform uniform, float value);
|
||||
bool setUniform(IntUniform uniform, int value);
|
||||
|
||||
|
@ -340,6 +344,7 @@ private:
|
|||
bool mLocationsResolved:1;
|
||||
int mMatrixLocation[MatrixCount];
|
||||
int mVec2Location[Vec2UniformCount];
|
||||
int mVec4Location[Vec4UniformCount];
|
||||
int mFloatLocation[FloatUniformCount];
|
||||
int mIntLocation[IntUniformCount];
|
||||
float mTextureWidth;
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
uniform sampler2D sample;
|
||||
uniform float opacity;
|
||||
uniform float brightness;
|
||||
uniform vec4 modulation;
|
||||
uniform float saturation;
|
||||
uniform int debug;
|
||||
uniform int u_forceAlpha;
|
||||
|
@ -11,19 +10,22 @@ varying vec2 varyingTexCoords;
|
|||
|
||||
void main() {
|
||||
vec4 tex = texture2D(sample, varyingTexCoords);
|
||||
|
||||
if (u_forceAlpha > 0) {
|
||||
tex.a = 1.0;
|
||||
}
|
||||
|
||||
if( saturation != 1.0 ) {
|
||||
vec3 desaturated = tex.rgb * vec3( 0.30, 0.59, 0.11 );
|
||||
desaturated = vec3( dot( desaturated, tex.rgb ));
|
||||
tex.rgb = tex.rgb * vec3( saturation ) + desaturated * vec3( 1.0 - saturation );
|
||||
}
|
||||
tex.rgb = tex.rgb * opacity * brightness;
|
||||
tex.a = tex.a * opacity;
|
||||
|
||||
tex *= modulation;
|
||||
|
||||
/*if (debug != 0) {
|
||||
tex.g += 0.5;
|
||||
}*/
|
||||
|
||||
|
||||
gl_FragColor = tex;
|
||||
}
|
||||
|
|
|
@ -729,10 +729,13 @@ void SceneOpenGL::Window::prepareShaderRenderStates(TextureType type, double opa
|
|||
glBlendFunc(GL_ONE, GL_ONE_MINUS_CONSTANT_ALPHA);
|
||||
}
|
||||
}
|
||||
shader->setUniform(GLShader::Opacity, opacity);
|
||||
shader->setUniform(GLShader::Saturation, saturation);
|
||||
shader->setUniform(GLShader::Brightness, brightness);
|
||||
shader->setUniform(GLShader::AlphaToOne, opaque ? 1 : 0);
|
||||
|
||||
const float rgb = brightness * opacity;
|
||||
const float a = opacity;
|
||||
|
||||
shader->setUniform(GLShader::ModulationConstant, QVector4D(rgb, rgb, rgb, a));
|
||||
shader->setUniform(GLShader::Saturation, saturation);
|
||||
shader->setUniform(GLShader::AlphaToOne, opaque ? 1 : 0);
|
||||
|
||||
const float texw = shader->textureWidth();
|
||||
const float texh = shader->textureHeight();
|
||||
|
@ -1081,8 +1084,8 @@ void SceneOpenGL::EffectFrame::render(QRegion region, double opacity, double fra
|
|||
if (sceneShader)
|
||||
shader->setUniform(GLShader::Offset, QVector2D(0, 0));
|
||||
|
||||
shader->setUniform(GLShader::ModulationConstant, QVector4D(1.0, 1.0, 1.0, 1.0));
|
||||
shader->setUniform(GLShader::Saturation, 1.0f);
|
||||
shader->setUniform(GLShader::Brightness, 1.0f);
|
||||
shader->setUniform(GLShader::AlphaToOne, 0);
|
||||
|
||||
shader->setUniform(GLShader::TextureWidth, 1.0f);
|
||||
|
@ -1210,8 +1213,10 @@ void SceneOpenGL::EffectFrame::render(QRegion region, double opacity, double fra
|
|||
m_unstyledVBO->setData(verts.count() / 2, 2, verts.data(), texCoords.data());
|
||||
}
|
||||
|
||||
if (shader)
|
||||
shader->setUniform(GLShader::Opacity, opacity * frameOpacity);
|
||||
if (shader) {
|
||||
const float a = opacity * frameOpacity;
|
||||
shader->setUniform(GLShader::ModulationConstant, QVector4D(a, a, a, a));
|
||||
}
|
||||
#ifndef KWIN_HAVE_OPENGLES
|
||||
else
|
||||
glColor4f(0.0, 0.0, 0.0, opacity * frameOpacity);
|
||||
|
@ -1243,8 +1248,10 @@ void SceneOpenGL::EffectFrame::render(QRegion region, double opacity, double fra
|
|||
if (!m_texture) // Lazy creation
|
||||
updateTexture();
|
||||
|
||||
if (shader)
|
||||
shader->setUniform(GLShader::Opacity, opacity * frameOpacity);
|
||||
if (shader) {
|
||||
const float a = opacity * frameOpacity;
|
||||
shader->setUniform(GLShader::ModulationConstant, QVector4D(a, a, a, a));
|
||||
}
|
||||
#ifndef KWIN_HAVE_OPENGLES
|
||||
else
|
||||
glColor4f(1.0, 1.0, 1.0, opacity * frameOpacity);
|
||||
|
@ -1275,9 +1282,10 @@ void SceneOpenGL::EffectFrame::render(QRegion region, double opacity, double fra
|
|||
m_effectFrame->geometry().center().y() - m_effectFrame->iconSize().height() / 2);
|
||||
|
||||
if (m_effectFrame->isCrossFade() && m_oldIconTexture) {
|
||||
if (shader)
|
||||
shader->setUniform(GLShader::Opacity,
|
||||
opacity * (1.0f - m_effectFrame->crossFadeProgress()));
|
||||
if (shader) {
|
||||
const float a = opacity * (1.0 - m_effectFrame->crossFadeProgress());
|
||||
shader->setUniform(GLShader::ModulationConstant, QVector4D(a, a, a, a));
|
||||
}
|
||||
#ifndef KWIN_HAVE_OPENGLES
|
||||
else
|
||||
glColor4f(1.0, 1.0, 1.0, opacity * (1.0 - m_effectFrame->crossFadeProgress()));
|
||||
|
@ -1286,15 +1294,19 @@ void SceneOpenGL::EffectFrame::render(QRegion region, double opacity, double fra
|
|||
m_oldIconTexture->bind();
|
||||
m_oldIconTexture->render(region, QRect(topLeft, m_effectFrame->iconSize()));
|
||||
m_oldIconTexture->unbind();
|
||||
if (shader)
|
||||
shader->setUniform(GLShader::Opacity, opacity * m_effectFrame->crossFadeProgress());
|
||||
if (shader) {
|
||||
const float a = opacity * m_effectFrame->crossFadeProgress();
|
||||
shader->setUniform(GLShader::ModulationConstant, QVector4D(a, a, a, a));
|
||||
}
|
||||
#ifndef KWIN_HAVE_OPENGLES
|
||||
else
|
||||
glColor4f(1.0, 1.0, 1.0, opacity * m_effectFrame->crossFadeProgress());
|
||||
#endif
|
||||
} else {
|
||||
if (shader)
|
||||
shader->setUniform(GLShader::Opacity, opacity);
|
||||
if (shader) {
|
||||
const QVector4D constant(opacity, opacity, opacity, opacity);
|
||||
shader->setUniform(GLShader::ModulationConstant, constant);
|
||||
}
|
||||
#ifndef KWIN_HAVE_OPENGLES
|
||||
else
|
||||
glColor4f(1.0, 1.0, 1.0, opacity);
|
||||
|
@ -1315,8 +1327,10 @@ void SceneOpenGL::EffectFrame::render(QRegion region, double opacity, double fra
|
|||
// Render text
|
||||
if (!m_effectFrame->text().isEmpty()) {
|
||||
if (m_effectFrame->isCrossFade() && m_oldTextTexture) {
|
||||
if (shader)
|
||||
shader->setUniform(GLShader::Opacity, opacity * (1.0f - m_effectFrame->crossFadeProgress()));
|
||||
if (shader) {
|
||||
const float a = opacity * (1.0 - m_effectFrame->crossFadeProgress());
|
||||
shader->setUniform(GLShader::ModulationConstant, QVector4D(a, a, a, a));
|
||||
}
|
||||
#ifndef KWIN_HAVE_OPENGLES
|
||||
else
|
||||
glColor4f(1.0, 1.0, 1.0, opacity *(1.0 - m_effectFrame->crossFadeProgress()));
|
||||
|
@ -1325,15 +1339,19 @@ void SceneOpenGL::EffectFrame::render(QRegion region, double opacity, double fra
|
|||
m_oldTextTexture->bind();
|
||||
m_oldTextTexture->render(region, m_effectFrame->geometry());
|
||||
m_oldTextTexture->unbind();
|
||||
if (shader)
|
||||
shader->setUniform(GLShader::Opacity, opacity * m_effectFrame->crossFadeProgress());
|
||||
if (shader) {
|
||||
const float a = opacity * m_effectFrame->crossFadeProgress();
|
||||
shader->setUniform(GLShader::ModulationConstant, QVector4D(a, a, a, a));
|
||||
}
|
||||
#ifndef KWIN_HAVE_OPENGLES
|
||||
else
|
||||
glColor4f(1.0, 1.0, 1.0, opacity * m_effectFrame->crossFadeProgress());
|
||||
#endif
|
||||
} else {
|
||||
if (shader)
|
||||
shader->setUniform(GLShader::Opacity, opacity);
|
||||
if (shader) {
|
||||
const QVector4D constant(opacity, opacity, opacity, opacity);
|
||||
shader->setUniform(GLShader::ModulationConstant, constant);
|
||||
}
|
||||
#ifndef KWIN_HAVE_OPENGLES
|
||||
else
|
||||
glColor4f(1.0, 1.0, 1.0, opacity);
|
||||
|
|
Loading…
Reference in a new issue