| 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 blockExecuted 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 blockExecuted 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 blockExecuted 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 blockExecuted 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 blockExecuted 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 blockExecuted 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 blockExecuted 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 |