aboutsummaryrefslogtreecommitdiffstats
path: root/src/quick/items
diff options
context:
space:
mode:
authorLaszlo Agocs <laszlo.agocs@qt.io>2016-06-27 17:13:37 +0200
committerLaszlo Agocs <laszlo.agocs@qt.io>2016-06-29 11:59:54 +0000
commit5ee02242d72ac9a536584b36ba549480a97303f7 (patch)
treec898b2eedad203ee0536d7b40cab6c1c08234056 /src/quick/items
parent12bff27aa6f1caac9bfacf365c542cf5da6e3148 (diff)
Unify ShaderEffect property setting
rendererInterface() should not require isSceneGraphInitialized() to be true - the API and language queries like graphicsApi() have no need for the scenegraph, they only need the plugin to be loaded, i.e. that the QQuickWindow is constructed. This is the key to be able to make GraphicsInfo report graphicsApi and shaderType with the correct values as early as possible - meaning as soon as the item is associated with a window. The initialization of the scenegraph (the exact timing of which varies backend to backend) does not matter here. The fragment and vertex shader property setting is now unified in the two ShaderEffect implementations: - If the component is complete, the shader is attempted to be processed right from the setter. - Otherwise the item will trigger processing once the component is complete. - If there is no window when processing is trigerred, it is deferred via polish. To implement item polish handling we need a new virtual in QQuickItemPrivate since we cannot intrdouce virtuals into the public classes. This way one can write a condition (and later potentially use file selectors) like this: fragmentShader: GraphicsInfo.shaderType == GraphicsInfo.GLSL ? "..." : ... without having to worry about getting an unintended value processed due to GraphicsInfo not yet reporting an up-to-date value. parseLog() forces, for GL at least, shader processing to prevent autotests from breaking. Change-Id: If55c69d746c29cd07348ddad2d6b0f2b5dd7f3a2 Reviewed-by: Andy Nichols <andy.nichols@qt.io>
Diffstat (limited to 'src/quick/items')
-rw-r--r--src/quick/items/qquickgenericshadereffect.cpp65
-rw-r--r--src/quick/items/qquickgenericshadereffect_p.h9
-rw-r--r--src/quick/items/qquickgraphicsinfo.cpp35
-rw-r--r--src/quick/items/qquickitem_p.h2
-rw-r--r--src/quick/items/qquickopenglshadereffect.cpp31
-rw-r--r--src/quick/items/qquickopenglshadereffect_p.h4
-rw-r--r--src/quick/items/qquickshadereffect.cpp29
-rw-r--r--src/quick/items/qquickshadereffect_p.h3
-rw-r--r--src/quick/items/qquickwindow.cpp25
9 files changed, 130 insertions, 73 deletions
diff --git a/src/quick/items/qquickgenericshadereffect.cpp b/src/quick/items/qquickgenericshadereffect.cpp
index 11259a588a..683453d4ee 100644
--- a/src/quick/items/qquickgenericshadereffect.cpp
+++ b/src/quick/items/qquickgenericshadereffect.cpp
@@ -59,10 +59,11 @@ QQuickGenericShaderEffect::QQuickGenericShaderEffect(QQuickShaderEffect *item, Q
, m_blending(true)
, m_supportsAtlasTextures(false)
, m_mgr(nullptr)
+ , m_fragNeedsUpdate(true)
+ , m_vertNeedsUpdate(true)
, m_dirty(0)
{
qRegisterMetaType<QSGGuiThreadShaderEffectManager::ShaderInfo::Type>("ShaderInfo::Type");
- connect(m_item, SIGNAL(windowChanged(QQuickWindow*)), this, SLOT(itemWindowChanged(QQuickWindow*)));
for (int i = 0; i < NShader; ++i)
m_inProgress[i] = nullptr;
}
@@ -88,12 +89,11 @@ void QQuickGenericShaderEffect::setFragmentShader(const QByteArray &src)
return;
m_fragShader = src;
- m_dirty |= QSGShaderEffectNode::DirtyShaders;
+ m_fragNeedsUpdate = true;
if (m_item->isComponentComplete())
- updateShader(Fragment, src);
+ maybeUpdateShaders();
- m_item->update();
emit m_item->fragmentShaderChanged();
}
@@ -103,12 +103,11 @@ void QQuickGenericShaderEffect::setVertexShader(const QByteArray &src)
return;
m_vertShader = src;
- m_dirty |= QSGShaderEffectNode::DirtyShaders;
+ m_vertNeedsUpdate = true;
if (m_item->isComponentComplete())
- updateShader(Vertex, src);
+ maybeUpdateShaders();
- m_item->update();
emit m_item->vertexShaderChanged();
}
@@ -187,6 +186,12 @@ void QQuickGenericShaderEffect::setSupportsAtlasTextures(bool supports)
emit m_item->supportsAtlasTexturesChanged();
}
+QString QQuickGenericShaderEffect::parseLog()
+{
+ maybeUpdateShaders();
+ return log();
+}
+
QString QQuickGenericShaderEffect::log() const
{
QSGGuiThreadShaderEffectManager *mgr = shaderEffectManager();
@@ -294,10 +299,14 @@ QSGNode *QQuickGenericShaderEffect::handleUpdatePaintNode(QSGNode *oldNode, QQui
return node;
}
-void QQuickGenericShaderEffect::handleComponentComplete()
+void QQuickGenericShaderEffect::maybeUpdateShaders()
{
- updateShader(Vertex, m_vertShader);
- updateShader(Fragment, m_fragShader);
+ if (m_vertNeedsUpdate)
+ m_vertNeedsUpdate = !updateShader(Vertex, m_vertShader);
+ if (m_fragNeedsUpdate)
+ m_fragNeedsUpdate = !updateShader(Fragment, m_fragShader);
+ if (m_vertNeedsUpdate || m_fragNeedsUpdate)
+ m_item->polish();
}
void QQuickGenericShaderEffect::handleItemChange(QQuickItem::ItemChange change, const QQuickItem::ItemChangeData &value)
@@ -326,9 +335,8 @@ QSGGuiThreadShaderEffectManager *QQuickGenericShaderEffect::shaderEffectManager(
// return null if this is not the gui thread and not already created
if (QThread::currentThread() != m_item->thread())
return m_mgr;
- // need a window and a rendercontext (i.e. the scenegraph backend is ready)
QQuickWindow *w = m_item->window();
- if (w && w->isSceneGraphInitialized()) {
+ if (w) { // note: just the window, don't care about isSceneGraphInitialized() here
m_mgr = QQuickWindowPrivate::get(w)->context->sceneGraphContext()->createGuiThreadShaderEffectManager();
if (m_mgr) {
connect(m_mgr, SIGNAL(logAndStatusChanged()), m_item, SIGNAL(logChanged()));
@@ -336,34 +344,12 @@ QSGGuiThreadShaderEffectManager *QQuickGenericShaderEffect::shaderEffectManager(
connect(m_mgr, SIGNAL(textureChanged()), this, SLOT(markGeometryDirtyAndUpdateIfSupportsAtlas()));
connect(m_mgr, &QSGGuiThreadShaderEffectManager::shaderCodePrepared, this, &QQuickGenericShaderEffect::shaderCodePrepared);
}
- } else if (!w) {
- // Wait until itemWindowChanged() gets called. Return null for now.
- } else {
- // Have window, but no scenegraph -> ensure the signal is connected. Return null for now.
- const_cast<QQuickGenericShaderEffect *>(this)->itemWindowChanged(w);
}
}
return m_mgr;
}
-void QQuickGenericShaderEffect::itemWindowChanged(QQuickWindow *w)
-{
- if (w) {
- if (w->isSceneGraphInitialized())
- backendChanged();
- else
- connect(w, SIGNAL(sceneGraphInitialized()), this, SLOT(backendChanged()), Qt::UniqueConnection);
- }
-}
-
-void QQuickGenericShaderEffect::backendChanged()
-{
- disconnect(m_item->window(), SIGNAL(sceneGraphInitialized()), this, SLOT(backendChanged()));
- emit m_item->logChanged();
- emit m_item->statusChanged();
-}
-
void QQuickGenericShaderEffect::disconnectSignals(Shader shaderType)
{
for (auto &sm : m_signalMappers[shaderType]) {
@@ -407,11 +393,11 @@ struct ShaderInfoCache
Q_GLOBAL_STATIC(ShaderInfoCache, shaderInfoCache)
-void QQuickGenericShaderEffect::updateShader(Shader shaderType, const QByteArray &src)
+bool QQuickGenericShaderEffect::updateShader(Shader shaderType, const QByteArray &src)
{
QSGGuiThreadShaderEffectManager *mgr = shaderEffectManager();
if (!mgr)
- return;
+ return false;
const bool texturesSeparate = mgr->hasSeparateSamplerAndTextureObjects();
@@ -439,7 +425,7 @@ void QQuickGenericShaderEffect::updateShader(Shader shaderType, const QByteArray
// source->bytecode compilation as well in this step.
mgr->prepareShaderCode(typeHint, src, m_inProgress[shaderType]);
// the rest is handled in shaderCodePrepared()
- return;
+ return true;
}
} else {
m_shaders[shaderType].hasShaderCode = false;
@@ -459,6 +445,9 @@ void QQuickGenericShaderEffect::updateShader(Shader shaderType, const QByteArray
}
updateShaderVars(shaderType);
+ m_dirty |= QSGShaderEffectNode::DirtyShaders;
+ m_item->update();
+ return true;
}
void QQuickGenericShaderEffect::shaderCodePrepared(bool ok, QSGGuiThreadShaderEffectManager::ShaderInfo::Type typeHint,
@@ -486,6 +475,8 @@ void QQuickGenericShaderEffect::shaderCodePrepared(bool ok, QSGGuiThreadShaderEf
m_shaders[shaderType].hasShaderCode = true;
shaderInfoCache()->insert(src, m_shaders[shaderType].shaderInfo);
updateShaderVars(shaderType);
+ m_dirty |= QSGShaderEffectNode::DirtyShaders;
+ m_item->update();
}
void QQuickGenericShaderEffect::updateShaderVars(Shader shaderType)
diff --git a/src/quick/items/qquickgenericshadereffect_p.h b/src/quick/items/qquickgenericshadereffect_p.h
index 5ec83eb60f..ab19816493 100644
--- a/src/quick/items/qquickgenericshadereffect_p.h
+++ b/src/quick/items/qquickgenericshadereffect_p.h
@@ -90,19 +90,20 @@ public:
bool supportsAtlasTextures() const { return m_supportsAtlasTextures; }
void setSupportsAtlasTextures(bool supports);
+ QString parseLog();
+
void handleEvent(QEvent *);
void handleGeometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry);
QSGNode *handleUpdatePaintNode(QSGNode *, QQuickItem::UpdatePaintNodeData *);
void handleComponentComplete();
void handleItemChange(QQuickItem::ItemChange change, const QQuickItem::ItemChangeData &value);
+ void maybeUpdateShaders();
private slots:
void propertyChanged(int mappedId);
void sourceDestroyed(QObject *object);
void markGeometryDirtyAndUpdate();
void markGeometryDirtyAndUpdateIfSupportsAtlas();
- void itemWindowChanged(QQuickWindow *w);
- void backendChanged();
void shaderCodePrepared(bool ok, QSGGuiThreadShaderEffectManager::ShaderInfo::Type typeHint,
const QByteArray &src, QSGGuiThreadShaderEffectManager::ShaderInfo *result);
@@ -115,7 +116,7 @@ private:
NShader
};
- void updateShader(Shader shaderType, const QByteArray &src);
+ bool updateShader(Shader shaderType, const QByteArray &src);
void updateShaderVars(Shader shaderType);
void disconnectSignals(Shader shaderType);
bool sourceIsUnique(QQuickItem *source, Shader typeToSkip, int indexToSkip) const;
@@ -129,7 +130,9 @@ private:
bool m_supportsAtlasTextures;
mutable QSGGuiThreadShaderEffectManager *m_mgr;
QByteArray m_fragShader;
+ bool m_fragNeedsUpdate;
QByteArray m_vertShader;
+ bool m_vertNeedsUpdate;
QSGShaderEffectNode::ShaderData m_shaders[NShader];
QSGShaderEffectNode::DirtyShaderFlags m_dirty;
diff --git a/src/quick/items/qquickgraphicsinfo.cpp b/src/quick/items/qquickgraphicsinfo.cpp
index 79b0edf031..761d0c3cad 100644
--- a/src/quick/items/qquickgraphicsinfo.cpp
+++ b/src/quick/items/qquickgraphicsinfo.cpp
@@ -112,11 +112,11 @@ QQuickGraphicsInfo *QQuickGraphicsInfo::qmlAttachedProperties(QObject *object)
\endlist
\note The value is only up-to-date once the item is associated with a
- window and the window's scenegraph has initialized. Bindings relying on the
- value have to keep this in mind since the value may change from
- GraphicsInfo.UnknownShadingLanguage to the actual value after component
- initialization is complete. This is particularly relevant for ShaderEffect
- items inside ShaderEffectSource items set as property values.
+ window. Bindings relying on the value have to keep this in mind since the
+ value may change from GraphicsInfo.UnknownShadingLanguage to the actual
+ value after component initialization is complete. This is particularly
+ relevant for ShaderEffect items inside ShaderEffectSource items set as
+ property values.
\since 5.8
\since QtQuick 2.8
@@ -140,11 +140,10 @@ QQuickGraphicsInfo *QQuickGraphicsInfo::qmlAttachedProperties(QObject *object)
expected to focus more on GraphicsInfo.OfflineCompilation, however.
\note The value is only up-to-date once the item is associated with a
- window and the window's scenegraph has initialized. Bindings relying on the
- value have to keep this in mind since the value may change from \c 0 to the
- actual bitmask after component initialization is complete. This is
- particularly relevant for ShaderEffect items inside ShaderEffectSource
- items set as property values.
+ window. Bindings relying on the value have to keep this in mind since the
+ value may change from \c 0 to the actual bitmask after component
+ initialization is complete. This is particularly relevant for ShaderEffect
+ items inside ShaderEffectSource items set as property values.
\since 5.8
\since QtQuick 2.8
@@ -172,11 +171,10 @@ QQuickGraphicsInfo *QQuickGraphicsInfo::qmlAttachedProperties(QObject *object)
bytecode.
\note The value is only up-to-date once the item is associated with a
- window and the window's scenegraph has initialized. Bindings relying on the
- value have to keep this in mind since the value may change from \c 0 to the
- actual bitmask after component initialization is complete. This is
- particularly relevant for ShaderEffect items inside ShaderEffectSource
- items set as property values.
+ window. Bindings relying on the value have to keep this in mind since the
+ value may change from \c 0 to the actual bitmask after component
+ initialization is complete. This is particularly relevant for ShaderEffect
+ items inside ShaderEffectSource items set as property values.
\since 5.8
\since QtQuick 2.8
@@ -240,9 +238,8 @@ QQuickGraphicsInfo *QQuickGraphicsInfo::qmlAttachedProperties(QObject *object)
void QQuickGraphicsInfo::updateInfo()
{
- const bool sgReady = m_window && m_window->isSceneGraphInitialized();
-
- if (sgReady) {
+ // The queries via the RIF do not depend on isSceneGraphInitialized(), they only need a window.
+ if (m_window) {
QSGRendererInterface *rif = m_window->rendererInterface();
if (rif) {
GraphicsApi newAPI = GraphicsApi(rif->graphicsApi());
@@ -261,7 +258,7 @@ void QQuickGraphicsInfo::updateInfo()
QSurfaceFormat format = QSurfaceFormat::defaultFormat();
#ifndef QT_NO_OPENGL
- if (sgReady) {
+ if (m_window && m_window->isSceneGraphInitialized()) {
QOpenGLContext *context = m_window->openglContext();
if (context)
format = context->format();
diff --git a/src/quick/items/qquickitem_p.h b/src/quick/items/qquickitem_p.h
index 3468172484..8328dd513b 100644
--- a/src/quick/items/qquickitem_p.h
+++ b/src/quick/items/qquickitem_p.h
@@ -610,6 +610,8 @@ public:
// recursive helper to let a visual parent mark its visual children
void markObjects(QV4::ExecutionEngine *e);
+
+ virtual void updatePolish() { }
};
/*
diff --git a/src/quick/items/qquickopenglshadereffect.cpp b/src/quick/items/qquickopenglshadereffect.cpp
index 1e66971fdb..f65062ae38 100644
--- a/src/quick/items/qquickopenglshadereffect.cpp
+++ b/src/quick/items/qquickopenglshadereffect.cpp
@@ -556,6 +556,8 @@ QQuickOpenGLShaderEffect::QQuickOpenGLShaderEffect(QQuickShaderEffect *item, QOb
, m_dirtyGeometry(true)
, m_customVertexShader(false)
, m_supportsAtlasTextures(false)
+ , m_vertNeedsUpdate(true)
+ , m_fragNeedsUpdate(true)
{
}
@@ -573,8 +575,9 @@ void QQuickOpenGLShaderEffect::setFragmentShader(const QByteArray &code)
m_dirtyProgram = true;
m_dirtyParseLog = true;
+ m_fragNeedsUpdate = true;
if (m_item->isComponentComplete())
- m_common.updateShader(m_item, Key::FragmentShader);
+ maybeUpdateShaders();
m_item->update();
if (m_status != QQuickShaderEffect::Uncompiled) {
@@ -593,8 +596,9 @@ void QQuickOpenGLShaderEffect::setVertexShader(const QByteArray &code)
m_dirtyParseLog = true;
m_customVertexShader = true;
+ m_vertNeedsUpdate = true;
if (m_item->isComponentComplete())
- m_common.updateShader(m_item, Key::VertexShader);
+ maybeUpdateShaders();
m_item->update();
if (m_status != QQuickShaderEffect::Uncompiled) {
@@ -677,6 +681,8 @@ void QQuickOpenGLShaderEffect::setSupportsAtlasTextures(bool supports)
QString QQuickOpenGLShaderEffect::parseLog()
{
+ maybeUpdateShaders(true);
+
if (m_dirtyParseLog) {
m_common.updateParseLog(m_mesh != 0);
m_dirtyParseLog = false;
@@ -862,10 +868,25 @@ QSGNode *QQuickOpenGLShaderEffect::handleUpdatePaintNode(QSGNode *oldNode, QQuic
return node;
}
-void QQuickOpenGLShaderEffect::handleComponentComplete()
+void QQuickOpenGLShaderEffect::maybeUpdateShaders(bool force)
{
- m_common.updateShader(m_item, Key::VertexShader);
- m_common.updateShader(m_item, Key::FragmentShader);
+ // Defer processing if a window is not yet associated with the item. This
+ // is because the actual scenegraph backend is not known so conditions
+ // based on GraphicsInfo.shaderType and similar evaluate to wrong results.
+ if (!m_item->window() && !force) {
+ m_item->polish();
+ return;
+ }
+
+ if (m_vertNeedsUpdate) {
+ m_vertNeedsUpdate = false;
+ m_common.updateShader(m_item, Key::VertexShader);
+ }
+
+ if (m_fragNeedsUpdate) {
+ m_fragNeedsUpdate = false;
+ m_common.updateShader(m_item, Key::FragmentShader);
+ }
}
void QQuickOpenGLShaderEffect::handleItemChange(QQuickItem::ItemChange change, const QQuickItem::ItemChangeData &value)
diff --git a/src/quick/items/qquickopenglshadereffect_p.h b/src/quick/items/qquickopenglshadereffect_p.h
index 0e54813443..bc60ba1e83 100644
--- a/src/quick/items/qquickopenglshadereffect_p.h
+++ b/src/quick/items/qquickopenglshadereffect_p.h
@@ -132,8 +132,8 @@ public:
void handleEvent(QEvent *);
void handleGeometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry);
QSGNode *handleUpdatePaintNode(QSGNode *, QQuickItem::UpdatePaintNodeData *);
- void handleComponentComplete();
void handleItemChange(QQuickItem::ItemChange change, const QQuickItem::ItemChangeData &value);
+ void maybeUpdateShaders(bool force = false);
private Q_SLOTS:
void updateGeometry();
@@ -169,6 +169,8 @@ private:
uint m_dirtyGeometry : 1;
uint m_customVertexShader : 1;
uint m_supportsAtlasTextures : 1;
+ uint m_vertNeedsUpdate : 1;
+ uint m_fragNeedsUpdate : 1;
};
QT_END_NAMESPACE
diff --git a/src/quick/items/qquickshadereffect.cpp b/src/quick/items/qquickshadereffect.cpp
index 4f1a9a28ec..f7c103a58f 100644
--- a/src/quick/items/qquickshadereffect.cpp
+++ b/src/quick/items/qquickshadereffect.cpp
@@ -39,6 +39,7 @@
#include <private/qquickshadereffect_p.h>
#include <private/qsgcontextplugin_p.h>
+#include <private/qquickitem_p.h>
#ifndef QT_NO_OPENGL
#include <private/qquickopenglshadereffect_p.h>
#endif
@@ -382,10 +383,18 @@ QT_BEGIN_NAMESPACE
\sa {Item Layers}
*/
+class QQuickShaderEffectPrivate : public QQuickItemPrivate
+{
+ Q_DECLARE_PUBLIC(QQuickShaderEffect)
+
+public:
+ void updatePolish() override;
+};
+
QSGContextFactoryInterface::Flags qsg_backend_flags();
QQuickShaderEffect::QQuickShaderEffect(QQuickItem *parent)
- : QQuickItem(parent),
+ : QQuickItem(*new QQuickShaderEffectPrivate, parent),
#ifndef QT_NO_OPENGL
m_glImpl(nullptr),
#endif
@@ -712,12 +721,12 @@ void QQuickShaderEffect::componentComplete()
{
#ifndef QT_NO_OPENGL
if (m_glImpl) {
- m_glImpl->handleComponentComplete();
+ m_glImpl->maybeUpdateShaders();
QQuickItem::componentComplete();
return;
}
#endif
- m_impl->handleComponentComplete();
+ m_impl->maybeUpdateShaders();
QQuickItem::componentComplete();
}
@@ -745,7 +754,19 @@ QString QQuickShaderEffect::parseLog() // for OpenGL-based autotests
if (m_glImpl)
return m_glImpl->parseLog();
#endif
- return QString();
+ return m_impl->parseLog();
+}
+
+void QQuickShaderEffectPrivate::updatePolish()
+{
+ Q_Q(QQuickShaderEffect);
+#ifndef QT_NO_OPENGL
+ if (q->m_glImpl) {
+ q->m_glImpl->maybeUpdateShaders();
+ return;
+ }
+#endif
+ q->m_impl->maybeUpdateShaders();
}
QT_END_NAMESPACE
diff --git a/src/quick/items/qquickshadereffect_p.h b/src/quick/items/qquickshadereffect_p.h
index 62d7e6fe5f..17b009039a 100644
--- a/src/quick/items/qquickshadereffect_p.h
+++ b/src/quick/items/qquickshadereffect_p.h
@@ -58,6 +58,7 @@ QT_BEGIN_NAMESPACE
class QQuickOpenGLShaderEffect;
class QQuickGenericShaderEffect;
+class QQuickShaderEffectPrivate;
class Q_QUICK_PRIVATE_EXPORT QQuickShaderEffect : public QQuickItem
{
@@ -134,6 +135,8 @@ private:
QQuickOpenGLShaderEffect *m_glImpl;
#endif
QQuickGenericShaderEffect *m_impl;
+
+ Q_DECLARE_PRIVATE(QQuickShaderEffect)
};
QT_END_NAMESPACE
diff --git a/src/quick/items/qquickwindow.cpp b/src/quick/items/qquickwindow.cpp
index 10b769b5b0..c3c886de35 100644
--- a/src/quick/items/qquickwindow.cpp
+++ b/src/quick/items/qquickwindow.cpp
@@ -293,7 +293,9 @@ void QQuickWindowPrivate::polishItems()
int recursionSafeguard = INT_MAX;
while (!itemsToPolish.isEmpty() && --recursionSafeguard > 0) {
QQuickItem *item = itemsToPolish.takeLast();
- QQuickItemPrivate::get(item)->polishScheduled = false;
+ QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(item);
+ itemPrivate->polishScheduled = false;
+ itemPrivate->updatePolish();
item->updatePolish();
}
@@ -4450,16 +4452,31 @@ qreal QQuickWindow::effectiveDevicePixelRatio() const
}
/*!
- Returns the current renderer interface if there is one. Otherwise null is returned.
+ \return the current renderer interface. The value is always valid and is never null.
+
+ \note This function can be called at any time after constructing the
+ QQuickWindow, even while isSceneGraphInitialized() is still false. However,
+ some renderer interface functions, in particular
+ QSGRendererInterface::getResource() will not be functional until the
+ scenegraph is up and running. Backend queries, like
+ QSGRendererInterface::graphicsApi() or QSGRendererInterface::shaderType(),
+ will always be functional on the other hand.
- \sa QSGRenderNode, QSGRendererInterface, isSceneGraphInitialized()
+ \sa QSGRenderNode, QSGRendererInterface
\since 5.8
*/
QSGRendererInterface *QQuickWindow::rendererInterface() const
{
Q_D(const QQuickWindow);
- return isSceneGraphInitialized() ? d->context->sceneGraphContext()->rendererInterface(d->context) : nullptr;
+
+ // no context validity check - it is essential to be able to return a
+ // renderer interface instance before scenegraphInitialized() is emitted
+ // (depending on the backend, that can happen way too late for some of the
+ // rif use cases, like examining the graphics api or shading language in
+ // use)
+
+ return d->context->sceneGraphContext()->rendererInterface(d->context);
}
/*!