[SCM] WebKit Debian packaging branch, debian/experimental, updated. debian/1.3.8-1-1049-g2e11a8e

enne at google.com enne at google.com
Fri Jan 21 14:38:20 UTC 2011


The following commit has been merged in the debian/experimental branch:
commit da8e8a95e6ccceb1c898225dc3122618f9c9d3fd
Author: enne at google.com <enne at google.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Thu Dec 23 19:16:59 2010 +0000

    2010-12-20  Adrienne Walker  <enne at google.com>
    
            Reviewed by Kenneth Russell.
    
            [chromium] Tile root layer of the compositor.
            https://bugs.webkit.org/show_bug.cgi?id=49947
    
            Refactor root layer update and drawing from LayerRendererChromium into
            LayerTilerChromium.  The root layer is now drawn as multiple tiles
            rather than as one single large texture.  Scrollbars are now drawn
            separately rather than as part of the root layer.
    
            Test: LayoutTests/compositing/
    
            * WebCore.gypi:
            * page/FrameView.cpp:
            (WebCore::FrameView::repaintContentRectangle):
            * platform/ScrollView.cpp:
            (WebCore::ScrollView::ScrollView):
            (WebCore::ScrollView::setClipsRepaints):
            * platform/ScrollView.h:
            (WebCore::ScrollView::clipsRepaints):
            * platform/graphics/chromium/LayerChromium.h:
            * platform/graphics/chromium/LayerRendererChromium.cpp:
            (WebCore::LayerRendererChromium::LayerRendererChromium):
            (WebCore::LayerRendererChromium::~LayerRendererChromium):
            (WebCore::LayerRendererChromium::useShader):
            (WebCore::LayerRendererChromium::verticalScrollbarRect):
            (WebCore::LayerRendererChromium::horizontalScrollbarRect):
            (WebCore::LayerRendererChromium::invalidateRootLayerRect):
            (WebCore::LayerRendererChromium::updateAndDrawRootLayer):
            (WebCore::LayerRendererChromium::drawLayers):
            (WebCore::LayerRendererChromium::setRootLayer):
            (WebCore::LayerRendererChromium::initializeSharedObjects):
            (WebCore::LayerRendererChromium::cleanupSharedObjects):
            * platform/graphics/chromium/LayerRendererChromium.h:
            * platform/graphics/chromium/LayerTilerChromium.cpp: Added.
            (WebCore::LayerTilerChromium::create):
            (WebCore::LayerTilerChromium::LayerTilerChromium):
            (WebCore::LayerTilerChromium::~LayerTilerChromium):
            (WebCore::LayerTilerChromium::layerRendererContext):
            (WebCore::LayerTilerChromium::setTileSize):
            (WebCore::LayerTilerChromium::reset):
            (WebCore::LayerTilerChromium::createTile):
            (WebCore::LayerTilerChromium::invalidateTiles):
            (WebCore::LayerTilerChromium::contentRectToTileIndices):
            (WebCore::LayerTilerChromium::contentRectToLayerRect):
            (WebCore::LayerTilerChromium::layerRectToContentRect):
            (WebCore::LayerTilerChromium::tileIndex):
            (WebCore::LayerTilerChromium::tileContentRect):
            (WebCore::LayerTilerChromium::tileLayerRect):
            (WebCore::LayerTilerChromium::invalidateRect):
            (WebCore::LayerTilerChromium::invalidateEntireLayer):
            (WebCore::LayerTilerChromium::update):
            (WebCore::LayerTilerChromium::setLayerPosition):
            (WebCore::LayerTilerChromium::draw):
            (WebCore::LayerTilerChromium::resizeLayer):
            (WebCore::LayerTilerChromium::growLayerToContain):
            (WebCore::LayerTilerChromium::Tile::~Tile):
            (WebCore::LayerTilerChromium::Tile::releaseTextureId):
            * platform/graphics/chromium/LayerTilerChromium.h: Added.
            (WebCore::LayerTilerChromium::Tile::Tile):
            (WebCore::LayerTilerChromium::Tile::textureId):
            (WebCore::LayerTilerChromium::Tile::dirty):
            (WebCore::LayerTilerChromium::Tile::clearDirty):
            (WebCore::LayerTilerChromium::layerRenderer):
    2010-12-20  Adrienne Walker  <enne at google.com>
    
            Reviewed by Kenneth Russell.
    
            [chromium] Tile root layer of the compositor.
            https://bugs.webkit.org/show_bug.cgi?id=49947
    
            Refactor root layer logic out of WebViewImpl and into
            LayerTilerChromium.  The painting is now done through an interface
            rather than directly in WebViewImpl.
    
            * src/WebViewImpl.cpp:
            (WebKit::WebViewImpl::scrollRootLayerRect):
            (WebKit::WebViewImpl::invalidateRootLayerRect):
            (WebKit::WebViewImpl::setIsAcceleratedCompositingActive):
            (WebKit::WebViewImplTilePaintInterface::WebViewImplTilePaintInterface):
            (WebKit::WebViewImplTilePaintInterface::paint):
            (WebKit::WebViewImplScrollbarPaintInterface::WebViewImplScrollbarPaintInterface):
            (WebKit::WebViewImplScrollbarPaintInterface::paint):
            (WebKit::WebViewImpl::doComposite):
            * src/WebViewImpl.h:
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@74568 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index 36da6ef..691af37 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,70 @@
+2010-12-20  Adrienne Walker  <enne at google.com>
+
+        Reviewed by Kenneth Russell.
+
+        [chromium] Tile root layer of the compositor.
+        https://bugs.webkit.org/show_bug.cgi?id=49947
+
+        Refactor root layer update and drawing from LayerRendererChromium into
+        LayerTilerChromium.  The root layer is now drawn as multiple tiles
+        rather than as one single large texture.  Scrollbars are now drawn
+        separately rather than as part of the root layer.
+
+        Test: LayoutTests/compositing/
+
+        * WebCore.gypi:
+        * page/FrameView.cpp:
+        (WebCore::FrameView::repaintContentRectangle):
+        * platform/ScrollView.cpp:
+        (WebCore::ScrollView::ScrollView):
+        (WebCore::ScrollView::setClipsRepaints):
+        * platform/ScrollView.h:
+        (WebCore::ScrollView::clipsRepaints):
+        * platform/graphics/chromium/LayerChromium.h:
+        * platform/graphics/chromium/LayerRendererChromium.cpp:
+        (WebCore::LayerRendererChromium::LayerRendererChromium):
+        (WebCore::LayerRendererChromium::~LayerRendererChromium):
+        (WebCore::LayerRendererChromium::useShader):
+        (WebCore::LayerRendererChromium::verticalScrollbarRect):
+        (WebCore::LayerRendererChromium::horizontalScrollbarRect):
+        (WebCore::LayerRendererChromium::invalidateRootLayerRect):
+        (WebCore::LayerRendererChromium::updateAndDrawRootLayer):
+        (WebCore::LayerRendererChromium::drawLayers):
+        (WebCore::LayerRendererChromium::setRootLayer):
+        (WebCore::LayerRendererChromium::initializeSharedObjects):
+        (WebCore::LayerRendererChromium::cleanupSharedObjects):
+        * platform/graphics/chromium/LayerRendererChromium.h:
+        * platform/graphics/chromium/LayerTilerChromium.cpp: Added.
+        (WebCore::LayerTilerChromium::create):
+        (WebCore::LayerTilerChromium::LayerTilerChromium):
+        (WebCore::LayerTilerChromium::~LayerTilerChromium):
+        (WebCore::LayerTilerChromium::layerRendererContext):
+        (WebCore::LayerTilerChromium::setTileSize):
+        (WebCore::LayerTilerChromium::reset):
+        (WebCore::LayerTilerChromium::createTile):
+        (WebCore::LayerTilerChromium::invalidateTiles):
+        (WebCore::LayerTilerChromium::contentRectToTileIndices):
+        (WebCore::LayerTilerChromium::contentRectToLayerRect):
+        (WebCore::LayerTilerChromium::layerRectToContentRect):
+        (WebCore::LayerTilerChromium::tileIndex):
+        (WebCore::LayerTilerChromium::tileContentRect):
+        (WebCore::LayerTilerChromium::tileLayerRect):
+        (WebCore::LayerTilerChromium::invalidateRect):
+        (WebCore::LayerTilerChromium::invalidateEntireLayer):
+        (WebCore::LayerTilerChromium::update):
+        (WebCore::LayerTilerChromium::setLayerPosition):
+        (WebCore::LayerTilerChromium::draw):
+        (WebCore::LayerTilerChromium::resizeLayer):
+        (WebCore::LayerTilerChromium::growLayerToContain):
+        (WebCore::LayerTilerChromium::Tile::~Tile):
+        (WebCore::LayerTilerChromium::Tile::releaseTextureId):
+        * platform/graphics/chromium/LayerTilerChromium.h: Added.
+        (WebCore::LayerTilerChromium::Tile::Tile):
+        (WebCore::LayerTilerChromium::Tile::textureId):
+        (WebCore::LayerTilerChromium::Tile::dirty):
+        (WebCore::LayerTilerChromium::Tile::clearDirty):
+        (WebCore::LayerTilerChromium::layerRenderer):
+
 2010-12-22  Ryosuke Niwa  <rniwa at webkit.org>
 
         Reviewed by Eric Seidel.
diff --git a/WebCore/WebCore.gypi b/WebCore/WebCore.gypi
index fca8cfc..2fa41b3 100644
--- a/WebCore/WebCore.gypi
+++ b/WebCore/WebCore.gypi
@@ -2599,6 +2599,8 @@
             'platform/graphics/chromium/LayerRendererChromium.h',
             'platform/graphics/chromium/LayerTexture.cpp',
             'platform/graphics/chromium/LayerTexture.h',
+            'platform/graphics/chromium/LayerTilerChromium.cpp',
+            'platform/graphics/chromium/LayerTilerChromium.h',
             'platform/graphics/chromium/MediaPlayerPrivateChromium.h',
             'platform/graphics/chromium/PlatformIcon.h',
             'platform/graphics/chromium/PluginLayerChromium.cpp',
diff --git a/WebCore/page/FrameView.cpp b/WebCore/page/FrameView.cpp
index 14a8fbd..8873c53 100644
--- a/WebCore/page/FrameView.cpp
+++ b/WebCore/page/FrameView.cpp
@@ -1314,7 +1314,7 @@ void FrameView::repaintContentRectangle(const IntRect& r, bool immediate)
     double delay = adjustedDeferredRepaintDelay();
     if ((m_deferringRepaints || m_deferredRepaintTimer.isActive() || delay) && !immediate) {
         IntRect paintRect = r;
-        if (!paintsEntireContents())
+        if (clipsRepaints() && !paintsEntireContents())
             paintRect.intersect(visibleContentRect());
         if (paintRect.isEmpty())
             return;
diff --git a/WebCore/platform/ScrollView.cpp b/WebCore/platform/ScrollView.cpp
index 7d9e792..57a5918 100644
--- a/WebCore/platform/ScrollView.cpp
+++ b/WebCore/platform/ScrollView.cpp
@@ -53,6 +53,7 @@ ScrollView::ScrollView()
     , m_drawPanScrollIcon(false)
     , m_useFixedLayout(false)
     , m_paintsEntireContents(false)
+    , m_clipsRepaints(true)
     , m_delegatesScrolling(false)
 {
     platformInit();
@@ -202,6 +203,11 @@ void ScrollView::setPaintsEntireContents(bool paintsEntireContents)
     m_paintsEntireContents = paintsEntireContents;
 }
 
+void ScrollView::setClipsRepaints(bool clipsRepaints)
+{
+    m_clipsRepaints = clipsRepaints;
+}
+
 void ScrollView::setDelegatesScrolling(bool delegatesScrolling)
 {
     m_delegatesScrolling = delegatesScrolling;
@@ -794,7 +800,7 @@ void ScrollView::frameRectsChanged()
 void ScrollView::repaintContentRectangle(const IntRect& rect, bool now)
 {
     IntRect paintRect = rect;
-    if (!paintsEntireContents())
+    if (clipsRepaints() && !paintsEntireContents())
         paintRect.intersect(visibleContentRect());
     if (paintRect.isEmpty())
         return;
@@ -1155,4 +1161,3 @@ bool ScrollView::platformIsOffscreen() const
 #endif
 
 }
-
diff --git a/WebCore/platform/ScrollView.h b/WebCore/platform/ScrollView.h
index ed33098..66b4c09 100644
--- a/WebCore/platform/ScrollView.h
+++ b/WebCore/platform/ScrollView.h
@@ -111,6 +111,11 @@ public:
     bool paintsEntireContents() const { return m_paintsEntireContents; }
     void setPaintsEntireContents(bool);
 
+    // By default, paint events are clipped to the visible area.  If set to
+    // false, paint events are no longer clipped.  paintsEntireContents() implies !clipsRepaints().
+    bool clipsRepaints() const { return m_clipsRepaints; }
+    void setClipsRepaints(bool);
+
     // By default programmatic scrolling is handled by WebCore and not by the UI application.
     // In the case of using a tiled backing store, this mode can be set, so that the scroll requests
     // are delegated to the UI application.
@@ -325,6 +330,7 @@ private:
     bool m_useFixedLayout;
 
     bool m_paintsEntireContents;
+    bool m_clipsRepaints;
     bool m_delegatesScrolling;
 
     // There are 8 possible combinations of writing mode and direction.  Scroll origin will be non-zero in the x or y axis
diff --git a/WebCore/platform/graphics/chromium/LayerChromium.h b/WebCore/platform/graphics/chromium/LayerChromium.h
index ac95285..a0a690f 100644
--- a/WebCore/platform/graphics/chromium/LayerChromium.h
+++ b/WebCore/platform/graphics/chromium/LayerChromium.h
@@ -60,6 +60,7 @@ class LayerRendererChromium;
 // this class.
 class LayerChromium : public RefCounted<LayerChromium> {
     friend class LayerRendererChromium;
+    friend class LayerTilerChromium;
 public:
     static PassRefPtr<LayerChromium> create(GraphicsLayerChromium* owner = 0);
 
diff --git a/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp b/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp
index 882baae..0f56777 100644
--- a/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp
+++ b/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp
@@ -100,8 +100,7 @@ PassRefPtr<LayerRendererChromium> LayerRendererChromium::create(PassRefPtr<Graph
 }
 
 LayerRendererChromium::LayerRendererChromium(PassRefPtr<GraphicsContext3D> context)
-    : m_rootLayerTextureId(0)
-    , m_rootLayerTextureWidth(0)
+    : m_rootLayerTextureWidth(0)
     , m_rootLayerTextureHeight(0)
     , m_rootLayer(0)
     , m_scrollPosition(IntPoint(-1, -1))
@@ -112,11 +111,19 @@ LayerRendererChromium::LayerRendererChromium(PassRefPtr<GraphicsContext3D> conte
     , m_defaultRenderSurface(0)
 {
     m_hardwareCompositing = initializeSharedObjects();
+    m_rootLayerTiler = LayerTilerChromium::create(this, IntSize(256, 256));
+    ASSERT(m_rootLayerTiler);
 }
 
 LayerRendererChromium::~LayerRendererChromium()
 {
     cleanupSharedObjects();
+
+    // Because the tilers need to clean up textures, clean them up explicitly
+    // before the GraphicsContext3D is destroyed.
+    m_rootLayerTiler.clear();
+    m_horizontalScrollbarTiler.clear();
+    m_verticalScrollbarTiler.clear();
 }
 
 GraphicsContext3D* LayerRendererChromium::context()
@@ -131,54 +138,83 @@ void LayerRendererChromium::debugGLCall(GraphicsContext3D* context, const char*
         LOG_ERROR("GL command failed: File: %s\n\tLine %d\n\tcommand: %s, error %x\n", file, line, command, static_cast<int>(error));
 }
 
-// Creates a canvas and an associated graphics context that the root layer will
-// render into.
-void LayerRendererChromium::setRootLayerCanvasSize(const IntSize& size)
+void LayerRendererChromium::useShader(unsigned programId)
 {
-    if (size == m_rootLayerCanvasSize)
-        return;
+    if (programId != m_currentShader) {
+        GLC(m_context.get(), m_context->useProgram(programId));
+        m_currentShader = programId;
+    }
+}
 
-#if PLATFORM(SKIA)
-    // Create new canvas and context. OwnPtr takes care of freeing up
-    // the old ones.
-    m_rootLayerCanvas = new skia::PlatformCanvas(size.width(), size.height(), false);
-    m_rootLayerSkiaContext = new PlatformContextSkia(m_rootLayerCanvas.get());
-    m_rootLayerGraphicsContext = new GraphicsContext(reinterpret_cast<PlatformGraphicsContext*>(m_rootLayerSkiaContext.get()));
-#elif PLATFORM(CG)
-    // Release the previous CGBitmapContext before reallocating the backing store as a precaution.
-    m_rootLayerCGContext.adoptCF(0);
-    int rowBytes = 4 * size.width();
-    m_rootLayerBackingStore.resize(rowBytes * size.height());
-    memset(m_rootLayerBackingStore.data(), 0, m_rootLayerBackingStore.size());
-    RetainPtr<CGColorSpaceRef> colorSpace(AdoptCF, CGColorSpaceCreateDeviceRGB());
-    m_rootLayerCGContext.adoptCF(CGBitmapContextCreate(m_rootLayerBackingStore.data(),
-                                                       size.width(), size.height(), 8, rowBytes,
-                                                       colorSpace.get(),
-                                                       kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host));
-    CGContextTranslateCTM(m_rootLayerCGContext.get(), 0, size.height());
-    CGContextScaleCTM(m_rootLayerCGContext.get(), 1, -1);
-    m_rootLayerGraphicsContext = new GraphicsContext(m_rootLayerCGContext.get());
-#else
-#error "Need to implement for your platform."
-#endif
+IntRect LayerRendererChromium::verticalScrollbarRect(const IntRect& visibleRect, const IntRect& contentRect)
+{
+    IntRect verticalScrollbar(IntPoint(contentRect.right(), contentRect.y()), IntSize(visibleRect.width() - contentRect.width(), visibleRect.height()));
+    return verticalScrollbar;
+}
 
-    m_rootLayerCanvasSize = size;
+IntRect LayerRendererChromium::horizontalScrollbarRect(const IntRect& visibleRect, const IntRect& contentRect)
+{
+    IntRect horizontalScrollbar(IntPoint(contentRect.x(), contentRect.bottom()), IntSize(visibleRect.width(), visibleRect.height() - contentRect.height()));
+    return horizontalScrollbar;
 }
 
-void LayerRendererChromium::useShader(unsigned programId)
+void LayerRendererChromium::invalidateRootLayerRect(const IntRect& dirtyRect, const IntRect& visibleRect, const IntRect& contentRect)
 {
-    if (programId != m_currentShader) {
-        GLC(m_context.get(), m_context->useProgram(programId));
-        m_currentShader = programId;
+    if (contentRect.intersects(dirtyRect))
+        m_rootLayerTiler->invalidateRect(dirtyRect);
+    if (m_horizontalScrollbarTiler) {
+        IntRect scrollbar = horizontalScrollbarRect(visibleRect, contentRect);
+        if (dirtyRect.intersects(scrollbar)) {
+            m_horizontalScrollbarTiler->setLayerPosition(scrollbar.location());
+            m_horizontalScrollbarTiler->invalidateRect(dirtyRect);
+        }
+    }
+    if (m_verticalScrollbarTiler) {
+        IntRect scrollbar = verticalScrollbarRect(visibleRect, contentRect);
+        if (dirtyRect.intersects(scrollbar)) {
+            m_verticalScrollbarTiler->setLayerPosition(scrollbar.location());
+            m_verticalScrollbarTiler->invalidateRect(dirtyRect);
+        }
     }
 }
 
-// This method must be called before any other updates are made to the
-// root layer texture. It resizes the root layer texture and scrolls its
-// contents as needed. It also sets up common GL state used by the rest
-// of the layer drawing code.
-void LayerRendererChromium::prepareToDrawLayers(const IntRect& visibleRect, const IntRect& contentRect,
-                                                const IntPoint& scrollPosition)
+void LayerRendererChromium::updateAndDrawRootLayer(TilePaintInterface& tilePaint, TilePaintInterface& scrollbarPaint, const IntRect& visibleRect, const IntRect& contentRect)
+{
+    // Mask out writes to alpha channel: subpixel antialiasing via Skia results in invalid
+    // zero alpha values on text glyphs. The root layer is always opaque.
+    GLC(m_context.get(), m_context->colorMask(true, true, true, false));
+
+    m_rootLayerTiler->update(tilePaint, visibleRect);
+    m_rootLayerTiler->draw(visibleRect);
+
+    if (visibleRect.width() > contentRect.width()) {
+        IntRect verticalScrollbar = verticalScrollbarRect(visibleRect, contentRect);
+        IntSize tileSize = verticalScrollbar.size().shrunkTo(IntSize(m_maxTextureSize, m_maxTextureSize));
+        if (!m_verticalScrollbarTiler)
+            m_verticalScrollbarTiler = LayerTilerChromium::create(this, tileSize);
+        else
+            m_verticalScrollbarTiler->setTileSize(tileSize);
+        m_verticalScrollbarTiler->setLayerPosition(verticalScrollbar.location());
+        m_verticalScrollbarTiler->update(scrollbarPaint, visibleRect);
+        m_verticalScrollbarTiler->draw(visibleRect);
+    }
+
+    if (visibleRect.height() > contentRect.height()) {
+        IntRect horizontalScrollbar = horizontalScrollbarRect(visibleRect, contentRect);
+        IntSize tileSize = horizontalScrollbar.size().shrunkTo(IntSize(m_maxTextureSize, m_maxTextureSize));
+        if (!m_horizontalScrollbarTiler)
+            m_horizontalScrollbarTiler = LayerTilerChromium::create(this, tileSize);
+        else
+            m_horizontalScrollbarTiler->setTileSize(tileSize);
+        m_horizontalScrollbarTiler->setLayerPosition(horizontalScrollbar.location());
+        m_horizontalScrollbarTiler->update(scrollbarPaint, visibleRect);
+        m_horizontalScrollbarTiler->draw(visibleRect);
+    }
+}
+
+void LayerRendererChromium::drawLayers(const IntRect& visibleRect, const IntRect& contentRect,
+                                       const IntPoint& scrollPosition, TilePaintInterface& tilePaint,
+                                       TilePaintInterface& scrollbarPaint)
 {
     ASSERT(m_hardwareCompositing);
 
@@ -187,10 +223,6 @@ void LayerRendererChromium::prepareToDrawLayers(const IntRect& visibleRect, cons
 
     makeContextCurrent();
 
-    GLC(m_context.get(), m_context->bindTexture(GraphicsContext3D::TEXTURE_2D, m_rootLayerTextureId));
-
-    bool skipScroll = false;
-
     // If the size of the visible area has changed then allocate a new texture
     // to store the contents of the root layer and adjust the projection matrix
     // and viewport.
@@ -199,15 +231,10 @@ void LayerRendererChromium::prepareToDrawLayers(const IntRect& visibleRect, cons
     if (visibleRectWidth != m_rootLayerTextureWidth || visibleRectHeight != m_rootLayerTextureHeight) {
         m_rootLayerTextureWidth = visibleRectWidth;
         m_rootLayerTextureHeight = visibleRectHeight;
-        GLC(m_context.get(), m_context->texImage2DResourceSafe(GraphicsContext3D::TEXTURE_2D, 0, GraphicsContext3D::RGBA, m_rootLayerTextureWidth, m_rootLayerTextureHeight, 0, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE));
 
         // Reset the current render surface to force an update of the viewport and
         // projection matrix next time useRenderSurface is called.
         m_currentRenderSurface = 0;
-
-        // The root layer texture was just resized so its contents are not
-        // useful for scrolling.
-        skipScroll = true;
     }
 
     // The GL viewport covers the entire visible area, including the scrollbars.
@@ -223,75 +250,7 @@ void LayerRendererChromium::prepareToDrawLayers(const IntRect& visibleRect, cons
     // Blending disabled by default. Root layer alpha channel on Windows is incorrect when Skia uses ClearType.
     GLC(m_context.get(), m_context->disable(GraphicsContext3D::BLEND));
 
-    if (m_scrollPosition == IntPoint(-1, -1)) {
-        m_scrollPosition = scrollPosition;
-        skipScroll = true;
-    }
-
-    IntPoint scrollDelta = toPoint(scrollPosition - m_scrollPosition);
-
-    // Scrolling larger than the contentRect size does not preserve any of the pixels, so there is
-    // no need to copy framebuffer pixels back into the texture.
-    if (abs(scrollDelta.y()) > contentRect.height() || abs(scrollDelta.x()) > contentRect.width())
-        skipScroll = true;
-
-    // Scroll the backbuffer
-    if (!skipScroll && (scrollDelta.x() || scrollDelta.y())) {
-        // Scrolling works as follows: We render a quad with the current root layer contents
-        // translated by the amount the page has scrolled since the last update and then read the
-        // pixels of the content area (visible area excluding the scroll bars) back into the
-        // root layer texture. The newly exposed area will be filled by a subsequent drawLayersIntoRect call
-        TransformationMatrix scrolledLayerMatrix;
-
-        scrolledLayerMatrix.translate3d(0.5 * visibleRect.width() - scrollDelta.x(),
-            0.5 * visibleRect.height() + scrollDelta.y(), 0);
-        scrolledLayerMatrix.scale3d(1, -1, 1);
-
-        const RenderSurfaceChromium::SharedValues* rsv = renderSurfaceSharedValues();
-        useShader(rsv->shaderProgram());
-        GLC(m_context.get(), m_context->uniform1i(rsv->shaderSamplerLocation(), 0));
-        LayerChromium::drawTexturedQuad(m_context.get(), m_projectionMatrix, scrolledLayerMatrix,
-                                        visibleRect.width(), visibleRect.height(), 1,
-                                        rsv->shaderMatrixLocation(), rsv->shaderAlphaLocation());
-
-        GLC(m_context.get(), m_context->copyTexSubImage2D(GraphicsContext3D::TEXTURE_2D, 0, 0, 0, 0, 0, contentRect.width(), contentRect.height()));
-    }
-
     m_scrollPosition = scrollPosition;
-}
-
-void LayerRendererChromium::updateRootLayerTextureRect(const IntRect& updateRect)
-{
-    ASSERT(m_hardwareCompositing);
-
-    if (!m_rootLayer)
-        return;
-
-    GLC(m_context.get(), m_context->bindTexture(GraphicsContext3D::TEXTURE_2D, m_rootLayerTextureId));
-
-    // Update the root layer texture.
-    ASSERT((updateRect.right()  <= m_rootLayerTextureWidth)
-           && (updateRect.bottom() <= m_rootLayerTextureHeight));
-
-#if PLATFORM(SKIA)
-    // Get the contents of the updated rect.
-    const SkBitmap& bitmap = m_rootLayerCanvas->getDevice()->accessBitmap(false);
-    ASSERT(bitmap.width() == updateRect.width() && bitmap.height() == updateRect.height());
-    void* pixels = bitmap.getPixels();
-#elif PLATFORM(CG)
-    // Get the contents of the updated rect.
-    ASSERT(static_cast<int>(CGBitmapContextGetWidth(m_rootLayerCGContext.get())) == updateRect.width() && static_cast<int>(CGBitmapContextGetHeight(m_rootLayerCGContext.get())) == updateRect.height());
-    void* pixels = m_rootLayerBackingStore.data();
-#else
-#error "Need to implement for your platform."
-#endif
-    // Copy the contents of the updated rect to the root layer texture.
-    GLC(m_context.get(), m_context->texSubImage2D(GraphicsContext3D::TEXTURE_2D, 0, updateRect.x(), updateRect.y(), updateRect.width(), updateRect.height(), GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, pixels));
-}
-
-void LayerRendererChromium::drawLayers(const IntRect& visibleRect, const IntRect& contentRect)
-{
-    ASSERT(m_hardwareCompositing);
 
     m_defaultRenderSurface = m_rootLayer->m_renderSurface.get();
     if (!m_defaultRenderSurface)
@@ -304,22 +263,7 @@ void LayerRendererChromium::drawLayers(const IntRect& visibleRect, const IntRect
     m_context->clearColor(0, 0, 1, 1);
     m_context->clear(GraphicsContext3D::COLOR_BUFFER_BIT);
 
-    GLC(m_context.get(), m_context->bindTexture(GraphicsContext3D::TEXTURE_2D, m_rootLayerTextureId));
-
-    // Render the root layer using a quad that takes up the entire visible area of the window.
-    // We reuse the shader program used by ContentLayerChromium.
-    const ContentLayerChromium::SharedValues* contentLayerValues = contentLayerSharedValues();
-    useShader(contentLayerValues->contentShaderProgram());
-    GLC(m_context.get(), m_context->uniform1i(contentLayerValues->shaderSamplerLocation(), 0));
-    // Mask out writes to alpha channel: ClearType via Skia results in invalid
-    // zero alpha values on text glyphs. The root layer is always opaque.
-    GLC(m_context.get(), m_context->colorMask(true, true, true, false));
-    TransformationMatrix layerMatrix;
-    layerMatrix.translate3d(visibleRect.width() * 0.5f, visibleRect.height() * 0.5f, 0);
-    LayerChromium::drawTexturedQuad(m_context.get(), m_projectionMatrix, layerMatrix,
-                                    visibleRect.width(), visibleRect.height(), 1,
-                                    contentLayerValues->shaderMatrixLocation(), contentLayerValues->shaderAlphaLocation());
-    GLC(m_context.get(), m_context->colorMask(true, true, true, true));
+    updateAndDrawRootLayer(tilePaint, scrollbarPaint, visibleRect, contentRect);
 
     // Set the root visible/content rects --- used by subsequent drawLayers calls.
     m_rootVisibleRect = visibleRect;
@@ -389,6 +333,16 @@ void LayerRendererChromium::present()
     m_context->prepareTexture();
 }
 
+void LayerRendererChromium::setRootLayer(PassRefPtr<LayerChromium> layer)
+{
+    m_rootLayer = layer;
+    m_rootLayerTiler->invalidateEntireLayer();
+    if (m_horizontalScrollbarTiler)
+        m_horizontalScrollbarTiler->invalidateEntireLayer();
+    if (m_verticalScrollbarTiler)
+        m_verticalScrollbarTiler->invalidateEntireLayer();
+}
+
 void LayerRendererChromium::getFramebufferPixels(void *pixels, const IntRect& rect)
 {
     ASSERT(rect.right() <= rootLayerTextureSize().width()
@@ -782,19 +736,6 @@ bool LayerRendererChromium::initializeSharedObjects()
 {
     makeContextCurrent();
 
-    // Create a texture object to hold the contents of the root layer.
-    m_rootLayerTextureId = createLayerTexture();
-    if (!m_rootLayerTextureId) {
-        LOG_ERROR("Failed to create texture for root layer");
-        cleanupSharedObjects();
-        return false;
-    }
-    // Turn off filtering for the root layer to avoid blurring from the repeated
-    // writes and reads to the framebuffer that happen while scrolling.
-    GLC(m_context.get(), m_context->bindTexture(GraphicsContext3D::TEXTURE_2D, m_rootLayerTextureId));
-    GLC(m_context.get(), m_context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MIN_FILTER, GraphicsContext3D::NEAREST));
-    GLC(m_context.get(), m_context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MAG_FILTER, GraphicsContext3D::NEAREST));
-
     // Get the max texture size supported by the system.
     m_maxTextureSize = 0;
     GLC(m_context.get(), m_context->getIntegerv(GraphicsContext3D::MAX_TEXTURE_SIZE, &m_maxTextureSize));
@@ -829,12 +770,6 @@ void LayerRendererChromium::cleanupSharedObjects()
     m_videoLayerSharedValues.clear();
     m_pluginLayerSharedValues.clear();
     m_renderSurfaceSharedValues.clear();
-
-    if (m_rootLayerTextureId) {
-        deleteLayerTexture(m_rootLayerTextureId);
-        m_rootLayerTextureId = 0;
-    }
-
     if (m_offscreenFramebufferId)
         GLC(m_context.get(), m_context->deleteFramebuffer(m_offscreenFramebufferId));
 
diff --git a/WebCore/platform/graphics/chromium/LayerRendererChromium.h b/WebCore/platform/graphics/chromium/LayerRendererChromium.h
index c0e610a..6474269 100644
--- a/WebCore/platform/graphics/chromium/LayerRendererChromium.h
+++ b/WebCore/platform/graphics/chromium/LayerRendererChromium.h
@@ -38,6 +38,7 @@
 #include "ContentLayerChromium.h"
 #include "IntRect.h"
 #include "LayerChromium.h"
+#include "LayerTilerChromium.h"
 #include "PluginLayerChromium.h"
 #include "RenderSurfaceChromium.h"
 #include "SkBitmap.h"
@@ -67,14 +68,12 @@ public:
 
     GraphicsContext3D* context();
 
-    // updates size of root texture, if needed, and scrolls the backbuffer.
-    void prepareToDrawLayers(const IntRect& visibleRect, const IntRect& contentRect, const IntPoint& scrollPosition);
+    void invalidateRootLayerRect(const IntRect& dirtyRect, const IntRect& visibleRect, const IntRect& contentRect);
 
-    // updates a rectangle within the root layer texture
-    void updateRootLayerTextureRect(const IntRect& updateRect);
-
-    // draws the current layers onto the backbuffer
-    void drawLayers(const IntRect& visibleRect, const IntRect& contentRect);
+    // updates and draws the current layers onto the backbuffer
+    void drawLayers(const IntRect& visibleRect, const IntRect& contentRect,
+                    const IntPoint& scrollPosition, TilePaintInterface& tilePaint,
+                    TilePaintInterface& scrollbarPaint);
 
     // waits for rendering to finish
     void finish();
@@ -82,7 +81,7 @@ public:
     // puts backbuffer onscreen
     void present();
 
-    void setRootLayer(PassRefPtr<LayerChromium> layer) { m_rootLayer = layer; }
+    void setRootLayer(PassRefPtr<LayerChromium> layer);
     LayerChromium* rootLayer() { return m_rootLayer.get(); }
     void transferRootLayer(LayerRendererChromium* other) { other->m_rootLayer = m_rootLayer.release(); }
 
@@ -126,6 +125,8 @@ private:
 
     void drawLayer(LayerChromium*, RenderSurfaceChromium*);
 
+    void updateAndDrawRootLayer(TilePaintInterface& tilePaint, TilePaintInterface& scrollbarPaint, const IntRect& visibleRect, const IntRect& contentRect);
+
     bool isLayerVisible(LayerChromium*, const TransformationMatrix&, const IntRect& visibleRect);
 
     void setDrawViewportRect(const IntRect&, bool flipY);
@@ -139,13 +140,18 @@ private:
     bool initializeSharedObjects();
     void cleanupSharedObjects();
 
-    unsigned m_rootLayerTextureId;
+    static IntRect verticalScrollbarRect(const IntRect& visibleRect, const IntRect& contentRect);
+    static IntRect horizontalScrollbarRect(const IntRect& visibleRect, const IntRect& contentRect);
+
     int m_rootLayerTextureWidth;
     int m_rootLayerTextureHeight;
 
     TransformationMatrix m_projectionMatrix;
 
     RefPtr<LayerChromium> m_rootLayer;
+    OwnPtr<LayerTilerChromium> m_rootLayerTiler;
+    OwnPtr<LayerTilerChromium> m_horizontalScrollbarTiler;
+    OwnPtr<LayerTilerChromium> m_verticalScrollbarTiler;
 
     IntPoint m_scrollPosition;
     bool m_hardwareCompositing;
diff --git a/WebCore/platform/graphics/chromium/LayerTilerChromium.cpp b/WebCore/platform/graphics/chromium/LayerTilerChromium.cpp
new file mode 100644
index 0000000..749f462
--- /dev/null
+++ b/WebCore/platform/graphics/chromium/LayerTilerChromium.cpp
@@ -0,0 +1,423 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * 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 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 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 "config.h"
+
+#if USE(ACCELERATED_COMPOSITING)
+
+#include "LayerTilerChromium.h"
+
+#include "GraphicsContext.h"
+#include "GraphicsContext3D.h"
+#include "LayerRendererChromium.h"
+
+#if PLATFORM(SKIA)
+#include "NativeImageSkia.h"
+#include "PlatformContextSkia.h"
+#elif PLATFORM(CG)
+#include <CoreGraphics/CGBitmapContext.h>
+#endif
+
+#include <wtf/PassOwnArrayPtr.h>
+
+namespace WebCore {
+
+PassOwnPtr<LayerTilerChromium> LayerTilerChromium::create(LayerRendererChromium* layerRenderer, const IntSize& tileSize)
+{
+    if (!layerRenderer || tileSize.isEmpty())
+        return 0;
+
+    return adoptPtr(new LayerTilerChromium(layerRenderer, tileSize));
+}
+
+LayerTilerChromium::LayerTilerChromium(LayerRendererChromium* layerRenderer, const IntSize& tileSize)
+    : m_layerRenderer(layerRenderer)
+{
+    setTileSize(tileSize);
+}
+
+LayerTilerChromium::~LayerTilerChromium()
+{
+    reset();
+}
+
+GraphicsContext3D* LayerTilerChromium::layerRendererContext() const
+{
+    ASSERT(layerRenderer());
+    return layerRenderer()->context();
+}
+
+void LayerTilerChromium::setTileSize(const IntSize& size)
+{
+    if (m_tileSize == size)
+        return;
+
+    reset();
+
+    m_tileSize = size;
+    m_tilePixels = adoptArrayPtr(new uint8_t[m_tileSize.width() * m_tileSize.height() * 4]);
+}
+
+void LayerTilerChromium::reset()
+{
+    for (size_t i = 0; i < m_tiles.size(); ++i) {
+        if (!m_tiles[i])
+            continue;
+        layerRenderer()->deleteLayerTexture(m_tiles[i]->releaseTextureId());
+    }
+    m_tiles.clear();
+    for (size_t i = 0; i < m_unusedTiles.size(); ++i) {
+        if (!m_unusedTiles[i])
+            continue;
+        layerRenderer()->deleteLayerTexture(m_unusedTiles[i]->releaseTextureId());
+    }
+    m_unusedTiles.clear();
+
+    m_layerSize = IntSize();
+    m_layerTileSize = IntSize();
+    m_lastUpdateLayerRect = IntRect();
+}
+
+LayerTilerChromium::Tile* LayerTilerChromium::createTile(int i, int j)
+{
+    const int index = tileIndex(i, j);
+    ASSERT(!m_tiles[index]);
+
+    if (m_unusedTiles.size() > 0) {
+        m_tiles[index] = m_unusedTiles.last().release();
+        m_unusedTiles.removeLast();
+    } else {
+        const unsigned int textureId = layerRenderer()->createLayerTexture();
+        OwnPtr<Tile> tile = adoptPtr(new Tile(textureId));
+
+        GraphicsContext3D* context = layerRendererContext();
+        GLC(context, context->texImage2DResourceSafe(GraphicsContext3D::TEXTURE_2D, 0, GraphicsContext3D::RGBA, m_tileSize.width(), m_tileSize.height(), 0, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE));
+
+        m_tiles[index] = tile.release();
+    }
+
+    m_tiles[index]->m_dirtyLayerRect = tileLayerRect(i, j);
+    return m_tiles[index].get();
+}
+
+void LayerTilerChromium::invalidateTiles(const IntRect& oldLayerRect, const IntRect& newLayerRect)
+{
+    if (!m_tiles.size())
+        return;
+
+    IntRect oldContentRect = layerRectToContentRect(oldLayerRect);
+    int oldLeft, oldTop, oldRight, oldBottom;
+    contentRectToTileIndices(oldContentRect, oldLeft, oldTop, oldRight, oldBottom);
+
+    IntRect newContentRect = layerRectToContentRect(newLayerRect);
+    int newLeft, newTop, newRight, newBottom;
+    contentRectToTileIndices(newContentRect, newLeft, newTop, newRight, newBottom);
+
+    // Iterating through just the old tile indices is an optimization to avoid
+    // iterating through the entire m_tiles array.
+    for (int j = oldTop; j <= oldBottom; ++j) {
+        for (int i = oldLeft; i <= oldRight; ++i) {
+            if (i >= newLeft && i <= newRight && j >= newTop && j <= newBottom)
+                continue;
+
+            const int index = tileIndex(i, j);
+            if (m_tiles[index])
+                m_unusedTiles.append(m_tiles[index].release());
+        }
+    }
+}
+
+void LayerTilerChromium::contentRectToTileIndices(const IntRect& contentRect, int &left, int &top, int &right, int &bottom) const
+{
+    const IntRect layerRect = contentRectToLayerRect(contentRect);
+
+    left = layerRect.x() / m_tileSize.width();
+    top = layerRect.y() / m_tileSize.height();
+    right = (layerRect.right() - 1) / m_tileSize.width();
+    bottom = (layerRect.bottom() - 1) / m_tileSize.height();
+}
+
+IntRect LayerTilerChromium::contentRectToLayerRect(const IntRect& contentRect) const
+{
+    IntPoint pos(contentRect.x() - m_layerPosition.x(), contentRect.y() - m_layerPosition.y());
+    IntRect layerRect(pos, contentRect.size());
+
+    // Clip to the position.
+    if (pos.x() < 0 || pos.y() < 0)
+        layerRect = IntRect(IntPoint(0, 0), IntSize(contentRect.width() + pos.x(), contentRect.height() + pos.y()));
+    return layerRect;
+}
+
+IntRect LayerTilerChromium::layerRectToContentRect(const IntRect& layerRect) const
+{
+    IntRect contentRect = layerRect;
+    contentRect.move(m_layerPosition.x(), m_layerPosition.y());
+    return contentRect;
+}
+
+int LayerTilerChromium::tileIndex(int i, int j) const
+{
+    ASSERT(i >= 0 && j >= 0 && i < m_layerTileSize.width() && j < m_layerTileSize.height());
+    return i + j * m_layerTileSize.width();
+}
+
+IntRect LayerTilerChromium::tileContentRect(int i, int j) const
+{
+    IntPoint anchor(m_layerPosition.x() + i * m_tileSize.width(), m_layerPosition.y() + j * m_tileSize.height());
+    IntRect tile(anchor, m_tileSize);
+    return tile;
+}
+
+IntRect LayerTilerChromium::tileLayerRect(int i, int j) const
+{
+    IntPoint anchor(i * m_tileSize.width(), j * m_tileSize.height());
+    IntRect tile(anchor, m_tileSize);
+    return tile;
+}
+
+void LayerTilerChromium::invalidateRect(const IntRect& contentRect)
+{
+    if (contentRect.isEmpty())
+        return;
+
+    growLayerToContain(contentRect);
+
+    // Dirty rects are always in layer space, as the layer could be repositioned
+    // after invalidation.
+    IntRect layerRect = contentRectToLayerRect(contentRect);
+
+    int left, top, right, bottom;
+    contentRectToTileIndices(contentRect, left, top, right, bottom);
+    for (int j = top; j <= bottom; ++j) {
+        for (int i = left; i <= right; ++i) {
+            Tile* tile = m_tiles[tileIndex(i, j)].get();
+            if (!tile)
+                continue;
+            IntRect bound = tileLayerRect(i, j);
+            bound.intersect(layerRect);
+            tile->m_dirtyLayerRect.unite(bound);
+        }
+    }
+}
+
+void LayerTilerChromium::invalidateEntireLayer()
+{
+    for (size_t i = 0; i < m_tiles.size(); ++i) {
+        if (m_tiles[i])
+            m_unusedTiles.append(m_tiles[i].release());
+    }
+    m_tiles.clear();
+
+    m_layerSize = IntSize();
+    m_layerTileSize = IntSize();
+    m_lastUpdateLayerRect = IntRect();
+}
+
+void LayerTilerChromium::update(TilePaintInterface& painter, const IntRect& contentRect)
+{
+    // Invalidate old tiles that were previously used but aren't in use this
+    // frame so that they can get reused for new tiles.
+    IntRect layerRect = contentRectToLayerRect(contentRect);
+    invalidateTiles(m_lastUpdateLayerRect, layerRect);
+    m_lastUpdateLayerRect = layerRect;
+
+    growLayerToContain(contentRect);
+
+    // Create tiles as needed, expanding a dirty rect to contain all
+    // the dirty regions currently being drawn.
+    IntRect dirtyLayerRect;
+    int left, top, right, bottom;
+    contentRectToTileIndices(contentRect, left, top, right, bottom);
+    for (int j = top; j <= bottom; ++j) {
+        for (int i = left; i <= right; ++i) {
+            Tile* tile = m_tiles[tileIndex(i, j)].get();
+            if (!tile)
+                tile = createTile(i, j);
+            dirtyLayerRect.unite(tile->m_dirtyLayerRect);
+        }
+    }
+
+    if (dirtyLayerRect.isEmpty())
+        return;
+
+    const IntRect paintRect = layerRectToContentRect(dirtyLayerRect);
+    GraphicsContext3D* context = layerRendererContext();
+#if PLATFORM(SKIA)
+    OwnPtr<skia::PlatformCanvas> canvas(new skia::PlatformCanvas(paintRect.width(), paintRect.height(), false));
+    OwnPtr<PlatformContextSkia> skiaContext(new PlatformContextSkia(canvas.get()));
+    OwnPtr<GraphicsContext> graphicsContext(new GraphicsContext(reinterpret_cast<PlatformGraphicsContext*>(skiaContext.get())));
+
+    // Bring the canvas into the coordinate system of the paint rect.
+    canvas->translate(static_cast<SkScalar>(-paintRect.x()), static_cast<SkScalar>(-paintRect.y()));
+
+    painter.paint(*graphicsContext, paintRect);
+
+    // Get the contents of the updated rect.
+    const SkBitmap& bitmap = canvas->getDevice()->accessBitmap(false);
+    ASSERT(bitmap.width() == paintRect.width() && bitmap.height() == paintRect.height());
+    uint8_t* paintPixels = static_cast<uint8_t*>(bitmap.getPixels());
+#elif PLATFORM(CG)
+    Vector<uint8_t> canvasPixels;
+    int rowBytes = 4 * paintRect.width();
+    canvasPixels.resize(rowBytes * paintRect.height());
+    memset(canvasPixels.data(), 0, canvasPixels.size());
+    RetainPtr<CGColorSpaceRef> colorSpace(AdoptCF, CGColorSpaceCreateDeviceRGB());
+    RetainPtr<CGContextRef> m_cgContext;
+    m_cgContext.adoptCF(CGBitmapContextCreate(canvasPixels.data(),
+                                                       paintRect.width(), paintRect.height(), 8, rowBytes,
+                                                       colorSpace.get(),
+                                                       kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host));
+    CGContextTranslateCTM(m_cgContext.get(), 0, paintRect.height());
+    CGContextScaleCTM(m_cgContext.get(), 1, -1);
+    OwnPtr<GraphicsContext> m_graphicsContext(new GraphicsContext(m_cgContext.get()));
+
+    // Bring the CoreGraphics context into the coordinate system of the paint rect.
+    CGContextTranslateCTM(m_cgContext.get(), -paintRect.x(), -paintRect.y());
+    painter.paint(*m_graphicsContext, paintRect);
+
+    // Get the contents of the updated rect.
+    ASSERT(static_cast<int>(CGBitmapContextGetWidth(m_cgContext.get())) == paintRect.width() && static_cast<int>(CGBitmapContextGetHeight(m_cgContext.get())) == paintRect.height());
+    uint8_t* paintPixels = static_cast<uint8_t*>(canvasPixels.data());
+#else
+#error "Need to implement for your platform."
+#endif
+
+    for (int j = top; j <= bottom; ++j) {
+        for (int i = left; i <= right; ++i) {
+            Tile* tile = m_tiles[tileIndex(i, j)].get();
+            if (!tile->dirty())
+                continue;
+
+            // Calculate page-space rectangle to copy from.
+            IntRect sourceRect = tileContentRect(i, j);
+            const IntPoint anchor = sourceRect.location();
+            sourceRect.intersect(layerRectToContentRect(tile->m_dirtyLayerRect));
+
+            // Calculate tile-space rectangle to upload into.
+            IntRect destRect(IntPoint(sourceRect.x() - anchor.x(), sourceRect.y() - anchor.y()), sourceRect.size());
+
+            // Offset from paint rectangle to this tile's dirty rectangle.
+            IntPoint paintOffset(sourceRect.x() - paintRect.x(), sourceRect.y() - paintRect.y());
+
+            uint8_t* pixelSource;
+            if (paintRect.width() == sourceRect.width() && !paintOffset.x())
+                pixelSource = &paintPixels[4 * paintOffset.y() * paintRect.width()];
+            else {
+                // Strides not equal, so do a row-by-row memcpy from the
+                // paint results into a temp buffer for uploading.
+                for (int row = 0; row < destRect.height(); ++row)
+                    memcpy(&m_tilePixels[destRect.width() * 4 * row],
+                           &paintPixels[4 * (paintOffset.x() + (paintOffset.y() + row) * paintRect.width())],
+                           destRect.width() * 4);
+
+                pixelSource = &m_tilePixels[0];
+            }
+
+            GLC(context, context->bindTexture(GraphicsContext3D::TEXTURE_2D, tile->textureId()));
+            GLC(context, context->texSubImage2D(GraphicsContext3D::TEXTURE_2D, 0, destRect.x(), destRect.y(), destRect.width(), destRect.height(), GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, pixelSource));
+
+            tile->clearDirty();
+        }
+    }
+}
+
+void LayerTilerChromium::setLayerPosition(const IntPoint& layerPosition)
+{
+    m_layerPosition = layerPosition;
+}
+
+void LayerTilerChromium::draw(const IntRect& contentRect)
+{
+    // We reuse the shader program used by ContentLayerChromium.
+    GraphicsContext3D* context = layerRendererContext();
+    const ContentLayerChromium::SharedValues* contentLayerValues = layerRenderer()->contentLayerSharedValues();
+    layerRenderer()->useShader(contentLayerValues->contentShaderProgram());
+    GLC(context, context->uniform1i(contentLayerValues->shaderSamplerLocation(), 0));
+
+    int left, top, right, bottom;
+    contentRectToTileIndices(contentRect, left, top, right, bottom);
+    for (int j = top; j <= bottom; ++j) {
+        for (int i = left; i <= right; ++i) {
+            Tile* tile = m_tiles[tileIndex(i, j)].get();
+            ASSERT(tile);
+
+            GLC(context, context->bindTexture(GraphicsContext3D::TEXTURE_2D, tile->textureId()));
+
+            TransformationMatrix tileMatrix;
+            IntRect tileRect = tileContentRect(i, j);
+            tileMatrix.translate3d(tileRect.x() - contentRect.x() + tileRect.width() / 2.0, tileRect.y() - contentRect.y() + tileRect.height() / 2.0, 0);
+
+            LayerChromium::drawTexturedQuad(context, layerRenderer()->projectionMatrix(), tileMatrix, m_tileSize.width(), m_tileSize.height(), 1, contentLayerValues->shaderMatrixLocation(), contentLayerValues->shaderAlphaLocation());
+        }
+    }
+}
+
+void LayerTilerChromium::resizeLayer(const IntSize& size)
+{
+    if (m_layerSize == size)
+        return;
+
+    int width = (size.width() + m_tileSize.width() - 1) / m_tileSize.width();
+    int height = (size.height() + m_tileSize.height() - 1) / m_tileSize.height();
+
+    Vector<OwnPtr<Tile> > newTiles;
+    newTiles.resize(width * height);
+    for (int j = 0; j < m_layerTileSize.height(); ++j)
+        for (int i = 0; i < m_layerTileSize.width(); ++i)
+            newTiles[i + j * width].swap(m_tiles[i + j * m_layerTileSize.width()]);
+
+    m_tiles.swap(newTiles);
+    m_layerSize = size;
+    m_layerTileSize = IntSize(width, height);
+}
+
+void LayerTilerChromium::growLayerToContain(const IntRect& contentRect)
+{
+    // Grow the tile array to contain this content rect.
+    IntRect layerRect = contentRectToLayerRect(contentRect);
+    IntRect layer(IntPoint(0, 0), m_layerSize);
+    layer.unite(layerRect);
+    resizeLayer(layer.size());
+}
+
+LayerTilerChromium::Tile::~Tile()
+{
+    // Each tile doesn't have a reference to the context, so can't clean up
+    // its own texture.  If this assert is hit, then the LayerTilerChromium
+    // destructor didn't clean this up.
+    ASSERT(!m_textureId);
+}
+
+unsigned int LayerTilerChromium::Tile::releaseTextureId()
+{
+    unsigned int id = m_textureId;
+    m_textureId = 0;
+    return id;
+}
+
+} // namespace WebCore
+
+#endif // USE(ACCELERATED_COMPOSITING)
diff --git a/WebCore/platform/graphics/chromium/LayerTilerChromium.h b/WebCore/platform/graphics/chromium/LayerTilerChromium.h
new file mode 100644
index 0000000..c066fdf
--- /dev/null
+++ b/WebCore/platform/graphics/chromium/LayerTilerChromium.h
@@ -0,0 +1,123 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * 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 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 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 LayerTilerChromium_h
+#define LayerTilerChromium_h
+
+#if USE(ACCELERATED_COMPOSITING)
+
+#include "LayerChromium.h"
+#include <wtf/OwnArrayPtr.h>
+
+namespace WebCore {
+
+class GraphicsContext3D;
+class LayerRendererChromium;
+
+class TilePaintInterface {
+public:
+    virtual void paint(GraphicsContext& context, const IntRect& contentRect) = 0;
+};
+
+class LayerTilerChromium : public Noncopyable {
+public:
+    static PassOwnPtr<LayerTilerChromium> create(LayerRendererChromium* layerRenderer, const IntSize& tileSize);
+
+    ~LayerTilerChromium();
+
+    void invalidateRect(const IntRect& contentRect);
+    void invalidateEntireLayer();
+    void update(TilePaintInterface& painter, const IntRect& contentRect);
+    void draw(const IntRect& contentRect);
+
+    // Set position of this tiled layer in content space.
+    void setLayerPosition(const IntPoint& position);
+    // Change the tile size.  This may invalidate all the existing tiles.
+    void setTileSize(const IntSize& size);
+
+private:
+    LayerTilerChromium(LayerRendererChromium* layerRenderer, const IntSize& tileSize);
+
+    class Tile {
+    public:
+        explicit Tile(unsigned int textureId) : m_textureId(textureId) { }
+        ~Tile();
+
+        unsigned int textureId() const { return m_textureId; }
+        unsigned int releaseTextureId();
+
+        bool dirty() const { return !m_dirtyLayerRect.isEmpty(); }
+        void clearDirty() { m_dirtyLayerRect = IntRect(); }
+
+        // Layer-space dirty rectangle that needs to be repainted.
+        IntRect m_dirtyLayerRect;
+    private:
+        unsigned int m_textureId;
+    };
+
+    void resizeLayer(const IntSize& size);
+    // Grow layer size to contain this rectangle.
+    void growLayerToContain(const IntRect& contentRect);
+
+    LayerRendererChromium* layerRenderer() const { return m_layerRenderer; }
+    GraphicsContext3D* layerRendererContext() const;
+    Tile* createTile(int i, int j);
+    // Invalidate any tiles which do not intersect with the newLayerRect.
+    void invalidateTiles(const IntRect& oldLayerRect, const IntRect& newLayerRect);
+    void reset();
+    void contentRectToTileIndices(const IntRect& contentRect, int &left, int &top, int &right, int &bottom) const;
+    IntRect contentRectToLayerRect(const IntRect& contentRect) const;
+    IntRect layerRectToContentRect(const IntRect& layerRect) const;
+
+    // Returns the index into m_tiles for a given tile location.
+    int tileIndex(int i, int j) const;
+    // Returns the bounds in content space for a given tile location.
+    IntRect tileContentRect(int i, int j) const;
+    // Returns the bounds in layer space for a given tile location.
+    IntRect tileLayerRect(int i, int j) const;
+
+    IntSize m_tileSize;
+    IntSize m_layerSize;
+    IntSize m_layerTileSize;
+    IntRect m_lastUpdateLayerRect;
+    IntPoint m_layerPosition;
+
+    // Logical 2D array of tiles (dimensions of m_layerTileSize)
+    Vector<OwnPtr<Tile> > m_tiles;
+    // Linear array of unused tiles.
+    Vector<OwnPtr<Tile> > m_unusedTiles;
+
+    // Cache a tile-sized pixel buffer to draw into.
+    OwnArrayPtr<uint8_t> m_tilePixels;
+
+    LayerRendererChromium* m_layerRenderer;
+};
+
+}
+
+#endif // USE(ACCELERATED_COMPOSITING)
+
+#endif
diff --git a/WebKit/chromium/ChangeLog b/WebKit/chromium/ChangeLog
index fee8b24..2a61a5e 100644
--- a/WebKit/chromium/ChangeLog
+++ b/WebKit/chromium/ChangeLog
@@ -1,3 +1,25 @@
+2010-12-20  Adrienne Walker  <enne at google.com>
+
+        Reviewed by Kenneth Russell.
+
+        [chromium] Tile root layer of the compositor.
+        https://bugs.webkit.org/show_bug.cgi?id=49947
+
+        Refactor root layer logic out of WebViewImpl and into
+        LayerTilerChromium.  The painting is now done through an interface
+        rather than directly in WebViewImpl.
+
+        * src/WebViewImpl.cpp:
+        (WebKit::WebViewImpl::scrollRootLayerRect):
+        (WebKit::WebViewImpl::invalidateRootLayerRect):
+        (WebKit::WebViewImpl::setIsAcceleratedCompositingActive):
+        (WebKit::WebViewImplTilePaintInterface::WebViewImplTilePaintInterface):
+        (WebKit::WebViewImplTilePaintInterface::paint):
+        (WebKit::WebViewImplScrollbarPaintInterface::WebViewImplScrollbarPaintInterface):
+        (WebKit::WebViewImplScrollbarPaintInterface::paint):
+        (WebKit::WebViewImpl::doComposite):
+        * src/WebViewImpl.h:
+
 2010-12-22  Ryosuke Niwa  <rniwa at webkit.org>
 
         Reviewed by Eric Seidel.
diff --git a/WebKit/chromium/src/WebViewImpl.cpp b/WebKit/chromium/src/WebViewImpl.cpp
index ac05dd2..a7c4aa1 100644
--- a/WebKit/chromium/src/WebViewImpl.cpp
+++ b/WebKit/chromium/src/WebViewImpl.cpp
@@ -2268,70 +2268,6 @@ void WebViewImpl::setRootLayerNeedsDisplay()
 
 void WebViewImpl::scrollRootLayerRect(const IntSize& scrollDelta, const IntRect& clipRect)
 {
-    ASSERT(m_layerRenderer);
-    // Compute the damage rect in viewport space.
-    WebFrameImpl* webframe = mainFrameImpl();
-    if (!webframe)
-        return;
-    FrameView* view = webframe->frameView();
-    if (!view)
-        return;
-
-    IntRect contentRect = view->visibleContentRect(false);
-    IntRect screenRect = view->contentsToWindow(contentRect);
-
-    // We support fast scrolling in one direction at a time.
-    if (scrollDelta.width() && scrollDelta.height()) {
-        invalidateRootLayerRect(WebRect(screenRect));
-        return;
-    }
-
-    // Compute the region we will expose by scrolling. We use the
-    // content rect for invalidation.  Using this space for damage
-    // rects allows us to intermix invalidates with scrolls.
-    IntRect damagedContentsRect;
-    if (scrollDelta.width()) {
-        int dx = scrollDelta.width();
-        damagedContentsRect.setY(screenRect.y());
-        damagedContentsRect.setHeight(screenRect.height());
-        if (dx > 0) {
-            damagedContentsRect.setX(screenRect.x());
-            damagedContentsRect.setWidth(dx);
-        } else {
-            damagedContentsRect.setX(screenRect.right() + dx);
-            damagedContentsRect.setWidth(-dx);
-        }
-    } else {
-        int dy = scrollDelta.height();
-        damagedContentsRect.setX(screenRect.x());
-        damagedContentsRect.setWidth(screenRect.width());
-        if (dy > 0) {
-            damagedContentsRect.setY(screenRect.y());
-            damagedContentsRect.setHeight(dy);
-        } else {
-            damagedContentsRect.setY(screenRect.bottom() + dy);
-            damagedContentsRect.setHeight(-dy);
-        }
-    }
-
-    // Move the previous damage
-    m_rootLayerScrollDamage.move(scrollDelta.width(), scrollDelta.height());
-    // Union with the new damage rect.
-    m_rootLayerScrollDamage.unite(damagedContentsRect);
-
-    // Scroll any existing damage that intersects with clip rect
-    if (clipRect.intersects(m_rootLayerDirtyRect)) {
-        // Find the inner damage
-        IntRect innerDamage(clipRect);
-        innerDamage.intersect(m_rootLayerDirtyRect);
-
-        // Move the damage
-        innerDamage.move(scrollDelta.width(), scrollDelta.height());
-
-        // Merge it back into the damaged rect
-        m_rootLayerDirtyRect.unite(innerDamage);
-    }
-
     setRootLayerNeedsDisplay();
 }
 
@@ -2342,9 +2278,12 @@ void WebViewImpl::invalidateRootLayerRect(const IntRect& rect)
     if (!page())
         return;
 
-    // FIXME: add a smarter damage aggregation logic and/or unify with
-    // LayerChromium's damage logic
-    m_rootLayerDirtyRect.unite(rect);
+    FrameView* view = page()->mainFrame()->view();
+    IntRect contentRect = view->visibleContentRect(false);
+    IntRect visibleRect = view->visibleContentRect(true);
+
+    IntRect dirtyRect = view->windowToContents(rect);
+    m_layerRenderer->invalidateRootLayerRect(dirtyRect, visibleRect, contentRect);
     setRootLayerNeedsDisplay();
 }
 
@@ -2361,89 +2300,77 @@ void WebViewImpl::setIsAcceleratedCompositingActive(bool active)
         if (m_layerRenderer)
             m_layerRenderer->finish(); // finish all GL rendering before we hide the window?
         m_client->didActivateAcceleratedCompositing(false);
-        return;
-    }
-
-    if (m_layerRenderer) {
+    } else if (m_layerRenderer) {
         m_isAcceleratedCompositingActive = true;
         m_layerRenderer->resizeOnscreenContent(WebCore::IntSize(std::max(1, m_size.width),
                                                                 std::max(1, m_size.height)));
 
         m_client->didActivateAcceleratedCompositing(true);
-        return;
-    }
-
-    RefPtr<GraphicsContext3D> context = m_temporaryOnscreenGraphicsContext3D.release();
-    if (!context) {
-        context = GraphicsContext3D::create(getCompositorContextAttributes(), m_page->chrome(), GraphicsContext3D::RenderDirectlyToHostWindow);
-        if (context)
-            context->reshape(std::max(1, m_size.width), std::max(1, m_size.height));
-    }
-    m_layerRenderer = LayerRendererChromium::create(context.release());
-    if (m_layerRenderer) {
-        m_client->didActivateAcceleratedCompositing(true);
-        m_isAcceleratedCompositingActive = true;
-        m_compositorCreationFailed = false;
     } else {
-        m_isAcceleratedCompositingActive = false;
-        m_client->didActivateAcceleratedCompositing(false);
-        m_compositorCreationFailed = true;
+        RefPtr<GraphicsContext3D> context = m_temporaryOnscreenGraphicsContext3D.release();
+        if (!context) {
+            context = GraphicsContext3D::create(getCompositorContextAttributes(), m_page->chrome(), GraphicsContext3D::RenderDirectlyToHostWindow);
+            if (context)
+                context->reshape(std::max(1, m_size.width), std::max(1, m_size.height));
+        }
+        m_layerRenderer = LayerRendererChromium::create(context.release());
+        if (m_layerRenderer) {
+            m_client->didActivateAcceleratedCompositing(true);
+            m_isAcceleratedCompositingActive = true;
+            m_compositorCreationFailed = false;
+        } else {
+            m_isAcceleratedCompositingActive = false;
+            m_client->didActivateAcceleratedCompositing(false);
+            m_compositorCreationFailed = true;
+        }
     }
+    if (page())
+        page()->mainFrame()->view()->setClipsRepaints(!m_isAcceleratedCompositingActive);
 }
 
-void WebViewImpl::updateRootLayerContents(const IntRect& rect)
-{
-    if (!isAcceleratedCompositingActive())
-        return;
-
-    WebFrameImpl* webframe = mainFrameImpl();
-    if (!webframe)
-        return;
-    FrameView* view = webframe->frameView();
-    if (!view)
-        return;
-
-    LayerChromium* rootLayer = m_layerRenderer->rootLayer();
-    if (rootLayer) {
-        IntRect visibleRect = view->visibleContentRect(true);
-
-        m_layerRenderer->setRootLayerCanvasSize(IntSize(rect.width(), rect.height()));
-        GraphicsContext* rootLayerContext = m_layerRenderer->rootLayerGraphicsContext();
-
-#if PLATFORM(SKIA)
-        PlatformContextSkia* skiaContext = rootLayerContext->platformContext();
-        skia::PlatformCanvas* platformCanvas = skiaContext->canvas();
-
-        platformCanvas->save();
-
-        // Bring the canvas into the coordinate system of the paint rect.
-        platformCanvas->translate(static_cast<SkScalar>(-rect.x()), static_cast<SkScalar>(-rect.y()));
-
-        rootLayerContext->save();
-
-        webframe->paintWithContext(*rootLayerContext, rect);
-        rootLayerContext->restore();
+class WebViewImplTilePaintInterface : public TilePaintInterface {
+public:
+    explicit WebViewImplTilePaintInterface(WebViewImpl* webViewImpl)
+        : m_webViewImpl(webViewImpl)
+    {
+    }
 
-        platformCanvas->restore();
-#elif PLATFORM(CG)
-        CGContextRef cgContext = rootLayerContext->platformContext();
+    virtual void paint(GraphicsContext& context, const IntRect& contentRect)
+    {
+        Page* page = m_webViewImpl->page();
+        if (!page)
+            return;
+        FrameView* view = page->mainFrame()->view();
+        view->paintContents(&context, contentRect);
+    }
 
-        CGContextSaveGState(cgContext);
+private:
+    WebViewImpl* m_webViewImpl;
+};
 
-        // Bring the CoreGraphics context into the coordinate system of the paint rect.
-        CGContextTranslateCTM(cgContext, -rect.x(), -rect.y());
 
-        rootLayerContext->save();
+class WebViewImplScrollbarPaintInterface : public TilePaintInterface {
+public:
+    explicit WebViewImplScrollbarPaintInterface(WebViewImpl* webViewImpl)
+        : m_webViewImpl(webViewImpl)
+    {
+    }
 
-        webframe->paintWithContext(*rootLayerContext, rect);
-        rootLayerContext->restore();
+    virtual void paint(GraphicsContext& context, const IntRect& contentRect)
+    {
+        Page* page = m_webViewImpl->page();
+        if (!page)
+            return;
+        FrameView* view = page->mainFrame()->view();
 
-        CGContextRestoreGState(cgContext);
-#else
-#error Must port to your platform
-#endif
+        context.translate(view->scrollX(), view->scrollY());
+        IntRect windowRect = view->contentsToWindow(contentRect);
+        view->paintScrollbars(&context, windowRect);
     }
-}
+
+private:
+    WebViewImpl* m_webViewImpl;
+};
 
 void WebViewImpl::doComposite()
 {
@@ -2455,32 +2382,12 @@ void WebViewImpl::doComposite()
     // The visibleRect includes scrollbars whereas the contentRect doesn't.
     IntRect visibleRect = view->visibleContentRect(true);
     IntRect contentRect = view->visibleContentRect(false);
-    IntRect viewPort = IntRect(0, 0, m_size.width, m_size.height);
-
-    // Give the compositor a chance to setup/resize the root texture handle and perform scrolling.
-    m_layerRenderer->prepareToDrawLayers(visibleRect, contentRect, IntPoint(view->scrollX(), view->scrollY()));
+    IntPoint scroll(view->scrollX(), view->scrollY());
 
-    // Draw the contents of the root layer.
-    Vector<IntRect> damageRects;
-    damageRects.append(m_rootLayerScrollDamage);
-    damageRects.append(m_rootLayerDirtyRect);
-    for (size_t i = 0; i < damageRects.size(); ++i) {
-        IntRect damagedRect = damageRects[i];
-
-        // Intersect this rectangle with the viewPort.
-        damagedRect.intersect(viewPort);
-
-        // Now render it.
-        if (damagedRect.width() && damagedRect.height()) {
-            updateRootLayerContents(damagedRect);
-            m_layerRenderer->updateRootLayerTextureRect(damagedRect);
-        }
-    }
-    m_rootLayerDirtyRect = IntRect();
-    m_rootLayerScrollDamage = IntRect();
+    WebViewImplTilePaintInterface tilePaint(this);
 
-    // Draw the actual layers...
-    m_layerRenderer->drawLayers(visibleRect, contentRect);
+    WebViewImplScrollbarPaintInterface scrollbarPaint(this);
+    m_layerRenderer->drawLayers(visibleRect, contentRect, scroll, tilePaint, scrollbarPaint);
 }
 
 void WebViewImpl::reallocateRenderer()
diff --git a/WebKit/chromium/src/WebViewImpl.h b/WebKit/chromium/src/WebViewImpl.h
index 6e8dcac..80abf81 100644
--- a/WebKit/chromium/src/WebViewImpl.h
+++ b/WebKit/chromium/src/WebViewImpl.h
@@ -396,7 +396,6 @@ private:
 
 #if USE(ACCELERATED_COMPOSITING)
     void setIsAcceleratedCompositingActive(bool);
-    void updateRootLayerContents(const WebCore::IntRect&);
     void doComposite();
     void doPixelReadbackToCanvas(WebCanvas*, const WebCore::IntRect&);
     void reallocateRenderer();
@@ -528,7 +527,6 @@ private:
     RefPtr<WebCore::Node> m_mouseCaptureNode;
 
 #if USE(ACCELERATED_COMPOSITING)
-    WebCore::IntRect m_rootLayerDirtyRect;
     WebCore::IntRect m_rootLayerScrollDamage;
     RefPtr<WebCore::LayerRendererChromium> m_layerRenderer;
     bool m_isAcceleratedCompositingActive;

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list