aboutsummaryrefslogtreecommitdiffstats
path: root/src/quick/scenegraph
diff options
context:
space:
mode:
Diffstat (limited to 'src/quick/scenegraph')
-rw-r--r--src/quick/scenegraph/adaptations/software/qsgsoftwareadaptation.cpp5
-rw-r--r--src/quick/scenegraph/coreapi/qsgrendererinterface.cpp9
-rw-r--r--src/quick/scenegraph/qsgadaptationlayer.cpp26
-rw-r--r--src/quick/scenegraph/qsgadaptationlayer_p.h133
-rw-r--r--src/quick/scenegraph/qsgcontext.cpp26
-rw-r--r--src/quick/scenegraph/qsgcontext_p.h5
-rw-r--r--src/quick/scenegraph/qsgcontextplugin_p.h2
7 files changed, 203 insertions, 3 deletions
diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwareadaptation.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwareadaptation.cpp
index 05628ea69c..0e2f4f5382 100644
--- a/src/quick/scenegraph/adaptations/software/qsgsoftwareadaptation.cpp
+++ b/src/quick/scenegraph/adaptations/software/qsgsoftwareadaptation.cpp
@@ -65,7 +65,10 @@ QSGContext *QSGSoftwareAdaptation::create(const QString &) const
QSGContextFactoryInterface::Flags QSGSoftwareAdaptation::flags(const QString &) const
{
- return QSGContextFactoryInterface::SupportsShaderEffectV2;
+ // Claim we support adaptable shader effects, then return null for the
+ // shader effect node. The result is shader effects not being rendered,
+ // with the application working fine in all other respects.
+ return QSGContextFactoryInterface::SupportsShaderEffectNode;
}
QSGRenderLoop *QSGSoftwareAdaptation::createWindowManager()
diff --git a/src/quick/scenegraph/coreapi/qsgrendererinterface.cpp b/src/quick/scenegraph/coreapi/qsgrendererinterface.cpp
index 6a01fac212..b680dbe3d5 100644
--- a/src/quick/scenegraph/coreapi/qsgrendererinterface.cpp
+++ b/src/quick/scenegraph/coreapi/qsgrendererinterface.cpp
@@ -87,6 +87,11 @@ QSGRendererInterface::~QSGRendererInterface()
\fn QSGRenderNode::GraphicsAPI QSGRenderNode::graphicsAPI() const
Returns the graphics API that is in use by the Qt Quick scenegraph.
+
+ \note This function can be called on any thread. However, the renderer
+ interface's lifetime may be tied to the render thread and therefore calling
+ this function from other threads during the process of application shutdown
+ or QQuickWindow closing is likely to become invalid.
*/
/*!
@@ -98,6 +103,8 @@ QSGRendererInterface::~QSGRendererInterface()
pointer to an opaque handle that needs to be dereferenced first (for
example, \c{VkDevice dev = *static_cast<VkDevice *>(result)}). The latter
is necessary since such handles may have sizes different from a pointer.
+
+ \note This function must only be called on the render thread.
*/
void *QSGRendererInterface::getResource(Resource resource) const
{
@@ -109,6 +116,8 @@ void *QSGRendererInterface::getResource(Resource resource) const
Queries a graphics resource. \a resource is a backend-specific key. This
allows supporting any future resources that are not listed in the
Resource enum.
+
+ \note This function must only be called on the render thread.
*/
void *QSGRendererInterface::getResource(const char *resource) const
{
diff --git a/src/quick/scenegraph/qsgadaptationlayer.cpp b/src/quick/scenegraph/qsgadaptationlayer.cpp
index e8ef6befcd..b0259c50b0 100644
--- a/src/quick/scenegraph/qsgadaptationlayer.cpp
+++ b/src/quick/scenegraph/qsgadaptationlayer.cpp
@@ -519,4 +519,30 @@ void QSGNodeVisitorEx::visitChildren(QSGNode *node)
}
}
+#ifndef QT_NO_DEBUG_STREAM
+QDebug operator<<(QDebug debug, const QSGGuiThreadShaderEffectManager::ShaderInfo::InputParameter &p)
+{
+ debug << p.semanticName << p.semanticIndex;
+ return debug;
+}
+QDebug operator<<(QDebug debug, const QSGGuiThreadShaderEffectManager::ShaderInfo::Variable &v)
+{
+ debug << v.name;
+ switch (v.type) {
+ case QSGGuiThreadShaderEffectManager::ShaderInfo::Constant:
+ debug << "cvar" << "offset" << v.offset << "size" << v.size;
+ break;
+ case QSGGuiThreadShaderEffectManager::ShaderInfo::Sampler:
+ debug << "sampler" << "bindpoint" << v.bindPoint;
+ break;
+ case QSGGuiThreadShaderEffectManager::ShaderInfo::Texture:
+ debug << "texture" << "bindpoint" << v.bindPoint;
+ break;
+ default:
+ break;
+ }
+ return debug;
+}
+#endif
+
QT_END_NAMESPACE
diff --git a/src/quick/scenegraph/qsgadaptationlayer_p.h b/src/quick/scenegraph/qsgadaptationlayer_p.h
index 78bb07599f..5155cdd719 100644
--- a/src/quick/scenegraph/qsgadaptationlayer_p.h
+++ b/src/quick/scenegraph/qsgadaptationlayer_p.h
@@ -223,6 +223,139 @@ Q_SIGNALS:
void scheduledUpdateCompleted();
};
+class Q_QUICK_PRIVATE_EXPORT QSGGuiThreadShaderEffectManager : public QObject
+{
+ Q_OBJECT
+
+public:
+ // Enum values must match ShaderEffect.
+ enum ShaderType {
+ GLSL,
+ HLSL,
+ Metal
+ };
+ enum ShaderCompilationType {
+ RuntimeCompilation = 0x01,
+ OfflineCompilation = 0x02
+ };
+ enum ShaderSourceType {
+ ShaderSourceString = 0x01,
+ ShaderSourceFile = 0x02,
+ ShaderByteCode = 0x04
+ };
+ enum Status {
+ Compiled,
+ Uncompiled,
+ Error
+ };
+
+ virtual ShaderType shaderType() const = 0;
+ virtual int shaderCompilationType() const = 0;
+ virtual int shaderSourceType() const = 0;
+
+ virtual bool hasSeparateSamplerAndTextureObjects() const = 0;
+
+ virtual QString log() const = 0;
+ virtual Status status() const = 0;
+
+ struct ShaderInfo {
+ enum Type {
+ TypeVertex,
+ TypeFragment,
+ TypeOther
+ };
+ enum VariableType {
+ Constant, // cbuffer members or uniforms
+ Sampler,
+ Texture // for APIs with separate texture and sampler objects
+ };
+ struct InputParameter {
+ InputParameter() : semanticIndex(0) { }
+ // Semantics use the D3D keys (POSITION, TEXCOORD).
+ // Attribute name based APIs can map based on pre-defined names.
+ QByteArray semanticName;
+ int semanticIndex;
+ };
+ struct Variable {
+ Variable() : type(Constant), offset(0), size(0), bindPoint(0) { }
+ VariableType type;
+ QByteArray name;
+ uint offset; // for cbuffer members
+ uint size; // for cbuffer members
+ int bindPoint; // for textures and samplers; for register-based APIs
+ };
+
+ QByteArray blob; // source or bytecode
+ Type type;
+ QVector<InputParameter> inputParameters;
+ QVector<Variable> variables;
+ };
+
+ virtual bool reflect(const QByteArray &src, ShaderInfo *result) = 0;
+
+Q_SIGNALS:
+ void textureChanged();
+ void logAndStatusChanged();
+};
+
+#ifndef QT_NO_DEBUG_STREAM
+Q_QUICK_PRIVATE_EXPORT QDebug operator<<(QDebug debug, const QSGGuiThreadShaderEffectManager::ShaderInfo::InputParameter &p);
+Q_QUICK_PRIVATE_EXPORT QDebug operator<<(QDebug debug, const QSGGuiThreadShaderEffectManager::ShaderInfo::Variable &v);
+#endif
+
+class Q_QUICK_PRIVATE_EXPORT QSGShaderEffectNode : public QSGVisitableNode
+{
+public:
+ enum DirtyShaderFlag {
+ DirtyShaderVertex = 0x01,
+ DirtyShaderFragment = 0x02,
+ DirtyShaderConstant = 0x04,
+ DirtyShaderTexture = 0x08,
+ DirtyShaderGeometry = 0x10,
+ DirtyShaderMesh = 0x20
+ };
+ Q_DECLARE_FLAGS(DirtyShaderFlags, DirtyShaderFlag)
+
+ enum CullMode { // must match ShaderEffect
+ NoCulling,
+ BackFaceCulling,
+ FrontFaceCulling
+ };
+
+ struct VariableData {
+ enum SpecialType { None, Unused, SubRect, Opacity, Matrix, Source };
+
+ QVariant value;
+ SpecialType specialType;
+ };
+
+ struct ShaderData {
+ ShaderData() : valid(false) { }
+ bool valid;
+ QSGGuiThreadShaderEffectManager::ShaderInfo shaderInfo;
+ QVector<VariableData> varData;
+ };
+
+ struct SyncData {
+ DirtyShaderFlags dirty;
+ CullMode cullMode;
+ bool blending;
+ bool supportsAtlasTextures;
+ ShaderData *vertexShader;
+ ShaderData *fragmentShader;
+ };
+
+ // Each ShaderEffect item has one node (render thread) and one manager (gui thread).
+ QSGShaderEffectNode(QSGGuiThreadShaderEffectManager *) { }
+
+ virtual QRectF normalizedTextureSubRect() const = 0;
+ virtual void sync(SyncData *syncData) = 0;
+
+ void accept(QSGNodeVisitorEx *visitor) override { if (visitor->visit(this)) visitor->visitChildren(this); visitor->endVisit(this); }
+};
+
+Q_DECLARE_OPERATORS_FOR_FLAGS(QSGShaderEffectNode::DirtyShaderFlags)
+
class Q_QUICK_PRIVATE_EXPORT QSGGlyphNode : public QSGVisitableNode
{
public:
diff --git a/src/quick/scenegraph/qsgcontext.cpp b/src/quick/scenegraph/qsgcontext.cpp
index 0f0a7be3b2..27d0f01753 100644
--- a/src/quick/scenegraph/qsgcontext.cpp
+++ b/src/quick/scenegraph/qsgcontext.cpp
@@ -277,11 +277,29 @@ QSGRectangleNode *QSGContext::createRectangleNode(const QRectF &rect, const QCol
return node;
}
+/*!
+ Creates a new shader effect helper instance. This function is called on the
+ gui thread, unlike the others. This is necessary in order to provide
+ adaptable, backend-specific shader effect functionality to the gui thread too.
+ */
+QSGGuiThreadShaderEffectManager *QSGContext::createGuiThreadShaderEffectManager()
+{
+ return nullptr;
+}
/*!
- Creates a new animation driver.
+ Creates a new shader effect node. The default of returning nullptr is
+ valid as long as the backend does not claim SupportsShaderEffectNode or
+ ignoring ShaderEffect elements is acceptable.
*/
+QSGShaderEffectNode *QSGContext::createShaderEffectNode(QSGRenderContext *, QSGGuiThreadShaderEffectManager *)
+{
+ return nullptr;
+}
+/*!
+ Creates a new animation driver.
+ */
QAnimationDriver *QSGContext::createAnimationDriver(QObject *parent)
{
return new QSGAnimationDriver(parent);
@@ -296,6 +314,12 @@ QSize QSGContext::minimumFBOSize() const
return QSize(1, 1);
}
+/*!
+ Returns a pointer to the (presumably) global renderer interface.
+
+ \note This function may be called on the gui thread in order to get access
+ to QSGRendererInterface::graphicsAPI().
+ */
QSGRendererInterface *QSGContext::rendererInterface(QSGRenderContext *renderContext)
{
Q_UNUSED(renderContext);
diff --git a/src/quick/scenegraph/qsgcontext_p.h b/src/quick/scenegraph/qsgcontext_p.h
index 19a8636f19..2139377ebb 100644
--- a/src/quick/scenegraph/qsgcontext_p.h
+++ b/src/quick/scenegraph/qsgcontext_p.h
@@ -83,6 +83,8 @@ class QSGDistanceFieldGlyphCacheManager;
class QSGContext;
class QQuickPaintedItem;
class QSGRendererInterface;
+class QSGShaderEffectNode;
+class QSGGuiThreadShaderEffectManager;
Q_DECLARE_LOGGING_CATEGORY(QSG_LOG_TIME_RENDERLOOP)
Q_DECLARE_LOGGING_CATEGORY(QSG_LOG_TIME_COMPILATION)
@@ -166,6 +168,9 @@ public:
virtual QSGGlyphNode *createGlyphNode(QSGRenderContext *rc, bool preferNativeGlyphNode) = 0;
virtual QSGNinePatchNode *createNinePatchNode() = 0;
virtual QSGLayer *createLayer(QSGRenderContext *renderContext) = 0;
+ virtual QSGGuiThreadShaderEffectManager *createGuiThreadShaderEffectManager();
+ virtual QSGShaderEffectNode *createShaderEffectNode(QSGRenderContext *renderContext,
+ QSGGuiThreadShaderEffectManager *mgr);
virtual QAnimationDriver *createAnimationDriver(QObject *parent);
virtual QSize minimumFBOSize() const;
diff --git a/src/quick/scenegraph/qsgcontextplugin_p.h b/src/quick/scenegraph/qsgcontextplugin_p.h
index 779dca62fc..08c3d21408 100644
--- a/src/quick/scenegraph/qsgcontextplugin_p.h
+++ b/src/quick/scenegraph/qsgcontextplugin_p.h
@@ -65,7 +65,7 @@ class QSGRenderLoop;
struct Q_QUICK_PRIVATE_EXPORT QSGContextFactoryInterface : public QFactoryInterface
{
enum Flag {
- SupportsShaderEffectV2 = 0x01
+ SupportsShaderEffectNode = 0x01
};
Q_DECLARE_FLAGS(Flags, Flag)