fix several canvasitem bugs
authorCharles Yin <charles.yin@nokia.com>
Tue, 11 Oct 2011 06:23:50 +0000 (16:23 +1000)
committerQt by Nokia <qt-info@nokia.com>
Wed, 12 Oct 2011 00:36:56 +0000 (02:36 +0200)
Change-Id: I6a6d97253fe66184736f8ac089e97aa114f0e83a
Reviewed-on: http://codereview.qt-project.org/6405
Sanity-Review: Qt Sanity Bot <qt_sanity_bot@ovi.com>
Reviewed-by: Charles Yin <charles.yin@nokia.com>
src/declarative/items/context2d/qsgcanvasitem.cpp
src/declarative/items/context2d/qsgcontext2dnode.cpp
src/declarative/items/context2d/qsgcontext2dnode_p.h
src/declarative/items/context2d/qsgcontext2dtexture.cpp
src/declarative/items/context2d/qsgcontext2dtexture_p.h
tests/auto/declarative/qsgcanvasitem/data/tst_canvas.qml

index deb3493..43bb734 100644 (file)
@@ -425,6 +425,7 @@ void QSGCanvasItem::componentComplete()
     d->baseUrl = qmlEngine(this)->contextForObject(this)->baseUrl();
     requestPaint();
     updatePolish(); //force update the canvas sizes to texture for the first time
+    update();
     d->componentCompleted = true;
 }
 
@@ -453,6 +454,7 @@ QSGNode *QSGCanvasItem::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *)
         node = new QSGContext2DNode(this);
 
     node->setTexture(d->texture);
+    node->setSize(d->canvasWindow.size());
     node->update();
     return node;
 }
index 4173b32..e20d649 100644 (file)
@@ -52,6 +52,7 @@ QSGContext2DNode::QSGContext2DNode(QSGCanvasItem* item)
     , m_item(item)
     , m_geometry(QSGGeometry::defaultAttributes_TexturedPoint2D(), 4)
     , m_texture(0)
+    , m_size(1, 1)
     , m_dirtyGeometry(false)
     , m_dirtyTexture(false)
 {
@@ -65,13 +66,20 @@ QSGContext2DNode::~QSGContext2DNode()
 {
 }
 
+void QSGContext2DNode::setSize(const QSizeF& size)
+{
+    if (m_size != size) {
+        m_dirtyGeometry = true;
+        m_size = size;
+    }
+}
+
 void QSGContext2DNode::preprocess()
 {
     bool doDirty = false;
     QSGDynamicTexture *t = qobject_cast<QSGDynamicTexture *>(m_material.texture());
     if (t) {
         doDirty = t->updateTexture();
-        updateGeometry();
     }
     if (doDirty) {
         m_dirtyTexture = true;
@@ -106,10 +114,9 @@ void QSGContext2DNode::updateTexture()
 
 void QSGContext2DNode::updateGeometry()
 {
-    QSizeF size = m_item->canvasWindow().size();
     QRectF source = m_texture->textureSubRect();
     QSGGeometry::updateTexturedRectGeometry(&m_geometry,
-                                            QRectF(0, 0, size.width(), size.height()),
+                                            QRectF(0, 0, m_size.width(), m_size.height()),
                                             source);
     markDirty(DirtyGeometry);
 }
index 70446d7..957c14b 100644 (file)
@@ -63,6 +63,7 @@ public:
     void setTexture(QSGContext2DTexture* texture);
     void update();
     void preprocess();
+    void setSize(const QSizeF& size);
 private:
     void updateTexture();
     void updateGeometry();
@@ -72,6 +73,7 @@ private:
     QSGTextureMaterial m_materialO;
     QSGGeometry m_geometry;
     QSGContext2DTexture* m_texture;
+    QSizeF m_size;
 
     bool m_dirtyGeometry;
     bool m_dirtyTexture;
index c84dda4..617d666 100644 (file)
@@ -101,8 +101,6 @@ void QSGContext2DTexture::markDirtyTexture()
     m_dirtyTexture = true;
     unlock();
     emit textureChanged();
-    if (m_item)
-        emit m_item->painted();
 }
 
 bool QSGContext2DTexture::setCanvasSize(const QSize &size)
@@ -144,6 +142,7 @@ void QSGContext2DTexture::setItem(QSGCanvasItem* item)
         m_context = item->context();
         m_state = m_context->state;
         unlock();
+        connect(this, SIGNAL(textureChanged()), m_item, SIGNAL(painted()));
     }
 }
 
@@ -412,6 +411,13 @@ QSGContext2DFBOTexture::QSGContext2DFBOTexture()
     m_threadRendering = false;
 }
 
+QSGContext2DFBOTexture::~QSGContext2DFBOTexture()
+{
+    delete m_fbo;
+    delete m_multisampledFbo;
+    delete m_paint_device;
+}
+
 bool QSGContext2DFBOTexture::setCanvasSize(const QSize &size)
 {
     QSize s = QSize(qMax(QT_MINIMUM_FBO_SIZE, qt_next_power_of_two(size.width()))
@@ -464,9 +470,9 @@ void QSGContext2DFBOTexture::bind()
 QRectF QSGContext2DFBOTexture::textureSubRect() const
 {
     return QRectF(0
-                , 1
+                , 0
                 , qreal(m_canvasWindow.width()) / m_fboSize.width()
-                , qreal(-m_canvasWindow.height()) / m_fboSize.height());
+                , qreal(m_canvasWindow.height()) / m_fboSize.height());
 }
 
 
@@ -570,6 +576,7 @@ QPaintDevice* QSGContext2DFBOTexture::beginPainting()
         delete m_multisampledFbo;
         m_fbo = 0;
         m_multisampledFbo = 0;
+        return 0;
     } else if (!m_fbo || m_fbo->size() != m_fboSize) {
         delete m_fbo;
         delete m_multisampledFbo;
@@ -585,20 +592,23 @@ QPaintDevice* QSGContext2DFBOTexture::beginPainting()
                 format.setAttachment(QOpenGLFramebufferObject::NoAttachment);
                 m_fbo = new QOpenGLFramebufferObject(m_fboSize, format);
             }
-            m_multisampledFbo->bind();
         } else {
             QOpenGLFramebufferObjectFormat format;
             format.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil);
-            delete m_fbo;
 
             m_fbo = new QOpenGLFramebufferObject(m_fboSize, format);
-            m_fbo->bind();
         }
     }
 
+    if (doMultisampling())
+        m_multisampledFbo->bind();
+    else
+        m_fbo->bind();
+
 
     if (!m_paint_device) {
         QOpenGLPaintDevice *gl_device = new QOpenGLPaintDevice(m_fbo->size());
+        gl_device->setPaintFlipped(true);
         m_paint_device = gl_device;
     }
 
index 716de87..1555120 100644 (file)
@@ -133,6 +133,7 @@ class QSGContext2DFBOTexture : public QSGContext2DTexture
 
 public:
     QSGContext2DFBOTexture();
+    ~QSGContext2DFBOTexture();
     virtual int textureId() const;
     virtual bool updateTexture();
     virtual QSGContext2DTile* createTile() const;
index db61fce..70bedb2 100644 (file)
@@ -222,10 +222,11 @@ Rectangle {
            verify(c);
 
            c.renderTarget = Canvas.Image;
-
-           c.requestPaint();
-           wait(100);
+           c.renderInThread = true;
+           var ctx = c.getContext();
+           ctx.fillRect(0, 0, c.width, c.height);
            c.toDataURL();
+           wait(100);
 
            compare(c.paintedCount, 1);
            compare(c.paintCount, 1);