diff options
author | Kim Motoyoshi Kalland <kim.kalland@nokia.com> | 2012-01-11 17:34:58 +0100 |
---|---|---|
committer | Qt by Nokia <qt-info@nokia.com> | 2012-01-16 15:07:33 +0100 |
commit | e79eedcb1eaf56280035550f4c6bb2395a51fd16 (patch) | |
tree | 45e6d0c6aa05ddd59762159b7dc27bd877f57134 /src/quick/items/qquickshadereffectnode.cpp | |
parent | 7911627f718d0e4876c42adbb5f3e02cf3c9f4eb (diff) |
Added log and status properties to ShaderEffect.
Task-number: QTBUG-23531
Change-Id: I136f6d9642ff9d4074fe8dae1f5714a05349107a
Reviewed-by: Gunnar Sletta <gunnar.sletta@nokia.com>
Diffstat (limited to 'src/quick/items/qquickshadereffectnode.cpp')
-rw-r--r-- | src/quick/items/qquickshadereffectnode.cpp | 90 |
1 files changed, 88 insertions, 2 deletions
diff --git a/src/quick/items/qquickshadereffectnode.cpp b/src/quick/items/qquickshadereffectnode.cpp index 968982bb88..c0d8fbcd30 100644 --- a/src/quick/items/qquickshadereffectnode.cpp +++ b/src/quick/items/qquickshadereffectnode.cpp @@ -42,6 +42,7 @@ #include <private/qquickshadereffectnode_p.h> #include "qquickshadereffectmesh_p.h" +#include "qquickshadereffect_p.h" #include <QtQuick/qsgtextureprovider.h> #include <QtQuick/private/qsgrenderer_p.h> @@ -58,6 +59,7 @@ public: protected: friend class QQuickShaderEffectNode; + virtual void compile(); virtual void initialize(); virtual const char *vertexShader() const; virtual const char *fragmentShader() const; @@ -65,6 +67,8 @@ protected: const QQuickShaderEffectMaterialKey m_key; QVector<const char *> m_attributeNames; const QVector<QByteArray> m_attributes; + QString m_log; + bool m_compiled; QVector<int> m_uniformLocs; int m_opacityLoc; @@ -75,6 +79,7 @@ protected: QQuickCustomMaterialShader::QQuickCustomMaterialShader(const QQuickShaderEffectMaterialKey &key, const QVector<QByteArray> &attributes) : m_key(key) , m_attributes(attributes) + , m_compiled(false) , m_textureIndicesSet(false) { for (int i = 0; i < attributes.count(); ++i) @@ -92,7 +97,12 @@ void QQuickCustomMaterialShader::updateState(const RenderState &state, QSGMateri { Q_ASSERT(newEffect != 0); - const QQuickShaderEffectMaterial *material = static_cast<const QQuickShaderEffectMaterial *>(newEffect); + QQuickShaderEffectMaterial *material = static_cast<QQuickShaderEffectMaterial *>(newEffect); + if (!material->m_emittedLogChanged && material->m_node) { + material->m_emittedLogChanged = true; + emit material->m_node->logAndStatusChanged(m_log, m_compiled ? QQuickShaderEffect::Compiled + : QQuickShaderEffect::Error); + } if (!m_textureIndicesSet) { for (int i = 0; i < material->m_textures.size(); ++i) @@ -192,6 +202,78 @@ char const *const *QQuickCustomMaterialShader::attributeNames() const return m_attributeNames.constData(); } +void QQuickCustomMaterialShader::compile() +{ + Q_ASSERT_X(!program()->isLinked(), "QQuickCustomMaterialShader::compile()", "Compile called multiple times!"); + + m_log.clear(); + m_compiled = true; + if (!program()->addShaderFromSourceCode(QOpenGLShader::Vertex, vertexShader())) { + m_log += QLatin1String("*** Vertex shader ***\n"); + m_log += program()->log(); + m_compiled = false; + } + if (!program()->addShaderFromSourceCode(QOpenGLShader::Fragment, fragmentShader())) { + m_log += QLatin1String("*** Fragment shader ***\n"); + m_log += program()->log(); + m_compiled = false; + } + + char const *const *attr = attributeNames(); +#ifndef QT_NO_DEBUG + int maxVertexAttribs = 0; + glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &maxVertexAttribs); + int attrCount = 0; + while (attrCount < maxVertexAttribs && attr[attrCount]) + ++attrCount; + if (attr[attrCount]) { + qWarning("List of attribute names is too long.\n" + "Maximum number of attributes on this hardware is %i.\n" + "Vertex shader:\n%s\n" + "Fragment shader:\n%s\n", + maxVertexAttribs, vertexShader(), fragmentShader()); + } +#endif + + if (m_compiled) { +#ifndef QT_NO_DEBUG + for (int i = 0; i < attrCount; ++i) { +#else + for (int i = 0; attr[i]; ++i) { +#endif + if (*attr[i]) + program()->bindAttributeLocation(attr[i], i); + } + m_compiled = program()->link(); + m_log += program()->log(); + } + + static const char *fallbackVertexShader = + "uniform highp mat4 qt_Matrix;" + "attribute highp vec4 v;" + "void main() { gl_Position = qt_Matrix * v; }"; + static const char *fallbackFragmentShader = + "void main() { gl_FragColor = vec4(1., 0., 1., 1.); }"; + + if (!m_compiled) { + qWarning("QQuickCustomMaterialShader: Shader compilation failed:"); + qWarning() << program()->log(); + + program()->removeAllShaders(); + program()->addShaderFromSourceCode(QOpenGLShader::Vertex, fallbackVertexShader); + program()->addShaderFromSourceCode(QOpenGLShader::Fragment, fallbackFragmentShader); +#ifndef QT_NO_DEBUG + for (int i = 0; i < attrCount; ++i) { +#else + for (int i = 0; attr[i]; ++i) { +#endif + if (qstrcmp(attr[i], qtPositionAttributeName()) == 0) + program()->bindAttributeLocation("v", i); + } + program()->link(); + } +} + void QQuickCustomMaterialShader::initialize() { m_opacityLoc = program()->uniformLocation("qt_Opacity"); @@ -222,8 +304,10 @@ uint qHash(const QQuickShaderEffectMaterialKey &key) QHash<QQuickShaderEffectMaterialKey, QSharedPointer<QSGMaterialType> > QQuickShaderEffectMaterial::materialMap; -QQuickShaderEffectMaterial::QQuickShaderEffectMaterial() +QQuickShaderEffectMaterial::QQuickShaderEffectMaterial(QQuickShaderEffectNode *node) : m_cullMode(NoCulling) + , m_node(node) + , m_emittedLogChanged(false) { setFlag(Blending, true); } @@ -256,6 +340,7 @@ QQuickShaderEffectMaterial::CullMode QQuickShaderEffectMaterial::cullMode() cons void QQuickShaderEffectMaterial::setProgramSource(const QQuickShaderEffectProgram &source) { m_source = source; + m_emittedLogChanged = false; m_type = materialMap.value(m_source); if (m_type.isNull()) { m_type = QSharedPointer<QSGMaterialType>(new QSGMaterialType); @@ -290,6 +375,7 @@ void QQuickShaderEffectMaterial::updateTextures() const QQuickShaderEffectNode::QQuickShaderEffectNode() + : m_material(this) { QSGNode::setFlag(UsePreprocess, true); setMaterial(&m_material); |