opengl/qopenglengineshadermanager.cpp

Switch to Source codePreprocessed file
LineSource CodeCoverage
1 -
2 -
3 -
4 -
5 -
6 -
7 -
8 -
9 -
10 -
11class QOpenGLEngineSharedShadersResource : public QOpenGLSharedResource -
12{ -
13public: -
14 QOpenGLEngineSharedShadersResource(QOpenGLContext *ctx) -
15 : QOpenGLSharedResource(ctx->shareGroup()) -
16 , m_shaders(new QOpenGLEngineSharedShaders(ctx)) -
17 { -
18 }
never executed: }
0
19 -
20 ~QOpenGLEngineSharedShadersResource() -
21 { -
22 delete m_shaders; -
23 }
never executed: }
0
24 -
25 void invalidateResource() -
26 { -
27 delete m_shaders; -
28 m_shaders = 0; -
29 }
never executed: }
0
30 -
31 void freeResource(QOpenGLContext *) -
32 { -
33 } -
34 -
35 QOpenGLEngineSharedShaders *shaders() const { return m_shaders; }
never executed: return m_shaders;
0
36 -
37private: -
38 QOpenGLEngineSharedShaders *m_shaders; -
39}; -
40 -
41class QOpenGLShaderStorage -
42{ -
43public: -
44 QOpenGLEngineSharedShaders *shadersForThread(QOpenGLContext *context) { -
45 QOpenGLMultiGroupSharedResource *&shaders = m_storage.localData(); -
46 if (!shaders)
never evaluated: !shaders
0
47 shaders = new QOpenGLMultiGroupSharedResource;
never executed: shaders = new QOpenGLMultiGroupSharedResource;
0
48 QOpenGLEngineSharedShadersResource *resource = -
49 shaders->value<QOpenGLEngineSharedShadersResource>(context); -
50 return resource ? resource->shaders() : 0;
never executed: return resource ? resource->shaders() : 0;
0
51 } -
52 -
53private: -
54 QThreadStorage<QOpenGLMultiGroupSharedResource *> m_storage; -
55}; -
56 -
57static QOpenGLShaderStorage *qt_shader_storage() { static QGlobalStatic<QOpenGLShaderStorage > thisGlobalStatic = { { (0) }, false }; if (!thisGlobalStatic.pointer.load() && !thisGlobalStatic.destroyed) { QOpenGLShaderStorage *x = new QOpenGLShaderStorage; if (!thisGlobalStatic.pointer.testAndSetOrdered(0, x)) delete x; else static QGlobalStaticDeleter<QOpenGLShaderStorage > cleanup(thisGlobalStatic); } return thisGlobalStatic.pointer.load(); };
never evaluated: !thisGlobalStatic.pointer.testAndSetOrdered(0, x)
never evaluated: !thisGlobalStatic.pointer.load()
never evaluated: !thisGlobalStatic.destroyed
never executed: delete x;
never executed: return thisGlobalStatic.pointer.load();
0
58 -
59QOpenGLEngineSharedShaders *QOpenGLEngineSharedShaders::shadersForContext(QOpenGLContext *context) -
60{ -
61 return qt_shader_storage()->shadersForThread(context);
never executed: return qt_shader_storage()->shadersForThread(context);
0
62} -
63 -
64const char* QOpenGLEngineSharedShaders::qShaderSnippets[] = { -
65 0,0,0,0,0,0,0,0,0,0, -
66 0,0,0,0,0,0,0,0,0,0, -
67 0,0,0,0,0,0,0,0,0,0, -
68 0,0,0,0,0 -
69}; -
70 -
71QOpenGLEngineSharedShaders::QOpenGLEngineSharedShaders(QOpenGLContext* context) -
72 : blitShaderProg(0) -
73 , simpleShaderProg(0) -
74{ -
75 -
76 -
77 -
78 -
79 -
80 -
81 -
82 static bool snippetsPopulated = false; -
83 if (!snippetsPopulated) {
never evaluated: !snippetsPopulated
0
84 -
85 const char** code = qShaderSnippets; -
86 -
87 code[MainVertexShader] = qopenglslMainVertexShader; -
88 code[MainWithTexCoordsVertexShader] = qopenglslMainWithTexCoordsVertexShader; -
89 code[MainWithTexCoordsAndOpacityVertexShader] = qopenglslMainWithTexCoordsAndOpacityVertexShader; -
90 -
91 code[UntransformedPositionVertexShader] = qopenglslUntransformedPositionVertexShader; -
92 code[PositionOnlyVertexShader] = qopenglslPositionOnlyVertexShader; -
93 code[ComplexGeometryPositionOnlyVertexShader] = qopenglslComplexGeometryPositionOnlyVertexShader; -
94 code[PositionWithPatternBrushVertexShader] = qopenglslPositionWithPatternBrushVertexShader; -
95 code[PositionWithLinearGradientBrushVertexShader] = qopenglslPositionWithLinearGradientBrushVertexShader; -
96 code[PositionWithConicalGradientBrushVertexShader] = qopenglslPositionWithConicalGradientBrushVertexShader; -
97 code[PositionWithRadialGradientBrushVertexShader] = qopenglslPositionWithRadialGradientBrushVertexShader; -
98 code[PositionWithTextureBrushVertexShader] = qopenglslPositionWithTextureBrushVertexShader; -
99 code[AffinePositionWithPatternBrushVertexShader] = qopenglslAffinePositionWithPatternBrushVertexShader; -
100 code[AffinePositionWithLinearGradientBrushVertexShader] = qopenglslAffinePositionWithLinearGradientBrushVertexShader; -
101 code[AffinePositionWithConicalGradientBrushVertexShader] = qopenglslAffinePositionWithConicalGradientBrushVertexShader; -
102 code[AffinePositionWithRadialGradientBrushVertexShader] = qopenglslAffinePositionWithRadialGradientBrushVertexShader; -
103 code[AffinePositionWithTextureBrushVertexShader] = qopenglslAffinePositionWithTextureBrushVertexShader; -
104 -
105 code[MainFragmentShader_CMO] = qopenglslMainFragmentShader_CMO; -
106 code[MainFragmentShader_CM] = qopenglslMainFragmentShader_CM; -
107 code[MainFragmentShader_MO] = qopenglslMainFragmentShader_MO; -
108 code[MainFragmentShader_M] = qopenglslMainFragmentShader_M; -
109 code[MainFragmentShader_CO] = qopenglslMainFragmentShader_CO; -
110 code[MainFragmentShader_C] = qopenglslMainFragmentShader_C; -
111 code[MainFragmentShader_O] = qopenglslMainFragmentShader_O; -
112 code[MainFragmentShader] = qopenglslMainFragmentShader; -
113 code[MainFragmentShader_ImageArrays] = qopenglslMainFragmentShader_ImageArrays; -
114 -
115 code[ImageSrcFragmentShader] = qopenglslImageSrcFragmentShader; -
116 code[ImageSrcWithPatternFragmentShader] = qopenglslImageSrcWithPatternFragmentShader; -
117 code[NonPremultipliedImageSrcFragmentShader] = qopenglslNonPremultipliedImageSrcFragmentShader; -
118 code[CustomImageSrcFragmentShader] = qopenglslCustomSrcFragmentShader; -
119 code[SolidBrushSrcFragmentShader] = qopenglslSolidBrushSrcFragmentShader; -
120 code[TextureBrushSrcFragmentShader] = qopenglslTextureBrushSrcFragmentShader; -
121 code[TextureBrushSrcWithPatternFragmentShader] = qopenglslTextureBrushSrcWithPatternFragmentShader; -
122 code[PatternBrushSrcFragmentShader] = qopenglslPatternBrushSrcFragmentShader; -
123 code[LinearGradientBrushSrcFragmentShader] = qopenglslLinearGradientBrushSrcFragmentShader; -
124 code[RadialGradientBrushSrcFragmentShader] = qopenglslRadialGradientBrushSrcFragmentShader; -
125 code[ConicalGradientBrushSrcFragmentShader] = qopenglslConicalGradientBrushSrcFragmentShader; -
126 code[ShockingPinkSrcFragmentShader] = qopenglslShockingPinkSrcFragmentShader; -
127 -
128 code[NoMaskFragmentShader] = ""; -
129 code[MaskFragmentShader] = qopenglslMaskFragmentShader; -
130 code[RgbMaskFragmentShaderPass1] = qopenglslRgbMaskFragmentShaderPass1; -
131 code[RgbMaskFragmentShaderPass2] = qopenglslRgbMaskFragmentShaderPass2; -
132 code[RgbMaskWithGammaFragmentShader] = ""; -
133 -
134 code[NoCompositionModeFragmentShader] = ""; -
135 code[MultiplyCompositionModeFragmentShader] = ""; -
136 code[ScreenCompositionModeFragmentShader] = ""; -
137 code[OverlayCompositionModeFragmentShader] = ""; -
138 code[DarkenCompositionModeFragmentShader] = ""; -
139 code[LightenCompositionModeFragmentShader] = ""; -
140 code[ColorDodgeCompositionModeFragmentShader] = ""; -
141 code[ColorBurnCompositionModeFragmentShader] = ""; -
142 code[HardLightCompositionModeFragmentShader] = ""; -
143 code[SoftLightCompositionModeFragmentShader] = ""; -
144 code[DifferenceCompositionModeFragmentShader] = ""; -
145 code[ExclusionCompositionModeFragmentShader] = ""; -
146 snippetsPopulated = true; -
147 }
never executed: }
0
148 -
149 QOpenGLShader* fragShader; -
150 QOpenGLShader* vertexShader; -
151 QByteArray vertexSource; -
152 QByteArray fragSource; -
153 -
154 -
155 vertexSource.append(qShaderSnippets[MainVertexShader]); -
156 vertexSource.append(qShaderSnippets[PositionOnlyVertexShader]); -
157 -
158 fragSource.append(qShaderSnippets[MainFragmentShader]); -
159 fragSource.append(qShaderSnippets[ShockingPinkSrcFragmentShader]); -
160 -
161 simpleShaderProg = new QOpenGLShaderProgram; -
162 -
163 CachedShader simpleShaderCache(fragSource, vertexSource); -
164 -
165 bool inCache = simpleShaderCache.load(simpleShaderProg, context); -
166 -
167 if (!inCache) {
never evaluated: !inCache
0
168 vertexShader = new QOpenGLShader(QOpenGLShader::Vertex); -
169 shaders.append(vertexShader); -
170 if (!vertexShader->compileSourceCode(vertexSource))
never evaluated: !vertexShader->compileSourceCode(vertexSource)
0
171 QMessageLogger("opengl/qopenglengineshadermanager.cpp", 228, __PRETTY_FUNCTION__).warning("Vertex shader for simpleShaderProg (MainVertexShader & PositionOnlyVertexShader) failed to compile");
never executed: QMessageLogger("opengl/qopenglengineshadermanager.cpp", 228, __PRETTY_FUNCTION__).warning("Vertex shader for simpleShaderProg (MainVertexShader & PositionOnlyVertexShader) failed to compile");
0
172 -
173 fragShader = new QOpenGLShader(QOpenGLShader::Fragment); -
174 shaders.append(fragShader); -
175 if (!fragShader->compileSourceCode(fragSource))
never evaluated: !fragShader->compileSourceCode(fragSource)
0
176 QMessageLogger("opengl/qopenglengineshadermanager.cpp", 233, __PRETTY_FUNCTION__).warning("Fragment shader for simpleShaderProg (MainFragmentShader & ShockingPinkSrcFragmentShader) failed to compile");
never executed: QMessageLogger("opengl/qopenglengineshadermanager.cpp", 233, __PRETTY_FUNCTION__).warning("Fragment shader for simpleShaderProg (MainFragmentShader & ShockingPinkSrcFragmentShader) failed to compile");
0
177 -
178 simpleShaderProg->addShader(vertexShader); -
179 simpleShaderProg->addShader(fragShader); -
180 -
181 simpleShaderProg->bindAttributeLocation("vertexCoordsArray", QT_VERTEX_COORDS_ATTR); -
182 simpleShaderProg->bindAttributeLocation("pmvMatrix1", QT_PMV_MATRIX_1_ATTR); -
183 simpleShaderProg->bindAttributeLocation("pmvMatrix2", QT_PMV_MATRIX_2_ATTR); -
184 simpleShaderProg->bindAttributeLocation("pmvMatrix3", QT_PMV_MATRIX_3_ATTR); -
185 }
never executed: }
0
186 -
187 simpleShaderProg->link(); -
188 -
189 if (simpleShaderProg->isLinked()) {
never evaluated: simpleShaderProg->isLinked()
0
190 if (!inCache)
never evaluated: !inCache
0
191 simpleShaderCache.store(simpleShaderProg, context);
never executed: simpleShaderCache.store(simpleShaderProg, context);
0
192 } else {
never executed: }
0
193 QMessageLogger("opengl/qopenglengineshadermanager.cpp", 250, __PRETTY_FUNCTION__).critical("Errors linking simple shader: %s", QString(simpleShaderProg->log()).toLocal8Bit().constData()); -
194 }
never executed: }
0
195 -
196 -
197 vertexSource.clear(); -
198 vertexSource.append(qShaderSnippets[MainWithTexCoordsVertexShader]); -
199 vertexSource.append(qShaderSnippets[UntransformedPositionVertexShader]); -
200 -
201 fragSource.clear(); -
202 fragSource.append(qShaderSnippets[MainFragmentShader]); -
203 fragSource.append(qShaderSnippets[ImageSrcFragmentShader]); -
204 -
205 blitShaderProg = new QOpenGLShaderProgram; -
206 -
207 CachedShader blitShaderCache(fragSource, vertexSource); -
208 -
209 inCache = blitShaderCache.load(blitShaderProg, context); -
210 -
211 if (!inCache) {
never evaluated: !inCache
0
212 vertexShader = new QOpenGLShader(QOpenGLShader::Vertex); -
213 shaders.append(vertexShader); -
214 if (!vertexShader->compileSourceCode(vertexSource))
never evaluated: !vertexShader->compileSourceCode(vertexSource)
0
215 QMessageLogger("opengl/qopenglengineshadermanager.cpp", 272, __PRETTY_FUNCTION__).warning("Vertex shader for blitShaderProg (MainWithTexCoordsVertexShader & UntransformedPositionVertexShader) failed to compile");
never executed: QMessageLogger("opengl/qopenglengineshadermanager.cpp", 272, __PRETTY_FUNCTION__).warning("Vertex shader for blitShaderProg (MainWithTexCoordsVertexShader & UntransformedPositionVertexShader) failed to compile");
0
216 -
217 fragShader = new QOpenGLShader(QOpenGLShader::Fragment); -
218 shaders.append(fragShader); -
219 if (!fragShader->compileSourceCode(fragSource))
never evaluated: !fragShader->compileSourceCode(fragSource)
0
220 QMessageLogger("opengl/qopenglengineshadermanager.cpp", 277, __PRETTY_FUNCTION__).warning("Fragment shader for blitShaderProg (MainFragmentShader & ImageSrcFragmentShader) failed to compile");
never executed: QMessageLogger("opengl/qopenglengineshadermanager.cpp", 277, __PRETTY_FUNCTION__).warning("Fragment shader for blitShaderProg (MainFragmentShader & ImageSrcFragmentShader) failed to compile");
0
221 -
222 blitShaderProg->addShader(vertexShader); -
223 blitShaderProg->addShader(fragShader); -
224 -
225 blitShaderProg->bindAttributeLocation("textureCoordArray", QT_TEXTURE_COORDS_ATTR); -
226 blitShaderProg->bindAttributeLocation("vertexCoordsArray", QT_VERTEX_COORDS_ATTR); -
227 }
never executed: }
0
228 -
229 blitShaderProg->link(); -
230 if (blitShaderProg->isLinked()) {
never evaluated: blitShaderProg->isLinked()
0
231 if (!inCache)
never evaluated: !inCache
0
232 blitShaderCache.store(blitShaderProg, context);
never executed: blitShaderCache.store(blitShaderProg, context);
0
233 } else {
never executed: }
0
234 QMessageLogger("opengl/qopenglengineshadermanager.cpp", 291, __PRETTY_FUNCTION__).critical("Errors linking blit shader: %s", QString(blitShaderProg->log()).toLocal8Bit().constData()); -
235 }
never executed: }
0
236 -
237 -
238 -
239 -
240} -
241 -
242QOpenGLEngineSharedShaders::~QOpenGLEngineSharedShaders() -
243{ -
244 -
245 -
246 -
247 qDeleteAll(shaders); -
248 shaders.clear(); -
249 -
250 qDeleteAll(cachedPrograms); -
251 cachedPrograms.clear(); -
252 -
253 if (blitShaderProg) {
never evaluated: blitShaderProg
0
254 delete blitShaderProg; -
255 blitShaderProg = 0; -
256 }
never executed: }
0
257 -
258 if (simpleShaderProg) {
never evaluated: simpleShaderProg
0
259 delete simpleShaderProg; -
260 simpleShaderProg = 0; -
261 }
never executed: }
0
262}
never executed: }
0
263QOpenGLEngineShaderProg *QOpenGLEngineSharedShaders::findProgramInCache(const QOpenGLEngineShaderProg &prog) -
264{ -
265 for (int i = 0; i < cachedPrograms.size(); ++i) {
never evaluated: i < cachedPrograms.size()
0
266 QOpenGLEngineShaderProg *cachedProg = cachedPrograms[i]; -
267 if (*cachedProg == prog) {
never evaluated: *cachedProg == prog
0
268 -
269 cachedPrograms.move(i, 0); -
270 cachedProg->program->bind(); -
271 return cachedProg;
never executed: return cachedProg;
0
272 } -
273 }
never executed: }
0
274 -
275 QScopedPointer<QOpenGLEngineShaderProg> newProg; -
276 -
277 do { -
278 QByteArray fragSource; -
279 -
280 -
281 if (prog.srcPixelFragShader == CustomImageSrcFragmentShader)
never evaluated: prog.srcPixelFragShader == CustomImageSrcFragmentShader
0
282 fragSource.append(prog.customStageSource);
never executed: fragSource.append(prog.customStageSource);
0
283 fragSource.append(qShaderSnippets[prog.mainFragShader]); -
284 fragSource.append(qShaderSnippets[prog.srcPixelFragShader]); -
285 if (prog.compositionFragShader)
never evaluated: prog.compositionFragShader
0
286 fragSource.append(qShaderSnippets[prog.compositionFragShader]);
never executed: fragSource.append(qShaderSnippets[prog.compositionFragShader]);
0
287 if (prog.maskFragShader)
never evaluated: prog.maskFragShader
0
288 fragSource.append(qShaderSnippets[prog.maskFragShader]);
never executed: fragSource.append(qShaderSnippets[prog.maskFragShader]);
0
289 -
290 QByteArray vertexSource; -
291 vertexSource.append(qShaderSnippets[prog.mainVertexShader]); -
292 vertexSource.append(qShaderSnippets[prog.positionVertexShader]); -
293 -
294 QScopedPointer<QOpenGLShaderProgram> shaderProgram(new QOpenGLShaderProgram); -
295 -
296 CachedShader shaderCache(fragSource, vertexSource); -
297 bool inCache = shaderCache.load(shaderProgram.data(), QOpenGLContext::currentContext()); -
298 -
299 if (!inCache) {
never evaluated: !inCache
0
300 -
301 QScopedPointer<QOpenGLShader> fragShader(new QOpenGLShader(QOpenGLShader::Fragment)); -
302 QByteArray description; -
303 if (!fragShader->compileSourceCode(fragSource)) {
never evaluated: !fragShader->compileSourceCode(fragSource)
0
304 QMessageLogger("opengl/qopenglengineshadermanager.cpp", 388, __PRETTY_FUNCTION__).warning() << "Warning:" << description << "failed to compile!"; -
305 break;
never executed: break;
0
306 } -
307 -
308 QScopedPointer<QOpenGLShader> vertexShader(new QOpenGLShader(QOpenGLShader::Vertex)); -
309 if (!vertexShader->compileSourceCode(vertexSource)) {
never evaluated: !vertexShader->compileSourceCode(vertexSource)
0
310 QMessageLogger("opengl/qopenglengineshadermanager.cpp", 403, __PRETTY_FUNCTION__).warning() << "Warning:" << description << "failed to compile!"; -
311 break;
never executed: break;
0
312 } -
313 -
314 shaders.append(vertexShader.data()); -
315 shaders.append(fragShader.data()); -
316 shaderProgram->addShader(vertexShader.take()); -
317 shaderProgram->addShader(fragShader.take()); -
318 -
319 -
320 shaderProgram->bindAttributeLocation("vertexCoordsArray", QT_VERTEX_COORDS_ATTR); -
321 if (prog.useTextureCoords)
never evaluated: prog.useTextureCoords
0
322 shaderProgram->bindAttributeLocation("textureCoordArray", QT_TEXTURE_COORDS_ATTR);
never executed: shaderProgram->bindAttributeLocation("textureCoordArray", QT_TEXTURE_COORDS_ATTR);
0
323 if (prog.useOpacityAttribute)
never evaluated: prog.useOpacityAttribute
0
324 shaderProgram->bindAttributeLocation("opacityArray", QT_OPACITY_ATTR);
never executed: shaderProgram->bindAttributeLocation("opacityArray", QT_OPACITY_ATTR);
0
325 if (prog.usePmvMatrixAttribute) {
never evaluated: prog.usePmvMatrixAttribute
0
326 shaderProgram->bindAttributeLocation("pmvMatrix1", QT_PMV_MATRIX_1_ATTR); -
327 shaderProgram->bindAttributeLocation("pmvMatrix2", QT_PMV_MATRIX_2_ATTR); -
328 shaderProgram->bindAttributeLocation("pmvMatrix3", QT_PMV_MATRIX_3_ATTR); -
329 }
never executed: }
0
330 }
never executed: }
0
331 -
332 newProg.reset(new QOpenGLEngineShaderProg(prog)); -
333 newProg->program = shaderProgram.take(); -
334 -
335 newProg->program->link(); -
336 if (newProg->program->isLinked()) {
never evaluated: newProg->program->isLinked()
0
337 if (!inCache)
never evaluated: !inCache
0
338 shaderCache.store(newProg->program, QOpenGLContext::currentContext());
never executed: shaderCache.store(newProg->program, QOpenGLContext::currentContext());
0
339 } else {
never executed: }
0
340 QLatin1String none("none"); -
341 QLatin1String br("\n"); -
342 QString error; -
343 error = QLatin1String("Shader program failed to link,"); -
344 error += QLatin1String(" Error Log:\n") -
345 + QLatin1String(" ") + newProg->program->log(); -
346 QMessageLogger("opengl/qopenglengineshadermanager.cpp", 447, __PRETTY_FUNCTION__).warning() << error; -
347 break;
never executed: break;
0
348 } -
349 -
350 newProg->program->bind(); -
351 -
352 if (newProg->maskFragShader != QOpenGLEngineSharedShaders::NoMaskFragmentShader) {
never evaluated: newProg->maskFragShader != QOpenGLEngineSharedShaders::NoMaskFragmentShader
0
353 GLuint location = newProg->program->uniformLocation("maskTexture"); -
354 newProg->program->setUniformValue(location, GLuint(1)); -
355 }
never executed: }
0
356 -
357 if (cachedPrograms.count() > 30) {
never evaluated: cachedPrograms.count() > 30
0
358 -
359 -
360 -
361 for (int i = 0; i < 5; ++i) {
never evaluated: i < 5
0
362 delete cachedPrograms.last(); -
363 cachedPrograms.removeLast(); -
364 }
never executed: }
0
365 }
never executed: }
0
366 -
367 cachedPrograms.insert(0, newProg.data()); -
368 } while (false);
never evaluated: false
never executed: }
0
369 -
370 return newProg.take();
never executed: return newProg.take();
0
371} -
372 -
373void QOpenGLEngineSharedShaders::cleanupCustomStage(QOpenGLCustomShaderStage* stage) -
374{ -
375 -
376 for (int i = 0; i < cachedPrograms.size(); ++i) {
never evaluated: i < cachedPrograms.size()
0
377 QOpenGLEngineShaderProg *cachedProg = cachedPrograms[i]; -
378 if (cachedProg->customStageSource == stage->source()) {
never evaluated: cachedProg->customStageSource == stage->source()
0
379 delete cachedProg; -
380 cachedPrograms.removeAt(i); -
381 i--; -
382 }
never executed: }
0
383 }
never executed: }
0
384}
never executed: }
0
385 -
386 -
387QOpenGLEngineShaderManager::QOpenGLEngineShaderManager(QOpenGLContext* context) -
388 : ctx(context), -
389 shaderProgNeedsChanging(true), -
390 complexGeometry(false), -
391 srcPixelType(Qt::NoBrush), -
392 opacityMode(NoOpacity), -
393 maskType(NoMask), -
394 compositionMode(QPainter::CompositionMode_SourceOver), -
395 customSrcStage(0), -
396 currentShaderProg(0) -
397{ -
398 sharedShaders = QOpenGLEngineSharedShaders::shadersForContext(context); -
399}
never executed: }
0
400 -
401QOpenGLEngineShaderManager::~QOpenGLEngineShaderManager() -
402{ -
403 -
404 removeCustomStage(); -
405}
never executed: }
0
406 -
407GLuint QOpenGLEngineShaderManager::getUniformLocation(Uniform id) -
408{ -
409 if (!currentShaderProg)
never evaluated: !currentShaderProg
0
410 return 0;
never executed: return 0;
0
411 -
412 QVector<uint> &uniformLocations = currentShaderProg->uniformLocations; -
413 if (uniformLocations.isEmpty())
never evaluated: uniformLocations.isEmpty()
0
414 uniformLocations.fill(GLuint(-1), NumUniforms);
never executed: uniformLocations.fill(GLuint(-1), NumUniforms);
0
415 -
416 static const char *uniformNames[] = { -
417 "imageTexture", -
418 "patternColor", -
419 "globalOpacity", -
420 "depth", -
421 "maskTexture", -
422 "fragmentColor", -
423 "linearData", -
424 "angle", -
425 "halfViewportSize", -
426 "fmp", -
427 "fmp2_m_radius2", -
428 "inverse_2_fmp2_m_radius2", -
429 "sqrfr", -
430 "bradius", -
431 "invertedTextureSize", -
432 "brushTransform", -
433 "brushTexture", -
434 "matrix" -
435 }; -
436 -
437 if (uniformLocations.at(id) == GLuint(-1))
never evaluated: uniformLocations.at(id) == GLuint(-1)
0
438 uniformLocations[id] = currentShaderProg->program->uniformLocation(uniformNames[id]);
never executed: uniformLocations[id] = currentShaderProg->program->uniformLocation(uniformNames[id]);
0
439 -
440 return uniformLocations.at(id);
never executed: return uniformLocations.at(id);
0
441} -
442 -
443 -
444void QOpenGLEngineShaderManager::optimiseForBrushTransform(QTransform::TransformationType transformType) -
445{ -
446 (void)transformType;; -
447}
never executed: }
0
448 -
449void QOpenGLEngineShaderManager::setDirty() -
450{ -
451 shaderProgNeedsChanging = true; -
452}
never executed: }
0
453 -
454void QOpenGLEngineShaderManager::setSrcPixelType(Qt::BrushStyle style) -
455{ -
456 qt_noop(); -
457 if (srcPixelType == PixelSrcType(style))
never evaluated: srcPixelType == PixelSrcType(style)
0
458 return;
never executed: return;
0
459 -
460 srcPixelType = style; -
461 shaderProgNeedsChanging = true; -
462}
never executed: }
0
463 -
464void QOpenGLEngineShaderManager::setSrcPixelType(PixelSrcType type) -
465{ -
466 if (srcPixelType == type)
never evaluated: srcPixelType == type
0
467 return;
never executed: return;
0
468 -
469 srcPixelType = type; -
470 shaderProgNeedsChanging = true; -
471}
never executed: }
0
472 -
473void QOpenGLEngineShaderManager::setOpacityMode(OpacityMode mode) -
474{ -
475 if (opacityMode == mode)
never evaluated: opacityMode == mode
0
476 return;
never executed: return;
0
477 -
478 opacityMode = mode; -
479 shaderProgNeedsChanging = true; -
480}
never executed: }
0
481 -
482void QOpenGLEngineShaderManager::setMaskType(MaskType type) -
483{ -
484 if (maskType == type)
never evaluated: maskType == type
0
485 return;
never executed: return;
0
486 -
487 maskType = type; -
488 shaderProgNeedsChanging = true; -
489}
never executed: }
0
490 -
491void QOpenGLEngineShaderManager::setCompositionMode(QPainter::CompositionMode mode) -
492{ -
493 if (compositionMode == mode)
never evaluated: compositionMode == mode
0
494 return;
never executed: return;
0
495 -
496 compositionMode = mode; -
497 shaderProgNeedsChanging = true; -
498}
never executed: }
0
499 -
500void QOpenGLEngineShaderManager::setCustomStage(QOpenGLCustomShaderStage* stage) -
501{ -
502 if (customSrcStage)
never evaluated: customSrcStage
0
503 removeCustomStage();
never executed: removeCustomStage();
0
504 customSrcStage = stage; -
505 shaderProgNeedsChanging = true; -
506}
never executed: }
0
507 -
508void QOpenGLEngineShaderManager::removeCustomStage() -
509{ -
510 if (customSrcStage)
never evaluated: customSrcStage
0
511 customSrcStage->setInactive();
never executed: customSrcStage->setInactive();
0
512 customSrcStage = 0; -
513 shaderProgNeedsChanging = true; -
514}
never executed: }
0
515 -
516QOpenGLShaderProgram* QOpenGLEngineShaderManager::currentProgram() -
517{ -
518 if (currentShaderProg)
never evaluated: currentShaderProg
0
519 return currentShaderProg->program;
never executed: return currentShaderProg->program;
0
520 else -
521 return sharedShaders->simpleProgram();
never executed: return sharedShaders->simpleProgram();
0
522} -
523 -
524void QOpenGLEngineShaderManager::useSimpleProgram() -
525{ -
526 sharedShaders->simpleProgram()->bind(); -
527 QOpenGLContextPrivate* ctx_d = ctx->d_func(); -
528 (void)ctx_d;; -
529 -
530 QOpenGL2PaintEngineEx *active_engine = static_cast<QOpenGL2PaintEngineEx *>(ctx_d->active_engine); -
531 -
532 active_engine->d_func()->setVertexAttribArrayEnabled(QT_VERTEX_COORDS_ATTR, true); -
533 active_engine->d_func()->setVertexAttribArrayEnabled(QT_TEXTURE_COORDS_ATTR, false); -
534 active_engine->d_func()->setVertexAttribArrayEnabled(QT_OPACITY_ATTR, false); -
535 -
536 shaderProgNeedsChanging = true; -
537}
never executed: }
0
538 -
539void QOpenGLEngineShaderManager::useBlitProgram() -
540{ -
541 sharedShaders->blitProgram()->bind(); -
542 QOpenGLContextPrivate* ctx_d = ctx->d_func(); -
543 QOpenGL2PaintEngineEx *active_engine = static_cast<QOpenGL2PaintEngineEx *>(ctx_d->active_engine); -
544 active_engine->d_func()->setVertexAttribArrayEnabled(QT_VERTEX_COORDS_ATTR, true); -
545 active_engine->d_func()->setVertexAttribArrayEnabled(QT_TEXTURE_COORDS_ATTR, true); -
546 active_engine->d_func()->setVertexAttribArrayEnabled(QT_OPACITY_ATTR, false); -
547 shaderProgNeedsChanging = true; -
548}
never executed: }
0
549 -
550QOpenGLShaderProgram* QOpenGLEngineShaderManager::simpleProgram() -
551{ -
552 return sharedShaders->simpleProgram();
never executed: return sharedShaders->simpleProgram();
0
553} -
554 -
555QOpenGLShaderProgram* QOpenGLEngineShaderManager::blitProgram() -
556{ -
557 return sharedShaders->blitProgram();
never executed: return sharedShaders->blitProgram();
0
558} -
559 -
560 -
561 -
562 -
563 -
564bool QOpenGLEngineShaderManager::useCorrectShaderProg() -
565{ -
566 if (!shaderProgNeedsChanging)
never evaluated: !shaderProgNeedsChanging
0
567 return false;
never executed: return false;
0
568 -
569 bool useCustomSrc = customSrcStage != 0; -
570 if (useCustomSrc && srcPixelType != QOpenGLEngineShaderManager::ImageSrc && srcPixelType != Qt::TexturePattern) {
never evaluated: useCustomSrc
never evaluated: srcPixelType != QOpenGLEngineShaderManager::ImageSrc
never evaluated: srcPixelType != Qt::TexturePattern
0
571 useCustomSrc = false; -
572 QMessageLogger("opengl/qopenglengineshadermanager.cpp", 673, __PRETTY_FUNCTION__).warning("QOpenGLEngineShaderManager - Ignoring custom shader stage for non image src"); -
573 }
never executed: }
0
574 -
575 QOpenGLEngineShaderProg requiredProgram; -
576 -
577 bool texCoords = false; -
578 -
579 -
580 -
581 requiredProgram.positionVertexShader = QOpenGLEngineSharedShaders::InvalidSnippetName; -
582 requiredProgram.srcPixelFragShader = QOpenGLEngineSharedShaders::InvalidSnippetName; -
583 bool isAffine = brushTransform.isAffine(); -
584 if ( (srcPixelType >= Qt::Dense1Pattern) && (srcPixelType <= Qt::DiagCrossPattern) ) {
never evaluated: (srcPixelType >= Qt::Dense1Pattern)
never evaluated: (srcPixelType <= Qt::DiagCrossPattern)
0
585 if (isAffine)
never evaluated: isAffine
0
586 requiredProgram.positionVertexShader = QOpenGLEngineSharedShaders::AffinePositionWithPatternBrushVertexShader;
never executed: requiredProgram.positionVertexShader = QOpenGLEngineSharedShaders::AffinePositionWithPatternBrushVertexShader;
0
587 else -
588 requiredProgram.positionVertexShader = QOpenGLEngineSharedShaders::PositionWithPatternBrushVertexShader;
never executed: requiredProgram.positionVertexShader = QOpenGLEngineSharedShaders::PositionWithPatternBrushVertexShader;
0
589 -
590 requiredProgram.srcPixelFragShader = QOpenGLEngineSharedShaders::PatternBrushSrcFragmentShader; -
591 }
never executed: }
0
592 else switch (srcPixelType) { -
593 default: -
594 case Qt::NoBrush: -
595 QMessageLogger("opengl/qopenglengineshadermanager.cpp", 696, __PRETTY_FUNCTION__).fatal("QOpenGLEngineShaderManager::useCorrectShaderProg() - Qt::NoBrush style is set"); -
596 break;
never executed: break;
0
597 case QOpenGLEngineShaderManager::ImageSrc: -
598 requiredProgram.srcPixelFragShader = QOpenGLEngineSharedShaders::ImageSrcFragmentShader; -
599 requiredProgram.positionVertexShader = QOpenGLEngineSharedShaders::PositionOnlyVertexShader; -
600 texCoords = true; -
601 break;
never executed: break;
0
602 case QOpenGLEngineShaderManager::NonPremultipliedImageSrc: -
603 requiredProgram.srcPixelFragShader = QOpenGLEngineSharedShaders::NonPremultipliedImageSrcFragmentShader; -
604 requiredProgram.positionVertexShader = QOpenGLEngineSharedShaders::PositionOnlyVertexShader; -
605 texCoords = true; -
606 break;
never executed: break;
0
607 case QOpenGLEngineShaderManager::PatternSrc: -
608 requiredProgram.srcPixelFragShader = QOpenGLEngineSharedShaders::ImageSrcWithPatternFragmentShader; -
609 requiredProgram.positionVertexShader = QOpenGLEngineSharedShaders::PositionOnlyVertexShader; -
610 texCoords = true; -
611 break;
never executed: break;
0
612 case QOpenGLEngineShaderManager::TextureSrcWithPattern: -
613 requiredProgram.srcPixelFragShader = QOpenGLEngineSharedShaders::TextureBrushSrcWithPatternFragmentShader; -
614 requiredProgram.positionVertexShader = isAffine ? QOpenGLEngineSharedShaders::AffinePositionWithTextureBrushVertexShader
never evaluated: isAffine
0
615 : QOpenGLEngineSharedShaders::PositionWithTextureBrushVertexShader; -
616 break;
never executed: break;
0
617 case Qt::SolidPattern: -
618 requiredProgram.srcPixelFragShader = QOpenGLEngineSharedShaders::SolidBrushSrcFragmentShader; -
619 requiredProgram.positionVertexShader = QOpenGLEngineSharedShaders::PositionOnlyVertexShader; -
620 break;
never executed: break;
0
621 case Qt::LinearGradientPattern: -
622 requiredProgram.srcPixelFragShader = QOpenGLEngineSharedShaders::LinearGradientBrushSrcFragmentShader; -
623 requiredProgram.positionVertexShader = isAffine ? QOpenGLEngineSharedShaders::AffinePositionWithLinearGradientBrushVertexShader
never evaluated: isAffine
0
624 : QOpenGLEngineSharedShaders::PositionWithLinearGradientBrushVertexShader; -
625 break;
never executed: break;
0
626 case Qt::ConicalGradientPattern: -
627 requiredProgram.srcPixelFragShader = QOpenGLEngineSharedShaders::ConicalGradientBrushSrcFragmentShader; -
628 requiredProgram.positionVertexShader = isAffine ? QOpenGLEngineSharedShaders::AffinePositionWithConicalGradientBrushVertexShader
never evaluated: isAffine
0
629 : QOpenGLEngineSharedShaders::PositionWithConicalGradientBrushVertexShader; -
630 break;
never executed: break;
0
631 case Qt::RadialGradientPattern: -
632 requiredProgram.srcPixelFragShader = QOpenGLEngineSharedShaders::RadialGradientBrushSrcFragmentShader; -
633 requiredProgram.positionVertexShader = isAffine ? QOpenGLEngineSharedShaders::AffinePositionWithRadialGradientBrushVertexShader
never evaluated: isAffine
0
634 : QOpenGLEngineSharedShaders::PositionWithRadialGradientBrushVertexShader; -
635 break;
never executed: break;
0
636 case Qt::TexturePattern: -
637 requiredProgram.srcPixelFragShader = QOpenGLEngineSharedShaders::TextureBrushSrcFragmentShader; -
638 requiredProgram.positionVertexShader = isAffine ? QOpenGLEngineSharedShaders::AffinePositionWithTextureBrushVertexShader
never evaluated: isAffine
0
639 : QOpenGLEngineSharedShaders::PositionWithTextureBrushVertexShader; -
640 break;
never executed: break;
0
641 };
never executed: }
0
642 -
643 if (useCustomSrc) {
never evaluated: useCustomSrc
0
644 requiredProgram.srcPixelFragShader = QOpenGLEngineSharedShaders::CustomImageSrcFragmentShader; -
645 requiredProgram.customStageSource = customSrcStage->source(); -
646 }
never executed: }
0
647 -
648 const bool hasCompose = compositionMode > QPainter::CompositionMode_Plus; -
649 const bool hasMask = maskType != QOpenGLEngineShaderManager::NoMask; -
650 -
651 -
652 if (opacityMode == AttributeOpacity) {
never evaluated: opacityMode == AttributeOpacity
0
653 qt_noop(); -
654 requiredProgram.mainFragShader = QOpenGLEngineSharedShaders::MainFragmentShader_ImageArrays; -
655 } else {
never executed: }
0
656 bool useGlobalOpacity = (opacityMode == UniformOpacity); -
657 if (hasCompose && hasMask && useGlobalOpacity)
never evaluated: hasCompose
never evaluated: hasMask
never evaluated: useGlobalOpacity
0
658 requiredProgram.mainFragShader = QOpenGLEngineSharedShaders::MainFragmentShader_CMO;
never executed: requiredProgram.mainFragShader = QOpenGLEngineSharedShaders::MainFragmentShader_CMO;
0
659 if (hasCompose && hasMask && !useGlobalOpacity)
never evaluated: hasCompose
never evaluated: hasMask
never evaluated: !useGlobalOpacity
0
660 requiredProgram.mainFragShader = QOpenGLEngineSharedShaders::MainFragmentShader_CM;
never executed: requiredProgram.mainFragShader = QOpenGLEngineSharedShaders::MainFragmentShader_CM;
0
661 if (!hasCompose && hasMask && useGlobalOpacity)
never evaluated: !hasCompose
never evaluated: hasMask
never evaluated: useGlobalOpacity
0
662 requiredProgram.mainFragShader = QOpenGLEngineSharedShaders::MainFragmentShader_MO;
never executed: requiredProgram.mainFragShader = QOpenGLEngineSharedShaders::MainFragmentShader_MO;
0
663 if (!hasCompose && hasMask && !useGlobalOpacity)
never evaluated: !hasCompose
never evaluated: hasMask
never evaluated: !useGlobalOpacity
0
664 requiredProgram.mainFragShader = QOpenGLEngineSharedShaders::MainFragmentShader_M;
never executed: requiredProgram.mainFragShader = QOpenGLEngineSharedShaders::MainFragmentShader_M;
0
665 if (hasCompose && !hasMask && useGlobalOpacity)
never evaluated: hasCompose
never evaluated: !hasMask
never evaluated: useGlobalOpacity
0
666 requiredProgram.mainFragShader = QOpenGLEngineSharedShaders::MainFragmentShader_CO;
never executed: requiredProgram.mainFragShader = QOpenGLEngineSharedShaders::MainFragmentShader_CO;
0
667 if (hasCompose && !hasMask && !useGlobalOpacity)
never evaluated: hasCompose
never evaluated: !hasMask
never evaluated: !useGlobalOpacity
0
668 requiredProgram.mainFragShader = QOpenGLEngineSharedShaders::MainFragmentShader_C;
never executed: requiredProgram.mainFragShader = QOpenGLEngineSharedShaders::MainFragmentShader_C;
0
669 if (!hasCompose && !hasMask && useGlobalOpacity)
never evaluated: !hasCompose
never evaluated: !hasMask
never evaluated: useGlobalOpacity
0
670 requiredProgram.mainFragShader = QOpenGLEngineSharedShaders::MainFragmentShader_O;
never executed: requiredProgram.mainFragShader = QOpenGLEngineSharedShaders::MainFragmentShader_O;
0
671 if (!hasCompose && !hasMask && !useGlobalOpacity)
never evaluated: !hasCompose
never evaluated: !hasMask
never evaluated: !useGlobalOpacity
0
672 requiredProgram.mainFragShader = QOpenGLEngineSharedShaders::MainFragmentShader;
never executed: requiredProgram.mainFragShader = QOpenGLEngineSharedShaders::MainFragmentShader;
0
673 }
never executed: }
0
674 -
675 if (hasMask) {
never evaluated: hasMask
0
676 if (maskType == PixelMask) {
never evaluated: maskType == PixelMask
0
677 requiredProgram.maskFragShader = QOpenGLEngineSharedShaders::MaskFragmentShader; -
678 texCoords = true; -
679 } else if (maskType == SubPixelMaskPass1) {
never executed: }
never evaluated: maskType == SubPixelMaskPass1
0
680 requiredProgram.maskFragShader = QOpenGLEngineSharedShaders::RgbMaskFragmentShaderPass1; -
681 texCoords = true; -
682 } else if (maskType == SubPixelMaskPass2) {
never executed: }
never evaluated: maskType == SubPixelMaskPass2
0
683 requiredProgram.maskFragShader = QOpenGLEngineSharedShaders::RgbMaskFragmentShaderPass2; -
684 texCoords = true; -
685 } else if (maskType == SubPixelWithGammaMask) {
never executed: }
never evaluated: maskType == SubPixelWithGammaMask
0
686 requiredProgram.maskFragShader = QOpenGLEngineSharedShaders::RgbMaskWithGammaFragmentShader; -
687 texCoords = true; -
688 } else {
never executed: }
0
689 QMessageLogger("opengl/qopenglengineshadermanager.cpp", 790, __PRETTY_FUNCTION__).critical("QOpenGLEngineShaderManager::useCorrectShaderProg() - Unknown mask type"); -
690 }
never executed: }
0
691 } else { -
692 requiredProgram.maskFragShader = QOpenGLEngineSharedShaders::NoMaskFragmentShader; -
693 }
never executed: }
0
694 -
695 if (hasCompose) {
never evaluated: hasCompose
0
696 switch (compositionMode) { -
697 case QPainter::CompositionMode_Multiply: -
698 requiredProgram.compositionFragShader = QOpenGLEngineSharedShaders::MultiplyCompositionModeFragmentShader; -
699 break;
never executed: break;
0
700 case QPainter::CompositionMode_Screen: -
701 requiredProgram.compositionFragShader = QOpenGLEngineSharedShaders::ScreenCompositionModeFragmentShader; -
702 break;
never executed: break;
0
703 case QPainter::CompositionMode_Overlay: -
704 requiredProgram.compositionFragShader = QOpenGLEngineSharedShaders::OverlayCompositionModeFragmentShader; -
705 break;
never executed: break;
0
706 case QPainter::CompositionMode_Darken: -
707 requiredProgram.compositionFragShader = QOpenGLEngineSharedShaders::DarkenCompositionModeFragmentShader; -
708 break;
never executed: break;
0
709 case QPainter::CompositionMode_Lighten: -
710 requiredProgram.compositionFragShader = QOpenGLEngineSharedShaders::LightenCompositionModeFragmentShader; -
711 break;
never executed: break;
0
712 case QPainter::CompositionMode_ColorDodge: -
713 requiredProgram.compositionFragShader = QOpenGLEngineSharedShaders::ColorDodgeCompositionModeFragmentShader; -
714 break;
never executed: break;
0
715 case QPainter::CompositionMode_ColorBurn: -
716 requiredProgram.compositionFragShader = QOpenGLEngineSharedShaders::ColorBurnCompositionModeFragmentShader; -
717 break;
never executed: break;
0
718 case QPainter::CompositionMode_HardLight: -
719 requiredProgram.compositionFragShader = QOpenGLEngineSharedShaders::HardLightCompositionModeFragmentShader; -
720 break;
never executed: break;
0
721 case QPainter::CompositionMode_SoftLight: -
722 requiredProgram.compositionFragShader = QOpenGLEngineSharedShaders::SoftLightCompositionModeFragmentShader; -
723 break;
never executed: break;
0
724 case QPainter::CompositionMode_Difference: -
725 requiredProgram.compositionFragShader = QOpenGLEngineSharedShaders::DifferenceCompositionModeFragmentShader; -
726 break;
never executed: break;
0
727 case QPainter::CompositionMode_Exclusion: -
728 requiredProgram.compositionFragShader = QOpenGLEngineSharedShaders::ExclusionCompositionModeFragmentShader; -
729 break;
never executed: break;
0
730 default: -
731 QMessageLogger("opengl/qopenglengineshadermanager.cpp", 832, __PRETTY_FUNCTION__).warning("QOpenGLEngineShaderManager::useCorrectShaderProg() - Unsupported composition mode"); -
732 }
never executed: }
0
733 } else {
never executed: }
0
734 requiredProgram.compositionFragShader = QOpenGLEngineSharedShaders::NoCompositionModeFragmentShader; -
735 }
never executed: }
0
736 -
737 -
738 if (opacityMode == AttributeOpacity) {
never evaluated: opacityMode == AttributeOpacity
0
739 qt_noop(); -
740 requiredProgram.mainVertexShader = QOpenGLEngineSharedShaders::MainWithTexCoordsAndOpacityVertexShader; -
741 } else if (texCoords) {
never executed: }
never evaluated: texCoords
0
742 requiredProgram.mainVertexShader = QOpenGLEngineSharedShaders::MainWithTexCoordsVertexShader; -
743 } else {
never executed: }
0
744 requiredProgram.mainVertexShader = QOpenGLEngineSharedShaders::MainVertexShader; -
745 }
never executed: }
0
746 requiredProgram.useTextureCoords = texCoords; -
747 requiredProgram.useOpacityAttribute = (opacityMode == AttributeOpacity); -
748 if (complexGeometry && srcPixelType == Qt::SolidPattern) {
never evaluated: complexGeometry
never evaluated: srcPixelType == Qt::SolidPattern
0
749 requiredProgram.positionVertexShader = QOpenGLEngineSharedShaders::ComplexGeometryPositionOnlyVertexShader; -
750 requiredProgram.usePmvMatrixAttribute = false; -
751 } else {
never executed: }
0
752 requiredProgram.usePmvMatrixAttribute = true; -
753 -
754 -
755 -
756 complexGeometry = false; -
757 }
never executed: }
0
758 -
759 -
760 currentShaderProg = sharedShaders->findProgramInCache(requiredProgram); -
761 -
762 if (currentShaderProg && useCustomSrc) {
never evaluated: currentShaderProg
never evaluated: useCustomSrc
0
763 customSrcStage->setUniforms(currentShaderProg->program); -
764 }
never executed: }
0
765 -
766 -
767 -
768 QOpenGLContextPrivate* ctx_d = ctx->d_func(); -
769 QOpenGL2PaintEngineEx *active_engine = static_cast<QOpenGL2PaintEngineEx *>(ctx_d->active_engine); -
770 active_engine->d_func()->setVertexAttribArrayEnabled(QT_VERTEX_COORDS_ATTR, true); -
771 active_engine->d_func()->setVertexAttribArrayEnabled(QT_TEXTURE_COORDS_ATTR, currentShaderProg && currentShaderProg->useTextureCoords); -
772 active_engine->d_func()->setVertexAttribArrayEnabled(QT_OPACITY_ATTR, currentShaderProg && currentShaderProg->useOpacityAttribute); -
773 -
774 shaderProgNeedsChanging = false; -
775 return true;
never executed: return true;
0
776} -
777 -
778 -
779 -
Switch to Source codePreprocessed file

Generated by Squish Coco Non-Commercial