[SCM] WebKit Debian packaging branch, debian/experimental, updated. upstream/1.3.3-9427-gc2be6fc

andreas.kling at nokia.com andreas.kling at nokia.com
Wed Dec 22 15:51:42 UTC 2010


The following commit has been merged in the debian/experimental branch:
commit 8be26126cb25bc82a556df0a8115a01ce7b8d693
Author: andreas.kling at nokia.com <andreas.kling at nokia.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Mon Nov 15 17:34:00 2010 +0000

    2010-11-15  Andreas Kling  <andreas.kling at nokia.com>
    
            Reviewed by Kenneth Rohde Christiansen.
    
            [WK2][Qt] WebKit2 implementation of tiled backing store
            https://bugs.webkit.org/show_bug.cgi?id=49526
    
            Basic opt-in tiling implementation for WebKit2/Qt.
    
            Original patch by Antti Koivisto.
    
            * Shared/CoreIPCSupport/DrawingAreaMessageKinds.h:
            New messages: RequestTileUpdate and CancelTileUpdate.
    
            * Shared/CoreIPCSupport/DrawingAreaProxyMessageKinds.h:
            New messages: Invalidate, TileUpdated, AllTileUpdatesProcessed.
    
            * Shared/DrawingAreaBase.h:
            New area type: TiledDrawingAreaType.
    
            * UIProcess/API/qt/qgraphicswkview.h:
            * UIProcess/API/qt/qgraphicswkview.cpp:
            (QGraphicsWKView::QGraphicsWKView):
            (QGraphicsWKView::setGeometry):
            (QGraphicsWKViewPrivate::QGraphicsWKViewPrivate):
            (QGraphicsWKView::prepareScaleChange):
            (QGraphicsWKView::commitScaleChange):
            (QGraphicsWKViewPrivate::onScaleChanged):
            (QGraphicsWKViewPrivate::commitScale):
            Support for tiled backing store.
    
            * UIProcess/TiledDrawingAreaProxy.cpp: Added.
            (WebKit::TiledDrawingAreaProxy::create):
            (WebKit::TiledDrawingAreaProxy::TiledDrawingAreaProxy):
            (WebKit::TiledDrawingAreaProxy::~TiledDrawingAreaProxy):
            (WebKit::TiledDrawingAreaProxy::setSize):
            (WebKit::TiledDrawingAreaProxy::setPageIsVisible):
            (WebKit::TiledDrawingAreaProxy::didSetSize):
            (WebKit::TiledDrawingAreaProxy::didReceiveMessage):
            (WebKit::TiledDrawingAreaProxy::didReceiveSyncMessage):
            (WebKit::TiledDrawingAreaProxy::requestTileUpdate):
            (WebKit::TiledDrawingAreaProxy::waitUntilUpdatesComplete):
            (WebKit::TiledDrawingAreaProxy::createTile):
            (WebKit::TiledDrawingAreaProxy::setTileSize):
            (WebKit::TiledDrawingAreaProxy::setTileCreationDelay):
            (WebKit::TiledDrawingAreaProxy::setKeepAndCoverAreaMultipliers):
            (WebKit::TiledDrawingAreaProxy::invalidate):
            (WebKit::TiledDrawingAreaProxy::updateTileBuffers):
            (WebKit::TiledDrawingAreaProxy::tileBufferUpdateComplete):
            (WebKit::TiledDrawingAreaProxy::paint):
            (WebKit::TiledDrawingAreaProxy::adjustVisibleRect):
            (WebKit::TiledDrawingAreaProxy::setContentsScale):
            (WebKit::TiledDrawingAreaProxy::removeAllTiles):
            (WebKit::TiledDrawingAreaProxy::tileDistance):
            (WebKit::TiledDrawingAreaProxy::calculateKeepRect):
            (WebKit::TiledDrawingAreaProxy::calculateCoverRect):
            (WebKit::TiledDrawingAreaProxy::createTiles):
            (WebKit::TiledDrawingAreaProxy::resizeEdgeTiles):
            (WebKit::TiledDrawingAreaProxy::dropTilesOutsideRect):
            (WebKit::TiledDrawingAreaProxy::tileAt):
            (WebKit::TiledDrawingAreaProxy::setTile):
            (WebKit::TiledDrawingAreaProxy::removeTile):
            (WebKit::TiledDrawingAreaProxy::mapToContents):
            (WebKit::TiledDrawingAreaProxy::mapFromContents):
            (WebKit::TiledDrawingAreaProxy::contentsRect):
            (WebKit::TiledDrawingAreaProxy::tileRectForCoordinate):
            (WebKit::TiledDrawingAreaProxy::tileCoordinateForPoint):
            (WebKit::TiledDrawingAreaProxy::startTileBufferUpdateTimer):
            (WebKit::TiledDrawingAreaProxy::tileBufferUpdateTimerFired):
            (WebKit::TiledDrawingAreaProxy::startTileCreationTimer):
            (WebKit::TiledDrawingAreaProxy::tileCreationTimerFired):
            (WebKit::TiledDrawingAreaProxy::hasPendingUpdates):
            * UIProcess/TiledDrawingAreaProxy.h: Added.
            (WebKit::TiledDrawingAreaProxy::contentsScale):
            (WebKit::TiledDrawingAreaProxy::attachCompositingContext):
            (WebKit::TiledDrawingAreaProxy::detachCompositingContext):
            (WebKit::TiledDrawingAreaProxy::tileSize):
            (WebKit::TiledDrawingAreaProxy::tileCreationDelay):
            (WebKit::TiledDrawingAreaProxy::getKeepAndCoverAreaMultipliers):
            * UIProcess/TiledDrawingAreaTile.h: Added.
            (WebKit::TiledDrawingAreaTile::create):
            (WebKit::TiledDrawingAreaTile::hasBackBufferUpdatePending):
            (WebKit::TiledDrawingAreaTile::coordinate):
            (WebKit::TiledDrawingAreaTile::rect):
            (WebKit::TiledDrawingAreaTile::ID):
            * WebProcess/WebPage/DrawingArea.cpp:
            (WebKit::DrawingArea::create):
            * WebProcess/WebPage/TiledDrawingArea.cpp: Added.
            (WebKit::TiledDrawingArea::TiledDrawingArea):
            (WebKit::TiledDrawingArea::~TiledDrawingArea):
            (WebKit::TiledDrawingArea::invalidateWindow):
            (WebKit::TiledDrawingArea::invalidateContentsAndWindow):
            (WebKit::TiledDrawingArea::invalidateContentsForSlowScroll):
            (WebKit::TiledDrawingArea::scroll):
            (WebKit::TiledDrawingArea::setNeedsDisplay):
            (WebKit::TiledDrawingArea::display):
            (WebKit::TiledDrawingArea::scheduleDisplay):
            (WebKit::TiledDrawingArea::setSize):
            (WebKit::TiledDrawingArea::suspendPainting):
            (WebKit::TiledDrawingArea::resumePainting):
            (WebKit::TiledDrawingArea::didUpdate):
            (WebKit::TiledDrawingArea::updateTile):
            (WebKit::TiledDrawingArea::tileUpdateTimerFired):
            (WebKit::TiledDrawingArea::didReceiveMessage):
            * WebProcess/WebPage/TiledDrawingArea.h: Added.
            (WebKit::TiledDrawingArea::attachCompositingContext):
            (WebKit::TiledDrawingArea::detachCompositingContext):
            (WebKit::TiledDrawingArea::setRootCompositingLayer):
            (WebKit::TiledDrawingArea::scheduleCompositingLayerSync):
            (WebKit::TiledDrawingArea::syncCompositingLayers):
            * WebProcess/WebPage/qt/TiledDrawingAreaQt.cpp: Added.
            (WebKit::TiledDrawingArea::paintIntoUpdateChunk):
            * WebKit2.pro:
            * UIProcess/qt/TiledDrawingAreaTileQt.cpp: Added.
            (WebKit::checkeredPixmap):
            (WebKit::TiledDrawingAreaTile::TiledDrawingAreaTile):
            (WebKit::TiledDrawingAreaTile::~TiledDrawingAreaTile):
            (WebKit::TiledDrawingAreaTile::isDirty):
            (WebKit::TiledDrawingAreaTile::isReadyToPaint):
            (WebKit::TiledDrawingAreaTile::hasReadyBackBuffer):
            (WebKit::TiledDrawingAreaTile::invalidate):
            (WebKit::TiledDrawingAreaTile::resize):
            (WebKit::TiledDrawingAreaTile::swapBackBufferToFront):
            (WebKit::TiledDrawingAreaTile::paint):
            (WebKit::TiledDrawingAreaTile::paintCheckerPattern):
            (WebKit::TiledDrawingAreaTile::updateFromChunk):
            (WebKit::TiledDrawingAreaTile::updateBackBuffer):
            * UIProcess/qt/TiledDrawingAreaProxyQt.cpp: Added.
            (WebKit::TiledDrawingAreaProxy::updateWebView):
            (WebKit::TiledDrawingAreaProxy::webViewVisibleRect):
            (WebKit::TiledDrawingAreaProxy::page):
    
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@72010 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/WebKit2/ChangeLog b/WebKit2/ChangeLog
index bcbf556..ed41d6c 100644
--- a/WebKit2/ChangeLog
+++ b/WebKit2/ChangeLog
@@ -1,3 +1,135 @@
+2010-11-15  Andreas Kling  <andreas.kling at nokia.com>
+
+        Reviewed by Kenneth Rohde Christiansen.
+
+        [WK2][Qt] WebKit2 implementation of tiled backing store
+        https://bugs.webkit.org/show_bug.cgi?id=49526
+
+        Basic opt-in tiling implementation for WebKit2/Qt.
+
+        Original patch by Antti Koivisto.
+
+        * Shared/CoreIPCSupport/DrawingAreaMessageKinds.h:
+        New messages: RequestTileUpdate and CancelTileUpdate.
+
+        * Shared/CoreIPCSupport/DrawingAreaProxyMessageKinds.h:
+        New messages: Invalidate, TileUpdated, AllTileUpdatesProcessed.
+
+        * Shared/DrawingAreaBase.h:
+        New area type: TiledDrawingAreaType.
+
+        * UIProcess/API/qt/qgraphicswkview.h:
+        * UIProcess/API/qt/qgraphicswkview.cpp:
+        (QGraphicsWKView::QGraphicsWKView):
+        (QGraphicsWKView::setGeometry):
+        (QGraphicsWKViewPrivate::QGraphicsWKViewPrivate):
+        (QGraphicsWKView::prepareScaleChange):
+        (QGraphicsWKView::commitScaleChange):
+        (QGraphicsWKViewPrivate::onScaleChanged):
+        (QGraphicsWKViewPrivate::commitScale):
+        Support for tiled backing store.
+
+        * UIProcess/TiledDrawingAreaProxy.cpp: Added.
+        (WebKit::TiledDrawingAreaProxy::create):
+        (WebKit::TiledDrawingAreaProxy::TiledDrawingAreaProxy):
+        (WebKit::TiledDrawingAreaProxy::~TiledDrawingAreaProxy):
+        (WebKit::TiledDrawingAreaProxy::setSize):
+        (WebKit::TiledDrawingAreaProxy::setPageIsVisible):
+        (WebKit::TiledDrawingAreaProxy::didSetSize):
+        (WebKit::TiledDrawingAreaProxy::didReceiveMessage):
+        (WebKit::TiledDrawingAreaProxy::didReceiveSyncMessage):
+        (WebKit::TiledDrawingAreaProxy::requestTileUpdate):
+        (WebKit::TiledDrawingAreaProxy::waitUntilUpdatesComplete):
+        (WebKit::TiledDrawingAreaProxy::createTile):
+        (WebKit::TiledDrawingAreaProxy::setTileSize):
+        (WebKit::TiledDrawingAreaProxy::setTileCreationDelay):
+        (WebKit::TiledDrawingAreaProxy::setKeepAndCoverAreaMultipliers):
+        (WebKit::TiledDrawingAreaProxy::invalidate):
+        (WebKit::TiledDrawingAreaProxy::updateTileBuffers):
+        (WebKit::TiledDrawingAreaProxy::tileBufferUpdateComplete):
+        (WebKit::TiledDrawingAreaProxy::paint):
+        (WebKit::TiledDrawingAreaProxy::adjustVisibleRect):
+        (WebKit::TiledDrawingAreaProxy::setContentsScale):
+        (WebKit::TiledDrawingAreaProxy::removeAllTiles):
+        (WebKit::TiledDrawingAreaProxy::tileDistance):
+        (WebKit::TiledDrawingAreaProxy::calculateKeepRect):
+        (WebKit::TiledDrawingAreaProxy::calculateCoverRect):
+        (WebKit::TiledDrawingAreaProxy::createTiles):
+        (WebKit::TiledDrawingAreaProxy::resizeEdgeTiles):
+        (WebKit::TiledDrawingAreaProxy::dropTilesOutsideRect):
+        (WebKit::TiledDrawingAreaProxy::tileAt):
+        (WebKit::TiledDrawingAreaProxy::setTile):
+        (WebKit::TiledDrawingAreaProxy::removeTile):
+        (WebKit::TiledDrawingAreaProxy::mapToContents):
+        (WebKit::TiledDrawingAreaProxy::mapFromContents):
+        (WebKit::TiledDrawingAreaProxy::contentsRect):
+        (WebKit::TiledDrawingAreaProxy::tileRectForCoordinate):
+        (WebKit::TiledDrawingAreaProxy::tileCoordinateForPoint):
+        (WebKit::TiledDrawingAreaProxy::startTileBufferUpdateTimer):
+        (WebKit::TiledDrawingAreaProxy::tileBufferUpdateTimerFired):
+        (WebKit::TiledDrawingAreaProxy::startTileCreationTimer):
+        (WebKit::TiledDrawingAreaProxy::tileCreationTimerFired):
+        (WebKit::TiledDrawingAreaProxy::hasPendingUpdates):
+        * UIProcess/TiledDrawingAreaProxy.h: Added.
+        (WebKit::TiledDrawingAreaProxy::contentsScale):
+        (WebKit::TiledDrawingAreaProxy::attachCompositingContext):
+        (WebKit::TiledDrawingAreaProxy::detachCompositingContext):
+        (WebKit::TiledDrawingAreaProxy::tileSize):
+        (WebKit::TiledDrawingAreaProxy::tileCreationDelay):
+        (WebKit::TiledDrawingAreaProxy::getKeepAndCoverAreaMultipliers):
+        * UIProcess/TiledDrawingAreaTile.h: Added.
+        (WebKit::TiledDrawingAreaTile::create):
+        (WebKit::TiledDrawingAreaTile::hasBackBufferUpdatePending):
+        (WebKit::TiledDrawingAreaTile::coordinate):
+        (WebKit::TiledDrawingAreaTile::rect):
+        (WebKit::TiledDrawingAreaTile::ID):
+        * WebProcess/WebPage/DrawingArea.cpp:
+        (WebKit::DrawingArea::create):
+        * WebProcess/WebPage/TiledDrawingArea.cpp: Added.
+        (WebKit::TiledDrawingArea::TiledDrawingArea):
+        (WebKit::TiledDrawingArea::~TiledDrawingArea):
+        (WebKit::TiledDrawingArea::invalidateWindow):
+        (WebKit::TiledDrawingArea::invalidateContentsAndWindow):
+        (WebKit::TiledDrawingArea::invalidateContentsForSlowScroll):
+        (WebKit::TiledDrawingArea::scroll):
+        (WebKit::TiledDrawingArea::setNeedsDisplay):
+        (WebKit::TiledDrawingArea::display):
+        (WebKit::TiledDrawingArea::scheduleDisplay):
+        (WebKit::TiledDrawingArea::setSize):
+        (WebKit::TiledDrawingArea::suspendPainting):
+        (WebKit::TiledDrawingArea::resumePainting):
+        (WebKit::TiledDrawingArea::didUpdate):
+        (WebKit::TiledDrawingArea::updateTile):
+        (WebKit::TiledDrawingArea::tileUpdateTimerFired):
+        (WebKit::TiledDrawingArea::didReceiveMessage):
+        * WebProcess/WebPage/TiledDrawingArea.h: Added.
+        (WebKit::TiledDrawingArea::attachCompositingContext):
+        (WebKit::TiledDrawingArea::detachCompositingContext):
+        (WebKit::TiledDrawingArea::setRootCompositingLayer):
+        (WebKit::TiledDrawingArea::scheduleCompositingLayerSync):
+        (WebKit::TiledDrawingArea::syncCompositingLayers):
+        * WebProcess/WebPage/qt/TiledDrawingAreaQt.cpp: Added.
+        (WebKit::TiledDrawingArea::paintIntoUpdateChunk):
+        * WebKit2.pro:
+        * UIProcess/qt/TiledDrawingAreaTileQt.cpp: Added.
+        (WebKit::checkeredPixmap):
+        (WebKit::TiledDrawingAreaTile::TiledDrawingAreaTile):
+        (WebKit::TiledDrawingAreaTile::~TiledDrawingAreaTile):
+        (WebKit::TiledDrawingAreaTile::isDirty):
+        (WebKit::TiledDrawingAreaTile::isReadyToPaint):
+        (WebKit::TiledDrawingAreaTile::hasReadyBackBuffer):
+        (WebKit::TiledDrawingAreaTile::invalidate):
+        (WebKit::TiledDrawingAreaTile::resize):
+        (WebKit::TiledDrawingAreaTile::swapBackBufferToFront):
+        (WebKit::TiledDrawingAreaTile::paint):
+        (WebKit::TiledDrawingAreaTile::paintCheckerPattern):
+        (WebKit::TiledDrawingAreaTile::updateFromChunk):
+        (WebKit::TiledDrawingAreaTile::updateBackBuffer):
+        * UIProcess/qt/TiledDrawingAreaProxyQt.cpp: Added.
+        (WebKit::TiledDrawingAreaProxy::updateWebView):
+        (WebKit::TiledDrawingAreaProxy::webViewVisibleRect):
+        (WebKit::TiledDrawingAreaProxy::page):
+
 2010-11-12  Benjamin Poulain  <benjamin.poulain at nokia.com>
 
         Reviewed by Andreas Kling.
diff --git a/WebKit2/Shared/CoreIPCSupport/DrawingAreaMessageKinds.h b/WebKit2/Shared/CoreIPCSupport/DrawingAreaMessageKinds.h
index 802e612..0d2ec26 100644
--- a/WebKit2/Shared/CoreIPCSupport/DrawingAreaMessageKinds.h
+++ b/WebKit2/Shared/CoreIPCSupport/DrawingAreaMessageKinds.h
@@ -45,6 +45,14 @@ enum Kind {
     // Called when an update chunk sent to the drawing area has been
     // incorporated into the backing store.
     DidUpdate,
+
+#if ENABLE(TILED_BACKING_STORE)
+    // Called to request a tile update.
+    RequestTileUpdate,
+
+    // Called to cancel a requested tile update.
+    CancelTileUpdate,
+#endif
 };
 
 }
diff --git a/WebKit2/Shared/CoreIPCSupport/DrawingAreaProxyMessageKinds.h b/WebKit2/Shared/CoreIPCSupport/DrawingAreaProxyMessageKinds.h
index 8b29ed1..254a9ce 100644
--- a/WebKit2/Shared/CoreIPCSupport/DrawingAreaProxyMessageKinds.h
+++ b/WebKit2/Shared/CoreIPCSupport/DrawingAreaProxyMessageKinds.h
@@ -38,6 +38,11 @@ enum Kind {
 #if USE(ACCELERATED_COMPOSITING)
     AttachCompositingContext,
 #endif
+#if ENABLE(TILED_BACKING_STORE)
+    Invalidate,
+    TileUpdated,
+    AllTileUpdatesProcessed,
+#endif
 };
 
 }
diff --git a/WebKit2/Shared/DrawingAreaBase.h b/WebKit2/Shared/DrawingAreaBase.h
index 41656d8..146e38e 100644
--- a/WebKit2/Shared/DrawingAreaBase.h
+++ b/WebKit2/Shared/DrawingAreaBase.h
@@ -44,6 +44,9 @@ public:
 #if USE(ACCELERATED_COMPOSITING)
         LayerBackedDrawingAreaType,
 #endif
+#if ENABLE(TILED_BACKING_STORE)
+        TiledDrawingAreaType,
+#endif
     };
     
     typedef uint64_t DrawingAreaID;
diff --git a/WebKit2/UIProcess/API/qt/qgraphicswkview.cpp b/WebKit2/UIProcess/API/qt/qgraphicswkview.cpp
index 92c43ca..2a8a880 100644
--- a/WebKit2/UIProcess/API/qt/qgraphicswkview.cpp
+++ b/WebKit2/UIProcess/API/qt/qgraphicswkview.cpp
@@ -23,6 +23,8 @@
 #include "ChunkedUpdateDrawingAreaProxy.h"
 #include "IntSize.h"
 #include "RunLoop.h"
+#include "TiledDrawingAreaProxy.h"
+#include "UpdateChunk.h"
 #include "WKAPICast.h"
 #include "WebPageNamespace.h"
 #include "qwkpage.h"
@@ -33,6 +35,7 @@
 #include <QPainter>
 #include <QScrollBar>
 #include <QStyleOptionGraphicsItem>
+#include <QUrl>
 #include <QtDebug>
 #include <WebKit2/WKRetainPtr.h>
 #include <wtf/RefPtr.h>
@@ -45,8 +48,13 @@ struct QGraphicsWKViewPrivate {
     QGraphicsWKViewPrivate(QGraphicsWKView* view);
     WKPageRef pageRef() const { return page->pageRef(); }
 
+    void onScaleChanged();
+    void commitScale();
+
     QGraphicsWKView* q;
     QWKPage* page;
+    RunLoop::Timer<QGraphicsWKViewPrivate> m_scaleCommitTimer;
+    bool m_isChangingScale;
 };
 
 QGraphicsWKView::QGraphicsWKView(WKPageNamespaceRef pageNamespaceRef, BackingStoreType backingStoreType, QGraphicsItem* parent)
@@ -56,8 +64,23 @@ QGraphicsWKView::QGraphicsWKView(WKPageNamespaceRef pageNamespaceRef, BackingSto
     setFocusPolicy(Qt::StrongFocus);
     setAcceptHoverEvents(true);
 
+    PassOwnPtr<DrawingAreaProxy> drawingAreaProxy;
+
+    switch (backingStoreType) {
+#if ENABLE(TILED_BACKING_STORE)
+    case Tiled:
+        drawingAreaProxy = TiledDrawingAreaProxy::create(this);
+        connect(this, SIGNAL(scaleChanged()), this, SLOT(onScaleChanged()));
+        break;
+#endif
+    case Simple:
+    default:
+        drawingAreaProxy = ChunkedUpdateDrawingAreaProxy::create(this);
+        break;
+    }
+
     d->page = new QWKPage(pageNamespaceRef);
-    d->page->d->init(size().toSize(), ChunkedUpdateDrawingAreaProxy::create(this));
+    d->page->d->init(size().toSize(), drawingAreaProxy);
     connect(d->page, SIGNAL(titleChanged(QString)), this, SIGNAL(titleChanged(QString)));
     connect(d->page, SIGNAL(loadStarted()), this, SIGNAL(loadStarted()));
     connect(d->page, SIGNAL(loadFinished(bool)), this, SIGNAL(loadFinished(bool)));
@@ -85,7 +108,10 @@ void QGraphicsWKView::paint(QPainter* painter, const QStyleOptionGraphicsItem* o
 
 void QGraphicsWKView::setGeometry(const QRectF& rect)
 {
+    QSizeF oldSize = geometry().size();
     QGraphicsWidget::setGeometry(rect);
+    if (geometry().size() == oldSize)
+        return;
 
     // NOTE: call geometry() as setGeometry ensures that
     // the geometry is within legal bounds (minimumSize, maximumSize)
@@ -262,6 +288,7 @@ void QGraphicsWKView::focusOutEvent(QFocusEvent*)
 
 QGraphicsWKViewPrivate::QGraphicsWKViewPrivate(QGraphicsWKView* view)
     : q(view)
+    , m_scaleCommitTimer(RunLoop::current(), this, &QGraphicsWKViewPrivate::commitScale)
 {
 }
 
@@ -280,4 +307,46 @@ QRectF QGraphicsWKView::visibleRect() const
     return mapRectFromScene(QRectF(QPointF(xOffset, yOffset), graphicsView->viewport()->size()));
 }
 
+void QGraphicsWKView::prepareScaleChange()
+{
+#if ENABLE(TILED_BACKING_STORE)
+    ASSERT(!d->m_isChangingScale);
+    d->m_isChangingScale = true;
+    d->m_scaleCommitTimer.stop();
+#endif
+}
+
+void QGraphicsWKView::commitScaleChange()
+{
+#if ENABLE(TILED_BACKING_STORE)
+    ASSERT(d->m_isChangingScale);
+    d->m_isChangingScale = false;
+    d->commitScale();
+#endif
+}
+
+void QGraphicsWKViewPrivate::onScaleChanged()
+{
+#if ENABLE(TILED_BACKING_STORE)
+    if (!m_isChangingScale)
+        m_scaleCommitTimer.startOneShot(0.1);
+#endif
+}
+
+void QGraphicsWKViewPrivate::commitScale()
+{
+#if ENABLE(TILED_BACKING_STORE)
+    DrawingAreaProxy* drawingArea = page->d->page->drawingArea();
+    float newScale = q->scale();
+    if (drawingArea->info().type == DrawingAreaProxy::TiledDrawingAreaType) {
+        TiledDrawingAreaProxy* tiledDrawingArea = static_cast<TiledDrawingAreaProxy*>(drawingArea);
+        if (tiledDrawingArea->contentsScale() == newScale)
+            return;
+        tiledDrawingArea->setContentsScale(newScale);
+        // For now we block until complete.
+        tiledDrawingArea->waitUntilUpdatesComplete();
+    }
+#endif
+}
+
 #include "moc_qgraphicswkview.cpp"
diff --git a/WebKit2/UIProcess/API/qt/qgraphicswkview.h b/WebKit2/UIProcess/API/qt/qgraphicswkview.h
index c5e43b2..dd24ac1 100644
--- a/WebKit2/UIProcess/API/qt/qgraphicswkview.h
+++ b/WebKit2/UIProcess/API/qt/qgraphicswkview.h
@@ -48,6 +48,9 @@ public:
     // FIXME: should not be public
     virtual QRectF visibleRect() const;
 
+    void prepareScaleChange();
+    void commitScaleChange();
+
 public:
     Q_SIGNAL void titleChanged(const QString& title);
     Q_SIGNAL void loadStarted();
@@ -80,8 +83,11 @@ protected:
     virtual void focusOutEvent(QFocusEvent*);
 
 private:
+    Q_PRIVATE_SLOT(d, void onScaleChanged());
+
     QGraphicsWKViewPrivate* d;
     friend class QGraphicsWKViewPrivate;
+    friend class TiledDrawingAreaProxy;
 };
 
 #endif /* qgraphicswkview_h */
diff --git a/WebKit2/UIProcess/TiledDrawingAreaProxy.cpp b/WebKit2/UIProcess/TiledDrawingAreaProxy.cpp
new file mode 100644
index 0000000..9b22637
--- /dev/null
+++ b/WebKit2/UIProcess/TiledDrawingAreaProxy.cpp
@@ -0,0 +1,614 @@
+/*
+ * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "TiledDrawingAreaProxy.h"
+
+#include "DrawingAreaMessageKinds.h"
+#include "DrawingAreaProxyMessageKinds.h"
+#include "MessageID.h"
+#include "UpdateChunk.h"
+#include "WebCoreArgumentCoders.h"
+#include "WebPageProxy.h"
+#include "WebProcessProxy.h"
+
+using namespace WebCore;
+
+namespace WebKit {
+
+static const int defaultTileWidth = 1024;
+static const int defaultTileHeight = 1024;
+
+PassOwnPtr<TiledDrawingAreaProxy> TiledDrawingAreaProxy::create(PlatformWebView* webView)
+{
+    return adoptPtr(new TiledDrawingAreaProxy(webView));
+}
+
+TiledDrawingAreaProxy::TiledDrawingAreaProxy(PlatformWebView* webView)
+    : DrawingAreaProxy(TiledDrawingAreaType)
+    , m_isWaitingForDidSetFrameNotification(false)
+    , m_isVisible(true)
+    , m_webView(webView)
+    , m_tileBufferUpdateTimer(RunLoop::main(), this, &TiledDrawingAreaProxy::tileBufferUpdateTimerFired)
+    , m_tileCreationTimer(RunLoop::main(), this, &TiledDrawingAreaProxy::tileCreationTimerFired)
+    , m_tileSize(defaultTileWidth, defaultTileHeight)
+    , m_tileCreationDelay(0.01)
+    , m_keepAreaMultiplier(2.5, 4.5)
+    , m_coverAreaMultiplier(2, 3)
+    , m_contentsScale(1)
+{
+}
+
+TiledDrawingAreaProxy::~TiledDrawingAreaProxy()
+{
+}
+
+void TiledDrawingAreaProxy::setSize(const IntSize& viewSize)
+{
+    WebPageProxy* page = this->page();
+    if (!page || !page->isValid())
+        return;
+
+    if (viewSize.isEmpty())
+        return;
+
+    m_viewSize = viewSize;
+    m_lastSetViewSize = viewSize;
+
+    if (m_isWaitingForDidSetFrameNotification)
+        return;
+    m_isWaitingForDidSetFrameNotification = true;
+
+    page->process()->responsivenessTimer()->start();
+    page->process()->send(DrawingAreaMessage::SetSize, page->pageID(), CoreIPC::In(viewSize));
+}
+
+void TiledDrawingAreaProxy::setPageIsVisible(bool isVisible)
+{
+    WebPageProxy* page = this->page();
+
+    if (isVisible == m_isVisible)
+        return;
+
+    m_isVisible = isVisible;
+    if (!page || !page->isValid())
+        return;
+
+    if (!m_isVisible) {
+        // Tell the web process that it doesn't need to paint anything for now.
+        page->process()->send(DrawingAreaMessage::SuspendPainting, page->pageID(), CoreIPC::In());
+        return;
+    }
+
+    // The page is now visible.
+    page->process()->send(DrawingAreaMessage::ResumePainting, page->pageID(), CoreIPC::In());
+
+    // FIXME: We should request a full repaint here if needed.
+}
+
+void TiledDrawingAreaProxy::didSetSize(const IntSize& viewSize)
+{
+    ASSERT(m_isWaitingForDidSetFrameNotification);
+    m_isWaitingForDidSetFrameNotification = false;
+
+    if (viewSize != m_lastSetViewSize)
+        setSize(m_lastSetViewSize);
+
+    WebPageProxy* page = this->page();
+    page->process()->responsivenessTimer()->stop();
+}
+
+void TiledDrawingAreaProxy::didReceiveMessage(CoreIPC::Connection*, CoreIPC::MessageID messageID, CoreIPC::ArgumentDecoder* arguments)
+{
+    switch (messageID.get<DrawingAreaProxyMessage::Kind>()) {
+    case DrawingAreaProxyMessage::TileUpdated: {
+        int tileID;
+        UpdateChunk updateChunk;
+        float scale;
+        unsigned pendingUpdateCount;
+        if (!arguments->decode(CoreIPC::Out(tileID, updateChunk, scale, pendingUpdateCount)))
+            return;
+
+        TiledDrawingAreaTile* tile = m_tilesByID.get(tileID);
+        ASSERT(!tile || tile->ID() == tileID);
+        if (tile)
+            tile->updateFromChunk(&updateChunk, scale);
+        tileBufferUpdateComplete();
+        break;
+    }
+    case DrawingAreaProxyMessage::DidSetSize: {
+        IntSize size;
+        if (!arguments->decode(CoreIPC::Out(size)))
+            return;
+
+        didSetSize(size);
+        break;
+    }
+    case DrawingAreaProxyMessage::Invalidate: {
+        IntRect rect;
+        if (!arguments->decode(CoreIPC::Out(rect)))
+            return;
+
+        invalidate(rect);
+        break;
+    }
+    case DrawingAreaProxyMessage::AllTileUpdatesProcessed: {
+        tileBufferUpdateComplete();
+        break;
+    }
+    default:
+        ASSERT_NOT_REACHED();
+    }
+}
+
+void TiledDrawingAreaProxy::didReceiveSyncMessage(CoreIPC::Connection*, CoreIPC::MessageID, CoreIPC::ArgumentDecoder*, CoreIPC::ArgumentEncoder&)
+{
+    ASSERT_NOT_REACHED();
+}
+
+void TiledDrawingAreaProxy::requestTileUpdate(int tileID, const IntRect& dirtyRect)
+{
+    page()->process()->connection()->send(DrawingAreaMessage::RequestTileUpdate, page()->pageID(), CoreIPC::In(tileID, dirtyRect, contentsScale()));
+}
+
+void TiledDrawingAreaProxy::waitUntilUpdatesComplete()
+{
+    while (hasPendingUpdates()) {
+        int tileID;
+        UpdateChunk updateChunk;
+        float scale;
+        unsigned pendingUpdateCount;
+        static const double tileUpdateTimeout = 10.0;
+        OwnPtr<CoreIPC::ArgumentDecoder> arguments = page()->process()->connection()->waitFor(DrawingAreaProxyMessage::TileUpdated, page()->pageID(), tileUpdateTimeout);
+        if (!arguments)
+            break;
+        if (!arguments->decode(CoreIPC::Out(tileID, updateChunk, scale, pendingUpdateCount)))
+            break;
+        TiledDrawingAreaTile* tile = m_tilesByID.get(tileID);
+        ASSERT(!tile || tile->ID() == tileID);
+        if (tile)
+            tile->updateFromChunk(&updateChunk, scale);
+    }
+    tileBufferUpdateComplete();
+}
+
+PassRefPtr<TiledDrawingAreaTile> TiledDrawingAreaProxy::createTile(const TiledDrawingAreaTile::Coordinate& coordinate)
+{
+    RefPtr<TiledDrawingAreaTile> tile = TiledDrawingAreaTile::create(this, coordinate);
+    setTile(coordinate, tile);
+    return tile;
+}
+
+void TiledDrawingAreaProxy::setTileSize(const IntSize& size)
+{
+    if (m_tileSize == size)
+        return;
+    m_tileSize = size;
+    removeAllTiles();
+    startTileCreationTimer();
+}
+
+void TiledDrawingAreaProxy::setTileCreationDelay(double delay)
+{
+    m_tileCreationDelay = delay;
+}
+
+void TiledDrawingAreaProxy::setKeepAndCoverAreaMultipliers(const FloatSize& keepMultiplier, const FloatSize& coverMultiplier)
+{
+    m_keepAreaMultiplier = keepMultiplier;
+    m_coverAreaMultiplier = coverMultiplier;
+    startTileCreationTimer();
+}
+
+void TiledDrawingAreaProxy::invalidate(const IntRect& contentsDirtyRect)
+{
+    IntRect dirtyRect(mapFromContents(contentsDirtyRect));
+
+    TiledDrawingAreaTile::Coordinate topLeft = tileCoordinateForPoint(dirtyRect.topLeft());
+    TiledDrawingAreaTile::Coordinate bottomRight = tileCoordinateForPoint(dirtyRect.bottomRight());
+
+    IntRect coverRect = calculateCoverRect(m_previousVisibleRect);
+
+    Vector<TiledDrawingAreaTile::Coordinate> tilesToRemove;
+
+    for (unsigned yCoordinate = topLeft.y(); yCoordinate <= bottomRight.y(); ++yCoordinate) {
+        for (unsigned xCoordinate = topLeft.x(); xCoordinate <= bottomRight.x(); ++xCoordinate) {
+            RefPtr<TiledDrawingAreaTile> currentTile = tileAt(TiledDrawingAreaTile::Coordinate(xCoordinate, yCoordinate));
+            if (!currentTile)
+                continue;
+            if (!currentTile->rect().intersects(dirtyRect))
+                continue;
+            // If a tile outside out current cover rect gets invalidated, just drop it instead of updating.
+            if (!currentTile->rect().intersects(coverRect)) {
+                tilesToRemove.append(currentTile->coordinate());
+                continue;
+            }
+            currentTile->invalidate(dirtyRect);
+        }
+    }
+
+    unsigned removeCount = tilesToRemove.size();
+    for (unsigned n = 0; n < removeCount; ++n)
+        removeTile(tilesToRemove[n]);
+
+    startTileBufferUpdateTimer();
+}
+
+void TiledDrawingAreaProxy::updateTileBuffers()
+{
+    Vector<RefPtr<TiledDrawingAreaTile> > newDirtyTiles;
+    TileMap::iterator end = m_tiles.end();
+    for (TileMap::iterator it = m_tiles.begin(); it != end; ++it) {
+        RefPtr<TiledDrawingAreaTile>& current = it->second;
+        if (!current->isDirty())
+            continue;
+        newDirtyTiles.append(it->second);
+    }
+
+    if (newDirtyTiles.isEmpty())
+        return;
+
+    unsigned size = newDirtyTiles.size();
+    for (unsigned n = 0; n < size; ++n)
+        newDirtyTiles[n]->updateBackBuffer();
+}
+
+void TiledDrawingAreaProxy::tileBufferUpdateComplete()
+{
+    // Bail out if all tile back buffers have not been updated.
+    Vector<TiledDrawingAreaTile*> tilesToFlip;
+    TileMap::iterator end = m_tiles.end();
+    for (TileMap::iterator it = m_tiles.begin(); it != end; ++it) {
+        RefPtr<TiledDrawingAreaTile>& current = it->second;
+        if (current->isReadyToPaint() && (current->isDirty() || current->hasBackBufferUpdatePending()))
+            return;
+        if (current->hasReadyBackBuffer())
+            tilesToFlip.append(current.get());
+    }
+    // Everything done, move back buffers to front.
+    Vector<IntRect> paintedArea;
+    unsigned size = tilesToFlip.size();
+    for (unsigned n = 0; n < size; ++n) {
+        TiledDrawingAreaTile* tile = tilesToFlip[n];
+        tile->swapBackBufferToFront();
+        // FIXME: should not request system repaint for the full tile.
+        paintedArea.append(mapToContents(tile->rect()));
+    }
+    if (size)
+        updateWebView(paintedArea);
+
+    m_tileCreationTimer.startOneShot(0);
+}
+
+void TiledDrawingAreaProxy::paint(const IntRect& rect, PlatformDrawingContext context)
+{
+    if (m_isWaitingForDidSetFrameNotification) {
+        WebPageProxy* page = this->page();
+        if (!page->isValid())
+            return;
+
+        if (page->process()->isLaunching())
+            return;
+    }
+
+    adjustVisibleRect();
+
+    GraphicsContext gc(context);
+    gc.save();
+
+    // Assumes the backing store is painted with the scale transform applied.
+    // Since tile content is already scaled, first revert the scaling from the painter.
+    gc.scale(FloatSize(1 / m_contentsScale, 1 / m_contentsScale));
+
+    IntRect dirtyRect = mapFromContents(rect);
+
+    TiledDrawingAreaTile::Coordinate topLeft = tileCoordinateForPoint(dirtyRect.topLeft());
+    TiledDrawingAreaTile::Coordinate bottomRight = tileCoordinateForPoint(dirtyRect.bottomRight());
+
+    for (unsigned yCoordinate = topLeft.y(); yCoordinate <= bottomRight.y(); ++yCoordinate) {
+        for (unsigned xCoordinate = topLeft.x(); xCoordinate <= bottomRight.x(); ++xCoordinate) {
+            TiledDrawingAreaTile::Coordinate currentCoordinate(xCoordinate, yCoordinate);
+            RefPtr<TiledDrawingAreaTile> currentTile = tileAt(currentCoordinate);
+            if (currentTile && currentTile->isReadyToPaint())
+                currentTile->paint(&gc, dirtyRect);
+            else {
+                IntRect tileRect = tileRectForCoordinate(currentCoordinate);
+                IntRect target = intersection(tileRect, dirtyRect);
+                if (target.isEmpty())
+                    continue;
+                TiledDrawingAreaTile::paintCheckerPattern(&gc, FloatRect(target));
+            }
+        }
+    }
+    gc.restore();
+}
+
+void TiledDrawingAreaProxy::adjustVisibleRect()
+{
+    IntRect visibleRect = mapFromContents(webViewVisibleRect());
+    if (m_previousVisibleRect == visibleRect)
+        return;
+    m_previousVisibleRect = visibleRect;
+
+    startTileCreationTimer();
+}
+
+void TiledDrawingAreaProxy::setContentsScale(float scale)
+{
+    if (m_contentsScale == scale)
+        return;
+    m_contentsScale = scale;
+    removeAllTiles();
+    createTiles();
+}
+
+void TiledDrawingAreaProxy::removeAllTiles()
+{
+    Vector<RefPtr<TiledDrawingAreaTile> > tilesToRemove;
+    copyValuesToVector(m_tiles, tilesToRemove);
+    unsigned removeCount = tilesToRemove.size();
+    for (unsigned n = 0; n < removeCount; ++n)
+        removeTile(tilesToRemove[n]->coordinate());
+}
+
+double TiledDrawingAreaProxy::tileDistance(const IntRect& viewport, const TiledDrawingAreaTile::Coordinate& tileCoordinate)
+{
+    if (viewport.intersects(tileRectForCoordinate(tileCoordinate)))
+        return 0;
+
+    IntPoint viewCenter = viewport.location() + IntSize(viewport.width() / 2, viewport.height() / 2);
+    TiledDrawingAreaTile::Coordinate centerCoordinate = tileCoordinateForPoint(viewCenter);
+
+    // Manhattan distance, biased so that vertical distances are shorter.
+    const double horizontalBias = 1.3;
+    return abs(centerCoordinate.y() - tileCoordinate.y()) + horizontalBias * abs(centerCoordinate.x() - tileCoordinate.x());
+}
+
+IntRect TiledDrawingAreaProxy::calculateKeepRect(const IntRect& visibleRect) const
+{
+    IntRect result = visibleRect;
+    result.inflateX(visibleRect.width() * (m_keepAreaMultiplier.width() - 1));
+    result.inflateY(visibleRect.height() * (m_keepAreaMultiplier.height() - 1));
+    result.intersect(contentsRect());
+    return result;
+}
+
+IntRect TiledDrawingAreaProxy::calculateCoverRect(const IntRect& visibleRect) const
+{
+    IntRect result = visibleRect;
+    result.inflateX(visibleRect.width() * (m_coverAreaMultiplier.width() - 1));
+    result.inflateY(visibleRect.height() * (m_coverAreaMultiplier.height() - 1));
+    result.intersect(contentsRect());
+    return result;
+}
+
+void TiledDrawingAreaProxy::createTiles()
+{
+    IntRect visibleRect = mapFromContents(webViewVisibleRect());
+    m_previousVisibleRect = visibleRect;
+
+    if (visibleRect.isEmpty())
+        return;
+
+    // Resize tiles on edges in case the contents size has changed.
+    bool didResizeTiles = resizeEdgeTiles();
+
+    // Remove tiles outside out current maximum keep rect.
+    dropTilesOutsideRect(calculateKeepRect(visibleRect));
+
+    // Cover the cover rect with tiles.
+    IntRect coverRect = calculateCoverRect(visibleRect);
+
+    // Search for the tile position closest to the viewport center that does not yet contain a tile.
+    // Which position is considered the closest depends on the tileDistance function.
+    double shortestDistance = std::numeric_limits<double>::infinity();
+    Vector<TiledDrawingAreaTile::Coordinate> tilesToCreate;
+    unsigned requiredTileCount = 0;
+    bool hasVisibleCheckers = false;
+    TiledDrawingAreaTile::Coordinate topLeft = tileCoordinateForPoint(coverRect.topLeft());
+    TiledDrawingAreaTile::Coordinate bottomRight = tileCoordinateForPoint(coverRect.bottomRight());
+    for (unsigned yCoordinate = topLeft.y(); yCoordinate <= bottomRight.y(); ++yCoordinate) {
+        for (unsigned xCoordinate = topLeft.x(); xCoordinate <= bottomRight.x(); ++xCoordinate) {
+            TiledDrawingAreaTile::Coordinate currentCoordinate(xCoordinate, yCoordinate);
+            // Distance is 0 for all currently visible tiles.
+            double distance = tileDistance(visibleRect, currentCoordinate);
+
+            RefPtr<TiledDrawingAreaTile> tile = tileAt(currentCoordinate);
+            if (!distance && (!tile || !tile->isReadyToPaint()))
+                hasVisibleCheckers = true;
+            if (tile)
+                continue;
+
+            ++requiredTileCount;
+
+            if (distance > shortestDistance)
+                continue;
+            if (distance < shortestDistance) {
+                tilesToCreate.clear();
+                shortestDistance = distance;
+            }
+            tilesToCreate.append(currentCoordinate);
+        }
+    }
+
+    if (hasVisibleCheckers && shortestDistance > 0)
+        return;
+
+    // Now construct the tile(s).
+    unsigned tilesToCreateCount = tilesToCreate.size();
+    for (unsigned n = 0; n < tilesToCreateCount; ++n)
+        createTile(tilesToCreate[n]);
+
+    requiredTileCount -= tilesToCreateCount;
+
+    // Paint the content of the newly created tiles.
+    if (tilesToCreateCount || didResizeTiles)
+        updateTileBuffers();
+
+    // Keep creating tiles until the whole coverRect is covered.
+    if (requiredTileCount)
+        m_tileCreationTimer.startOneShot(m_tileCreationDelay);
+}
+
+bool TiledDrawingAreaProxy::resizeEdgeTiles()
+{
+    IntRect contentsRect = this->contentsRect();
+    bool wasResized = false;
+
+    Vector<TiledDrawingAreaTile::Coordinate> tilesToRemove;
+    TileMap::iterator end = m_tiles.end();
+    for (TileMap::iterator it = m_tiles.begin(); it != end; ++it) {
+        TiledDrawingAreaTile::Coordinate tileCoordinate = it->second->coordinate();
+        IntRect tileRect = it->second->rect();
+        IntRect expectedTileRect = tileRectForCoordinate(tileCoordinate);
+        if (!contentsRect.contains(tileRect))
+            tilesToRemove.append(tileCoordinate);
+        else if (expectedTileRect != tileRect) {
+            it->second->resize(expectedTileRect.size());
+            wasResized = true;
+        }
+    }
+    unsigned removeCount = tilesToRemove.size();
+    for (unsigned n = 0; n < removeCount; ++n)
+        removeTile(tilesToRemove[n]);
+    return wasResized;
+}
+
+void TiledDrawingAreaProxy::dropTilesOutsideRect(const IntRect& keepRect)
+{
+    FloatRect keepRectF = keepRect;
+
+    Vector<TiledDrawingAreaTile::Coordinate> toRemove;
+    TileMap::iterator end = m_tiles.end();
+    for (TileMap::iterator it = m_tiles.begin(); it != end; ++it) {
+        TiledDrawingAreaTile::Coordinate coordinate = it->second->coordinate();
+        FloatRect tileRect = it->second->rect();
+        if (!tileRect.intersects(keepRectF))
+            toRemove.append(coordinate);
+    }
+    unsigned removeCount = toRemove.size();
+    for (unsigned n = 0; n < removeCount; ++n)
+        removeTile(toRemove[n]);
+}
+
+PassRefPtr<TiledDrawingAreaTile> TiledDrawingAreaProxy::tileAt(const TiledDrawingAreaTile::Coordinate& coordinate) const
+{
+    return m_tiles.get(coordinate);
+}
+
+void TiledDrawingAreaProxy::setTile(const TiledDrawingAreaTile::Coordinate& coordinate, RefPtr<TiledDrawingAreaTile> tile)
+{
+    m_tiles.set(coordinate, tile);
+    m_tilesByID.set(tile->ID(), tile.get());
+}
+
+void TiledDrawingAreaProxy::removeTile(const TiledDrawingAreaTile::Coordinate& coordinate)
+{
+    RefPtr<TiledDrawingAreaTile> tile = m_tiles.take(coordinate);
+
+    m_tilesByID.remove(tile->ID());
+
+    if (!tile->hasBackBufferUpdatePending())
+        return;
+    WebPageProxy* page = this->page();
+    page->process()->send(DrawingAreaMessage::CancelTileUpdate, page->pageID(), CoreIPC::In(tile->ID()));
+}
+
+IntRect TiledDrawingAreaProxy::mapToContents(const IntRect& rect) const
+{
+    return enclosingIntRect(FloatRect(rect.x() / m_contentsScale,
+                                      rect.y() / m_contentsScale,
+                                      rect.width() / m_contentsScale,
+                                      rect.height() / m_contentsScale));
+}
+
+IntRect TiledDrawingAreaProxy::mapFromContents(const IntRect& rect) const
+{
+    return enclosingIntRect(FloatRect(rect.x() * m_contentsScale,
+                                      rect.y() * m_contentsScale,
+                                      rect.width() * m_contentsScale,
+                                      rect.height() * m_contentsScale));
+}
+
+IntRect TiledDrawingAreaProxy::contentsRect() const
+{
+    return mapFromContents(IntRect(IntPoint(0, 0), m_viewSize));
+}
+
+IntRect TiledDrawingAreaProxy::tileRectForCoordinate(const TiledDrawingAreaTile::Coordinate& coordinate) const
+{
+    IntRect rect(coordinate.x() * m_tileSize.width(),
+                 coordinate.y() * m_tileSize.height(),
+                 m_tileSize.width(),
+                 m_tileSize.height());
+
+    rect.intersect(contentsRect());
+    return rect;
+}
+
+TiledDrawingAreaTile::Coordinate TiledDrawingAreaProxy::tileCoordinateForPoint(const IntPoint& point) const
+{
+    int x = point.x() / m_tileSize.width();
+    int y = point.y() / m_tileSize.height();
+    return TiledDrawingAreaTile::Coordinate(std::max(x, 0), std::max(y, 0));
+}
+
+
+void TiledDrawingAreaProxy::startTileBufferUpdateTimer()
+{
+    if (m_tileBufferUpdateTimer.isActive())
+        return;
+    m_tileBufferUpdateTimer.startOneShot(0);
+}
+
+void TiledDrawingAreaProxy::tileBufferUpdateTimerFired()
+{
+    updateTileBuffers();
+}
+
+void TiledDrawingAreaProxy::startTileCreationTimer()
+{
+    if (m_tileCreationTimer.isActive())
+        return;
+    m_tileCreationTimer.startOneShot(0);
+}
+
+void TiledDrawingAreaProxy::tileCreationTimerFired()
+{
+    createTiles();
+}
+
+bool TiledDrawingAreaProxy::hasPendingUpdates() const
+{
+    TileMap::const_iterator end = m_tiles.end();
+    for (TileMap::const_iterator it = m_tiles.begin(); it != end; ++it) {
+        const RefPtr<TiledDrawingAreaTile>& current = it->second;
+        if (current->hasBackBufferUpdatePending())
+            return true;
+    }
+    return false;
+}
+
+} // namespace WebKit
+
diff --git a/WebKit2/UIProcess/TiledDrawingAreaProxy.h b/WebKit2/UIProcess/TiledDrawingAreaProxy.h
new file mode 100644
index 0000000..7aa26d4
--- /dev/null
+++ b/WebKit2/UIProcess/TiledDrawingAreaProxy.h
@@ -0,0 +1,185 @@
+/*
+ * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef TiledDrawingAreaProxy_h
+#define TiledDrawingAreaProxy_h
+
+#if ENABLE(TILED_BACKING_STORE)
+
+#include "DrawingAreaProxy.h"
+#include <WebCore/GraphicsContext.h>
+#include <WebCore/IntSize.h>
+#include <WebCore/IntRect.h>
+#include <wtf/HashSet.h>
+
+#include "RunLoop.h"
+#include "TiledDrawingAreaTile.h"
+
+#if PLATFORM(MAC)
+#include <wtf/RetainPtr.h>
+#ifdef __OBJC__
+ at class WKView;
+#else
+class WKView;
+#endif
+#elif PLATFORM(QT)
+class QGraphicsWKView;
+#include <QImage>
+#endif
+
+namespace WebKit {
+
+class UpdateChunk;
+class WebPageProxy;
+
+#if PLATFORM(MAC)
+typedef WKView PlatformWebView;
+#elif PLATFORM(WIN)
+class WebView;
+typedef WebView PlatformWebView;
+#elif PLATFORM(QT)
+typedef QGraphicsWKView PlatformWebView;
+#endif
+
+class TiledDrawingAreaProxy : public DrawingAreaProxy {
+public:
+    static PassOwnPtr<TiledDrawingAreaProxy> create(PlatformWebView* webView);
+
+    TiledDrawingAreaProxy(PlatformWebView*);
+    virtual ~TiledDrawingAreaProxy();
+
+    float contentsScale() const { return m_contentsScale; }
+    void setContentsScale(float);
+
+    void waitUntilUpdatesComplete();
+
+#if USE(ACCELERATED_COMPOSITING)
+    virtual void attachCompositingContext(uint32_t /* contextID */) { }
+    virtual void detachCompositingContext() { }
+#endif
+
+    void paint(WebCore::GraphicsContext*, const WebCore::IntRect&);
+
+    WebCore::IntSize tileSize() { return m_tileSize; }
+    void setTileSize(const WebCore::IntSize&);
+
+    double tileCreationDelay() const { return m_tileCreationDelay; }
+    void setTileCreationDelay(double delay);
+
+    // Tiled are dropped outside the keep area, and created for cover area. The values a relative to the viewport size.
+    void getKeepAndCoverAreaMultipliers(WebCore::FloatSize& keepMultiplier, WebCore::FloatSize& coverMultiplier)
+    {
+        keepMultiplier = m_keepAreaMultiplier;
+        coverMultiplier = m_coverAreaMultiplier;
+    }
+    void setKeepAndCoverAreaMultipliers(const WebCore::FloatSize& keepMultiplier, const WebCore::FloatSize& coverMultiplier);
+
+    void tileBufferUpdateComplete();
+
+    WebCore::IntRect mapToContents(const WebCore::IntRect&) const;
+    WebCore::IntRect mapFromContents(const WebCore::IntRect&) const;
+
+    bool hasPendingUpdates() const;
+
+private:
+    WebPageProxy* page();
+    WebCore::IntRect webViewVisibleRect();
+    void updateWebView(const Vector<WebCore::IntRect>& paintedArea);
+
+    // DrawingAreaProxy
+    virtual void didReceiveMessage(CoreIPC::Connection*, CoreIPC::MessageID, CoreIPC::ArgumentDecoder*);
+    virtual void didReceiveSyncMessage(CoreIPC::Connection*, CoreIPC::MessageID, CoreIPC::ArgumentDecoder*, CoreIPC::ArgumentEncoder&);
+    virtual void paint(const WebCore::IntRect&, PlatformDrawingContext);
+    virtual void setSize(const WebCore::IntSize&);
+    virtual void setPageIsVisible(bool isVisible);
+
+    void didSetSize(const WebCore::IntSize&);
+    void invalidate(const WebCore::IntRect& rect);
+    void adjustVisibleRect();
+
+    void requestTileUpdate(int tileID, const WebCore::IntRect& dirtyRect);
+
+    PassRefPtr<TiledDrawingAreaTile> createTile(const TiledDrawingAreaTile::Coordinate&);
+
+    void startTileBufferUpdateTimer();
+    void startTileCreationTimer();
+
+    void tileBufferUpdateTimerFired();
+    void tileCreationTimerFired();
+
+    void updateTileBuffers();
+    void createTiles();
+
+    bool resizeEdgeTiles();
+    void dropTilesOutsideRect(const WebCore::IntRect&);
+
+    PassRefPtr<TiledDrawingAreaTile> tileAt(const TiledDrawingAreaTile::Coordinate&) const;
+    void setTile(const TiledDrawingAreaTile::Coordinate& coordinate, RefPtr<TiledDrawingAreaTile> tile);
+    void removeTile(const TiledDrawingAreaTile::Coordinate& coordinate);
+    void removeAllTiles();
+
+    WebCore::IntRect contentsRect() const;
+
+    WebCore::IntRect calculateKeepRect(const WebCore::IntRect& visibleRect) const;
+    WebCore::IntRect calculateCoverRect(const WebCore::IntRect& visibleRect) const;
+
+    WebCore::IntRect tileRectForCoordinate(const TiledDrawingAreaTile::Coordinate&) const;
+    TiledDrawingAreaTile::Coordinate tileCoordinateForPoint(const WebCore::IntPoint&) const;
+    double tileDistance(const WebCore::IntRect& viewport, const TiledDrawingAreaTile::Coordinate&);
+
+private:
+    bool m_isWaitingForDidSetFrameNotification;
+    bool m_isVisible;
+
+    WebCore::IntSize m_viewSize; // Size of the BackingStore as well.
+    WebCore::IntSize m_lastSetViewSize;
+
+    PlatformWebView* m_webView;
+
+    typedef HashMap<TiledDrawingAreaTile::Coordinate, RefPtr<TiledDrawingAreaTile> > TileMap;
+    TileMap m_tiles;
+
+    WTF::HashMap<int, TiledDrawingAreaTile*> m_tilesByID;
+
+    typedef RunLoop::Timer<TiledDrawingAreaProxy> TileTimer;
+    TileTimer m_tileBufferUpdateTimer;
+    TileTimer m_tileCreationTimer;
+
+    WebCore::IntSize m_tileSize;
+    double m_tileCreationDelay;
+    WebCore::FloatSize m_keepAreaMultiplier;
+    WebCore::FloatSize m_coverAreaMultiplier;
+
+    WebCore::IntRect m_previousVisibleRect;
+    float m_contentsScale;
+
+    friend class TiledDrawingAreaTile;
+};
+
+} // namespace WebKit
+
+#endif // TILED_BACKING_STORE
+
+#endif // TiledDrawingAreaProxy_h
diff --git a/WebKit2/UIProcess/TiledDrawingAreaTile.h b/WebKit2/UIProcess/TiledDrawingAreaTile.h
new file mode 100644
index 0000000..0201461
--- /dev/null
+++ b/WebKit2/UIProcess/TiledDrawingAreaTile.h
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef TiledDrawingAreaTile_h
+#define TiledDrawingAreaTile_h
+
+#include "IntPoint.h"
+#include "IntPointHash.h"
+#include "IntRect.h"
+#include "GraphicsContext.h"
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefCounted.h>
+
+#if PLATFORM(QT)
+#include <QPixmap>
+#include <QRegion>
+#endif
+
+namespace WebKit {
+
+class TiledDrawingAreaProxy;
+class UpdateChunk;
+
+class TiledDrawingAreaTile : public RefCounted<TiledDrawingAreaTile> {
+public:
+    typedef WebCore::IntPoint Coordinate;
+
+    static PassRefPtr<TiledDrawingAreaTile> create(TiledDrawingAreaProxy* proxy, const Coordinate& tileCoordinate) { return adoptRef(new TiledDrawingAreaTile(proxy, tileCoordinate)); }
+    ~TiledDrawingAreaTile();
+
+    bool isDirty() const;
+    void invalidate(const WebCore::IntRect&);
+    void updateBackBuffer();
+    bool hasReadyBackBuffer() const;
+    void swapBackBufferToFront();
+    bool isReadyToPaint() const;
+    void paint(WebCore::GraphicsContext*, const WebCore::IntRect&);
+    bool hasBackBufferUpdatePending() const { return m_hasUpdatePending; }
+
+    const TiledDrawingAreaTile::Coordinate& coordinate() const { return m_coordinate; }
+    const WebCore::IntRect& rect() const { return m_rect; }
+    void resize(const WebCore::IntSize&);
+
+    void updateFromChunk(UpdateChunk* updateChunk, float);
+
+    static void paintCheckerPattern(WebCore::GraphicsContext*, const WebCore::FloatRect&);
+
+    int ID() const { return m_ID; }
+
+private:
+    TiledDrawingAreaTile(TiledDrawingAreaProxy* proxy, const TiledDrawingAreaTile::Coordinate& tileCoordinate);
+
+    TiledDrawingAreaProxy* m_proxy;
+    Coordinate m_coordinate;
+    WebCore::IntRect m_rect;
+
+    int m_ID;
+    bool m_hasUpdatePending;
+
+#if PLATFORM(QT)
+    QPixmap m_buffer;
+    QPixmap m_backBuffer;
+    QRegion m_dirtyRegion;
+#endif
+};
+
+}
+
+#endif
diff --git a/WebKit2/UIProcess/qt/TiledDrawingAreaProxyQt.cpp b/WebKit2/UIProcess/qt/TiledDrawingAreaProxyQt.cpp
new file mode 100644
index 0000000..f9471c0
--- /dev/null
+++ b/WebKit2/UIProcess/qt/TiledDrawingAreaProxyQt.cpp
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "TiledDrawingAreaProxy.h"
+
+#include "DrawingAreaMessageKinds.h"
+#include "DrawingAreaProxyMessageKinds.h"
+#include "UpdateChunk.h"
+#include "WKAPICast.h"
+#include "WebPageProxy.h"
+
+#include "qgraphicswkview.h"
+
+using namespace WebCore;
+
+#define TILE_DEBUG_LOG
+
+namespace WebKit {
+
+void TiledDrawingAreaProxy::updateWebView(const Vector<IntRect>& paintedArea)
+{
+    if (!page() || !page()->isValid())
+        return;
+
+    unsigned size = paintedArea.size();
+    for (unsigned n = 0; n < size; ++n)
+        m_webView->update(QRect(paintedArea[n]));
+}
+
+IntRect TiledDrawingAreaProxy::webViewVisibleRect()
+{
+    return enclosingIntRect(FloatRect(m_webView->visibleRect()));
+}
+
+WebPageProxy* TiledDrawingAreaProxy::page()
+{
+    return toImpl(m_webView->page()->pageRef());
+}
+
+} // namespace WebKit
diff --git a/WebKit2/UIProcess/qt/TiledDrawingAreaTileQt.cpp b/WebKit2/UIProcess/qt/TiledDrawingAreaTileQt.cpp
new file mode 100644
index 0000000..f4ca678
--- /dev/null
+++ b/WebKit2/UIProcess/qt/TiledDrawingAreaTileQt.cpp
@@ -0,0 +1,204 @@
+/*
+ * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "TiledDrawingAreaTile.h"
+
+#include "GraphicsContext.h"
+#include "TiledDrawingAreaProxy.h"
+#include "WebPageProxy.h"
+#include "WebProcessProxy.h"
+#include "UpdateChunk.h"
+#include <QApplication>
+#include <QObject>
+#include <QPainter>
+
+using namespace WebCore;
+
+namespace WebKit {
+
+static const unsigned checkerSize = 16;
+static const unsigned checkerColor1 = 0xff555555;
+static const unsigned checkerColor2 = 0xffaaaaaa;
+
+static QPixmap& checkeredPixmap()
+{
+    static QPixmap* pixmap;
+    if (!pixmap) {
+        pixmap = new QPixmap(checkerSize, checkerSize);
+        QPainter painter(pixmap);
+        QColor color1(checkerColor1);
+        QColor color2(checkerColor2);
+        for (unsigned y = 0; y < checkerSize; y += checkerSize / 2) {
+            bool alternate = y % checkerSize;
+            for (unsigned x = 0; x < checkerSize; x += checkerSize / 2) {
+                painter.fillRect(x, y, checkerSize / 2, checkerSize / 2, alternate ? color1 : color2);
+                alternate = !alternate;
+            }
+        }
+    }
+    return *pixmap;
+}
+
+TiledDrawingAreaTile::TiledDrawingAreaTile(TiledDrawingAreaProxy* proxy, const Coordinate& tileCoordinate)
+    : m_proxy(proxy)
+    , m_coordinate(tileCoordinate)
+    , m_rect(proxy->tileRectForCoordinate(tileCoordinate))
+    , m_hasUpdatePending(false)
+    , m_dirtyRegion(m_rect)
+{
+    static int id = 0;
+    m_ID = ++id;
+#ifdef TILE_DEBUG_LOG
+    qDebug() << "deleting tile id=" << m_ID;
+#endif
+}
+
+TiledDrawingAreaTile::~TiledDrawingAreaTile()
+{
+#ifdef TILE_DEBUG_LOG
+    qDebug() << "deleting tile id=" << m_ID;
+#endif
+}
+
+bool TiledDrawingAreaTile::isDirty() const
+{
+    return !m_dirtyRegion.isEmpty();
+}
+
+bool TiledDrawingAreaTile::isReadyToPaint() const
+{
+    return !m_buffer.isNull();
+}
+
+bool TiledDrawingAreaTile::hasReadyBackBuffer() const
+{
+    return !m_backBuffer.isNull() && !m_hasUpdatePending;
+}
+
+void TiledDrawingAreaTile::invalidate(const IntRect& dirtyRect)
+{
+    IntRect tileDirtyRect = intersection(dirtyRect, m_rect);
+    if (tileDirtyRect.isEmpty())
+        return;
+
+    m_dirtyRegion += tileDirtyRect;
+}
+
+void TiledDrawingAreaTile::resize(const IntSize& newSize)
+{
+    IntRect oldRect = m_rect;
+    m_rect = IntRect(m_rect.topLeft(), newSize);
+    if (m_rect.right() > oldRect.right())
+        invalidate(IntRect(oldRect.right(), oldRect.y(), m_rect.right() - oldRect.right(), m_rect.height()));
+    if (m_rect.bottom() > oldRect.bottom())
+        invalidate(IntRect(oldRect.x(), oldRect.bottom(), m_rect.width(), m_rect.bottom() - oldRect.bottom()));
+}
+
+void TiledDrawingAreaTile::swapBackBufferToFront()
+{
+    ASSERT(!m_backBuffer.isNull());
+
+    m_buffer = m_backBuffer;
+    m_backBuffer = QPixmap();
+}
+
+void TiledDrawingAreaTile::paint(GraphicsContext* context, const IntRect& rect)
+{
+    ASSERT(!m_buffer.isNull());
+
+    IntRect target = intersection(rect, m_rect);
+    IntRect source((target.x() - m_rect.x()),
+                   (target.y() - m_rect.y()),
+                   target.width(),
+                   target.height());
+
+    context->platformContext()->drawPixmap(target, m_buffer, source);
+}
+
+void TiledDrawingAreaTile::paintCheckerPattern(GraphicsContext* context, const FloatRect& target)
+{
+    QPainter* painter = context->platformContext();
+    QTransform worldTransform = painter->worldTransform();
+    qreal scaleX = worldTransform.m11();
+    qreal scaleY = worldTransform.m22();
+
+    QRect targetViewRect = QRectF(target.x() * scaleX,
+                                  target.y() * scaleY,
+                                  target.width() * scaleX,
+                                  target.height() * scaleY).toAlignedRect();
+
+    QTransform adjustedTransform(1., worldTransform.m12(), worldTransform.m13(),
+                                 worldTransform.m21(), 1., worldTransform.m23(),
+                                 worldTransform.m31(), worldTransform.m32(), worldTransform.m33());
+    painter->setWorldTransform(adjustedTransform);
+
+    painter->drawTiledPixmap(targetViewRect,
+                             checkeredPixmap(),
+                             QPoint(targetViewRect.left() % checkerSize,
+                                    targetViewRect.top() % checkerSize));
+
+    painter->setWorldTransform(worldTransform);
+}
+
+void TiledDrawingAreaTile::updateFromChunk(UpdateChunk* updateChunk, float)
+{
+    QImage image(updateChunk->createImage());
+    const IntRect& updateChunkRect = updateChunk->rect();
+
+#ifdef TILE_DEBUG_LOG
+    qDebug() << "tile updated id=" << ID() << " rect=" << QRect(updateChunkRect);
+#endif
+    if (updateChunkRect.size() == m_proxy->tileSize())
+        m_backBuffer = QPixmap::fromImage(image);
+    else {
+        if (m_backBuffer.isNull())
+            m_backBuffer = m_buffer.isNull() ? QPixmap(m_proxy->tileSize()) : m_buffer;
+        QPainter painter(&m_backBuffer);
+        IntSize drawPoint = updateChunkRect.topLeft() - m_rect.topLeft();
+        painter.drawImage(QPoint(drawPoint.width(), drawPoint.height()), image);
+    }
+    m_hasUpdatePending = false;
+}
+
+void TiledDrawingAreaTile::updateBackBuffer()
+{
+    if (isReadyToPaint() && !isDirty())
+        return;
+
+    // FIXME: individual rects
+    IntRect dirtyRect = m_dirtyRegion.boundingRect();
+    m_dirtyRegion = QRegion();
+
+#ifdef TILE_DEBUG_LOG
+    qDebug() << "requesting tile update id=" << m_ID << " rect=" << QRect(dirtyRect) << " scale=" << m_proxy->contentsScale();
+#endif
+    if (!m_proxy->page()->process()->isValid())
+        return;
+    m_proxy->requestTileUpdate(m_ID, dirtyRect);
+
+    m_hasUpdatePending = true;
+}
+
+}
diff --git a/WebKit2/WebKit2.pro b/WebKit2/WebKit2.pro
index 81c12ad..fca8f06 100644
--- a/WebKit2/WebKit2.pro
+++ b/WebKit2/WebKit2.pro
@@ -284,6 +284,7 @@ HEADERS += \
     UIProcess/Plugins/PluginInfoStore.h \
     UIProcess/ProcessModel.h \
     UIProcess/ResponsivenessTimer.h \
+    UIProcess/TiledDrawingAreaProxy.h \
     UIProcess/VisitedLinkProvider.h \
     UIProcess/WebContext.h \
     UIProcess/WebContextInjectedBundleClient.h \
@@ -454,6 +455,7 @@ SOURCES += \
     UIProcess/Plugins/PluginInfoStore.cpp \
     UIProcess/Plugins/qt/PluginInfoStoreQt.cpp \
     UIProcess/ResponsivenessTimer.cpp \
+    UIProcess/TiledDrawingAreaProxy.cpp \
     UIProcess/VisitedLinkProvider.cpp \
     UIProcess/WebBackForwardList.cpp \
     UIProcess/WebBackForwardListItem.cpp \
@@ -480,6 +482,8 @@ SOURCES += \
     UIProcess/WebProcessProxy.cpp \
     UIProcess/WebUIClient.cpp \
     UIProcess/qt/ChunkedUpdateDrawingAreaProxyQt.cpp \
+    UIProcess/qt/TiledDrawingAreaProxyQt.cpp \
+    UIProcess/qt/TiledDrawingAreaTileQt.cpp \
     UIProcess/qt/WebContextMenuProxyQt.cpp \
     UIProcess/qt/WebContextQt.cpp \
     UIProcess/qt/WebInspectorProxyQt.cpp \
@@ -539,6 +543,7 @@ SOURCES += \
     WebProcess/WebPage/DrawingArea.cpp \
     WebProcess/WebPage/FindController.cpp \
     WebProcess/WebPage/PageOverlay.cpp \
+    WebProcess/WebPage/TiledDrawingArea.cpp \
     WebProcess/WebPage/WebBackForwardListProxy.cpp \
     WebProcess/WebPage/WebContextMenu.cpp \
     WebProcess/WebPage/WebEditCommand.cpp \
@@ -547,6 +552,7 @@ SOURCES += \
     WebProcess/WebPage/qt/WebInspectorQt.cpp \
     WebProcess/WebPage/WebPage.cpp \
     WebProcess/WebPage/qt/ChunkedUpdateDrawingAreaQt.cpp \
+    WebProcess/WebPage/qt/TiledDrawingAreaQt.cpp \
     WebProcess/WebPage/qt/WebPageQt.cpp \
     WebProcess/WebProcess.cpp \
     WebProcess/qt/WebProcessMainQt.cpp \
diff --git a/WebKit2/WebProcess/WebPage/DrawingArea.cpp b/WebKit2/WebProcess/WebPage/DrawingArea.cpp
index 273126b..0f9b6ae 100644
--- a/WebKit2/WebProcess/WebPage/DrawingArea.cpp
+++ b/WebKit2/WebProcess/WebPage/DrawingArea.cpp
@@ -31,6 +31,10 @@
 #include "LayerBackedDrawingArea.h"
 #endif
 
+#if ENABLE(TILED_BACKING_STORE)
+#include "TiledDrawingArea.h"
+#endif
+
 namespace WebKit {
 
 PassRefPtr<DrawingArea> DrawingArea::create(Type type, DrawingAreaID identifier, WebPage* webPage)
@@ -47,6 +51,10 @@ PassRefPtr<DrawingArea> DrawingArea::create(Type type, DrawingAreaID identifier,
         case LayerBackedDrawingAreaType:
             return adoptRef(new LayerBackedDrawingArea(identifier, webPage));
 #endif
+#if ENABLE(TILED_BACKING_STORE)
+        case TiledDrawingAreaType:
+            return adoptRef(new TiledDrawingArea(identifier, webPage));
+#endif
     }
 
     return 0;
diff --git a/WebKit2/WebProcess/WebPage/TiledDrawingArea.cpp b/WebKit2/WebProcess/WebPage/TiledDrawingArea.cpp
new file mode 100644
index 0000000..87af668
--- /dev/null
+++ b/WebKit2/WebProcess/WebPage/TiledDrawingArea.cpp
@@ -0,0 +1,230 @@
+/*
+ * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#if ENABLE(TILED_BACKING_STORE)
+
+#include "TiledDrawingArea.h"
+
+#include "DrawingAreaMessageKinds.h"
+#include "DrawingAreaProxyMessageKinds.h"
+#include "MessageID.h"
+#include "UpdateChunk.h"
+#include "WebCore/Frame.h"
+#include "WebCore/FrameView.h"
+#include "WebCoreArgumentCoders.h"
+#include "WebFrame.h"
+#include "WebPage.h"
+#include "WebProcess.h"
+
+using namespace WebCore;
+
+namespace WebKit {
+
+TiledDrawingArea::TiledDrawingArea(DrawingAreaID identifier, WebPage* webPage)
+    : DrawingArea(TiledDrawingAreaType, identifier, webPage)
+    , m_isWaitingForUpdate(false)
+    , m_shouldPaint(true)
+    , m_displayTimer(WebProcess::shared().runLoop(), this, &TiledDrawingArea::display)
+    , m_tileUpdateTimer(WebProcess::shared().runLoop(), this, &TiledDrawingArea::tileUpdateTimerFired)
+{
+}
+
+TiledDrawingArea::~TiledDrawingArea()
+{
+}
+
+void TiledDrawingArea::invalidateWindow(const IntRect& rect, bool immediate)
+{
+}
+
+void TiledDrawingArea::invalidateContentsAndWindow(const IntRect& rect, bool immediate)
+{
+    setNeedsDisplay(rect);
+}
+
+void TiledDrawingArea::invalidateContentsForSlowScroll(const IntRect& rect, bool immediate)
+{
+    setNeedsDisplay(rect);
+}
+
+void TiledDrawingArea::scroll(const IntSize& scrollDelta, const IntRect& rectToScroll, const IntRect& clipRect)
+{
+    // FIXME: Do something much smarter.
+    setNeedsDisplay(rectToScroll);
+}
+
+void TiledDrawingArea::setNeedsDisplay(const IntRect& rect)
+{
+    // FIXME: Collect a set of rects/region instead of just the union of all rects.
+    m_dirtyRect.unite(rect);
+    scheduleDisplay();
+}
+
+void TiledDrawingArea::display()
+{
+    if (!m_shouldPaint)
+        return;
+
+    if (m_dirtyRect.isEmpty())
+        return;
+
+    m_webPage->layoutIfNeeded();
+
+    IntRect dirtyRect = m_dirtyRect;
+    m_dirtyRect = IntRect();
+
+    WebProcess::shared().connection()->send(DrawingAreaProxyMessage::Invalidate, m_webPage->pageID(), CoreIPC::In(dirtyRect));
+
+    m_displayTimer.stop();
+}
+
+void TiledDrawingArea::scheduleDisplay()
+{
+    if (!m_shouldPaint)
+        return;
+
+    if (m_displayTimer.isActive())
+        return;
+
+    m_displayTimer.startOneShot(0);
+}
+
+void TiledDrawingArea::setSize(const IntSize& viewSize)
+{
+    ASSERT(m_shouldPaint);
+    ASSERT_ARG(viewSize, !viewSize.isEmpty());
+
+    m_webPage->setSize(viewSize);
+
+    scheduleDisplay();
+
+    WebProcess::shared().connection()->send(DrawingAreaProxyMessage::DidSetSize, m_webPage->pageID(), CoreIPC::In(viewSize));
+}
+
+void TiledDrawingArea::suspendPainting()
+{
+    ASSERT(m_shouldPaint);
+
+    m_shouldPaint = false;
+    m_displayTimer.stop();
+}
+
+void TiledDrawingArea::resumePainting()
+{
+    ASSERT(!m_shouldPaint);
+
+    m_shouldPaint = true;
+
+    // Display if needed.
+    display();
+}
+
+void TiledDrawingArea::didUpdate()
+{
+    // Display if needed.
+    display();
+}
+
+void TiledDrawingArea::updateTile(int tileID, const IntRect& dirtyRect, float scale)
+{
+    m_webPage->layoutIfNeeded();
+
+    UpdateChunk updateChunk(dirtyRect);
+    paintIntoUpdateChunk(&updateChunk, scale);
+
+    unsigned pendingUpdateCount = m_pendingUpdates.size();
+    WebProcess::shared().connection()->send(DrawingAreaProxyMessage::TileUpdated, m_webPage->pageID(), CoreIPC::In(tileID, updateChunk, scale, pendingUpdateCount));
+}
+
+void TiledDrawingArea::tileUpdateTimerFired()
+{
+    ASSERT(!m_pendingUpdates.isEmpty());
+
+    UpdateMap::iterator it = m_pendingUpdates.begin();
+    TileUpdate update = it->second;
+    m_pendingUpdates.remove(it);
+
+    updateTile(update.tileID, update.dirtyRect, update.scale);
+
+    if (m_pendingUpdates.isEmpty())
+        WebProcess::shared().connection()->send(DrawingAreaProxyMessage::AllTileUpdatesProcessed, m_webPage->pageID(), CoreIPC::In());
+    else
+        m_tileUpdateTimer.startOneShot(0.001);
+}
+
+void TiledDrawingArea::didReceiveMessage(CoreIPC::Connection*, CoreIPC::MessageID messageID, CoreIPC::ArgumentDecoder* arguments)
+{
+    switch (messageID.get<DrawingAreaMessage::Kind>()) {
+    case DrawingAreaMessage::SetSize: {
+        IntSize size;
+        if (!arguments->decode(CoreIPC::Out(size)))
+            return;
+
+        setSize(size);
+        break;
+    }
+    case DrawingAreaMessage::SuspendPainting:
+        suspendPainting();
+        break;
+    case DrawingAreaMessage::ResumePainting:
+        resumePainting();
+        break;
+    case DrawingAreaMessage::CancelTileUpdate: {
+        int tileID;
+        if (!arguments->decode(CoreIPC::Out(tileID)))
+            return;
+        UpdateMap::iterator it = m_pendingUpdates.find(tileID);
+        if (it != m_pendingUpdates.end()) {
+            m_pendingUpdates.remove(it);
+            if (m_pendingUpdates.isEmpty()) {
+                WebProcess::shared().connection()->send(DrawingAreaProxyMessage::AllTileUpdatesProcessed, m_webPage->pageID(), CoreIPC::In());
+                m_tileUpdateTimer.stop();
+            }
+        }
+        break;
+    }
+    case DrawingAreaMessage::RequestTileUpdate: {
+        TileUpdate update;
+        if (!arguments->decode(CoreIPC::Out(update.tileID, update.dirtyRect, update.scale)))
+            return;
+        UpdateMap::iterator it = m_pendingUpdates.find(update.tileID);
+        if (it != m_pendingUpdates.end())
+            it->second.dirtyRect.unite(update.dirtyRect);
+        else {
+            m_pendingUpdates.add(update.tileID, update);
+            if (!m_tileUpdateTimer.isActive())
+                m_tileUpdateTimer.startOneShot(0);
+        }
+        break;
+    }
+    default:
+        ASSERT_NOT_REACHED();
+        break;
+    }
+}
+
+} // namespace WebKit
+
+#endif // TILED_BACKING_STORE
diff --git a/WebKit2/WebProcess/WebPage/TiledDrawingArea.h b/WebKit2/WebProcess/WebPage/TiledDrawingArea.h
new file mode 100644
index 0000000..ce20b65
--- /dev/null
+++ b/WebKit2/WebProcess/WebPage/TiledDrawingArea.h
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef TiledDrawingArea_h
+#define TiledDrawingArea_h
+
+#if ENABLE(TILED_BACKING_STORE)
+
+#include "DrawingArea.h"
+#include "RunLoop.h"
+#include <WebCore/IntPoint.h>
+#include <WebCore/IntRect.h>
+#include <wtf/Vector.h>
+
+namespace WebKit {
+
+class UpdateChunk;
+
+class TiledDrawingArea : public DrawingArea {
+public:
+    TiledDrawingArea(DrawingAreaID identifier, WebPage*);
+    virtual ~TiledDrawingArea();
+
+    virtual void invalidateWindow(const WebCore::IntRect& rect, bool immediate);
+    virtual void invalidateContentsAndWindow(const WebCore::IntRect& rect, bool immediate);
+    virtual void invalidateContentsForSlowScroll(const WebCore::IntRect& rect, bool immediate);
+    virtual void scroll(const WebCore::IntSize& scrollDelta, const WebCore::IntRect& rectToScroll, const WebCore::IntRect& clipRect);
+    virtual void setNeedsDisplay(const WebCore::IntRect&);
+    virtual void display();
+
+#if USE(ACCELERATED_COMPOSITING)
+    virtual void attachCompositingContext() { }
+    virtual void detachCompositingContext() { }
+    virtual void setRootCompositingLayer(WebCore::GraphicsLayer*) { }
+    virtual void scheduleCompositingLayerSync() { }
+    virtual void syncCompositingLayers() { }
+#endif
+
+    virtual void didReceiveMessage(CoreIPC::Connection*, CoreIPC::MessageID, CoreIPC::ArgumentDecoder*);
+
+private:
+    void scheduleDisplay();
+
+    // CoreIPC message handlers.
+    void setSize(const WebCore::IntSize& viewSize);
+    void suspendPainting();
+    void resumePainting();
+    void didUpdate();
+    void updateTile(int tileID, const WebCore::IntRect& dirtyRect, float scale);
+
+    // Platform overrides
+    void paintIntoUpdateChunk(UpdateChunk*, float scale);
+
+    void tileUpdateTimerFired();
+
+    WebCore::IntRect m_dirtyRect;
+    bool m_isWaitingForUpdate;
+    bool m_shouldPaint;
+    RunLoop::Timer<TiledDrawingArea> m_displayTimer;
+
+    struct TileUpdate {
+        int tileID;
+        WebCore::IntRect dirtyRect;
+        float scale;
+    };
+    typedef HashMap<int, TileUpdate> UpdateMap;
+    UpdateMap m_pendingUpdates;
+    RunLoop::Timer<TiledDrawingArea> m_tileUpdateTimer;
+};
+
+} // namespace WebKit
+
+#endif // TILED_BACKING_STORE
+
+#endif // TiledDrawingArea_h
diff --git a/WebKit2/WebProcess/WebPage/qt/TiledDrawingAreaQt.cpp b/WebKit2/WebProcess/WebPage/qt/TiledDrawingAreaQt.cpp
new file mode 100644
index 0000000..b7ad782
--- /dev/null
+++ b/WebKit2/WebProcess/WebPage/qt/TiledDrawingAreaQt.cpp
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#if ENABLE(TILED_BACKING_STORE)
+
+#include "TiledDrawingArea.h"
+
+#include "UpdateChunk.h"
+#include "WebPage.h"
+#include <WebCore/GraphicsContext.h>
+
+#include <QImage>
+#include <QPainter>
+
+using namespace WebCore;
+
+namespace WebKit {
+
+void TiledDrawingArea::paintIntoUpdateChunk(UpdateChunk* updateChunk, float scale)
+{
+    IntRect tileRect = updateChunk->rect();
+    QImage image(updateChunk->createImage());
+    QPainter painter(&image);
+    // Now paint into the backing store.
+    GraphicsContext graphicsContext(&painter);
+    graphicsContext.translate(-tileRect.x(), -tileRect.y());
+    graphicsContext.scale(FloatSize(scale, scale));
+    IntRect contentRect = enclosingIntRect(FloatRect(tileRect.x() / scale,
+                                                     tileRect.y() / scale,
+                                                     tileRect.width() / scale,
+                                                     tileRect.height() / scale));
+    m_webPage->drawRect(graphicsContext, contentRect);
+}
+
+} // namespace WebKit
+
+#endif // TILED_BACKING_STORE

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list