aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/declarative/items/qsgcanvas.cpp3
-rw-r--r--src/declarative/items/qsgimage.cpp60
-rw-r--r--src/declarative/items/qsgimage_p.h9
-rw-r--r--src/declarative/items/qsgimage_p_p.h4
-rw-r--r--src/declarative/items/qsgshadereffect.cpp50
-rw-r--r--src/declarative/items/qsgshadereffect_p.h2
-rw-r--r--src/declarative/items/qsgshadereffectnode.cpp37
-rw-r--r--src/declarative/items/qsgshadereffectnode_p.h8
-rw-r--r--src/declarative/items/qsgshadereffectsource.cpp99
-rw-r--r--src/declarative/items/qsgshadereffectsource_p.h10
-rw-r--r--src/declarative/particles/qsgcustomparticle.cpp16
-rw-r--r--src/declarative/scenegraph/util/qsgtextureprovider.cpp15
-rw-r--r--src/declarative/scenegraph/util/qsgtextureprovider_p.h10
13 files changed, 211 insertions, 112 deletions
diff --git a/src/declarative/items/qsgcanvas.cpp b/src/declarative/items/qsgcanvas.cpp
index 48ed443902..1caee4fd72 100644
--- a/src/declarative/items/qsgcanvas.cpp
+++ b/src/declarative/items/qsgcanvas.cpp
@@ -1963,6 +1963,9 @@ void QSGCanvasRenderThread::run()
}
unlock();
+
+ // Process any "deleteLater" objects...
+ QCoreApplication::processEvents();
}
#ifdef THREAD_DEBUG
diff --git a/src/declarative/items/qsgimage.cpp b/src/declarative/items/qsgimage.cpp
index ed55104f2d..48cefb5bd2 100644
--- a/src/declarative/items/qsgimage.cpp
+++ b/src/declarative/items/qsgimage.cpp
@@ -42,6 +42,8 @@
#include "qsgimage_p.h"
#include "qsgimage_p_p.h"
+#include <private/qsgtextureprovider_p.h>
+
#include <private/qsgcontext_p.h>
#include <private/qsgadaptationlayer_p.h>
@@ -50,6 +52,36 @@
QT_BEGIN_NAMESPACE
+class QSGImageTextureProvider : public QSGTextureProvider
+{
+ Q_OBJECT
+public:
+ QSGImageTextureProvider(const QSGImage *imageItem)
+ : d((QSGImagePrivate *) QSGItemPrivate::get(imageItem))
+ , m_texture(0)
+ , m_smooth(false)
+ {
+ }
+
+ QSGTexture *texture() const {
+ if (m_texture) {
+ m_texture->setFiltering(m_smooth ? QSGTexture::Linear : QSGTexture::Nearest);
+ m_texture->setMipmapFiltering(QSGTexture::Nearest);
+ m_texture->setHorizontalWrapMode(QSGTexture::ClampToEdge);
+ m_texture->setVerticalWrapMode(QSGTexture::ClampToEdge);
+ }
+ return m_texture;
+ }
+
+ friend class QSGImage;
+
+ QSGImagePrivate *d;
+ QSGTexture *m_texture;
+ bool m_smooth;
+};
+
+#include "qsgimage.moc"
+
QSGImagePrivate::QSGImagePrivate()
: fillMode(QSGImage::Stretch)
, paintedWidth(0)
@@ -57,6 +89,7 @@ QSGImagePrivate::QSGImagePrivate()
, pixmapChanged(false)
, hAlign(QSGImage::AlignHCenter)
, vAlign(QSGImage::AlignVCenter)
+ , provider(0)
{
}
@@ -128,6 +161,9 @@ QSGImage::QSGImage(QSGImagePrivate &dd, QSGItem *parent)
QSGImage::~QSGImage()
{
+ Q_D(QSGImage);
+ if (d->provider)
+ d->provider->deleteLater();
}
void QSGImagePrivate::setPixmap(const QPixmap &pixmap)
@@ -504,17 +540,19 @@ QRectF QSGImage::boundingRect() const
return QRectF(0, 0, qMax(width(), d->paintedWidth), qMax(height(), d->paintedHeight));
}
-QSGTexture *QSGImage::texture() const
+QSGTextureProvider *QSGImage::textureProvider() const
{
Q_D(const QSGImage);
- QSGTexture *t = d->pix.texture(d->sceneGraphContext());
- if (t) {
- t->setFiltering(QSGItemPrivate::get(this)->smooth ? QSGTexture::Linear : QSGTexture::Nearest);
- t->setMipmapFiltering(QSGTexture::None);
- t->setHorizontalWrapMode(QSGTexture::ClampToEdge);
- t->setVerticalWrapMode(QSGTexture::ClampToEdge);
+ if (!d->provider) {
+ Q_ASSERT(d->sceneGraphContext());
+ // Make sure it gets thread affinity on the rendering thread so deletion works properly..
+ Q_ASSERT_X(QThread::currentThread() == d->sceneGraphContext()->thread(),
+ "QSGImage::textureProvider",
+ "Cannot be used outside the GUI thread");
+ const_cast<QSGImagePrivate *>(d)->provider = new QSGImageTextureProvider(this);
}
- return t;
+
+ return d->provider;
}
QSGNode *QSGImage::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *)
@@ -523,6 +561,12 @@ QSGNode *QSGImage::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *)
QSGTexture *texture = d->pix.texture(d->sceneGraphContext());
+ // Copy over the current texture state into the texture provider...
+ if (d->provider) {
+ d->provider->m_smooth = d->smooth;
+ d->provider->m_texture = texture;
+ }
+
if (!texture || width() <= 0 || height() <= 0) {
delete oldNode;
return 0;
diff --git a/src/declarative/items/qsgimage_p.h b/src/declarative/items/qsgimage_p.h
index 4faf96dfa0..b49447f1c2 100644
--- a/src/declarative/items/qsgimage_p.h
+++ b/src/declarative/items/qsgimage_p.h
@@ -53,7 +53,7 @@ QT_BEGIN_NAMESPACE
QT_MODULE(Declarative)
class QSGImagePrivate;
-class Q_AUTOTEST_EXPORT QSGImage : public QSGImageBase, public QSGTextureProvider
+class Q_AUTOTEST_EXPORT QSGImage : public QSGImageBase
{
Q_OBJECT
Q_ENUMS(FillMode)
@@ -63,12 +63,9 @@ class Q_AUTOTEST_EXPORT QSGImage : public QSGImageBase, public QSGTextureProvide
Q_PROPERTY(FillMode fillMode READ fillMode WRITE setFillMode NOTIFY fillModeChanged)
Q_PROPERTY(qreal paintedWidth READ paintedWidth NOTIFY paintedGeometryChanged)
Q_PROPERTY(qreal paintedHeight READ paintedHeight NOTIFY paintedGeometryChanged)
- Q_PROPERTY(QSGTexture *texture READ texture)
Q_PROPERTY(HAlignment horizontalAlignment READ horizontalAlignment WRITE setHorizontalAlignment NOTIFY horizontalAlignmentChanged)
Q_PROPERTY(VAlignment verticalAlignment READ verticalAlignment WRITE setVerticalAlignment NOTIFY verticalAlignmentChanged)
- Q_INTERFACES(QSGTextureProvider)
-
public:
QSGImage(QSGItem *parent=0);
~QSGImage();
@@ -90,14 +87,14 @@ public:
QRectF boundingRect() const;
- virtual QSGTexture *texture() const;
-
HAlignment horizontalAlignment() const;
void setHorizontalAlignment(HAlignment align);
VAlignment verticalAlignment() const;
void setVerticalAlignment(VAlignment align);
+ QSGTextureProvider *textureProvider() const;
+
Q_SIGNALS:
void fillModeChanged();
void paintedGeometryChanged();
diff --git a/src/declarative/items/qsgimage_p_p.h b/src/declarative/items/qsgimage_p_p.h
index d0b109942a..9f8b9716c7 100644
--- a/src/declarative/items/qsgimage_p_p.h
+++ b/src/declarative/items/qsgimage_p_p.h
@@ -59,7 +59,7 @@
QT_BEGIN_NAMESPACE
-class QSGImagePrivate;
+class QSGImageTextureProvider;
class QSGImagePrivate : public QSGImageBasePrivate
{
@@ -76,6 +76,8 @@ public:
bool pixmapChanged : 1;
QSGImage::HAlignment hAlign;
QSGImage::VAlignment vAlign;
+
+ QSGImageTextureProvider *provider;
};
QT_END_NAMESPACE
diff --git a/src/declarative/items/qsgshadereffect.cpp b/src/declarative/items/qsgshadereffect.cpp
index 97fe24937e..97cc8985ba 100644
--- a/src/declarative/items/qsgshadereffect.cpp
+++ b/src/declarative/items/qsgshadereffect.cpp
@@ -49,6 +49,9 @@
#include <private/qsgtextureprovider_p.h>
#include "qsgcanvas.h"
+#include <qsgimage_p.h>
+#include <qsgshadereffectsource_p.h>
+
#include <QtCore/qsignalmapper.h>
#include <QtOpenGL/qglframebufferobject.h>
@@ -402,7 +405,7 @@ void QSGShaderEffect::setSource(const QVariant &var, int index)
SourceData &source = m_sources[index];
- source.item = 0;
+ source.sourceObject = 0;
if (var.isNull()) {
return;
} else if (!qVariantCanConvert<QObject *>(var)) {
@@ -411,21 +414,23 @@ void QSGShaderEffect::setSource(const QVariant &var, int index)
}
QObject *obj = qVariantValue<QObject *>(var);
-
- QSGTextureProvider *int3rface = QSGTextureProvider::from(obj);
- if (!int3rface) {
- qWarning("Could not assign property '%s', did not implement QSGTextureProvider.", source.name.constData());
+ if (!QSGTextureProvider::from(obj)) {
+ qWarning("ShaderEffect: source uniform [%s] is not assigned a valid texture provider: %s [%s]",
+ qPrintable(source.name), qPrintable(obj->objectName()), obj->metaObject()->className());
+ return;
}
- source.item = qobject_cast<QSGItem *>(obj);
+ source.sourceObject = obj;
+
+ QSGItem *item = qobject_cast<QSGItem *>(obj);
// TODO: Find better solution.
- // 'source.item' needs a canvas to get a scenegraph node.
+ // 'item' needs a canvas to get a scenegraph node.
// The easiest way to make sure it gets a canvas is to
// make it a part of the same item tree as 'this'.
- if (source.item && source.item->parentItem() == 0) {
- source.item->setParentItem(this);
- source.item->setVisible(false);
+ if (item && item->parentItem() == 0) {
+ item->setParentItem(this);
+ item->setVisible(false);
}
}
@@ -484,8 +489,9 @@ void QSGShaderEffect::reset()
for (int i = 0; i < m_sources.size(); ++i) {
const SourceData &source = m_sources.at(i);
delete source.mapper;
- if (source.item && source.item->parentItem() == this)
- source.item->setParentItem(0);
+ QSGItem *item = qobject_cast<QSGItem *>(source.sourceObject);
+ if (item && item->parentItem() == this)
+ item->setParentItem(0);
}
m_sources.clear();
@@ -558,7 +564,7 @@ void QSGShaderEffect::lookThroughShaderCode(const QByteArray &code)
SourceData d;
d.mapper = new QSignalMapper;
d.name = name;
- d.item = 0;
+ d.sourceObject = 0;
m_sources.append(d);
}
}
@@ -635,24 +641,24 @@ QSGNode *QSGShaderEffect::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData
if (m_dirtyData) {
QVector<QPair<QByteArray, QVariant> > values;
- QVector<QPair<QByteArray, QPointer<QSGItem> > > textures;
- const QVector<QPair<QByteArray, QPointer<QSGItem> > > &oldTextures = material->textureProviders();
+ QVector<QPair<QByteArray, QSGTextureProvider *> > textures;
+ const QVector<QPair<QByteArray, QSGTextureProvider *> > &oldTextures = material->textureProviders();
for (QSet<QByteArray>::const_iterator it = m_source.uniformNames.begin();
it != m_source.uniformNames.end(); ++it) {
values.append(qMakePair(*it, property(*it)));
}
for (int i = 0; i < oldTextures.size(); ++i) {
- QSGTextureProvider *oldSource = QSGTextureProvider::from(oldTextures.at(i).second);
- if (oldSource && oldSource->textureChangedSignal())
- disconnect(oldTextures.at(i).second, oldSource->textureChangedSignal(), node, SLOT(markDirtyTexture()));
+ QSGTextureProvider *t = oldTextures.at(i).second;
+ if (t)
+ disconnect(t, SIGNAL(textureChanged()), node, SLOT(markDirtyTexture()));
}
for (int i = 0; i < m_sources.size(); ++i) {
const SourceData &source = m_sources.at(i);
- textures.append(qMakePair(source.name, source.item));
- QSGTextureProvider *t = QSGTextureProvider::from(source.item);
- if (t && t->textureChangedSignal())
- connect(source.item, t->textureChangedSignal(), node, SLOT(markDirtyTexture()), Qt::DirectConnection);
+ QSGTextureProvider *t = QSGTextureProvider::from(source.sourceObject);
+ textures.append(qMakePair(source.name, t));
+ if (t)
+ connect(t, SIGNAL(textureChanged()), node, SLOT(markDirtyTexture()), Qt::DirectConnection);
}
material->setUniforms(values);
material->setTextureProviders(textures);
diff --git a/src/declarative/items/qsgshadereffect_p.h b/src/declarative/items/qsgshadereffect_p.h
index c72441c5ef..556ff9b0aa 100644
--- a/src/declarative/items/qsgshadereffect_p.h
+++ b/src/declarative/items/qsgshadereffect_p.h
@@ -138,7 +138,7 @@ private:
struct SourceData
{
QSignalMapper *mapper;
- QPointer<QSGItem> item;
+ QPointer<QObject> sourceObject;
QByteArray name;
};
QVector<SourceData> m_sources;
diff --git a/src/declarative/items/qsgshadereffectnode.cpp b/src/declarative/items/qsgshadereffectnode.cpp
index f86b4cba4b..d51317a122 100644
--- a/src/declarative/items/qsgshadereffectnode.cpp
+++ b/src/declarative/items/qsgshadereffectnode.cpp
@@ -110,15 +110,15 @@ void QSGCustomMaterialShader::updateState(const RenderState &state, QSGMaterial
QGLFunctions *functions = state.context()->functions();
for (int i = material->m_textures.size() - 1; i >= 0; --i) {
- QPointer<QSGItem> source = material->m_textures.at(i).second;
- QSGTextureProvider *provider = QSGTextureProvider::from(source);
- QSGTexture *texture = provider ? provider->texture() : 0;
- if (!source || !provider || !texture) {
- qWarning("ShaderEffectItem: source or provider missing when binding textures");
- continue;
- }
functions->glActiveTexture(GL_TEXTURE0 + i);
- provider->texture()->bind();
+ if (QSGTextureProvider *provider = material->m_textures.at(i).second) {
+ if (QSGTexture *texture = provider->texture()) {
+ texture->bind();
+ continue;
+ }
+ }
+ qWarning("ShaderEffectItem: source or provider missing when binding textures");
+ glBindTexture(GL_TEXTURE_2D, 0);
}
if (material->m_source.respectsOpacity)
@@ -271,12 +271,12 @@ void QSGShaderEffectMaterial::setUniforms(const QVector<QPair<QByteArray, QVaria
m_uniformValues = uniformValues;
}
-void QSGShaderEffectMaterial::setTextureProviders(const QVector<QPair<QByteArray, QPointer<QSGItem> > > &textures)
+void QSGShaderEffectMaterial::setTextureProviders(const QVector<QPair<QByteArray, QSGTextureProvider *> > &textures)
{
m_textures = textures;
}
-const QVector<QPair<QByteArray, QPointer<QSGItem> > > &QSGShaderEffectMaterial::textureProviders() const
+const QVector<QPair<QByteArray, QSGTextureProvider *> > &QSGShaderEffectMaterial::textureProviders() const
{
return m_textures;
}
@@ -284,20 +284,9 @@ const QVector<QPair<QByteArray, QPointer<QSGItem> > > &QSGShaderEffectMaterial::
void QSGShaderEffectMaterial::updateTextures() const
{
for (int i = 0; i < m_textures.size(); ++i) {
- QSGItem *item = m_textures.at(i).second;
- if (item) {
- QSGTextureProvider *provider = QSGTextureProvider::from(item);
- if (provider) {
- QSGTexture *texture = provider->texture();
- if (!texture) {
- qWarning("QSGShaderEffectMaterial: no texture from %s [%s]",
- qPrintable(item->objectName()),
- item->metaObject()->className());
- }
- if (QSGDynamicTexture *t = qobject_cast<QSGDynamicTexture *>(provider->texture())) {
- t->updateTexture();
- }
- }
+ if (QSGTextureProvider *provider = m_textures.at(i).second) {
+ if (QSGDynamicTexture *texture = qobject_cast<QSGDynamicTexture *>(provider->texture()))
+ texture->updateTexture();
}
}
}
diff --git a/src/declarative/items/qsgshadereffectnode_p.h b/src/declarative/items/qsgshadereffectnode_p.h
index 4623cac9ce..d95dfaf3cb 100644
--- a/src/declarative/items/qsgshadereffectnode_p.h
+++ b/src/declarative/items/qsgshadereffectnode_p.h
@@ -100,8 +100,8 @@ public:
void setProgramSource(const QSGShaderEffectProgram &);
void setUniforms(const QVector<QPair<QByteArray, QVariant> > &uniformValues);
- void setTextureProviders(const QVector<QPair<QByteArray, QPointer<QSGItem> > > &textures);
- const QVector<QPair<QByteArray, QPointer<QSGItem> > > &textureProviders() const;
+ void setTextureProviders(const QVector<QPair<QByteArray, QSGTextureProvider *> > &textures);
+ const QVector<QPair<QByteArray, QSGTextureProvider *> > &textureProviders() const;
void updateTextures() const;
protected:
@@ -118,7 +118,7 @@ protected:
QSGShaderEffectProgram m_source;
QVector<QPair<QByteArray, QVariant> > m_uniformValues;
- QVector<QPair<QByteArray, QPointer<QSGItem> > > m_textures;
+ QVector<QPair<QByteArray, QSGTextureProvider *> > m_textures;
CullMode m_cullMode;
static QHash<QSGShaderEffectMaterialKey, QSharedPointer<QSGMaterialType> > materialMap;
@@ -143,8 +143,6 @@ private Q_SLOTS:
private:
QSGShaderEffectMaterial m_material;
-
-
};
QT_END_NAMESPACE
diff --git a/src/declarative/items/qsgshadereffectsource.cpp b/src/declarative/items/qsgshadereffectsource.cpp
index d2854e6079..24580073b1 100644
--- a/src/declarative/items/qsgshadereffectsource.cpp
+++ b/src/declarative/items/qsgshadereffectsource.cpp
@@ -54,6 +54,33 @@ QT_BEGIN_NAMESPACE
DEFINE_BOOL_CONFIG_OPTION(qmlFboOverlay, QML_FBO_OVERLAY)
+class QSGShaderEffectSourceTextureProvider : public QSGTextureProvider
+{
+ Q_OBJECT
+public:
+ QSGShaderEffectSourceTextureProvider()
+ : sourceTexture(0)
+ {
+ }
+
+ QSGTexture *texture() const {
+ sourceTexture->setMipmapFiltering(mipmapFiltering);
+ sourceTexture->setFiltering(filtering);
+ sourceTexture->setHorizontalWrapMode(horizontalWrap);
+ sourceTexture->setVerticalWrapMode(verticalWrap);
+ return sourceTexture;
+ }
+
+ QSGShaderEffectTexture *sourceTexture;
+
+ QSGTexture::Filtering mipmapFiltering;
+ QSGTexture::Filtering filtering;
+ QSGTexture::WrapMode horizontalWrap;
+ QSGTexture::WrapMode verticalWrap;
+};
+#include "qsgshadereffectsource.moc"
+
+
QSGShaderEffectSourceNode::QSGShaderEffectSourceNode()
{
setFlag(UsePreprocess, true);
@@ -458,6 +485,7 @@ void QSGShaderEffectTexture::grab()
QSGShaderEffectSource::QSGShaderEffectSource(QSGItem *parent)
: QSGItem(parent)
+ , m_provider(0)
, m_wrapMode(ClampToEdge)
, m_sourceItem(0)
, m_textureSize(0, 0)
@@ -470,7 +498,6 @@ QSGShaderEffectSource::QSGShaderEffectSource(QSGItem *parent)
{
setFlag(ItemHasContents);
m_texture = new QSGShaderEffectTexture(this);
- connect(m_texture, SIGNAL(textureChanged()), this, SIGNAL(textureChanged()), Qt::DirectConnection);
connect(m_texture, SIGNAL(textureChanged()), this, SLOT(update()));
}
@@ -478,10 +505,28 @@ QSGShaderEffectSource::~QSGShaderEffectSource()
{
m_texture->scheduleForCleanup();
+ if (m_provider)
+ m_provider->deleteLater();
+
if (m_sourceItem)
QSGItemPrivate::get(m_sourceItem)->derefFromEffectItem(m_hideSource);
}
+QSGTextureProvider *QSGShaderEffectSource::textureProvider() const
+{
+ if (!m_provider) {
+ Q_ASSERT(QSGItemPrivate::get(this)->sceneGraphContext());
+ // Make sure it gets thread affinity on the rendering thread so deletion works properly..
+ Q_ASSERT_X(QThread::currentThread() == QSGItemPrivate::get(this)->sceneGraphContext()->thread(),
+ "QSGShaderEffectSource::textureProvider",
+ "Cannot be used outside the GUI thread");
+ const_cast<QSGShaderEffectSource *>(this)->m_provider = new QSGShaderEffectSourceTextureProvider();
+ connect(m_texture, SIGNAL(textureChanged()), m_provider, SIGNAL(textureChanged()), Qt::DirectConnection);
+ m_provider->sourceTexture = m_texture;
+ }
+ return m_provider;
+}
+
/*!
\qmlproperty enumeration ShaderEffectSource::wrapMode
@@ -764,17 +809,6 @@ static void get_wrap_mode(QSGShaderEffectSource::WrapMode mode, QSGTexture::Wrap
}
-QSGTexture *QSGShaderEffectSource::texture() const
-{
- m_texture->setMipmapFiltering(m_mipmap ? QSGTexture::Linear : QSGTexture::None);
- m_texture->setFiltering(QSGItemPrivate::get(this)->smooth ? QSGTexture::Linear : QSGTexture::Nearest);
- QSGTexture::WrapMode h, v;
- get_wrap_mode(m_wrapMode, &h, &v);
- m_texture->setHorizontalWrapMode(h);
- m_texture->setVerticalWrapMode(v);
- return m_texture;
-}
-
QSGNode *QSGShaderEffectSource::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *)
{
if (!m_sourceItem) {
@@ -782,19 +816,7 @@ QSGNode *QSGShaderEffectSource::updatePaintNode(QSGNode *oldNode, UpdatePaintNod
return 0;
}
- QSGShaderEffectSourceNode *node = static_cast<QSGShaderEffectSourceNode *>(oldNode);
- if (!node) {
- node = new QSGShaderEffectSourceNode;
- node->setTexture(m_texture);
- connect(m_texture, SIGNAL(textureChanged()), node, SLOT(markDirtyTexture()), Qt::DirectConnection);
- }
-
- // If live and recursive, update continuously.
- if (m_live && m_recursive)
- node->markDirty(QSGNode::DirtyMaterial);
-
QSGShaderEffectTexture *tex = qobject_cast<QSGShaderEffectTexture *>(m_texture);
-
tex->setLive(m_live);
tex->setItem(QSGItemPrivate::get(m_sourceItem)->itemNode());
QRectF sourceRect = m_sourceRect.isNull()
@@ -817,12 +839,35 @@ QSGNode *QSGShaderEffectSource::updatePaintNode(QSGNode *oldNode, UpdatePaintNod
? QSGTexture::Linear
: QSGTexture::Nearest;
QSGTexture::Filtering mmFiltering = m_mipmap ? filtering : QSGTexture::None;
- node->setMipmapFiltering(mmFiltering);
- node->setFiltering(filtering);
-
QSGTexture::WrapMode hWrap, vWrap;
get_wrap_mode(m_wrapMode, &hWrap, &vWrap);
+ if (m_provider) {
+ m_provider->mipmapFiltering = mmFiltering;
+ m_provider->filtering = filtering;
+ m_provider->horizontalWrap = hWrap;
+ m_provider->verticalWrap = vWrap;
+ }
+
+ // Don't create the paint node if we're not spanning any area
+ if (width() == 0 || height() == 0) {
+ delete oldNode;
+ return 0;
+ }
+
+ QSGShaderEffectSourceNode *node = static_cast<QSGShaderEffectSourceNode *>(oldNode);
+ if (!node) {
+ node = new QSGShaderEffectSourceNode;
+ node->setTexture(m_texture);
+ connect(m_texture, SIGNAL(textureChanged()), node, SLOT(markDirtyTexture()), Qt::DirectConnection);
+ }
+
+ // If live and recursive, update continuously.
+ if (m_live && m_recursive)
+ node->markDirty(QSGNode::DirtyMaterial);
+
+ node->setMipmapFiltering(mmFiltering);
+ node->setFiltering(filtering);
node->setHorizontalWrapMode(hWrap);
node->setVerticalWrapMode(vWrap);
node->setTargetRect(QRectF(0, 0, width(), height()));
diff --git a/src/declarative/items/qsgshadereffectsource_p.h b/src/declarative/items/qsgshadereffectsource_p.h
index 1108e8cca8..ff9359f906 100644
--- a/src/declarative/items/qsgshadereffectsource_p.h
+++ b/src/declarative/items/qsgshadereffectsource_p.h
@@ -64,6 +64,8 @@ class QSGNode;
class UpdatePaintNodeData;
class QGLFramebufferObject;
+class QSGShaderEffectSourceTextureProvider;
+
class QSGShaderEffectSourceNode : public QObject, public QSGDefaultImageNode
{
Q_OBJECT
@@ -150,7 +152,7 @@ private:
uint m_grab : 1;
};
-class QSGShaderEffectSource : public QSGItem, public QSGTextureProvider
+class QSGShaderEffectSource : public QSGItem
{
Q_OBJECT
Q_PROPERTY(WrapMode wrapMode READ wrapMode WRITE setWrapMode NOTIFY wrapModeChanged)
@@ -162,7 +164,7 @@ class QSGShaderEffectSource : public QSGItem, public QSGTextureProvider
Q_PROPERTY(bool hideSource READ hideSource WRITE setHideSource NOTIFY hideSourceChanged)
Q_PROPERTY(bool mipmap READ mipmap WRITE setMipmap NOTIFY mipmapChanged)
Q_PROPERTY(bool recursive READ recursive WRITE setRecursive NOTIFY recursiveChanged)
- Q_INTERFACES(QSGTextureProvider)
+
Q_ENUMS(Format WrapMode)
public:
enum WrapMode {
@@ -208,8 +210,7 @@ public:
bool recursive() const;
void setRecursive(bool enabled);
- QSGTexture *texture() const;
- const char *textureChangedSignal() const { return SIGNAL(textureChanged()); }
+ QSGTextureProvider *textureProvider() const;
Q_INVOKABLE void scheduleUpdate();
@@ -230,6 +231,7 @@ protected:
virtual QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *);
private:
+ QSGShaderEffectSourceTextureProvider *m_provider;
QSGShaderEffectTexture *m_texture;
WrapMode m_wrapMode;
QPointer<QSGItem> m_sourceItem;
diff --git a/src/declarative/particles/qsgcustomparticle.cpp b/src/declarative/particles/qsgcustomparticle.cpp
index 7397fc6b50..770c5fd382 100644
--- a/src/declarative/particles/qsgcustomparticle.cpp
+++ b/src/declarative/particles/qsgcustomparticle.cpp
@@ -490,21 +490,21 @@ void QSGCustomParticle::buildData()
if (!m_rootNode)
return;
QVector<QPair<QByteArray, QVariant> > values;
- QVector<QPair<QByteArray, QPointer<QSGItem> > > textures;
- const QVector<QPair<QByteArray, QPointer<QSGItem> > > &oldTextures = m_material.textureProviders();
+ QVector<QPair<QByteArray, QSGTextureProvider *> > textures;
+ const QVector<QPair<QByteArray, QSGTextureProvider *> > &oldTextures = m_material.textureProviders();
for (int i = 0; i < oldTextures.size(); ++i) {
- QSGTextureProvider *oldSource = QSGTextureProvider::from(oldTextures.at(i).second);
- if (oldSource && oldSource->textureChangedSignal())
+ QSGTextureProvider *t = oldTextures.at(i).second;
+ if (t)
foreach (QSGShaderEffectNode* node, m_nodes)
- disconnect(oldTextures.at(i).second, oldSource->textureChangedSignal(), node, SLOT(markDirtyTexture()));
+ disconnect(t, SIGNAL(textureChanged()), node, SLOT(markDirtyTexture()));
}
for (int i = 0; i < m_sources.size(); ++i) {
const SourceData &source = m_sources.at(i);
- textures.append(qMakePair(source.name, source.item));
QSGTextureProvider *t = QSGTextureProvider::from(source.item);
- if (t && t->textureChangedSignal())
+ textures.append(qMakePair(source.name, t));
+ if (t)
foreach (QSGShaderEffectNode* node, m_nodes)
- connect(source.item, t->textureChangedSignal(), node, SLOT(markDirtyTexture()), Qt::DirectConnection);
+ connect(t, SIGNAL(textureChanged()), node, SLOT(markDirtyTexture()), Qt::DirectConnection);
}
for (QSet<QByteArray>::const_iterator it = m_source.uniformNames.begin();
it != m_source.uniformNames.end(); ++it) {
diff --git a/src/declarative/scenegraph/util/qsgtextureprovider.cpp b/src/declarative/scenegraph/util/qsgtextureprovider.cpp
index abaf96ed5a..cc88854663 100644
--- a/src/declarative/scenegraph/util/qsgtextureprovider.cpp
+++ b/src/declarative/scenegraph/util/qsgtextureprovider.cpp
@@ -41,6 +41,9 @@
#include "qsgtextureprovider_p.h"
+#include <qsgimage_p.h>
+#include <qsgshadereffectsource_p.h>
+
#ifndef GL_CLAMP_TO_EDGE
#define GL_CLAMP_TO_EDGE 0x812F
#endif
@@ -50,6 +53,8 @@ QT_BEGIN_NAMESPACE
/*!
\class QSGTextureProvider
\brief The QSGTextureProvider class encapsulates texture based entities in QML.
+
+ The QSGTextureProvider lives primarily in the scene graph rendering thread.
*/
@@ -58,7 +63,15 @@ QT_BEGIN_NAMESPACE
*/
QSGTextureProvider *QSGTextureProvider::from(QObject *object)
{
- return object ? static_cast<QSGTextureProvider *>(object->qt_metacast("QSGTextureProvider")) : 0;
+ if (QSGImage *image = qobject_cast<QSGImage*>(object))
+ return image->textureProvider();
+ else if (QSGShaderEffectSource *source = qobject_cast<QSGShaderEffectSource *>(object))
+ return source->textureProvider();
+ else if (QSGTextureProvider *provider = qobject_cast<QSGTextureProvider *>(object))
+ return provider;
+
+ qDebug() << "QSGTextureProvider::from() not a texture provider" << object;
+ return 0;
}
diff --git a/src/declarative/scenegraph/util/qsgtextureprovider_p.h b/src/declarative/scenegraph/util/qsgtextureprovider_p.h
index 756f1c613a..372039470e 100644
--- a/src/declarative/scenegraph/util/qsgtextureprovider_p.h
+++ b/src/declarative/scenegraph/util/qsgtextureprovider_p.h
@@ -42,8 +42,6 @@
#ifndef QSGTEXTUREPROVIDER_H
#define QSGTEXTUREPROVIDER_H
-#include <qgl.h>
-
#include "qsgtexture.h"
#include "qobject.h"
@@ -53,15 +51,17 @@ QT_BEGIN_NAMESPACE
QT_MODULE(Declarative)
-class QSGTextureProvider
+class QSGTextureProvider : public QObject
{
+ Q_OBJECT
public:
virtual QSGTexture *texture() const = 0;
- virtual const char *textureChangedSignal() const { return 0; }
static QSGTextureProvider *from(QObject *object);
+
+Q_SIGNALS:
+ void textureChanged();
};
-Q_DECLARE_INTERFACE(QSGTextureProvider, "QSGTextureProvider")
QT_END_NAMESPACE