diff options
author | Simon Hausmann <simon.hausmann@digia.com> | 2014-02-18 09:58:57 +0100 |
---|---|---|
committer | Simon Hausmann <simon.hausmann@digia.com> | 2014-02-18 09:58:57 +0100 |
commit | ba9ca0e3d64c46fc63cdbc62f3e4a96e36a842f8 (patch) | |
tree | f9631624c841281302a2a546fbcc06a2375f410e /src | |
parent | a65b8785621ebf58f34eb0c1759376fc0a1117c7 (diff) | |
parent | 464bd2bf975797241213191a374e70431c5c3763 (diff) |
Merge remote-tracking branch 'origin/stable' into dev
Conflicts:
src/qml/jsruntime/qv4functionobject.cpp
src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h
Change-Id: Id164f6c3b45501aa466908659ec4e3b957323753
Diffstat (limited to 'src')
-rw-r--r-- | src/qml/compiler/qv4isel_p.cpp | 3 | ||||
-rw-r--r-- | src/qml/compiler/qv4ssa.cpp | 3 | ||||
-rw-r--r-- | src/qml/doc/src/qmllanguageref/modules/qmldir.qdoc | 14 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4functionobject.cpp | 19 | ||||
-rw-r--r-- | src/qml/qml/qqmljavascriptexpression.cpp | 113 | ||||
-rw-r--r-- | src/qml/qml/qqmljavascriptexpression_p.h | 5 | ||||
-rw-r--r-- | src/quick/items/qquickitemview.cpp | 2 | ||||
-rw-r--r-- | src/quick/items/qquickrectangle.cpp | 20 | ||||
-rw-r--r-- | src/quick/items/qquickrectangle_p.h | 6 | ||||
-rw-r--r-- | src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp | 22 | ||||
-rw-r--r-- | src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h | 3 | ||||
-rw-r--r-- | src/quick/scenegraph/coreapi/qsgmaterial.cpp | 6 | ||||
-rw-r--r-- | src/quick/scenegraph/coreapi/qsgnode.cpp | 5 | ||||
-rw-r--r-- | src/quick/scenegraph/coreapi/qsgnode.h | 1 | ||||
-rw-r--r-- | src/quick/scenegraph/coreapi/qsgrenderer_p.h | 1 | ||||
-rw-r--r-- | src/quick/scenegraph/qsgcontext.cpp | 34 | ||||
-rw-r--r-- | src/quick/scenegraph/qsgcontext_p.h | 3 |
17 files changed, 157 insertions, 103 deletions
diff --git a/src/qml/compiler/qv4isel_p.cpp b/src/qml/compiler/qv4isel_p.cpp index b86837e167..644e06b59a 100644 --- a/src/qml/compiler/qv4isel_p.cpp +++ b/src/qml/compiler/qv4isel_p.cpp @@ -53,7 +53,8 @@ #include <cassert> namespace { -QTextStream qout(stderr, QIODevice::WriteOnly); +Q_GLOBAL_STATIC_WITH_ARGS(QTextStream, qout, (stderr, QIODevice::WriteOnly)); +#define qout *qout() } // anonymous namespace using namespace QQmlJS; diff --git a/src/qml/compiler/qv4ssa.cpp b/src/qml/compiler/qv4ssa.cpp index 52c546039c..5f79146127 100644 --- a/src/qml/compiler/qv4ssa.cpp +++ b/src/qml/compiler/qv4ssa.cpp @@ -77,7 +77,8 @@ using namespace V4IR; namespace { -QTextStream qout(stdout, QIODevice::WriteOnly); +Q_GLOBAL_STATIC_WITH_ARGS(QTextStream, qout, (stderr, QIODevice::WriteOnly)); +#define qout *qout() void showMeTheCode(Function *function) { diff --git a/src/qml/doc/src/qmllanguageref/modules/qmldir.qdoc b/src/qml/doc/src/qmllanguageref/modules/qmldir.qdoc index c89d4a3c0d..88c866baf3 100644 --- a/src/qml/doc/src/qmllanguageref/modules/qmldir.qdoc +++ b/src/qml/doc/src/qmllanguageref/modules/qmldir.qdoc @@ -27,7 +27,7 @@ /*! \page qtqml-modules-qmldir.html \title Module Definition qmldir Files -\brief How to write a qmldir file which defines a QML module +\brief Defines a QML module There are two distinct types of \c qmldir files: \list @@ -177,6 +177,18 @@ plugin <Name> [<Path>] \code plugin MyPluginLibrary \endcode + \row + \li C++ Plugin Class + \li + \code + classname <C++ plugin class> + \endcode + \li Provides the class name of the C++ plugin used by the module. + + This information is required for all the QML modules that depend + on a C++ plugin for additional functionality. Qt Quick applications + built with static linking cannot resolve the module imports without + this information. \row \li Type Information Description File Declaration diff --git a/src/qml/jsruntime/qv4functionobject.cpp b/src/qml/jsruntime/qv4functionobject.cpp index 58e0277395..fb87822a5a 100644 --- a/src/qml/jsruntime/qv4functionobject.cpp +++ b/src/qml/jsruntime/qv4functionobject.cpp @@ -447,11 +447,12 @@ ReturnedValue ScriptFunction::construct(Managed *that, CallData *callData) callData->thisObject = obj.asReturnedValue(); ExecutionContext *ctx = context->newCallContext(f.getPointer(), callData); + ExecutionContextSaver ctxSaver(context); + ScopedValue result(scope, Q_V4_PROFILE(v4, ctx, f->function)); + if (f->function->compiledFunction->hasQmlDependencies()) QmlContextWrapper::registerQmlDependencies(v4, f->function->compiledFunction); - ExecutionContextSaver ctxSaver(context); - ScopedValue result(scope, Q_V4_PROFILE(v4, ctx, f->function)); if (result->isObject()) return result.asReturnedValue(); return obj.asReturnedValue(); @@ -470,11 +471,13 @@ ReturnedValue ScriptFunction::call(Managed *that, CallData *callData) CallContext *ctx = context->newCallContext(f, callData); + ExecutionContextSaver ctxSaver(context); + ScopedValue result(scope, Q_V4_PROFILE(v4, ctx, f->function)); + if (f->function->compiledFunction->hasQmlDependencies()) QmlContextWrapper::registerQmlDependencies(ctx->engine, f->function->compiledFunction); - ExecutionContextSaver ctxSaver(context); - return Q_V4_PROFILE(v4, ctx, f->function); + return result.asReturnedValue(); } DEFINE_OBJECT_VTABLE(SimpleScriptFunction); @@ -542,11 +545,11 @@ ReturnedValue SimpleScriptFunction::construct(Managed *that, CallData *callData) } Q_ASSERT(v4->currentContext() == &ctx); + Scoped<Object> result(scope, Q_V4_PROFILE(v4, &ctx, f->function)); + if (f->function->compiledFunction->hasQmlDependencies()) QmlContextWrapper::registerQmlDependencies(v4, f->function->compiledFunction); - Scoped<Object> result(scope, Q_V4_PROFILE(v4, &ctx, f->function)); - if (!result) return callData->thisObject.asReturnedValue(); return result.asReturnedValue(); @@ -579,10 +582,12 @@ ReturnedValue SimpleScriptFunction::call(Managed *that, CallData *callData) } Q_ASSERT(v4->currentContext() == &ctx); + ScopedValue result(scope, Q_V4_PROFILE(v4, &ctx, f->function)); + if (f->function->compiledFunction->hasQmlDependencies()) QmlContextWrapper::registerQmlDependencies(v4, f->function->compiledFunction); - return Q_V4_PROFILE(v4, &ctx, f->function); + return result.asReturnedValue(); } diff --git a/src/qml/qml/qqmljavascriptexpression.cpp b/src/qml/qml/qqmljavascriptexpression.cpp index b7673bdb37..b233b6e98c 100644 --- a/src/qml/qml/qqmljavascriptexpression.cpp +++ b/src/qml/qml/qqmljavascriptexpression.cpp @@ -138,8 +138,12 @@ QV4::ReturnedValue QQmlJavaScriptExpression::evaluate(QQmlContextData *context, QQmlEnginePrivate *ep = QQmlEnginePrivate::get(context->engine); + // All code that follows must check with watcher before it accesses data members + // incase we have been deleted. + DeleteWatcher watcher(this); + Q_ASSERT(notifyOnValueChanged() || activeGuards.isEmpty()); - GuardCapture capture(context->engine, this); + GuardCapture capture(context->engine, this, &watcher); QQmlEnginePrivate::PropertyCapture *lastPropertyCapture = ep->propertyCapture; ep->propertyCapture = notifyOnValueChanged()?&capture:0; @@ -148,10 +152,6 @@ QV4::ReturnedValue QQmlJavaScriptExpression::evaluate(QQmlContextData *context, if (notifyOnValueChanged()) capture.guards.copyAndClearPrepend(activeGuards); - // All code that follows must check with watcher before it accesses data members - // incase we have been deleted. - DeleteWatcher watcher(this); - QV4::ExecutionEngine *v4 = QV8Engine::getV4(ep->v8engine()); QV4::Scope scope(v4); QV4::ScopedValue result(scope, QV4::Primitive::undefinedValue()); @@ -196,72 +196,75 @@ QV4::ReturnedValue QQmlJavaScriptExpression::evaluate(QQmlContextData *context, void QQmlJavaScriptExpression::GuardCapture::captureProperty(QQmlNotifier *n) { - if (expression) { + if (watcher->wasDeleted()) + return; + + Q_ASSERT(expression); + // Try and find a matching guard + while (!guards.isEmpty() && !guards.first()->isConnected(n)) + guards.takeFirst()->Delete(); + + Guard *g = 0; + if (!guards.isEmpty()) { + g = guards.takeFirst(); + g->cancelNotify(); + Q_ASSERT(g->isConnected(n)); + } else { + g = Guard::New(expression, engine); + g->connect(n); + } + + expression->activeGuards.prepend(g); +} + +/*! \internal + \reimp + + \a n is in the signal index range (see QObjectPrivate::signalIndex()). +*/ +void QQmlJavaScriptExpression::GuardCapture::captureProperty(QObject *o, int c, int n) +{ + if (watcher->wasDeleted()) + return; + + Q_ASSERT(expression); + if (n == -1) { + if (!errorString) { + errorString = new QStringList; + QString preamble = QLatin1String("QQmlExpression: Expression ") + + expression->m_vtable->expressionIdentifier(expression) + + QLatin1String(" depends on non-NOTIFYable properties:"); + errorString->append(preamble); + } + + const QMetaObject *metaObj = o->metaObject(); + QMetaProperty metaProp = metaObj->property(c); + + QString error = QLatin1String(" ") + + QString::fromUtf8(metaObj->className()) + + QLatin1String("::") + + QString::fromUtf8(metaProp.name()); + errorString->append(error); + } else { // Try and find a matching guard - while (!guards.isEmpty() && !guards.first()->isConnected(n)) + while (!guards.isEmpty() && !guards.first()->isConnected(o, n)) guards.takeFirst()->Delete(); Guard *g = 0; if (!guards.isEmpty()) { g = guards.takeFirst(); g->cancelNotify(); - Q_ASSERT(g->isConnected(n)); + Q_ASSERT(g->isConnected(o, n)); } else { g = Guard::New(expression, engine); - g->connect(n); + g->connect(o, n, engine); } expression->activeGuards.prepend(g); } } -/*! \internal - \reimp - - \a n is in the signal index range (see QObjectPrivate::signalIndex()). -*/ -void QQmlJavaScriptExpression::GuardCapture::captureProperty(QObject *o, int c, int n) -{ - if (expression) { - if (n == -1) { - if (!errorString) { - errorString = new QStringList; - QString preamble = QLatin1String("QQmlExpression: Expression ") + - expression->m_vtable->expressionIdentifier(expression) + - QLatin1String(" depends on non-NOTIFYable properties:"); - errorString->append(preamble); - } - - const QMetaObject *metaObj = o->metaObject(); - QMetaProperty metaProp = metaObj->property(c); - - QString error = QLatin1String(" ") + - QString::fromUtf8(metaObj->className()) + - QLatin1String("::") + - QString::fromUtf8(metaProp.name()); - errorString->append(error); - } else { - - // Try and find a matching guard - while (!guards.isEmpty() && !guards.first()->isConnected(o, n)) - guards.takeFirst()->Delete(); - - Guard *g = 0; - if (!guards.isEmpty()) { - g = guards.takeFirst(); - g->cancelNotify(); - Q_ASSERT(g->isConnected(o, n)); - } else { - g = Guard::New(expression, engine); - g->connect(o, n, engine); - } - - expression->activeGuards.prepend(g); - } - } -} - void QQmlJavaScriptExpression::clearError() { if (m_vtable.hasValue()) { diff --git a/src/qml/qml/qqmljavascriptexpression_p.h b/src/qml/qml/qqmljavascriptexpression_p.h index 7d65f1c9cc..d0f10e498d 100644 --- a/src/qml/qml/qqmljavascriptexpression_p.h +++ b/src/qml/qml/qqmljavascriptexpression_p.h @@ -161,8 +161,8 @@ private: friend void QQmlJavaScriptExpressionGuard_callback(QQmlNotifierEndpoint *, void **); struct GuardCapture : public QQmlEnginePrivate::PropertyCapture { - GuardCapture(QQmlEngine *engine, QQmlJavaScriptExpression *e) - : engine(engine), expression(e), errorString(0) { } + GuardCapture(QQmlEngine *engine, QQmlJavaScriptExpression *e, DeleteWatcher *w) + : engine(engine), expression(e), watcher(w), errorString(0) { } ~GuardCapture() { Q_ASSERT(guards.isEmpty()); @@ -174,6 +174,7 @@ private: QQmlEngine *engine; QQmlJavaScriptExpression *expression; + DeleteWatcher *watcher; QFieldList<Guard, &Guard::next> guards; QStringList *errorString; }; diff --git a/src/quick/items/qquickitemview.cpp b/src/quick/items/qquickitemview.cpp index 10f134f7ae..30d0619f7a 100644 --- a/src/quick/items/qquickitemview.cpp +++ b/src/quick/items/qquickitemview.cpp @@ -1872,7 +1872,7 @@ void QQuickItemViewPrivate::layout() prepareVisibleItemTransitions(); - QRectF viewBounds(0, position(), q->width(), q->height()); + QRectF viewBounds(q->contentX(), q->contentY(), q->width(), q->height()); for (QList<FxViewItem*>::Iterator it = releasePendingTransition.begin(); it != releasePendingTransition.end(); ) { FxViewItem *item = *it; diff --git a/src/quick/items/qquickrectangle.cpp b/src/quick/items/qquickrectangle.cpp index ee1b66f2b5..8d9f6b9d4a 100644 --- a/src/quick/items/qquickrectangle.cpp +++ b/src/quick/items/qquickrectangle.cpp @@ -255,6 +255,18 @@ QQmlListProperty<QQuickGradientStop> QQuickGradient::stops() return QQmlListProperty<QQuickGradientStop>(this, m_stops); } +QGradientStops QQuickGradient::gradientStops() const +{ + QGradientStops stops; + for (int i = 0; i < m_stops.size(); ++i){ + int j = 0; + while (j < stops.size() && stops.at(j).first < m_stops[i]->position()) + j++; + stops.insert(j, QGradientStop(m_stops.at(i)->position(), m_stops.at(i)->color())); + } + return stops; +} + void QQuickGradient::doUpdate() { emit updated(); @@ -492,13 +504,7 @@ QSGNode *QQuickRectangle::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData QGradientStops stops; if (d->gradient) { - QList<QQuickGradientStop *> qxstops = d->gradient->m_stops; - for (int i = 0; i < qxstops.size(); ++i){ - int j = 0; - while (j < stops.size() && stops.at(j).first < qxstops[i]->position()) - j++; - stops.insert(j, QGradientStop(qxstops.at(i)->position(), qxstops.at(i)->color())); - } + stops = d->gradient->gradientStops(); } rectangle->setGradientStops(stops); diff --git a/src/quick/items/qquickrectangle_p.h b/src/quick/items/qquickrectangle_p.h index 009512afd4..09b530c191 100644 --- a/src/quick/items/qquickrectangle_p.h +++ b/src/quick/items/qquickrectangle_p.h @@ -81,7 +81,7 @@ private: bool m_valid : 1; }; -class Q_AUTOTEST_EXPORT QQuickGradientStop : public QObject +class Q_QUICK_PRIVATE_EXPORT QQuickGradientStop : public QObject { Q_OBJECT @@ -105,7 +105,7 @@ private: QColor m_color; }; -class Q_AUTOTEST_EXPORT QQuickGradient : public QObject +class Q_QUICK_PRIVATE_EXPORT QQuickGradient : public QObject { Q_OBJECT @@ -118,6 +118,8 @@ public: QQmlListProperty<QQuickGradientStop> stops(); + QGradientStops gradientStops() const; + Q_SIGNALS: void updated(); diff --git a/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp b/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp index f121e16523..30081093f2 100644 --- a/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp +++ b/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp @@ -143,11 +143,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) { @@ -155,14 +150,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; @@ -198,8 +189,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; @@ -292,6 +283,7 @@ void Updater::updateStates(QSGNode *n) m_added = 0; m_transformChange = 0; + m_opacityChange = 0; Node *sn = renderer->m_nodes.value(n, 0); Q_ASSERT(sn); @@ -779,7 +771,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); diff --git a/src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h b/src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h index c38c483df4..7c06de774a 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), visualizeProgram(0) { } + ShaderManager(QSGRenderContext *ctx) : blitProgram(0), visualizeProgram(0), context(ctx) { } ~ShaderManager() { qDeleteAll(rewrittenShaders.values()); qDeleteAll(stockShaders.values()); @@ -389,6 +389,7 @@ public: QOpenGLShaderProgram *blitProgram; QOpenGLShaderProgram *visualizeProgram; + QSGRenderContext *context; }; class Q_QUICK_PRIVATE_EXPORT Renderer : public QSGRenderer diff --git a/src/quick/scenegraph/coreapi/qsgmaterial.cpp b/src/quick/scenegraph/coreapi/qsgmaterial.cpp index 686d1438b4..4954fe20bb 100644 --- a/src/quick/scenegraph/coreapi/qsgmaterial.cpp +++ b/src/quick/scenegraph/coreapi/qsgmaterial.cpp @@ -257,9 +257,6 @@ const char *QSGMaterialShader::fragmentShader() const 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() @@ -271,9 +268,6 @@ void QSGMaterialShader::activate() /*! 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() diff --git a/src/quick/scenegraph/coreapi/qsgnode.cpp b/src/quick/scenegraph/coreapi/qsgnode.cpp index b0c869c096..5c196b252c 100644 --- a/src/quick/scenegraph/coreapi/qsgnode.cpp +++ b/src/quick/scenegraph/coreapi/qsgnode.cpp @@ -648,10 +648,7 @@ void QSGNode::setFlags(Flags f, bool enabled) /*! - Marks this node with the states in \a bits as dirty. - - When a node is marked dirty, it recursively marks the parent chain - as dirty and notify all connected renderers that the has dirty states. + Notifies all connected renderers that the node has dirty \a bits. */ void QSGNode::markDirty(DirtyState bits) diff --git a/src/quick/scenegraph/coreapi/qsgnode.h b/src/quick/scenegraph/coreapi/qsgnode.h index 60e7652e7a..f85184db90 100644 --- a/src/quick/scenegraph/coreapi/qsgnode.h +++ b/src/quick/scenegraph/coreapi/qsgnode.h @@ -161,6 +161,7 @@ protected: private: friend class QSGRootNode; friend class QSGBatchRenderer::Renderer; + friend class QSGRenderer; void init(); void destroy(); diff --git a/src/quick/scenegraph/coreapi/qsgrenderer_p.h b/src/quick/scenegraph/coreapi/qsgrenderer_p.h index 296d6e2cfd..55c9444365 100644 --- a/src/quick/scenegraph/coreapi/qsgrenderer_p.h +++ b/src/quick/scenegraph/coreapi/qsgrenderer_p.h @@ -150,6 +150,7 @@ protected: void addNodesToPreprocess(QSGNode *node); void removeNodesToPreprocess(QSGNode *node); + void markNodeDirtyState(QSGNode *node, QSGNode::DirtyState state) { node->m_dirtyState |= state; } QColor m_clear_color; ClearMode m_clear_mode; diff --git a/src/quick/scenegraph/qsgcontext.cpp b/src/quick/scenegraph/qsgcontext.cpp index dd00f75fae..9f58876def 100644 --- a/src/quick/scenegraph/qsgcontext.cpp +++ b/src/quick/scenegraph/qsgcontext.cpp @@ -631,4 +631,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 3b58cecd6a..f8d5588649 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); |