KWin
Loading...
Searching...
No Matches
contrastshader.cpp
Go to the documentation of this file.
1/*
2 SPDX-FileCopyrightText: 2010 Fredrik Höglund <fredrik@kde.org>
3 SPDX-FileCopyrightText: 2014 Marco Martin <mart@kde.org>
4
5 SPDX-License-Identifier: GPL-2.0-or-later
6*/
7
8#include "contrastshader.h"
9
11#include "opengl/glplatform.h"
12
13#include <QByteArray>
14#include <QMatrix4x4>
15#include <QTextStream>
16#include <QVector2D>
17
18#include <cmath>
19
20namespace KWin
21{
22
24 : m_valid(false)
25 , m_shader(nullptr)
26 , m_opacity(1)
27{
28}
29
31{
32 m_shader.reset();
33
34 setIsValid(false);
35}
36
37void ContrastShader::setOpacity(float opacity)
38{
39 m_opacity = opacity;
40
41 ShaderManager::instance()->pushShader(m_shader.get());
42 m_shader->setUniform(m_opacityLocation, opacity);
44}
45
47{
48 return m_opacity;
49}
50
51void ContrastShader::setColorMatrix(const QMatrix4x4 &matrix)
52{
53 if (!isValid()) {
54 return;
55 }
56
57 ShaderManager::instance()->pushShader(m_shader.get());
58 m_shader->setUniform(m_colorMatrixLocation, matrix);
60}
61
62void ContrastShader::setTextureMatrix(const QMatrix4x4 &matrix)
63{
64 if (!isValid()) {
65 return;
66 }
67
68 m_shader->setUniform(m_textureMatrixLocation, matrix);
69}
70
72{
73 if (!isValid()) {
74 return;
75 }
76
77 m_shader->setUniform(m_mvpMatrixLocation, matrix);
78}
79
81{
82 if (!isValid()) {
83 return;
84 }
85
86 ShaderManager::instance()->pushShader(m_shader.get());
87}
88
93
95{
96 reset();
97
98 const bool gles = GLPlatform::instance()->isGLES();
99 const bool glsl_140 = !gles && GLPlatform::instance()->glslVersion() >= Version(1, 40);
100 const bool core = glsl_140 || (gles && GLPlatform::instance()->glslVersion() >= Version(3, 0));
101
102 QByteArray vertexSource;
103 QByteArray fragmentSource;
104
105 const QByteArray attribute = core ? "in" : "attribute";
106 const QByteArray varying_in = core ? (gles ? "in" : "noperspective in") : "varying";
107 const QByteArray varying_out = core ? (gles ? "out" : "noperspective out") : "varying";
108 const QByteArray texture2D = core ? "texture" : "texture2D";
109 const QByteArray fragColor = core ? "fragColor" : "gl_FragColor";
110
111 // Vertex shader
112 // ===================================================================
113 QTextStream stream(&vertexSource);
114
115 if (gles) {
116 if (core) {
117 stream << "#version 300 es\n\n";
118 }
119 stream << "precision highp float;\n";
120 } else if (glsl_140) {
121 stream << "#version 140\n\n";
122 }
123
124 stream << "uniform mat4 modelViewProjectionMatrix;\n";
125 stream << "uniform mat4 textureMatrix;\n";
126 stream << attribute << " vec4 vertex;\n\n";
127 stream << varying_out << " vec4 varyingTexCoords;\n";
128 stream << "\n";
129 stream << "void main(void)\n";
130 stream << "{\n";
131 stream << " varyingTexCoords = vec4(textureMatrix * vertex).stst;\n";
132 stream << " gl_Position = modelViewProjectionMatrix * vertex;\n";
133 stream << "}\n";
134 stream.flush();
135
136 // Fragment shader
137 // ===================================================================
138 QTextStream stream2(&fragmentSource);
139
140 if (gles) {
141 if (core) {
142 stream2 << "#version 300 es\n\n";
143 }
144 stream2 << "precision highp float;\n";
145 } else if (glsl_140) {
146 stream2 << "#version 140\n\n";
147 }
148
149 stream2 << "uniform mat4 colorMatrix;\n";
150 stream2 << "uniform sampler2D sampler;\n";
151 stream2 << "uniform float opacity;\n";
152 stream2 << varying_in << " vec4 varyingTexCoords;\n";
153
154 if (core) {
155 stream2 << "out vec4 fragColor;\n\n";
156 }
157
158 stream2 << "void main(void)\n";
159 stream2 << "{\n";
160 stream2 << " vec4 tex = " << texture2D << "(sampler, varyingTexCoords.st);\n";
161
162 stream2 << " if (opacity >= 1.0) {\n";
163 stream2 << " " << fragColor << " = tex * colorMatrix;\n";
164 stream2 << " } else {\n";
165 stream2 << " " << fragColor << " = tex * (opacity * colorMatrix + (1.0 - opacity) * mat4(1.0));\n";
166 stream2 << " }\n";
167
168 stream2 << "}\n";
169 stream2.flush();
170
171 m_shader = ShaderManager::instance()->loadShaderFromCode(vertexSource, fragmentSource);
172
173 if (m_shader->isValid()) {
174 m_colorMatrixLocation = m_shader->uniformLocation("colorMatrix");
175 m_textureMatrixLocation = m_shader->uniformLocation("textureMatrix");
176 m_mvpMatrixLocation = m_shader->uniformLocation("modelViewProjectionMatrix");
177 m_opacityLocation = m_shader->uniformLocation("opacity");
178
179 QMatrix4x4 modelViewProjection;
180 const QSize screenSize = effects->virtualScreenSize();
181 modelViewProjection.ortho(0, screenSize.width(), screenSize.height(), 0, 0, 65535);
182 ShaderManager::instance()->pushShader(m_shader.get());
183 m_shader->setUniform(m_colorMatrixLocation, QMatrix4x4());
184 m_shader->setUniform(m_textureMatrixLocation, QMatrix4x4());
185 m_shader->setUniform(m_mvpMatrixLocation, modelViewProjection);
186 m_shader->setUniform(m_opacityLocation, (float)1.0);
188 }
189
190 setIsValid(m_shader->isValid());
191}
192
194{
195 m_valid = value;
196}
197
199{
200 return m_valid;
201}
202
203} // namespace KWin
void setColorMatrix(const QMatrix4x4 &matrix)
void setTextureMatrix(const QMatrix4x4 &matrix)
void setOpacity(float opacity)
void setIsValid(bool value)
void setModelViewProjectionMatrix(const QMatrix4x4 &matrix)
Version glslVersion() const
static GLPlatform * instance()
Definition glplatform.h:394
bool isGLES() const
static ShaderManager * instance()
std::unique_ptr< GLShader > loadShaderFromCode(const QByteArray &vertexSource, const QByteArray &fragmentSource)
GLShader * pushShader(ShaderTraits traits)
EffectsHandler * effects