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) {
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;
#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;
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);
float lastOpacity;
};
- ShaderManager() : blitProgram(0) { }
+ ShaderManager(QSGRenderContext *ctx) : blitProgram(0), context(ctx) { }
~ShaderManager() {
qDeleteAll(rewrittenShaders.values());
qDeleteAll(stockShaders.values());
QHash<QSGMaterialType *, Shader *> stockShaders;
QOpenGLShaderProgram *blitProgram;
+ QSGRenderContext *context;
};
class Q_QUICK_PRIVATE_EXPORT Renderer : public QSGRenderer
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
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);