Documentation and API cleanup of QSGMaterial
authorGunnar Sletta <gunnar.sletta@nokia.com>
Wed, 11 May 2011 10:56:51 +0000 (12:56 +0200)
committerGunnar Sletta <gunnar.sletta@nokia.com>
Wed, 11 May 2011 11:16:01 +0000 (13:16 +0200)
14 files changed:
src/declarative/items/qsgshadereffectnode.cpp
src/declarative/scenegraph/coreapi/qsgdefaultrenderer.cpp
src/declarative/scenegraph/coreapi/qsgmaterial.cpp
src/declarative/scenegraph/coreapi/qsgmaterial.h
src/declarative/scenegraph/qsgcontext.cpp
src/declarative/scenegraph/qsgdefaultglyphnode_p.cpp
src/declarative/scenegraph/qsgdistancefieldglyphnode_p.cpp
src/declarative/scenegraph/util/qsgflatcolormaterial.cpp
src/declarative/scenegraph/util/qsgtexturematerial.cpp
src/declarative/scenegraph/util/qsgvertexcolormaterial.cpp
src/imports/particles/coloredparticle.cpp
src/imports/particles/deformableparticle.cpp
src/imports/particles/spriteimage.cpp
src/imports/particles/spriteparticle.cpp

index d1c8fbc..74cd995 100644 (file)
@@ -95,7 +95,7 @@ void QSGCustomMaterialShader::updateState(const RenderState &state, QSGMaterial
 
     if (!m_textureIndicesSet) {
         for (int i = 0; i < material->m_textures.size(); ++i)
-            m_program.setUniformValue(material->m_textures.at(i).first.constData(), i);
+            program()->setUniformValue(material->m_textures.at(i).first.constData(), i);
         m_textureIndicesSet = true;
     }
 
@@ -103,7 +103,7 @@ void QSGCustomMaterialShader::updateState(const RenderState &state, QSGMaterial
         m_uniformLocs.reserve(material->m_uniformValues.size());
         for (int i = 0; i < material->m_uniformValues.size(); ++i) {
             const QByteArray &name = material->m_uniformValues.at(i).first;
-            m_uniformLocs.append(m_program.uniformLocation(name.constData()));
+            m_uniformLocs.append(program()->uniformLocation(name.constData()));
         }
     }
 
@@ -121,44 +121,44 @@ void QSGCustomMaterialShader::updateState(const RenderState &state, QSGMaterial
     }
 
     if (material->m_source.respectsOpacity)
-        m_program.setUniformValue(m_opacityLoc, state.opacity());
+        program()->setUniformValue(m_opacityLoc, state.opacity());
 
     for (int i = 0; i < material->m_uniformValues.count(); ++i) {
         const QVariant &v = material->m_uniformValues.at(i).second;
 
         switch (v.type()) {
         case QVariant::Color:
-            m_program.setUniformValue(m_uniformLocs.at(i), qt_premultiply_color(qvariant_cast<QColor>(v)));
+            program()->setUniformValue(m_uniformLocs.at(i), qt_premultiply_color(qvariant_cast<QColor>(v)));
             break;
         case QVariant::Double:
-            m_program.setUniformValue(m_uniformLocs.at(i), (float) qvariant_cast<double>(v));
+            program()->setUniformValue(m_uniformLocs.at(i), (float) qvariant_cast<double>(v));
             break;
         case QVariant::Transform:
-            m_program.setUniformValue(m_uniformLocs.at(i), qvariant_cast<QTransform>(v));
+            program()->setUniformValue(m_uniformLocs.at(i), qvariant_cast<QTransform>(v));
             break;
         case QVariant::Int:
-            m_program.setUniformValue(m_uniformLocs.at(i), v.toInt());
+            program()->setUniformValue(m_uniformLocs.at(i), v.toInt());
             break;
         case QVariant::Bool:
-            m_program.setUniformValue(m_uniformLocs.at(i), GLint(v.toBool()));
+            program()->setUniformValue(m_uniformLocs.at(i), GLint(v.toBool()));
             break;
         case QVariant::Size:
         case QVariant::SizeF:
-            m_program.setUniformValue(m_uniformLocs.at(i), v.toSizeF());
+            program()->setUniformValue(m_uniformLocs.at(i), v.toSizeF());
             break;
         case QVariant::Point:
         case QVariant::PointF:
-            m_program.setUniformValue(m_uniformLocs.at(i), v.toPointF());
+            program()->setUniformValue(m_uniformLocs.at(i), v.toPointF());
             break;
         case QVariant::Rect:
         case QVariant::RectF:
             {
                 QRectF r = v.toRectF();
-                m_program.setUniformValue(m_uniformLocs.at(i), r.x(), r.y(), r.width(), r.height());
+                program()->setUniformValue(m_uniformLocs.at(i), r.x(), r.y(), r.width(), r.height());
             }
             break;
         case QVariant::Vector3D:
-            m_program.setUniformValue(m_uniformLocs.at(i), qvariant_cast<QVector3D>(v));
+            program()->setUniformValue(m_uniformLocs.at(i), qvariant_cast<QVector3D>(v));
             break;
         default:
             break;
@@ -183,7 +183,7 @@ void QSGCustomMaterialShader::updateState(const RenderState &state, QSGMaterial
     }
 
     if ((state.isMatrixDirty()) && material->m_source.respectsMatrix)
-        m_program.setUniformValue(m_matrixLoc, state.combinedMatrix());
+        program()->setUniformValue(m_matrixLoc, state.combinedMatrix());
 }
 
 char const *const *QSGCustomMaterialShader::attributeNames() const
@@ -193,8 +193,8 @@ char const *const *QSGCustomMaterialShader::attributeNames() const
 
 void QSGCustomMaterialShader::initialize()
 {
-    m_opacityLoc = m_program.uniformLocation("qt_Opacity");
-    m_matrixLoc = m_program.uniformLocation("qt_ModelViewProjectionMatrix");
+    m_opacityLoc = program()->uniformLocation("qt_Opacity");
+    m_matrixLoc = program()->uniformLocation("qt_ModelViewProjectionMatrix");
 }
 
 const char *QSGCustomMaterialShader::vertexShader() const
index badaa2c..5680843 100644 (file)
@@ -468,6 +468,7 @@ void QMLRenderer::renderNodes(const QVector<QSGGeometryNode *> &list)
 
         QSGMaterial *material = geomNode->activeMaterial();
         QSGMaterialShader *program = m_context->prepareMaterial(material);
+        Q_ASSERT(program->program()->isLinked());
 
         bool changeClip = geomNode->clipList() != m_currentClip;
         QSGRenderer::ClipType clipType = QSGRenderer::NoClip;
index 4c42744..afec4a5 100644 (file)
 
 QT_BEGIN_NAMESPACE
 
+
+/*!
+    \class QSGMaterialShader
+    \brief The QSGMaterialShader class implements a material renders geometry.
+
+    The QSGMaterial and QSGMaterialShader form a tight relationship. For one
+    scene graph (including nested graphs), there is one unique QSGMaterialShader
+    instance which encapsulates the QGLShaderProgram the scene graph uses
+    to render that material, such as a shader to flat coloring of geometry.
+    Each QSGGeometryNode can have a unique QSGMaterial containing the
+    how the shader should be configured when drawing that node, such as
+    the actual color to used to render the geometry.
+
+    An instance of QSGMaterialShader is never created explicitely by the user,
+    it will be created on demand by the scene graph through
+    QSGMaterial::createShader(). The scene graph will make sure that there
+    is only one instance of each shader implementation through a scene graph.
+
+    The source code returned from vertexShader() is used to control what the
+    material does with the vertiex data that comes in from the geometry.
+    The source code returned from the fragmentShader() is used to control
+    what how the material should fill each individual pixel in the geometry.
+    The vertex and fragment source code is queried once during initialization,
+    changing what is returned from these functions later will not have
+    any effect.
+
+    The activate() function is called by the scene graph when a shader is
+    is starting to be used. The deactivate function is called by the scene
+    graph when the shader is no longer going to be used. While active,
+    the scene graph may make one or more calls to updateState() which
+    will update the state of the shader for each individual geometry to
+    render.
+
+    The attributeNames() returns the name of the attributes used in the
+    vertexShader(). These are used in the default implementation of
+    activate() and deactive() to decide whice vertex registers are enabled.
+
+    The initialize() function is called during program creation to allow
+    subclasses to prepare for use, such as resolve uniform names in the
+    vertexShader() and fragmentShader().
+
+    A minimal example:
+    \code
+        class Shader : public QSGMaterialShader
+        {
+        public:
+            const char *vertexShader() const {
+                return
+                "attribute highp vec4 vertex;          \n"
+                "uniform highp mat4 matrix;            \n"
+                "void main() {                         \n"
+                "    gl_Position = matrix * vertex;    \n"
+                "}";
+            }
+
+            const char *fragmentShader() const {
+                return
+                "uniform lowp float opacity;                            \n"
+                "void main() {                                          \n"
+                        "    gl_FragColor = vec4(1, 0, 0, 1) * opacity; \n"
+                "}";
+            }
+
+            char const *const *attributeNames() const
+            {
+                static char const *const names[] = { "vertex", 0 };
+                return names;
+            }
+
+            void initialize()
+            {
+                QSGMaterialShader::initialize();
+                m_id_matrix = program()->uniformLocation("matrix");
+                m_id_opacity = program()->uniformLocation("opacity");
+            }
+
+            void updateState(const RenderState &state, QSGMaterial *newMaterial, QSGMaterial *oldMaterial)
+            {
+                Q_ASSERT(program()->isLinked());
+                if (state.isMatrixDirty())
+                    program()->setUniformValue(m_id_matrix, state.combinedMatrix());
+                if (state.isOpacityDirty())
+                    program()->setUniformValue(m_id_opacity, state.opacity());
+            }
+
+        private:
+            int m_id_matrix;
+            int m_id_opacity;
+        };
+    \endcode
+
+    \warning Instances of QSGMaterialShader belongs to the Scene Graph rendering
+    thread, and cannot be used from the GUI thread.
+
+ */
+
+
+
+/*!
+    Creates a new QSGMaterialShader.
+ */
 QSGMaterialShader::QSGMaterialShader()
-    : m_compiled(false)
 {
 }
 
+
+
+/*!
+    \fn QGLShaderProgram *QSGMaterialShader::program() const
+
+    Returns the shader program used by this QSGMaterialShader.
+ */
+
+
+
+/*!
+    This function is called by the scene graph to indicate that geometry is
+    about to be rendered using this shader.
+
+    State that is global for all uses of the shader, independent of the geometry
+    that is being drawn, can be setup in this function.
+
+    If reimplemented, make sure to either call the base class implementation to
+    enable the vertex attribute registers.
+ */
+
 void QSGMaterialShader::activate()
 {
-    if (!m_compiled)
-        compile();
+    Q_ASSERT(program()->isLinked());
 
-    m_program.bind();
+    program()->bind();
     char const *const *attr = attributeNames();
     for (int i = 0; attr[i]; ++i) {
         if (*attr[i])
-            m_program.enableAttributeArray(i);
+            program()->enableAttributeArray(i);
     }
 }
 
+
+
+/*!
+    This function is called by the scene graph to indicate that geometry will
+    no longer to be rendered using this shader.
+
+    If reimplemented, make sure to either call the base class implementation to
+    disable the vertex attribute registers.
+ */
+
 void QSGMaterialShader::deactivate()
 {
     char const *const *attr = attributeNames();
     for (int i = 0; attr[i]; ++i) {
         if (*attr[i])
-            m_program.disableAttributeArray(i);
+            program()->disableAttributeArray(i);
     }
 }
 
-void QSGMaterialShader::updateState(const RenderState &, QSGMaterial *, QSGMaterial *)
+
+
+/*!
+    This function is called by the scene graph before geometry is rendered
+    to make sure the shader is in the right state.
+
+    The current rendering \a state is passed from the scene graph. If the state
+    indicates that any state is dirty, the updateState implementation must
+    update accordingly for the geometry to render correctly.
+
+    The subclass specific state, such as the color of a flat color material, should
+    be extracted from \a newMaterial to update the color uniforms accordingly.
+
+    The \a oldMaterial can be used to minimze state changes when updating
+    material states. The \a oldMaterial is 0 if this shader was just activated.
+
+    \sa activate(), deactivate()
+ */
+
+void QSGMaterialShader::updateState(const RenderState &state, QSGMaterial *newMaterial, QSGMaterial *oldMaterial)
 {
 }
 
+
+
+/*!
+    This function is called when the shader is initialized to compile the
+    actual QGLShaderProgram. Do not call it explicitely.
+
+    The default implementation will extract the vertexShader() and
+    fragmentShader() and bind the names returned from attributeNames()
+    to consecutive vertex attribute registers starting at 0.
+ */
+
 void QSGMaterialShader::compile()
 {
-    Q_ASSERT(!m_compiled);
+    Q_ASSERT_X(!m_program.isLinked(), "QSGSMaterialShader::compile()", "Compile called multiple times!");
 
-    m_program.addShaderFromSourceCode(QGLShader::Vertex, vertexShader());
-    m_program.addShaderFromSourceCode(QGLShader::Fragment, fragmentShader());
+    program()->addShaderFromSourceCode(QGLShader::Vertex, vertexShader());
+    program()->addShaderFromSourceCode(QGLShader::Fragment, fragmentShader());
 
     char const *const *attr = attributeNames();
 #ifndef QT_NO_DEBUG
@@ -95,55 +255,139 @@ void QSGMaterialShader::compile()
                    maxVertexAttribs, vertexShader(), fragmentShader());
         }
         if (*attr[i])
-            m_program.bindAttributeLocation(attr[i], i);
+            program()->bindAttributeLocation(attr[i], i);
     }
 #else
     for (int i = 0; attr[i]; ++i) {
         if (*attr[i])
-            m_program.bindAttributeLocation(attr[i], i);
+            program()->bindAttributeLocation(attr[i], i);
     }
 #endif
 
-    if (!m_program.link()) {
+    if (!program()->link()) {
         qWarning("QSGMaterialShader: Shader compilation failed:");
-        qWarning() << m_program.log();
+        qWarning() << program()->log();
     }
-
-    m_compiled = true;
-    initialize();
 }
 
 
+
+/*!
+    \class QSGMaterialShader::RenderState
+    \brief The QSGMaterialShader::RenderState encapsulates the current rendering state
+    during a call to QSGMaterialShader::updateState().
+
+    The render state contains a number of accessors that the shader needs to respect
+    in order to conform to the current state of the scene graph.
+
+    The instance is only valid inside a call to QSGMaterialShader::updateState() and
+    should not be used outisde this function.
+ */
+
+
+
+/*!
+    \enum QSGMaterialShader::RenderState::DirtyState
+
+    \value DirtyMatrix Used to indicate that the matrix has changed and must be updated.
+
+    \value DirtyOpacity Used to indicate that the opacity has changed and must be updated.
+ */
+
+
+
+/*!
+    \fn bool QSGMaterialShader::RenderState::isMatrixDirty() const
+
+    Convenience function to check if the dirtyStates() indicates that the matrix
+    needs to be updated.
+ */
+
+
+
+/*!
+    \fn bool QSGMaterialShader::RenderState::isOpacityDirty() const
+
+    Conveience function to check if the dirtyStates() indicates that the opacity
+    needs to be updated.
+ */
+
+
+
+/*!
+    \fn QSGMaterialShader::RenderState::DirtyStates QSGMaterialShader::RenderState::dirtyStates() const
+
+    Returns which rendering states that have changed and needs to be updated
+    for geometry rendered with this material to conform to the current
+    rendering state.
+ */
+
+
+
+/*!
+    Returns the accumulated opacity to be used for rendering
+ */
+
 float QSGMaterialShader::RenderState::opacity() const
 {
     Q_ASSERT(m_data);
     return static_cast<const QSGRenderer *>(m_data)->renderOpacity();
 }
 
+
+
+/*!
+    Returns the matrix combined of modelview matrix and project matrix.
+ */
+
 QMatrix4x4 QSGMaterialShader::RenderState::combinedMatrix() const
 {
     Q_ASSERT(m_data);
     return static_cast<const QSGRenderer *>(m_data)->combinedMatrix();
 }
 
+
+
+/*!
+    Returns the model view matrix.
+ */
+
 QMatrix4x4 QSGMaterialShader::RenderState::modelViewMatrix() const
 {
     Q_ASSERT(m_data);
     return const_cast<QSGRenderer *>(static_cast<const QSGRenderer *>(m_data))->modelViewMatrix().top();
 }
 
+
+
+/*!
+    Returns the viewport rect of the surface being rendered to.
+ */
+
 QRect QSGMaterialShader::RenderState::viewportRect() const
 {
     Q_ASSERT(m_data);
     return static_cast<const QSGRenderer *>(m_data)->viewportRect();
 }
 
+
+
+/*!
+    Returns the device rect of the surface being rendered to
+ */
+
 QRect QSGMaterialShader::RenderState::deviceRect() const
 {
     Q_ASSERT(m_data);
     return static_cast<const QSGRenderer *>(m_data)->deviceRect();
 }
 
+
+
+/*!
+    Returns the QGLContext that is being used for rendering
+ */
+
 const QGLContext *QSGMaterialShader::RenderState::context() const
 {
     return static_cast<const QSGRenderer *>(m_data)->glContext();
@@ -160,6 +404,44 @@ static void qt_print_material_count()
 }
 #endif
 
+/*!
+    \class QSGMaterialType
+    \brief The QSGMaterialType class is used as a unique type token in combination with QSGMaterial.
+
+    It serves no purpose outside the QSGMaterial::type() function.
+ */
+
+/*!
+    \class QSGMaterial
+    \brief The QSGMaterial class encapsulates rendering state for a shader program.
+
+    The QSGMaterial and QSGMaterialShader subclasses form a tight relationship. For
+    one scene graph (including nested graphs), there is one unique QSGMaterialShader
+    instance which encapsulates the QGLShaderProgram the scene graph uses
+    to render that material, such as a shader to flat coloring of geometry.
+    Each QSGGeometryNode can have a unique QSGMaterial containing the
+    how the shader should be configured when drawing that node, such as
+    the actual color to used to render the geometry.
+
+    The QSGMaterial has two virtual functions that both need to be implemented.
+    The function type() should return a unique instance for all instances of a
+    specific subclass. The createShader() function should return a new instance
+    of QSGMaterialShader, specific to the subclass of QSGMaterial.
+
+    A minimal QSGMaterial implementation could look like this:
+    \code
+        class Material : public QSGMaterial
+        {
+        public:
+            QSGMaterialType *type() const { static QSGMaterialType type; return &type; }
+            QSGMaterialShader *createShader() const { return new Shader; }
+        };
+    \endcode
+
+    \warning Instances of QSGMaterial belongs to the Scene Graph rendering thread,
+    and cannot be used from the GUI thread.
+ */
+
 QSGMaterial::QSGMaterial()
     : m_flags(0)
 {
@@ -182,18 +464,72 @@ QSGMaterial::~QSGMaterial()
 #endif
 }
 
-void QSGMaterial::setFlag(Flags flags, bool set)
+
+
+/*!
+    \enum QSGMaterial::Flag
+
+    \value Blending Set this flag to true if the material requires GL_BLEND to be
+    enabled during rendering.
+ */
+
+
+
+/*!
+    Sets the flags \a flags on this material if \a on is true;
+    otherwise clears the attribute.
+*/
+
+void QSGMaterial::setFlag(Flags flags, bool on)
 {
-    if (set)
+    if (on)
         m_flags |= flags;
     else
         m_flags &= ~flags;
 }
 
+
+
+/*!
+    Compares this material to \a other and returns 0 if they are equal; -1 if
+    this material should sort before \a other and 1 if \a other should sort
+    before.
+
+    The scene graph can reorder geometry nodes to minimize state changes.
+    The compare function is called during the sorting process so that
+    the materials can be sorted to minimize state changes in each
+    call to QSGMaterialShader::updateState().
+
+    The this pointer and \a other is guaranteed to have the same type().
+ */
+
 int QSGMaterial::compare(const QSGMaterial *other) const
 {
     Q_ASSERT(other && type() == other->type());
     return qint64(this) - qint64(other);
 }
 
+
+
+/*!
+    \fn QSGMaterialType QSGMaterial::type() const
+
+    This function is called by the scene graph to return a unique instance
+    per subclass.
+ */
+
+
+
+/*!
+    \fn QSGMaterialShader *QSGMaterial::createShader() const
+
+    This function returns a new instance of a the QSGMaterialShader
+    implementatation used to render geometry for a specifc implementation
+    of QSGMaterial.
+
+    The function will be called only once for each material type that
+    exists in the scene graph and will be cached internally.
+*/
+
+
 QT_END_NAMESPACE
index c151395..66e37c5 100644 (file)
@@ -64,7 +64,7 @@ public:
         };
         Q_DECLARE_FLAGS(DirtyStates, DirtyState)
 
-        inline DirtyStates dirtyState() const { return m_dirty; }
+        inline DirtyStates dirtyStates() const { return m_dirty; }
 
         inline bool isMatrixDirty() const { return m_dirty & DirtyMatrix; }
         inline bool isOpacityDirty() const { return m_dirty & DirtyOpacity; }
@@ -91,15 +91,20 @@ public:
     virtual void updateState(const RenderState &state, QSGMaterial *newMaterial, QSGMaterial *oldMaterial);
     virtual char const *const *attributeNames() const = 0; // Array must end with null.
 
+    inline QGLShaderProgram *program() { return &m_program; }
+
 protected:
-    void compile();
+
+    friend class QSGContext;
+
+    virtual void compile();
     virtual void initialize() { }
 
     virtual const char *vertexShader() const = 0;
     virtual const char *fragmentShader() const = 0;
 
+private:
     QGLShaderProgram m_program;
-    bool m_compiled;
     void *m_reserved;
 };
 
@@ -121,9 +126,7 @@ public:
     virtual int compare(const QSGMaterial *other) const;
 
     QSGMaterial::Flags flags() const { return m_flags; }
-
-protected:
-    void setFlag(Flags flags, bool set);
+    void setFlag(Flags flags, bool on = true);
 
 private:
     Flags m_flags;
index d604c83..dd35c06 100644 (file)
@@ -350,12 +350,14 @@ QSGTexture *QSGContext::decodeImageToTexture(QIODevice *dev,
 }
 
 
+
 /*!
     Factory function for texture objects.
 
     If \a image is a valid image, the QSGTexture::setImage function
     will be called with \a image as argument.
  */
+
 QSGTexture *QSGContext::createTexture(const QImage &image) const
 {
     QSGPlainTexture *t = new QSGPlainTexture();
@@ -365,9 +367,11 @@ QSGTexture *QSGContext::createTexture(const QImage &image) const
 }
 
 
+
 /*!
     Returns a material shader for the given material.
  */
+
 QSGMaterialShader *QSGContext::prepareMaterial(QSGMaterial *material)
 {
     Q_D(QSGContext);
@@ -377,13 +381,19 @@ QSGMaterialShader *QSGContext::prepareMaterial(QSGMaterial *material)
         return shader;
 
     shader = material->createShader();
+    shader->compile();
+    shader->initialize();
     d->materials[type] = shader;
+
     return shader;
 }
 
+
+
 /*!
     Sets weither the scene graph should render with flashing update rectangles or not
   */
+
 void QSGContext::setFlashModeEnabled(bool enabled)
 {
     d_func()->flashMode = enabled;
index 00090be..4b51dfc 100644 (file)
@@ -105,9 +105,9 @@ QSGTextMaskMaterialData::QSGTextMaskMaterialData()
 
 void QSGTextMaskMaterialData::initialize()
 {
-    m_matrix_id = m_program.uniformLocation("matrix");
-    m_color_id = m_program.uniformLocation("color");
-    m_textureScale_id = m_program.uniformLocation("textureScale");
+    m_matrix_id = program()->uniformLocation("matrix");
+    m_color_id = program()->uniformLocation("color");
+    m_textureScale_id = program()->uniformLocation("textureScale");
 }
 
 void QSGTextMaskMaterialData::updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect)
@@ -120,7 +120,7 @@ void QSGTextMaskMaterialData::updateState(const RenderState &state, QSGMaterial
         QVector4D color(material->color().redF(), material->color().greenF(),
                         material->color().blueF(), material->color().alphaF());
         color *= state.opacity();
-        m_program.setUniformValue(m_color_id, color);
+        program()->setUniformValue(m_color_id, color);
     }
 
     bool updated = material->ensureUpToDate();
@@ -130,7 +130,7 @@ void QSGTextMaskMaterialData::updateState(const RenderState &state, QSGMaterial
     if (updated
             || oldMaterial == 0
             || oldMaterial->texture()->textureId() != material->texture()->textureId()) {
-        m_program.setUniformValue(m_textureScale_id, QVector2D(1.0 / material->cacheTextureWidth(),
+        program()->setUniformValue(m_textureScale_id, QVector2D(1.0 / material->cacheTextureWidth(),
                                                                1.0 / material->cacheTextureHeight()));
         glBindTexture(GL_TEXTURE_2D, material->texture()->textureId());
 
@@ -143,7 +143,7 @@ void QSGTextMaskMaterialData::updateState(const RenderState &state, QSGMaterial
     }
 
     if (state.isMatrixDirty())
-        m_program.setUniformValue(m_matrix_id, state.combinedMatrix());
+        program()->setUniformValue(m_matrix_id, state.combinedMatrix());
 }
 
 QSGTextMaskMaterial::QSGTextMaskMaterial(const QRawFont &font)
index c822810..a54c764 100644 (file)
@@ -115,18 +115,18 @@ void QSGDistanceFieldTextMaterialShader::updateAlphaRange()
     qreal combinedScale = m_fontScale * m_matrixScale;
     qreal alphaMin = qMax(0.0, 0.5 - 0.07 / combinedScale);
     qreal alphaMax = qMin(0.5 + 0.07 / combinedScale, 1.0);
-    m_program.setUniformValue(m_alphaMin_id, GLfloat(alphaMin));
-    m_program.setUniformValue(m_alphaMax_id, GLfloat(alphaMax));
+    program()->setUniformValue(m_alphaMin_id, GLfloat(alphaMin));
+    program()->setUniformValue(m_alphaMax_id, GLfloat(alphaMax));
 }
 
 void QSGDistanceFieldTextMaterialShader::initialize()
 {
     QSGMaterialShader::initialize();
-    m_matrix_id = m_program.uniformLocation("matrix");
-    m_textureScale_id = m_program.uniformLocation("textureScale");
-    m_color_id = m_program.uniformLocation("color");
-    m_alphaMin_id = m_program.uniformLocation("alphaMin");
-    m_alphaMax_id = m_program.uniformLocation("alphaMax");
+    m_matrix_id = program()->uniformLocation("matrix");
+    m_textureScale_id = program()->uniformLocation("textureScale");
+    m_color_id = program()->uniformLocation("color");
+    m_alphaMin_id = program()->uniformLocation("alphaMin");
+    m_alphaMax_id = program()->uniformLocation("alphaMax");
 }
 
 void QSGDistanceFieldTextMaterialShader::updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect)
@@ -145,7 +145,7 @@ void QSGDistanceFieldTextMaterialShader::updateState(const RenderState &state, Q
         QVector4D color(material->color().redF(), material->color().greenF(),
                         material->color().blueF(), material->color().alphaF());
         color *= state.opacity();
-        m_program.setUniformValue(m_color_id, color);
+        program()->setUniformValue(m_color_id, color);
     }
 
     bool updateRange = false;
@@ -155,7 +155,7 @@ void QSGDistanceFieldTextMaterialShader::updateState(const RenderState &state, Q
         updateRange = true;
     }
     if (state.isMatrixDirty()) {
-        m_program.setUniformValue(m_matrix_id, state.combinedMatrix());
+        program()->setUniformValue(m_matrix_id, state.combinedMatrix());
         m_matrixScale = qSqrt(state.modelViewMatrix().determinant());
         updateRange = true;
     }
@@ -167,7 +167,7 @@ void QSGDistanceFieldTextMaterialShader::updateState(const RenderState &state, Q
     if (updated
             || oldMaterial == 0
             || oldMaterial->glyphCache()->texture() != material->glyphCache()->texture()) {
-        m_program.setUniformValue(m_textureScale_id, QVector2D(1.0 / material->glyphCache()->textureSize().width(),
+        program()->setUniformValue(m_textureScale_id, QVector2D(1.0 / material->glyphCache()->textureSize().width(),
                                                                1.0 / material->glyphCache()->textureSize().height()));
         glBindTexture(GL_TEXTURE_2D, material->glyphCache()->texture());
 
@@ -253,7 +253,7 @@ DistanceFieldStyledTextMaterialShader::DistanceFieldStyledTextMaterialShader()
 void DistanceFieldStyledTextMaterialShader::initialize()
 {
     QSGDistanceFieldTextMaterialShader::initialize();
-    m_styleColor_id = m_program.uniformLocation("styleColor");
+    m_styleColor_id = program()->uniformLocation("styleColor");
 }
 
 void DistanceFieldStyledTextMaterialShader::updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect)
@@ -269,7 +269,7 @@ void DistanceFieldStyledTextMaterialShader::updateState(const RenderState &state
         QVector4D color(material->styleColor().redF(), material->styleColor().greenF(),
                         material->styleColor().blueF(), material->styleColor().alphaF());
         color *= state.opacity();
-        m_program.setUniformValue(m_styleColor_id, color);
+        program()->setUniformValue(m_styleColor_id, color);
     }
 }
 
@@ -337,8 +337,8 @@ DistanceFieldOutlineTextMaterialShader::DistanceFieldOutlineTextMaterialShader()
 void DistanceFieldOutlineTextMaterialShader::initialize()
 {
     DistanceFieldStyledTextMaterialShader::initialize();
-    m_outlineAlphaMax0_id = m_program.uniformLocation("outlineAlphaMax0");
-    m_outlineAlphaMax1_id = m_program.uniformLocation("outlineAlphaMax1");
+    m_outlineAlphaMax0_id = program()->uniformLocation("outlineAlphaMax0");
+    m_outlineAlphaMax1_id = program()->uniformLocation("outlineAlphaMax1");
 }
 
 void DistanceFieldOutlineTextMaterialShader::updateOutlineAlphaRange(int dfRadius)
@@ -349,8 +349,8 @@ void DistanceFieldOutlineTextMaterialShader::updateOutlineAlphaRange(int dfRadiu
     qreal alphaMin = qMax(0.0, 0.5 - 0.07 / combinedScale);
     qreal styleAlphaMin0 = qMax(0.0, outlineLimit - 0.07 / combinedScale);
     qreal styleAlphaMin1 = qMin(qreal(outlineLimit + 0.07 / combinedScale), alphaMin);
-    m_program.setUniformValue(m_outlineAlphaMax0_id, GLfloat(styleAlphaMin0));
-    m_program.setUniformValue(m_outlineAlphaMax1_id, GLfloat(styleAlphaMin1));
+    program()->setUniformValue(m_outlineAlphaMax0_id, GLfloat(styleAlphaMin0));
+    program()->setUniformValue(m_outlineAlphaMax1_id, GLfloat(styleAlphaMin1));
 }
 
 void DistanceFieldOutlineTextMaterialShader::updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect)
@@ -413,7 +413,7 @@ DistanceFieldShiftedStyleTextMaterialShader::DistanceFieldShiftedStyleTextMateri
 void DistanceFieldShiftedStyleTextMaterialShader::initialize()
 {
     DistanceFieldStyledTextMaterialShader::initialize();
-    m_shift_id = m_program.uniformLocation("shift");
+    m_shift_id = program()->uniformLocation("shift");
 }
 
 void DistanceFieldShiftedStyleTextMaterialShader::updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect)
@@ -435,7 +435,7 @@ void DistanceFieldShiftedStyleTextMaterialShader::updateShift(const QSGDistanceF
 {
     QPointF texel(1.0 / cache->fontScale() * shift.x(),
                   1.0 / cache->fontScale() * shift.y());
-    m_program.setUniformValue(m_shift_id, texel);
+    program()->setUniformValue(m_shift_id, texel);
 }
 
 const char *DistanceFieldShiftedStyleTextMaterialShader::vertexShader() const
@@ -604,8 +604,8 @@ const char *QSGSubPixelDistanceFieldTextMaterialShader::fragmentShader() const {
 void QSGSubPixelDistanceFieldTextMaterialShader::initialize()
 {
     QSGDistanceFieldTextMaterialShader::initialize();
-    m_fontScale_id = m_program.uniformLocation("fontScale");
-    m_vecDelta_id = m_program.uniformLocation("vecDelta");
+    m_fontScale_id = program()->uniformLocation("fontScale");
+    m_vecDelta_id = program()->uniformLocation("vecDelta");
 }
 
 void QSGSubPixelDistanceFieldTextMaterialShader::activate()
@@ -625,8 +625,8 @@ void QSGSubPixelDistanceFieldTextMaterialShader::updateAlphaRange()
     qreal combinedScale = m_fontScale * m_matrixScale;
     qreal alphaMin = qMax(0.0, 0.5 - 0.05 / combinedScale);
     qreal alphaMax = qMin(0.5 + 0.05 / combinedScale, 1.0);
-    m_program.setUniformValue(m_alphaMin_id, GLfloat(alphaMin));
-    m_program.setUniformValue(m_alphaMax_id, GLfloat(alphaMax));
+    program()->setUniformValue(m_alphaMin_id, GLfloat(alphaMin));
+    program()->setUniformValue(m_alphaMax_id, GLfloat(alphaMax));
 }
 
 void QSGSubPixelDistanceFieldTextMaterialShader::updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect)
@@ -641,12 +641,12 @@ void QSGSubPixelDistanceFieldTextMaterialShader::updateState(const RenderState &
     }
 
     if (oldMaterial == 0 || material->glyphCache()->fontScale() != oldMaterial->glyphCache()->fontScale())
-        m_program.setUniformValue(m_fontScale_id, GLfloat(material->glyphCache()->fontScale()));
+        program()->setUniformValue(m_fontScale_id, GLfloat(material->glyphCache()->fontScale()));
 
     if (oldMaterial == 0 || state.isMatrixDirty()) {
         int viewportWidth = state.viewportRect().width();
         QMatrix4x4 mat = state.combinedMatrix().inverted();
-        m_program.setUniformValue(m_vecDelta_id, mat.column(0) * (qreal(2) / viewportWidth));
+        program()->setUniformValue(m_vecDelta_id, mat.column(0) * (qreal(2) / viewportWidth));
     }
 
     QSGDistanceFieldTextMaterialShader::updateState(state, newEffect, oldEffect);
index ed3d96f..74ff8ac 100644 (file)
@@ -79,11 +79,11 @@ void FlatColorMaterialShader::updateState(const RenderState &state, QSGMaterial
                     c.greenF() * c.alphaF() * opacity,
                     c.blueF() * c.alphaF() * opacity,
                     c.alphaF() * opacity);
-        m_program.setUniformValue(m_color_id, v);
+        program()->setUniformValue(m_color_id, v);
     }
 
     if (state.isMatrixDirty())
-        m_program.setUniformValue(m_matrix_id, state.combinedMatrix());
+        program()->setUniformValue(m_matrix_id, state.combinedMatrix());
 }
 
 char const *const *FlatColorMaterialShader::attributeNames() const
@@ -94,8 +94,8 @@ char const *const *FlatColorMaterialShader::attributeNames() const
 
 void FlatColorMaterialShader::initialize()
 {
-    m_matrix_id = m_program.uniformLocation("matrix");
-    m_color_id = m_program.uniformLocation("color");
+    m_matrix_id = program()->uniformLocation("matrix");
+    m_color_id = program()->uniformLocation("color");
 }
 
 const char *FlatColorMaterialShader::vertexShader() const {
index 38b9107..1e14172 100644 (file)
@@ -83,7 +83,7 @@ char const *const *QSGOpaqueTextureMaterialShader::attributeNames() const
 
 void QSGOpaqueTextureMaterialShader::initialize()
 {
-    m_matrix_id = m_program.uniformLocation("qt_Matrix");
+    m_matrix_id = program()->uniformLocation("qt_Matrix");
 }
 
 void QSGOpaqueTextureMaterialShader::updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect)
@@ -105,7 +105,7 @@ void QSGOpaqueTextureMaterialShader::updateState(const RenderState &state, QSGMa
         t->updateBindOptions();
 
     if (state.isMatrixDirty())
-        m_program.setUniformValue(m_matrix_id, state.combinedMatrix());
+        program()->setUniformValue(m_matrix_id, state.combinedMatrix());
 }
 
 
@@ -378,7 +378,7 @@ void QSGTextureMaterialShader::updateState(const RenderState &state, QSGMaterial
 {
     Q_ASSERT(oldEffect == 0 || newEffect->type() == oldEffect->type());
     if (state.isOpacityDirty())
-        m_program.setUniformValue(m_opacity_id, state.opacity());
+        program()->setUniformValue(m_opacity_id, state.opacity());
 
     QSGOpaqueTextureMaterialShader::updateState(state, newEffect, oldEffect);
 }
@@ -386,7 +386,7 @@ void QSGTextureMaterialShader::updateState(const RenderState &state, QSGMaterial
 void QSGTextureMaterialShader::initialize()
 {
     QSGOpaqueTextureMaterialShader::initialize();
-    m_opacity_id = m_program.uniformLocation("opacity");
+    m_opacity_id = program()->uniformLocation("opacity");
 }
 
 QT_END_NAMESPACE
index dee64ba..033de1f 100644 (file)
@@ -67,10 +67,10 @@ QSGMaterialType QSGVertexColorMaterialShader::type;
 void QSGVertexColorMaterialShader::updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *)
 {
     if (!(newEffect->flags() & QSGMaterial::Blending) || state.isOpacityDirty())
-        m_program.setUniformValue(m_opacity_id, state.opacity());
+        program()->setUniformValue(m_opacity_id, state.opacity());
 
     if (state.isMatrixDirty())
-        m_program.setUniformValue(m_matrix_id, state.combinedMatrix());
+        program()->setUniformValue(m_matrix_id, state.combinedMatrix());
 }
 
 char const *const *QSGVertexColorMaterialShader::attributeNames() const
@@ -81,8 +81,8 @@ char const *const *QSGVertexColorMaterialShader::attributeNames() const
 
 void QSGVertexColorMaterialShader::initialize()
 {
-    m_matrix_id = m_program.uniformLocation("matrix");
-    m_opacity_id = m_program.uniformLocation("opacity");
+    m_matrix_id = program()->uniformLocation("matrix");
+    m_opacity_id = program()->uniformLocation("opacity");
 }
 
 const char *QSGVertexColorMaterialShader::vertexShader() const {
index 449c6b2..22ef2d2 100644 (file)
@@ -100,7 +100,7 @@ public:
         QSGMaterialShader::deactivate();
 
         for (int i=0; i<8; ++i) {
-            m_program.setAttributeArray(i, GL_FLOAT, chunkOfBytes, 1, 0);
+            program()->setAttributeArray(i, GL_FLOAT, chunkOfBytes, 1, 0);
         }
     }
 
@@ -110,17 +110,17 @@ public:
         state.context()->functions()->glActiveTexture(GL_TEXTURE0);
         m->texture->bind();
 
-        m_program.setUniformValue(m_opacity_id, state.opacity());
-        m_program.setUniformValue(m_timestamp_id, (float) m->timestamp);
+        program()->setUniformValue(m_opacity_id, state.opacity());
+        program()->setUniformValue(m_timestamp_id, (float) m->timestamp);
 
         if (state.isMatrixDirty())
-            m_program.setUniformValue(m_matrix_id, state.combinedMatrix());
+            program()->setUniformValue(m_matrix_id, state.combinedMatrix());
     }
 
     virtual void initialize() {
-        m_matrix_id = m_program.uniformLocation("matrix");
-        m_opacity_id = m_program.uniformLocation("opacity");
-        m_timestamp_id = m_program.uniformLocation("timestamp");
+        m_matrix_id = program()->uniformLocation("matrix");
+        m_opacity_id = program()->uniformLocation("opacity");
+        m_timestamp_id = program()->uniformLocation("timestamp");
     }
 
     virtual const char *vertexShader() const { return m_vertex_code.constData(); }
@@ -193,9 +193,9 @@ public:
 
     virtual void initialize() {
         ParticleTrailsMaterialData::initialize();
-        m_colortable_id = m_program.uniformLocation("colortable");
-        m_sizetable_id = m_program.uniformLocation("sizetable");
-        m_opacitytable_id = m_program.uniformLocation("opacitytable");
+        m_colortable_id = program()->uniformLocation("colortable");
+        m_sizetable_id = program()->uniformLocation("sizetable");
+        m_opacitytable_id = program()->uniformLocation("opacitytable");
     }
 
     virtual void updateState(const RenderState &state, QSGMaterial *current, QSGMaterial *old)
@@ -205,15 +205,15 @@ public:
         ParticleTrailsMaterialCT *m = static_cast<ParticleTrailsMaterialCT *>(current);
         state.context()->functions()->glActiveTexture(GL_TEXTURE1);
         m->colortable->bind();
-        m_program.setUniformValue(m_colortable_id, 1);
+        program()->setUniformValue(m_colortable_id, 1);
 
         state.context()->functions()->glActiveTexture(GL_TEXTURE2);
         m->sizetable->bind();
-        m_program.setUniformValue(m_sizetable_id, 2);
+        program()->setUniformValue(m_sizetable_id, 2);
 
         state.context()->functions()->glActiveTexture(GL_TEXTURE3);
         m->opacitytable->bind();
-        m_program.setUniformValue(m_opacitytable_id, 3);
+        program()->setUniformValue(m_opacitytable_id, 3);
 
         ParticleTrailsMaterialData::updateState(state, current, old);
     }
index 176ef2b..768e4eb 100644 (file)
@@ -100,7 +100,7 @@ public:
         QSGMaterialShader::deactivate();
 
         for (int i=0; i<8; ++i) {
-            m_program.setAttributeArray(i, GL_FLOAT, chunkOfBytes, 1, 0);
+            program()->setAttributeArray(i, GL_FLOAT, chunkOfBytes, 1, 0);
         }
     }
 
@@ -110,17 +110,17 @@ public:
         state.context()->functions()->glActiveTexture(GL_TEXTURE0);
         m->texture->bind();
 
-        m_program.setUniformValue(m_opacity_id, state.opacity());
-        m_program.setUniformValue(m_timestamp_id, (float) m->timestamp);
+        program()->setUniformValue(m_opacity_id, state.opacity());
+        program()->setUniformValue(m_timestamp_id, (float) m->timestamp);
 
         if (state.isMatrixDirty())
-            m_program.setUniformValue(m_matrix_id, state.combinedMatrix());
+            program()->setUniformValue(m_matrix_id, state.combinedMatrix());
     }
 
     virtual void initialize() {
-        m_matrix_id = m_program.uniformLocation("matrix");
-        m_opacity_id = m_program.uniformLocation("opacity");
-        m_timestamp_id = m_program.uniformLocation("timestamp");
+        m_matrix_id = program()->uniformLocation("matrix");
+        m_opacity_id = program()->uniformLocation("opacity");
+        m_timestamp_id = program()->uniformLocation("timestamp");
     }
 
     virtual const char *vertexShader() const { return m_vertex_code.constData(); }
index b0f8564..0ce3461 100644 (file)
@@ -114,7 +114,7 @@ public:
         QSGMaterialShader::deactivate();
 
         for (int i=0; i<8; ++i) {
-            m_program.setAttributeArray(i, GL_FLOAT, chunkOfBytes, 1, 0);
+            program()->setAttributeArray(i, GL_FLOAT, chunkOfBytes, 1, 0);
         }
     }
 
@@ -123,25 +123,25 @@ public:
         SpriteMaterial *m = static_cast<SpriteMaterial *>(newEffect);
         m->texture->bind();
 
-        m_program.setUniformValue(m_opacity_id, state.opacity());
-        m_program.setUniformValue(m_timestamp_id, (float) m->timestamp);
-        m_program.setUniformValue(m_framecount_id, (float) m->framecount);
-        m_program.setUniformValue(m_animcount_id, (float) m->animcount);
-        m_program.setUniformValue(m_width_id, (float) m->width);
-        m_program.setUniformValue(m_height_id, (float) m->height);
+        program()->setUniformValue(m_opacity_id, state.opacity());
+        program()->setUniformValue(m_timestamp_id, (float) m->timestamp);
+        program()->setUniformValue(m_framecount_id, (float) m->framecount);
+        program()->setUniformValue(m_animcount_id, (float) m->animcount);
+        program()->setUniformValue(m_width_id, (float) m->width);
+        program()->setUniformValue(m_height_id, (float) m->height);
 
         if (state.isMatrixDirty())
-            m_program.setUniformValue(m_matrix_id, state.combinedMatrix());
+            program()->setUniformValue(m_matrix_id, state.combinedMatrix());
     }
 
     virtual void initialize() {
-        m_matrix_id = m_program.uniformLocation("matrix");
-        m_opacity_id = m_program.uniformLocation("opacity");
-        m_timestamp_id = m_program.uniformLocation("timestamp");
-        m_framecount_id = m_program.uniformLocation("framecount");
-        m_animcount_id = m_program.uniformLocation("animcount");
-        m_width_id = m_program.uniformLocation("width");
-        m_height_id = m_program.uniformLocation("height");
+        m_matrix_id = program()->uniformLocation("matrix");
+        m_opacity_id = program()->uniformLocation("opacity");
+        m_timestamp_id = program()->uniformLocation("timestamp");
+        m_framecount_id = program()->uniformLocation("framecount");
+        m_animcount_id = program()->uniformLocation("animcount");
+        m_width_id = program()->uniformLocation("width");
+        m_height_id = program()->uniformLocation("height");
     }
 
     virtual const char *vertexShader() const { return m_vertex_code.constData(); }
index 84f2db0..1b62765 100644 (file)
@@ -109,7 +109,7 @@ public:
         QSGMaterialShader::deactivate();
 
         for (int i=0; i<8; ++i) {
-            m_program.setAttributeArray(i, GL_FLOAT, chunkOfBytes, 1, 0);
+            program()->setAttributeArray(i, GL_FLOAT, chunkOfBytes, 1, 0);
         }
     }
 
@@ -118,21 +118,21 @@ public:
         SpriteParticlesMaterial *m = static_cast<SpriteParticlesMaterial *>(newEffect);
         m->texture->bind();
 
-        m_program.setUniformValue(m_opacity_id, state.opacity());
-        m_program.setUniformValue(m_timestamp_id, (float) m->timestamp);
-        m_program.setUniformValue(m_framecount_id, (float) m->framecount);
-        m_program.setUniformValue(m_animcount_id, (float) m->animcount);
+        program()->setUniformValue(m_opacity_id, state.opacity());
+        program()->setUniformValue(m_timestamp_id, (float) m->timestamp);
+        program()->setUniformValue(m_framecount_id, (float) m->framecount);
+        program()->setUniformValue(m_animcount_id, (float) m->animcount);
 
         if (state.isMatrixDirty())
-            m_program.setUniformValue(m_matrix_id, state.combinedMatrix());
+            program()->setUniformValue(m_matrix_id, state.combinedMatrix());
     }
 
     virtual void initialize() {
-        m_matrix_id = m_program.uniformLocation("matrix");
-        m_opacity_id = m_program.uniformLocation("opacity");
-        m_timestamp_id = m_program.uniformLocation("timestamp");
-        m_framecount_id = m_program.uniformLocation("framecount");
-        m_animcount_id = m_program.uniformLocation("animcount");
+        m_matrix_id = program()->uniformLocation("matrix");
+        m_opacity_id = program()->uniformLocation("opacity");
+        m_timestamp_id = program()->uniformLocation("timestamp");
+        m_framecount_id = program()->uniformLocation("framecount");
+        m_animcount_id = program()->uniformLocation("animcount");
     }
 
     virtual const char *vertexShader() const { return m_vertex_code.constData(); }