Merge remote-tracking branch 'origin/5.4' into dev
authorOswald Buddenhagen <oswald.buddenhagen@digia.com>
Thu, 11 Sep 2014 08:44:17 +0000 (10:44 +0200)
committerOswald Buddenhagen <oswald.buddenhagen@digia.com>
Thu, 11 Sep 2014 08:44:17 +0000 (10:44 +0200)
Conflicts:
src/quick/items/qquickpainteditem.h
src/quick/items/qquickshadereffectsource.cpp
src/quick/items/qquickshadereffectsource_p.h

Change-Id: If98096443afe85fc4370cef971eace050006a61b

69 files changed:
1  2 
src/quick/items/context2d/qquickcanvasitem_p.h
src/quick/items/context2d/qquickcontext2dcommandbuffer.cpp
src/quick/items/qquickaccessibleattached.cpp
src/quick/items/qquickaccessibleattached_p.h
src/quick/items/qquickanchors_p_p.h
src/quick/items/qquickanimatedimage_p.h
src/quick/items/qquickanimatedsprite.cpp
src/quick/items/qquickanimatedsprite_p.h
src/quick/items/qquickborderimage_p.h
src/quick/items/qquickdrag.cpp
src/quick/items/qquickdroparea_p.h
src/quick/items/qquickflickable.cpp
src/quick/items/qquickflickable_p.h
src/quick/items/qquickflickable_p_p.h
src/quick/items/qquickflipable.cpp
src/quick/items/qquickflipable_p.h
src/quick/items/qquickframebufferobject.h
src/quick/items/qquickgridview.cpp
src/quick/items/qquickgridview_p.h
src/quick/items/qquickimage_p.h
src/quick/items/qquickimagebase_p.h
src/quick/items/qquickimplicitsizeitem_p_p.h
src/quick/items/qquickitem.h
src/quick/items/qquickitem_p.h
src/quick/items/qquickitemanimation.cpp
src/quick/items/qquickitemanimation_p.h
src/quick/items/qquickitemview_p.h
src/quick/items/qquickitemview_p_p.h
src/quick/items/qquickitemviewtransition.cpp
src/quick/items/qquicklistview.cpp
src/quick/items/qquicklistview_p.h
src/quick/items/qquickloader_p.h
src/quick/items/qquickloader_p_p.h
src/quick/items/qquickmultipointtoucharea_p.h
src/quick/items/qquickpainteditem.h
src/quick/items/qquickpathview_p.h
src/quick/items/qquickpathview_p_p.h
src/quick/items/qquickpincharea_p.h
src/quick/items/qquickpositioners_p.h
src/quick/items/qquickpositioners_p_p.h
src/quick/items/qquickrectangle_p.h
src/quick/items/qquickrepeater_p.h
src/quick/items/qquickshadereffect_p.h
src/quick/items/qquickshadereffectmesh_p.h
src/quick/items/qquickshadereffectnode.cpp
src/quick/items/qquickshadereffectnode_p.h
src/quick/items/qquickshadereffectsource_p.h
src/quick/items/qquicksprite_p.h
src/quick/items/qquickspriteengine_p.h
src/quick/items/qquickspritesequence.cpp
src/quick/items/qquickspritesequence_p.h
src/quick/items/qquickstateoperations_p.h
src/quick/items/qquicktext_p.h
src/quick/items/qquicktext_p_p.h
src/quick/items/qquicktextcontrol_p.h
src/quick/items/qquicktextedit_p.h
src/quick/items/qquicktextedit_p_p.h
src/quick/items/qquicktextinput_p.h
src/quick/items/qquicktextinput_p_p.h
src/quick/items/qquicktranslate_p.h
src/quick/items/qquickview.h
src/quick/items/qquickview_p.h
src/quick/items/qquickwindow.cpp
src/quick/items/qquickwindow.h
src/quick/items/qquickwindowmodule.cpp
src/quick/scenegraph/qsgdefaultlayer.cpp
src/quick/scenegraph/qsgdefaultlayer_p.h
src/quick/scenegraph/util/qsgvertexcolormaterial.cpp
src/quickwidgets/qquickwidget.h

@@@ -164,15 -159,15 +159,15 @@@ public Q_SLOTS
  private Q_SLOTS:
      void sceneGraphInitialized();
      void checkAnimationCallbacks();
-     void invalidateSG();
+     void invalidateSceneGraph();
  
  protected:
 -    void componentComplete();
 -    void itemChange(QQuickItem::ItemChange, const QQuickItem::ItemChangeData &);
 -    void updatePolish();
 -    QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *);
 -    void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry);
 -    void releaseResources();
 +    void componentComplete() Q_DECL_OVERRIDE;
 +    void itemChange(QQuickItem::ItemChange, const QQuickItem::ItemChangeData &) Q_DECL_OVERRIDE;
 +    void updatePolish() Q_DECL_OVERRIDE;
 +    QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *) Q_DECL_OVERRIDE;
 +    void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) Q_DECL_OVERRIDE;
 +    void releaseResources() Q_DECL_OVERRIDE;
  private:
      Q_DECLARE_PRIVATE(QQuickCanvasItem)
      Q_INVOKABLE void delayedCreate();
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
@@@ -83,8 -75,12 +75,12 @@@ public
  
      virtual Renderer *createRenderer() const = 0;
  
+     bool isTextureProvider() const Q_DECL_OVERRIDE;
+     QSGTextureProvider *textureProvider() const Q_DECL_OVERRIDE;
+     void releaseResources() Q_DECL_OVERRIDE;
  protected:
 -    void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry);
 +    void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) Q_DECL_OVERRIDE;
  
  protected:
      QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *) Q_DECL_OVERRIDE;
Simple merge
Simple merge
Simple merge
Simple merge
@@@ -383,11 -375,8 +375,8 @@@ Q_SIGNALS
      void implicitWidthChanged();
      void implicitHeightChanged();
  
-     Q_REVISION(2) void sceneGraphInvalidated();
-     Q_REVISION(2) void sceneGraphInitialized();
  protected:
 -    virtual bool event(QEvent *);
 +    bool event(QEvent *) Q_DECL_OVERRIDE;
  
      bool isComponentComplete() const;
      virtual void itemChange(ItemChange, const ItemChangeData &);
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
@@@ -112,7 -107,11 +107,11 @@@ Q_SIGNALS
  
  protected:
      QQuickPaintedItem(QQuickPaintedItemPrivate &dd, QQuickItem *parent = 0);
 -    virtual QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *);
 +    QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *) Q_DECL_OVERRIDE;
+     void releaseResources() Q_DECL_OVERRIDE;
+ private Q_SLOTS:
+     void invalidateSceneGraph();
  
  private:
      Q_DISABLE_COPY(QQuickPaintedItem)
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
@@@ -60,11 -52,12 +52,12 @@@ public
  protected:
      friend class QQuickShaderEffectNode;
  
 -    virtual void compile();
 -    virtual const char *vertexShader() const;
 -    virtual const char *fragmentShader() const;
 +    void compile() Q_DECL_OVERRIDE;
 +    const char *vertexShader() const Q_DECL_OVERRIDE;
 +    const char *fragmentShader() const Q_DECL_OVERRIDE;
  
      const QQuickShaderEffectMaterialKey m_key;
+     QVector<QByteArray> m_attributes;
      QVector<const char *> m_attributeNames;
      QString m_log;
      bool m_compiled;
@@@ -235,14 -132,14 +132,14 @@@ Q_SIGNALS
  
  private Q_SLOTS:
      void sourceItemDestroyed(QObject *item);
-     void invalidateSG();
+     void invalidateSceneGraph();
  
  protected:
 -    virtual void releaseResources();
 -    virtual QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *);
 +    void releaseResources() Q_DECL_OVERRIDE;
 +    QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *) Q_DECL_OVERRIDE;
  
 -    virtual void itemGeometryChanged(QQuickItem *item, const QRectF &newRect, const QRectF &oldRect);
 -    virtual void itemChange(ItemChange change, const ItemChangeData &value);
 +    void itemGeometryChanged(QQuickItem *item, const QRectF &newRect, const QRectF &oldRect) Q_DECL_OVERRIDE;
 +    void itemChange(ItemChange change, const ItemChangeData &value) Q_DECL_OVERRIDE;
  
  private:
      void ensureTexture();
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
index 0000000,c93517f..29f125e
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,445 +1,445 @@@
 -        virtual void bind() const;
+ /****************************************************************************
+ **
+ ** 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();
++        void bind() const Q_DECL_OVERRIDE;
+     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();
+ }
index 0000000,47a0448..b4a5ada
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,131 +1,131 @@@
 -    virtual bool updateTexture();
+ /****************************************************************************
+ **
+ ** 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();
++    bool updateTexture() Q_DECL_OVERRIDE;
+     // 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
Simple merge