diff --git a/src/qml/debugger/debugger.pri b/src/qml/debugger/debugger.pri
index 2545c7836d6933aeb74049ed272230eb5f25f224..77a3ba64909076cba607fc3a8bf3f1dc6d287503 100644
--- a/src/qml/debugger/debugger.pri
+++ b/src/qml/debugger/debugger.pri
@@ -34,8 +34,3 @@ HEADERS += \
     $$PWD/qqmlprofiler_p.h
 
 INCLUDEPATH += $$PWD
-
-!contains(DEFINES, QT_QML_NO_DEBUGGER): static {
-    DEFINES += QML_DEBUGGER_EMBED
-    include(../../plugins/qmltooling/qmldbg_tcp/qmldbg_tcp.pri)
-}
diff --git a/src/quick/doc/src/examples.qdoc b/src/quick/doc/src/examples.qdoc
index 51525b8f579b44adcf2129708979c4b4827124bb..0ec4507450f22cd18a8f67d88a60505634818845 100644
--- a/src/quick/doc/src/examples.qdoc
+++ b/src/quick/doc/src/examples.qdoc
@@ -72,8 +72,8 @@ The following pages show how to develop Qt applications using
 \l{Qt Creator Manual}{Qt Creator} and Qt Quick. The pages demonstrate various
 steps such as use cases and introductory material. For more information about Qt Quick Applications and related modules, visit the \l{QML Applications} page.
 
-\div {class="landingicons"}
-    \div {class="icons1of3"}
+\div {class="multi-column"}
+    \div {class="doc-column"}
         \b{Development Environment}
         \list
         \li \l{Qt Creator: Creating Qt Quick Projects}{Creating Qt Quick Projects}
@@ -84,7 +84,7 @@ steps such as use cases and introductory material. For more information about Qt
         \li \l{Qt Creator: Using QML Modules with Plugins}{Using QML Modules with Plugins}
         \endlist
     \enddiv
-    \div {class="icons1of3"}
+    \div {class="doc-column"}
         \b{Beginning with QML and Qt Quick}
         \list
         \li \l{First Steps with QML}
@@ -92,7 +92,7 @@ steps such as use cases and introductory material. For more information about Qt
         \li \l{QML Advanced Tutorial}{SameGame}
         \endlist
     \enddiv
-    \div {class="icons1of3"}
+    \div {class="doc-column"}
         \b{Use Cases}
         \list
         \li \l{qtquick-usecase-visual.html}{Visual types in QML}
@@ -120,8 +120,8 @@ Examples are small applications which show how to implement various Qt Quick
 features. The examples run on various platforms and are opened from within Qt
 Creator.
 
-\div {class="landingicons"}
-    \div {class="icons1of3"}
+\div {class="multi-column"}
+    \div {class="doc-column"}
         \b{QML Types and Controls}
         \list
         \li \l{Qt Quick Controls - Gallery}{Controls Gallery}
@@ -132,7 +132,7 @@ Creator.
         \li \l{Qt Quick Examples - Toggle Switch}{Custom Toggle Switch}
         \endlist
     \enddiv
-    \div {class="icons1of3"}
+    \div {class="doc-column"}
         \b{Layouts and Views}
         \list
         \li \l{Qt Quick Controls - Basic Layouts Example}{Basic Layouts}
@@ -142,7 +142,7 @@ Creator.
         \li \l{Qt Quick Examples - Right to Left}{Right-to-Left and Text Layout}
         \endlist
     \enddiv
-    \div {class="icons1of3"}
+    \div {class="doc-column"}
         \b{Image and Graphics}
         \list
         \li \l{Qt Quick Examples - Image Elements}{Image Elements}
@@ -153,8 +153,8 @@ Creator.
     \enddiv
 \enddiv
 
-\div {class="landingicons"}
-    \div {class="icons1of3"}
+\div {class="multi-column"}
+    \div {class="doc-column"}
         \b{Keyboard, Focus, and Touch}
         \list
         \li \l{Qt Quick Examples - Key Interaction}{Key Interaction}
@@ -162,7 +162,7 @@ Creator.
         \li \l{Qt Quick Controls - Touch Gallery}{Touch Gallery}
         \endlist
     \enddiv
-    \div {class="icons1of3"}
+    \div {class="doc-column"}
         \b{System and Events}
         \list
         \li \l{Qt Quick Examples - Threading}{Threading}
@@ -171,7 +171,7 @@ Creator.
         \li \l{Qt Quick Examples - Drag and Drop}{Drag and Drop}
         \endlist
     \enddiv
-    \div {class="icons1of3"}
+    \div {class="doc-column"}
         \b{Scene Graph}
         \list
         \li \l{Scene Graph - OpenGL Under QML}{OpenGL Under QML}
diff --git a/src/quick/doc/src/qmltypereference.qdoc b/src/quick/doc/src/qmltypereference.qdoc
index 4d3341aac45779ccd96df480e1587c7327215d75..cc602d4aeeb759b1388d562170876287000273dc 100644
--- a/src/quick/doc/src/qmltypereference.qdoc
+++ b/src/quick/doc/src/qmltypereference.qdoc
@@ -26,7 +26,7 @@
 ****************************************************************************/
 
 /*!
-\qmlmodule QtQuick 2.3
+\qmlmodule QtQuick 2.4
 \title Qt Quick QML Types
 \ingroup qmlmodules
 \brief Provides graphical QML types.
@@ -34,11 +34,11 @@
 The \l{Qt Quick} module provides graphical primitive types. These types are only
 available in a QML document if that document imports the \c QtQuick namespace.
 
-The current version of the \c QtQuick module is version 2.3, and thus it may be
+The current version of the \c QtQuick module is version 2.4, and thus it may be
 imported via the following statement:
 
 \qml
-import QtQuick 2.3
+import QtQuick 2.4
 \endqml
 
 Visit the \l {Qt Quick} module documentation for more
diff --git a/src/quick/items/qquickborderimage.cpp b/src/quick/items/qquickborderimage.cpp
index 07b8958664f8670cd3891d610b47fd898ac9a991..38bbc6689662e4e8153cd1f5b9e92a3701a6a04f 100644
--- a/src/quick/items/qquickborderimage.cpp
+++ b/src/quick/items/qquickborderimage.cpp
@@ -540,390 +540,90 @@ void QQuickBorderImage::doUpdate()
     update();
 }
 
-QImage QQuickBorderImage::shallowCopy(const QImage &image, const QRect &rect)
-{
-    if (image.depth() == 1) {
-        return image.copy(rect);
-    } else {
-        const uchar *bits = image.constBits() + image.bytesPerLine() * rect.y()  + (image.depth() / 8) * rect.x();
-        return QImage(bits, rect.width(), rect.height(), image.bytesPerLine(), image.format());
-    }
-}
-
 QSGNode *QQuickBorderImage::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *)
 {
     Q_D(QQuickBorderImage);
 
-    if (!d->pix.isReady() || width() <= 0 || height() <= 0) {
+    QSGTexture *texture = d->sceneGraphRenderContext()->textureForFactory(d->pix.textureFactory(), window());
+
+    if (!texture || width() <= 0 || height() <= 0) {
         delete oldNode;
         return 0;
     }
 
-    // Don't implicitly create the scalegrid in the rendering thread...
-    QRectF innerSourceRect(0, 0, 1, 1);
-    QRectF innerTargetRect(0, 0, width(), height());
-    int borderLeft = 0, borderTop = 0, borderRight = 0, borderBottom = 0;
-
-    bool updateNode = !oldNode;
-    if (d->border) {
-        const QQuickScaleGrid *border = d->getScaleGrid();
-
-        borderLeft = qBound(0, border->left(), d->pix.width());
-        borderTop = qBound(0, border->top(), d->pix.height());
-        borderRight = d->pix.rect().width() - qBound(0, border->right(), d->pix.rect().width() - borderLeft);
-        borderBottom = d->pix.rect().height() - qBound(0, border->bottom(), d->pix.rect().height() - borderTop);
-
-        innerSourceRect = QRectF(borderLeft / qreal(d->pix.width()),
-                                 borderTop / qreal(d->pix.height()),
-                                 qMax<qreal>(0, borderRight - borderLeft) / d->pix.width(),
-                                 qMax<qreal>(0, borderBottom - borderTop) / d->pix.height());
-        innerTargetRect = QRectF(borderLeft,
-                                 borderTop,
-                                 qMax<qreal>(0, width() - border->right() - border->left()),
-                                 qMax<qreal>(0, height() - border->bottom() - border->top()));
-
-        QSizeF newSize(width(), height());
-        if (innerSourceRect != d->oldInnerSourceRect
-                || innerTargetRect != d->oldInnerTargetRect
-                || newSize != d->oldSize) {
-            updateNode = true;
-        }
-
-        d->oldInnerSourceRect = innerSourceRect;
-        d->oldInnerTargetRect = innerTargetRect;
-        d->oldSize = newSize;
-    }
+    QSGImageNode *node = static_cast<QSGImageNode *>(oldNode);
 
     bool updatePixmap = d->pixmapChanged;
     d->pixmapChanged = false;
-    if (updateNode) {
-        delete oldNode;
-        oldNode = new QSGNode;
+    if (!node) {
+        node = d->sceneGraphContext()->createImageNode();
         updatePixmap = true;
-
-        for (int i=0; i<9; ++i)
-            d->regions[i].node = 0;
-
-        if (innerSourceRect.left() > 0) {
-            if (innerSourceRect.top() > 0) {
-                QRectF rect(0,
-                            0,
-                            innerTargetRect.left(),
-                            innerTargetRect.top());
-
-                if (!rect.isEmpty()) {
-                    d->regions[0].node = d->sceneGraphContext()->createImageNode();
-                    d->regions[0].node->setTargetRect(rect);
-                    d->regions[0].node->setInnerTargetRect(rect);
-                    d->regions[0].targetRect = rect;
-                }
-            }
-
-            if (innerSourceRect.bottom() < 1) {
-                QRectF rect(0,
-                            innerTargetRect.bottom(),
-                            innerTargetRect.left(),
-                            height() - innerTargetRect.height() - innerTargetRect.top());
-
-                if (!rect.isEmpty()) {
-                    d->regions[6].node = d->sceneGraphContext()->createImageNode();
-                    d->regions[6].node->setTargetRect(rect);
-                    d->regions[6].node->setInnerTargetRect(rect);
-                    d->regions[6].targetRect = rect;
-                }
-            }
-
-            if (innerSourceRect.top() < innerSourceRect.bottom()) {
-                QRectF rect(0,
-                            innerTargetRect.top(),
-                            innerTargetRect.left(),
-                            innerTargetRect.height());
-
-                if (!rect.isEmpty()) {
-                    d->regions[3].node = d->sceneGraphContext()->createImageNode();
-                    d->regions[3].node->setTargetRect(rect);
-                    d->regions[3].node->setInnerTargetRect(rect);
-                    d->regions[3].targetRect = rect;
-                }
-            }
-        }
-
-        if (innerSourceRect.right() < 1) {
-            if (innerSourceRect.top() > 0) {
-                QRectF rect(innerTargetRect.right(),
-                            0,
-                            width() - innerTargetRect.width() - innerTargetRect.left(),
-                            innerTargetRect.top());
-
-                if (!rect.isEmpty()) {
-                    d->regions[2].node = d->sceneGraphContext()->createImageNode();
-                    d->regions[2].node->setTargetRect(rect);
-                    d->regions[2].node->setInnerTargetRect(rect);
-                    d->regions[2].targetRect = rect;
-                }
-            }
-
-            if (innerSourceRect.bottom() < 1) {
-                QRectF rect(innerTargetRect.right(),
-                            innerTargetRect.bottom(),
-                            width() - innerTargetRect.width() - innerTargetRect.left(),
-                            height() - innerTargetRect.height() - innerTargetRect.top());
-
-                if (!rect.isEmpty()) {
-                    d->regions[8].node = d->sceneGraphContext()->createImageNode();
-                    d->regions[8].node->setTargetRect(rect);
-                    d->regions[8].node->setInnerTargetRect(rect);
-                    d->regions[8].targetRect = rect;
-                }
-            }
-
-            if (innerSourceRect.top() < innerSourceRect.bottom()) {
-                QRectF rect(innerTargetRect.right(),
-                            innerTargetRect.top(),
-                            width() - innerTargetRect.width() - innerTargetRect.left(),
-                            innerTargetRect.height());
-
-                if (!rect.isEmpty()) {
-                    d->regions[5].node = d->sceneGraphContext()->createImageNode();
-                    d->regions[5].node->setTargetRect(rect);
-                    d->regions[5].node->setInnerTargetRect(rect);
-                    d->regions[5].targetRect = rect;
-                }
-            }
-        }
-
-        if (innerSourceRect.top() > 0 && innerSourceRect.left() < innerSourceRect.right()) {
-            QRectF rect(innerTargetRect.left(),
-                        0,
-                        innerTargetRect.width(),
-                        innerTargetRect.top());
-
-            if (!rect.isEmpty()) {
-                d->regions[1].node = d->sceneGraphContext()->createImageNode();
-                d->regions[1].node->setTargetRect(rect);
-                d->regions[1].node->setInnerTargetRect(rect);
-                d->regions[1].targetRect = rect;
-            }
-        }
-
-        if (innerSourceRect.bottom() < 1 && innerSourceRect.left() < innerSourceRect.right()) {
-            QRectF rect(innerTargetRect.left(),
-                        innerTargetRect.bottom(),
-                        innerTargetRect.width(),
-                        height() - innerTargetRect.height() - innerTargetRect.top());
-
-            if (!rect.isEmpty()) {
-                d->regions[7].node = d->sceneGraphContext()->createImageNode();
-                d->regions[7].node->setTargetRect(rect);
-                d->regions[7].node->setInnerTargetRect(rect);
-                d->regions[7].targetRect = rect;
-            }
-        }
-
-        if (innerSourceRect.left() < innerSourceRect.right()
-                && innerSourceRect.top() < innerSourceRect.bottom()) {
-            if (!innerTargetRect.isEmpty()) {
-                d->regions[4].node = d->sceneGraphContext()->createImageNode();
-                d->regions[4].node->setInnerTargetRect(innerTargetRect);
-                d->regions[4].node->setTargetRect(innerTargetRect);
-                d->regions[4].targetRect = innerTargetRect;
-            }
-        }
-
-        for (int i=0; i<9; ++i) {
-            if (d->regions[i].node != 0)
-                oldNode->appendChildNode(d->regions[i].node);
-        }
-    }
-
-
-    QImage image = d->pix.image();
-
-    if (d->regions[0].node != 0) {
-        if (updatePixmap)
-            d->regions[0].image = shallowCopy(image, QRect(QPoint(0, 0), QSize(borderLeft, borderTop)));
-
-        QSGImageNode::AntialiasingFlags antialiasing = QSGImageNode::AntialiasingFlags(QSGImageNode::AntialiasingLeft | QSGImageNode::AntialiasingTop);
-        if (d->regions[1].node == 0 && d->regions[2].node == 0)
-            antialiasing |= QSGImageNode::AntialiasingRight;
-        if (d->regions[3].node == 0 && d->regions[6].node == 0)
-            antialiasing |= QSGImageNode::AntialiasingBottom;
-        d->regions[0].node->setAntialiasing(antialiasing);
     }
 
-    if (d->regions[1].node != 0) {
-        if (updatePixmap)
-            d->regions[1].image = shallowCopy(image, QRect(QPoint(borderLeft, 0), QSize(borderRight - borderLeft, borderTop)));
-
-        QSGImageNode::AntialiasingFlags antialiasing = QSGImageNode::AntialiasingTop;
-        if (d->regions[0].node == 0)
-            antialiasing |= QSGImageNode::AntialiasingLeft;
-        if (d->regions[2].node == 0)
-            antialiasing |= QSGImageNode::AntialiasingRight;
-        if (d->regions[4].node == 0 && d->regions[7].node == 0)
-            antialiasing |= QSGImageNode::AntialiasingBottom;
-        d->regions[1].node->setAntialiasing(antialiasing);
-    }
-
-    if (d->regions[2].node != 0) {
-        if (updatePixmap)
-            d->regions[2].image = shallowCopy(image, QRect(QPoint(borderRight, 0), QSize(d->pix.rect().width() - borderRight, borderTop)));
+    if (updatePixmap)
+        node->setTexture(texture);
 
-        QSGImageNode::AntialiasingFlags antialiasing = QSGImageNode::AntialiasingFlags(QSGImageNode::AntialiasingTop | QSGImageNode::AntialiasingRight);
-        if (d->regions[0].node == 0 && d->regions[1].node == 0)
-            antialiasing |= QSGImageNode::AntialiasingLeft;
-        if (d->regions[5].node == 0 && d->regions[8].node == 0)
-            antialiasing |= QSGImageNode::AntialiasingBottom;
-        d->regions[2].node->setAntialiasing(antialiasing);
-    }
-
-    if (d->regions[3].node != 0) {
-        if (updatePixmap)
-            d->regions[3].image = shallowCopy(image, QRect(QPoint(0, borderTop), QSize(borderLeft, borderBottom - borderTop)));
-
-        QSGImageNode::AntialiasingFlags antialiasing = QSGImageNode::AntialiasingLeft;
-        if (d->regions[4].node == 0 && d->regions[5].node == 0)
-            antialiasing |= QSGImageNode::AntialiasingRight;
-        if (d->regions[6].node == 0)
-            antialiasing |= QSGImageNode::AntialiasingBottom;
-        if (d->regions[0].node == 0)
-            antialiasing |= QSGImageNode::AntialiasingTop;
-        d->regions[3].node->setAntialiasing(antialiasing);
+    // Don't implicitly create the scalegrid in the rendering thread...
+    QRectF innerSourceRect(0, 0, 1, 1);
+    QRectF targetRect(0, 0, width(), height());
+    QRectF innerTargetRect = targetRect;
+    if (d->border) {
+        const QQuickScaleGrid *border = d->getScaleGrid();
+        innerSourceRect = QRectF(border->left() / qreal(d->pix.width()),
+                                 border->top() / qreal(d->pix.height()),
+                                 qMax<qreal>(0, d->pix.width() - border->right() - border->left()) / d->pix.width(),
+                                 qMax<qreal>(0, d->pix.height() - border->bottom() - border->top()) / d->pix.height());
+        innerTargetRect = QRectF(border->left(),
+                                 border->top(),
+                                 qMax<qreal>(0, width() - border->right() - border->left()),
+                                 qMax<qreal>(0, height() - border->bottom() - border->top()));
     }
-
-    if (d->regions[4].node != 0) {
-        if (updatePixmap) {
-            if (innerSourceRect == QRectF(0, 0, 1, 1)) {
-                d->regions[4].image = image;
-            } else {
-                d->regions[4].image = shallowCopy(image, QRect(QPoint(borderLeft, borderTop), QSize(borderRight - borderLeft, borderBottom - borderTop)));
-            }
+    qreal hTiles = 1;
+    qreal vTiles = 1;
+    if (innerSourceRect.width() != 0) {
+        switch (d->horizontalTileMode) {
+        case QQuickBorderImage::Repeat:
+            hTiles = innerTargetRect.width() / qreal(innerSourceRect.width() * d->pix.width());
+            break;
+        case QQuickBorderImage::Round:
+            hTiles = qCeil(innerTargetRect.width() / qreal(innerSourceRect.width() * d->pix.width()));
+            break;
+        default:
+            break;
         }
-
-        QSGImageNode::AntialiasingFlags antialiasing = QSGImageNode::AntialiasingNone;
-        if (d->regions[3].node == 0)
-            antialiasing |= QSGImageNode::AntialiasingLeft;
-        if (d->regions[5].node == 0)
-            antialiasing |= QSGImageNode::AntialiasingRight;
-        if (d->regions[1].node == 0)
-            antialiasing |= QSGImageNode::AntialiasingTop;
-        if (d->regions[7].node == 0)
-            antialiasing |= QSGImageNode::AntialiasingBottom;
-        d->regions[4].node->setAntialiasing(antialiasing);
     }
-
-    if (d->regions[5].node != 0) {
-        if (updatePixmap)
-            d->regions[5].image = shallowCopy(image, QRect(QPoint(borderRight, borderTop), QSize(d->pix.rect().width() - borderRight, borderBottom - borderTop)));
-
-        QSGImageNode::AntialiasingFlags antialiasing = QSGImageNode::AntialiasingRight;
-        if (d->regions[4].node == 0 && d->regions[3].node == 0)
-            antialiasing |= QSGImageNode::AntialiasingLeft;
-        if (d->regions[2].node == 0)
-            antialiasing |= QSGImageNode::AntialiasingTop;
-        if (d->regions[8].node == 0)
-            antialiasing |= QSGImageNode::AntialiasingBottom;
-        d->regions[5].node->setAntialiasing(antialiasing);
-    }
-
-    if (d->regions[6].node != 0) {
-        if (updatePixmap)
-            d->regions[6].image = shallowCopy(image, QRect(QPoint(0, borderBottom), QSize(borderLeft, d->pix.rect().height() - borderBottom)));
-
-        QSGImageNode::AntialiasingFlags antialiasing = QSGImageNode::AntialiasingFlags(QSGImageNode::AntialiasingBottom | QSGImageNode::AntialiasingLeft);
-        if (d->regions[7].node == 0 && d->regions[8].node == 0)
-            antialiasing |= QSGImageNode::AntialiasingRight;
-        if (d->regions[3].node == 0 && d->regions[0].node == 0)
-            antialiasing |= QSGImageNode::AntialiasingTop;
-        d->regions[6].node->setAntialiasing(antialiasing);
-    }
-
-    if (d->regions[7].node != 0) {
-        if (updatePixmap)
-            d->regions[7].image = shallowCopy(image, QRect(QPoint(borderLeft, borderBottom), QSize(borderRight - borderLeft, d->pix.rect().height() - borderBottom)));
-
-        QSGImageNode::AntialiasingFlags antialiasing = QSGImageNode::AntialiasingBottom;
-        if (d->regions[6].node == 0)
-            antialiasing |= QSGImageNode::AntialiasingLeft;
-        if (d->regions[8].node == 0)
-            antialiasing |= QSGImageNode::AntialiasingRight;
-        if (d->regions[4].node == 0 && d->regions[1].node == 0)
-            antialiasing |= QSGImageNode::AntialiasingTop;
-        d->regions[7].node->setAntialiasing(antialiasing);
-    }
-
-    if (d->regions[8].node != 0) {
-        if (updatePixmap)
-            d->regions[8].image = shallowCopy(image, QRect(QPoint(borderRight, borderBottom), QSize(d->pix.rect().width() - borderRight, d->pix.rect().height() - borderBottom)));
-
-        QSGImageNode::AntialiasingFlags antialiasing = QSGImageNode::AntialiasingFlags(QSGImageNode::AntialiasingBottom | QSGImageNode::AntialiasingRight);
-        if (d->regions[7].node == 0 && d->regions[6].node == 0)
-            antialiasing |= QSGImageNode::AntialiasingLeft;
-        if (d->regions[5].node == 0 && d->regions[2].node == 0)
-            antialiasing |= QSGImageNode::AntialiasingTop;
-        d->regions[8].node->setAntialiasing(antialiasing);
+    if (innerSourceRect.height() != 0) {
+        switch (d->verticalTileMode) {
+        case QQuickBorderImage::Repeat:
+            vTiles = innerTargetRect.height() / qreal(innerSourceRect.height() * d->pix.height());
+            break;
+        case QQuickBorderImage::Round:
+            vTiles = qCeil(innerTargetRect.height() / qreal(innerSourceRect.height() * d->pix.height()));
+            break;
+        default:
+            break;
+        }
     }
 
-    for (int i=0; i<9; ++i) {
-        if (d->regions[i].node != 0) {
-            if (updatePixmap) {
-                QQuickTextureFactory *textureFactory = QSGContext::createTextureFactoryFromImage(d->regions[i].image);
-                if (textureFactory == 0)
-                    textureFactory = new QQuickDefaultTextureFactory(d->regions[i].image);
-                d->regions[i].textureFactory.reset(textureFactory);
-                d->regions[i].node->setTexture(d->sceneGraphRenderContext()->textureForFactory(d->regions[i].textureFactory.data(),
-                                                                                               window()));
-            }
-
-            d->regions[i].node->setInnerSourceRect(QRectF(0, 0, 1, 1));
-            d->regions[i].node->setMipmapFiltering(QSGTexture::None);
-            d->regions[i].node->setFiltering(d->smooth ? QSGTexture::Linear : QSGTexture::Nearest);
-            d->regions[i].node->setMirror(d->mirror);
-
-
-            qreal hTiles = 1;
-            qreal vTiles = 1;
-
-            if (innerSourceRect.width() != 0) {
-                switch (d->horizontalTileMode) {
-                case QQuickBorderImage::Repeat:
-                    hTiles = d->regions[i].targetRect.width() / qreal(d->regions[i].image.width());
-                    break;
-                case QQuickBorderImage::Round:
-                    hTiles = qCeil(d->regions[i].targetRect.width() / qreal(d->regions[i].image.width()));
-                    break;
-                default:
-                    break;
-                }
-            }
-
-            if (innerSourceRect.height() != 0) {
-                switch (d->verticalTileMode) {
-                case QQuickBorderImage::Repeat:
-                    vTiles = d->regions[i].targetRect.height() / qreal(d->regions[i].image.height());
-                    break;
-                case QQuickBorderImage::Round:
-                    vTiles = qCeil(d->regions[i].targetRect.height() / qreal(d->regions[i].image.height()));
-                    break;
-                default:
-                    break;
-                }
-            }
-
-            if (vTiles > 1 || hTiles > 1) {
-                d->regions[i].node->setHorizontalWrapMode(QSGTexture::Repeat);
-                d->regions[i].node->setVerticalWrapMode(QSGTexture::Repeat);
-            } else {
-                d->regions[i].node->setHorizontalWrapMode(QSGTexture::ClampToEdge);
-                d->regions[i].node->setVerticalWrapMode(QSGTexture::ClampToEdge);
-            }
-
-            d->regions[i].node->setSubSourceRect(QRectF(0, 0, hTiles, vTiles));
-            d->regions[i].node->update();
-        }
+    node->setTargetRect(targetRect);
+    node->setInnerSourceRect(innerSourceRect);
+    node->setInnerTargetRect(innerTargetRect);
+    node->setSubSourceRect(QRectF(0, 0, hTiles, vTiles));
+    node->setMirror(d->mirror);
+
+    node->setMipmapFiltering(QSGTexture::None);
+    node->setFiltering(d->smooth ? QSGTexture::Linear : QSGTexture::Nearest);
+    if (innerSourceRect == QRectF(0, 0, 1, 1) && (vTiles > 1 || hTiles > 1)) {
+        node->setHorizontalWrapMode(QSGTexture::Repeat);
+        node->setVerticalWrapMode(QSGTexture::Repeat);
+    } else {
+        node->setHorizontalWrapMode(QSGTexture::ClampToEdge);
+        node->setVerticalWrapMode(QSGTexture::ClampToEdge);
     }
+    node->setAntialiasing(d->antialiasing);
+    node->update();
 
-    return oldNode;
+    return node;
 }
 
 void QQuickBorderImage::pixmapChange()
diff --git a/src/quick/items/qquickborderimage_p.h b/src/quick/items/qquickborderimage_p.h
index 1d0898115ddbef91cfd5174152ee204fe4e1c361..6a2469adc2609f7d4b82189d91abbeebd1abb5fe 100644
--- a/src/quick/items/qquickborderimage_p.h
+++ b/src/quick/items/qquickborderimage_p.h
@@ -87,8 +87,6 @@ private Q_SLOTS:
     void sciRequestFinished();
 
 private:
-    static QImage shallowCopy(const QImage &image, const QRect &rect);
-
     Q_DISABLE_COPY(QQuickBorderImage)
     Q_DECLARE_PRIVATE(QQuickBorderImage)
 };
diff --git a/src/quick/items/qquickborderimage_p_p.h b/src/quick/items/qquickborderimage_p_p.h
index bda2867696fb1a8fae0ee2f82554dfa7e65af08a..d5b959fd9f4dba90463edea787e77cfeac021f1d 100644
--- a/src/quick/items/qquickborderimage_p_p.h
+++ b/src/quick/items/qquickborderimage_p_p.h
@@ -89,16 +89,6 @@ public:
     QQuickBorderImage::TileMode verticalTileMode;
     int redirectCount;
 
-    struct BorderImageRegion
-    {
-        BorderImageRegion() : node(0), textureFactory(0) {}
-        QImage image;
-        QSGImageNode *node;
-        QScopedPointer<QQuickTextureFactory> textureFactory;
-        QRectF targetRect;
-    };
-    BorderImageRegion regions[9];
-
     bool pixmapChanged : 1;
 };
 
diff --git a/src/quick/items/qquickimagebase_p_p.h b/src/quick/items/qquickimagebase_p_p.h
index 21d11a74481387263f7cde1f95797d77806ab48c..f30eacb4ac1047f7ee3d614ad8274a4e3bd350ab 100644
--- a/src/quick/items/qquickimagebase_p_p.h
+++ b/src/quick/items/qquickimagebase_p_p.h
@@ -75,9 +75,6 @@ public:
     QSize sourcesize;
     QSize oldSourceSize;
     qreal devicePixelRatio;
-    QRectF oldInnerSourceRect;
-    QRectF oldInnerTargetRect;
-    QSizeF oldSize;
     bool async : 1;
     bool cache : 1;
     bool mirror: 1;
diff --git a/src/quick/items/qquicktext.cpp b/src/quick/items/qquicktext.cpp
index bfa2fccd67d0fe62eb92fc851d23f60a1e7d84f8..87255f4bd95d11ae15d648e8b3628b6b826be8f2 100644
--- a/src/quick/items/qquicktext.cpp
+++ b/src/quick/items/qquicktext.cpp
@@ -79,6 +79,7 @@ QQuickTextPrivate::QQuickTextPrivate()
     , requireImplicitSize(false), implicitWidthValid(false), implicitHeightValid(false)
     , truncated(false), hAlignImplicit(true), rightToLeftText(false)
     , layoutTextElided(false), textHasChanged(true), needToUpdateLayout(false), formatModifiesFontSize(false)
+    , polishSize(false)
 {
     implicitAntialiasing = true;
 }
@@ -356,6 +357,8 @@ void QQuickTextPrivate::updateLayout()
         textHasChanged = true;
         updateLayout();
     }
+
+    q->polish();
 }
 
 void QQuickText::imageDownloadFinished()
@@ -2248,13 +2251,22 @@ QSGNode *QQuickText::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *data
                 node->addImage(QRectF(img->pos.x() + dx, img->pos.y() + dy, pix->width(), pix->height()), pix->image());
         }
     }
+
+    // The font caches have now been initialized on the render thread, so they have to be
+    // invalidated before we can use them from the main thread again.
+    invalidateFontCaches();
+
     return node;
 }
 
 void QQuickText::updatePolish()
 {
     Q_D(QQuickText);
-    d->updateSize();
+    if (d->polishSize) {
+        d->updateSize();
+        d->polishSize = false;
+    }
+    invalidateFontCaches();
 }
 
 /*!
@@ -2381,6 +2393,7 @@ void QQuickText::setFontSizeMode(FontSizeMode mode)
     if (d->fontSizeMode() == mode)
         return;
 
+    d->polishSize = true;
     polish();
 
     d->extra.value().fontSizeMode = mode;
@@ -2409,8 +2422,10 @@ void QQuickText::setMinimumPixelSize(int size)
     if (d->minimumPixelSize() == size)
         return;
 
-    if (d->fontSizeMode() != FixedSize && (widthValid() || heightValid()))
+    if (d->fontSizeMode() != FixedSize && (widthValid() || heightValid())) {
+        d->polishSize = true;
         polish();
+    }
     d->extra.value().minimumPixelSize = size;
     emit minimumPixelSizeChanged();
 }
@@ -2437,8 +2452,10 @@ void QQuickText::setMinimumPointSize(int size)
     if (d->minimumPointSize() == size)
         return;
 
-    if (d->fontSizeMode() != FixedSize && (widthValid() || heightValid()))
+    if (d->fontSizeMode() != FixedSize && (widthValid() || heightValid())) {
+        d->polishSize = true;
         polish();
+    }
     d->extra.value().minimumPointSize = size;
     emit minimumPointSizeChanged();
 }
@@ -2699,4 +2716,26 @@ QString QQuickText::linkAt(qreal x, qreal y) const
     return d->anchorAt(QPointF(x, y));
 }
 
+/*!
+ * \internal
+ *
+ * Invalidates font caches owned by the text objects owned by the element
+ * to work around the fact that text objects cannot be used from multiple threads.
+ */
+void QQuickText::invalidateFontCaches()
+{
+    Q_D(QQuickText);
+
+    if (d->richText && d->extra->doc != 0) {
+        QTextBlock block;
+        for (block = d->extra->doc->firstBlock(); block.isValid(); block = block.next()) {
+            if (block.layout() != 0 && block.layout()->engine() != 0)
+                block.layout()->engine()->resetFontEngineCache();
+        }
+    } else {
+        if (d->layout.engine() != 0)
+            d->layout.engine()->resetFontEngineCache();
+    }
+}
+
 QT_END_NAMESPACE
diff --git a/src/quick/items/qquicktext_p.h b/src/quick/items/qquicktext_p.h
index c9f64d3fabc2069f4e30fb5dc33cacdce9fabc62..c3fa9e6935195295104dd3d64428ef015c33a80b 100644
--- a/src/quick/items/qquicktext_p.h
+++ b/src/quick/items/qquicktext_p.h
@@ -245,6 +245,7 @@ protected:
     void hoverEnterEvent(QHoverEvent *event);
     void hoverMoveEvent(QHoverEvent *event);
     void hoverLeaveEvent(QHoverEvent *event);
+    void invalidateFontCaches();
 
 private Q_SLOTS:
     void q_imagesLoaded();
diff --git a/src/quick/items/qquicktext_p_p.h b/src/quick/items/qquicktext_p_p.h
index 022c2ac9d53076f9401648d6e0f66f8f4d7b0c81..d645ce5ed5f0ca18390de32098b93b9ae78fbcb3 100644
--- a/src/quick/items/qquicktext_p_p.h
+++ b/src/quick/items/qquicktext_p_p.h
@@ -151,6 +151,7 @@ public:
     bool textHasChanged:1;
     bool needToUpdateLayout:1;
     bool formatModifiesFontSize:1;
+    bool polishSize:1; // Workaround for problem with polish called after updateSize (QTBUG-42636)
 
     static const QChar elideChar;
 
diff --git a/src/quick/items/qquicktextedit.cpp b/src/quick/items/qquicktextedit.cpp
index aca7150ca2dff965c9fc0bc5b1ca498ab59fc28f..b950f962773786cd14b0ce30cc166a05b53f68ea 100644
--- a/src/quick/items/qquicktextedit.cpp
+++ b/src/quick/items/qquicktextedit.cpp
@@ -1739,6 +1739,7 @@ void QQuickTextEdit::triggerPreprocess()
     Q_D(QQuickTextEdit);
     if (d->updateType == QQuickTextEditPrivate::UpdateNone)
         d->updateType = QQuickTextEditPrivate::UpdateOnlyPreprocess;
+    polish();
     update();
 }
 
@@ -1758,6 +1759,25 @@ static inline void updateNodeTransform(QQuickTextNode* node, const QPointF &topL
     node->setMatrix(transformMatrix);
 }
 
+/*!
+ * \internal
+ *
+ * Invalidates font caches owned by the text objects owned by the element
+ * to work around the fact that text objects cannot be used from multiple threads.
+ */
+void QQuickTextEdit::invalidateFontCaches()
+{
+    Q_D(QQuickTextEdit);
+    if (d->document == 0)
+        return;
+
+    QTextBlock block;
+    for (block = d->document->firstBlock(); block.isValid(); block = block.next()) {
+        if (block.layout() != 0 && block.layout()->engine() != 0)
+            block.layout()->engine()->resetFontEngineCache();
+    }
+}
+
 QSGNode *QQuickTextEdit::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *updatePaintNodeData)
 {
     Q_UNUSED(updatePaintNodeData);
@@ -1911,9 +1931,16 @@ QSGNode *QQuickTextEdit::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *
         rootNode->resetCursorNode(cursor);
     }
 
+    invalidateFontCaches();
+
     return rootNode;
 }
 
+void QQuickTextEdit::updatePolish()
+{
+    invalidateFontCaches();
+}
+
 /*!
     \qmlproperty bool QtQuick::TextEdit::canPaste
 
@@ -2079,6 +2106,7 @@ void QQuickTextEdit::q_contentsChange(int pos, int charsRemoved, int charsAdded)
 
     markDirtyNodesForRange(pos, editRange, delta);
 
+    polish();
     if (isComponentComplete()) {
         d->updateType = QQuickTextEditPrivate::UpdatePaintNode;
         update();
@@ -2106,6 +2134,7 @@ void QQuickTextEdit::updateSelection()
     // No need for node updates when we go from an empty selection to another empty selection
     if (d->control->textCursor().hasSelection() || d->hadSelection) {
         markDirtyNodesForRange(qMin(d->lastSelectionStart, d->control->textCursor().selectionStart()), qMax(d->control->textCursor().selectionEnd(), d->lastSelectionEnd), 0);
+        polish();
         if (isComponentComplete()) {
             d->updateType = QQuickTextEditPrivate::UpdatePaintNode;
             update();
@@ -2246,6 +2275,7 @@ void QQuickTextEdit::updateWholeDocument()
             node->setDirty();
     }
 
+    polish();
     if (isComponentComplete()) {
         d->updateType = QQuickTextEditPrivate::UpdatePaintNode;
         update();
@@ -2260,6 +2290,7 @@ void QQuickTextEdit::invalidateBlock(const QTextBlock &block)
 void QQuickTextEdit::updateCursor()
 {
     Q_D(QQuickTextEdit);
+    polish();
     if (isComponentComplete()) {
         d->updateType = QQuickTextEditPrivate::UpdatePaintNode;
         update();
diff --git a/src/quick/items/qquicktextedit_p.h b/src/quick/items/qquicktextedit_p.h
index 54e6dd229af48f2b41e1ed3a4751109c104a070c..5d1c026c5cf5ef8d40cd33bdd683f90acb1b1318 100644
--- a/src/quick/items/qquicktextedit_p.h
+++ b/src/quick/items/qquicktextedit_p.h
@@ -330,6 +330,7 @@ private Q_SLOTS:
 private:
     void markDirtyNodesForRange(int start, int end, int charDelta);
     void updateTotalLines();
+    void invalidateFontCaches();
 
 protected:
     virtual void geometryChanged(const QRectF &newGeometry,
@@ -354,6 +355,7 @@ protected:
     void inputMethodEvent(QInputMethodEvent *e);
 #endif
     QSGNode *updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *updatePaintNodeData);
+    void updatePolish();
 
     friend class QQuickTextUtil;
     friend class QQuickTextDocument;
diff --git a/src/quick/items/qquicktextinput.cpp b/src/quick/items/qquicktextinput.cpp
index 1f03fb21e21c224dd9fda36604f9b0db7b41e684..a9c60273d2b8de0cba65d548ff1cc16373ff5cd7 100644
--- a/src/quick/items/qquicktextinput.cpp
+++ b/src/quick/items/qquicktextinput.cpp
@@ -56,6 +56,8 @@
 #include "qquickaccessibleattached_p.h"
 #endif
 
+#include <QtGui/private/qtextengine_p.h>
+
 QT_BEGIN_NAMESPACE
 
 DEFINE_BOOL_CONFIG_OPTION(qmlDisableDistanceField, QML_DISABLE_DISTANCEFIELD)
@@ -362,6 +364,7 @@ void QQuickTextInput::setColor(const QColor &c)
         d->color = c;
         d->textLayoutDirty = true;
         d->updateType = QQuickTextInputPrivate::UpdatePaintNode;
+        polish();
         update();
         emit colorChanged();
     }
@@ -389,6 +392,7 @@ void QQuickTextInput::setSelectionColor(const QColor &color)
     if (d->hasSelectedText()) {
         d->textLayoutDirty = true;
         d->updateType = QQuickTextInputPrivate::UpdatePaintNode;
+        polish();
         update();
     }
     emit selectionColorChanged();
@@ -414,6 +418,7 @@ void QQuickTextInput::setSelectedTextColor(const QColor &color)
     if (d->hasSelectedText()) {
         d->textLayoutDirty = true;
         d->updateType = QQuickTextInputPrivate::UpdatePaintNode;
+        polish();
         update();
     }
     emit selectedTextColorChanged();
@@ -723,6 +728,7 @@ void QQuickTextInput::setCursorVisible(bool on)
     if (!d->cursorItem) {
         d->setCursorBlinkPeriod(on ? qApp->styleHints()->cursorFlashTime() : 0);
         d->updateType = QQuickTextInputPrivate::UpdatePaintNode;
+        polish();
         update();
     }
     emit cursorVisibleChanged(d->cursorVisible);
@@ -1830,9 +1836,23 @@ void QQuickTextInput::triggerPreprocess()
     Q_D(QQuickTextInput);
     if (d->updateType == QQuickTextInputPrivate::UpdateNone)
         d->updateType = QQuickTextInputPrivate::UpdateOnlyPreprocess;
+    polish();
     update();
 }
 
+void QQuickTextInput::updatePolish()
+{
+    invalidateFontCaches();
+}
+
+void QQuickTextInput::invalidateFontCaches()
+{
+    Q_D(QQuickTextInput);
+
+    if (d->m_textLayout.engine() != 0)
+        d->m_textLayout.engine()->resetFontEngineCache();
+}
+
 QSGNode *QQuickTextInput::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *data)
 {
     Q_UNUSED(data);
@@ -1891,6 +1911,8 @@ QSGNode *QQuickTextInput::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData
         d->textLayoutDirty = false;
     }
 
+    invalidateFontCaches();
+
     return node;
 }
 
@@ -2651,6 +2673,7 @@ void QQuickTextInput::updateCursorRectangle(bool scroll)
         d->updateVerticalScroll();
     }
     d->updateType = QQuickTextInputPrivate::UpdatePaintNode;
+    polish();
     update();
     emit cursorRectangleChanged();
     if (d->cursorItem) {
@@ -2668,6 +2691,7 @@ void QQuickTextInput::selectionChanged()
     Q_D(QQuickTextInput);
     d->textLayoutDirty = true; //TODO: Only update rect in selection
     d->updateType = QQuickTextInputPrivate::UpdatePaintNode;
+    polish();
     update();
     emit selectedTextChanged();
 
@@ -2879,6 +2903,7 @@ void QQuickTextInputPrivate::updateLayout()
     contentSize = QSizeF(width, height);
 
     updateType = UpdatePaintNode;
+    q->polish();
     q->update();
 
     if (!requireImplicitWidth && !q->widthValid())
@@ -4167,6 +4192,7 @@ void QQuickTextInputPrivate::setCursorBlinkPeriod(int msec)
         m_blinkTimer = 0;
         if (m_blinkStatus == 1) {
             updateType = UpdatePaintNode;
+            q->polish();
             q->update();
         }
     }
@@ -4179,6 +4205,7 @@ void QQuickTextInput::timerEvent(QTimerEvent *event)
     if (event->timerId() == d->m_blinkTimer) {
         d->m_blinkStatus = !d->m_blinkStatus;
         d->updateType = QQuickTextInputPrivate::UpdatePaintNode;
+        polish();
         update();
     } else if (event->timerId() == d->m_passwordEchoTimer.timerId()) {
         d->m_passwordEchoTimer.stop();
diff --git a/src/quick/items/qquicktextinput_p.h b/src/quick/items/qquicktextinput_p.h
index 4b945305870d35b07c9d0ffc8458e2327208aede..2386fc564299041496e52c2a8235b8ab65055f27 100644
--- a/src/quick/items/qquicktextinput_p.h
+++ b/src/quick/items/qquicktextinput_p.h
@@ -314,6 +314,9 @@ Q_SIGNALS:
 #endif
     void renderTypeChanged();
 
+private:
+    void invalidateFontCaches();
+
 protected:
     virtual void geometryChanged(const QRectF &newGeometry,
                                  const QRectF &oldGeometry);
@@ -332,6 +335,7 @@ protected:
     void focusInEvent(QFocusEvent *event);
     void timerEvent(QTimerEvent *event);
     QSGNode *updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *data);
+    void updatePolish();
 
 public Q_SLOTS:
     void selectAll();
diff --git a/src/quick/scenegraph/qsgadaptationlayer_p.h b/src/quick/scenegraph/qsgadaptationlayer_p.h
index 962fc5a98a1715b1d8c50d30e495ee1eb74b8c91..ef21385ee6511c55be3c333a480f28f913c3243c 100644
--- a/src/quick/scenegraph/qsgadaptationlayer_p.h
+++ b/src/quick/scenegraph/qsgadaptationlayer_p.h
@@ -126,17 +126,6 @@ public:
 class Q_QUICK_PRIVATE_EXPORT QSGImageNode : public QSGVisitableNode
 {
 public:
-    enum AntialiasingFlag
-    {
-        AntialiasingNone = 0,
-        AntialiasingLeft = 1,
-        AntialiasingRight = 2,
-        AntialiasingTop = 4,
-        AntialiasingBottom = 8,
-        AntialiasingAll = AntialiasingLeft | AntialiasingRight | AntialiasingBottom | AntialiasingTop
-    };
-    Q_DECLARE_FLAGS(AntialiasingFlags, AntialiasingFlag)
-
     virtual void setTargetRect(const QRectF &rect) = 0;
     virtual void setInnerTargetRect(const QRectF &rect) = 0;
     virtual void setInnerSourceRect(const QRectF &rect) = 0;
@@ -151,7 +140,6 @@ public:
     virtual void setFiltering(QSGTexture::Filtering filtering) = 0;
     virtual void setHorizontalWrapMode(QSGTexture::WrapMode wrapMode) = 0;
     virtual void setVerticalWrapMode(QSGTexture::WrapMode wrapMode) = 0;
-    virtual void setAntialiasing(AntialiasingFlags flags) { Q_UNUSED(flags); }
 
     virtual void update() = 0;
 
diff --git a/src/quick/scenegraph/qsgdefaultimagenode.cpp b/src/quick/scenegraph/qsgdefaultimagenode.cpp
index 69df506d2aa02e99f71b476d2063d28bba9b8be6..7f85c31ccbf3151b1b9084c65ac54649c4713e6a 100644
--- a/src/quick/scenegraph/qsgdefaultimagenode.cpp
+++ b/src/quick/scenegraph/qsgdefaultimagenode.cpp
@@ -140,11 +140,10 @@ void SmoothTextureMaterialShader::initialize()
 QSGDefaultImageNode::QSGDefaultImageNode()
     : m_innerSourceRect(0, 0, 1, 1)
     , m_subSourceRect(0, 0, 1, 1)
+    , m_antialiasing(false)
     , m_mirror(false)
     , m_dirtyGeometry(false)
     , m_geometry(QSGGeometry::defaultAttributes_TexturedPoint2D(), 4)
-    , m_antialiasing(AntialiasingNone)
-
 {
     setMaterial(&m_materialO);
     setOpaqueMaterial(&m_material);
@@ -250,20 +249,10 @@ void QSGDefaultImageNode::setTexture(QSGTexture *texture)
 
 void QSGDefaultImageNode::setAntialiasing(bool antialiasing)
 {
-    AntialiasingFlags antialiasingFlags = antialiasing
-                                          ? AntialiasingAll
-                                          : AntialiasingNone;
-
-    setAntialiasing(antialiasingFlags);
-}
-
-void QSGDefaultImageNode::setAntialiasing(AntialiasingFlags antialiasingFlags)
-{
-    if (antialiasingFlags == m_antialiasing)
+    if (antialiasing == m_antialiasing)
         return;
-
-    m_antialiasing = antialiasingFlags;
-    if (m_antialiasing != AntialiasingNone) {
+    m_antialiasing = antialiasing;
+    if (m_antialiasing) {
         setMaterial(&m_smoothMaterial);
         setOpaqueMaterial(0);
         setGeometry(new QSGGeometry(smoothAttributeSet(), 0));
@@ -375,14 +364,11 @@ void QSGDefaultImageNode::updateGeometry()
         }
 
         // An image can be rendered as a single quad if:
-        // - There is antialiasing on all or no edges
         // - There are no margins, and either:
         //   - the image isn't repeated
         //   - the source rectangle fills the entire texture so that texture wrapping can be used,
         //     and NPOT is supported
-        if (!hasMargins
-                && (m_antialiasing == AntialiasingAll || m_antialiasing == AntialiasingNone)
-                && (!hasTiles || (fullTexture && wrapSupported))) {
+        if (!hasMargins && (!hasTiles || (fullTexture && wrapSupported))) {
             QRectF sr;
             if (!fullTexture) {
                 sr = QRectF(innerSourceRect.x() + (m_subSourceRect.left() - floorLeft) * innerSourceRect.width(),
@@ -561,35 +547,10 @@ void QSGDefaultImageNode::updateGeometry()
                     topDv = bottomDv *= 0.5f;
                 }
 
-                if (!m_antialiasing.testFlag(AntialiasingTop)) {
-                    topDy = 0.0f;
-                    topDv = 0.0f;
-                }
-
-                if (!m_antialiasing.testFlag(AntialiasingBottom)) {
-                    bottomDy = 0.0f;
-                    bottomDv = 0.0f;
-                }
-
-                if (!m_antialiasing.testFlag(AntialiasingLeft)) {
-                    leftDx = 0.0f;
-                    leftDu = 0.0f;
-                }
-
-                if (!m_antialiasing.testFlag(AntialiasingRight)) {
-                    rightDx = 0.0f;
-                    rightDu = 0.0f;
-                }
-
                 // This delta is how much the fuzziness can reach out from the image.
                 float delta = float(qAbs(m_targetRect.width()) < qAbs(m_targetRect.height())
                                     ? m_targetRect.width() : m_targetRect.height()) * 0.5f;
 
-                float deltaTop = m_antialiasing.testFlag(AntialiasingTop) ? delta : 0.0f;
-                float deltaBottom = m_antialiasing.testFlag(AntialiasingBottom) ? delta : 0.0f;
-                float deltaLeft = m_antialiasing.testFlag(AntialiasingLeft) ? delta : 0.0f;
-                float deltaRight = m_antialiasing.testFlag(AntialiasingRight) ? delta : 0.0f;
-
                 quint16 index = 0;
                 ys = yData.data();
                 for (int j = 0; j < vCells; ++j, ys += 2) {
@@ -639,28 +600,28 @@ void QSGDefaultImageNode::updateGeometry()
                         if (isTop) {
                             vertices[topLeft].dy = vertices[topRight].dy = topDy;
                             vertices[topLeft].dv = vertices[topRight].dv = topDv;
-                            vertices[topLeft + 1].dy = vertices[topRight + 1].dy = -deltaTop;
+                            vertices[topLeft + 1].dy = vertices[topRight + 1].dy = -delta;
                             appendQuad(&indices, topLeft + 1, topRight + 1, topLeft, topRight);
                         }
 
                         if (isBottom) {
                             vertices[bottomLeft].dy = vertices[bottomRight].dy = -bottomDy;
                             vertices[bottomLeft].dv = vertices[bottomRight].dv = -bottomDv;
-                            vertices[bottomLeft + 1].dy = vertices[bottomRight + 1].dy = deltaBottom;
+                            vertices[bottomLeft + 1].dy = vertices[bottomRight + 1].dy = delta;
                             appendQuad(&indices, bottomLeft, bottomRight, bottomLeft + 1, bottomRight + 1);
                         }
 
                         if (isLeft) {
                             vertices[topLeft].dx = vertices[bottomLeft].dx = leftDx;
                             vertices[topLeft].du = vertices[bottomLeft].du = leftDu;
-                            vertices[topLeft + 1].dx = vertices[bottomLeft + 1].dx = -deltaLeft;
+                            vertices[topLeft + 1].dx = vertices[bottomLeft + 1].dx = -delta;
                             appendQuad(&indices, topLeft + 1, topLeft, bottomLeft + 1, bottomLeft);
                         }
 
                         if (isRight) {
                             vertices[topRight].dx = vertices[bottomRight].dx = -rightDx;
                             vertices[topRight].du = vertices[bottomRight].du = -rightDu;
-                            vertices[topRight + 1].dx = vertices[bottomRight + 1].dx = deltaRight;
+                            vertices[topRight + 1].dx = vertices[bottomRight + 1].dx = delta;
                             appendQuad(&indices, topRight, topRight + 1, bottomRight, bottomRight + 1);
                         }
                     }
diff --git a/src/quick/scenegraph/qsgdefaultimagenode_p.h b/src/quick/scenegraph/qsgdefaultimagenode_p.h
index 558e4d8ba49a88038ecc77e843228b8ff7981d80..26b087284b1f6fbffd3801d97446d7bd2e1ff153 100644
--- a/src/quick/scenegraph/qsgdefaultimagenode_p.h
+++ b/src/quick/scenegraph/qsgdefaultimagenode_p.h
@@ -62,7 +62,6 @@ public:
     virtual void setSubSourceRect(const QRectF &rect);
     virtual void setTexture(QSGTexture *t);
     virtual void setAntialiasing(bool antialiasing);
-    virtual void setAntialiasing(AntialiasingFlags antialiasing);
     virtual void setMirror(bool mirror);
     virtual void update();
 
@@ -85,11 +84,11 @@ private:
     QSGTextureMaterial m_materialO;
     QSGSmoothTextureMaterial m_smoothMaterial;
 
+    uint m_antialiasing : 1;
     uint m_mirror : 1;
     uint m_dirtyGeometry : 1;
 
     QSGGeometry m_geometry;
-    AntialiasingFlags m_antialiasing;
 };
 
 QT_END_NAMESPACE
diff --git a/src/quick/scenegraph/qsgwindowsrenderloop.cpp b/src/quick/scenegraph/qsgwindowsrenderloop.cpp
index 070d6b82fdde93b4b6c996f3ad618677a7c63cf1..1213c7e771bcebfc8d87a7322a58b0647a22e05b 100644
--- a/src/quick/scenegraph/qsgwindowsrenderloop.cpp
+++ b/src/quick/scenegraph/qsgwindowsrenderloop.cpp
@@ -38,6 +38,7 @@
 
 #include <QtGui/QScreen>
 #include <QtGui/QGuiApplication>
+#include <QtGui/QOffscreenSurface>
 
 #include <QtQuick/private/qsgcontext_p.h>
 #include <QtQuick/private/qquickwindow_p.h>
@@ -210,15 +211,29 @@ void QSGWindowsRenderLoop::windowDestroyed(QQuickWindow *window)
     hide(window);
 
     QQuickWindowPrivate *d = QQuickWindowPrivate::get(window);
-    if (m_gl)
-        m_gl->makeCurrent(window);
+    bool current = false;
+    QScopedPointer<QOffscreenSurface> offscreenSurface;
+    if (m_gl) {
+        QSurface *surface = window;
+        // There may be no platform window if the window got closed.
+        if (!window->handle()) {
+            offscreenSurface.reset(new QOffscreenSurface);
+            offscreenSurface->setFormat(m_gl->format());
+            offscreenSurface->create();
+            surface = offscreenSurface.data();
+        }
+        current = m_gl->makeCurrent(surface);
+    }
+    if (Q_UNLIKELY(!current))
+        qCDebug(QSG_LOG_RENDERLOOP) << "cleanup without an OpenGL context";
+
     d->cleanupNodesOnShutdown();
     if (m_windows.size() == 0) {
         d->context->invalidate();
         QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete);
         delete m_gl;
         m_gl = 0;
-    } else if (m_gl) {
+    } else if (m_gl && current) {
         m_gl->doneCurrent();
     }
 }
diff --git a/tools/qml/main.cpp b/tools/qml/main.cpp
index 69ccd7a316ae512f7994ea1ee51f7a0589ce2a15..e06f249b40cb5e280475ef4c72bd4b248978d7ab 100644
--- a/tools/qml/main.cpp
+++ b/tools/qml/main.cpp
@@ -494,6 +494,7 @@ int main(int argc, char *argv[])
 
     foreach (const QString &path, files) {
         //QUrl::fromUserInput doesn't treat no scheme as relative file paths
+#ifndef QT_NO_REGULAREXPRESSION
         QRegularExpression urlRe("[[:word:]]+://.*");
         if (urlRe.match(path).hasMatch()) { //Treat as a URL
             QUrl url = QUrl::fromUserInput(path);
@@ -503,7 +504,9 @@ int main(int argc, char *argv[])
                         ? QDir::toNativeSeparators(url.toLocalFile())
                         : url.toString()));
             e.load(url);
-        } else { //Local file path
+        } else
+#endif
+        { //Local file path
             if (verboseMode)
                 printf("qml: loading %s\n", qPrintable(QDir::toNativeSeparators(path)));