Absolute File Name: | /home/opencoverage/opencoverage/guest-scripts/qtdeclarative/src/qtdeclarative/src/quick/scenegraph/coreapi/qsgmaterial.cpp |
Source code | Switch to Preprocessed file |
Line | Source | Count | ||||||
---|---|---|---|---|---|---|---|---|
1 | /**************************************************************************** | - | ||||||
2 | ** | - | ||||||
3 | ** Copyright (C) 2016 The Qt Company Ltd. | - | ||||||
4 | ** Contact: https://www.qt.io/licensing/ | - | ||||||
5 | ** | - | ||||||
6 | ** This file is part of the QtQuick module of the Qt Toolkit. | - | ||||||
7 | ** | - | ||||||
8 | ** $QT_BEGIN_LICENSE:LGPL$ | - | ||||||
9 | ** Commercial License Usage | - | ||||||
10 | ** Licensees holding valid commercial Qt licenses may use this file in | - | ||||||
11 | ** accordance with the commercial license agreement provided with the | - | ||||||
12 | ** Software or, alternatively, in accordance with the terms contained in | - | ||||||
13 | ** a written agreement between you and The Qt Company. For licensing terms | - | ||||||
14 | ** and conditions see https://www.qt.io/terms-conditions. For further | - | ||||||
15 | ** information use the contact form at https://www.qt.io/contact-us. | - | ||||||
16 | ** | - | ||||||
17 | ** GNU Lesser General Public License Usage | - | ||||||
18 | ** Alternatively, this file may be used under the terms of the GNU Lesser | - | ||||||
19 | ** General Public License version 3 as published by the Free Software | - | ||||||
20 | ** Foundation and appearing in the file LICENSE.LGPL3 included in the | - | ||||||
21 | ** packaging of this file. Please review the following information to | - | ||||||
22 | ** ensure the GNU Lesser General Public License version 3 requirements | - | ||||||
23 | ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. | - | ||||||
24 | ** | - | ||||||
25 | ** GNU General Public License Usage | - | ||||||
26 | ** Alternatively, this file may be used under the terms of the GNU | - | ||||||
27 | ** General Public License version 2.0 or (at your option) the GNU General | - | ||||||
28 | ** Public license version 3 or any later version approved by the KDE Free | - | ||||||
29 | ** Qt Foundation. The licenses are as published by the Free Software | - | ||||||
30 | ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 | - | ||||||
31 | ** included in the packaging of this file. Please review the following | - | ||||||
32 | ** information to ensure the GNU General Public License requirements will | - | ||||||
33 | ** be met: https://www.gnu.org/licenses/gpl-2.0.html and | - | ||||||
34 | ** https://www.gnu.org/licenses/gpl-3.0.html. | - | ||||||
35 | ** | - | ||||||
36 | ** $QT_END_LICENSE$ | - | ||||||
37 | ** | - | ||||||
38 | ****************************************************************************/ | - | ||||||
39 | - | |||||||
40 | #include "qsgmaterial.h" | - | ||||||
41 | #include "qsgrenderer_p.h" | - | ||||||
42 | #include "qsgmaterialshader_p.h" | - | ||||||
43 | #if QT_CONFIG(opengl) | - | ||||||
44 | # include <private/qsgshadersourcebuilder_p.h> | - | ||||||
45 | # include <private/qsgdefaultcontext_p.h> | - | ||||||
46 | # include <private/qsgdefaultrendercontext_p.h> | - | ||||||
47 | # include <QtGui/QOpenGLFunctions> | - | ||||||
48 | # include <QtGui/QOpenGLContext> | - | ||||||
49 | #endif | - | ||||||
50 | - | |||||||
51 | QT_BEGIN_NAMESPACE | - | ||||||
52 | - | |||||||
53 | #ifndef QT_NO_DEBUG | - | ||||||
54 | bool qsg_material_failure = false; | - | ||||||
55 | bool qsg_test_and_clear_material_failure() | - | ||||||
56 | { | - | ||||||
57 | bool fail = qsg_material_failure; | - | ||||||
58 | qsg_material_failure = false; | - | ||||||
59 | return fail; executed 116002 times by 70 tests: return fail; Executed by:
| 116002 | ||||||
60 | } | - | ||||||
61 | - | |||||||
62 | void qsg_set_material_failure() | - | ||||||
63 | { | - | ||||||
64 | qsg_material_failure = true; | - | ||||||
65 | } never executed: end of block | 0 | ||||||
66 | #endif | - | ||||||
67 | #if QT_CONFIG(opengl) | - | ||||||
68 | const char *QSGMaterialShaderPrivate::loadShaderSource(QOpenGLShader::ShaderType type) const | - | ||||||
69 | { | - | ||||||
70 | const QStringList files = m_sourceFiles[type]; | - | ||||||
71 | QSGShaderSourceBuilder builder; | - | ||||||
72 | for (const QString &file : files) | - | ||||||
73 | builder.appendSourceFile(file); executed 8754 times by 70 tests: builder.appendSourceFile(file); Executed by:
| 8754 | ||||||
74 | m_sources[type] = builder.source(); | - | ||||||
75 | return m_sources[type].constData(); executed 8754 times by 70 tests: return m_sources[type].constData(); Executed by:
| 8754 | ||||||
76 | } | - | ||||||
77 | #endif | - | ||||||
78 | - | |||||||
79 | #ifndef QT_NO_DEBUG | - | ||||||
80 | static const bool qsg_leak_check = !qEnvironmentVariableIsEmpty("QML_LEAK_CHECK"); | - | ||||||
81 | #endif | - | ||||||
82 | - | |||||||
83 | /*! | - | ||||||
84 | \group qtquick-scenegraph-materials | - | ||||||
85 | \title Qt Quick Scene Graph Material Classes | - | ||||||
86 | \brief classes used to define materials in the Qt Quick Scene Graph. | - | ||||||
87 | - | |||||||
88 | This page lists the material classes in \l {Qt Quick}'s | - | ||||||
89 | \l {scene graph}{Qt Quick Scene Graph}. | - | ||||||
90 | */ | - | ||||||
91 | - | |||||||
92 | /*! | - | ||||||
93 | \class QSGMaterialShader | - | ||||||
94 | \brief The QSGMaterialShader class represents an OpenGL shader program | - | ||||||
95 | in the renderer. | - | ||||||
96 | \inmodule QtQuick | - | ||||||
97 | \ingroup qtquick-scenegraph-materials | - | ||||||
98 | - | |||||||
99 | The QSGMaterialShader API is very low-level. A more convenient API, which | - | ||||||
100 | provides almost all the same features, is available through | - | ||||||
101 | QSGSimpleMaterialShader. | - | ||||||
102 | - | |||||||
103 | The QSGMaterial and QSGMaterialShader form a tight relationship. For one | - | ||||||
104 | scene graph (including nested graphs), there is one unique QSGMaterialShader | - | ||||||
105 | instance which encapsulates the QOpenGLShaderProgram the scene graph uses | - | ||||||
106 | to render that material, such as a shader to flat coloring of geometry. | - | ||||||
107 | Each QSGGeometryNode can have a unique QSGMaterial containing the | - | ||||||
108 | how the shader should be configured when drawing that node, such as | - | ||||||
109 | the actual color used to render the geometry. | - | ||||||
110 | - | |||||||
111 | An instance of QSGMaterialShader is never created explicitly by the user, | - | ||||||
112 | it will be created on demand by the scene graph through | - | ||||||
113 | QSGMaterial::createShader(). The scene graph will make sure that there | - | ||||||
114 | is only one instance of each shader implementation through a scene graph. | - | ||||||
115 | - | |||||||
116 | The source code returned from vertexShader() is used to control what the | - | ||||||
117 | material does with the vertiex data that comes in from the geometry. | - | ||||||
118 | The source code returned from the fragmentShader() is used to control | - | ||||||
119 | what how the material should fill each individual pixel in the geometry. | - | ||||||
120 | The vertex and fragment source code is queried once during initialization, | - | ||||||
121 | changing what is returned from these functions later will not have | - | ||||||
122 | any effect. | - | ||||||
123 | - | |||||||
124 | The activate() function is called by the scene graph when a shader is | - | ||||||
125 | is starting to be used. The deactivate function is called by the scene | - | ||||||
126 | graph when the shader is no longer going to be used. While active, | - | ||||||
127 | the scene graph may make one or more calls to updateState() which | - | ||||||
128 | will update the state of the shader for each individual geometry to | - | ||||||
129 | render. | - | ||||||
130 | - | |||||||
131 | The attributeNames() returns the name of the attributes used in the | - | ||||||
132 | vertexShader(). These are used in the default implementation of | - | ||||||
133 | activate() and deactivate() to decide whice vertex registers are enabled. | - | ||||||
134 | - | |||||||
135 | The initialize() function is called during program creation to allow | - | ||||||
136 | subclasses to prepare for use, such as resolve uniform names in the | - | ||||||
137 | vertexShader() and fragmentShader(). | - | ||||||
138 | - | |||||||
139 | A minimal example: | - | ||||||
140 | \code | - | ||||||
141 | class Shader : public QSGMaterialShader | - | ||||||
142 | { | - | ||||||
143 | public: | - | ||||||
144 | const char *vertexShader() const { | - | ||||||
145 | return | - | ||||||
146 | "attribute highp vec4 vertex; \n" | - | ||||||
147 | "uniform highp mat4 matrix; \n" | - | ||||||
148 | "void main() { \n" | - | ||||||
149 | " gl_Position = matrix * vertex; \n" | - | ||||||
150 | "}"; | - | ||||||
151 | } | - | ||||||
152 | - | |||||||
153 | const char *fragmentShader() const { | - | ||||||
154 | return | - | ||||||
155 | "uniform lowp float opacity; \n" | - | ||||||
156 | "void main() { \n" | - | ||||||
157 | " gl_FragColor = vec4(1, 0, 0, 1) * opacity; \n" | - | ||||||
158 | "}"; | - | ||||||
159 | } | - | ||||||
160 | - | |||||||
161 | char const *const *attributeNames() const | - | ||||||
162 | { | - | ||||||
163 | static char const *const names[] = { "vertex", 0 }; | - | ||||||
164 | return names; | - | ||||||
165 | } | - | ||||||
166 | - | |||||||
167 | void initialize() | - | ||||||
168 | { | - | ||||||
169 | QSGMaterialShader::initialize(); | - | ||||||
170 | m_id_matrix = program()->uniformLocation("matrix"); | - | ||||||
171 | m_id_opacity = program()->uniformLocation("opacity"); | - | ||||||
172 | } | - | ||||||
173 | - | |||||||
174 | void updateState(const RenderState &state, QSGMaterial *newMaterial, QSGMaterial *oldMaterial) | - | ||||||
175 | { | - | ||||||
176 | Q_ASSERT(program()->isLinked()); | - | ||||||
177 | if (state.isMatrixDirty()) | - | ||||||
178 | program()->setUniformValue(m_id_matrix, state.combinedMatrix()); | - | ||||||
179 | if (state.isOpacityDirty()) | - | ||||||
180 | program()->setUniformValue(m_id_opacity, state.opacity()); | - | ||||||
181 | } | - | ||||||
182 | - | |||||||
183 | private: | - | ||||||
184 | int m_id_matrix; | - | ||||||
185 | int m_id_opacity; | - | ||||||
186 | }; | - | ||||||
187 | \endcode | - | ||||||
188 | - | |||||||
189 | \note All classes with QSG prefix should be used solely on the scene graph's | - | ||||||
190 | rendering thread. See \l {Scene Graph and Rendering} for more information. | - | ||||||
191 | - | |||||||
192 | */ | - | ||||||
193 | - | |||||||
194 | - | |||||||
195 | - | |||||||
196 | /*! | - | ||||||
197 | Creates a new QSGMaterialShader. | - | ||||||
198 | */ | - | ||||||
199 | QSGMaterialShader::QSGMaterialShader() | - | ||||||
200 | : d_ptr(new QSGMaterialShaderPrivate) | - | ||||||
201 | { | - | ||||||
202 | } executed 4482 times by 70 tests: end of block Executed by:
| 4482 | ||||||
203 | - | |||||||
204 | /*! | - | ||||||
205 | \internal | - | ||||||
206 | */ | - | ||||||
207 | QSGMaterialShader::QSGMaterialShader(QSGMaterialShaderPrivate &dd) | - | ||||||
208 | : d_ptr(&dd) | - | ||||||
209 | { | - | ||||||
210 | } executed 22 times by 2 tests: end of block Executed by:
| 22 | ||||||
211 | - | |||||||
212 | /*! | - | ||||||
213 | \internal | - | ||||||
214 | */ | - | ||||||
215 | QSGMaterialShader::~QSGMaterialShader() | - | ||||||
216 | { | - | ||||||
217 | } | - | ||||||
218 | - | |||||||
219 | /*! | - | ||||||
220 | \fn char const *const *QSGMaterialShader::attributeNames() const | - | ||||||
221 | - | |||||||
222 | Returns a zero-terminated array describing the names of the | - | ||||||
223 | attributes used in the vertex shader. | - | ||||||
224 | - | |||||||
225 | This function is called when the shader is compiled to specify | - | ||||||
226 | which attributes exist. The order of the attribute names | - | ||||||
227 | defines the attribute register position in the vertex shader. | - | ||||||
228 | */ | - | ||||||
229 | - | |||||||
230 | #if QT_CONFIG(opengl) | - | ||||||
231 | /*! | - | ||||||
232 | \fn const char *QSGMaterialShader::vertexShader() const | - | ||||||
233 | - | |||||||
234 | Called when the shader is being initialized to get the vertex | - | ||||||
235 | shader source code. | - | ||||||
236 | - | |||||||
237 | The contents returned from this function should never change. | - | ||||||
238 | */ | - | ||||||
239 | const char *QSGMaterialShader::vertexShader() const | - | ||||||
240 | { | - | ||||||
241 | Q_D(const QSGMaterialShader); | - | ||||||
242 | return d->loadShaderSource(QOpenGLShader::Vertex); executed 4377 times by 70 tests: return d->loadShaderSource(QOpenGLShader::Vertex); Executed by:
| 4377 | ||||||
243 | } | - | ||||||
244 | - | |||||||
245 | - | |||||||
246 | /*! | - | ||||||
247 | \fn const char *QSGMaterialShader::fragmentShader() const | - | ||||||
248 | - | |||||||
249 | Called when the shader is being initialized to get the fragment | - | ||||||
250 | shader source code. | - | ||||||
251 | - | |||||||
252 | The contents returned from this function should never change. | - | ||||||
253 | */ | - | ||||||
254 | const char *QSGMaterialShader::fragmentShader() const | - | ||||||
255 | { | - | ||||||
256 | Q_D(const QSGMaterialShader); | - | ||||||
257 | return d->loadShaderSource(QOpenGLShader::Fragment); executed 4377 times by 70 tests: return d->loadShaderSource(QOpenGLShader::Fragment); Executed by:
| 4377 | ||||||
258 | } | - | ||||||
259 | - | |||||||
260 | - | |||||||
261 | /*! | - | ||||||
262 | \fn QOpenGLShaderProgram *QSGMaterialShader::program() | - | ||||||
263 | - | |||||||
264 | Returns the shader program used by this QSGMaterialShader. | - | ||||||
265 | */ | - | ||||||
266 | #endif | - | ||||||
267 | - | |||||||
268 | /*! | - | ||||||
269 | \fn void QSGMaterialShader::initialize() | - | ||||||
270 | - | |||||||
271 | Reimplement this function to do one-time initialization when the | - | ||||||
272 | shader program is compiled. The OpenGL shader program is compiled | - | ||||||
273 | and linked, but not bound, when this function is called. | - | ||||||
274 | */ | - | ||||||
275 | - | |||||||
276 | - | |||||||
277 | /*! | - | ||||||
278 | This function is called by the scene graph to indicate that geometry is | - | ||||||
279 | about to be rendered using this shader. | - | ||||||
280 | - | |||||||
281 | State that is global for all uses of the shader, independent of the geometry | - | ||||||
282 | that is being drawn, can be setup in this function. | - | ||||||
283 | */ | - | ||||||
284 | - | |||||||
285 | void QSGMaterialShader::activate() | - | ||||||
286 | { | - | ||||||
287 | } | - | ||||||
288 | - | |||||||
289 | - | |||||||
290 | - | |||||||
291 | /*! | - | ||||||
292 | This function is called by the scene graph to indicate that geometry will | - | ||||||
293 | no longer to be rendered using this shader. | - | ||||||
294 | */ | - | ||||||
295 | - | |||||||
296 | void QSGMaterialShader::deactivate() | - | ||||||
297 | { | - | ||||||
298 | } | - | ||||||
299 | - | |||||||
300 | - | |||||||
301 | - | |||||||
302 | /*! | - | ||||||
303 | This function is called by the scene graph before geometry is rendered | - | ||||||
304 | to make sure the shader is in the right state. | - | ||||||
305 | - | |||||||
306 | The current rendering \a state is passed from the scene graph. If the state | - | ||||||
307 | indicates that any state is dirty, the updateState implementation must | - | ||||||
308 | update accordingly for the geometry to render correctly. | - | ||||||
309 | - | |||||||
310 | The subclass specific state, such as the color of a flat color material, should | - | ||||||
311 | be extracted from \a newMaterial to update the color uniforms accordingly. | - | ||||||
312 | - | |||||||
313 | The \a oldMaterial can be used to minimze state changes when updating | - | ||||||
314 | material states. The \a oldMaterial is 0 if this shader was just activated. | - | ||||||
315 | - | |||||||
316 | \sa activate(), deactivate() | - | ||||||
317 | */ | - | ||||||
318 | - | |||||||
319 | void QSGMaterialShader::updateState(const RenderState & /* state */, QSGMaterial * /* newMaterial */, QSGMaterial * /* oldMaterial */) | - | ||||||
320 | { | - | ||||||
321 | } | - | ||||||
322 | - | |||||||
323 | #if QT_CONFIG(opengl) | - | ||||||
324 | /*! | - | ||||||
325 | Sets the GLSL source file for the shader stage \a type to \a sourceFile. The | - | ||||||
326 | default implementation of the vertexShader() and fragmentShader() functions | - | ||||||
327 | will load the source files set by this function. | - | ||||||
328 | - | |||||||
329 | This function is useful when you have a single source file for a given shader | - | ||||||
330 | stage. If your shader consists of multiple source files then use | - | ||||||
331 | setShaderSourceFiles() | - | ||||||
332 | - | |||||||
333 | \sa setShaderSourceFiles(), vertexShader(), fragmentShader() | - | ||||||
334 | */ | - | ||||||
335 | void QSGMaterialShader::setShaderSourceFile(QOpenGLShader::ShaderType type, const QString &sourceFile) | - | ||||||
336 | { | - | ||||||
337 | Q_D(QSGMaterialShader); | - | ||||||
338 | d->m_sourceFiles[type] = (QStringList() << sourceFile); | - | ||||||
339 | } executed 11868 times by 70 tests: end of block Executed by:
| 11868 | ||||||
340 | - | |||||||
341 | /*! | - | ||||||
342 | Sets the GLSL source files for the shader stage \a type to \a sourceFiles. The | - | ||||||
343 | default implementation of the vertexShader() and fragmentShader() functions | - | ||||||
344 | will load the source files set by this function in the order given. | - | ||||||
345 | - | |||||||
346 | \sa setShaderSourceFile(), vertexShader(), fragmentShader() | - | ||||||
347 | */ | - | ||||||
348 | void QSGMaterialShader::setShaderSourceFiles(QOpenGLShader::ShaderType type, const QStringList &sourceFiles) | - | ||||||
349 | { | - | ||||||
350 | Q_D(QSGMaterialShader); | - | ||||||
351 | d->m_sourceFiles[type] = sourceFiles; | - | ||||||
352 | } never executed: end of block | 0 | ||||||
353 | - | |||||||
354 | /*! | - | ||||||
355 | This function is called when the shader is initialized to compile the | - | ||||||
356 | actual QOpenGLShaderProgram. Do not call it explicitly. | - | ||||||
357 | - | |||||||
358 | The default implementation will extract the vertexShader() and | - | ||||||
359 | fragmentShader() and bind the names returned from attributeNames() | - | ||||||
360 | to consecutive vertex attribute registers starting at 0. | - | ||||||
361 | */ | - | ||||||
362 | - | |||||||
363 | void QSGMaterialShader::compile() | - | ||||||
364 | { | - | ||||||
365 | Q_ASSERT_X(!m_program.isLinked(), "QSGSMaterialShader::compile()", "Compile called multiple times!"); | - | ||||||
366 | - | |||||||
367 | program()->addCacheableShaderFromSourceCode(QOpenGLShader::Vertex, vertexShader()); | - | ||||||
368 | program()->addCacheableShaderFromSourceCode(QOpenGLShader::Fragment, fragmentShader()); | - | ||||||
369 | - | |||||||
370 | char const *const *attr = attributeNames(); | - | ||||||
371 | #ifndef QT_NO_DEBUG | - | ||||||
372 | int maxVertexAttribs = 0; | - | ||||||
373 | QOpenGLFunctions *funcs = QOpenGLContext::currentContext()->functions(); | - | ||||||
374 | funcs->glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &maxVertexAttribs); | - | ||||||
375 | for (int i = 0; attr[i]; ++i) {
| 135-404 | ||||||
376 | if (i >= maxVertexAttribs) {
| 0-404 | ||||||
377 | qFatal("List of attribute names is either too long or not null-terminated.\n" | - | ||||||
378 | "Maximum number of attributes on this hardware is %i.\n" | - | ||||||
379 | "Vertex shader:\n%s\n" | - | ||||||
380 | "Fragment shader:\n%s\n", | - | ||||||
381 | maxVertexAttribs, vertexShader(), fragmentShader()); | - | ||||||
382 | } never executed: end of block | 0 | ||||||
383 | if (*attr[i])
| 0-404 | ||||||
384 | program()->bindAttributeLocation(attr[i], i); executed 404 times by 29 tests: program()->bindAttributeLocation(attr[i], i); Executed by:
| 404 | ||||||
385 | } executed 404 times by 29 tests: end of block Executed by:
| 404 | ||||||
386 | #else | - | ||||||
387 | for (int i = 0; attr[i]; ++i) { | - | ||||||
388 | if (*attr[i]) | - | ||||||
389 | program()->bindAttributeLocation(attr[i], i); | - | ||||||
390 | } | - | ||||||
391 | #endif | - | ||||||
392 | - | |||||||
393 | if (!program()->link()) {
| 0-135 | ||||||
394 | qWarning("QSGMaterialShader: Shader compilation failed:"); | - | ||||||
395 | qWarning() << program()->log(); | - | ||||||
396 | } never executed: end of block | 0 | ||||||
397 | } executed 135 times by 29 tests: end of block Executed by:
| 135 | ||||||
398 | - | |||||||
399 | #endif | - | ||||||
400 | - | |||||||
401 | /*! | - | ||||||
402 | \class QSGMaterialShader::RenderState | - | ||||||
403 | \brief The QSGMaterialShader::RenderState encapsulates the current rendering state | - | ||||||
404 | during a call to QSGMaterialShader::updateState(). | - | ||||||
405 | \inmodule QtQuick | - | ||||||
406 | - | |||||||
407 | The render state contains a number of accessors that the shader needs to respect | - | ||||||
408 | in order to conform to the current state of the scene graph. | - | ||||||
409 | - | |||||||
410 | The instance is only valid inside a call to QSGMaterialShader::updateState() and | - | ||||||
411 | should not be used outisde this function. | - | ||||||
412 | */ | - | ||||||
413 | - | |||||||
414 | - | |||||||
415 | - | |||||||
416 | /*! | - | ||||||
417 | \enum QSGMaterialShader::RenderState::DirtyState | - | ||||||
418 | - | |||||||
419 | \value DirtyMatrix Used to indicate that the matrix has changed and must be updated. | - | ||||||
420 | - | |||||||
421 | \value DirtyOpacity Used to indicate that the opacity has changed and must be updated. | - | ||||||
422 | - | |||||||
423 | \value DirtyCachedMaterialData Used to indicate that the cached material data have changed and must be updated. | - | ||||||
424 | - | |||||||
425 | \value DirtyAll Used to indicate that everything needs to be updated. | - | ||||||
426 | */ | - | ||||||
427 | - | |||||||
428 | - | |||||||
429 | - | |||||||
430 | /*! | - | ||||||
431 | \fn bool QSGMaterialShader::RenderState::isMatrixDirty() const | - | ||||||
432 | - | |||||||
433 | Returns \c true if the dirtyStates() contain the dirty matrix state, | - | ||||||
434 | otherwise returns \c false. | - | ||||||
435 | */ | - | ||||||
436 | - | |||||||
437 | - | |||||||
438 | - | |||||||
439 | /*! | - | ||||||
440 | \fn bool QSGMaterialShader::RenderState::isOpacityDirty() const | - | ||||||
441 | - | |||||||
442 | Returns \c true if the dirtyStates() contains the dirty opacity state, | - | ||||||
443 | otherwise returns \c false. | - | ||||||
444 | */ | - | ||||||
445 | - | |||||||
446 | /*! | - | ||||||
447 | \fn bool QSGMaterialShader::RenderState::isCachedMaterialDataDirty() const | - | ||||||
448 | - | |||||||
449 | Returns \c true if the dirtyStates() contains the dirty cached material state, | - | ||||||
450 | otherwise returns \c false. | - | ||||||
451 | */ | - | ||||||
452 | - | |||||||
453 | /*! | - | ||||||
454 | \fn QSGMaterialShader::RenderState::DirtyStates QSGMaterialShader::RenderState::dirtyStates() const | - | ||||||
455 | - | |||||||
456 | Returns which rendering states that have changed and needs to be updated | - | ||||||
457 | for geometry rendered with this material to conform to the current | - | ||||||
458 | rendering state. | - | ||||||
459 | */ | - | ||||||
460 | - | |||||||
461 | - | |||||||
462 | - | |||||||
463 | /*! | - | ||||||
464 | Returns the accumulated opacity to be used for rendering. | - | ||||||
465 | */ | - | ||||||
466 | - | |||||||
467 | float QSGMaterialShader::RenderState::opacity() const | - | ||||||
468 | { | - | ||||||
469 | Q_ASSERT(m_data); | - | ||||||
470 | return static_cast<const QSGRenderer *>(m_data)->currentOpacity(); executed 59094 times by 67 tests: return static_cast<const QSGRenderer *>(m_data)->currentOpacity(); Executed by:
| 59094 | ||||||
471 | } | - | ||||||
472 | - | |||||||
473 | /*! | - | ||||||
474 | Returns the modelview determinant to be used for rendering. | - | ||||||
475 | */ | - | ||||||
476 | - | |||||||
477 | float QSGMaterialShader::RenderState::determinant() const | - | ||||||
478 | { | - | ||||||
479 | Q_ASSERT(m_data); | - | ||||||
480 | return static_cast<const QSGRenderer *>(m_data)->determinant(); executed 34190 times by 24 tests: return static_cast<const QSGRenderer *>(m_data)->determinant(); Executed by:
| 34190 | ||||||
481 | } | - | ||||||
482 | - | |||||||
483 | /*! | - | ||||||
484 | Returns the matrix combined of modelview matrix and project matrix. | - | ||||||
485 | */ | - | ||||||
486 | - | |||||||
487 | QMatrix4x4 QSGMaterialShader::RenderState::combinedMatrix() const | - | ||||||
488 | { | - | ||||||
489 | Q_ASSERT(m_data); | - | ||||||
490 | return static_cast<const QSGRenderer *>(m_data)->currentCombinedMatrix(); executed 150174 times by 70 tests: return static_cast<const QSGRenderer *>(m_data)->currentCombinedMatrix(); Executed by:
| 150174 | ||||||
491 | } | - | ||||||
492 | /*! | - | ||||||
493 | Returns the ratio between physical pixels and device-independent pixels | - | ||||||
494 | to be used for rendering. | - | ||||||
495 | */ | - | ||||||
496 | float QSGMaterialShader::RenderState::devicePixelRatio() const | - | ||||||
497 | { | - | ||||||
498 | Q_ASSERT(m_data); | - | ||||||
499 | return static_cast<const QSGRenderer *>(m_data)->devicePixelRatio(); executed 34190 times by 24 tests: return static_cast<const QSGRenderer *>(m_data)->devicePixelRatio(); Executed by:
| 34190 | ||||||
500 | } | - | ||||||
501 | - | |||||||
502 | - | |||||||
503 | - | |||||||
504 | /*! | - | ||||||
505 | Returns the model view matrix. | - | ||||||
506 | - | |||||||
507 | If the material has the RequiresFullMatrix flag | - | ||||||
508 | set, this is guaranteed to be the complete transform | - | ||||||
509 | matrix calculated from the scenegraph. | - | ||||||
510 | - | |||||||
511 | However, if this flag is not set, the renderer may | - | ||||||
512 | choose to alter this matrix. For example, it may | - | ||||||
513 | pre-transform vertices on the CPU and set this matrix | - | ||||||
514 | to identity. | - | ||||||
515 | - | |||||||
516 | In a situation such as the above, it is still possible | - | ||||||
517 | to retrieve the actual matrix determinant by setting | - | ||||||
518 | the RequiresDeterminant flag in the material and | - | ||||||
519 | calling the determinant() accessor. | - | ||||||
520 | */ | - | ||||||
521 | - | |||||||
522 | QMatrix4x4 QSGMaterialShader::RenderState::modelViewMatrix() const | - | ||||||
523 | { | - | ||||||
524 | Q_ASSERT(m_data); | - | ||||||
525 | return static_cast<const QSGRenderer *>(m_data)->currentModelViewMatrix(); never executed: return static_cast<const QSGRenderer *>(m_data)->currentModelViewMatrix(); | 0 | ||||||
526 | } | - | ||||||
527 | - | |||||||
528 | /*! | - | ||||||
529 | Returns the projection matrix. | - | ||||||
530 | */ | - | ||||||
531 | - | |||||||
532 | QMatrix4x4 QSGMaterialShader::RenderState::projectionMatrix() const | - | ||||||
533 | { | - | ||||||
534 | Q_ASSERT(m_data); | - | ||||||
535 | return static_cast<const QSGRenderer *>(m_data)->currentProjectionMatrix(); never executed: return static_cast<const QSGRenderer *>(m_data)->currentProjectionMatrix(); | 0 | ||||||
536 | } | - | ||||||
537 | - | |||||||
538 | - | |||||||
539 | - | |||||||
540 | /*! | - | ||||||
541 | Returns the viewport rect of the surface being rendered to. | - | ||||||
542 | */ | - | ||||||
543 | - | |||||||
544 | QRect QSGMaterialShader::RenderState::viewportRect() const | - | ||||||
545 | { | - | ||||||
546 | Q_ASSERT(m_data); | - | ||||||
547 | return static_cast<const QSGRenderer *>(m_data)->viewportRect(); executed 35688 times by 26 tests: return static_cast<const QSGRenderer *>(m_data)->viewportRect(); Executed by:
| 35688 | ||||||
548 | } | - | ||||||
549 | - | |||||||
550 | - | |||||||
551 | - | |||||||
552 | /*! | - | ||||||
553 | Returns the device rect of the surface being rendered to | - | ||||||
554 | */ | - | ||||||
555 | - | |||||||
556 | QRect QSGMaterialShader::RenderState::deviceRect() const | - | ||||||
557 | { | - | ||||||
558 | Q_ASSERT(m_data); | - | ||||||
559 | return static_cast<const QSGRenderer *>(m_data)->deviceRect(); never executed: return static_cast<const QSGRenderer *>(m_data)->deviceRect(); | 0 | ||||||
560 | } | - | ||||||
561 | - | |||||||
562 | #if QT_CONFIG(opengl) | - | ||||||
563 | - | |||||||
564 | /*! | - | ||||||
565 | Returns the QOpenGLContext that is being used for rendering | - | ||||||
566 | */ | - | ||||||
567 | - | |||||||
568 | QOpenGLContext *QSGMaterialShader::RenderState::context() const | - | ||||||
569 | { | - | ||||||
570 | // Only the QSGDefaultRenderContext will have an OpenGL Context to query | - | ||||||
571 | auto openGLRenderContext = static_cast<const QSGDefaultRenderContext *>(static_cast<const QSGRenderer *>(m_data)->context()); | - | ||||||
572 | if (openGLRenderContext != nullptr)
| 0-84778 | ||||||
573 | return openGLRenderContext->openglContext(); executed 84778 times by 33 tests: return openGLRenderContext->openglContext(); Executed by:
| 84778 | ||||||
574 | else | - | ||||||
575 | return nullptr; never executed: return nullptr; | 0 | ||||||
576 | } | - | ||||||
577 | - | |||||||
578 | #endif | - | ||||||
579 | - | |||||||
580 | #ifndef QT_NO_DEBUG | - | ||||||
581 | static int qt_material_count = 0; | - | ||||||
582 | - | |||||||
583 | static void qt_print_material_count() | - | ||||||
584 | { | - | ||||||
585 | qDebug("Number of leaked materials: %i", qt_material_count); | - | ||||||
586 | qt_material_count = -1; | - | ||||||
587 | } never executed: end of block | 0 | ||||||
588 | #endif | - | ||||||
589 | - | |||||||
590 | /*! | - | ||||||
591 | \class QSGMaterialType | - | ||||||
592 | \brief The QSGMaterialType class is used as a unique type token in combination with QSGMaterial. | - | ||||||
593 | \inmodule QtQuick | - | ||||||
594 | \ingroup qtquick-scenegraph-materials | - | ||||||
595 | - | |||||||
596 | It serves no purpose outside the QSGMaterial::type() function. | - | ||||||
597 | - | |||||||
598 | \note All classes with QSG prefix should be used solely on the scene graph's | - | ||||||
599 | rendering thread. See \l {Scene Graph and Rendering} for more information. | - | ||||||
600 | */ | - | ||||||
601 | - | |||||||
602 | /*! | - | ||||||
603 | \class QSGMaterial | - | ||||||
604 | \brief The QSGMaterial class encapsulates rendering state for a shader program. | - | ||||||
605 | \inmodule QtQuick | - | ||||||
606 | \ingroup qtquick-scenegraph-materials | - | ||||||
607 | - | |||||||
608 | The QSGMaterial API is very low-level. A more convenient API, which | - | ||||||
609 | provides almost all the same features, is available through | - | ||||||
610 | QSGSimpleMaterialShader. | - | ||||||
611 | - | |||||||
612 | The QSGMaterial and QSGMaterialShader subclasses form a tight relationship. For | - | ||||||
613 | one scene graph (including nested graphs), there is one unique QSGMaterialShader | - | ||||||
614 | instance which encapsulates the QOpenGLShaderProgram the scene graph uses | - | ||||||
615 | to render that material, such as a shader to flat coloring of geometry. | - | ||||||
616 | Each QSGGeometryNode can have a unique QSGMaterial containing the | - | ||||||
617 | how the shader should be configured when drawing that node, such as | - | ||||||
618 | the actual color to used to render the geometry. | - | ||||||
619 | - | |||||||
620 | The QSGMaterial has two virtual functions that both need to be implemented. | - | ||||||
621 | The function type() should return a unique instance for all instances of a | - | ||||||
622 | specific subclass. The createShader() function should return a new instance | - | ||||||
623 | of QSGMaterialShader, specific to the subclass of QSGMaterial. | - | ||||||
624 | - | |||||||
625 | A minimal QSGMaterial implementation could look like this: | - | ||||||
626 | \code | - | ||||||
627 | class Material : public QSGMaterial | - | ||||||
628 | { | - | ||||||
629 | public: | - | ||||||
630 | QSGMaterialType *type() const { static QSGMaterialType type; return &type; } | - | ||||||
631 | QSGMaterialShader *createShader() const { return new Shader; } | - | ||||||
632 | }; | - | ||||||
633 | \endcode | - | ||||||
634 | - | |||||||
635 | \note All classes with QSG prefix should be used solely on the scene graph's | - | ||||||
636 | rendering thread. See \l {Scene Graph and Rendering} for more information. | - | ||||||
637 | */ | - | ||||||
638 | - | |||||||
639 | /*! | - | ||||||
640 | \internal | - | ||||||
641 | */ | - | ||||||
642 | - | |||||||
643 | QSGMaterial::QSGMaterial() | - | ||||||
644 | : m_flags(nullptr) | - | ||||||
645 | { | - | ||||||
646 | Q_UNUSED(m_reserved); | - | ||||||
647 | #ifndef QT_NO_DEBUG | - | ||||||
648 | if (qsg_leak_check) {
| 0-610546 | ||||||
649 | ++qt_material_count; | - | ||||||
650 | static bool atexit_registered = false; | - | ||||||
651 | if (!atexit_registered) {
| 0 | ||||||
652 | atexit(qt_print_material_count); | - | ||||||
653 | atexit_registered = true; | - | ||||||
654 | } never executed: end of block | 0 | ||||||
655 | } never executed: end of block | 0 | ||||||
656 | #endif | - | ||||||
657 | } executed 610546 times by 72 tests: end of block Executed by:
| 610546 | ||||||
658 | - | |||||||
659 | - | |||||||
660 | /*! | - | ||||||
661 | \internal | - | ||||||
662 | */ | - | ||||||
663 | - | |||||||
664 | QSGMaterial::~QSGMaterial() | - | ||||||
665 | { | - | ||||||
666 | #ifndef QT_NO_DEBUG | - | ||||||
667 | if (qsg_leak_check) {
| 0-610546 | ||||||
668 | --qt_material_count; | - | ||||||
669 | if (qt_material_count < 0)
| 0 | ||||||
670 | qDebug("Material destroyed after qt_print_material_count() was called."); never executed: QMessageLogger(__FILE__, 670, __PRETTY_FUNCTION__).debug("Material destroyed after qt_print_material_count() was called."); | 0 | ||||||
671 | } never executed: end of block | 0 | ||||||
672 | #endif | - | ||||||
673 | } executed 610546 times by 72 tests: end of block Executed by:
| 610546 | ||||||
674 | - | |||||||
675 | - | |||||||
676 | - | |||||||
677 | /*! | - | ||||||
678 | \enum QSGMaterial::Flag | - | ||||||
679 | - | |||||||
680 | \value Blending Set this flag to true if the material requires GL_BLEND to be | - | ||||||
681 | enabled during rendering. | - | ||||||
682 | - | |||||||
683 | \value RequiresDeterminant Set this flag to true if the material relies on | - | ||||||
684 | the determinant of the matrix of the geometry nodes for rendering. | - | ||||||
685 | - | |||||||
686 | \value RequiresFullMatrixExceptTranslate Set this flag to true if the material | - | ||||||
687 | relies on the full matrix of the geometry nodes for rendering, except the translation part. | - | ||||||
688 | - | |||||||
689 | \value RequiresFullMatrix Set this flag to true if the material relies on | - | ||||||
690 | the full matrix of the geometry nodes for rendering. | - | ||||||
691 | - | |||||||
692 | \value CustomCompileStep Starting with Qt 5.2, the scene graph will not always call | - | ||||||
693 | QSGMaterialShader::compile() when its shader program is compiled and linked. | - | ||||||
694 | Set this flag to enforce that the function is called. | - | ||||||
695 | - | |||||||
696 | */ | - | ||||||
697 | - | |||||||
698 | /*! | - | ||||||
699 | \fn QSGMaterial::Flags QSGMaterial::flags() const | - | ||||||
700 | - | |||||||
701 | Returns the material's flags. | - | ||||||
702 | */ | - | ||||||
703 | - | |||||||
704 | - | |||||||
705 | - | |||||||
706 | /*! | - | ||||||
707 | Sets the flags \a flags on this material if \a on is true; | - | ||||||
708 | otherwise clears the attribute. | - | ||||||
709 | */ | - | ||||||
710 | - | |||||||
711 | void QSGMaterial::setFlag(Flags flags, bool on) | - | ||||||
712 | { | - | ||||||
713 | if (on)
| 269307-487220 | ||||||
714 | m_flags |= flags; executed 487220 times by 70 tests: m_flags |= flags; Executed by:
| 487220 | ||||||
715 | else | - | ||||||
716 | m_flags &= ~flags; executed 269307 times by 69 tests: m_flags &= ~flags; Executed by:
| 269307 | ||||||
717 | } | - | ||||||
718 | - | |||||||
719 | - | |||||||
720 | - | |||||||
721 | /*! | - | ||||||
722 | Compares this material to \a other and returns 0 if they are equal; -1 if | - | ||||||
723 | this material should sort before \a other and 1 if \a other should sort | - | ||||||
724 | before. | - | ||||||
725 | - | |||||||
726 | The scene graph can reorder geometry nodes to minimize state changes. | - | ||||||
727 | The compare function is called during the sorting process so that | - | ||||||
728 | the materials can be sorted to minimize state changes in each | - | ||||||
729 | call to QSGMaterialShader::updateState(). | - | ||||||
730 | - | |||||||
731 | The this pointer and \a other is guaranteed to have the same type(). | - | ||||||
732 | */ | - | ||||||
733 | - | |||||||
734 | int QSGMaterial::compare(const QSGMaterial *other) const | - | ||||||
735 | { | - | ||||||
736 | Q_ASSERT(other && type() == other->type()); | - | ||||||
737 | return qint64(this) - qint64(other); executed 2025 times by 5 tests: return qint64(this) - qint64(other); Executed by:
| 2025 | ||||||
738 | } | - | ||||||
739 | - | |||||||
740 | - | |||||||
741 | - | |||||||
742 | /*! | - | ||||||
743 | \fn QSGMaterialType QSGMaterial::type() const | - | ||||||
744 | - | |||||||
745 | This function is called by the scene graph to return a unique instance | - | ||||||
746 | per subclass. | - | ||||||
747 | */ | - | ||||||
748 | - | |||||||
749 | - | |||||||
750 | - | |||||||
751 | /*! | - | ||||||
752 | \fn QSGMaterialShader *QSGMaterial::createShader() const | - | ||||||
753 | - | |||||||
754 | This function returns a new instance of a the QSGMaterialShader | - | ||||||
755 | implementatation used to render geometry for a specific implementation | - | ||||||
756 | of QSGMaterial. | - | ||||||
757 | - | |||||||
758 | The function will be called only once for each material type that | - | ||||||
759 | exists in the scene graph and will be cached internally. | - | ||||||
760 | */ | - | ||||||
761 | - | |||||||
762 | - | |||||||
763 | QT_END_NAMESPACE | - | ||||||
Source code | Switch to Preprocessed file |