[plasma/kwin] src: opengl: Pre-multiply RGB values in QColor uniforms
Vlad Zahorodnii <[email protected]>
| Newsgroups | gmane.comp.kde.cvs |
|---|---|
| Message-ID | <[email protected]> |
Git commit c908a326186e0e0dfddb03b1b314126a632be513 by Vlad Zahorodnii.
Committed on 21/07/2026 at 07:31.
Pushed by vladz into branch 'master'.
opengl: Pre-multiply RGB values in QColor uniforms
The blend equation that we often use assumes that the RGB values are
pre-multiplied by the alpha value. So perform the pre-multiplication
step when the uniform is set.
We could require that the input QColor needs to have the RGB values
pre-multiplied but that'll be inconvenient and easy to forget.
This should fix QColor::alpha() not doing anything with border outlines.
M +8 -1 src/opengl/glshader.cpp
M +8 -0 src/opengl/glshader.h
M +1 -1 src/plugins/mouseclick/mouseclick.cpp
M +1 -1 src/plugins/showpaint/showpaint.cpp
M +1 -1 src/plugins/touchpoints/touchpoints.cpp
https://invent.kde.org/plasma/kwin/-/commit/c908a326186e0e0dfddb03b1b314126a632be513
diff --git a/src/opengl/glshader.cpp b/src/opengl/glshader.cpp
index 8518d1b5f1b..399902cb0b8 100644
--- a/src/opengl/glshader.cpp
+++ b/src/opengl/glshader.cpp
@@ -461,7 +461,14 @@ bool GLShader::setUniform(int location, const QMatrix4x4 &value)
bool GLShader::setUniform(int location, const QColor &color)
{
if (location >= 0) {
- glUniform4f(location, color.redF(), color.greenF(), color.blueF(), color.alphaF());
+ // Pre-multiply RGB values with the alpha channel. The blend equation that we often
+ // use assumes that colors are pre-multiplied by the alpha value.
+ const float alpha = color.alphaF();
+ const float red = color.redF() * alpha;
+ const float green = color.greenF() * alpha;
+ const float blue = color.blueF() * alpha;
+
+ glUniform4f(location, red, green, blue, alpha);
}
return (location >= 0);
}
diff --git a/src/opengl/glshader.h b/src/opengl/glshader.h
index 7efc35314a9..124c6f0bbf2 100644
--- a/src/opengl/glshader.h
+++ b/src/opengl/glshader.h
@@ -55,6 +55,10 @@ public:
bool setUniform(int location, const QVector4D &value);
bool setUniform(int location, const QMatrix3x3 &value);
bool setUniform(int location, const QMatrix4x4 &value);
+
+ /**
+ * The RGB values will be pre-multiplied with the alpha value.
+ */
bool setUniform(int location, const QColor &value);
int attributeLocation(const char *name);
@@ -134,6 +138,10 @@ public:
bool setUniform(FloatUniform uniform, float value);
bool setUniform(IntUniform uniform, int value);
bool setUniform(ColorUniform uniform, const QVector4D &value);
+
+ /**
+ * The RGB values will be pre-multiplied with the alpha value.
+ */
bool setUniform(ColorUniform uniform, const QColor &value);
void setColorspaceUniforms(const std::shared_ptr<ColorDescription> &src, const std::shared_ptr<ColorDescription> &dst, RenderingIntent intent);
diff --git a/src/plugins/mouseclick/mouseclick.cpp b/src/plugins/mouseclick/mouseclick.cpp
index f2e783e62c4..2e02c1af7ba 100644
--- a/src/plugins/mouseclick/mouseclick.cpp
+++ b/src/plugins/mouseclick/mouseclick.cpp
@@ -290,7 +290,7 @@ void MouseClickEffect::paintScreenSetupGl(const RenderTarget &renderTarget, cons
glLineWidth(m_lineWidth);
glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
}
void MouseClickEffect::paintScreenFinishGl()
diff --git a/src/plugins/showpaint/showpaint.cpp b/src/plugins/showpaint/showpaint.cpp
index e99c0432d96..1687bf47877 100644
--- a/src/plugins/showpaint/showpaint.cpp
+++ b/src/plugins/showpaint/showpaint.cpp
@@ -52,7 +52,7 @@ void ShowPaintEffect::paintGL(const RenderTarget &renderTarget, const RenderView
binder.shader()->setUniform(GLShader::Mat4Uniform::ModelViewProjectionMatrix, viewport.projectionMatrix());
binder.shader()->setColorspaceUniforms(ColorDescription::sRGB, renderTarget.colorDescription(), RenderingIntent::Perceptual);
glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
QColor color = s_colors[m_colorIndex];
color.setAlphaF(s_alpha);
binder.shader()->setUniform(GLShader::ColorUniform::Color, color);
diff --git a/src/plugins/touchpoints/touchpoints.cpp b/src/plugins/touchpoints/touchpoints.cpp
index 63e5b5f290c..cf8d7ad0e3b 100644
--- a/src/plugins/touchpoints/touchpoints.cpp
+++ b/src/plugins/touchpoints/touchpoints.cpp
@@ -218,7 +218,7 @@ void TouchPointsEffect::paintScreenSetupGl(const RenderTarget &renderTarget, con
glLineWidth(m_lineWidth);
glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
}
void TouchPointsEffect::paintScreenFinishGl()