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

jamesr at google.com jamesr at google.com
Wed Dec 22 18:20:33 UTC 2010


The following commit has been merged in the debian/experimental branch:
commit 0b08057d4d8f8c0e1e96f341b9cf165c5e499514
Author: jamesr at google.com <jamesr at google.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Fri Dec 10 01:45:18 2010 +0000

    2010-12-09  James Robinson  <jamesr at chromium.org>
    
            Reviewed by Kenneth Russell.
    
            [chromium] Compositor needs to manage its VRAM use
            https://bugs.webkit.org/show_bug.cgi?id=49629
    
            Adds a few tests involving lots of visible image layers.  The tests are designed
            to require slightly more than 64MB of VRAM.
    
            * platform/chromium-gpu-win/compositing/lots-of-img-layers-expected.checksum: Added.
            * platform/chromium-gpu-win/compositing/lots-of-img-layers-expected.png: Added.
            * platform/chromium-gpu-win/compositing/lots-of-img-layers-expected.txt: Added.
            * platform/chromium-gpu-win/compositing/lots-of-img-layers-with-opacity-expected.checksum: Added.
            * platform/chromium-gpu-win/compositing/lots-of-img-layers-with-opacity-expected.png: Added.
            * platform/chromium-gpu-win/compositing/lots-of-img-layers-with-opacity-expected.txt: Added.
            * platform/chromium-gpu/test_expectations.txt:
            * platform/chromium/compositing/lots-of-img-layers-with-opacity.html: Added.
            * platform/chromium/compositing/lots-of-img-layers.html: Added.
            * platform/chromium/test_expectations.txt:
    2010-12-09  James Robinson  <jamesr at chromium.org>
    
            Reviewed by Kenneth Russell.
    
            [chromium] Compositor needs to manage its VRAM use
            https://bugs.webkit.org/show_bug.cgi?id=49629
    
            This adds a basic texture manager to the Chromium compositor to limit the amount of VRAM
            used by compositor textures and switches ContentLayerChromium, ImageLayerChromium, and
            RenderSurfaceChromium to use managed LayerTexture.  The other *LayerChromium classes (Canvas,
            Video, and WebGL) and the root layer are still unmanaged.
    
            The TextureManager works by providing tokens to callers that want to use a managed texture.
            The token can be used to request a texture, see if the previously requested texture is still
            available, and to protect/unprotect textures when they cannot be collected.  Whenever a
            texture is created the manager attempts to free up the least recently used textures until the
            total memory use is below the provided threshhold.  If the manager cannot satisfy the memory
            limit it will not return any new textures until some old textures are released.
    
            A LayerTexture wraps a TextureManager token, size, and format.  A LayerChromium can check if a
            previously requested texture is still available for use and reserve the LayerTexture's underlying
            storage between the updateContentsIfDirty() and the draw() call.
    
            Also changes LayerChromium from having separate contentsDirty()/updateContents() calls to a single
            updateContentsIfDirty().
    
            Tests: platform/chromium/compositing/lots-of-img-layers-with-opacity.html
                   platform/chromium/compositing/lots-of-img-layers.html
    
            * WebCore.gypi:
            * platform/graphics/chromium/Canvas2DLayerChromium.cpp:
            (WebCore::Canvas2DLayerChromium::updateContentsIfDirty):
            * platform/graphics/chromium/Canvas2DLayerChromium.h:
            * platform/graphics/chromium/ContentLayerChromium.cpp:
            (WebCore::ContentLayerChromium::cleanupResources):
            (WebCore::ContentLayerChromium::updateContentsIfDirty):
            (WebCore::ContentLayerChromium::updateTextureRect):
            (WebCore::ContentLayerChromium::draw):
            * platform/graphics/chromium/ContentLayerChromium.h:
            * platform/graphics/chromium/ImageLayerChromium.cpp:
            (WebCore::ImageLayerChromium::updateContentsIfDirty):
            * platform/graphics/chromium/ImageLayerChromium.h:
            * platform/graphics/chromium/LayerChromium.h:
            (WebCore::LayerChromium::updateContentsIfDirty):
            (WebCore::LayerChromium::draw):
            * platform/graphics/chromium/LayerRendererChromium.cpp:
            (WebCore::LayerRendererChromium::LayerRendererChromium):
            (WebCore::LayerRendererChromium::useShader):
            (WebCore::LayerRendererChromium::prepareToDrawLayers):
            (WebCore::LayerRendererChromium::updateRootLayerTextureRect):
            (WebCore::LayerRendererChromium::drawLayers):
            (WebCore::LayerRendererChromium::getFramebufferPixels):
            (WebCore::LayerRendererChromium::createLayerTexture):
            (WebCore::LayerRendererChromium::deleteLayerTexture):
            (WebCore::LayerRendererChromium::updateLayersRecursive):
            (WebCore::LayerRendererChromium::useRenderSurface):
            (WebCore::LayerRendererChromium::drawLayer):
            (WebCore::LayerRendererChromium::setScissorToRect):
            (WebCore::LayerRendererChromium::setDrawViewportRect):
            (WebCore::LayerRendererChromium::initializeSharedObjects):
            (WebCore::LayerRendererChromium::cleanupSharedObjects):
            * platform/graphics/chromium/LayerRendererChromium.h:
            (WebCore::LayerRendererChromium::renderSurfaceSharedValues):
            (WebCore::LayerRendererChromium::textureManager):
            * platform/graphics/chromium/LayerTexture.cpp: Added.
            (WebCore::LayerTexture::LayerTexture):
            (WebCore::LayerTexture::~LayerTexture):
            (WebCore::LayerTexture::isValid):
            (WebCore::LayerTexture::reserve):
            (WebCore::LayerTexture::unreserve):
            (WebCore::LayerTexture::bindTexture):
            (WebCore::LayerTexture::framebufferTexture2D):
            * platform/graphics/chromium/LayerTexture.h: Added.
            (WebCore::LayerTexture::create):
            * platform/graphics/chromium/PluginLayerChromium.cpp:
            (WebCore::PluginLayerChromium::updateContentsIfDirty):
            * platform/graphics/chromium/PluginLayerChromium.h:
            * platform/graphics/chromium/RenderSurfaceChromium.cpp:
            (WebCore::RenderSurfaceChromium::SharedValues::SharedValues):
            (WebCore::RenderSurfaceChromium::SharedValues::~SharedValues):
            (WebCore::RenderSurfaceChromium::RenderSurfaceChromium):
            (WebCore::RenderSurfaceChromium::cleanupResources):
            (WebCore::RenderSurfaceChromium::prepareContentsTexture):
            (WebCore::RenderSurfaceChromium::draw):
            * platform/graphics/chromium/RenderSurfaceChromium.h:
            (WebCore::RenderSurfaceChromium::SharedValues::shaderProgram):
            (WebCore::RenderSurfaceChromium::SharedValues::shaderSamplerLocation):
            (WebCore::RenderSurfaceChromium::SharedValues::shaderMatrixLocation):
            (WebCore::RenderSurfaceChromium::SharedValues::shaderAlphaLocation):
            (WebCore::RenderSurfaceChromium::SharedValues::initialized):
            * platform/graphics/chromium/TextureManager.cpp: Added.
            (WebCore::memoryUseBytes):
            (WebCore::TextureManager::TextureManager):
            (WebCore::TextureManager::getToken):
            (WebCore::TextureManager::releaseToken):
            (WebCore::TextureManager::hasTexture):
            (WebCore::TextureManager::protectTexture):
            (WebCore::TextureManager::unprotectTexture):
            (WebCore::TextureManager::reduceMemoryToLimit):
            (WebCore::TextureManager::addTexture):
            (WebCore::TextureManager::removeTexture):
            (WebCore::TextureManager::requestTexture):
            * platform/graphics/chromium/TextureManager.h: Added.
            (WebCore::TextureManager::create):
            * platform/graphics/chromium/VideoLayerChromium.cpp:
            (WebCore::VideoLayerChromium::updateContentsIfDirty):
            * platform/graphics/chromium/VideoLayerChromium.h:
            * platform/graphics/chromium/WebGLLayerChromium.cpp:
            (WebCore::WebGLLayerChromium::updateContentsIfDirty):
            * platform/graphics/chromium/WebGLLayerChromium.h:
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@73663 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog
index 30adac6..55f133a 100644
--- a/LayoutTests/ChangeLog
+++ b/LayoutTests/ChangeLog
@@ -1,3 +1,24 @@
+2010-12-09  James Robinson  <jamesr at chromium.org>
+
+        Reviewed by Kenneth Russell.
+
+        [chromium] Compositor needs to manage its VRAM use
+        https://bugs.webkit.org/show_bug.cgi?id=49629
+
+        Adds a few tests involving lots of visible image layers.  The tests are designed
+        to require slightly more than 64MB of VRAM.
+
+        * platform/chromium-gpu-win/compositing/lots-of-img-layers-expected.checksum: Added.
+        * platform/chromium-gpu-win/compositing/lots-of-img-layers-expected.png: Added.
+        * platform/chromium-gpu-win/compositing/lots-of-img-layers-expected.txt: Added.
+        * platform/chromium-gpu-win/compositing/lots-of-img-layers-with-opacity-expected.checksum: Added.
+        * platform/chromium-gpu-win/compositing/lots-of-img-layers-with-opacity-expected.png: Added.
+        * platform/chromium-gpu-win/compositing/lots-of-img-layers-with-opacity-expected.txt: Added.
+        * platform/chromium-gpu/test_expectations.txt:
+        * platform/chromium/compositing/lots-of-img-layers-with-opacity.html: Added.
+        * platform/chromium/compositing/lots-of-img-layers.html: Added.
+        * platform/chromium/test_expectations.txt:
+
 2010-12-09  Mihai Parparita  <mihaip at chromium.org>
 
         Unreviewed Chromium test expectations update.
diff --git a/LayoutTests/platform/chromium-gpu-win/compositing/lots-of-img-layers-expected.checksum b/LayoutTests/platform/chromium-gpu-win/compositing/lots-of-img-layers-expected.checksum
new file mode 100644
index 0000000..6bc3769
--- /dev/null
+++ b/LayoutTests/platform/chromium-gpu-win/compositing/lots-of-img-layers-expected.checksum
@@ -0,0 +1 @@
+87fa5eccd988570bd19aaa2505cc8c2d
\ No newline at end of file
diff --git a/LayoutTests/platform/chromium-gpu-win/compositing/lots-of-img-layers-expected.png b/LayoutTests/platform/chromium-gpu-win/compositing/lots-of-img-layers-expected.png
new file mode 100644
index 0000000..809e653
Binary files /dev/null and b/LayoutTests/platform/chromium-gpu-win/compositing/lots-of-img-layers-expected.png differ
diff --git a/LayoutTests/platform/chromium-gpu-win/compositing/lots-of-img-layers-expected.txt b/LayoutTests/platform/chromium-gpu-win/compositing/lots-of-img-layers-expected.txt
new file mode 100644
index 0000000..c75f32b
--- /dev/null
+++ b/LayoutTests/platform/chromium-gpu-win/compositing/lots-of-img-layers-expected.txt
@@ -0,0 +1,705 @@
+layer at (0,0) size 800x733
+  RenderView at (0,0) size 800x600
+layer at (0,0) size 800x8
+  RenderBlock {HTML} at (0,0) size 800x8
+    RenderBody {BODY} at (8,8) size 784x0
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
diff --git a/LayoutTests/platform/chromium-gpu-win/compositing/lots-of-img-layers-with-opacity-expected.checksum b/LayoutTests/platform/chromium-gpu-win/compositing/lots-of-img-layers-with-opacity-expected.checksum
new file mode 100644
index 0000000..09b3f42
--- /dev/null
+++ b/LayoutTests/platform/chromium-gpu-win/compositing/lots-of-img-layers-with-opacity-expected.checksum
@@ -0,0 +1 @@
+49186f5dccb4d787d4b8e7319c9dde10
\ No newline at end of file
diff --git a/LayoutTests/platform/chromium-gpu-win/compositing/lots-of-img-layers-with-opacity-expected.png b/LayoutTests/platform/chromium-gpu-win/compositing/lots-of-img-layers-with-opacity-expected.png
new file mode 100644
index 0000000..9d75ba5
Binary files /dev/null and b/LayoutTests/platform/chromium-gpu-win/compositing/lots-of-img-layers-with-opacity-expected.png differ
diff --git a/LayoutTests/platform/chromium-gpu-win/compositing/lots-of-img-layers-with-opacity-expected.txt b/LayoutTests/platform/chromium-gpu-win/compositing/lots-of-img-layers-with-opacity-expected.txt
new file mode 100644
index 0000000..f027408
--- /dev/null
+++ b/LayoutTests/platform/chromium-gpu-win/compositing/lots-of-img-layers-with-opacity-expected.txt
@@ -0,0 +1,705 @@
+layer at (0,0) size 800x600
+  RenderView at (0,0) size 800x600
+layer at (0,0) size 800x8
+  RenderBlock {HTML} at (0,0) size 800x8
+    RenderBody {BODY} at (8,8) size 784x0
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
+layer at (8,8) size 214x232
+  RenderImage {IMG} at (8,8) size 214x232
diff --git a/LayoutTests/platform/chromium-gpu/test_expectations.txt b/LayoutTests/platform/chromium-gpu/test_expectations.txt
index 68b6952..2e47b50 100644
--- a/LayoutTests/platform/chromium-gpu/test_expectations.txt
+++ b/LayoutTests/platform/chromium-gpu/test_expectations.txt
@@ -363,6 +363,11 @@ BUGJAMESR WIN MAC : compositing/text-on-large-layer.html = PASS FAIL
 BUGWK47243 LINUX : fast/canvas/webgl/uniform-location.html = TIMEOUT TEXT
 BUGWK47243 WIN : fast/canvas/webgl/uniform-location.html = TIMEOUT CRASH
 
+// These tests are too slow with our MESA backend.  We can re-enable when we have
+// bots running tests on real hardware.
+BUGWK49629 SKIP : platform/chromium/compositing/lots-of-img-layers.html = PASS
+BUGWK49629 SKIP : platform/chromium/compositing/lots-of-img-layers-with-opacity.html = PASS
+
 BUG57431 WIN LINUX : fast/canvas/canvas-strokeRect.html = TEXT
 BUG57432 WIN LINUX : fast/canvas/drawImage-with-negative-source-destination.html = TEXT
 BUG58534 WIN LINUX : canvas/philip/tests/2d.composite.globalAlpha.fill.html = TEXT
diff --git a/LayoutTests/platform/chromium/compositing/lots-of-img-layers-with-opacity.html b/LayoutTests/platform/chromium/compositing/lots-of-img-layers-with-opacity.html
new file mode 100644
index 0000000..1744689
--- /dev/null
+++ b/LayoutTests/platform/chromium/compositing/lots-of-img-layers-with-opacity.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<body style="overflow:hidden">
+<script>
+for (var i=0; i<350; ++i) {
+    var img = document.createElement("img");
+    img.style.webkitTransform = "rotate("+(i/2)+"deg) translateZ(0)";
+    img.style.webkitTransformOrigin = "300px 300px";
+    img.style.position = "absolute";
+    img.style.opacity = 0.2;
+    document.body.appendChild(img);
+    img.src = "resources/apple.jpg";
+}
+</script>
+</body>
+
diff --git a/LayoutTests/platform/chromium/compositing/lots-of-img-layers.html b/LayoutTests/platform/chromium/compositing/lots-of-img-layers.html
new file mode 100644
index 0000000..f22389e
--- /dev/null
+++ b/LayoutTests/platform/chromium/compositing/lots-of-img-layers.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<body style="overflow:hidden">
+<script>
+for (var i=0; i<350; ++i) {
+    var img = document.createElement("img");
+    img.style.webkitTransform = "rotate("+i+"deg) translateZ(0)";
+    img.style.webkitTransformOrigin = "300px 300px";
+    img.style.position = "absolute";
+    document.body.appendChild(img);
+    img.src = "resources/apple.jpg";
+}
+</script>
+</body>
+
diff --git a/LayoutTests/platform/chromium/test_expectations.txt b/LayoutTests/platform/chromium/test_expectations.txt
index fdb6f9e..c11a30f 100644
--- a/LayoutTests/platform/chromium/test_expectations.txt
+++ b/LayoutTests/platform/chromium/test_expectations.txt
@@ -277,6 +277,7 @@ BUG10395 WONTFIX SKIP : http/tests/webarchive = FAIL PASS
 // Compositing tests are run separately on machines with GPUs; see
 // LayoutTests/platform/chromium-gpu.
 BUG15733 WONTFIX SKIP : compositing = FAIL PASS TIMEOUT
+BUG15733 WONTFIX SKIP : platform/chromium/compositing = FAIL PASS TIMEOUT
 
 // Run the Mac-specific platform tests, but only to check for crashes.
 WONTFIX : platform/gtk = FAIL PASS
@@ -3280,4 +3281,4 @@ BUG66087 WIN : inspector/timeline-parse-html.html = PASS TEXT
 // Needs V8 investigation
 BUG66099 MAC LINUX SLOW : fast/js/array-sort-modifying-tostring.html = TEXT
 BUG66099 WIN RELEASE SLOW : fast/js/array-sort-modifying-tostring.html = TEXT
-BUG66099 WIN DEBUG : fast/js/array-sort-modifying-tostring.html = TIMEOUT
\ No newline at end of file
+BUG66099 WIN DEBUG : fast/js/array-sort-modifying-tostring.html = TIMEOUT
diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index f5062dd..f8fff71 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,114 @@
+2010-12-09  James Robinson  <jamesr at chromium.org>
+
+        Reviewed by Kenneth Russell.
+
+        [chromium] Compositor needs to manage its VRAM use
+        https://bugs.webkit.org/show_bug.cgi?id=49629
+
+        This adds a basic texture manager to the Chromium compositor to limit the amount of VRAM
+        used by compositor textures and switches ContentLayerChromium, ImageLayerChromium, and
+        RenderSurfaceChromium to use managed LayerTexture.  The other *LayerChromium classes (Canvas,
+        Video, and WebGL) and the root layer are still unmanaged.
+
+        The TextureManager works by providing tokens to callers that want to use a managed texture.
+        The token can be used to request a texture, see if the previously requested texture is still
+        available, and to protect/unprotect textures when they cannot be collected.  Whenever a
+        texture is created the manager attempts to free up the least recently used textures until the
+        total memory use is below the provided threshhold.  If the manager cannot satisfy the memory
+        limit it will not return any new textures until some old textures are released.
+
+        A LayerTexture wraps a TextureManager token, size, and format.  A LayerChromium can check if a
+        previously requested texture is still available for use and reserve the LayerTexture's underlying
+        storage between the updateContentsIfDirty() and the draw() call.
+
+        Also changes LayerChromium from having separate contentsDirty()/updateContents() calls to a single
+        updateContentsIfDirty().
+
+        Tests: platform/chromium/compositing/lots-of-img-layers-with-opacity.html
+               platform/chromium/compositing/lots-of-img-layers.html
+
+        * WebCore.gypi:
+        * platform/graphics/chromium/Canvas2DLayerChromium.cpp:
+        (WebCore::Canvas2DLayerChromium::updateContentsIfDirty):
+        * platform/graphics/chromium/Canvas2DLayerChromium.h:
+        * platform/graphics/chromium/ContentLayerChromium.cpp:
+        (WebCore::ContentLayerChromium::cleanupResources):
+        (WebCore::ContentLayerChromium::updateContentsIfDirty):
+        (WebCore::ContentLayerChromium::updateTextureRect):
+        (WebCore::ContentLayerChromium::draw):
+        * platform/graphics/chromium/ContentLayerChromium.h:
+        * platform/graphics/chromium/ImageLayerChromium.cpp:
+        (WebCore::ImageLayerChromium::updateContentsIfDirty):
+        * platform/graphics/chromium/ImageLayerChromium.h:
+        * platform/graphics/chromium/LayerChromium.h:
+        (WebCore::LayerChromium::updateContentsIfDirty):
+        (WebCore::LayerChromium::draw):
+        * platform/graphics/chromium/LayerRendererChromium.cpp:
+        (WebCore::LayerRendererChromium::LayerRendererChromium):
+        (WebCore::LayerRendererChromium::useShader):
+        (WebCore::LayerRendererChromium::prepareToDrawLayers):
+        (WebCore::LayerRendererChromium::updateRootLayerTextureRect):
+        (WebCore::LayerRendererChromium::drawLayers):
+        (WebCore::LayerRendererChromium::getFramebufferPixels):
+        (WebCore::LayerRendererChromium::createLayerTexture):
+        (WebCore::LayerRendererChromium::deleteLayerTexture):
+        (WebCore::LayerRendererChromium::updateLayersRecursive):
+        (WebCore::LayerRendererChromium::useRenderSurface):
+        (WebCore::LayerRendererChromium::drawLayer):
+        (WebCore::LayerRendererChromium::setScissorToRect):
+        (WebCore::LayerRendererChromium::setDrawViewportRect):
+        (WebCore::LayerRendererChromium::initializeSharedObjects):
+        (WebCore::LayerRendererChromium::cleanupSharedObjects):
+        * platform/graphics/chromium/LayerRendererChromium.h:
+        (WebCore::LayerRendererChromium::renderSurfaceSharedValues):
+        (WebCore::LayerRendererChromium::textureManager):
+        * platform/graphics/chromium/LayerTexture.cpp: Added.
+        (WebCore::LayerTexture::LayerTexture):
+        (WebCore::LayerTexture::~LayerTexture):
+        (WebCore::LayerTexture::isValid):
+        (WebCore::LayerTexture::reserve):
+        (WebCore::LayerTexture::unreserve):
+        (WebCore::LayerTexture::bindTexture):
+        (WebCore::LayerTexture::framebufferTexture2D):
+        * platform/graphics/chromium/LayerTexture.h: Added.
+        (WebCore::LayerTexture::create):
+        * platform/graphics/chromium/PluginLayerChromium.cpp:
+        (WebCore::PluginLayerChromium::updateContentsIfDirty):
+        * platform/graphics/chromium/PluginLayerChromium.h:
+        * platform/graphics/chromium/RenderSurfaceChromium.cpp:
+        (WebCore::RenderSurfaceChromium::SharedValues::SharedValues):
+        (WebCore::RenderSurfaceChromium::SharedValues::~SharedValues):
+        (WebCore::RenderSurfaceChromium::RenderSurfaceChromium):
+        (WebCore::RenderSurfaceChromium::cleanupResources):
+        (WebCore::RenderSurfaceChromium::prepareContentsTexture):
+        (WebCore::RenderSurfaceChromium::draw):
+        * platform/graphics/chromium/RenderSurfaceChromium.h:
+        (WebCore::RenderSurfaceChromium::SharedValues::shaderProgram):
+        (WebCore::RenderSurfaceChromium::SharedValues::shaderSamplerLocation):
+        (WebCore::RenderSurfaceChromium::SharedValues::shaderMatrixLocation):
+        (WebCore::RenderSurfaceChromium::SharedValues::shaderAlphaLocation):
+        (WebCore::RenderSurfaceChromium::SharedValues::initialized):
+        * platform/graphics/chromium/TextureManager.cpp: Added.
+        (WebCore::memoryUseBytes):
+        (WebCore::TextureManager::TextureManager):
+        (WebCore::TextureManager::getToken):
+        (WebCore::TextureManager::releaseToken):
+        (WebCore::TextureManager::hasTexture):
+        (WebCore::TextureManager::protectTexture):
+        (WebCore::TextureManager::unprotectTexture):
+        (WebCore::TextureManager::reduceMemoryToLimit):
+        (WebCore::TextureManager::addTexture):
+        (WebCore::TextureManager::removeTexture):
+        (WebCore::TextureManager::requestTexture):
+        * platform/graphics/chromium/TextureManager.h: Added.
+        (WebCore::TextureManager::create):
+        * platform/graphics/chromium/VideoLayerChromium.cpp:
+        (WebCore::VideoLayerChromium::updateContentsIfDirty):
+        * platform/graphics/chromium/VideoLayerChromium.h:
+        * platform/graphics/chromium/WebGLLayerChromium.cpp:
+        (WebCore::WebGLLayerChromium::updateContentsIfDirty):
+        * platform/graphics/chromium/WebGLLayerChromium.h:
+
 2010-12-09  Darin Adler  <darin at apple.com>
 
         Reviewed by Sam Weinig.
diff --git a/WebCore/WebCore.gypi b/WebCore/WebCore.gypi
index 8d4ed02..48aa06e 100644
--- a/WebCore/WebCore.gypi
+++ b/WebCore/WebCore.gypi
@@ -2582,6 +2582,8 @@
             'platform/graphics/chromium/LayerChromium.h',
             'platform/graphics/chromium/LayerRendererChromium.cpp',
             'platform/graphics/chromium/LayerRendererChromium.h',
+            'platform/graphics/chromium/LayerTexture.cpp',
+            'platform/graphics/chromium/LayerTexture.h',
             'platform/graphics/chromium/MediaPlayerPrivateChromium.h',
             'platform/graphics/chromium/PlatformIcon.h',
             'platform/graphics/chromium/PluginLayerChromium.cpp',
@@ -2590,6 +2592,8 @@
             'platform/graphics/chromium/RenderSurfaceChromium.cpp',
             'platform/graphics/chromium/SimpleFontDataChromiumWin.cpp',
             'platform/graphics/chromium/SimpleFontDataLinux.cpp',
+            'platform/graphics/chromium/TextureManager.cpp',
+            'platform/graphics/chromium/TextureManager.h',
             'platform/graphics/chromium/TransparencyWin.cpp',
             'platform/graphics/chromium/TransparencyWin.h',
             'platform/graphics/chromium/UniscribeHelper.cpp',
diff --git a/WebCore/platform/graphics/chromium/Canvas2DLayerChromium.cpp b/WebCore/platform/graphics/chromium/Canvas2DLayerChromium.cpp
index c2cde19..adf84a9 100644
--- a/WebCore/platform/graphics/chromium/Canvas2DLayerChromium.cpp
+++ b/WebCore/platform/graphics/chromium/Canvas2DLayerChromium.cpp
@@ -56,9 +56,9 @@ Canvas2DLayerChromium::~Canvas2DLayerChromium()
         layerRendererContext()->deleteTexture(m_textureId);
 }
 
-void Canvas2DLayerChromium::updateContents()
+void Canvas2DLayerChromium::updateContentsIfDirty()
 {
-    if (!m_drawingBuffer)
+    if (!m_contentsDirty || !m_drawingBuffer)
         return;
     if (m_textureChanged) { // We have to generate a new backing texture.
         GraphicsContext3D* context = layerRendererContext();
diff --git a/WebCore/platform/graphics/chromium/Canvas2DLayerChromium.h b/WebCore/platform/graphics/chromium/Canvas2DLayerChromium.h
index 0031229..44ef050 100644
--- a/WebCore/platform/graphics/chromium/Canvas2DLayerChromium.h
+++ b/WebCore/platform/graphics/chromium/Canvas2DLayerChromium.h
@@ -46,7 +46,7 @@ public:
     static PassRefPtr<Canvas2DLayerChromium> create(DrawingBuffer*, GraphicsLayerChromium* owner);
     virtual ~Canvas2DLayerChromium();
     virtual bool drawsContent() { return true; }
-    virtual void updateContents();
+    virtual void updateContentsIfDirty();
 
     void setTextureChanged();
     unsigned textureId() const;
diff --git a/WebCore/platform/graphics/chromium/ContentLayerChromium.cpp b/WebCore/platform/graphics/chromium/ContentLayerChromium.cpp
index 421abf3..d00faf8 100644
--- a/WebCore/platform/graphics/chromium/ContentLayerChromium.cpp
+++ b/WebCore/platform/graphics/chromium/ContentLayerChromium.cpp
@@ -36,6 +36,7 @@
 
 #include "GraphicsContext3D.h"
 #include "LayerRendererChromium.h"
+#include "LayerTexture.h"
 #include "RenderLayerBacking.h"
 
 #if PLATFORM(SKIA)
@@ -144,12 +145,7 @@ ContentLayerChromium::~ContentLayerChromium()
 void ContentLayerChromium::cleanupResources()
 {
     LayerChromium::cleanupResources();
-    if (layerRenderer()) {
-        if (m_contentsTexture) {
-            layerRenderer()->deleteLayerTexture(m_contentsTexture);
-            m_contentsTexture = 0;
-        }
-    }
+    m_contentsTexture.clear();
 }
 
 bool ContentLayerChromium::requiresClippedUpdateRect() const
@@ -163,33 +159,7 @@ bool ContentLayerChromium::requiresClippedUpdateRect() const
             || !layerRenderer()->checkTextureSize(m_bounds));
 }
 
-void ContentLayerChromium::calculateClippedUpdateRect(IntRect& dirtyRect, IntRect& drawRect) const
-{
-    // For the given layer size and content rect, calculate:
-    // 1) The minimal texture space rectangle to be uploaded, returned in dirtyRect.
-    // 2) The rectangle to draw this texture in relative to the target render surface, returned in drawRect.
-
-    ASSERT(m_targetRenderSurface);
-    const IntRect clipRect = m_targetRenderSurface->contentRect();
-
-    TransformationMatrix layerOriginTransform = drawTransform();
-    layerOriginTransform.translate3d(-0.5 * m_bounds.width(), -0.5 * m_bounds.height(), 0);
-
-    // For now we apply the large layer treatment only for layers that are either untransformed
-    // or are purely translated. Their matrix is expected to be invertible.
-    ASSERT(layerOriginTransform.isInvertible());
-
-    TransformationMatrix targetToLayerMatrix = layerOriginTransform.inverse();
-    IntRect clipRectInLayerCoords = targetToLayerMatrix.mapRect(clipRect);
-    clipRectInLayerCoords.intersect(IntRect(0, 0, m_bounds.width(), m_bounds.height()));
-
-    dirtyRect = clipRectInLayerCoords;
-
-    // Map back to the target surface coordinate system.
-    drawRect = layerOriginTransform.mapRect(dirtyRect);
-}
-
-void ContentLayerChromium::updateContents()
+void ContentLayerChromium::updateContentsIfDirty()
 {
     RenderLayerBacking* backing = static_cast<RenderLayerBacking*>(m_owner->client());
     if (!backing || backing->paintingGoesToWindow())
@@ -204,6 +174,7 @@ void ContentLayerChromium::updateContents()
     IntRect updateRect;
     IntSize requiredTextureSize;
     IntSize bitmapSize;
+    IntRect boundsRect(IntPoint(0, 0), m_bounds);
 
     // FIXME: Remove this test when tiled layers are implemented.
     if (requiresClippedUpdateRect()) {
@@ -215,33 +186,57 @@ void ContentLayerChromium::updateContents()
             return;
         }
 
-        calculateClippedUpdateRect(dirtyRect, m_largeLayerDrawRect);
-        if (!layerRenderer()->checkTextureSize(m_largeLayerDrawRect.size())) {
+        // Calculate the region of this layer that is currently visible.
+        const IntRect clipRect = m_targetRenderSurface->contentRect();
+
+        TransformationMatrix layerOriginTransform = drawTransform();
+        layerOriginTransform.translate3d(-0.5 * m_bounds.width(), -0.5 * m_bounds.height(), 0);
+
+        // For now we apply the large layer treatment only for layers that are either untransformed
+        // or are purely translated. Their matrix is expected to be invertible.
+        ASSERT(layerOriginTransform.isInvertible());
+
+        TransformationMatrix targetToLayerMatrix = layerOriginTransform.inverse();
+        IntRect visibleRectInLayerCoords = targetToLayerMatrix.mapRect(clipRect);
+        visibleRectInLayerCoords.intersect(IntRect(0, 0, m_bounds.width(), m_bounds.height()));
+
+        // For normal layers, the center of the texture corresponds with the center of the layer.
+        // In large layers the center of the texture is the center of the visible region so we have
+        // to keep track of the offset in order to render correctly.
+        IntRect visibleRectInSurfaceCoords = layerOriginTransform.mapRect(visibleRectInLayerCoords);
+        m_layerCenterInSurfaceCoords = FloatRect(visibleRectInSurfaceCoords).center();
+
+        // If this is still too large to render, then skip the layer completely.
+        if (!layerRenderer()->checkTextureSize(visibleRectInLayerCoords.size())) {
             m_skipsDraw = true;
             return;
         }
 
-        // If the portion of the large layer that's visible hasn't changed
-        // then we don't need to update it, _unless_ its contents have changed
-        // in which case we only update the dirty bits.
-        if (m_largeLayerDirtyRect == dirtyRect) {
-            if (!m_dirtyRect.intersects(dirtyRect))
-                return;
-            dirtyRect.intersect(IntRect(m_dirtyRect));
-            updateRect = dirtyRect;
-            requiredTextureSize = m_largeLayerDirtyRect.size();
-        } else {
-            m_largeLayerDirtyRect = dirtyRect;
-            requiredTextureSize = dirtyRect.size();
-            updateRect = IntRect(IntPoint(0, 0), dirtyRect.size());
-        }
+        // If the visible portion of the layer is different from the last upload, or if our backing
+        // texture has been evicted, then the whole layer is considered dirty.
+        if (visibleRectInLayerCoords != m_visibleRectInLayerCoords || !m_contentsTexture || !m_contentsTexture->isValid(requiredTextureSize, GraphicsContext3D::RGBA))
+            m_dirtyRect = boundsRect;
+        m_visibleRectInLayerCoords = visibleRectInLayerCoords;
+
+        // Calculate the portion of the dirty rectangle that is visible.  m_dirtyRect is in layer space.
+        IntRect visibleDirtyRectInLayerSpace = enclosingIntRect(m_dirtyRect);
+        visibleDirtyRectInLayerSpace.intersect(visibleRectInLayerCoords);
+
+        // What the rectangles mean:
+        //   dirtyRect: The region of this layer that will be updated.
+        //   updateRect: The region of the layer's texture that will be uploaded into.
+        //   requiredTextureSize: is the required size of this layer's texture.
+        dirtyRect = visibleDirtyRectInLayerSpace;
+        updateRect = dirtyRect;
+        IntSize visibleRectOffsetInLayerCoords(visibleRectInLayerCoords.x(), visibleRectInLayerCoords.y());
+        updateRect.move(-visibleRectOffsetInLayerCoords);
+        requiredTextureSize = visibleRectInLayerCoords.size();
     } else {
         dirtyRect = IntRect(m_dirtyRect);
-        IntRect boundsRect(IntPoint(0, 0), m_bounds);
         requiredTextureSize = m_bounds;
         // If the texture needs to be reallocated then we must redraw the entire
         // contents of the layer.
-        if (requiredTextureSize != m_allocatedTextureSize)
+        if (!m_contentsTexture || !m_contentsTexture->isValid(requiredTextureSize, GraphicsContext3D::RGBA))
             dirtyRect = boundsRect;
         else {
             // Clip the dirtyRect to the size of the layer to avoid drawing
@@ -310,36 +305,28 @@ void ContentLayerChromium::updateContents()
 #error "Need to implement for your platform."
 #endif
 
-    unsigned textureId = m_contentsTexture;
-    if (!textureId)
-        textureId = layerRenderer()->createLayerTexture();
-
     if (pixels)
-        updateTextureRect(pixels, bitmapSize, requiredTextureSize, updateRect, textureId);
+        updateTextureRect(pixels, requiredTextureSize, updateRect);
 }
 
-void ContentLayerChromium::updateTextureRect(void* pixels, const IntSize& bitmapSize, const IntSize& requiredTextureSize, const IntRect& updateRect, unsigned textureId)
+void ContentLayerChromium::updateTextureRect(void* pixels, const IntSize& requiredTextureSize, const IntRect& updateRect)
 {
     if (!pixels)
         return;
 
     GraphicsContext3D* context = layerRendererContext();
-    context->bindTexture(GraphicsContext3D::TEXTURE_2D, textureId);
+    if (!m_contentsTexture)
+        m_contentsTexture = LayerTexture::create(context, layerRenderer()->textureManager());
 
-    // If the texture id or size changed since last time then we need to tell GL
-    // to re-allocate a texture.
-    if (m_contentsTexture != textureId || requiredTextureSize != m_allocatedTextureSize) {
-        ASSERT(bitmapSize == requiredTextureSize);
-        GLC(context, context->texImage2D(GraphicsContext3D::TEXTURE_2D, 0, GraphicsContext3D::RGBA, requiredTextureSize.width(), requiredTextureSize.height(), 0, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, pixels));
-
-        m_contentsTexture = textureId;
-        m_allocatedTextureSize = requiredTextureSize;
-    } else {
-        ASSERT(updateRect.width() <= m_allocatedTextureSize.width() && updateRect.height() <= m_allocatedTextureSize.height());
-        ASSERT(updateRect.width() == bitmapSize.width() && updateRect.height() == bitmapSize.height());
-        GLC(context, context->texSubImage2D(GraphicsContext3D::TEXTURE_2D, 0, updateRect.x(), updateRect.y(), updateRect.width(), updateRect.height(), GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, pixels));
+    if (!m_contentsTexture->reserve(requiredTextureSize, GraphicsContext3D::RGBA)) {
+        m_skipsDraw = true;
+        return;
     }
 
+    m_contentsTexture->bindTexture();
+
+    GLC(context, context->texSubImage2D(GraphicsContext3D::TEXTURE_2D, 0, updateRect.x(), updateRect.y(), updateRect.width(), updateRect.height(), GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, pixels));
+
     m_dirtyRect.setSize(FloatSize());
     // Large layers always stay dirty, because they need to update when the content rect changes.
     m_contentsDirty = requiresClippedUpdateRect();
@@ -351,22 +338,22 @@ void ContentLayerChromium::draw()
         return;
 
     ASSERT(layerRenderer());
+
     const ContentLayerChromium::SharedValues* sv = layerRenderer()->contentLayerSharedValues();
     ASSERT(sv && sv->initialized());
     GraphicsContext3D* context = layerRendererContext();
     GLC(context, context->activeTexture(GraphicsContext3D::TEXTURE0));
-    GLC(context, context->bindTexture(GraphicsContext3D::TEXTURE_2D, m_contentsTexture));
+    m_contentsTexture->bindTexture();
     layerRenderer()->useShader(sv->contentShaderProgram());
     GLC(context, context->uniform1i(sv->shaderSamplerLocation(), 0));
 
     if (requiresClippedUpdateRect()) {
         float m43 = drawTransform().m43();
         TransformationMatrix transform;
-        FloatPoint floatCenter = FloatRect(m_largeLayerDrawRect).center();
-        transform.translate3d(floatCenter.x(), floatCenter.y(), m43);
+        transform.translate3d(m_layerCenterInSurfaceCoords.x(), m_layerCenterInSurfaceCoords.y(), m43);
         drawTexturedQuad(context, layerRenderer()->projectionMatrix(),
-                         transform, m_largeLayerDrawRect.width(),
-                         m_largeLayerDrawRect.height(), drawOpacity(),
+                         transform, m_visibleRectInLayerCoords.width(),
+                         m_visibleRectInLayerCoords.height(), drawOpacity(),
                          sv->shaderMatrixLocation(), sv->shaderAlphaLocation());
     } else {
         drawTexturedQuad(context, layerRenderer()->projectionMatrix(),
@@ -374,6 +361,7 @@ void ContentLayerChromium::draw()
                          drawOpacity(), sv->shaderMatrixLocation(),
                          sv->shaderAlphaLocation());
     }
+    m_contentsTexture->unreserve();
 }
 
 }
diff --git a/WebCore/platform/graphics/chromium/ContentLayerChromium.h b/WebCore/platform/graphics/chromium/ContentLayerChromium.h
index 32c2c49..dc1630b 100644
--- a/WebCore/platform/graphics/chromium/ContentLayerChromium.h
+++ b/WebCore/platform/graphics/chromium/ContentLayerChromium.h
@@ -35,9 +35,12 @@
 #if USE(ACCELERATED_COMPOSITING)
 
 #include "LayerChromium.h"
+#include "TextureManager.h"
 
 namespace WebCore {
 
+class LayerTexture;
+
 // A Layer that requires a GraphicsContext to render its contents.
 class ContentLayerChromium : public LayerChromium {
     friend class LayerRendererChromium;
@@ -46,7 +49,7 @@ public:
 
     virtual ~ContentLayerChromium();
 
-    virtual void updateContents();
+    virtual void updateContentsIfDirty();
     virtual void draw();
     virtual bool drawsContent() { return m_owner && m_owner->drawsContent(); }
 
@@ -74,22 +77,20 @@ public:
     };
 
 protected:
-    ContentLayerChromium(GraphicsLayerChromium* owner);
+    explicit ContentLayerChromium(GraphicsLayerChromium* owner);
 
-    void updateTextureRect(void* pixels, const IntSize& bitmapSize, const IntSize& requiredTextureSize,
-                           const IntRect& updateRect, unsigned textureId);
+    void updateTextureRect(void* pixels, const IntSize& requiredTextureSize, const IntRect& updateRect);
 
     virtual void cleanupResources();
     bool requiresClippedUpdateRect() const;
 
-    unsigned m_contentsTexture;
-    IntSize m_allocatedTextureSize;
+    OwnPtr<LayerTexture> m_contentsTexture;
     bool m_skipsDraw;
 
 private:
-    void calculateClippedUpdateRect(IntRect& dirtyRect, IntRect& drawRect) const;
-    IntRect m_largeLayerDrawRect;
-    IntRect m_largeLayerDirtyRect;
+
+    IntRect m_visibleRectInLayerCoords;
+    FloatPoint m_layerCenterInSurfaceCoords;
 };
 
 }
diff --git a/WebCore/platform/graphics/chromium/ImageLayerChromium.cpp b/WebCore/platform/graphics/chromium/ImageLayerChromium.cpp
index adcbb82..cd299c1 100644
--- a/WebCore/platform/graphics/chromium/ImageLayerChromium.cpp
+++ b/WebCore/platform/graphics/chromium/ImageLayerChromium.cpp
@@ -36,6 +36,7 @@
 
 #include "Image.h"
 #include "LayerRendererChromium.h"
+#include "LayerTexture.h"
 
 #if PLATFORM(SKIA)
 #include "NativeImageSkia.h"
@@ -71,7 +72,7 @@ void ImageLayerChromium::setContents(Image* contents)
     setNeedsDisplay();
 }
 
-void ImageLayerChromium::updateContents()
+void ImageLayerChromium::updateContentsIfDirty()
 {
     ASSERT(layerRenderer());
 
@@ -79,12 +80,11 @@ void ImageLayerChromium::updateContents()
     if (requiresClippedUpdateRect()) {
         // Use the base version of updateContents which draws a subset of the
         // image to a bitmap, as the pixel contents can't be uploaded directly.
-        ContentLayerChromium::updateContents();
+        ContentLayerChromium::updateContentsIfDirty();
         return;
     }
 
     void* pixels = 0;
-    IntSize requiredTextureSize;
     IntSize bitmapSize;
 
     NativeImagePtr nativeImage = m_contents->nativeImageForCurrentFrame();
@@ -93,22 +93,33 @@ void ImageLayerChromium::updateContents()
     // The layer contains an Image.
     NativeImageSkia* skiaImage = static_cast<NativeImageSkia*>(nativeImage);
     const SkBitmap* skiaBitmap = skiaImage;
-    requiredTextureSize = IntSize(skiaBitmap->width(), skiaBitmap->height());
+    bitmapSize = IntSize(skiaBitmap->width(), skiaBitmap->height());
     ASSERT(skiaBitmap);
+#elif PLATFORM(CG)
+    // NativeImagePtr is a CGImageRef on Mac OS X.
+    int width = CGImageGetWidth(nativeImage);
+    int height = CGImageGetHeight(nativeImage);
+    bitmapSize = IntSize(width, height);
+#endif
+
+    // Clip the dirty rect to the bitmap dimensions.
+    IntRect dirtyRect(m_dirtyRect);
+    dirtyRect.intersect(IntRect(IntPoint(0, 0), bitmapSize));
+
+    if (!m_contentsTexture || !m_contentsTexture->isValid(bitmapSize, GraphicsContext3D::RGBA))
+        dirtyRect = IntRect(IntPoint(0, 0), bitmapSize);
+    else if (!m_contentsDirty) {
+        m_contentsTexture->reserve(bitmapSize, GraphicsContext3D::RGBA);
+        return;
+    }
 
+#if PLATFORM(SKIA)
     SkAutoLockPixels lock(*skiaBitmap);
     SkBitmap::Config skiaConfig = skiaBitmap->config();
     // FIXME: do we need to support more image configurations?
-    if (skiaConfig == SkBitmap::kARGB_8888_Config) {
+    if (skiaConfig == SkBitmap::kARGB_8888_Config)
         pixels = skiaBitmap->getPixels();
-        bitmapSize = IntSize(skiaBitmap->width(), skiaBitmap->height());
-    }
 #elif PLATFORM(CG)
-    // NativeImagePtr is a CGImageRef on Mac OS X.
-    int width = CGImageGetWidth(nativeImage);
-    int height = CGImageGetHeight(nativeImage);
-    requiredTextureSize = IntSize(width, height);
-    bitmapSize = requiredTextureSize;
     // FIXME: we should get rid of this temporary copy where possible.
     int tempRowBytes = width * 4;
     Vector<uint8_t> tempVector;
@@ -145,16 +156,8 @@ void ImageLayerChromium::updateContents()
 #error "Need to implement for your platform."
 #endif
 
-    unsigned textureId = m_contentsTexture;
-    if (!textureId)
-        textureId = layerRenderer()->createLayerTexture();
-
-    // Clip the dirty rect to the bitmap dimensions.
-    IntRect dirtyRect(m_dirtyRect);
-    dirtyRect.intersect(IntRect(IntPoint(0, 0), bitmapSize));
-
     if (pixels)
-        updateTextureRect(pixels, bitmapSize, requiredTextureSize,  dirtyRect, textureId);
+        updateTextureRect(pixels, bitmapSize,  dirtyRect);
 }
 
 }
diff --git a/WebCore/platform/graphics/chromium/ImageLayerChromium.h b/WebCore/platform/graphics/chromium/ImageLayerChromium.h
index b91f04a..a5c1450 100644
--- a/WebCore/platform/graphics/chromium/ImageLayerChromium.h
+++ b/WebCore/platform/graphics/chromium/ImageLayerChromium.h
@@ -49,7 +49,7 @@ class ImageLayerChromium : public ContentLayerChromium {
 public:
     static PassRefPtr<ImageLayerChromium> create(GraphicsLayerChromium* owner = 0);
 
-    virtual void updateContents();
+    virtual void updateContentsIfDirty();
     virtual bool drawsContent() { return m_contents; }
 
     void setContents(Image* image);
diff --git a/WebCore/platform/graphics/chromium/LayerChromium.h b/WebCore/platform/graphics/chromium/LayerChromium.h
index 86f3580..ac95285 100644
--- a/WebCore/platform/graphics/chromium/LayerChromium.h
+++ b/WebCore/platform/graphics/chromium/LayerChromium.h
@@ -151,15 +151,13 @@ public:
 
     void setOwner(GraphicsLayerChromium* owner) { m_owner = owner; }
 
-    bool contentsDirty() { return m_contentsDirty; }
-
     // Returns the rect containtaining this layer in the current view's coordinate system.
     const IntRect getDrawRect() const;
 
     // These methods typically need to be overwritten by derived classes.
     virtual bool drawsContent() { return false; }
-    virtual void updateContents() { };
-    virtual void draw() { };
+    virtual void updateContentsIfDirty() { }
+    virtual void draw() { }
 
     void drawDebugBorder();
 
@@ -197,6 +195,12 @@ public:
 
     LayerRendererChromium* layerRenderer() const { return m_layerRenderer.get(); }
 
+    static unsigned createShaderProgram(GraphicsContext3D*, const char* vertexShaderSource, const char* fragmentShaderSource);
+
+    static void drawTexturedQuad(GraphicsContext3D*, const TransformationMatrix& projectionMatrix, const TransformationMatrix& layerMatrix,
+                                 float width, float height, float opacity,
+                                 int matrixLocation, int alphaLocation);
+
 protected:
     GraphicsLayerChromium* m_owner;
     LayerChromium(GraphicsLayerChromium* owner);
@@ -211,14 +215,8 @@ protected:
     // Returns true if any of the layer's descendants has content to draw.
     bool descendantsDrawContent();
 
-    static void drawTexturedQuad(GraphicsContext3D*, const TransformationMatrix& projectionMatrix, const TransformationMatrix& layerMatrix,
-                                 float width, float height, float opacity,
-                                 int matrixLocation, int alphaLocation);
-
     static void toGLMatrix(float*, const TransformationMatrix&);
 
-    static unsigned createShaderProgram(GraphicsContext3D*, const char* vertexShaderSource, const char* fragmentShaderSource);
-
     IntSize m_bounds;
     FloatRect m_dirtyRect;
     bool m_contentsDirty;
diff --git a/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp b/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp
index 1bdea85..6d5f642 100644
--- a/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp
+++ b/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp
@@ -37,7 +37,9 @@
 #include "Canvas2DLayerChromium.h"
 #include "GraphicsContext3D.h"
 #include "LayerChromium.h"
+#include "LayerTexture.h"
 #include "NotImplemented.h"
+#include "TextureManager.h"
 #include "WebGLLayerChromium.h"
 #if PLATFORM(SKIA)
 #include "NativeImageSkia.h"
@@ -48,6 +50,9 @@
 
 namespace WebCore {
 
+// FIXME: Make this limit adjustable and give it a useful value.
+static size_t textureMemoryLimitBytes = 64 * 1024 * 1024;
+
 static TransformationMatrix orthoMatrix(float left, float right, float bottom, float top)
 {
     float deltaX = right - left;
@@ -98,7 +103,6 @@ LayerRendererChromium::LayerRendererChromium(PassRefPtr<GraphicsContext3D> conte
     : m_rootLayerTextureId(0)
     , m_rootLayerTextureWidth(0)
     , m_rootLayerTextureHeight(0)
-    , m_textureLayerShaderProgram(0)
     , m_rootLayer(0)
     , m_scrollPosition(IntPoint(-1, -1))
     , m_currentShader(0)
@@ -164,7 +168,7 @@ void LayerRendererChromium::setRootLayerCanvasSize(const IntSize& size)
 void LayerRendererChromium::useShader(unsigned programId)
 {
     if (programId != m_currentShader) {
-        GLC(m_context, m_context->useProgram(programId));
+        GLC(m_context.get(), m_context->useProgram(programId));
         m_currentShader = programId;
     }
 }
@@ -173,7 +177,7 @@ void LayerRendererChromium::useShader(unsigned programId)
 // 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, 
+void LayerRendererChromium::prepareToDrawLayers(const IntRect& visibleRect, const IntRect& contentRect,
                                                 const IntPoint& scrollPosition)
 {
     ASSERT(m_hardwareCompositing);
@@ -183,8 +187,8 @@ void LayerRendererChromium::prepareToDrawLayers(const IntRect& visibleRect, cons
 
     makeContextCurrent();
 
-    GLC(m_context, m_context->bindTexture(GraphicsContext3D::TEXTURE_2D, m_rootLayerTextureId));
-    
+    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
@@ -196,7 +200,7 @@ void LayerRendererChromium::prepareToDrawLayers(const IntRect& visibleRect, cons
         m_rootLayerTextureWidth = visibleRectWidth;
         m_rootLayerTextureHeight = visibleRectHeight;
 
-        GLC(m_context, m_context->texImage2D(GraphicsContext3D::TEXTURE_2D, 0, GraphicsContext3D::RGBA, m_rootLayerTextureWidth, m_rootLayerTextureHeight, 0, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, 0));
+        GLC(m_context.get(), m_context->texImage2D(GraphicsContext3D::TEXTURE_2D, 0, GraphicsContext3D::RGBA, m_rootLayerTextureWidth, m_rootLayerTextureHeight, 0, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, 0));
 
         // Reset the current render surface to force an update of the viewport and
         // projection matrix next time useRenderSurface is called.
@@ -208,17 +212,17 @@ void LayerRendererChromium::prepareToDrawLayers(const IntRect& visibleRect, cons
     }
 
     // The GL viewport covers the entire visible area, including the scrollbars.
-    GLC(m_context, m_context->viewport(0, 0, visibleRectWidth, visibleRectHeight));
+    GLC(m_context.get(), m_context->viewport(0, 0, visibleRectWidth, visibleRectHeight));
 
     // Bind the common vertex attributes used for drawing all the layers.
     LayerChromium::prepareForDraw(layerSharedValues());
 
     // FIXME: These calls can be made once, when the compositor context is initialized.
-    GLC(m_context, m_context->disable(GraphicsContext3D::DEPTH_TEST));
-    GLC(m_context, m_context->disable(GraphicsContext3D::CULL_FACE));
+    GLC(m_context.get(), m_context->disable(GraphicsContext3D::DEPTH_TEST));
+    GLC(m_context.get(), m_context->disable(GraphicsContext3D::CULL_FACE));
 
-    // Blending disabled by default. Root layer alpha channel on Windows is incorrect when Skia uses ClearType. 
-    GLC(m_context, m_context->disable(GraphicsContext3D::BLEND)); 
+    // 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;
@@ -244,13 +248,14 @@ void LayerRendererChromium::prepareToDrawLayers(const IntRect& visibleRect, cons
             0.5 * visibleRect.height() + scrollDelta.y(), 0);
         scrolledLayerMatrix.scale3d(1, -1, 1);
 
-        useShader(m_textureLayerShaderProgram);
-        GLC(m_context, m_context->uniform1i(m_textureLayerShaderSamplerLocation, 0));
+        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,
-                                        m_textureLayerShaderMatrixLocation, m_textureLayerShaderAlphaLocation);
+                                        rsv->shaderMatrixLocation(), rsv->shaderAlphaLocation());
 
-        GLC(m_context, m_context->copyTexSubImage2D(GraphicsContext3D::TEXTURE_2D, 0, 0, 0, 0, 0, contentRect.width(), contentRect.height()));
+        GLC(m_context.get(), m_context->copyTexSubImage2D(GraphicsContext3D::TEXTURE_2D, 0, 0, 0, 0, 0, contentRect.width(), contentRect.height()));
     }
 
     m_scrollPosition = scrollPosition;
@@ -263,7 +268,7 @@ void LayerRendererChromium::updateRootLayerTextureRect(const IntRect& updateRect
     if (!m_rootLayer)
         return;
 
-    GLC(m_context, m_context->bindTexture(GraphicsContext3D::TEXTURE_2D, m_rootLayerTextureId));
+    GLC(m_context.get(), m_context->bindTexture(GraphicsContext3D::TEXTURE_2D, m_rootLayerTextureId));
 
     // Update the root layer texture.
     ASSERT((updateRect.right()  <= m_rootLayerTextureWidth)
@@ -282,7 +287,7 @@ void LayerRendererChromium::updateRootLayerTextureRect(const IntRect& updateRect
 #error "Need to implement for your platform."
 #endif
     // Copy the contents of the updated rect to the root layer texture.
-    GLC(m_context, m_context->texSubImage2D(GraphicsContext3D::TEXTURE_2D, 0, updateRect.x(), updateRect.y(), updateRect.width(), updateRect.height(), GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, pixels));
+    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)
@@ -300,22 +305,22 @@ 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, m_context->bindTexture(GraphicsContext3D::TEXTURE_2D, m_rootLayerTextureId));
+    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, m_context->uniform1i(contentLayerValues->shaderSamplerLocation(), 0));
+    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, m_context->colorMask(true, true, true, false));
+    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, m_context->colorMask(true, true, true, true));
+    GLC(m_context.get(), m_context->colorMask(true, true, true, true));
 
     // Set the root visible/content rects --- used by subsequent drawLayers calls.
     m_rootVisibleRect = visibleRect;
@@ -336,9 +341,9 @@ void LayerRendererChromium::drawLayers(const IntRect& visibleRect, const IntRect
 
     // The shader used to render layers returns pre-multiplied alpha colors
     // so we need to send the blending mode appropriately.
-    GLC(m_context, m_context->enable(GraphicsContext3D::BLEND));
-    GLC(m_context, m_context->blendFunc(GraphicsContext3D::ONE, GraphicsContext3D::ONE_MINUS_SRC_ALPHA));
-    GLC(m_context, m_context->enable(GraphicsContext3D::SCISSOR_TEST));
+    GLC(m_context.get(), m_context->enable(GraphicsContext3D::BLEND));
+    GLC(m_context.get(), m_context->blendFunc(GraphicsContext3D::ONE, GraphicsContext3D::ONE_MINUS_SRC_ALPHA));
+    GLC(m_context.get(), m_context->enable(GraphicsContext3D::SCISSOR_TEST));
 
     // Update the contents of the render surfaces. We traverse the array from
     // back to front to guarantee that nested render surfaces get rendered in the
@@ -352,22 +357,23 @@ void LayerRendererChromium::drawLayers(const IntRect& visibleRect, const IntRect
         if (!renderSurfaceLayer->m_renderSurface->m_layerList.size())
             continue;
 
-        useRenderSurface(renderSurfaceLayer->m_renderSurface.get());
-        if (renderSurfaceLayer != m_rootLayer) {
-            GLC(m_context, m_context->disable(GraphicsContext3D::SCISSOR_TEST));
-            GLC(m_context, m_context->clearColor(0, 0, 0, 0));
-            GLC(m_context, m_context->clear(GraphicsContext3D::COLOR_BUFFER_BIT));
-            GLC(m_context, m_context->enable(GraphicsContext3D::SCISSOR_TEST));
+        if (useRenderSurface(renderSurfaceLayer->m_renderSurface.get())) {
+            if (renderSurfaceLayer != m_rootLayer) {
+                GLC(m_context.get(), m_context->disable(GraphicsContext3D::SCISSOR_TEST));
+                GLC(m_context.get(), m_context->clearColor(0, 0, 0, 0));
+                GLC(m_context.get(), m_context->clear(GraphicsContext3D::COLOR_BUFFER_BIT));
+                GLC(m_context.get(), m_context->enable(GraphicsContext3D::SCISSOR_TEST));
+            }
+
+            Vector<LayerChromium*>& layerList = renderSurfaceLayer->m_renderSurface->m_layerList;
+            ASSERT(layerList.size());
+            for (unsigned layerIndex = 0; layerIndex < layerList.size(); ++layerIndex)
+                drawLayer(layerList[layerIndex], renderSurfaceLayer->m_renderSurface.get());
         }
-
-        Vector<LayerChromium*>& layerList = renderSurfaceLayer->m_renderSurface->m_layerList;
-        ASSERT(layerList.size());
-        for (unsigned layerIndex = 0; layerIndex < layerList.size(); ++layerIndex)
-            drawLayer(layerList[layerIndex], renderSurfaceLayer->m_renderSurface.get());
     }
 
-    GLC(m_context, m_context->disable(GraphicsContext3D::SCISSOR_TEST));
-    GLC(m_context, m_context->disable(GraphicsContext3D::BLEND));
+    GLC(m_context.get(), m_context->disable(GraphicsContext3D::SCISSOR_TEST));
+    GLC(m_context.get(), m_context->disable(GraphicsContext3D::BLEND));
 }
 
 void LayerRendererChromium::finish()
@@ -394,7 +400,7 @@ void LayerRendererChromium::getFramebufferPixels(void *pixels, const IntRect& re
 
     makeContextCurrent();
 
-    GLC(m_context, m_context->readPixels(rect.x(), rect.y(), rect.width(), rect.height(),
+    GLC(m_context.get(), m_context->readPixels(rect.x(), rect.y(), rect.width(), rect.height(),
                                          GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, pixels));
 }
 
@@ -402,14 +408,14 @@ void LayerRendererChromium::getFramebufferPixels(void *pixels, const IntRect& re
 unsigned LayerRendererChromium::createLayerTexture()
 {
     unsigned textureId = 0;
-    GLC(m_context, textureId = m_context->createTexture());
-    GLC(m_context, m_context->bindTexture(GraphicsContext3D::TEXTURE_2D, textureId));
+    GLC(m_context.get(), textureId = m_context->createTexture());
+    GLC(m_context.get(), m_context->bindTexture(GraphicsContext3D::TEXTURE_2D, textureId));
     // Do basic linear filtering on resize.
-    GLC(m_context, m_context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MIN_FILTER, GraphicsContext3D::LINEAR));
-    GLC(m_context, m_context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MAG_FILTER, GraphicsContext3D::LINEAR));
+    GLC(m_context.get(), m_context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MIN_FILTER, GraphicsContext3D::LINEAR));
+    GLC(m_context.get(), m_context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MAG_FILTER, GraphicsContext3D::LINEAR));
     // NPOT textures in GL ES only work when the wrap mode is set to GraphicsContext3D::CLAMP_TO_EDGE.
-    GLC(m_context, m_context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_WRAP_S, GraphicsContext3D::CLAMP_TO_EDGE));
-    GLC(m_context, m_context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_WRAP_T, GraphicsContext3D::CLAMP_TO_EDGE));
+    GLC(m_context.get(), m_context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_WRAP_S, GraphicsContext3D::CLAMP_TO_EDGE));
+    GLC(m_context.get(), m_context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_WRAP_T, GraphicsContext3D::CLAMP_TO_EDGE));
     return textureId;
 }
 
@@ -418,7 +424,7 @@ void LayerRendererChromium::deleteLayerTexture(unsigned textureId)
     if (!textureId)
         return;
 
-    GLC(m_context, m_context->deleteTexture(textureId));
+    GLC(m_context.get(), m_context->deleteTexture(textureId));
 }
 
 // Returns true if any part of the layer falls within the visibleRect
@@ -507,7 +513,7 @@ void LayerRendererChromium::updateLayersRecursive(LayerChromium* layer, const Tr
         // Layer's opacity will be applied when drawing the render surface.
         renderSurface->m_drawOpacity = layer->opacity();
         if (layer->superlayer()->preserves3D())
-            renderSurface->m_drawOpacity *= layer->superlayer()->m_drawOpacity;
+            renderSurface->m_drawOpacity *= layer->superlayer()->drawOpacity();
         layer->m_drawOpacity = 1;
 
         TransformationMatrix layerOriginTransform = combinedTransform;
@@ -598,7 +604,7 @@ void LayerRendererChromium::updateLayersRecursive(LayerChromium* layer, const Tr
 
         if (sublayer->m_renderSurface) {
             RenderSurfaceChromium* sublayerRenderSurface = sublayer->m_renderSurface.get();
-            const IntRect& contentRect = sublayerRenderSurface->m_contentRect;
+            const IntRect& contentRect = sublayerRenderSurface->contentRect();
             FloatRect sublayerRect(-0.5 * contentRect.width(), -0.5 * contentRect.height(),
                                    contentRect.width(), contentRect.height());
             layer->m_drawableContentRect.unite(enclosingIntRect(sublayerRenderSurface->m_drawTransform.mapRect(sublayerRect)));
@@ -664,17 +670,17 @@ bool LayerRendererChromium::useRenderSurface(RenderSurfaceChromium* renderSurfac
     m_currentRenderSurface = renderSurface;
 
     if (renderSurface == m_defaultRenderSurface) {
-        GLC(m_context, m_context->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, 0));
+        GLC(m_context.get(), m_context->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, 0));
         setDrawViewportRect(renderSurface->m_contentRect, true);
         return true;
     }
 
-    GLC(m_context, m_context->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, m_offscreenFramebufferId));
+    GLC(m_context.get(), m_context->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, m_offscreenFramebufferId));
 
-    renderSurface->prepareContentsTexture();
+    if (!renderSurface->prepareContentsTexture())
+        return false;
 
-    GLC(m_context, m_context->framebufferTexture2D(GraphicsContext3D::FRAMEBUFFER, GraphicsContext3D::COLOR_ATTACHMENT0,
-                                                   GraphicsContext3D::TEXTURE_2D, renderSurface->m_contentsTextureId, 0));
+    renderSurface->m_contentsTexture->framebufferTexture2D();
 
 #if !defined ( NDEBUG )
     if (m_context->checkFramebufferStatus(GraphicsContext3D::FRAMEBUFFER) != GraphicsContext3D::FRAMEBUFFER_COMPLETE) {
@@ -690,15 +696,7 @@ bool LayerRendererChromium::useRenderSurface(RenderSurfaceChromium* renderSurfac
 void LayerRendererChromium::drawLayer(LayerChromium* layer, RenderSurfaceChromium* targetSurface)
 {
     if (layer->m_renderSurface && layer->m_renderSurface != targetSurface) {
-        GLC(m_context, m_context->bindTexture(GraphicsContext3D::TEXTURE_2D, layer->m_renderSurface->m_contentsTextureId));
-        useShader(m_textureLayerShaderProgram);
-
-        setScissorToRect(layer->m_renderSurface->m_scissorRect);
-
-        IntRect contentRect = layer->m_renderSurface->m_contentRect;
-        LayerChromium::drawTexturedQuad(m_context.get(), m_projectionMatrix, layer->m_renderSurface->m_drawTransform,
-                                        contentRect.width(), contentRect.height(), layer->m_renderSurface->m_drawOpacity,
-                                        m_textureLayerShaderMatrixLocation, m_textureLayerShaderAlphaLocation);
+        layer->m_renderSurface->draw();
         return;
     }
 
@@ -721,12 +719,8 @@ void LayerRendererChromium::drawLayer(LayerChromium* layer, RenderSurfaceChromiu
 
     if (layer->drawsContent()) {
         // Update the contents of the layer if necessary.
-        if (layer->contentsDirty()) {
-            // Update the backing texture contents for any dirty portion of the layer.
-            layer->updateContents();
-            m_context->makeContextCurrent();
-        }
-
+        layer->updateContentsIfDirty();
+        m_context->makeContextCurrent();
         layer->draw();
     }
 
@@ -748,7 +742,7 @@ void LayerRendererChromium::setScissorToRect(const IntRect& scissorRect)
         scissorY = m_currentRenderSurface->m_contentRect.height() - (scissorRect.bottom() - m_currentRenderSurface->m_contentRect.y());
     else
         scissorY = scissorRect.y() - m_currentRenderSurface->m_contentRect.y();
-    GLC(m_context, m_context->scissor(scissorX, scissorY, scissorRect.width(), scissorRect.height()));
+    GLC(m_context.get(), m_context->scissor(scissorX, scissorY, scissorRect.width(), scissorRect.height()));
 }
 
 bool LayerRendererChromium::makeContextCurrent()
@@ -774,7 +768,7 @@ void LayerRendererChromium::setDrawViewportRect(const IntRect& drawRect, bool fl
         m_projectionMatrix = orthoMatrix(drawRect.x(), drawRect.right(), drawRect.bottom(), drawRect.y());
     else
         m_projectionMatrix = orthoMatrix(drawRect.x(), drawRect.right(), drawRect.y(), drawRect.bottom());
-    GLC(m_context, m_context->viewport(0, 0, drawRect.width(), drawRect.height()));
+    GLC(m_context.get(), m_context->viewport(0, 0, drawRect.width(), drawRect.height()));
 }
 
 
@@ -789,46 +783,6 @@ bool LayerRendererChromium::initializeSharedObjects()
 {
     makeContextCurrent();
 
-    // The following program composites layers whose contents are the results of a previous
-    // render operation and therefore doesn't perform any color swizzling. It is used
-    // in scrolling and for compositing offscreen textures.
-    char textureLayerVertexShaderString[] =
-        "attribute vec4 a_position;   \n"
-        "attribute vec2 a_texCoord;   \n"
-        "uniform mat4 matrix;         \n"
-        "varying vec2 v_texCoord;     \n"
-        "void main()                  \n"
-        "{                            \n"
-        "  gl_Position = matrix * a_position; \n"
-        "  v_texCoord = a_texCoord;   \n"
-        "}                            \n";
-    char textureLayerFragmentShaderString[] =
-        "precision mediump float;                            \n"
-        "varying vec2 v_texCoord;                            \n"
-        "uniform sampler2D s_texture;                        \n"
-        "uniform float alpha;                                \n"
-        "void main()                                         \n"
-        "{                                                   \n"
-        "  vec4 texColor = texture2D(s_texture, v_texCoord); \n"
-        "  gl_FragColor = vec4(texColor.x, texColor.y, texColor.z, texColor.w) * alpha; \n"
-        "}                                                   \n";
-
-    m_textureLayerShaderProgram = LayerChromium::createShaderProgram(m_context.get(), textureLayerVertexShaderString, textureLayerFragmentShaderString);
-    if (!m_textureLayerShaderProgram) {
-        LOG_ERROR("LayerRendererChromium: Failed to create scroll shader program");
-        cleanupSharedObjects();
-        return false;
-    }
-
-    GLC(m_context, m_textureLayerShaderSamplerLocation = m_context->getUniformLocation(m_textureLayerShaderProgram, "s_texture"));
-    GLC(m_context, m_textureLayerShaderMatrixLocation = m_context->getUniformLocation(m_textureLayerShaderProgram, "matrix"));
-    GLC(m_context, m_textureLayerShaderAlphaLocation = m_context->getUniformLocation(m_textureLayerShaderProgram, "alpha"));
-    if (m_textureLayerShaderSamplerLocation == -1 || m_textureLayerShaderMatrixLocation == -1 || m_textureLayerShaderAlphaLocation == -1) {
-        LOG_ERROR("Failed to initialize texture layer shader.");
-        cleanupSharedObjects();
-        return false;
-    }
-
     // Create a texture object to hold the contents of the root layer.
     m_rootLayerTextureId = createLayerTexture();
     if (!m_rootLayerTextureId) {
@@ -838,29 +792,31 @@ bool LayerRendererChromium::initializeSharedObjects()
     }
     // 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, m_context->bindTexture(GraphicsContext3D::TEXTURE_2D, m_rootLayerTextureId));
-    GLC(m_context, m_context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MIN_FILTER, GraphicsContext3D::NEAREST));
-    GLC(m_context, m_context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MAG_FILTER, GraphicsContext3D::NEAREST));
+    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, m_context->getIntegerv(GraphicsContext3D::MAX_TEXTURE_SIZE, &m_maxTextureSize));
+    GLC(m_context.get(), m_context->getIntegerv(GraphicsContext3D::MAX_TEXTURE_SIZE, &m_maxTextureSize));
 
     // Create an FBO for doing offscreen rendering.
-    GLC(m_context, m_offscreenFramebufferId = m_context->createFramebuffer());
+    GLC(m_context.get(), m_offscreenFramebufferId = m_context->createFramebuffer());
 
     m_layerSharedValues = adoptPtr(new LayerChromium::SharedValues(m_context.get()));
     m_contentLayerSharedValues = adoptPtr(new ContentLayerChromium::SharedValues(m_context.get()));
     m_canvasLayerSharedValues = adoptPtr(new CanvasLayerChromium::SharedValues(m_context.get()));
     m_videoLayerSharedValues = adoptPtr(new VideoLayerChromium::SharedValues(m_context.get()));
     m_pluginLayerSharedValues = adoptPtr(new PluginLayerChromium::SharedValues(m_context.get()));
+    m_renderSurfaceSharedValues = adoptPtr(new RenderSurfaceChromium::SharedValues(m_context.get()));
 
     if (!m_layerSharedValues->initialized() || !m_contentLayerSharedValues->initialized() || !m_canvasLayerSharedValues->initialized()
-        || !m_videoLayerSharedValues->initialized() || !m_pluginLayerSharedValues->initialized()) {
+        || !m_videoLayerSharedValues->initialized() || !m_pluginLayerSharedValues->initialized() || !m_renderSurfaceSharedValues->initialized()) {
         cleanupSharedObjects();
         return false;
     }
 
+    m_textureManager = TextureManager::create(m_context.get(), textureMemoryLimitBytes, m_maxTextureSize);
     return true;
 }
 
@@ -873,11 +829,7 @@ void LayerRendererChromium::cleanupSharedObjects()
     m_canvasLayerSharedValues.clear();
     m_videoLayerSharedValues.clear();
     m_pluginLayerSharedValues.clear();
-
-    if (m_textureLayerShaderProgram) {
-        GLC(m_context, m_context->deleteProgram(m_textureLayerShaderProgram));
-        m_textureLayerShaderProgram = 0;
-    }
+    m_renderSurfaceSharedValues.clear();
 
     if (m_rootLayerTextureId) {
         deleteLayerTexture(m_rootLayerTextureId);
@@ -885,7 +837,9 @@ void LayerRendererChromium::cleanupSharedObjects()
     }
 
     if (m_offscreenFramebufferId)
-        GLC(m_context, m_context->deleteFramebuffer(m_offscreenFramebufferId));
+        GLC(m_context.get(), m_context->deleteFramebuffer(m_offscreenFramebufferId));
+
+    m_textureManager.clear();
 }
 
 } // namespace WebCore
diff --git a/WebCore/platform/graphics/chromium/LayerRendererChromium.h b/WebCore/platform/graphics/chromium/LayerRendererChromium.h
index 531d652..c0e610a 100644
--- a/WebCore/platform/graphics/chromium/LayerRendererChromium.h
+++ b/WebCore/platform/graphics/chromium/LayerRendererChromium.h
@@ -108,6 +108,7 @@ public:
     const CanvasLayerChromium::SharedValues* canvasLayerSharedValues() const { return m_canvasLayerSharedValues.get(); }
     const VideoLayerChromium::SharedValues* videoLayerSharedValues() const { return m_videoLayerSharedValues.get(); }
     const PluginLayerChromium::SharedValues* pluginLayerSharedValues() const { return m_pluginLayerSharedValues.get(); }
+    const RenderSurfaceChromium::SharedValues* renderSurfaceSharedValues() const { return m_renderSurfaceSharedValues.get(); }
 
     void resizeOnscreenContent(const IntSize&);
 
@@ -115,6 +116,10 @@ public:
     IntRect rootLayerContentRect() const { return m_rootContentRect; }
     void getFramebufferPixels(void *pixels, const IntRect& rect);
 
+    TextureManager* textureManager() const { return m_textureManager.get(); }
+
+    void setScissorToRect(const IntRect&);
+
 private:
     explicit LayerRendererChromium(PassRefPtr<GraphicsContext3D> graphicsContext3D);
     void updateLayersRecursive(LayerChromium* layer, const TransformationMatrix& parentMatrix, Vector<LayerChromium*>& renderSurfaceLayerList, Vector<LayerChromium*>& layerList);
@@ -123,8 +128,6 @@ private:
 
     bool isLayerVisible(LayerChromium*, const TransformationMatrix&, const IntRect& visibleRect);
 
-    void setScissorToRect(const IntRect&);
-
     void setDrawViewportRect(const IntRect&, bool flipY);
 
     bool useRenderSurface(RenderSurfaceChromium*);
@@ -140,13 +143,6 @@ private:
     int m_rootLayerTextureWidth;
     int m_rootLayerTextureHeight;
 
-    // Shader uniform locations used by layers whose contents are the results of a
-    // previous rendering operation.
-    unsigned m_textureLayerShaderProgram;
-    int m_textureLayerShaderSamplerLocation;
-    int m_textureLayerShaderMatrixLocation;
-    int m_textureLayerShaderAlphaLocation;
-
     TransformationMatrix m_projectionMatrix;
 
     RefPtr<LayerChromium> m_rootLayer;
@@ -186,6 +182,9 @@ private:
     OwnPtr<CanvasLayerChromium::SharedValues> m_canvasLayerSharedValues;
     OwnPtr<VideoLayerChromium::SharedValues> m_videoLayerSharedValues;
     OwnPtr<PluginLayerChromium::SharedValues> m_pluginLayerSharedValues;
+    OwnPtr<RenderSurfaceChromium::SharedValues> m_renderSurfaceSharedValues;
+
+    OwnPtr<TextureManager> m_textureManager;
 
     RefPtr<GraphicsContext3D> m_context;
 
diff --git a/WebCore/platform/graphics/chromium/LayerTexture.cpp b/WebCore/platform/graphics/chromium/LayerTexture.cpp
new file mode 100644
index 0000000..32bfa0b
--- /dev/null
+++ b/WebCore/platform/graphics/chromium/LayerTexture.cpp
@@ -0,0 +1,93 @@
+/*
+ * 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 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 "config.h"
+
+#if USE(ACCELERATED_COMPOSITING)
+
+#include "LayerTexture.h"
+
+#include "GraphicsContext3D.h"
+#include "TextureManager.h"
+
+namespace WebCore {
+
+LayerTexture::LayerTexture(GraphicsContext3D* context, TextureManager* manager)
+    : m_context(context)
+    , m_textureManager(manager)
+    , m_token(0)
+    , m_format(0)
+    , m_textureId(0)
+{
+}
+
+LayerTexture::~LayerTexture()
+{
+    if (m_token)
+        m_textureManager->releaseToken(m_token);
+}
+
+bool LayerTexture::isValid(const IntSize& size, unsigned format)
+{
+    return m_token && size == m_size && format == m_format && m_textureManager->hasTexture(m_token);
+}
+
+bool LayerTexture::reserve(const IntSize& size, unsigned format)
+{
+    if (!m_token)
+        m_token = m_textureManager->getToken();
+
+    if (size == m_size && format == m_format && m_textureManager->hasTexture(m_token))
+        m_textureManager->protectTexture(m_token);
+    else {
+        m_textureId = m_textureManager->requestTexture(m_token, size, format);
+        if (m_textureId) {
+            m_size = size;
+            m_format = format;
+        }
+    }
+
+    return m_textureId;
+}
+
+void LayerTexture::unreserve()
+{
+    if (m_token)
+        m_textureManager->unprotectTexture(m_token);
+}
+
+void LayerTexture::bindTexture()
+{
+    m_context->bindTexture(GraphicsContext3D::TEXTURE_2D, m_textureId);
+}
+
+void LayerTexture::framebufferTexture2D()
+{
+    m_context->framebufferTexture2D(GraphicsContext3D::FRAMEBUFFER, GraphicsContext3D::COLOR_ATTACHMENT0, GraphicsContext3D::TEXTURE_2D, m_textureId, 0);
+}
+
+}
+
+#endif // USE(ACCELERATED_COMPOSITING)
+
diff --git a/WebCore/platform/graphics/chromium/LayerTexture.h b/WebCore/platform/graphics/chromium/LayerTexture.h
new file mode 100644
index 0000000..312adfa
--- /dev/null
+++ b/WebCore/platform/graphics/chromium/LayerTexture.h
@@ -0,0 +1,69 @@
+/*
+ * 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 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 LayerTexture_h
+#define LayerTexture_h
+
+#include "IntSize.h"
+#include "TextureManager.h"
+
+#include <wtf/Noncopyable.h>
+#include <wtf/PassOwnPtr.h>
+#include <wtf/RefPtr.h>
+
+namespace WebCore {
+
+class GraphicsContext3D;
+class TextureManager;
+
+class LayerTexture : public Noncopyable {
+public:
+    static PassOwnPtr<LayerTexture> create(GraphicsContext3D* context, TextureManager* manager)
+    {
+        return adoptPtr(new LayerTexture(context, manager));
+    }
+    ~LayerTexture();
+
+    bool isValid(const IntSize&, unsigned format);
+    bool reserve(const IntSize&, unsigned format);
+    void unreserve();
+
+    void bindTexture();
+    void framebufferTexture2D();
+
+private:
+    LayerTexture(GraphicsContext3D*, TextureManager*);
+
+    RefPtr<GraphicsContext3D> m_context;
+    TextureManager* m_textureManager;
+    TextureToken m_token;
+    IntSize m_size;
+    unsigned m_format;
+    unsigned m_textureId;
+};
+
+}
+
+#endif
+
diff --git a/WebCore/platform/graphics/chromium/PluginLayerChromium.cpp b/WebCore/platform/graphics/chromium/PluginLayerChromium.cpp
index 2d1852f..878c142 100644
--- a/WebCore/platform/graphics/chromium/PluginLayerChromium.cpp
+++ b/WebCore/platform/graphics/chromium/PluginLayerChromium.cpp
@@ -102,7 +102,7 @@ void PluginLayerChromium::setTextureId(unsigned id)
     m_textureId = id;
 }
 
-void PluginLayerChromium::updateContents()
+void PluginLayerChromium::updateContentsIfDirty()
 {
 }
 
diff --git a/WebCore/platform/graphics/chromium/PluginLayerChromium.h b/WebCore/platform/graphics/chromium/PluginLayerChromium.h
index 44a6cc9..853b328 100644
--- a/WebCore/platform/graphics/chromium/PluginLayerChromium.h
+++ b/WebCore/platform/graphics/chromium/PluginLayerChromium.h
@@ -38,7 +38,7 @@ class PluginLayerChromium : public LayerChromium {
 public:
     static PassRefPtr<PluginLayerChromium> create(GraphicsLayerChromium* owner = 0);
     virtual bool drawsContent() { return true; }
-    virtual void updateContents();
+    virtual void updateContentsIfDirty();
     virtual void draw();
     
     void setTextureId(unsigned textureId);
diff --git a/WebCore/platform/graphics/chromium/RenderSurfaceChromium.cpp b/WebCore/platform/graphics/chromium/RenderSurfaceChromium.cpp
index 816fd3d..e9fdf01 100644
--- a/WebCore/platform/graphics/chromium/RenderSurfaceChromium.cpp
+++ b/WebCore/platform/graphics/chromium/RenderSurfaceChromium.cpp
@@ -31,12 +31,67 @@
 
 #include "GraphicsContext3D.h"
 #include "LayerRendererChromium.h"
+#include "LayerTexture.h"
 
 namespace WebCore {
 
+RenderSurfaceChromium::SharedValues::SharedValues(GraphicsContext3D* context)
+    : m_context(context)
+    , m_shaderProgram(0)
+    , m_shaderSamplerLocation(-1)
+    , m_shaderMatrixLocation(-1)
+    , m_shaderAlphaLocation(-1)
+    , m_initialized(false)
+{
+    // The following program composites layers whose contents are the results of a previous
+    // render operation and therefore doesn't perform any color swizzling. It is used
+    // in scrolling and for compositing offscreen textures.
+    char renderSurfaceVertexShaderString[] =
+        "attribute vec4 a_position;   \n"
+        "attribute vec2 a_texCoord;   \n"
+        "uniform mat4 matrix;         \n"
+        "varying vec2 v_texCoord;     \n"
+        "void main()                  \n"
+        "{                            \n"
+        "  gl_Position = matrix * a_position; \n"
+        "  v_texCoord = a_texCoord;   \n"
+        "}                            \n";
+    char renderSurfaceFragmentShaderString[] =
+        "precision mediump float;                            \n"
+        "varying vec2 v_texCoord;                            \n"
+        "uniform sampler2D s_texture;                        \n"
+        "uniform float alpha;                                \n"
+        "void main()                                         \n"
+        "{                                                   \n"
+        "  vec4 texColor = texture2D(s_texture, v_texCoord); \n"
+        "  gl_FragColor = vec4(texColor.x, texColor.y, texColor.z, texColor.w) * alpha; \n"
+        "}                                                   \n";
+
+    m_shaderProgram = LayerChromium::createShaderProgram(m_context, renderSurfaceVertexShaderString, renderSurfaceFragmentShaderString);
+    if (!m_shaderProgram) {
+        LOG_ERROR("RenderSurfaceChromium: Failed to create shader program");
+        return;
+    }
+
+    GLC(m_context, m_shaderSamplerLocation = m_context->getUniformLocation(m_shaderProgram, "s_texture"));
+    GLC(m_context, m_shaderMatrixLocation = m_context->getUniformLocation(m_shaderProgram, "matrix"));
+    GLC(m_context, m_shaderAlphaLocation = m_context->getUniformLocation(m_shaderProgram, "alpha"));
+    if (m_shaderSamplerLocation == -1 || m_shaderMatrixLocation == -1 || m_shaderAlphaLocation == -1) {
+        LOG_ERROR("Failed to initialize texture layer shader.");
+        return;
+    }
+    m_initialized = true;
+}
+
+RenderSurfaceChromium::SharedValues::~SharedValues()
+{
+    if (m_shaderProgram)
+        GLC(m_context, m_context->deleteProgram(m_shaderProgram));
+}
+
 RenderSurfaceChromium::RenderSurfaceChromium(LayerChromium* owningLayer)
     : m_owningLayer(owningLayer)
-    , m_contentsTextureId(0)
+    , m_skipsDraw(false)
 {
 }
 
@@ -47,14 +102,12 @@ RenderSurfaceChromium::~RenderSurfaceChromium()
 
 void RenderSurfaceChromium::cleanupResources()
 {
-    if (!m_contentsTextureId)
+    if (!m_contentsTexture)
         return;
 
     ASSERT(layerRenderer());
 
-    layerRenderer()->deleteLayerTexture(m_contentsTextureId);
-    m_contentsTextureId = 0;
-    m_allocatedTextureSize = IntSize();
+    m_contentsTexture.clear();
 }
 
 LayerRendererChromium* RenderSurfaceChromium::layerRenderer()
@@ -63,25 +116,41 @@ LayerRendererChromium* RenderSurfaceChromium::layerRenderer()
     return m_owningLayer->layerRenderer();
 }
 
-void RenderSurfaceChromium::prepareContentsTexture()
+bool RenderSurfaceChromium::prepareContentsTexture()
 {
-    ASSERT(m_owningLayer);
+    IntSize requiredSize(m_contentRect.size());
+    TextureManager* textureManager = layerRenderer()->textureManager();
 
-    if (!m_contentsTextureId) {
-        m_contentsTextureId = layerRenderer()->createLayerTexture();
-        ASSERT(m_contentsTextureId);
-        m_allocatedTextureSize = IntSize();
-    }
+    if (!m_contentsTexture)
+        m_contentsTexture = LayerTexture::create(layerRenderer()->context(), textureManager);
 
-    IntSize requiredSize(m_contentRect.width(), m_contentRect.height());
-    if (m_allocatedTextureSize != requiredSize) {
-        GraphicsContext3D* context = m_owningLayer->layerRenderer()->context();
-        GLC(context, context->bindTexture(GraphicsContext3D::TEXTURE_2D, m_contentsTextureId));
-        GLC(context, context->texImage2D(GraphicsContext3D::TEXTURE_2D, 0, GraphicsContext3D::RGBA,
-                                             requiredSize.width(), requiredSize.height(), 0, GraphicsContext3D::RGBA,
-                                             GraphicsContext3D::UNSIGNED_BYTE, 0));
-        m_allocatedTextureSize = requiredSize;
+    if (!m_contentsTexture->reserve(requiredSize, GraphicsContext3D::RGBA)) {
+        m_skipsDraw = true;
+        return false;
     }
+
+    m_skipsDraw = false;
+    return true;
+}
+
+void RenderSurfaceChromium::draw()
+{
+    if (m_skipsDraw)
+        return;
+
+    m_contentsTexture->bindTexture();
+
+    const RenderSurfaceChromium::SharedValues* sv = layerRenderer()->renderSurfaceSharedValues();
+    ASSERT(sv && sv->initialized());
+
+    layerRenderer()->useShader(sv->shaderProgram());
+    layerRenderer()->setScissorToRect(m_scissorRect);
+
+    LayerChromium::drawTexturedQuad(layerRenderer()->context(), layerRenderer()->projectionMatrix(), m_drawTransform,
+                                    m_contentRect.width(), m_contentRect.height(), m_drawOpacity,
+                                    sv->shaderMatrixLocation(), sv->shaderAlphaLocation());
+
+    m_contentsTexture->unreserve();
 }
 
 }
diff --git a/WebCore/platform/graphics/chromium/RenderSurfaceChromium.h b/WebCore/platform/graphics/chromium/RenderSurfaceChromium.h
index 1f33527..a93218f 100644
--- a/WebCore/platform/graphics/chromium/RenderSurfaceChromium.h
+++ b/WebCore/platform/graphics/chromium/RenderSurfaceChromium.h
@@ -31,13 +31,15 @@
 
 #include "FloatRect.h"
 #include "IntRect.h"
+#include "TextureManager.h"
 #include "TransformationMatrix.h"
 #include <wtf/Noncopyable.h>
 
 namespace WebCore {
 
-class LayerRendererChromium;
 class LayerChromium;
+class LayerRendererChromium;
+class LayerTexture;
 
 class RenderSurfaceChromium : public Noncopyable {
     friend class LayerRendererChromium;
@@ -45,20 +47,45 @@ public:
     explicit RenderSurfaceChromium(LayerChromium*);
     ~RenderSurfaceChromium();
 
-    void prepareContentsTexture();
+    bool prepareContentsTexture();
     void cleanupResources();
+    void draw();
 
     FloatPoint contentRectCenter() const { return FloatRect(m_contentRect).center(); }
     IntRect contentRect() const { return m_contentRect; }
 
+    // Stores values that are shared between instances of this class that are
+    // associated with the same LayerRendererChromium (and hence the same GL
+    // context).
+    class SharedValues {
+    public:
+        explicit SharedValues(GraphicsContext3D*);
+        ~SharedValues();
+
+        unsigned shaderProgram() const { return m_shaderProgram; }
+        int shaderSamplerLocation() const { return m_shaderSamplerLocation; }
+        int shaderMatrixLocation() const { return m_shaderMatrixLocation; }
+        int shaderAlphaLocation() const { return m_shaderAlphaLocation; }
+        bool initialized() const { return m_initialized; }
+
+    private:
+        GraphicsContext3D* m_context;
+
+        unsigned m_shaderProgram;
+        int m_shaderSamplerLocation;
+        int m_shaderMatrixLocation;
+        int m_shaderAlphaLocation;
+        bool m_initialized;
+    };
+
 private:
     LayerRendererChromium* layerRenderer();
 
     LayerChromium* m_owningLayer;
     IntRect m_contentRect;
-    unsigned m_contentsTextureId;
+    bool m_skipsDraw;
+    OwnPtr<LayerTexture> m_contentsTexture;
     float m_drawOpacity;
-    IntSize m_allocatedTextureSize;
     TransformationMatrix m_drawTransform;
     TransformationMatrix m_originTransform;
     IntRect m_scissorRect;
diff --git a/WebCore/platform/graphics/chromium/TextureManager.cpp b/WebCore/platform/graphics/chromium/TextureManager.cpp
new file mode 100644
index 0000000..ac93aa3
--- /dev/null
+++ b/WebCore/platform/graphics/chromium/TextureManager.cpp
@@ -0,0 +1,171 @@
+/*
+ * 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 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 "config.h"
+
+#if USE(ACCELERATED_COMPOSITING)
+
+#include "TextureManager.h"
+
+#include "LayerRendererChromium.h"
+
+namespace WebCore {
+
+static size_t memoryUseBytes(IntSize size, unsigned textureFormat)
+{
+    // FIXME: This assumes all textures are 4 bytes/pixel, like RGBA.
+    return size.width() * size.height() * 4;
+}
+
+TextureManager::TextureManager(GraphicsContext3D* context, size_t memoryLimitBytes, int maxTextureSize)
+    : m_context(context)
+    , m_memoryLimitBytes(memoryLimitBytes)
+    , m_memoryUseBytes(0)
+    , m_maxTextureSize(maxTextureSize)
+    , m_nextToken(1)
+{
+}
+
+TextureToken TextureManager::getToken()
+{
+    return m_nextToken++;
+}
+
+void TextureManager::releaseToken(TextureToken token)
+{
+    TextureMap::iterator it = m_textures.find(token);
+    if (it != m_textures.end())
+        removeTexture(token, it->second);
+}
+
+bool TextureManager::hasTexture(TextureToken token)
+{
+    if (m_textures.contains(token)) {
+        // If someone asks about a texture put it at the end of the LRU list.
+        m_textureLRUSet.remove(token);
+        m_textureLRUSet.add(token);
+        return true;
+    }
+    return false;
+}
+
+void TextureManager::protectTexture(TextureToken token)
+{
+    ASSERT(hasTexture(token));
+    ASSERT(!m_textures.get(token).isProtected);
+    TextureInfo info = m_textures.take(token);
+    info.isProtected = true;
+    m_textures.add(token, info);
+}
+
+void TextureManager::unprotectTexture(TextureToken token)
+{
+    TextureMap::iterator it = m_textures.find(token);
+    if (it != m_textures.end()) {
+        TextureInfo info = it->second;
+        if (info.isProtected) {
+            info.isProtected = false;
+            m_textures.remove(it);
+            m_textures.add(token, info);
+        }
+    }
+}
+
+bool TextureManager::reduceMemoryToLimit(size_t limit)
+{
+    while (m_memoryUseBytes > limit) {
+        ASSERT(!m_textureLRUSet.isEmpty());
+        bool foundCandidate = false;
+        for (ListHashSet<TextureToken>::iterator lruIt = m_textureLRUSet.begin(); lruIt != m_textureLRUSet.end(); ++lruIt) {
+            TextureToken token = *lruIt;
+            TextureInfo info = m_textures.get(token);
+            if (info.isProtected)
+                continue;
+            removeTexture(token, info);
+            foundCandidate = true;
+            break;
+        }
+        if (!foundCandidate)
+            return false;
+    }
+    return true;
+}
+
+void TextureManager::addTexture(TextureToken token, TextureInfo info)
+{
+    ASSERT(!m_textureLRUSet.contains(token));
+    ASSERT(!m_textures.contains(token));
+    m_memoryUseBytes += memoryUseBytes(info.size, info.format);
+    m_textures.set(token, info);
+    m_textureLRUSet.add(token);
+}
+
+void TextureManager::removeTexture(TextureToken token, TextureInfo info)
+{
+    ASSERT(m_textureLRUSet.contains(token));
+    ASSERT(m_textures.contains(token));
+    m_memoryUseBytes -= memoryUseBytes(info.size, info.format);
+    m_textures.remove(token);
+    ASSERT(m_textureLRUSet.contains(token));
+    m_textureLRUSet.remove(token);
+    GLC(m_context.get(), m_context->deleteTexture(info.textureId));
+}
+
+unsigned TextureManager::requestTexture(TextureToken token, IntSize size, unsigned format, bool* newTexture)
+{
+    if (size.width() > m_maxTextureSize || size.height() > m_maxTextureSize)
+        return 0;
+
+    TextureMap::iterator it = m_textures.find(token);
+    if (it != m_textures.end()) {
+        ASSERT(it->second.size != size || it->second.format != format);
+        removeTexture(token, it->second);
+    }
+
+    size_t memoryRequiredBytes = memoryUseBytes(size, format);
+    if (memoryRequiredBytes > m_memoryLimitBytes || !reduceMemoryToLimit(m_memoryLimitBytes - memoryRequiredBytes))
+        return 0;
+
+    unsigned textureId = m_context->createTexture();
+    GLC(m_context.get(), textureId = m_context->createTexture());
+    GLC(m_context.get(), m_context->bindTexture(GraphicsContext3D::TEXTURE_2D, textureId));
+    // Do basic linear filtering on resize.
+    GLC(m_context.get(), m_context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MIN_FILTER, GraphicsContext3D::LINEAR));
+    GLC(m_context.get(), m_context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MAG_FILTER, GraphicsContext3D::LINEAR));
+    // NPOT textures in GL ES only work when the wrap mode is set to GraphicsContext3D::CLAMP_TO_EDGE.
+    GLC(m_context.get(), m_context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_WRAP_S, GraphicsContext3D::CLAMP_TO_EDGE));
+    GLC(m_context.get(), m_context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_WRAP_T, GraphicsContext3D::CLAMP_TO_EDGE));
+    GLC(m_context.get(), m_context->texImage2D(GraphicsContext3D::TEXTURE_2D, 0, format, size.width(), size.height(), 0, format, GraphicsContext3D::UNSIGNED_BYTE, 0));
+    TextureInfo info;
+    info.size = size;
+    info.format = format;
+    info.textureId = textureId;
+    info.isProtected = true;
+    addTexture(token, info);
+    return textureId;
+}
+
+}
+
+#endif // USE(ACCELERATED_COMPOSITING)
diff --git a/WebCore/platform/graphics/chromium/TextureManager.h b/WebCore/platform/graphics/chromium/TextureManager.h
new file mode 100644
index 0000000..1e850cd
--- /dev/null
+++ b/WebCore/platform/graphics/chromium/TextureManager.h
@@ -0,0 +1,83 @@
+/*
+ * 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 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 TextureManager_h
+#define TextureManager_h
+
+#include "GraphicsContext3D.h"
+#include "IntRect.h"
+#include "IntSize.h"
+
+#include <wtf/HashMap.h>
+#include <wtf/ListHashSet.h>
+
+namespace WebCore {
+
+typedef int TextureToken;
+
+class TextureManager : public Noncopyable {
+public:
+    static PassOwnPtr<TextureManager> create(GraphicsContext3D* context, size_t memoryLimitBytes, int maxTextureSize)
+    {
+        return adoptPtr(new TextureManager(context, memoryLimitBytes, maxTextureSize));
+    }
+
+    TextureToken getToken();
+    void releaseToken(TextureToken);
+    bool hasTexture(TextureToken);
+
+    unsigned requestTexture(TextureToken, IntSize, unsigned textureFormat, bool* newTexture = 0);
+
+    void protectTexture(TextureToken);
+    void unprotectTexture(TextureToken);
+
+private:
+    TextureManager(GraphicsContext3D*, size_t memoryLimitBytes, int maxTextureSize);
+
+    struct TextureInfo {
+        IntSize size;
+        unsigned format;
+        unsigned textureId;
+        bool isProtected;
+    };
+
+    bool reduceMemoryToLimit(size_t);
+    void addTexture(TextureToken, TextureInfo);
+    void removeTexture(TextureToken, TextureInfo);
+
+    RefPtr<GraphicsContext3D> m_context;
+
+    typedef HashMap<TextureToken, TextureInfo> TextureMap;
+    TextureMap m_textures;
+    ListHashSet<TextureToken> m_textureLRUSet;
+
+    size_t m_memoryLimitBytes;
+    size_t m_memoryUseBytes;
+    int m_maxTextureSize;
+    TextureToken m_nextToken;
+};
+
+}
+
+#endif
diff --git a/WebCore/platform/graphics/chromium/VideoLayerChromium.cpp b/WebCore/platform/graphics/chromium/VideoLayerChromium.cpp
index feb7ebc..d6bd871 100644
--- a/WebCore/platform/graphics/chromium/VideoLayerChromium.cpp
+++ b/WebCore/platform/graphics/chromium/VideoLayerChromium.cpp
@@ -200,8 +200,11 @@ void VideoLayerChromium::cleanupResources()
     }
 }
 
-void VideoLayerChromium::updateContents()
+void VideoLayerChromium::updateContentsIfDirty()
 {
+    if (!m_contentsDirty)
+        return;
+
     RenderLayerBacking* backing = static_cast<RenderLayerBacking*>(m_owner->client());
     if (!backing || backing->paintingGoesToWindow())
         return;
diff --git a/WebCore/platform/graphics/chromium/VideoLayerChromium.h b/WebCore/platform/graphics/chromium/VideoLayerChromium.h
index 05b6578..0992ab7 100644
--- a/WebCore/platform/graphics/chromium/VideoLayerChromium.h
+++ b/WebCore/platform/graphics/chromium/VideoLayerChromium.h
@@ -45,7 +45,7 @@ public:
     static PassRefPtr<VideoLayerChromium> create(GraphicsLayerChromium* owner = 0,
                                                  VideoFrameProvider* = 0);
     virtual ~VideoLayerChromium();
-    virtual void updateContents();
+    virtual void updateContentsIfDirty();
     virtual bool drawsContent() { return true; }
     virtual void draw();
 
diff --git a/WebCore/platform/graphics/chromium/WebGLLayerChromium.cpp b/WebCore/platform/graphics/chromium/WebGLLayerChromium.cpp
index 2055ae6..5b34bb9 100644
--- a/WebCore/platform/graphics/chromium/WebGLLayerChromium.cpp
+++ b/WebCore/platform/graphics/chromium/WebGLLayerChromium.cpp
@@ -50,8 +50,11 @@ WebGLLayerChromium::WebGLLayerChromium(GraphicsLayerChromium* owner)
 {
 }
 
-void WebGLLayerChromium::updateContents()
+void WebGLLayerChromium::updateContentsIfDirty()
 {
+    if (!m_contentsDirty)
+        return;
+
     GraphicsContext3D* rendererContext = layerRendererContext();
     ASSERT(m_context);
     if (m_textureChanged) {
diff --git a/WebCore/platform/graphics/chromium/WebGLLayerChromium.h b/WebCore/platform/graphics/chromium/WebGLLayerChromium.h
index 11b8db7..c67cc2c 100644
--- a/WebCore/platform/graphics/chromium/WebGLLayerChromium.h
+++ b/WebCore/platform/graphics/chromium/WebGLLayerChromium.h
@@ -45,7 +45,7 @@ class WebGLLayerChromium : public CanvasLayerChromium {
 public:
     static PassRefPtr<WebGLLayerChromium> create(GraphicsLayerChromium* owner = 0);
     virtual bool drawsContent() { return m_context; }
-    virtual void updateContents();
+    virtual void updateContentsIfDirty();
 
     void setContext(const GraphicsContext3D* context);
 

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list