166QQuickShaderEffectSource::~QQuickShaderEffectSource()
169 window()->scheduleRenderJob(
new QQuickShaderEffectSourceCleanup(m_texture, m_provider),
170 QQuickWindow::AfterSynchronizingStage);
174 Q_ASSERT(!m_texture);
175 Q_ASSERT(!m_provider);
179 QQuickItemPrivate *sd = QQuickItemPrivate::get(m_sourceItem);
180 sd->removeItemChangeListener(
this, QQuickItemPrivate::Geometry);
181 sd->derefFromEffectItem(m_hideSource);
207QSGTextureProvider *QQuickShaderEffectSource::textureProvider()
const
209 const QQuickItemPrivate *d = QQuickItemPrivate::get(
this);
210 if (!d->window || !d->sceneGraphRenderContext() || QThread::currentThread() != d->sceneGraphRenderContext()->thread()) {
211 qWarning(
"QQuickShaderEffectSource::textureProvider: can only be queried on the rendering thread of an exposed window");
216 const_cast<QQuickShaderEffectSource *>(
this)->m_provider =
new QQuickShaderEffectSourceTextureProvider();
217 const_cast<QQuickShaderEffectSource *>(
this)->ensureTexture();
218 connect(m_texture, SIGNAL(updateRequested()), m_provider, SIGNAL(textureChanged()));
220 get_wrap_mode(m_wrapMode, &m_provider->horizontalWrap, &m_provider->verticalWrap);
221 m_provider->mipmapFiltering = mipmap() ? QSGTexture::Linear : QSGTexture::None;
222 m_provider->filtering = smooth() ? QSGTexture::Linear : QSGTexture::Nearest;
223 m_provider->sourceTexture = m_texture;
281void QQuickShaderEffectSource::setSourceItem(QQuickItem *item)
283 if (item == m_sourceItem)
286 QQuickItemPrivate *d = QQuickItemPrivate::get(m_sourceItem);
287 d->derefFromEffectItem(m_hideSource);
288 d->removeItemChangeListener(
this, QQuickItemPrivate::Geometry);
289 disconnect(m_sourceItem, SIGNAL(destroyed(QObject*)),
this, SLOT(sourceItemDestroyed(QObject*)));
297 if (window() == m_sourceItem->window()
298 || (window() ==
nullptr && m_sourceItem->window())
299 || (m_sourceItem->window() ==
nullptr && window())) {
300 QQuickItemPrivate *d = QQuickItemPrivate::get(item);
306 d->refWindow(window());
307 else if (m_sourceItem->window())
308 d->refWindow(m_sourceItem->window());
309 d->refFromEffectItem(m_hideSource);
310 d->addItemChangeListener(
this, QQuickItemPrivate::Geometry);
311 connect(m_sourceItem, SIGNAL(destroyed(QObject*)),
this, SLOT(sourceItemDestroyed(QObject*)));
313 qWarning(
"ShaderEffectSource: sourceItem and ShaderEffectSource must both be children of the same window.");
314 m_sourceItem =
nullptr;
318 emit sourceItemChanged();
598static void get_wrap_mode(QQuickShaderEffectSource::WrapMode mode, QSGTexture::WrapMode *hWrap, QSGTexture::WrapMode *vWrap)
601 case QQuickShaderEffectSource::RepeatHorizontally:
602 *hWrap = QSGTexture::Repeat;
603 *vWrap = QSGTexture::ClampToEdge;
605 case QQuickShaderEffectSource::RepeatVertically:
606 *vWrap = QSGTexture::Repeat;
607 *hWrap = QSGTexture::ClampToEdge;
609 case QQuickShaderEffectSource::Repeat:
610 *hWrap = *vWrap = QSGTexture::Repeat;
614 *hWrap = *vWrap = QSGTexture::ClampToEdge;
657QSGNode *QQuickShaderEffectSource::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *)
659 if (!m_sourceItem || m_sourceItem->width() <= 0 || m_sourceItem->height() <= 0) {
661 m_texture->setItem(
nullptr);
668 m_texture->setLive(m_live);
669 m_texture->setItem(QQuickItemPrivate::get(m_sourceItem)->itemNode());
670 QRectF sourceRect = m_sourceRect.width() == 0 || m_sourceRect.height() == 0
671 ? QRectF(0, 0, m_sourceItem->width(), m_sourceItem->height())
673 m_texture->setRect(sourceRect);
674 QQuickItemPrivate *d =
static_cast<QQuickItemPrivate *>(QObjectPrivate::get(
this));
675 const float dpr = d->effectiveDevicePixelRatio();
676 QSize textureSize = m_textureSize.isEmpty()
677 ? QSize(qCeil(qAbs(sourceRect.width())), qCeil(qAbs(sourceRect.height()))) * dpr
679 Q_ASSERT(!textureSize.isEmpty());
681 const QSize minTextureSize = d->sceneGraphContext()->minimumFBOSize();
683 while (textureSize.width() < minTextureSize.width())
684 textureSize.rwidth() *= 2;
685 while (textureSize.height() < minTextureSize.height())
686 textureSize.rheight() *= 2;
688 m_texture->setDevicePixelRatio(d->effectiveDevicePixelRatio());
689 m_texture->setSize(textureSize);
690 m_texture->setRecursive(m_recursive);
691 m_texture->setFormat(toLayerFormat(m_format));
692 m_texture->setHasMipmaps(m_mipmap);
693 m_texture->setMirrorHorizontal(m_textureMirroring & MirrorHorizontally);
694 m_texture->setMirrorVertical(m_textureMirroring & MirrorVertically);
695 m_texture->setSamples(m_samples);
698 m_texture->scheduleUpdate();
701 QSGTexture::Filtering filtering = QQuickItemPrivate::get(
this)->smooth
703 : QSGTexture::Nearest;
704 QSGTexture::Filtering mmFiltering = m_mipmap ? filtering : QSGTexture::None;
705 QSGTexture::WrapMode hWrap, vWrap;
706 get_wrap_mode(m_wrapMode, &hWrap, &vWrap);
709 m_provider->mipmapFiltering = mmFiltering;
710 m_provider->filtering = filtering;
711 m_provider->horizontalWrap = hWrap;
712 m_provider->verticalWrap = vWrap;
716 if (width() <= 0 || height() <= 0) {
721 QSGInternalImageNode *node =
static_cast<QSGInternalImageNode *>(oldNode);
723 node = d->sceneGraphContext()->createInternalImageNode(d->sceneGraphRenderContext());
724 node->setFlag(QSGNode::UsePreprocess);
725 node->setTexture(m_texture);
726 QQuickShaderSourceAttachedNode *attached =
new QQuickShaderSourceAttachedNode;
727 node->appendChildNode(attached);
728 connect(m_texture, SIGNAL(updateRequested()), attached, SLOT(markTextureDirty()));
732 if (m_live && m_recursive)
733 node->markDirty(QSGNode::DirtyMaterial);
735 node->setMipmapFiltering(mmFiltering);
736 node->setFiltering(filtering);
737 node->setHorizontalWrapMode(hWrap);
738 node->setVerticalWrapMode(vWrap);
739 node->setTargetRect(QRectF(0, 0, width(), height()));
740 node->setInnerTargetRect(QRectF(0, 0, width(), height()));