Merge branch 'qtquick2' of scm.dev.nokia.troll.no:qt/qtdeclarative-staging into qtquick2
authorAlan Alpert <alan.alpert@nokia.com>
Mon, 23 May 2011 03:08:02 +0000 (13:08 +1000)
committerAlan Alpert <alan.alpert@nokia.com>
Mon, 23 May 2011 03:08:02 +0000 (13:08 +1000)
13 files changed:
src/declarative/items/qsgimage.cpp
src/declarative/scenegraph/coreapi/qsgdefaultrenderer.cpp
src/declarative/scenegraph/coreapi/qsgdefaultrenderer_p.h
src/declarative/scenegraph/coreapi/qsgnode.cpp
src/declarative/scenegraph/coreapi/qsgnode.h
src/declarative/scenegraph/util/qsgsimpletexturenode.cpp
src/qmltest/features/qmltestcase.prf [deleted file]
tests/auto/declarative/qdeclarativedebug/tst_qdeclarativedebug.cpp
tests/auto/declarative/qdeclarativemoduleplugin/data/implicit1/implicitQmldir.errors.txt [new file with mode: 0644]
tests/auto/declarative/qdeclarativemoduleplugin/data/implicit2/implicitQmldir.2.errors.txt [new file with mode: 0644]
tests/auto/declarative/qdeclarativemoduleplugin/tst_qdeclarativemoduleplugin.cpp
tests/auto/declarative/qsgimage/data/mirror.qml
tests/auto/declarative/qsgimage/tst_qsgimage.cpp

index d280ef0..c77f7a4 100644 (file)
@@ -191,7 +191,6 @@ QSGTexture *QSGImage::texture() const
 QSGNode *QSGImage::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *)
 {
     Q_D(QSGImage);
-    //XXX Support mirror property
 
     if (!d->pix.texture() || width() <= 0 || height() <= 0) {
         delete oldNode;
@@ -273,6 +272,12 @@ QSGNode *QSGImage::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *)
                   sourceRect.width() / d->pix.width(),
                   sourceRect.height() / d->pix.height());
 
+    if (d->mirror) {
+        qreal oldLeft = nsrect.left();
+        nsrect.setLeft(nsrect.right());
+        nsrect.setRight(oldLeft);
+    }
+
     node->setHorizontalWrapMode(hWrap);
     node->setVerticalWrapMode(vWrap);
     node->setFiltering(d->smooth ? QSGTexture::Linear : QSGTexture::Nearest);
index 5680843..e2bd8f6 100644 (file)
@@ -161,6 +161,9 @@ T Heap<T, prealloc>::pop()
 
 QMLRenderer::QMLRenderer(QSGContext *context)
     : QSGRenderer(context)
+    , m_opaqueNodes(64)
+    , m_transparentNodes(64)
+    , m_tempNodes(64)
     , m_rebuild_lists(false)
     , m_needs_sorting(false)
     , m_sort_front_to_back(false)
@@ -247,8 +250,8 @@ void QMLRenderer::render()
     m_currentMatrix = 0;
 
     if (m_rebuild_lists) {
-        m_opaqueNodes.clear();
-        m_transparentNodes.clear();
+        m_opaqueNodes.reset();
+        m_transparentNodes.reset();
         m_currentRenderOrder = 1;
         buildLists(rootNode());
         m_rebuild_lists = false;
@@ -260,10 +263,12 @@ void QMLRenderer::render()
 
 
     if (m_needs_sorting) {
-        qSort(m_opaqueNodes.begin(), m_opaqueNodes.end(),
-              m_sort_front_to_back
-              ? nodeLessThanWithRenderOrder
-              : nodeLessThan);
+        if (!m_opaqueNodes.isEmpty()) {
+            qSort(&m_opaqueNodes.first(), &m_opaqueNodes.first() + m_opaqueNodes.size(),
+                  m_sort_front_to_back
+                  ? nodeLessThanWithRenderOrder
+                  : nodeLessThan);
+        }
         m_needs_sorting = false;
     }
 
@@ -370,10 +375,10 @@ void QMLRenderer::buildLists(QSGNode *node)
         if ((m->flags() & QSGMaterial::Blending) || opacity < 1) {
 #endif
             geomNode->setRenderOrder(m_currentRenderOrder - 1);
-            m_transparentNodes.append(geomNode);
+            m_transparentNodes.add(geomNode);
         } else {
             geomNode->setRenderOrder(m_currentRenderOrder);
-            m_opaqueNodes.append(geomNode);
+            m_opaqueNodes.add(geomNode);
             m_currentRenderOrder += 2;
         }
     }
@@ -398,37 +403,39 @@ void QMLRenderer::buildLists(QSGNode *node)
             endIndices[i] = m_transparentNodes.size();
         }
 
-        Heap<Foo, 16> heap;
-        m_tempNodes.clear();
         int childNodeCount = m_transparentNodes.size() - baseCount;
-        while (childNodeCount) {
-            for (int i = 0; i < count; ++i) {
-                if (beginIndices[i] != endIndices[i])
-                    heap.insert(Foo(i, m_transparentNodes.at(beginIndices[i]++)));
-            }
-            while (!heap.isEmpty()) {
-                Foo foo = heap.pop();
-                m_tempNodes.append(foo.second);
-                --childNodeCount;
-                int i = foo.first;
-                if (beginIndices[i] != endIndices[i] && !nodeLessThan(m_transparentNodes.at(beginIndices[i]), foo.second))
-                    heap.insert(Foo(i, m_transparentNodes.at(beginIndices[i]++)));
+        if (childNodeCount) {
+            Heap<Foo, 16> heap;
+            m_tempNodes.reset();
+            m_tempNodes.reserve(childNodeCount);
+            while (childNodeCount) {
+                for (int i = 0; i < count; ++i) {
+                    if (beginIndices[i] != endIndices[i])
+                        heap.insert(Foo(i, m_transparentNodes.at(beginIndices[i]++)));
+                }
+                while (!heap.isEmpty()) {
+                    Foo foo = heap.pop();
+                    m_tempNodes.add(foo.second);
+                    --childNodeCount;
+                    int i = foo.first;
+                    if (beginIndices[i] != endIndices[i] && !nodeLessThan(m_transparentNodes.at(beginIndices[i]), foo.second))
+                        heap.insert(Foo(i, m_transparentNodes.at(beginIndices[i]++)));
+                }
             }
-        }
-        Q_ASSERT(m_tempNodes.size() == m_transparentNodes.size() - baseCount);
+            Q_ASSERT(m_tempNodes.size() == m_transparentNodes.size() - baseCount);
 
-        m_transparentNodes.resize(baseCount);
-        m_transparentNodes << m_tempNodes;
+            qMemCopy(&m_transparentNodes.at(baseCount), &m_tempNodes.at(0), m_tempNodes.size() * sizeof(QSGGeometryNode *));
+        }
     } else {
         for (int i = 0; i < count; ++i)
             buildLists(node->childAtIndex(i));
     }
 }
 
-void QMLRenderer::renderNodes(const QVector<QSGGeometryNode *> &list)
+void QMLRenderer::renderNodes(const QDataBuffer<QSGGeometryNode *> &list)
 {
     const float scale = 1.0f / m_currentRenderOrder;
-    int count = list.count();
+    int count = list.size();
     int currentRenderOrder = 0x80000000;
 
     //int clipChangeCount = 0;
index 805388a..ca1f559 100644 (file)
@@ -44,6 +44,8 @@
 
 #include "qsgrenderer_p.h"
 
+#include <QtGui/private/qdatabuffer_p.h>
+
 QT_BEGIN_HEADER
 
 QT_BEGIN_NAMESPACE
@@ -65,16 +67,16 @@ public:
 
 private:
     void buildLists(QSGNode *node);
-    void renderNodes(const QVector <QSGGeometryNode *> &list);
+    void renderNodes(const QDataBuffer<QSGGeometryNode *> &list);
 
     const QSGClipNode *m_currentClip;
     QSGMaterial *m_currentMaterial;
     QSGMaterialShader *m_currentProgram;
     const QMatrix4x4 *m_currentMatrix;
     QMatrix4x4 m_renderOrderMatrix;
-    QVector<QSGGeometryNode *> m_opaqueNodes;
-    QVector<QSGGeometryNode *> m_transparentNodes;
-    QVector<QSGGeometryNode *> m_tempNodes;
+    QDataBuffer<QSGGeometryNode *> m_opaqueNodes;
+    QDataBuffer<QSGGeometryNode *> m_transparentNodes;
+    QDataBuffer<QSGGeometryNode *> m_tempNodes;
 
     bool m_rebuild_lists;
     bool m_needs_sorting;
index 7e19339..3472c93 100644 (file)
@@ -83,9 +83,24 @@ static void qt_print_node_count()
 
 QSGNode::QSGNode()
     : m_parent(0)
+    , m_type(BasicNodeType)
     , m_nodeFlags(OwnedByParent)
     , m_flags(0)
 {
+    init();
+}
+
+QSGNode::QSGNode(NodeType type)
+    : m_parent(0)
+    , m_type(type)
+    , m_nodeFlags(OwnedByParent)
+    , m_flags(0)
+{
+    init();
+}
+
+void QSGNode::init()
+{
 #ifndef QT_NO_DEBUG
     ++qt_node_count;
     static bool atexit_registered = false;
@@ -94,7 +109,6 @@ QSGNode::QSGNode()
         atexit_registered = true;
     }
 #endif
-
 }
 
 QSGNode::~QSGNode()
@@ -369,8 +383,9 @@ void QSGNode::markDirty(DirtyFlags flags)
 /*!
     Creates a new basic geometry node.
  */
-QSGBasicGeometryNode::QSGBasicGeometryNode()
-    : m_geometry(0)
+QSGBasicGeometryNode::QSGBasicGeometryNode(NodeType type)
+    : QSGNode(type)
+    , m_geometry(0)
     , m_matrix(0)
     , m_clip_list(0)
 {
@@ -443,7 +458,8 @@ void QSGBasicGeometryNode::setGeometry(QSGGeometry *geometry)
  */
 
 QSGGeometryNode::QSGGeometryNode()
-    : m_render_order(0)
+    : QSGBasicGeometryNode(GeometryNodeType)
+    , m_render_order(0)
     , m_material(0)
     , m_opaque_material(0)
     , m_opacity(1)
@@ -608,6 +624,7 @@ void QSGGeometryNode::setInheritedOpacity(qreal opacity)
  */
 
 QSGClipNode::QSGClipNode()
+    : QSGBasicGeometryNode(ClipNodeType)
 {
 }
 
@@ -686,6 +703,7 @@ void QSGClipNode::setClipRect(const QRectF &rect)
  */
 
 QSGTransformNode::QSGTransformNode()
+    : QSGNode(TransformNodeType)
 {
 }
 
@@ -754,6 +772,10 @@ void QSGTransformNode::setCombinedMatrix(const QMatrix4x4 &matrix)
     Creates a new root node.
  */
 
+QSGRootNode::QSGRootNode()
+    : QSGNode(RootNodeType)
+{
+}
 
 
 /*!
@@ -812,7 +834,8 @@ void QSGRootNode::notifyNodeChange(QSGNode *node, DirtyFlags flags)
     The default opacity of nodes is 1.
   */
 QSGOpacityNode::QSGOpacityNode()
-    : m_opacity(1)
+    : QSGNode(OpacityNodeType)
+    , m_opacity(1)
     , m_combined_opacity(1)
 {
 }
index a905696..a391b55 100644 (file)
@@ -126,7 +126,7 @@ public:
     int childCount() const { return m_children.size(); }
     QSGNode *childAtIndex(int i) const { return m_children.at(i); }
 
-    virtual NodeType type() const { return BasicNodeType; }
+    inline NodeType type() const { return m_type; }
 
     void clearDirty() { m_flags = 0; }
     void markDirty(DirtyFlags flags);
@@ -145,22 +145,21 @@ public:
 #endif
 
 protected:
+    QSGNode(NodeType type);
+
     // When a node is destroyed, it will detach from the scene graph and the renderer will be
     // notified about the change. If the node is detached in the base node's destructor, the
-    // renderer can't check what type the node originally was because the node's type() method is
-    // virtual and will return the base node type. The renderer might therefore react incorrectly
-    // to the change. There are a few of ways I can think of to solve the problem:
-    // - The renderer must take into account that the notify method might be called from a node's
-    //   destructor.
-    // - The node can have a type property that is set in the constructor.
-    // - All the node destructors must call a common destroy method.
-    // I choose the third option since that will allow the renderer to treat the nodes as their
-    // proper types.
+    // renderer can't safely cast the node to its original type, since at this point it has been
+    // partly destroyed already. To solve this problem, all the node destructors must call a common
+    // destroy method.
 
     void destroy();
 
 private:
+    void init();
+
     QSGNode *m_parent;
+    NodeType m_type;
     QList<QSGNode *> m_children;
 
     Flags m_nodeFlags;
@@ -183,7 +182,6 @@ public:
 //    void setUsagePattern(UsagePattern pattern);
 //    UsagePattern usagePattern() const { return m_pattern; }
 
-    QSGBasicGeometryNode();
     ~QSGBasicGeometryNode();
 
     void setGeometry(QSGGeometry *geometry);
@@ -193,6 +191,9 @@ public:
     const QMatrix4x4 *matrix() const { return m_matrix; }
     const QSGClipNode *clipList() const { return m_clip_list; }
 
+protected:
+    QSGBasicGeometryNode(NodeType type);
+
 private:
     friend class QSGNodeUpdater;
     QSGGeometry *m_geometry;
@@ -222,8 +223,6 @@ public:
 
     QSGMaterial *activeMaterial() const;
 
-    virtual NodeType type() const { return GeometryNodeType; }
-
     void setRenderOrder(int order);
     int renderOrder() const { return m_render_order; }
 
@@ -246,8 +245,6 @@ public:
     QSGClipNode();
     ~QSGClipNode();
 
-    virtual NodeType type() const { return ClipNodeType; }
-
     void setIsRectangular(bool rectHint);
     bool isRectangular() const { return m_is_rectangular; }
 
@@ -268,8 +265,6 @@ public:
     QSGTransformNode();
     ~QSGTransformNode();
 
-    virtual NodeType type() const { return TransformNodeType; }
-
     void setMatrix(const QMatrix4x4 &matrix);
     const QMatrix4x4 &matrix() const { return m_matrix; }
 
@@ -285,8 +280,8 @@ private:
 class Q_DECLARATIVE_EXPORT QSGRootNode : public QSGNode
 {
 public:
+    QSGRootNode();
     ~QSGRootNode();
-    NodeType type() const { return RootNodeType; }
 
 private:
     void notifyNodeChange(QSGNode *node, DirtyFlags flags);
@@ -311,11 +306,8 @@ public:
     void setCombinedOpacity(qreal opacity);
     qreal combinedOpacity() const { return m_combined_opacity; }
 
-    virtual QSGNode::NodeType type() const { return OpacityNodeType; }
-
     bool isSubtreeBlocked() const;
 
-
 private:
     qreal m_opacity;
     qreal m_combined_opacity;
index 3438d16..a3c96dc 100644 (file)
@@ -52,7 +52,7 @@ static void qsgsimpletexturenode_update(QSGGeometry *g,
         return;
 
     QSize ts = texture->textureSize();
-    QRectF sourceRect(0, ts.height(), ts.width(), -ts.height());
+    QRectF sourceRect(0, 0, ts.width(), ts.height());
     QSGGeometry::updateTexturedRectGeometry(g, rect, texture->convertToNormalizedSourceRect(sourceRect));
 }
 
diff --git a/src/qmltest/features/qmltestcase.prf b/src/qmltest/features/qmltestcase.prf
deleted file mode 100644 (file)
index a3d66e6..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-CONFIG += testcase
-
-!symbian {
-    INCLUDEPATH += $$[QT_INSTALL_HEADERS]/QtQuickTest
-} else {
-    load(data_caging_paths)
-
-    INCLUDEPATH+=$$MW_LAYER_PUBLIC_EXPORT_PATH(QtQuickTest)
-}
-
-QT += declarative
-
-win32:CONFIG(debug, debug|release) {
-    LIBS += -lQtQuickTest$${QT_LIBINFIX}d
-} else {
-    LIBS += -lQtQuickTest$${QT_LIBINFIX}
-}
-
-# If the .pro file specified an IMPORTPATH, then add that to
-# the command-line when the test is run.
-!isEmpty(IMPORTPATH) {
-    load(testcase)
-    for(import, IMPORTPATH): check.commands += -import \"$$import\"
-}
-DEFINES += QUICK_TEST_SOURCE_DIR=\"\\\"$$OUT_PWD\\\"\"
index dba2007..b6f5c94 100644 (file)
@@ -1027,7 +1027,7 @@ void tst_QDeclarativeDebug::setBindingForObject()
     // set handler
     //
     rootObject = findRootObject();
-    QCOMPARE(rootObject.children().size(), 4); // Rectangle, Text, MouseArea, QDeclarativeComponentAttached
+    QCOMPARE(rootObject.children().size(), 5); // Rectangle, Text, MouseArea, Component.onCompleted, NonScriptPropertyElement
     QDeclarativeDebugObjectReference mouseAreaObject = rootObject.children().at(2);
     QDeclarativeDebugObjectQuery *q_obj = m_dbg->queryObjectRecursive(mouseAreaObject, this);
     waitForQuery(q_obj);
diff --git a/tests/auto/declarative/qdeclarativemoduleplugin/data/implicit1/implicitQmldir.errors.txt b/tests/auto/declarative/qdeclarativemoduleplugin/data/implicit1/implicitQmldir.errors.txt
new file mode 100644 (file)
index 0000000..ce3b796
--- /dev/null
@@ -0,0 +1 @@
+-1:-1:module "" plugin "AType" not found
diff --git a/tests/auto/declarative/qdeclarativemoduleplugin/data/implicit2/implicitQmldir.2.errors.txt b/tests/auto/declarative/qdeclarativemoduleplugin/data/implicit2/implicitQmldir.2.errors.txt
new file mode 100644 (file)
index 0000000..9cafb78
--- /dev/null
@@ -0,0 +1,3 @@
+1:12:unexpected token
+1:-1:expected '.'
+2:17:unexpected token
index 06b65d3..338a07f 100644 (file)
@@ -71,6 +71,7 @@ private slots:
     void versionNotInstalled();
     void versionNotInstalled_data();
     void implicitQmldir();
+    void implicitQmldir_data();
 };
 
 #ifdef Q_OS_SYMBIAN
@@ -85,7 +86,8 @@ private slots:
         QVERIFY(!component.isError()); \
         QVERIFY(component.errors().isEmpty()); \
     } else { \
-        QFile file(QLatin1String("data/") + QLatin1String(errorfile)); \
+        QString verify_errors_file_name = QLatin1String(SRCDIR) + QDir::separator() + QLatin1String("data") + QDir::separator() + QLatin1String(errorfile); \
+        QFile file(verify_errors_file_name); \
         QVERIFY(file.open(QIODevice::ReadOnly | QIODevice::Text)); \
         QByteArray data = file.readAll(); \
         file.close(); \
@@ -100,10 +102,11 @@ private slots:
                                   error.description().toUtf8(); \
             actual << errorStr; \
         } \
-        if (qgetenv("DEBUG") != "" && expected != actual) \
-            qWarning() << "Expected:" << expected << "Actual:" << actual;  \
+        if (qgetenv("DEBUG") != "" && expected != actual) { \
+            qWarning() << "Expected:" << expected << "Actual:" << actual; \
+        } \
         if (qgetenv("QDECLARATIVELANGUAGE_UPDATEERRORS") != "" && expected != actual) {\
-            QFile file(QLatin1String("data/") + QLatin1String(errorfile)); \
+            QFile file(QLatin1String(SRCDIR) + QDir::separator() + QLatin1String("data") + QDir::separator() + QLatin1String(errorfile)); \
             QVERIFY(file.open(QIODevice::WriteOnly)); \
             for (int ii = 0; ii < actual.count(); ++ii) { \
                 file.write(actual.at(ii)); file.write("\n"); \
@@ -310,46 +313,37 @@ void tst_qdeclarativemoduleplugin::versionNotInstalled()
 
 
 // test that errors are reporting correctly for plugin loading and qmldir parsing
+void tst_qdeclarativemoduleplugin::implicitQmldir_data()
+{
+    QTest::addColumn<QString>("directory");
+    QTest::addColumn<QString>("file");
+    QTest::addColumn<QString>("errorFile");
+
+    // parsing qmldir succeeds, but plugin specified in the qmldir file doesn't exist
+    QTest::newRow("implicitQmldir") << "implicit1" << "temptest.qml" << "implicitQmldir.errors.txt";
+
+    // parsing qmldir fails due to syntax errors, etc.
+    QTest::newRow("implicitQmldir2") << "implicit2" << "temptest2.qml" << "implicitQmldir.2.errors.txt";
+}
 void tst_qdeclarativemoduleplugin::implicitQmldir()
 {
-    QDeclarativeEngine engine;
+    QFETCH(QString, directory);
+    QFETCH(QString, file);
+    QFETCH(QString, errorFile);
 
-    QObject *obj = 0;
-    QList<QDeclarativeError> errors;
-    QString qmldirUrl;
-    QStringList expectedErrors;
+    QString importPath = QLatin1String(SRCDIR) + QDir::separator() + QLatin1String("data") + QDir::separator() + directory;
+    QString fileName = QLatin1String("data") + QDir::separator() + directory + QDir::separator() + file;
+    QString errorFileName = directory + QDir::separator() + errorFile;
+    QUrl testFileUrl = TEST_FILE(fileName);
 
-    // parsing qmldir succeeds, but plugin specified in the qmldir file doesn't exist
-    QDeclarativeComponent c(&engine, TEST_FILE("data/implicit1/temptest.qml"));
-    qmldirUrl = TEST_FILE("data/implicit1/qmldir").toString();
-    errors = c.errors();
-    QString moduleName = TEST_FILE("data/implicit1").toString().remove(0,7).replace(QLatin1String("/"), QLatin1String("."));
-    expectedErrors << QString(QLatin1String(": module \"") + moduleName + QLatin1String("\" plugin \"AType\" not found"));
-    QVERIFY(errors.size() == expectedErrors.size());
-    for (int i = 0; i < errors.size(); ++i) {
-        QString msg = qmldirUrl + expectedErrors.at(i);
-        QCOMPARE(errors.at(i).toString(), msg); // ensure that the expected message matches the real message.
-    }
-    QTest::ignoreMessage(QtWarningMsg, "QDeclarativeComponent: Component is not ready");
-    obj = c.create();
-    QVERIFY(!obj);
-    delete obj;
+    QDeclarativeEngine engine;
+    engine.addImportPath(importPath);
 
-    // parsing qmldir fails due to syntax errors etc.
-    QDeclarativeComponent c2(&engine, TEST_FILE("data/implicit2/temptest2.qml"));
-    qmldirUrl = TEST_FILE("data/implicit2/qmldir").toString();
-    errors = c2.errors();
-    expectedErrors = QStringList();
-    expectedErrors << QLatin1String(":1:12: unexpected token");
-    expectedErrors << QLatin1String(":1: expected '.'");
-    expectedErrors << QLatin1String(":2:17: unexpected token");
-    QVERIFY(errors.size() == expectedErrors.size());
-    for (int i = 0; i < errors.size(); ++i) {
-        QString msg = qmldirUrl + expectedErrors.at(i);
-        QCOMPARE(errors.at(i).toString(), msg); // ensure that the expected message matches the real message.
-    }
+    QDeclarativeComponent component(&engine, testFileUrl);
+    QList<QDeclarativeError> errors = component.errors();
+    VERIFY_ERRORS(errorFileName.toLatin1().constData());
     QTest::ignoreMessage(QtWarningMsg, "QDeclarativeComponent: Component is not ready");
-    obj = c2.create();
+    QObject *obj = component.create();
     QVERIFY(!obj);
     delete obj;
 }
index 69bdcb9..101a3a2 100644 (file)
@@ -1,5 +1,11 @@
 import QtQuick 2.0
 
-Image {
-    source: "heart200.png"
+Rectangle {
+    width: 300
+    height: 250
+    Image {
+        objectName: "image"
+        anchors.fill: parent
+        source: "heart200.png"
+    }
 }
index ff5de4b..a8dadf0 100644 (file)
@@ -284,17 +284,16 @@ void tst_qsgimage::mirror()
     qreal height = 250;
 
     QSGView *canvas = new QSGView;
-    canvas->show();
     canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/mirror.qml"));
 
-    QSGImage *obj = qobject_cast<QSGImage*>(canvas->rootObject());
+    QSGImage *obj = canvas->rootObject()->findChild<QSGImage*>("image");
     QVERIFY(obj != 0);
 
-    obj->setProperty("width", width);
-    obj->setProperty("height", height);
     obj->setFillMode((QSGImage::FillMode)fillMode);
     obj->setProperty("mirror", true);
 
+    canvas->show();
+
     QPixmap screenshot = canvas->renderPixmap();
 
     QPixmap srcPixmap;