aboutsummaryrefslogtreecommitdiffstats
path: root/src/quick
diff options
context:
space:
mode:
authorLaszlo Agocs <laszlo.agocs@theqtcompany.com>2016-04-11 16:06:39 +0200
committerLaszlo Agocs <laszlo.agocs@theqtcompany.com>2016-04-13 09:22:18 +0000
commit96a7afec18542396f8e9a0b0f75d219a08725b3f (patch)
treeba2ed094f071214a93afea29dd100e6669641fbb /src/quick
parente188a3d864a5310bf18c3ad759a12560013deb64 (diff)
Route ShaderEffect through the old GL impl
Register the common QQuickShaderEffect class as ShaderEffect to QML. In case of GL this will route to QQuickOpenGLShaderEffect. For others the default no-op implementation is used (at least for now). Later this new implementation will route to a backend-specific scenegraph node via the adaptation layer. This also means that QQuickOpenGLShaderEffect is no longer a QQuickItem and QQuickShaderEffect must handle everything item-related and forward. Change-Id: I1ff4b674253543a04978a69f4a3b67f3a44dd983 Reviewed-by: Andy Nichols <andy.nichols@theqtcompany.com>
Diffstat (limited to 'src/quick')
-rw-r--r--src/quick/items/qquickitemsmodule.cpp9
-rw-r--r--src/quick/items/qquickopenglshadereffect.cpp81
-rw-r--r--src/quick/items/qquickopenglshadereffect_p.h56
-rw-r--r--src/quick/items/qquickopenglshadereffectnode.cpp4
-rw-r--r--src/quick/items/qquickshadereffect.cpp137
-rw-r--r--src/quick/items/qquickshadereffect_p.h20
-rw-r--r--src/quick/scenegraph/adaptations/d3d12/qsgd3d12adaptation.cpp5
-rw-r--r--src/quick/scenegraph/adaptations/d3d12/qsgd3d12adaptation_p.h1
-rw-r--r--src/quick/scenegraph/adaptations/software/qsgsoftwareadaptation.cpp5
-rw-r--r--src/quick/scenegraph/adaptations/software/qsgsoftwareadaptation_p.h1
-rw-r--r--src/quick/scenegraph/qsgcontextplugin.cpp21
-rw-r--r--src/quick/scenegraph/qsgcontextplugin_p.h9
12 files changed, 257 insertions, 92 deletions
diff --git a/src/quick/items/qquickitemsmodule.cpp b/src/quick/items/qquickitemsmodule.cpp
index 575228cffa..a2323248c7 100644
--- a/src/quick/items/qquickitemsmodule.cpp
+++ b/src/quick/items/qquickitemsmodule.cpp
@@ -75,12 +75,12 @@
#include <QtQuick/private/qquickcontext2d_p.h>
#ifndef QT_NO_OPENGL
# include "qquickitemgrabresult.h"
-# include <private/qquickopenglshadereffect_p.h>
# include "qquicksprite_p.h"
# include "qquickspritesequence_p.h"
# include "qquickanimatedsprite_p.h"
# include "qquickopenglinfo_p.h"
#endif
+#include "qquickshadereffect_p.h"
#include "qquickshadereffectmesh_p.h"
#include "qquickdrag_p.h"
#include "qquickdroparea_p.h"
@@ -214,9 +214,7 @@ static void qt_quickitems_defineModule(const char *uri, int major, int minor)
qmlRegisterType<QQuickShaderEffectSource>("QtQuick", 2, 0, "ShaderEffectSource");
qmlRegisterUncreatableType<QQuickShaderEffectMesh>("QtQuick", 2, 0, "ShaderEffectMesh", QQuickShaderEffectMesh::tr("Cannot create instance of abstract class ShaderEffectMesh."));
qmlRegisterType<QQuickGridMesh>("QtQuick", 2, 0, "GridMesh");
-#ifndef QT_NO_OPENGL
- qmlRegisterType<QQuickOpenGLShaderEffect>("QtQuick", 2, 0, "ShaderEffect");
-#endif
+ qmlRegisterType<QQuickShaderEffect>("QtQuick", 2, 0, "ShaderEffect");
qmlRegisterUncreatableType<QQuickPaintedItem>("QtQuick", 2, 0, "PaintedItem", QQuickPaintedItem::tr("Cannot create instance of abstract class PaintedItem"));
@@ -267,8 +265,9 @@ static void qt_quickitems_defineModule(const char *uri, int major, int minor)
qmlRegisterType<QQuickItem, 2>(uri, 2, 4, "Item");
qmlRegisterType<QQuickListView, 2>(uri, 2, 4, "ListView");
qmlRegisterType<QQuickMouseArea, 1>(uri, 2, 4, "MouseArea");
+ qmlRegisterType<QQuickShaderEffect, 1>(uri, 2, 4, "ShaderEffect");
+
#ifndef QT_NO_OPENGL
- qmlRegisterType<QQuickOpenGLShaderEffect, 1>(uri, 2, 4, "ShaderEffect");
qmlRegisterUncreatableType<QQuickOpenGLInfo>(uri, 2, 4,"OpenGLInfo", QQuickOpenGLInfo::tr("OpenGLInfo is only available via attached properties"));
#endif
qmlRegisterType<QQuickPinchArea, 1>(uri, 2, 5,"PinchArea");
diff --git a/src/quick/items/qquickopenglshadereffect.cpp b/src/quick/items/qquickopenglshadereffect.cpp
index 8919afd066..354d7705e3 100644
--- a/src/quick/items/qquickopenglshadereffect.cpp
+++ b/src/quick/items/qquickopenglshadereffect.cpp
@@ -523,12 +523,13 @@ void QQuickOpenGLShaderEffectCommon::propertyChanged(QQuickItem *item, int mappe
}
}
-QQuickOpenGLShaderEffect::QQuickOpenGLShaderEffect(QQuickItem *parent)
- : QQuickItem(parent)
+QQuickOpenGLShaderEffect::QQuickOpenGLShaderEffect(QQuickShaderEffect *item, QObject *parent)
+ : QObject(parent)
+ , m_item(item)
, m_meshResolution(1, 1)
, m_mesh(0)
- , m_cullMode(NoCulling)
- , m_status(Uncompiled)
+ , m_cullMode(QQuickShaderEffect::NoCulling)
+ , m_status(QQuickShaderEffect::Uncompiled)
, m_blending(true)
, m_dirtyUniforms(true)
, m_dirtyUniformValues(true)
@@ -540,13 +541,12 @@ QQuickOpenGLShaderEffect::QQuickOpenGLShaderEffect(QQuickItem *parent)
, m_customVertexShader(false)
, m_supportsAtlasTextures(false)
{
- setFlag(QQuickItem::ItemHasContents);
}
QQuickOpenGLShaderEffect::~QQuickOpenGLShaderEffect()
{
for (int shaderType = 0; shaderType < Key::ShaderTypeCount; ++shaderType)
- m_common.disconnectPropertySignals(this, Key::ShaderType(shaderType));
+ m_common.disconnectPropertySignals(m_item, Key::ShaderType(shaderType));
}
void QQuickOpenGLShaderEffect::setFragmentShader(const QByteArray &code)
@@ -557,12 +557,12 @@ void QQuickOpenGLShaderEffect::setFragmentShader(const QByteArray &code)
m_dirtyProgram = true;
m_dirtyParseLog = true;
- if (isComponentComplete())
- m_common.updateShader(this, Key::FragmentShader);
+ if (m_item->isComponentComplete())
+ m_common.updateShader(m_item, Key::FragmentShader);
- update();
- if (m_status != Uncompiled) {
- m_status = Uncompiled;
+ m_item->update();
+ if (m_status != QQuickShaderEffect::Uncompiled) {
+ m_status = QQuickShaderEffect::Uncompiled;
emit statusChanged();
}
emit fragmentShaderChanged();
@@ -577,12 +577,12 @@ void QQuickOpenGLShaderEffect::setVertexShader(const QByteArray &code)
m_dirtyParseLog = true;
m_customVertexShader = true;
- if (isComponentComplete())
- m_common.updateShader(this, Key::VertexShader);
+ if (m_item->isComponentComplete())
+ m_common.updateShader(m_item, Key::VertexShader);
- update();
- if (m_status != Uncompiled) {
- m_status = Uncompiled;
+ m_item->update();
+ if (m_status != QQuickShaderEffect::Uncompiled) {
+ m_status = QQuickShaderEffect::Uncompiled;
emit statusChanged();
}
emit vertexShaderChanged();
@@ -594,7 +594,7 @@ void QQuickOpenGLShaderEffect::setBlending(bool enable)
return;
m_blending = enable;
- update();
+ m_item->update();
emit blendingChanged();
}
@@ -637,16 +637,16 @@ void QQuickOpenGLShaderEffect::setMesh(const QVariant &mesh)
m_dirtyMesh = true;
m_dirtyParseLog = true;
- update();
+ m_item->update();
emit meshChanged();
}
-void QQuickOpenGLShaderEffect::setCullMode(CullMode face)
+void QQuickOpenGLShaderEffect::setCullMode(QQuickShaderEffect::CullMode face)
{
if (face == m_cullMode)
return;
m_cullMode = face;
- update();
+ m_item->update();
emit cullModeChanged();
}
@@ -668,7 +668,7 @@ QString QQuickOpenGLShaderEffect::parseLog()
return m_common.parseLog;
}
-bool QQuickOpenGLShaderEffect::event(QEvent *event)
+void QQuickOpenGLShaderEffect::handleEvent(QEvent *event)
{
if (event->type() == QEvent::DynamicPropertyChange) {
QDynamicPropertyChangeEvent *e = static_cast<QDynamicPropertyChangeEvent *>(event);
@@ -676,21 +676,20 @@ bool QQuickOpenGLShaderEffect::event(QEvent *event)
for (int i = 0; i < m_common.uniformData[shaderType].size(); ++i) {
if (m_common.uniformData[shaderType].at(i).name == e->propertyName()) {
bool textureProviderChanged;
- m_common.propertyChanged(this, (shaderType << 16) | i, &textureProviderChanged);
+ m_common.propertyChanged(m_item, (shaderType << 16) | i, &textureProviderChanged);
m_dirtyTextureProviders |= textureProviderChanged;
m_dirtyUniformValues = true;
- update();
+ m_item->update();
}
}
}
}
- return QQuickItem::event(event);
}
void QQuickOpenGLShaderEffect::updateGeometry()
{
m_dirtyGeometry = true;
- update();
+ m_item->update();
}
void QQuickOpenGLShaderEffect::updateGeometryIfAtlased()
@@ -702,38 +701,36 @@ void QQuickOpenGLShaderEffect::updateGeometryIfAtlased()
void QQuickOpenGLShaderEffect::updateLogAndStatus(const QString &log, int status)
{
m_log = parseLog() + log;
- m_status = Status(status);
+ m_status = QQuickShaderEffect::Status(status);
emit logChanged();
emit statusChanged();
}
-void QQuickOpenGLShaderEffect::sourceDestroyed(QObject *object)
+void QQuickOpenGLShaderEffect::handleSourceDestroyed(QObject *object)
{
m_common.sourceDestroyed(object);
}
-
-void QQuickOpenGLShaderEffect::propertyChanged(int mappedId)
+void QQuickOpenGLShaderEffect::handlePropertyChanged(int mappedId)
{
bool textureProviderChanged;
- m_common.propertyChanged(this, mappedId, &textureProviderChanged);
+ m_common.propertyChanged(m_item, mappedId, &textureProviderChanged);
m_dirtyTextureProviders |= textureProviderChanged;
m_dirtyUniformValues = true;
- update();
+ m_item->update();
}
-void QQuickOpenGLShaderEffect::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
+void QQuickOpenGLShaderEffect::handleGeometryChanged(const QRectF &, const QRectF &)
{
m_dirtyGeometry = true;
- QQuickItem::geometryChanged(newGeometry, oldGeometry);
}
-QSGNode *QQuickOpenGLShaderEffect::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *)
+QSGNode *QQuickOpenGLShaderEffect::handleUpdatePaintNode(QSGNode *oldNode, QQuickItem::UpdatePaintNodeData *)
{
QQuickOpenGLShaderEffectNode *node = static_cast<QQuickOpenGLShaderEffectNode *>(oldNode);
// In the case of zero-size or a bad vertex shader, don't try to create a node...
- if (m_common.attributes.isEmpty() || width() <= 0 || height() <= 0) {
+ if (m_common.attributes.isEmpty() || m_item->width() <= 0 || m_item->height() <= 0) {
if (node)
delete node;
return 0;
@@ -821,7 +818,7 @@ QSGNode *QQuickOpenGLShaderEffect::updatePaintNode(QSGNode *oldNode, UpdatePaint
if (m_dirtyGeometry) {
node->setFlag(QSGNode::OwnsGeometry, false);
QSGGeometry *geometry = node->geometry();
- QRectF rect(0, 0, width(), height());
+ QRectF rect(0, 0, m_item->width(), m_item->height());
QQuickShaderEffectMesh *mesh = m_mesh ? m_mesh : &m_defaultMesh;
geometry = mesh->updateGeometry(geometry, m_common.attributes, srcRect, rect);
@@ -831,7 +828,7 @@ QSGNode *QQuickOpenGLShaderEffect::updatePaintNode(QSGNode *oldNode, UpdatePaint
m_log = parseLog();
m_log += QLatin1String("*** Mesh ***\n");
m_log += log;
- m_status = Error;
+ m_status = QQuickShaderEffect::Error;
emit logChanged();
emit statusChanged();
}
@@ -848,18 +845,16 @@ QSGNode *QQuickOpenGLShaderEffect::updatePaintNode(QSGNode *oldNode, UpdatePaint
return node;
}
-void QQuickOpenGLShaderEffect::componentComplete()
+void QQuickOpenGLShaderEffect::handleComponentComplete()
{
- m_common.updateShader(this, Key::VertexShader);
- m_common.updateShader(this, Key::FragmentShader);
- QQuickItem::componentComplete();
+ m_common.updateShader(m_item, Key::VertexShader);
+ m_common.updateShader(m_item, Key::FragmentShader);
}
-void QQuickOpenGLShaderEffect::itemChange(ItemChange change, const ItemChangeData &value)
+void QQuickOpenGLShaderEffect::handleItemChange(QQuickItem::ItemChange change, const QQuickItem::ItemChangeData &value)
{
if (change == QQuickItem::ItemSceneChange)
m_common.updateWindow(value.window);
- QQuickItem::itemChange(change, value);
}
QT_END_NAMESPACE
diff --git a/src/quick/items/qquickopenglshadereffect_p.h b/src/quick/items/qquickopenglshadereffect_p.h
index 1b72367e9f..80e1e5ee8e 100644
--- a/src/quick/items/qquickopenglshadereffect_p.h
+++ b/src/quick/items/qquickopenglshadereffect_p.h
@@ -96,36 +96,12 @@ struct Q_QUICK_PRIVATE_EXPORT QQuickOpenGLShaderEffectCommon
};
-class Q_QUICK_PRIVATE_EXPORT QQuickOpenGLShaderEffect : public QQuickItem
+class Q_QUICK_PRIVATE_EXPORT QQuickOpenGLShaderEffect : public QObject
{
Q_OBJECT
- Q_PROPERTY(QByteArray fragmentShader READ fragmentShader WRITE setFragmentShader NOTIFY fragmentShaderChanged)
- Q_PROPERTY(QByteArray vertexShader READ vertexShader WRITE setVertexShader NOTIFY vertexShaderChanged)
- Q_PROPERTY(bool blending READ blending WRITE setBlending NOTIFY blendingChanged)
- Q_PROPERTY(QVariant mesh READ mesh WRITE setMesh NOTIFY meshChanged)
- Q_PROPERTY(CullMode cullMode READ cullMode WRITE setCullMode NOTIFY cullModeChanged)
- Q_PROPERTY(QString log READ log NOTIFY logChanged)
- Q_PROPERTY(Status status READ status NOTIFY statusChanged)
- Q_PROPERTY(bool supportsAtlasTextures READ supportsAtlasTextures WRITE setSupportsAtlasTextures NOTIFY supportsAtlasTexturesChanged REVISION 1)
public:
- enum CullMode
- {
- NoCulling = QQuickShaderEffect::NoCulling,
- BackFaceCulling = QQuickShaderEffect::BackFaceCulling,
- FrontFaceCulling = QQuickShaderEffect::FrontFaceCulling
- };
- Q_ENUM(CullMode)
-
- enum Status
- {
- Compiled,
- Uncompiled,
- Error
- };
- Q_ENUM(Status)
-
- QQuickOpenGLShaderEffect(QQuickItem *parent = 0);
+ QQuickOpenGLShaderEffect(QQuickShaderEffect *item, QObject *parent = 0);
~QQuickOpenGLShaderEffect();
QByteArray fragmentShader() const { return m_common.source.sourceCode[Key::FragmentShader]; }
@@ -140,19 +116,17 @@ public:
QVariant mesh() const;
void setMesh(const QVariant &mesh);
- CullMode cullMode() const { return m_cullMode; }
- void setCullMode(CullMode face);
+ QQuickShaderEffect::CullMode cullMode() const { return m_cullMode; }
+ void setCullMode(QQuickShaderEffect::CullMode face);
QString log() const { return m_log; }
- Status status() const { return m_status; }
+ QQuickShaderEffect::Status status() const { return m_status; }
bool supportsAtlasTextures() const { return m_supportsAtlasTextures; }
void setSupportsAtlasTextures(bool supports);
QString parseLog();
- bool event(QEvent *) Q_DECL_OVERRIDE;
-
Q_SIGNALS:
void fragmentShaderChanged();
void vertexShaderChanged();
@@ -164,17 +138,18 @@ Q_SIGNALS:
void supportsAtlasTexturesChanged();
protected:
- void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) Q_DECL_OVERRIDE;
- QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *) Q_DECL_OVERRIDE;
- void componentComplete() Q_DECL_OVERRIDE;
- void itemChange(ItemChange change, const ItemChangeData &value) Q_DECL_OVERRIDE;
+ 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 handleSourceDestroyed(QObject *object);
+ void handlePropertyChanged(int mappedId);
private Q_SLOTS:
void updateGeometry();
void updateGeometryIfAtlased();
void updateLogAndStatus(const QString &log, int status);
- void sourceDestroyed(QObject *object);
- void propertyChanged(int mappedId);
private:
friend class QQuickCustomMaterialShader;
@@ -183,12 +158,13 @@ private:
typedef QQuickOpenGLShaderEffectMaterialKey Key;
typedef QQuickOpenGLShaderEffectMaterial::UniformData UniformData;
+ QQuickShaderEffect *m_item;
QSize m_meshResolution;
QQuickShaderEffectMesh *m_mesh;
QQuickGridMesh m_defaultMesh;
- CullMode m_cullMode;
+ QQuickShaderEffect::CullMode m_cullMode;
QString m_log;
- Status m_status;
+ QQuickShaderEffect::Status m_status;
QQuickOpenGLShaderEffectCommon m_common;
@@ -202,6 +178,8 @@ private:
uint m_dirtyGeometry : 1;
uint m_customVertexShader : 1;
uint m_supportsAtlasTextures : 1;
+
+ friend class QQuickShaderEffect;
};
QT_END_NAMESPACE
diff --git a/src/quick/items/qquickopenglshadereffectnode.cpp b/src/quick/items/qquickopenglshadereffectnode.cpp
index 4535aec332..aa8943aad7 100644
--- a/src/quick/items/qquickopenglshadereffectnode.cpp
+++ b/src/quick/items/qquickopenglshadereffectnode.cpp
@@ -111,8 +111,8 @@ void QQuickCustomMaterialShader::updateState(const RenderState &state, QSGMateri
QQuickOpenGLShaderEffectMaterial *material = static_cast<QQuickOpenGLShaderEffectMaterial *>(newEffect);
if (!material->m_emittedLogChanged && material->m_node) {
material->m_emittedLogChanged = true;
- emit material->m_node->logAndStatusChanged(m_log, m_compiled ? QQuickOpenGLShaderEffect::Compiled
- : QQuickOpenGLShaderEffect::Error);
+ emit material->m_node->logAndStatusChanged(m_log, m_compiled ? QQuickShaderEffect::Compiled
+ : QQuickShaderEffect::Error);
}
int textureProviderIndex = 0;
diff --git a/src/quick/items/qquickshadereffect.cpp b/src/quick/items/qquickshadereffect.cpp
index e604e80d96..71f5e56e32 100644
--- a/src/quick/items/qquickshadereffect.cpp
+++ b/src/quick/items/qquickshadereffect.cpp
@@ -38,6 +38,10 @@
****************************************************************************/
#include <private/qquickshadereffect_p.h>
+#include <private/qsgcontextplugin_p.h>
+#ifndef QT_NO_OPENGL
+#include <private/qquickopenglshadereffect_p.h>
+#endif
QT_BEGIN_NAMESPACE
@@ -189,10 +193,19 @@ QT_BEGIN_NAMESPACE
\sa {Item Layers}
*/
+QSGContextFactoryInterface::Flags qsg_backend_flags();
+
QQuickShaderEffect::QQuickShaderEffect(QQuickItem *parent)
: QQuickItem(parent)
{
setFlag(QQuickItem::ItemHasContents);
+
+#ifndef QT_NO_OPENGL
+ if (!qsg_backend_flags().testFlag(QSGContextFactoryInterface::SupportsShaderEffectV2))
+ m_glImpl = new QQuickOpenGLShaderEffect(this, this);
+ else
+ m_glImpl = nullptr;
+#endif
}
/*!
@@ -206,11 +219,19 @@ QQuickShaderEffect::QQuickShaderEffect(QQuickItem *parent)
QByteArray QQuickShaderEffect::fragmentShader() const
{
+#ifndef QT_NO_OPENGL
+ if (m_glImpl)
+ return m_glImpl->fragmentShader();
+#endif
return QByteArray();
}
void QQuickShaderEffect::setFragmentShader(const QByteArray &code)
{
+#ifndef QT_NO_OPENGL
+ if (m_glImpl)
+ m_glImpl->setFragmentShader(code);
+#endif
Q_UNUSED(code);
}
@@ -224,11 +245,19 @@ void QQuickShaderEffect::setFragmentShader(const QByteArray &code)
QByteArray QQuickShaderEffect::vertexShader() const
{
+#ifndef QT_NO_OPENGL
+ if (m_glImpl)
+ return m_glImpl->vertexShader();
+#endif
return QByteArray();
}
void QQuickShaderEffect::setVertexShader(const QByteArray &code)
{
+#ifndef QT_NO_OPENGL
+ if (m_glImpl)
+ m_glImpl->setVertexShader(code);
+#endif
Q_UNUSED(code);
}
@@ -243,11 +272,19 @@ void QQuickShaderEffect::setVertexShader(const QByteArray &code)
bool QQuickShaderEffect::blending() const
{
+#ifndef QT_NO_OPENGL
+ if (m_glImpl)
+ return m_glImpl->blending();
+#endif
return true;
}
void QQuickShaderEffect::setBlending(bool enable)
{
+#ifndef QT_NO_OPENGL
+ if (m_glImpl)
+ m_glImpl->setBlending(enable);
+#endif
Q_UNUSED(enable);
}
@@ -266,11 +303,19 @@ void QQuickShaderEffect::setBlending(bool enable)
QVariant QQuickShaderEffect::mesh() const
{
+#ifndef QT_NO_OPENGL
+ if (m_glImpl)
+ return m_glImpl->mesh();
+#endif
return QVariant();
}
void QQuickShaderEffect::setMesh(const QVariant &mesh)
{
+#ifndef QT_NO_OPENGL
+ if (m_glImpl)
+ m_glImpl->setMesh(mesh);
+#endif
Q_UNUSED(mesh);
}
@@ -290,11 +335,19 @@ void QQuickShaderEffect::setMesh(const QVariant &mesh)
QQuickShaderEffect::CullMode QQuickShaderEffect::cullMode() const
{
+#ifndef QT_NO_OPENGL
+ if (m_glImpl)
+ return m_glImpl->cullMode();
+#endif
return NoCulling;
}
void QQuickShaderEffect::setCullMode(CullMode face)
{
+#ifndef QT_NO_OPENGL
+ if (m_glImpl)
+ m_glImpl->setCullMode(face);
+#endif
Q_UNUSED(face);
}
@@ -321,11 +374,19 @@ void QQuickShaderEffect::setCullMode(CullMode face)
bool QQuickShaderEffect::supportsAtlasTextures() const
{
+#ifndef QT_NO_OPENGL
+ if (m_glImpl)
+ return m_glImpl->supportsAtlasTextures();
+#endif
return false;
}
void QQuickShaderEffect::setSupportsAtlasTextures(bool supports)
{
+#ifndef QT_NO_OPENGL
+ if (m_glImpl)
+ m_glImpl->setSupportsAtlasTextures(supports);
+#endif
Q_UNUSED(supports);
}
@@ -359,12 +420,88 @@ void QQuickShaderEffect::setSupportsAtlasTextures(bool supports)
QString QQuickShaderEffect::log() const
{
+#ifndef QT_NO_OPENGL
+ if (m_glImpl)
+ return m_glImpl->log();
+#endif
return QString();
}
QQuickShaderEffect::Status QQuickShaderEffect::status() const
{
+#ifndef QT_NO_OPENGL
+ if (m_glImpl)
+ return m_glImpl->status();
+#endif
return Uncompiled;
}
+bool QQuickShaderEffect::event(QEvent *e)
+{
+#ifndef QT_NO_OPENGL
+ if (m_glImpl)
+ m_glImpl->handleEvent(e);
+#endif
+ return QQuickItem::event(e);
+}
+
+void QQuickShaderEffect::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
+{
+#ifndef QT_NO_OPENGL
+ if (m_glImpl)
+ m_glImpl->handleGeometryChanged(newGeometry, oldGeometry);
+#endif
+ QQuickItem::geometryChanged(newGeometry, oldGeometry);
+}
+
+QSGNode *QQuickShaderEffect::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *updatePaintNodeData)
+{
+#ifndef QT_NO_OPENGL
+ if (m_glImpl)
+ return m_glImpl->handleUpdatePaintNode(oldNode, updatePaintNodeData);
+#endif
+ return nullptr;
+}
+
+void QQuickShaderEffect::componentComplete()
+{
+#ifndef QT_NO_OPENGL
+ if (m_glImpl)
+ m_glImpl->handleComponentComplete();
+#endif
+ QQuickItem::componentComplete();
+}
+
+void QQuickShaderEffect::itemChange(ItemChange change, const ItemChangeData &value)
+{
+#ifndef QT_NO_OPENGL
+ if (m_glImpl)
+ m_glImpl->handleItemChange(change, value);
+#endif
+ QQuickItem::itemChange(change, value);
+}
+
+bool QQuickShaderEffect::isComponentComplete() const
+{
+ return QQuickItem::isComponentComplete();
+}
+
+void QQuickShaderEffect::sourceDestroyed(QObject *object)
+{
+#ifndef QT_NO_OPENGL
+ if (m_glImpl)
+ m_glImpl->handleSourceDestroyed(object);
+#endif
+ Q_UNUSED(object);
+}
+
+void QQuickShaderEffect::propertyChanged(int mappedId)
+{
+#ifndef QT_NO_OPENGL
+ if (m_glImpl)
+ m_glImpl->handlePropertyChanged(mappedId);
+#endif
+ Q_UNUSED(mappedId);
+}
+
QT_END_NAMESPACE
diff --git a/src/quick/items/qquickshadereffect_p.h b/src/quick/items/qquickshadereffect_p.h
index 9368ecf89c..cabe657c3f 100644
--- a/src/quick/items/qquickshadereffect_p.h
+++ b/src/quick/items/qquickshadereffect_p.h
@@ -56,6 +56,8 @@
QT_BEGIN_NAMESPACE
+class QQuickOpenGLShaderEffect;
+
class Q_QUICK_PRIVATE_EXPORT QQuickShaderEffect : public QQuickItem
{
Q_OBJECT
@@ -106,6 +108,8 @@ public:
QString log() const;
Status status() const;
+ bool isComponentComplete() const;
+
Q_SIGNALS:
void fragmentShaderChanged();
void vertexShaderChanged();
@@ -115,6 +119,22 @@ Q_SIGNALS:
void logChanged();
void statusChanged();
void supportsAtlasTexturesChanged();
+
+protected:
+ bool event(QEvent *e) override;
+ void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) override;
+ QSGNode *updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *updatePaintNodeData) override;
+ void componentComplete() override;
+ void itemChange(ItemChange change, const ItemChangeData &value) override;
+
+private Q_SLOTS:
+ void sourceDestroyed(QObject *object);
+ void propertyChanged(int mappedId);
+
+private:
+#ifndef QT_NO_OPENGL
+ QQuickOpenGLShaderEffect *m_glImpl;
+#endif
};
QT_END_NAMESPACE
diff --git a/src/quick/scenegraph/adaptations/d3d12/qsgd3d12adaptation.cpp b/src/quick/scenegraph/adaptations/d3d12/qsgd3d12adaptation.cpp
index 826a1cc5cb..ba1a88d34a 100644
--- a/src/quick/scenegraph/adaptations/d3d12/qsgd3d12adaptation.cpp
+++ b/src/quick/scenegraph/adaptations/d3d12/qsgd3d12adaptation.cpp
@@ -61,6 +61,11 @@ QSGContext *QSGD3D12Adaptation::create(const QString &) const
return contextInstance;
}
+QSGContextFactoryInterface::Flags QSGD3D12Adaptation::flags(const QString &) const
+{
+ return QSGContextFactoryInterface::SupportsShaderEffectV2;
+}
+
QSGRenderLoop *QSGD3D12Adaptation::createWindowManager()
{
return new QSGD3D12RenderLoop;
diff --git a/src/quick/scenegraph/adaptations/d3d12/qsgd3d12adaptation_p.h b/src/quick/scenegraph/adaptations/d3d12/qsgd3d12adaptation_p.h
index f3f5d5706e..dbb408975d 100644
--- a/src/quick/scenegraph/adaptations/d3d12/qsgd3d12adaptation_p.h
+++ b/src/quick/scenegraph/adaptations/d3d12/qsgd3d12adaptation_p.h
@@ -66,6 +66,7 @@ public:
QStringList keys() const override;
QSGContext *create(const QString &key) const override;
+ QSGContextFactoryInterface::Flags flags(const QString &key) const override;
QSGRenderLoop *createWindowManager() override;
private:
diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwareadaptation.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwareadaptation.cpp
index 55d226bf93..05628ea69c 100644
--- a/src/quick/scenegraph/adaptations/software/qsgsoftwareadaptation.cpp
+++ b/src/quick/scenegraph/adaptations/software/qsgsoftwareadaptation.cpp
@@ -63,6 +63,11 @@ QSGContext *QSGSoftwareAdaptation::create(const QString &) const
return instance;
}
+QSGContextFactoryInterface::Flags QSGSoftwareAdaptation::flags(const QString &) const
+{
+ return QSGContextFactoryInterface::SupportsShaderEffectV2;
+}
+
QSGRenderLoop *QSGSoftwareAdaptation::createWindowManager()
{
return new QSGSoftwareRenderLoop();
diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwareadaptation_p.h b/src/quick/scenegraph/adaptations/software/qsgsoftwareadaptation_p.h
index 3bdfd0e90d..513dd2d361 100644
--- a/src/quick/scenegraph/adaptations/software/qsgsoftwareadaptation_p.h
+++ b/src/quick/scenegraph/adaptations/software/qsgsoftwareadaptation_p.h
@@ -55,6 +55,7 @@ public:
QStringList keys() const override;
QSGContext *create(const QString &key) const override;
+ QSGContextFactoryInterface::Flags flags(const QString &key) const override;
QSGRenderLoop *createWindowManager() override;
private:
static QSGSoftwareContext *instance;
diff --git a/src/quick/scenegraph/qsgcontextplugin.cpp b/src/quick/scenegraph/qsgcontextplugin.cpp
index 1605212c76..646798efe2 100644
--- a/src/quick/scenegraph/qsgcontextplugin.cpp
+++ b/src/quick/scenegraph/qsgcontextplugin.cpp
@@ -77,13 +77,15 @@ struct QSGAdaptionBackendData
bool tried;
QSGContextFactoryInterface *factory;
QString name;
+ QSGContextFactoryInterface::Flags flags;
QVector<QSGContextFactoryInterface *> builtIns;
};
QSGAdaptionBackendData::QSGAdaptionBackendData()
: tried(false)
- , factory(0)
+ , factory(nullptr)
+ , flags(0)
{
// Fill in the table with the built-in adaptations.
builtIns.append(new QSGSoftwareAdaptation);
@@ -94,6 +96,16 @@ QSGAdaptionBackendData::QSGAdaptionBackendData()
Q_GLOBAL_STATIC(QSGAdaptionBackendData, qsg_adaptation_data)
+// This only works when the backend is loaded (contextFactory() was called),
+// otherwise the return value is 0.
+//
+// Note that the default (OpenGL) implementation always results in 0, custom flags
+// can only be returned from the other (either compiled-in or plugin-based) backends.
+QSGContextFactoryInterface::Flags qsg_backend_flags()
+{
+ return qsg_adaptation_data()->flags;
+}
+
QSGAdaptionBackendData *contextFactory()
{
QSGAdaptionBackendData *backendData = qsg_adaptation_data();
@@ -136,6 +148,8 @@ QSGAdaptionBackendData *contextFactory()
for (QSGContextFactoryInterface *builtInBackend : qAsConst(backendData->builtIns)) {
if (builtInBackend->keys().contains(requestedBackend)) {
backendData->factory = builtInBackend;
+ backendData->name = requestedBackend;
+ backendData->flags = backendData->factory->flags(requestedBackend);
break;
}
}
@@ -146,7 +160,10 @@ QSGAdaptionBackendData *contextFactory()
const int index = loader()->indexOf(requestedBackend);
if (index != -1)
backendData->factory = qobject_cast<QSGContextFactoryInterface*>(loader()->instance(index));
- backendData->name = requestedBackend;
+ if (backendData->factory) {
+ backendData->name = requestedBackend;
+ backendData->flags = backendData->factory->flags(requestedBackend);
+ }
#ifndef QT_NO_DEBUG
if (!backendData->factory) {
qWarning("Could not create scene graph context for backend '%s'"
diff --git a/src/quick/scenegraph/qsgcontextplugin_p.h b/src/quick/scenegraph/qsgcontextplugin_p.h
index ca326ead07..779dca62fc 100644
--- a/src/quick/scenegraph/qsgcontextplugin_p.h
+++ b/src/quick/scenegraph/qsgcontextplugin_p.h
@@ -64,12 +64,20 @@ class QSGRenderLoop;
struct Q_QUICK_PRIVATE_EXPORT QSGContextFactoryInterface : public QFactoryInterface
{
+ enum Flag {
+ SupportsShaderEffectV2 = 0x01
+ };
+ Q_DECLARE_FLAGS(Flags, Flag)
+
virtual QSGContext *create(const QString &key) const = 0;
+ virtual Flags flags(const QString &key) const = 0;
virtual QQuickTextureFactory *createTextureFactoryFromImage(const QImage &image) = 0;
virtual QSGRenderLoop *createWindowManager() = 0;
};
+Q_DECLARE_OPERATORS_FOR_FLAGS(QSGContextFactoryInterface::Flags)
+
#define QSGContextFactoryInterface_iid \
"org.qt-project.Qt.QSGContextFactoryInterface"
Q_DECLARE_INTERFACE(QSGContextFactoryInterface, QSGContextFactoryInterface_iid)
@@ -83,7 +91,6 @@ public:
virtual ~QSGContextPlugin();
virtual QStringList keys() const = 0;
- virtual QSGContext *create(const QString &key) const = 0;
virtual QQuickTextureFactory *createTextureFactoryFromImage(const QImage &) { return 0; }
virtual QSGRenderLoop *createWindowManager() { return 0; }