aboutsummaryrefslogtreecommitdiffstats
path: root/src/quick/items
diff options
context:
space:
mode:
authorLaszlo Agocs <laszlo.agocs@theqtcompany.com>2016-04-28 15:49:26 +0200
committerLaszlo Agocs <laszlo.agocs@theqtcompany.com>2016-04-29 09:36:43 +0000
commit3169744ab415268a9b6ff544d1bd49031ef3c08a (patch)
tree18362e5a8dd62ab940e82a9f055be50c75432866 /src/quick/items
parentcb1033fd603a438041a16ba55547d77133ad1e79 (diff)
D3D12: Fix 'ShaderEffect in a ShaderEffectSource as property value'
Import (and clean up) the dropshadow from the shadereffects example. This is very useful since it tests a lot more paths and cases than the wobble. To overcome the issue of not having some of functionality available before the item is added to a window, make QQuickGenericShaderEffect smarter and enhance the documentation. The handling of vertical mirroring is revised. The GLSL and HLSL version of the dropshadow shaders produce correct, identical output now. Change-Id: I94800997bfba781140d80720eb6f340cda480747 Reviewed-by: Andy Nichols <andy.nichols@qt.io>
Diffstat (limited to 'src/quick/items')
-rw-r--r--src/quick/items/qquickgenericshadereffect.cpp48
-rw-r--r--src/quick/items/qquickgenericshadereffect_p.h2
-rw-r--r--src/quick/items/qquickshadereffect.cpp67
-rw-r--r--src/quick/items/qquickshadereffect_p.h4
4 files changed, 96 insertions, 25 deletions
diff --git a/src/quick/items/qquickgenericshadereffect.cpp b/src/quick/items/qquickgenericshadereffect.cpp
index ae34a65a2f..49ed25f799 100644
--- a/src/quick/items/qquickgenericshadereffect.cpp
+++ b/src/quick/items/qquickgenericshadereffect.cpp
@@ -61,6 +61,7 @@ QQuickGenericShaderEffect::QQuickGenericShaderEffect(QQuickShaderEffect *item, Q
, m_mgr(nullptr)
, m_dirty(0)
{
+ connect(m_item, SIGNAL(windowChanged(QQuickWindow*)), this, SLOT(itemWindowChanged(QQuickWindow*)));
}
QQuickGenericShaderEffect::~QQuickGenericShaderEffect()
@@ -76,7 +77,11 @@ QQuickGenericShaderEffect::~QQuickGenericShaderEffect()
void QQuickGenericShaderEffect::setFragmentShader(const QByteArray &src)
{
- if (m_fragShader.constData() == src.constData())
+ // Compare the actual values since they are often just filenames.
+ // Optimizing by comparing constData() is a bad idea since seemingly static
+ // strings in QML may in fact have different addresses when a binding
+ // triggers assigning the "same" value to the property.
+ if (m_fragShader == src)
return;
m_fragShader = src;
@@ -91,7 +96,7 @@ void QQuickGenericShaderEffect::setFragmentShader(const QByteArray &src)
void QQuickGenericShaderEffect::setVertexShader(const QByteArray &src)
{
- if (m_vertShader.constData() == src.constData())
+ if (m_vertShader == src)
return;
m_vertShader = src;
@@ -192,7 +197,7 @@ QQuickShaderEffect::Status QQuickGenericShaderEffect::status() const
{
QSGGuiThreadShaderEffectManager *mgr = shaderEffectManager();
if (!mgr)
- return QQuickShaderEffect::Error;
+ return QQuickShaderEffect::Uncompiled;
return QQuickShaderEffect::Status(mgr->status());
}
@@ -201,7 +206,7 @@ QQuickShaderEffect::ShaderType QQuickGenericShaderEffect::shaderType() const
{
QSGGuiThreadShaderEffectManager *mgr = shaderEffectManager();
if (!mgr)
- return QQuickShaderEffect::HLSL;
+ return QQuickShaderEffect::ShaderType(0);
return QQuickShaderEffect::ShaderType(mgr->shaderType());
}
@@ -210,7 +215,7 @@ QQuickShaderEffect::ShaderCompilationType QQuickGenericShaderEffect::shaderCompi
{
QSGGuiThreadShaderEffectManager *mgr = shaderEffectManager();
if (!mgr)
- return QQuickShaderEffect::OfflineCompilation;
+ return QQuickShaderEffect::ShaderCompilationType(0);
return QQuickShaderEffect::ShaderCompilationType(mgr->shaderCompilationType());
}
@@ -219,7 +224,7 @@ QQuickShaderEffect::ShaderSourceType QQuickGenericShaderEffect::shaderSourceType
{
QSGGuiThreadShaderEffectManager *mgr = shaderEffectManager();
if (!mgr)
- return QQuickShaderEffect::ShaderByteCode;
+ return QQuickShaderEffect::ShaderSourceType(0);
return QQuickShaderEffect::ShaderSourceType(mgr->shaderSourceType());
}
@@ -348,20 +353,41 @@ QSGGuiThreadShaderEffectManager *QQuickGenericShaderEffect::shaderEffectManager(
if (w && w->isSceneGraphInitialized()) {
m_mgr = QQuickWindowPrivate::get(w)->context->sceneGraphContext()->createGuiThreadShaderEffectManager();
if (m_mgr) {
- QObject::connect(m_mgr, SIGNAL(logAndStatusChanged()), m_item, SIGNAL(logChanged()));
- QObject::connect(m_mgr, SIGNAL(logAndStatusChanged()), m_item, SIGNAL(statusChanged()));
- QObject::connect(m_mgr, SIGNAL(textureChanged()), this, SLOT(markGeometryDirtyAndUpdateIfSupportsAtlas()));
+ connect(m_mgr, SIGNAL(logAndStatusChanged()), m_item, SIGNAL(logChanged()));
+ connect(m_mgr, SIGNAL(logAndStatusChanged()), m_item, SIGNAL(statusChanged()));
+ connect(m_mgr, SIGNAL(textureChanged()), this, SLOT(markGeometryDirtyAndUpdateIfSupportsAtlas()));
}
} else if (!w) {
- qWarning("ShaderEffect: Backend specifics cannot be queried until the item has a window");
+ // Wait until itemWindowChanged() gets called. Return null for now.
} else {
- qWarning("ShaderEffect: Backend specifics cannot be queried until the scenegraph has initialized");
+ // 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();
+ emit m_item->shaderTypeChanged();
+ emit m_item->shaderCompilationTypeChanged();
+ emit m_item->shaderSourceTypeChanged();
+}
+
void QQuickGenericShaderEffect::disconnectSignals(Shader shaderType)
{
for (auto &sm : m_signalMappers[shaderType]) {
diff --git a/src/quick/items/qquickgenericshadereffect_p.h b/src/quick/items/qquickgenericshadereffect_p.h
index 5f6652ec32..2af7d1156a 100644
--- a/src/quick/items/qquickgenericshadereffect_p.h
+++ b/src/quick/items/qquickgenericshadereffect_p.h
@@ -105,6 +105,8 @@ private slots:
void sourceDestroyed(QObject *object);
void markGeometryDirtyAndUpdate();
void markGeometryDirtyAndUpdateIfSupportsAtlas();
+ void itemWindowChanged(QQuickWindow *w);
+ void backendChanged();
private:
QSGGuiThreadShaderEffectManager *shaderEffectManager() const;
diff --git a/src/quick/items/qquickshadereffect.cpp b/src/quick/items/qquickshadereffect.cpp
index 36fc7ef3c8..560c49fb7c 100644
--- a/src/quick/items/qquickshadereffect.cpp
+++ b/src/quick/items/qquickshadereffect.cpp
@@ -321,6 +321,12 @@ QT_BEGIN_NAMESPACE
\endcode
\endtable
+ \note With OpenGL the \c y coordinate runs from bottom to top whereas with
+ Direct 3D it goes top to bottom. For shader effect sources Qt Quick hides
+ the difference by treating QtQuick::ShaderEffectSource::textureMirroring as
+ appropriate, meaning texture coordinates in HLSL version of the shaders
+ will not need any adjustments compared to the equivalent GLSL code.
+
\section1 ShaderEffect and Item Layers
The ShaderEffect type can be combined with \l {Item Layers} {layered items}.
@@ -644,12 +650,23 @@ QQuickShaderEffect::Status QQuickShaderEffect::status() const
}
/*!
- \qmlproperty QtQuick::ShaderEffect::ShaderType QtQuick::ShaderEffect::shaderType
+ \qmlproperty enumeration QtQuick::ShaderEffect::shaderType
This property contains the shading language supported by the current Qt
Quick backend the application is using.
- With OpenGL the value is GLSL.
+ \list
+ \li ShaderEffect.UnknownShadingLanguage - Not yet known due to no window and scenegraph associated
+ \li ShaderEffect.GLSL - GLSL or GLSL ES
+ \li ShaderEffect.HLSL - HLSL
+ \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
+ ShaderEffect.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
@@ -667,14 +684,26 @@ QQuickShaderEffect::ShaderType QQuickShaderEffect::shaderType() const
}
/*!
- \qmlproperty QtQuick::ShaderEffect::ShaderCompilationType QtQuick::ShaderEffect::shaderCompilationType
+ \qmlproperty enumeration QtQuick::ShaderEffect::shaderCompilationType
This property contains a bitmask of the shader compilation approaches
supported by the current Qt Quick backend the application is using.
- With OpenGL the value is RuntimeCompilation, which corresponds to the
- traditional way of using ShaderEffect. Non-OpenGL backends are expected to
- focus more on OfflineCompilation, however.
+ \list
+ \li ShaderEffect.RuntimeCompilation
+ \li ShaderEffect.OfflineCompilation
+ \endlist
+
+ With OpenGL the value is ShaderEffect.RuntimeCompilation, which corresponds
+ to the traditional way of using ShaderEffect. Non-OpenGL backends are
+ expected to focus more on ShaderEffect.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.
\since 5.8
\since QtQuick 2.8
@@ -692,16 +721,30 @@ QQuickShaderEffect::ShaderCompilationType QQuickShaderEffect::shaderCompilationT
}
/*!
- \qmlproperty QtQuick::ShaderEffect::ShaderSourceType QtQuick::ShaderEffect::shaderSourceType
+ \qmlproperty enumeration QtQuick::ShaderEffect::shaderSourceType
This property contains a bitmask of the supported ways of providing shader
sources.
- With OpenGL the value is ShaderSourceString, which corresponds to the
- traditional way of inlining GLSL source code into QML. Other, non-OpenGL Qt
- Quick backends may however decide not to support inlined shader sources, or
- even shader sources at all. In this case shaders are expected to be
- pre-compiled into formats like SPIR-V or D3D shader bytecode.
+ \list
+ \li ShaderEffect.ShaderSourceString
+ \li ShaderEffect.ShaderSourceFile
+ \li ShaderEffect.ShaderByteCode
+ \endlist
+
+ With OpenGL the value is ShaderEffect.ShaderSourceString, which corresponds
+ to the traditional way of inlining GLSL source code into QML. Other,
+ non-OpenGL Qt Quick backends may however decide not to support inlined
+ shader sources, or even shader sources at all. In this case shaders are
+ expected to be pre-compiled into formats like SPIR-V or D3D shader
+ 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.
\since 5.8
\since QtQuick 2.8
diff --git a/src/quick/items/qquickshadereffect_p.h b/src/quick/items/qquickshadereffect_p.h
index 390703350f..0410514c36 100644
--- a/src/quick/items/qquickshadereffect_p.h
+++ b/src/quick/items/qquickshadereffect_p.h
@@ -90,9 +90,9 @@ public:
Q_ENUM(Status)
enum ShaderType {
+ UnknownShadingLanguage,
GLSL,
- HLSL,
- Metal
+ HLSL
};
Q_ENUM(ShaderType)