diff options
-rw-r--r-- | src/declarative/items/qsgcanvas.cpp | 3 | ||||
-rw-r--r-- | src/declarative/items/qsgimage.cpp | 60 | ||||
-rw-r--r-- | src/declarative/items/qsgimage_p.h | 9 | ||||
-rw-r--r-- | src/declarative/items/qsgimage_p_p.h | 4 | ||||
-rw-r--r-- | src/declarative/items/qsgshadereffect.cpp | 50 | ||||
-rw-r--r-- | src/declarative/items/qsgshadereffect_p.h | 2 | ||||
-rw-r--r-- | src/declarative/items/qsgshadereffectnode.cpp | 37 | ||||
-rw-r--r-- | src/declarative/items/qsgshadereffectnode_p.h | 8 | ||||
-rw-r--r-- | src/declarative/items/qsgshadereffectsource.cpp | 99 | ||||
-rw-r--r-- | src/declarative/items/qsgshadereffectsource_p.h | 10 | ||||
-rw-r--r-- | src/declarative/particles/qsgcustomparticle.cpp | 16 | ||||
-rw-r--r-- | src/declarative/scenegraph/util/qsgtextureprovider.cpp | 15 | ||||
-rw-r--r-- | src/declarative/scenegraph/util/qsgtextureprovider_p.h | 10 |
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 |