Enable program binary support through QSGRenderContext API.
authorGunnar Sletta <gunnar.sletta@jollamobile.com>
Tue, 11 Feb 2014 21:49:08 +0000 (21:49 +0000)
committerThe Qt Project <gerrit-noreply@qt-project.org>
Thu, 13 Feb 2014 07:52:17 +0000 (08:52 +0100)
Change-Id: I4eecff3c8a2c727d38d394305d248eddeef87e8e
Reviewed-by: Michael Brasser <michael.brasser@live.com>
src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp
src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h
src/quick/scenegraph/qsgcontext.cpp
src/quick/scenegraph/qsgcontext_p.h

index 42a6c23..249cdca 100644 (file)
@@ -138,11 +138,6 @@ ShaderManager::Shader *ShaderManager::prepareMaterial(QSGMaterial *material)
     QSurfaceFormat::OpenGLContextProfile profile = ctx->format().profile();
 
     QOpenGLShaderProgram *p = s->program();
-    p->addShaderFromSourceCode(QOpenGLShader::Vertex,
-                               qsgShaderRewriter_insertZAttributes(s->vertexShader(), profile));
-    p->addShaderFromSourceCode(QOpenGLShader::Fragment,
-                               s->fragmentShader());
-
     char const *const *attr = s->attributeNames();
     int i;
     for (i = 0; attr[i]; ++i) {
@@ -150,14 +145,10 @@ ShaderManager::Shader *ShaderManager::prepareMaterial(QSGMaterial *material)
             p->bindAttributeLocation(attr[i], i);
     }
     p->bindAttributeLocation("_qt_order", i);
-
-    p->link();
-    if (!p->isLinked()) {
-        qDebug() << "Renderer failed shader compilation:" << endl << p->log();
+    context->compile(s, material, qsgShaderRewriter_insertZAttributes(s->vertexShader(), profile), 0);
+    context->initialize(s);
+    if (!p->isLinked())
         return 0;
-    }
-
-    s->initialize();
 
     shader = new Shader;
     shader->program = s;
@@ -196,8 +187,8 @@ ShaderManager::Shader *ShaderManager::prepareMaterialNoRewrite(QSGMaterial *mate
 #endif
 
     QSGMaterialShader *s = static_cast<QSGMaterialShader *>(material->createShader());
-    s->compile();
-    s->initialize();
+    context->compile(s, material);
+    context->initialize(s);
 
     shader = new Shader();
     shader->program = s;
@@ -776,7 +767,7 @@ Renderer::Renderer(QSGRenderContext *ctx)
 
     m_shaderManager = ctx->findChild<ShaderManager *>(QStringLiteral("__qt_ShaderManager"), Qt::FindDirectChildrenOnly);
     if (!m_shaderManager) {
-        m_shaderManager = new ShaderManager();
+        m_shaderManager = new ShaderManager(ctx);
         m_shaderManager->setObjectName(QStringLiteral("__qt_ShaderManager"));
         m_shaderManager->setParent(ctx);
         QObject::connect(ctx, SIGNAL(invalidated()), m_shaderManager, SLOT(invalidated()), Qt::DirectConnection);
index 379c0ee..128ae27 100644 (file)
@@ -371,7 +371,7 @@ public:
         float lastOpacity;
     };
 
-    ShaderManager() : blitProgram(0) { }
+    ShaderManager(QSGRenderContext *ctx) : blitProgram(0), context(ctx) { }
     ~ShaderManager() {
         qDeleteAll(rewrittenShaders.values());
         qDeleteAll(stockShaders.values());
@@ -388,6 +388,7 @@ public:
     QHash<QSGMaterialType *, Shader *> stockShaders;
 
     QOpenGLShaderProgram *blitProgram;
+    QSGRenderContext *context;
 };
 
 class Q_QUICK_PRIVATE_EXPORT Renderer : public QSGRenderer
index 5135cc6..f91dfc5 100644 (file)
@@ -649,4 +649,38 @@ void QSGRenderContext::textureFactoryDestroyed(QObject *o)
     m_mutex.unlock();
 }
 
+/*!
+    Compile \a shader, optionally using \a vertexCode and \a fragmentCode as
+    replacement for the source code supplied by \a shader.
+
+    If \a vertexCode or \a fragmentCode is supplied, the caller is responsible
+    for setting up attribute bindings.
+
+    \a material is supplied in case the implementation needs to take the
+    material flags into account.
+ */
+
+void QSGRenderContext::compile(QSGMaterialShader *shader, QSGMaterial *material, const char *vertexCode, const char *fragmentCode)
+{
+    Q_UNUSED(material);
+    if (vertexCode || fragmentCode) {
+        Q_ASSERT_X((material->flags() & QSGMaterial::CustomCompileStep) == 0,
+                   "QSGRenderContext::compile()",
+                   "materials with custom compile step cannot have custom vertex/fragment code");
+        QOpenGLShaderProgram *p = shader->program();
+        p->addShaderFromSourceCode(QOpenGLShader::Vertex, vertexCode ? vertexCode : shader->vertexShader());
+        p->addShaderFromSourceCode(QOpenGLShader::Fragment, fragmentCode ? fragmentCode : shader->fragmentShader());
+        p->link();
+        if (!p->isLinked())
+            qWarning() << "shader compilation failed:" << endl << p->log();
+    } else {
+        shader->compile();
+    }
+}
+
+void QSGRenderContext::initialize(QSGMaterialShader *shader)
+{
+    shader->initialize();
+}
+
 QT_END_NAMESPACE
index ef67dcc..b7dc93a 100644 (file)
@@ -106,6 +106,9 @@ public:
     virtual QSGTexture *createTextureNoAtlas(const QImage &image) const;
     virtual QSGRenderer *createRenderer();
 
+    virtual void compile(QSGMaterialShader *shader, QSGMaterial *material, const char *vertexCode = 0, const char *fragmentCode = 0);
+    virtual void initialize(QSGMaterialShader *shader);
+
     void registerFontengineForCleanup(QFontEngine *engine);
 
     static QSGRenderContext *from(QOpenGLContext *context);