diff --git a/src/quick/items/qquickborderimage.cpp b/src/quick/items/qquickborderimage.cpp
index 38bbc6689662e4e8153cd1f5b9e92a3701a6a04f..50a0a762670484fa85540806c90183d94e685af1 100644
--- a/src/quick/items/qquickborderimage.cpp
+++ b/src/quick/items/qquickborderimage.cpp
@@ -540,90 +540,347 @@ 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);
 
-    QSGTexture *texture = d->sceneGraphRenderContext()->textureForFactory(d->pix.textureFactory(), window());
-
-    if (!texture || width() <= 0 || height() <= 0) {
+    if (!d->pix.isReady() || width() <= 0 || height() <= 0) {
         delete oldNode;
         return 0;
     }
 
-    QSGImageNode *node = static_cast<QSGImageNode *>(oldNode);
-
-    bool updatePixmap = d->pixmapChanged;
-    d->pixmapChanged = false;
-    if (!node) {
-        node = d->sceneGraphContext()->createImageNode();
-        updatePixmap = true;
-    }
-
-    if (updatePixmap)
-        node->setTexture(texture);
-
     // 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;
+    QRectF innerTargetRect(0, 0, width(), height());
+    int borderLeft, borderTop, borderRight, borderBottom;
     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(),
+
+        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()));
     }
-    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;
+
+    bool updatePixmap = d->pixmapChanged;
+    d->pixmapChanged = false;
+    if (!oldNode) {
+        oldNode = new QSGNode;
+        updatePixmap = true;
+
+        for (int i=0; i<9; ++i)
+            d->regions[i].node = 0;
+
+        if (innerSourceRect.left() > 0) {
+            if (innerSourceRect.top() > 0)
+                d->regions[0].node = d->sceneGraphContext()->createImageNode();
+            if (innerSourceRect.bottom() < 1)
+                d->regions[6].node = d->sceneGraphContext()->createImageNode();
+
+            if (innerSourceRect.top() < innerSourceRect.bottom())
+                d->regions[3].node = d->sceneGraphContext()->createImageNode();
+        }
+
+        if (innerSourceRect.right() < 1) {
+            if (innerSourceRect.top() > 0)
+                d->regions[2].node = d->sceneGraphContext()->createImageNode();
+            if (innerSourceRect.bottom() < 1)
+                d->regions[8].node = d->sceneGraphContext()->createImageNode();
+
+            if (innerSourceRect.top() < innerSourceRect.bottom())
+                d->regions[5].node = d->sceneGraphContext()->createImageNode();
+        }
+
+        if (innerSourceRect.top() > 0 && innerSourceRect.left() < innerSourceRect.right())
+            d->regions[1].node = d->sceneGraphContext()->createImageNode();
+
+        if (innerSourceRect.bottom() < 1 && innerSourceRect.left() < innerSourceRect.right())
+            d->regions[7].node = d->sceneGraphContext()->createImageNode();
+
+        if (innerSourceRect.left() < innerSourceRect.right() && innerSourceRect.top() < innerSourceRect.bottom())
+            d->regions[4].node = d->sceneGraphContext()->createImageNode();
+
+        for (int i=0; i<9; ++i) {
+            if (d->regions[i].node != 0)
+                oldNode->appendChildNode(d->regions[i].node);
         }
     }
-    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;
+
+
+    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);
+
+        QRectF rect(0,
+                    0,
+                    innerTargetRect.left(),
+                    innerTargetRect.top());
+        d->regions[0].node->setTargetRect(rect);
+        d->regions[0].node->setInnerTargetRect(rect);
+        d->regions[0].targetRect = rect;
+    }
+
+    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);
+
+        QRectF rect(innerTargetRect.left(),
+                    0,
+                    innerTargetRect.width(),
+                    innerTargetRect.top());
+        d->regions[1].node->setTargetRect(rect);
+        d->regions[1].node->setInnerTargetRect(rect);
+        d->regions[1].targetRect = rect;
+    }
+
+    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)));
+
+        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);
+
+        QRectF rect(innerTargetRect.right(),
+                    0,
+                    width() - innerTargetRect.width() - innerTargetRect.left(),
+                    innerTargetRect.top());
+        d->regions[2].node->setTargetRect(rect);
+        d->regions[2].node->setInnerTargetRect(rect);
+        d->regions[2].targetRect = rect;
+    }
+
+    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);
+
+        QRectF rect(0,
+                    innerTargetRect.top(),
+                    innerTargetRect.left(),
+                    innerTargetRect.height());
+        d->regions[3].node->setTargetRect(rect);
+        d->regions[3].node->setInnerTargetRect(rect);
+        d->regions[3].targetRect = rect;
+    }
+
+    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)));
+            }
         }
+
+        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);
+
+        d->regions[4].node->setInnerTargetRect(innerTargetRect);
+        d->regions[4].node->setTargetRect(innerTargetRect);
+        d->regions[4].targetRect = innerTargetRect;
     }
 
-    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);
+    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);
+
+        QRectF rect(innerTargetRect.right(),
+                    innerTargetRect.top(),
+                    width() - innerTargetRect.width() - innerTargetRect.left(),
+                    innerTargetRect.height());
+        d->regions[5].node->setTargetRect(rect);
+        d->regions[5].node->setInnerTargetRect(rect);
+        d->regions[5].targetRect = rect;
+    }
+
+    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);
+
+        QRectF rect(0,
+                    innerTargetRect.bottom(),
+                    innerTargetRect.left(),
+                    height() - innerTargetRect.height() - innerTargetRect.top());
+        d->regions[6].node->setTargetRect(rect);
+        d->regions[6].node->setInnerTargetRect(rect);
+        d->regions[6].targetRect = rect;
+    }
+
+    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);
+
+        QRectF rect(innerTargetRect.left(),
+                    innerTargetRect.bottom(),
+                    innerTargetRect.width(),
+                    height() - innerTargetRect.height() - innerTargetRect.top());
+        d->regions[7].node->setTargetRect(rect);
+        d->regions[7].node->setInnerTargetRect(rect);
+        d->regions[7].targetRect = rect;
+    }
+
+    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);
+
+        QRectF rect(innerTargetRect.right(),
+                    innerTargetRect.bottom(),
+                    width() - innerTargetRect.width() - innerTargetRect.left(),
+                    height() - innerTargetRect.height() - innerTargetRect.top());
+        d->regions[8].node->setTargetRect(rect);
+        d->regions[8].node->setInnerTargetRect(rect);
+        d->regions[8].targetRect = rect;
+    }
+
+    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->setAntialiasing(d->antialiasing);
-    node->update();
 
-    return node;
+    return oldNode;
 }
 
 void QQuickBorderImage::pixmapChange()
diff --git a/src/quick/items/qquickborderimage_p.h b/src/quick/items/qquickborderimage_p.h
index 6a2469adc2609f7d4b82189d91abbeebd1abb5fe..1d0898115ddbef91cfd5174152ee204fe4e1c361 100644
--- a/src/quick/items/qquickborderimage_p.h
+++ b/src/quick/items/qquickborderimage_p.h
@@ -87,6 +87,8 @@ 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 d5b959fd9f4dba90463edea787e77cfeac021f1d..bda2867696fb1a8fae0ee2f82554dfa7e65af08a 100644
--- a/src/quick/items/qquickborderimage_p_p.h
+++ b/src/quick/items/qquickborderimage_p_p.h
@@ -89,6 +89,16 @@ 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/scenegraph/qsgadaptationlayer_p.h b/src/quick/scenegraph/qsgadaptationlayer_p.h
index c96d0a99e3c0aa6099e3a5fbdc66766bb2f3be87..71033bd6d0f08abddc859a78293867202c372822 100644
--- a/src/quick/scenegraph/qsgadaptationlayer_p.h
+++ b/src/quick/scenegraph/qsgadaptationlayer_p.h
@@ -126,6 +126,17 @@ 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;
@@ -140,6 +151,7 @@ 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 7f85c31ccbf3151b1b9084c65ac54649c4713e6a..69df506d2aa02e99f71b476d2063d28bba9b8be6 100644
--- a/src/quick/scenegraph/qsgdefaultimagenode.cpp
+++ b/src/quick/scenegraph/qsgdefaultimagenode.cpp
@@ -140,10 +140,11 @@ 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);
@@ -249,10 +250,20 @@ void QSGDefaultImageNode::setTexture(QSGTexture *texture)
 
 void QSGDefaultImageNode::setAntialiasing(bool antialiasing)
 {
-    if (antialiasing == m_antialiasing)
+    AntialiasingFlags antialiasingFlags = antialiasing
+                                          ? AntialiasingAll
+                                          : AntialiasingNone;
+
+    setAntialiasing(antialiasingFlags);
+}
+
+void QSGDefaultImageNode::setAntialiasing(AntialiasingFlags antialiasingFlags)
+{
+    if (antialiasingFlags == m_antialiasing)
         return;
-    m_antialiasing = antialiasing;
-    if (m_antialiasing) {
+
+    m_antialiasing = antialiasingFlags;
+    if (m_antialiasing != AntialiasingNone) {
         setMaterial(&m_smoothMaterial);
         setOpaqueMaterial(0);
         setGeometry(new QSGGeometry(smoothAttributeSet(), 0));
@@ -364,11 +375,14 @@ 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 && (!hasTiles || (fullTexture && wrapSupported))) {
+        if (!hasMargins
+                && (m_antialiasing == AntialiasingAll || m_antialiasing == AntialiasingNone)
+                && (!hasTiles || (fullTexture && wrapSupported))) {
             QRectF sr;
             if (!fullTexture) {
                 sr = QRectF(innerSourceRect.x() + (m_subSourceRect.left() - floorLeft) * innerSourceRect.width(),
@@ -547,10 +561,35 @@ 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) {
@@ -600,28 +639,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 = -delta;
+                            vertices[topLeft + 1].dy = vertices[topRight + 1].dy = -deltaTop;
                             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 = delta;
+                            vertices[bottomLeft + 1].dy = vertices[bottomRight + 1].dy = deltaBottom;
                             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 = -delta;
+                            vertices[topLeft + 1].dx = vertices[bottomLeft + 1].dx = -deltaLeft;
                             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 = delta;
+                            vertices[topRight + 1].dx = vertices[bottomRight + 1].dx = deltaRight;
                             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 26b087284b1f6fbffd3801d97446d7bd2e1ff153..558e4d8ba49a88038ecc77e843228b8ff7981d80 100644
--- a/src/quick/scenegraph/qsgdefaultimagenode_p.h
+++ b/src/quick/scenegraph/qsgdefaultimagenode_p.h
@@ -62,6 +62,7 @@ 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();
 
@@ -84,11 +85,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/tests/manual/scenegraph_lancelot/data/borderimages/borderimage_rotated_smoothed.qml b/tests/manual/scenegraph_lancelot/data/borderimages/borderimage_rotated_smoothed.qml
new file mode 100644
index 0000000000000000000000000000000000000000..804567cf19f3f5a46a7ace11374a2b828a497806
--- /dev/null
+++ b/tests/manual/scenegraph_lancelot/data/borderimages/borderimage_rotated_smoothed.qml
@@ -0,0 +1,34 @@
+import QtQuick 2.2
+
+Rectangle {
+    width: 320
+    height: 480
+
+    color: "red"
+
+    Item {
+        x: 80
+        y: 80
+
+        BorderImage {
+            source: "../shared/uniquepixels.png"
+
+            width: 8
+            height: 8
+
+            antialiasing: true
+
+            horizontalTileMode: BorderImage.Repeat
+            verticalTileMode: BorderImage.Repeat
+
+            smooth: true
+            rotation: 10
+            scale: 10
+
+            border.bottom: 1
+            border.left: 1
+            border.right: 1
+            border.top: 1
+        }
+    }
+}
diff --git a/tests/manual/scenegraph_lancelot/data/borderimages/borderimage_rotated_unsmoothed.qml b/tests/manual/scenegraph_lancelot/data/borderimages/borderimage_rotated_unsmoothed.qml
new file mode 100644
index 0000000000000000000000000000000000000000..b10554ad660161bf3ed7f4be4a982ffd871d7ba7
--- /dev/null
+++ b/tests/manual/scenegraph_lancelot/data/borderimages/borderimage_rotated_unsmoothed.qml
@@ -0,0 +1,34 @@
+import QtQuick 2.2
+
+Rectangle {
+    width: 320
+    height: 480
+
+    color: "red"
+
+    Item {
+        x: 80
+        y: 80
+
+        BorderImage {
+            source: "../shared/uniquepixels.png"
+
+            width: 8
+            height: 8
+
+            antialiasing: true
+
+            horizontalTileMode: BorderImage.Repeat
+            verticalTileMode: BorderImage.Repeat
+
+            smooth: false
+            rotation: 10
+            scale: 10
+
+            border.bottom: 1
+            border.left: 1
+            border.right: 1
+            border.top: 1
+        }
+    }
+}
diff --git a/tests/manual/scenegraph_lancelot/data/borderimages/borderimage_rotated_unsmoothed_border_overlap.qml b/tests/manual/scenegraph_lancelot/data/borderimages/borderimage_rotated_unsmoothed_border_overlap.qml
new file mode 100644
index 0000000000000000000000000000000000000000..73cc53ed2be9eba992c6e13a0ed668f559efcd5f
--- /dev/null
+++ b/tests/manual/scenegraph_lancelot/data/borderimages/borderimage_rotated_unsmoothed_border_overlap.qml
@@ -0,0 +1,31 @@
+import QtQuick 2.2
+
+Rectangle {
+    width: 320
+    height: 480
+
+    color: "red"
+
+    Item {
+        x: 80
+        y: 80
+
+        BorderImage {
+            source: "../shared/uniquepixels.png"
+
+            antialiasing: true
+
+            horizontalTileMode: BorderImage.Repeat
+            verticalTileMode: BorderImage.Repeat
+
+            smooth: false
+            rotation: 10
+            scale: 10
+
+            border.bottom: 0
+            border.left: 3
+            border.right: 3
+            border.top: 0
+        }
+    }
+}
diff --git a/tests/manual/scenegraph_lancelot/data/borderimages/borderimage_rotated_unsmoothed_negative_borders.qml b/tests/manual/scenegraph_lancelot/data/borderimages/borderimage_rotated_unsmoothed_negative_borders.qml
new file mode 100644
index 0000000000000000000000000000000000000000..8356f02614ca5e9c8bf3d30d47ceca276cf2a3c2
--- /dev/null
+++ b/tests/manual/scenegraph_lancelot/data/borderimages/borderimage_rotated_unsmoothed_negative_borders.qml
@@ -0,0 +1,34 @@
+import QtQuick 2.2
+
+Rectangle {
+    width: 320
+    height: 480
+
+    color: "red"
+
+    Item {
+        x: 80
+        y: 80
+
+        BorderImage {
+            source: "../shared/uniquepixels.png"
+
+            width: 8
+            height: 8
+
+            antialiasing: true
+
+            horizontalTileMode: BorderImage.Repeat
+            verticalTileMode: BorderImage.Repeat
+
+            smooth: false
+            rotation: 10
+            scale: 10
+
+            border.bottom: -1
+            border.left: -1
+            border.right: -1
+            border.top: -1
+        }
+    }
+}
diff --git a/tests/manual/scenegraph_lancelot/data/borderimages/borderimage_rotated_unsmoothed_no_borders.qml b/tests/manual/scenegraph_lancelot/data/borderimages/borderimage_rotated_unsmoothed_no_borders.qml
new file mode 100644
index 0000000000000000000000000000000000000000..9213589648a77c86734cc55378cfd5f3a325fe40
--- /dev/null
+++ b/tests/manual/scenegraph_lancelot/data/borderimages/borderimage_rotated_unsmoothed_no_borders.qml
@@ -0,0 +1,34 @@
+import QtQuick 2.2
+
+Rectangle {
+    width: 320
+    height: 480
+
+    color: "red"
+
+    Item {
+        x: 80
+        y: 80
+
+        BorderImage {
+            source: "../shared/uniquepixels.png"
+
+            width: 8
+            height: 8
+
+            antialiasing: true
+
+            horizontalTileMode: BorderImage.Repeat
+            verticalTileMode: BorderImage.Repeat
+
+            smooth: false
+            rotation: 10
+            scale: 10
+
+            border.bottom: 0
+            border.left: 0
+            border.right: 0
+            border.top: 0
+        }
+    }
+}
diff --git a/tests/manual/scenegraph_lancelot/data/borderimages/borderimage_rotated_unsmoothed_no_bottom.qml b/tests/manual/scenegraph_lancelot/data/borderimages/borderimage_rotated_unsmoothed_no_bottom.qml
new file mode 100644
index 0000000000000000000000000000000000000000..615abdee20bfabbd1f1b7966daef789d726b1103
--- /dev/null
+++ b/tests/manual/scenegraph_lancelot/data/borderimages/borderimage_rotated_unsmoothed_no_bottom.qml
@@ -0,0 +1,34 @@
+import QtQuick 2.2
+
+Rectangle {
+    width: 320
+    height: 480
+
+    color: "red"
+
+    Item {
+        x: 80
+        y: 80
+
+        BorderImage {
+            source: "../shared/uniquepixels.png"
+
+            width: 8
+            height: 8
+
+            antialiasing: true
+
+            horizontalTileMode: BorderImage.Repeat
+            verticalTileMode: BorderImage.Repeat
+
+            smooth: false
+            rotation: 10
+            scale: 10
+
+            border.bottom: 0
+            border.left: 1
+            border.right: 1
+            border.top: 1
+        }
+    }
+}
diff --git a/tests/manual/scenegraph_lancelot/data/borderimages/borderimage_rotated_unsmoothed_no_center.qml b/tests/manual/scenegraph_lancelot/data/borderimages/borderimage_rotated_unsmoothed_no_center.qml
new file mode 100644
index 0000000000000000000000000000000000000000..58ed4d44dc5c91db84b97f2469485505e6124687
--- /dev/null
+++ b/tests/manual/scenegraph_lancelot/data/borderimages/borderimage_rotated_unsmoothed_no_center.qml
@@ -0,0 +1,34 @@
+import QtQuick 2.2
+
+Rectangle {
+    width: 320
+    height: 480
+
+    color: "red"
+
+    Item {
+        x: 80
+        y: 80
+
+        BorderImage {
+            source: "../shared/uniquepixels.png"
+
+            width: 8
+            height: 8
+
+            antialiasing: true
+
+            horizontalTileMode: BorderImage.Repeat
+            verticalTileMode: BorderImage.Repeat
+
+            smooth: false
+            rotation: 10
+            scale: 10
+
+            border.bottom: 4
+            border.left: 4
+            border.right: 4
+            border.top: 4
+        }
+    }
+}
diff --git a/tests/manual/scenegraph_lancelot/data/borderimages/borderimage_rotated_unsmoothed_no_left.qml b/tests/manual/scenegraph_lancelot/data/borderimages/borderimage_rotated_unsmoothed_no_left.qml
new file mode 100644
index 0000000000000000000000000000000000000000..7e0045bf24a2c496753e002bb52e92e470fb91ed
--- /dev/null
+++ b/tests/manual/scenegraph_lancelot/data/borderimages/borderimage_rotated_unsmoothed_no_left.qml
@@ -0,0 +1,34 @@
+import QtQuick 2.2
+
+Rectangle {
+    width: 320
+    height: 480
+
+    color: "red"
+
+    Item {
+        x: 80
+        y: 80
+
+        BorderImage {
+            source: "../shared/uniquepixels.png"
+
+            width: 8
+            height: 8
+
+            antialiasing: true
+
+            horizontalTileMode: BorderImage.Repeat
+            verticalTileMode: BorderImage.Repeat
+
+            smooth: false
+            rotation: 10
+            scale: 10
+
+            border.bottom: 1
+            border.left: 0
+            border.right: 1
+            border.top: 1
+        }
+    }
+}
diff --git a/tests/manual/scenegraph_lancelot/data/borderimages/borderimage_rotated_unsmoothed_no_right.qml b/tests/manual/scenegraph_lancelot/data/borderimages/borderimage_rotated_unsmoothed_no_right.qml
new file mode 100644
index 0000000000000000000000000000000000000000..04c2d021f0359fbe0e80187e6f5945445c07b9a4
--- /dev/null
+++ b/tests/manual/scenegraph_lancelot/data/borderimages/borderimage_rotated_unsmoothed_no_right.qml
@@ -0,0 +1,34 @@
+import QtQuick 2.2
+
+Rectangle {
+    width: 320
+    height: 480
+
+    color: "red"
+
+    Item {
+        x: 80
+        y: 80
+
+        BorderImage {
+            source: "../shared/uniquepixels.png"
+
+            width: 8
+            height: 8
+
+            antialiasing: true
+
+            horizontalTileMode: BorderImage.Repeat
+            verticalTileMode: BorderImage.Repeat
+
+            smooth: false
+            rotation: 10
+            scale: 10
+
+            border.bottom: 1
+            border.left: 1
+            border.right: 0
+            border.top: 1
+        }
+    }
+}
diff --git a/tests/manual/scenegraph_lancelot/data/borderimages/borderimage_rotated_unsmoothed_no_right_left.qml b/tests/manual/scenegraph_lancelot/data/borderimages/borderimage_rotated_unsmoothed_no_right_left.qml
new file mode 100644
index 0000000000000000000000000000000000000000..5210bab321ec2cd2488f320df66d1ce33e402320
--- /dev/null
+++ b/tests/manual/scenegraph_lancelot/data/borderimages/borderimage_rotated_unsmoothed_no_right_left.qml
@@ -0,0 +1,34 @@
+import QtQuick 2.2
+
+Rectangle {
+    width: 320
+    height: 480
+
+    color: "red"
+
+    Item {
+        x: 80
+        y: 80
+
+        BorderImage {
+            source: "../shared/uniquepixels.png"
+
+            width: 8
+            height: 8
+
+            antialiasing: true
+
+            horizontalTileMode: BorderImage.Repeat
+            verticalTileMode: BorderImage.Repeat
+
+            smooth: false
+            rotation: 10
+            scale: 10
+
+            border.bottom: 1
+            border.left: 0
+            border.right: 0
+            border.top: 1
+        }
+    }
+}
diff --git a/tests/manual/scenegraph_lancelot/data/borderimages/borderimage_rotated_unsmoothed_no_top.qml b/tests/manual/scenegraph_lancelot/data/borderimages/borderimage_rotated_unsmoothed_no_top.qml
new file mode 100644
index 0000000000000000000000000000000000000000..2e89496c921fe3a9fe03166a63f068328d3479e5
--- /dev/null
+++ b/tests/manual/scenegraph_lancelot/data/borderimages/borderimage_rotated_unsmoothed_no_top.qml
@@ -0,0 +1,34 @@
+import QtQuick 2.2
+
+Rectangle {
+    width: 320
+    height: 480
+
+    color: "red"
+
+    Item {
+        x: 80
+        y: 80
+
+        BorderImage {
+            source: "../shared/uniquepixels.png"
+
+            width: 8
+            height: 8
+
+            antialiasing: true
+
+            horizontalTileMode: BorderImage.Repeat
+            verticalTileMode: BorderImage.Repeat
+
+            smooth: false
+            rotation: 10
+            scale: 10
+
+            border.bottom: 1
+            border.left: 1
+            border.right: 1
+            border.top: 0
+        }
+    }
+}
diff --git a/tests/manual/scenegraph_lancelot/data/borderimages/borderimage_rotated_unsmoothed_no_top_bottom.qml b/tests/manual/scenegraph_lancelot/data/borderimages/borderimage_rotated_unsmoothed_no_top_bottom.qml
new file mode 100644
index 0000000000000000000000000000000000000000..4388601f13dbfb6b486d5bf8e15fbb3160011943
--- /dev/null
+++ b/tests/manual/scenegraph_lancelot/data/borderimages/borderimage_rotated_unsmoothed_no_top_bottom.qml
@@ -0,0 +1,34 @@
+import QtQuick 2.2
+
+Rectangle {
+    width: 320
+    height: 480
+
+    color: "red"
+
+    Item {
+        x: 80
+        y: 80
+
+        BorderImage {
+            source: "../shared/uniquepixels.png"
+
+            width: 8
+            height: 8
+
+            antialiasing: true
+
+            horizontalTileMode: BorderImage.Repeat
+            verticalTileMode: BorderImage.Repeat
+
+            smooth: false
+            rotation: 10
+            scale: 10
+
+            border.bottom: 0
+            border.left: 1
+            border.right: 1
+            border.top: 0
+        }
+    }
+}
diff --git a/tests/manual/scenegraph_lancelot/data/shared/uniquepixels.png b/tests/manual/scenegraph_lancelot/data/shared/uniquepixels.png
new file mode 100644
index 0000000000000000000000000000000000000000..af240b09c3e0dcf48480f340e832c2a5231f67c7
Binary files /dev/null and b/tests/manual/scenegraph_lancelot/data/shared/uniquepixels.png differ