From 586ebf6c55ed095c2627185d90153ccfdc51c3d2 Mon Sep 17 00:00:00 2001 From: Gunnar Sletta Date: Tue, 11 Feb 2014 21:49:08 +0000 Subject: Enable program binary support through QSGRenderContext API. Change-Id: I4eecff3c8a2c727d38d394305d248eddeef87e8e Reviewed-by: Michael Brasser --- src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp | 21 ++++---------- src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h | 3 +- src/quick/scenegraph/qsgcontext.cpp | 34 +++++++++++++++++++++++ src/quick/scenegraph/qsgcontext_p.h | 3 ++ 4 files changed, 45 insertions(+), 16 deletions(-) diff --git a/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp b/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp index 42a6c23982..249cdca1da 100644 --- a/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp +++ b/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp @@ -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(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(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); diff --git a/src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h b/src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h index 379c0ee00e..128ae2765e 100644 --- a/src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h +++ b/src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h @@ -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 stockShaders; QOpenGLShaderProgram *blitProgram; + QSGRenderContext *context; }; class Q_QUICK_PRIVATE_EXPORT Renderer : public QSGRenderer diff --git a/src/quick/scenegraph/qsgcontext.cpp b/src/quick/scenegraph/qsgcontext.cpp index 5135cc629c..f91dfc5304 100644 --- a/src/quick/scenegraph/qsgcontext.cpp +++ b/src/quick/scenegraph/qsgcontext.cpp @@ -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 diff --git a/src/quick/scenegraph/qsgcontext_p.h b/src/quick/scenegraph/qsgcontext_p.h index ef67dcceba..b7dc93ae72 100644 --- a/src/quick/scenegraph/qsgcontext_p.h +++ b/src/quick/scenegraph/qsgcontext_p.h @@ -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); -- cgit v1.2.3