aboutsummaryrefslogtreecommitdiffstats
path: root/src/quick/items
diff options
context:
space:
mode:
Diffstat (limited to 'src/quick/items')
-rw-r--r--src/quick/items/context2d/qquickcanvascontext_p.h2
-rw-r--r--src/quick/items/qquickitemgrabresult.cpp5
-rw-r--r--src/quick/items/qquickshadereffectnode.cpp2
-rw-r--r--src/quick/items/qquickshadereffectsource.cpp416
-rw-r--r--src/quick/items/qquickshadereffectsource_p.h93
5 files changed, 11 insertions, 507 deletions
diff --git a/src/quick/items/context2d/qquickcanvascontext_p.h b/src/quick/items/context2d/qquickcanvascontext_p.h
index 2d8fbb5f85..8988ea9105 100644
--- a/src/quick/items/context2d/qquickcanvascontext_p.h
+++ b/src/quick/items/context2d/qquickcanvascontext_p.h
@@ -49,7 +49,7 @@
QT_BEGIN_NAMESPACE
class QQuickCanvasItem;
-class QSGDynamicTexture;
+class QSGLayer;
class QQuickCanvasContextPrivate;
class QQuickCanvasContext : public QObject
diff --git a/src/quick/items/qquickitemgrabresult.cpp b/src/quick/items/qquickitemgrabresult.cpp
index 93b9261c44..f5d72bbd3a 100644
--- a/src/quick/items/qquickitemgrabresult.cpp
+++ b/src/quick/items/qquickitemgrabresult.cpp
@@ -91,7 +91,7 @@ public:
QPointer<QQuickItem> item;
QPointer<QQuickWindow> window;
- QQuickShaderEffectTexture *texture;
+ QSGLayer *texture;
QSizeF itemSize;
QSize textureSize;
};
@@ -228,7 +228,8 @@ void QQuickItemGrabResult::setup()
return;
}
- d->texture = new QQuickShaderEffectTexture(d->item);
+ QSGRenderContext *rc = QQuickWindowPrivate::get(d->window.data())->context;
+ d->texture = rc->sceneGraphContext()->createLayer(rc);
d->texture->setItem(QQuickItemPrivate::get(d->item)->itemNode());
d->itemSize = QSizeF(d->item->width(), d->item->height());
}
diff --git a/src/quick/items/qquickshadereffectnode.cpp b/src/quick/items/qquickshadereffectnode.cpp
index cefb006648..3f7938c386 100644
--- a/src/quick/items/qquickshadereffectnode.cpp
+++ b/src/quick/items/qquickshadereffectnode.cpp
@@ -418,7 +418,7 @@ void QQuickShaderEffectMaterial::updateTextures() const
{
for (int i = 0; i < textureProviders.size(); ++i) {
if (QSGTextureProvider *provider = textureProviders.at(i)) {
- if (QSGDynamicTexture *texture = qobject_cast<QSGDynamicTexture *>(provider->texture()))
+ if (QSGLayer *texture = qobject_cast<QSGLayer *>(provider->texture()))
texture->updateTexture();
}
}
diff --git a/src/quick/items/qquickshadereffectsource.cpp b/src/quick/items/qquickshadereffectsource.cpp
index 2b42a01fc1..f027e044e1 100644
--- a/src/quick/items/qquickshadereffectsource.cpp
+++ b/src/quick/items/qquickshadereffectsource.cpp
@@ -54,44 +54,6 @@
QT_BEGIN_NAMESPACE
-DEFINE_BOOL_CONFIG_OPTION(qmlFboOverlay, QML_FBO_OVERLAY)
-DEFINE_BOOL_CONFIG_OPTION(qmlFboFlushBeforeDetach, QML_FBO_FLUSH_BEFORE_DETACH)
-
-namespace
-{
- class BindableFbo : public QSGBindable
- {
- public:
- BindableFbo(QOpenGLFramebufferObject *fbo, QSGDepthStencilBuffer *depthStencil);
- virtual ~BindableFbo();
- virtual void bind() const;
- private:
- QOpenGLFramebufferObject *m_fbo;
- QSGDepthStencilBuffer *m_depthStencil;
- };
-
- BindableFbo::BindableFbo(QOpenGLFramebufferObject *fbo, QSGDepthStencilBuffer *depthStencil)
- : m_fbo(fbo)
- , m_depthStencil(depthStencil)
- {
- }
-
- BindableFbo::~BindableFbo()
- {
- if (qmlFboFlushBeforeDetach())
- QOpenGLContext::currentContext()->functions()->glFlush();
- if (m_depthStencil)
- m_depthStencil->detach();
- }
-
- void BindableFbo::bind() const
- {
- m_fbo->bind();
- if (m_depthStencil)
- m_depthStencil->attach();
- }
-}
-
class QQuickShaderEffectSourceTextureProvider : public QSGTextureProvider
{
Q_OBJECT
@@ -113,7 +75,7 @@ public:
return sourceTexture;
}
- QQuickShaderEffectTexture *sourceTexture;
+ QSGLayer *sourceTexture;
QSGTexture::Filtering mipmapFiltering;
QSGTexture::Filtering filtering;
@@ -122,379 +84,10 @@ public:
};
#include "qquickshadereffectsource.moc"
-QQuickShaderEffectTexture::QQuickShaderEffectTexture(QQuickItem *shaderSource)
- : QSGDynamicTexture()
- , m_item(0)
- , m_shaderSourceNode(0)
- , m_device_pixel_ratio(1)
- , m_format(GL_RGBA)
- , m_renderer(0)
- , m_fbo(0)
- , m_secondaryFbo(0)
- , m_transparentTexture(0)
-#ifdef QSG_DEBUG_FBO_OVERLAY
- , m_debugOverlay(0)
-#endif
- , m_context(QQuickItemPrivate::get(shaderSource)->sceneGraphRenderContext())
- , m_mipmap(false)
- , m_live(true)
- , m_recursive(false)
- , m_dirtyTexture(true)
- , m_multisamplingChecked(false)
- , m_multisampling(false)
- , m_grab(false)
-{
-}
-
-QQuickShaderEffectTexture::~QQuickShaderEffectTexture()
-{
- invalidated();
-}
-
-void QQuickShaderEffectTexture::invalidated()
-{
- delete m_renderer;
- m_renderer = 0;
- delete m_fbo;
- delete m_secondaryFbo;
- m_fbo = m_secondaryFbo = 0;
-#ifdef QSG_DEBUG_FBO_OVERLAY
- delete m_debugOverlay;
- m_debugOverlay = 0;
-#endif
- if (m_transparentTexture) {
- QOpenGLContext::currentContext()->functions()->glDeleteTextures(1, &m_transparentTexture);
- m_transparentTexture = 0;
- }
-}
-
-void QQuickShaderEffectTexture::markDirtyTextureLater()
-{
- QCoreApplication::postEvent(this, new QEvent(QEvent::User));
-}
-
-void QQuickShaderEffectTexture::customEvent(QEvent *)
-{
- markDirtyTexture();
-}
-
-int QQuickShaderEffectTexture::textureId() const
-{
- return m_fbo ? m_fbo->texture() : 0;
-}
-
-bool QQuickShaderEffectTexture::hasAlphaChannel() const
-{
- return m_format != GL_RGB;
-}
-
-bool QQuickShaderEffectTexture::hasMipmaps() const
-{
- return m_mipmap;
-}
-
-
-void QQuickShaderEffectTexture::bind()
-{
-#ifndef QT_NO_DEBUG
- if (!m_recursive && m_fbo && ((m_multisampling && m_secondaryFbo->isBound()) || m_fbo->isBound()))
- qWarning("ShaderEffectSource: \'recursive\' must be set to true when rendering recursively.");
-#endif
- QOpenGLFunctions *funcs = QOpenGLContext::currentContext()->functions();
- if (!m_fbo && m_format == GL_RGBA) {
- if (m_transparentTexture == 0) {
- funcs->glGenTextures(1, &m_transparentTexture);
- funcs->glBindTexture(GL_TEXTURE_2D, m_transparentTexture);
- const uint zero = 0;
- funcs->glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &zero);
- } else {
- funcs->glBindTexture(GL_TEXTURE_2D, m_transparentTexture);
- }
- } else {
- funcs->glBindTexture(GL_TEXTURE_2D, m_fbo ? m_fbo->texture() : 0);
- updateBindOptions();
- }
-}
-
-bool QQuickShaderEffectTexture::updateTexture()
-{
- bool doGrab = (m_live || m_grab) && m_dirtyTexture;
- if (doGrab)
- grab();
- if (m_grab)
- emit scheduledUpdateCompleted();
- m_grab = false;
- return doGrab;
-}
-
-void QQuickShaderEffectTexture::setHasMipmaps(bool mipmap)
-{
- if (mipmap == m_mipmap)
- return;
- m_mipmap = mipmap;
- if (m_mipmap && m_fbo && !m_fbo->format().mipmap())
- markDirtyTexture();
-}
-
-
-void QQuickShaderEffectTexture::setItem(QSGNode *item)
-{
- if (item == m_item)
- return;
- m_item = item;
-
- if (m_live && !m_item) {
- delete m_fbo;
- delete m_secondaryFbo;
- m_fbo = m_secondaryFbo = 0;
- m_depthStencilBuffer.clear();
- }
-
- markDirtyTexture();
-}
-
-void QQuickShaderEffectTexture::setRect(const QRectF &rect)
-{
- if (rect == m_rect)
- return;
- m_rect = rect;
- markDirtyTexture();
-}
-
-void QQuickShaderEffectTexture::setSize(const QSize &size)
-{
- if (size == m_size)
- return;
- m_size = size;
-
- if (m_live && m_size.isNull()) {
- delete m_fbo;
- delete m_secondaryFbo;
- m_fbo = m_secondaryFbo = 0;
- m_depthStencilBuffer.clear();
- }
-
- markDirtyTexture();
-}
-
-void QQuickShaderEffectTexture::setFormat(GLenum format)
-{
- if (format == m_format)
- return;
- m_format = format;
- markDirtyTexture();
-}
-
-void QQuickShaderEffectTexture::setLive(bool live)
-{
- if (live == m_live)
- return;
- m_live = live;
-
- if (m_live && (!m_item || m_size.isNull())) {
- delete m_fbo;
- delete m_secondaryFbo;
- m_fbo = m_secondaryFbo = 0;
- m_depthStencilBuffer.clear();
- }
-
- markDirtyTexture();
-}
-
-void QQuickShaderEffectTexture::scheduleUpdate()
-{
- if (m_grab)
- return;
- m_grab = true;
- if (m_dirtyTexture) {
- emit updateRequested();
- if (m_shaderSourceNode)
- m_shaderSourceNode->markDirty(QSGNode::DirtyMaterial);
- }
-}
-
-void QQuickShaderEffectTexture::setRecursive(bool recursive)
-{
- m_recursive = recursive;
-}
-
-void QQuickShaderEffectTexture::markDirtyTexture()
-{
- m_dirtyTexture = true;
- if (m_live || m_grab) {
- emit updateRequested();
- if (m_shaderSourceNode)
- m_shaderSourceNode->markDirty(QSGNode::DirtyMaterial);
- }
-}
-
-void QQuickShaderEffectTexture::grab()
-{
- if (!m_item || m_size.isNull()) {
- delete m_fbo;
- delete m_secondaryFbo;
- m_fbo = m_secondaryFbo = 0;
- m_depthStencilBuffer.clear();
- m_dirtyTexture = false;
- return;
- }
- QSGNode *root = m_item;
- while (root->firstChild() && root->type() != QSGNode::RootNodeType)
- root = root->firstChild();
- if (root->type() != QSGNode::RootNodeType)
- return;
-
- if (!m_renderer) {
- m_renderer = m_context->createRenderer();
- connect(m_renderer, SIGNAL(sceneGraphChanged()), this, SLOT(markDirtyTextureLater()));
- }
- m_renderer->setDevicePixelRatio(m_device_pixel_ratio);
- m_renderer->setRootNode(static_cast<QSGRootNode *>(root));
-
- QOpenGLFunctions *funcs = QOpenGLContext::currentContext()->functions();
- bool deleteFboLater = false;
- if (!m_fbo || m_fbo->size() != m_size || m_fbo->format().internalTextureFormat() != m_format
- || (!m_fbo->format().mipmap() && m_mipmap))
- {
- if (!m_multisamplingChecked) {
- if (m_context->openglContext()->format().samples() <= 1) {
- m_multisampling = false;
- } else {
- const QSet<QByteArray> extensions = m_context->openglContext()->extensions();
- m_multisampling = extensions.contains(QByteArrayLiteral("GL_EXT_framebuffer_multisample"))
- && extensions.contains(QByteArrayLiteral("GL_EXT_framebuffer_blit"));
- }
- m_multisamplingChecked = true;
- }
- if (m_multisampling) {
- // Don't delete the FBO right away in case it is used recursively.
- deleteFboLater = true;
- delete m_secondaryFbo;
- QOpenGLFramebufferObjectFormat format;
-
- format.setInternalTextureFormat(m_format);
- format.setSamples(m_context->openglContext()->format().samples());
- m_secondaryFbo = new QOpenGLFramebufferObject(m_size, format);
- m_depthStencilBuffer = m_context->depthStencilBufferForFbo(m_secondaryFbo);
- } else {
- QOpenGLFramebufferObjectFormat format;
- format.setInternalTextureFormat(m_format);
- format.setMipmap(m_mipmap);
- if (m_recursive) {
- deleteFboLater = true;
- delete m_secondaryFbo;
- m_secondaryFbo = new QOpenGLFramebufferObject(m_size, format);
- funcs->glBindTexture(GL_TEXTURE_2D, m_secondaryFbo->texture());
- updateBindOptions(true);
- m_depthStencilBuffer = m_context->depthStencilBufferForFbo(m_secondaryFbo);
- } else {
- delete m_fbo;
- delete m_secondaryFbo;
- m_fbo = new QOpenGLFramebufferObject(m_size, format);
- m_secondaryFbo = 0;
- funcs->glBindTexture(GL_TEXTURE_2D, m_fbo->texture());
- updateBindOptions(true);
- m_depthStencilBuffer = m_context->depthStencilBufferForFbo(m_fbo);
- }
- }
- }
-
- if (m_recursive && !m_secondaryFbo) {
- // m_fbo already created, m_recursive was just set.
- Q_ASSERT(m_fbo);
- Q_ASSERT(!m_multisampling);
-
- m_secondaryFbo = new QOpenGLFramebufferObject(m_size, m_fbo->format());
- funcs->glBindTexture(GL_TEXTURE_2D, m_secondaryFbo->texture());
- updateBindOptions(true);
- }
-
- // Render texture.
- root->markDirty(QSGNode::DirtyForceUpdate); // Force matrix, clip and opacity update.
- m_renderer->nodeChanged(root, QSGNode::DirtyForceUpdate); // Force render list update.
-
-#ifdef QSG_DEBUG_FBO_OVERLAY
- if (qmlFboOverlay()) {
- if (!m_debugOverlay)
- m_debugOverlay = new QSGSimpleRectNode();
- m_debugOverlay->setRect(QRectF(0, 0, m_size.width(), m_size.height()));
- m_debugOverlay->setColor(QColor(0xff, 0x00, 0x80, 0x40));
- root->appendChildNode(m_debugOverlay);
- }
-#endif
-
- m_dirtyTexture = false;
-
- m_renderer->setDeviceRect(m_size);
- m_renderer->setViewportRect(m_size);
- QRectF mirrored(m_rect.left(), m_rect.bottom(), m_rect.width(), -m_rect.height());
- m_renderer->setProjectionMatrixToRect(mirrored);
- m_renderer->setClearColor(Qt::transparent);
-
- if (m_multisampling) {
- m_renderer->renderScene(BindableFbo(m_secondaryFbo, m_depthStencilBuffer.data()));
-
- if (deleteFboLater) {
- delete m_fbo;
- QOpenGLFramebufferObjectFormat format;
- format.setInternalTextureFormat(m_format);
- format.setAttachment(QOpenGLFramebufferObject::NoAttachment);
- format.setMipmap(m_mipmap);
- format.setSamples(0);
- m_fbo = new QOpenGLFramebufferObject(m_size, format);
- funcs->glBindTexture(GL_TEXTURE_2D, m_fbo->texture());
- updateBindOptions(true);
- }
-
- QRect r(QPoint(), m_size);
- QOpenGLFramebufferObject::blitFramebuffer(m_fbo, r, m_secondaryFbo, r);
- } else {
- if (m_recursive) {
- m_renderer->renderScene(BindableFbo(m_secondaryFbo, m_depthStencilBuffer.data()));
-
- if (deleteFboLater) {
- delete m_fbo;
- QOpenGLFramebufferObjectFormat format;
- format.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil);
- format.setInternalTextureFormat(m_format);
- format.setMipmap(m_mipmap);
- m_fbo = new QOpenGLFramebufferObject(m_size, format);
- funcs->glBindTexture(GL_TEXTURE_2D, m_fbo->texture());
- updateBindOptions(true);
- }
- qSwap(m_fbo, m_secondaryFbo);
- } else {
- m_renderer->renderScene(BindableFbo(m_fbo, m_depthStencilBuffer.data()));
- }
- }
-
- if (m_mipmap) {
- funcs->glBindTexture(GL_TEXTURE_2D, textureId());
- funcs->glGenerateMipmap(GL_TEXTURE_2D);
- }
-
- root->markDirty(QSGNode::DirtyForceUpdate); // Force matrix, clip, opacity and render list update.
-
-#ifdef QSG_DEBUG_FBO_OVERLAY
- if (qmlFboOverlay())
- root->removeChildNode(m_debugOverlay);
-#endif
- if (m_recursive)
- markDirtyTexture(); // Continuously update if 'live' and 'recursive'.
-}
-
-QImage QQuickShaderEffectTexture::toImage() const
-{
- if (m_fbo)
- return m_fbo->toImage();
-
- return QImage();
-}
-
class QQuickShaderEffectSourceCleanup : public QRunnable
{
public:
- QQuickShaderEffectSourceCleanup(QQuickShaderEffectTexture *t, QQuickShaderEffectSourceTextureProvider *p)
+ QQuickShaderEffectSourceCleanup(QSGLayer *t, QQuickShaderEffectSourceTextureProvider *p)
: texture(t)
, provider(p)
{}
@@ -502,7 +95,7 @@ public:
delete texture;
delete provider;
}
- QQuickShaderEffectTexture *texture;
+ QSGLayer *texture;
QQuickShaderEffectSourceTextureProvider *provider;
};
@@ -642,7 +235,8 @@ void QQuickShaderEffectSource::ensureTexture()
"QQuickShaderEffectSource::ensureTexture",
"Cannot be used outside the rendering thread");
- m_texture = new QQuickShaderEffectTexture(this);
+ QSGRenderContext *rc = QQuickItemPrivate::get(this)->sceneGraphRenderContext();
+ m_texture = rc->sceneGraphContext()->createLayer(rc);
connect(QQuickItemPrivate::get(this)->window, SIGNAL(sceneGraphInvalidated()), m_texture, SLOT(invalidated()), Qt::DirectConnection);
connect(m_texture, SIGNAL(updateRequested()), this, SLOT(update()));
connect(m_texture, SIGNAL(scheduledUpdateCompleted()), this, SIGNAL(scheduledUpdateCompleted()));
diff --git a/src/quick/items/qquickshadereffectsource_p.h b/src/quick/items/qquickshadereffectsource_p.h
index 4caeaab52c..35899339ce 100644
--- a/src/quick/items/qquickshadereffectsource_p.h
+++ b/src/quick/items/qquickshadereffectsource_p.h
@@ -53,8 +53,6 @@
#include "qsize.h"
#include "qrect.h"
-#define QSG_DEBUG_FBO_OVERLAY
-
QT_BEGIN_NAMESPACE
class QSGNode;
@@ -64,95 +62,6 @@ class QSGSimpleRectNode;
class QQuickShaderEffectSourceTextureProvider;
-class Q_QUICK_PRIVATE_EXPORT QQuickShaderEffectTexture : public QSGDynamicTexture
-{
- Q_OBJECT
-public:
- QQuickShaderEffectTexture(QQuickItem *shaderSource);
- ~QQuickShaderEffectTexture();
-
- virtual bool updateTexture();
-
- // The item's "paint node", not effect node.
- QSGNode *item() const { return m_item; }
- void setItem(QSGNode *item);
-
- void setShaderSourceNode(QSGNode *node) { m_shaderSourceNode = node; }
-
- QRectF rect() const { return m_rect; }
- void setRect(const QRectF &rect);
-
- QSize size() const { return m_size; }
- void setSize(const QSize &size);
-
- void setHasMipmaps(bool mipmap);
-
- void bind();
-
- bool hasAlphaChannel() const;
- bool hasMipmaps() const;
- int textureId() const;
- QSize textureSize() const { return m_size; }
-
- GLenum format() const { return m_format; }
- void setFormat(GLenum format);
-
- bool live() const { return bool(m_live); }
- void setLive(bool live);
-
- bool recursive() const { return bool(m_recursive); }
- void setRecursive(bool recursive);
-
- void setDevicePixelRatio(qreal ratio) { m_device_pixel_ratio = ratio; }
-
- void scheduleUpdate();
-
- QImage toImage() const;
-
-Q_SIGNALS:
- void updateRequested();
- void scheduledUpdateCompleted();
-
-public Q_SLOTS:
- void markDirtyTexture();
- void invalidated();
- void markDirtyTextureLater();
-
-protected:
- virtual void customEvent(QEvent *);
-
-private:
- void grab();
-
- QSGNode *m_item;
- QSGNode *m_shaderSourceNode;
- QRectF m_rect;
- QSize m_size;
- qreal m_device_pixel_ratio;
- GLenum m_format;
-
- QSGRenderer *m_renderer;
- QOpenGLFramebufferObject *m_fbo;
- QOpenGLFramebufferObject *m_secondaryFbo;
- QSharedPointer<QSGDepthStencilBuffer> m_depthStencilBuffer;
-
- GLuint m_transparentTexture;
-
-#ifdef QSG_DEBUG_FBO_OVERLAY
- QSGSimpleRectNode *m_debugOverlay;
-#endif
-
- QSGRenderContext *m_context;
-
- uint m_mipmap : 1;
- uint m_live : 1;
- uint m_recursive : 1;
- uint m_dirtyTexture : 1;
- uint m_multisamplingChecked : 1;
- uint m_multisampling : 1;
- uint m_grab : 1;
-};
-
class Q_QUICK_PRIVATE_EXPORT QQuickShaderEffectSource : public QQuickItem, public QQuickItemChangeListener
{
Q_OBJECT
@@ -244,7 +153,7 @@ private:
void ensureTexture();
QQuickShaderEffectSourceTextureProvider *m_provider;
- QQuickShaderEffectTexture *m_texture;
+ QSGLayer *m_texture;
WrapMode m_wrapMode;
QQuickItem *m_sourceItem;
QRectF m_sourceRect;