diff --git a/src/quick/designer/designersupport.cpp b/src/quick/designer/designersupport.cpp index 82f796361b3ef51357c0d11b0a9a314c1ae2256d..a57c1ae56958ab22b85f42e7fa740bb6239d31cd 100644 --- a/src/quick/designer/designersupport.cpp +++ b/src/quick/designer/designersupport.cpp @@ -65,10 +65,10 @@ DesignerSupport::DesignerSupport() DesignerSupport::~DesignerSupport() { - QHash<QQuickItem*, QQuickShaderEffectTexture*>::iterator iterator; + QHash<QQuickItem*, QSGLayer*>::iterator iterator; for (iterator = m_itemTextureHash.begin(); iterator != m_itemTextureHash.end(); ++iterator) { - QQuickShaderEffectTexture *texture = iterator.value(); + QSGLayer *texture = iterator.value(); QQuickItem *item = iterator.key(); QQuickItemPrivate::get(item)->derefFromEffectItem(true); delete texture; @@ -86,7 +86,8 @@ void DesignerSupport::refFromEffectItem(QQuickItem *referencedItem, bool hide) Q_ASSERT(QQuickItemPrivate::get(referencedItem)->rootNode()); if (!m_itemTextureHash.contains(referencedItem)) { - QQuickShaderEffectTexture *texture = new QQuickShaderEffectTexture(referencedItem); + QSGRenderContext *rc = QQuickWindowPrivate::get(referencedItem->window())->context; + QSGLayer *texture = rc->sceneGraphContext()->createLayer(rc); texture->setLive(true); texture->setItem(QQuickItemPrivate::get(referencedItem)->rootNode()); @@ -123,7 +124,7 @@ QImage DesignerSupport::renderImageForItem(QQuickItem *referencedItem, const QRe return QImage(); } - QQuickShaderEffectTexture *renderTexture = m_itemTextureHash.value(referencedItem); + QSGLayer *renderTexture = m_itemTextureHash.value(referencedItem); Q_ASSERT(renderTexture); if (renderTexture == 0) diff --git a/src/quick/designer/designersupport.h b/src/quick/designer/designersupport.h index 41458ae3d6d54b94a2a297c47c8295b94ccac243..8dfb4af1678c1dfa643dfcfadd398562d3f25191 100644 --- a/src/quick/designer/designersupport.h +++ b/src/quick/designer/designersupport.h @@ -62,7 +62,7 @@ QT_BEGIN_NAMESPACE class QQuickItem; -class QQuickShaderEffectTexture; +class QSGLayer; class QImage; class QTransform; class QQmlContext; @@ -154,7 +154,7 @@ public: static void polishItems(QQuickWindow *window); private: - QHash<QQuickItem*, QQuickShaderEffectTexture*> m_itemTextureHash; + QHash<QQuickItem*, QSGLayer*> m_itemTextureHash; }; QT_END_NAMESPACE diff --git a/src/quick/items/context2d/qquickcanvascontext_p.h b/src/quick/items/context2d/qquickcanvascontext_p.h index 2d8fbb5f85757017af3a358a83ace226ef752e33..8988ea91059ef1d33492b19cf8e6ffe90ff58c39 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 93b9261c440a7d85f6e9f31b9371da763fe49852..f5d72bbd3acb27ce1a2cb3de72d9f86c0eb2ff18 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 cefb006648be0905d773e8ce33f5429fbfa5b1a8..3f7938c386c7654487b226a14360628c55304ff2 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 2b42a01fc152b1e12180fd44048d39c25f4c7bb7..f027e044e1c43c2b0df5fefc15e974f9a443ff8d 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 4caeaab52c8ad2ffd437969b7770be8f09c19dfe..35899339ceecd8f24fdab9f709b01217eb7bf971 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; diff --git a/src/quick/scenegraph/qsgadaptationlayer.cpp b/src/quick/scenegraph/qsgadaptationlayer.cpp index ee077dbaf1108b8536949c40a36fea736a651714..68b1882c3fcc621a50b1505b63c2e8dcb547da95 100644 --- a/src/quick/scenegraph/qsgadaptationlayer.cpp +++ b/src/quick/scenegraph/qsgadaptationlayer.cpp @@ -328,6 +328,7 @@ void QSGNodeVisitorEx::visitChildren(QSGNode *node) } break; } + case QSGNode::RootNodeType: // fall through case QSGNode::BasicNodeType: { visitChildren(child); break; @@ -339,4 +340,25 @@ void QSGNodeVisitorEx::visitChildren(QSGNode *node) } } +void QSGLayer::markDirtyTextureLater() +{ + QCoreApplication::postEvent(this, new QEvent(static_cast<QEvent::Type>(markDirtyEventType()))); +} + +void QSGLayer::customEvent(QEvent *event) +{ + if (event->type() == markDirtyEventType()) + markDirtyTexture(); + else + QObject::customEvent(event); +} + +int QSGLayer::markDirtyEventType() +{ + static int type = QEvent::None; + if (type == QEvent::None) + type = QEvent::registerEventType(); + return type; +} + QT_END_NAMESPACE diff --git a/src/quick/scenegraph/qsgadaptationlayer_p.h b/src/quick/scenegraph/qsgadaptationlayer_p.h index cc998a9cef2c8aadcbff10ea14fd6678f4be7091..2e17cfdf40eb8642a4dfc87208ff7f34360a16f7 100644 --- a/src/quick/scenegraph/qsgadaptationlayer_p.h +++ b/src/quick/scenegraph/qsgadaptationlayer_p.h @@ -158,6 +158,37 @@ public: virtual void accept(QSGNodeVisitorEx *visitor) { visitor->visit(this); visitor->visitChildren(this); visitor->endVisit(this); } }; +class Q_QUICK_EXPORT QSGLayer : public QSGDynamicTexture +{ + Q_OBJECT +public: + virtual void setItem(QSGNode *item) = 0; + virtual void setShaderSourceNode(QSGNode *node) = 0; + virtual void setRect(const QRectF &rect) = 0; + virtual void setSize(const QSize &size) = 0; + virtual void scheduleUpdate() = 0; + virtual QImage toImage() const = 0; + virtual void setLive(bool live) = 0; + virtual void setRecursive(bool recursive) = 0; + virtual void setFormat(GLenum format) = 0; + virtual void setHasMipmaps(bool mipmap) = 0; + virtual void setDevicePixelRatio(qreal ratio) = 0; + Q_SLOT virtual void markDirtyTexture() = 0; + Q_SLOT virtual void invalidated() = 0; + + Q_SLOT void markDirtyTextureLater(); + +Q_SIGNALS: + void updateRequested(); + void scheduledUpdateCompleted(); + +protected: + virtual void customEvent(QEvent *); + +private: + int markDirtyEventType(); +}; + class Q_QUICK_PRIVATE_EXPORT QSGGlyphNode : public QSGVisitableNode { public: diff --git a/src/quick/scenegraph/qsgcontext.cpp b/src/quick/scenegraph/qsgcontext.cpp index f69dd7addead279882bb09781263be1f18b6eb0c..6ebc479ec5f1fc6921db8ad115763cb94698315f 100644 --- a/src/quick/scenegraph/qsgcontext.cpp +++ b/src/quick/scenegraph/qsgcontext.cpp @@ -51,6 +51,7 @@ #include <QtQuick/private/qsgshareddistancefieldglyphcache_p.h> #include <QtQuick/private/qsgatlastexture_p.h> #include <QtQuick/private/qsgrenderloop_p.h> +#include <QtQuick/private/qsgdefaultlayer_p.h> #include <QtQuick/private/qsgtexture_p.h> #include <QtQuick/private/qquickpixmapcache_p.h> @@ -321,6 +322,14 @@ QSGNinePatchNode *QSGContext::createNinePatchNode() return 0; } +/*! + Factory function for scene graph backends of layers. + */ +QSGLayer *QSGContext::createLayer(QSGRenderContext *renderContext) +{ + return new QSGDefaultLayer(renderContext); +} + QSurfaceFormat QSGContext::defaultSurfaceFormat() const { QSurfaceFormat format = QSurfaceFormat::defaultFormat(); diff --git a/src/quick/scenegraph/qsgcontext_p.h b/src/quick/scenegraph/qsgcontext_p.h index abf1abd4c019a325152513d14690e31f1715ed96..b5271f9f372cbc7b473ae72ff212ec5367eab514 100644 --- a/src/quick/scenegraph/qsgcontext_p.h +++ b/src/quick/scenegraph/qsgcontext_p.h @@ -72,6 +72,7 @@ class QSGTexture; class QSGMaterial; class QSGMaterialShader; class QSGRenderLoop; +class QSGLayer; class QOpenGLContext; class QOpenGLFramebufferObject; @@ -177,6 +178,7 @@ public: virtual QSGImageNode *createImageNode(); virtual QSGGlyphNode *createGlyphNode(QSGRenderContext *rc, bool preferNativeGlyphNode); virtual QSGNinePatchNode *createNinePatchNode(); + virtual QSGLayer *createLayer(QSGRenderContext *renderContext); virtual QAnimationDriver *createAnimationDriver(QObject *parent); virtual QSize minimumFBOSize() const; diff --git a/src/quick/scenegraph/qsgdefaultimagenode.cpp b/src/quick/scenegraph/qsgdefaultimagenode.cpp index d925b1c7c4b3d64e3f80cd48c0f37fdd78d5f8b3..7c70a259aa2fe6e7b34cba22b0dac9c76c06642a 100644 --- a/src/quick/scenegraph/qsgdefaultimagenode.cpp +++ b/src/quick/scenegraph/qsgdefaultimagenode.cpp @@ -292,7 +292,7 @@ void QSGDefaultImageNode::update() void QSGDefaultImageNode::preprocess() { bool doDirty = false; - QSGDynamicTexture *t = qobject_cast<QSGDynamicTexture *>(m_material.texture()); + QSGLayer *t = qobject_cast<QSGLayer *>(m_material.texture()); if (t) { doDirty = t->updateTexture(); updateGeometry(); diff --git a/src/quick/scenegraph/qsgdefaultlayer.cpp b/src/quick/scenegraph/qsgdefaultlayer.cpp new file mode 100644 index 0000000000000000000000000000000000000000..c93517fe3f2ff44082892c13f7a2c6716cfa95f5 --- /dev/null +++ b/src/quick/scenegraph/qsgdefaultlayer.cpp @@ -0,0 +1,445 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include "qsgdefaultlayer_p.h" + +#include <private/qqmlglobal_p.h> +#include <private/qsgrenderer_p.h> + +#include <QOpenGLFramebufferObject> + +#ifdef QSG_DEBUG_FBO_OVERLAY +DEFINE_BOOL_CONFIG_OPTION(qmlFboOverlay, QML_FBO_OVERLAY) +#endif +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(); + } +} + +QSGDefaultLayer::QSGDefaultLayer(QSGRenderContext *context) + : QSGLayer() + , 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(context) + , m_mipmap(false) + , m_live(true) + , m_recursive(false) + , m_dirtyTexture(true) + , m_multisamplingChecked(false) + , m_multisampling(false) + , m_grab(false) +{ +} + +QSGDefaultLayer::~QSGDefaultLayer() +{ + invalidated(); +} + +void QSGDefaultLayer::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; + } +} + +int QSGDefaultLayer::textureId() const +{ + return m_fbo ? m_fbo->texture() : 0; +} + +bool QSGDefaultLayer::hasAlphaChannel() const +{ + return m_format != GL_RGB; +} + +bool QSGDefaultLayer::hasMipmaps() const +{ + return m_mipmap; +} + + +void QSGDefaultLayer::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 QSGDefaultLayer::updateTexture() +{ + bool doGrab = (m_live || m_grab) && m_dirtyTexture; + if (doGrab) + grab(); + if (m_grab) + emit scheduledUpdateCompleted(); + m_grab = false; + return doGrab; +} + +void QSGDefaultLayer::setHasMipmaps(bool mipmap) +{ + if (mipmap == m_mipmap) + return; + m_mipmap = mipmap; + if (m_mipmap && m_fbo && !m_fbo->format().mipmap()) + markDirtyTexture(); +} + + +void QSGDefaultLayer::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 QSGDefaultLayer::setRect(const QRectF &rect) +{ + if (rect == m_rect) + return; + m_rect = rect; + markDirtyTexture(); +} + +void QSGDefaultLayer::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 QSGDefaultLayer::setFormat(GLenum format) +{ + if (format == m_format) + return; + m_format = format; + markDirtyTexture(); +} + +void QSGDefaultLayer::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 QSGDefaultLayer::scheduleUpdate() +{ + if (m_grab) + return; + m_grab = true; + if (m_dirtyTexture) { + emit updateRequested(); + if (m_shaderSourceNode) + m_shaderSourceNode->markDirty(QSGNode::DirtyMaterial); + } +} + +void QSGDefaultLayer::setRecursive(bool recursive) +{ + m_recursive = recursive; +} + +void QSGDefaultLayer::markDirtyTexture() +{ + m_dirtyTexture = true; + if (m_live || m_grab) { + emit updateRequested(); + if (m_shaderSourceNode) + m_shaderSourceNode->markDirty(QSGNode::DirtyMaterial); + } +} + +void QSGDefaultLayer::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 QSGDefaultLayer::toImage() const +{ + if (m_fbo) + return m_fbo->toImage(); + + return QImage(); +} diff --git a/src/quick/scenegraph/qsgdefaultlayer_p.h b/src/quick/scenegraph/qsgdefaultlayer_p.h new file mode 100644 index 0000000000000000000000000000000000000000..47a0448846b056420b421911f327f5f9036cce67 --- /dev/null +++ b/src/quick/scenegraph/qsgdefaultlayer_p.h @@ -0,0 +1,131 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#ifndef QSGDEFAULTLAYER_P_H +#define QSGDEFAULTLAYER_P_H + +#include <private/qsgadaptationlayer_p.h> +#include <private/qsgcontext_p.h> +#include <qsgsimplerectnode.h> + +#define QSG_DEBUG_FBO_OVERLAY + +class Q_QUICK_PRIVATE_EXPORT QSGDefaultLayer : public QSGLayer +{ + Q_OBJECT +public: + QSGDefaultLayer(QSGRenderContext *context); + ~QSGDefaultLayer(); + + 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; + +public Q_SLOTS: + void markDirtyTexture(); + void invalidated(); + +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; +}; + +#endif // QSGDEFAULTLAYER_P_H diff --git a/src/quick/scenegraph/scenegraph.pri b/src/quick/scenegraph/scenegraph.pri index d08fce03362a776d57f70fb7b99944cb16d87ca1..4d9d7444b374524409031e063f323a27bbc358bd 100644 --- a/src/quick/scenegraph/scenegraph.pri +++ b/src/quick/scenegraph/scenegraph.pri @@ -81,7 +81,8 @@ HEADERS += \ $$PWD/qsgshareddistancefieldglyphcache_p.h \ $$PWD/qsgrenderloop_p.h \ $$PWD/qsgthreadedrenderloop_p.h \ - $$PWD/qsgwindowsrenderloop_p.h + $$PWD/qsgwindowsrenderloop_p.h \ + $$PWD/qsgdefaultlayer_p.h SOURCES += \ $$PWD/qsgadaptationlayer.cpp \ @@ -97,7 +98,8 @@ SOURCES += \ $$PWD/qsgshareddistancefieldglyphcache.cpp \ $$PWD/qsgrenderloop.cpp \ $$PWD/qsgthreadedrenderloop.cpp \ - $$PWD/qsgwindowsrenderloop.cpp + $$PWD/qsgwindowsrenderloop.cpp \ + $$PWD/qsgdefaultlayer.cpp RESOURCES += \ $$PWD/scenegraph.qrc