[chromium] Add TextureCopier for copying texture contents
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 27 Mar 2012 18:18:42 +0000 (18:18 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 27 Mar 2012 18:18:42 +0000 (18:18 +0000)
https://bugs.webkit.org/show_bug.cgi?id=80870

Patch by Sami Kyostila <skyostil@chromium.org> on 2012-03-27
Reviewed by Stephen White.

Source/WebCore:

This patch introduces a TextureCopier class whose job is to copy the
contents from one GL texture to another using the most efficient means
for the current GPU. This version uses render-to-texture to do the copy,
but a path based on EXT_framebuffer_blit can be added later.

The class is intended to replace the use of image path operations such
as glCopyTex{Sub}Image2D for duplicating texture contents. The reason is
that such functions may not be very well optimized in some -- mainly
mobile -- GPU drivers.

With this patch the new copier is used just for Canvas2D layer
presentation, but another potential use is for WebGL layer presentation.

Test: webkit_unit_tests: TextureCopierTest

* WebCore.gypi:
* platform/graphics/chromium/Canvas2DLayerChromium.cpp:
(WebCore::Canvas2DLayerChromium::Canvas2DLayerChromium):
(WebCore::Canvas2DLayerChromium::~Canvas2DLayerChromium):
(WebCore::Canvas2DLayerChromium::updateCompositorResources):
* platform/graphics/chromium/Canvas2DLayerChromium.h:
(Canvas2DLayerChromium):
* platform/graphics/chromium/LayerRendererChromium.cpp:
(WebCore::LayerRendererChromium::initializeSharedObjects):
* platform/graphics/chromium/LayerRendererChromium.h:
(WebCore):
(WebCore::LayerRendererChromium::textureCopier):
(LayerRendererChromium):
* platform/graphics/chromium/ShaderChromium.cpp:
(WebCore::VertexShaderPosTexIdentity::getShaderString):
(WebCore):
(WebCore::FragmentShaderRGBATexCopy::getShaderString):
* platform/graphics/chromium/ShaderChromium.h:
(VertexShaderPosTexIdentity):
(WebCore::VertexShaderPosTexIdentity::init):
(WebCore):
(FragmentShaderRGBATexCopy):
* platform/graphics/chromium/TextureCopier.cpp: Added.
(WebCore):
(WebCore::AcceleratedTextureCopier::AcceleratedTextureCopier):
(WebCore::AcceleratedTextureCopier::~AcceleratedTextureCopier):
(WebCore::AcceleratedTextureCopier::copyTexture):
* platform/graphics/chromium/TextureCopier.h: Added.
(WebCore):
(TextureCopier):
(WebCore::TextureCopier::~TextureCopier):
(AcceleratedTextureCopier):
(WebCore::AcceleratedTextureCopier::create):
* platform/graphics/chromium/cc/CCSingleThreadProxy.cpp:
(WebCore::CCSingleThreadProxy::doCommit):
* platform/graphics/chromium/cc/CCTextureUpdater.cpp:
(WebCore::CCTextureUpdater::CCTextureUpdater):
* platform/graphics/chromium/cc/CCTextureUpdater.h:
(WebCore):
(CCTextureUpdater):
(WebCore::CCTextureUpdater::copier):
* platform/graphics/chromium/cc/CCThreadProxy.cpp:
(WebCore::CCThreadProxy::beginFrameCompleteOnImplThread):

Source/WebKit/chromium:

Add new test for TextureCopier.

* WebKit.gypi:
* tests/Canvas2DLayerChromiumTest.cpp:
* tests/TextureCopierTest.cpp: Added.
* tests/TiledLayerChromiumTest.cpp:
(FakeTextureCopier):
(WTF::FakeTextureCopier::copyTexture):
(WTF):
(WTF::TEST):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@112286 268f45cc-cd09-0410-ab3c-d52691b4dbfc

19 files changed:
Source/WebCore/ChangeLog
Source/WebCore/WebCore.gypi
Source/WebCore/platform/graphics/chromium/Canvas2DLayerChromium.cpp
Source/WebCore/platform/graphics/chromium/Canvas2DLayerChromium.h
Source/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp
Source/WebCore/platform/graphics/chromium/LayerRendererChromium.h
Source/WebCore/platform/graphics/chromium/ShaderChromium.cpp
Source/WebCore/platform/graphics/chromium/ShaderChromium.h
Source/WebCore/platform/graphics/chromium/TextureCopier.cpp [new file with mode: 0644]
Source/WebCore/platform/graphics/chromium/TextureCopier.h [new file with mode: 0644]
Source/WebCore/platform/graphics/chromium/cc/CCSingleThreadProxy.cpp
Source/WebCore/platform/graphics/chromium/cc/CCTextureUpdater.cpp
Source/WebCore/platform/graphics/chromium/cc/CCTextureUpdater.h
Source/WebCore/platform/graphics/chromium/cc/CCThreadProxy.cpp
Source/WebKit/chromium/ChangeLog
Source/WebKit/chromium/WebKit.gypi
Source/WebKit/chromium/tests/Canvas2DLayerChromiumTest.cpp
Source/WebKit/chromium/tests/TextureCopierTest.cpp [new file with mode: 0644]
Source/WebKit/chromium/tests/TiledLayerChromiumTest.cpp

index f9bff2e..55a85af 100644 (file)
@@ -1,3 +1,69 @@
+2012-03-27  Sami Kyostila  <skyostil@chromium.org>
+
+        [chromium] Add TextureCopier for copying texture contents
+        https://bugs.webkit.org/show_bug.cgi?id=80870
+
+        Reviewed by Stephen White.
+
+        This patch introduces a TextureCopier class whose job is to copy the
+        contents from one GL texture to another using the most efficient means
+        for the current GPU. This version uses render-to-texture to do the copy,
+        but a path based on EXT_framebuffer_blit can be added later.
+
+        The class is intended to replace the use of image path operations such
+        as glCopyTex{Sub}Image2D for duplicating texture contents. The reason is
+        that such functions may not be very well optimized in some -- mainly
+        mobile -- GPU drivers.
+
+        With this patch the new copier is used just for Canvas2D layer
+        presentation, but another potential use is for WebGL layer presentation.
+
+        Test: webkit_unit_tests: TextureCopierTest
+
+        * WebCore.gypi:
+        * platform/graphics/chromium/Canvas2DLayerChromium.cpp:
+        (WebCore::Canvas2DLayerChromium::Canvas2DLayerChromium):
+        (WebCore::Canvas2DLayerChromium::~Canvas2DLayerChromium):
+        (WebCore::Canvas2DLayerChromium::updateCompositorResources):
+        * platform/graphics/chromium/Canvas2DLayerChromium.h:
+        (Canvas2DLayerChromium):
+        * platform/graphics/chromium/LayerRendererChromium.cpp:
+        (WebCore::LayerRendererChromium::initializeSharedObjects):
+        * platform/graphics/chromium/LayerRendererChromium.h:
+        (WebCore):
+        (WebCore::LayerRendererChromium::textureCopier):
+        (LayerRendererChromium):
+        * platform/graphics/chromium/ShaderChromium.cpp:
+        (WebCore::VertexShaderPosTexIdentity::getShaderString):
+        (WebCore):
+        (WebCore::FragmentShaderRGBATexCopy::getShaderString):
+        * platform/graphics/chromium/ShaderChromium.h:
+        (VertexShaderPosTexIdentity):
+        (WebCore::VertexShaderPosTexIdentity::init):
+        (WebCore):
+        (FragmentShaderRGBATexCopy):
+        * platform/graphics/chromium/TextureCopier.cpp: Added.
+        (WebCore):
+        (WebCore::AcceleratedTextureCopier::AcceleratedTextureCopier):
+        (WebCore::AcceleratedTextureCopier::~AcceleratedTextureCopier):
+        (WebCore::AcceleratedTextureCopier::copyTexture):
+        * platform/graphics/chromium/TextureCopier.h: Added.
+        (WebCore):
+        (TextureCopier):
+        (WebCore::TextureCopier::~TextureCopier):
+        (AcceleratedTextureCopier):
+        (WebCore::AcceleratedTextureCopier::create):
+        * platform/graphics/chromium/cc/CCSingleThreadProxy.cpp:
+        (WebCore::CCSingleThreadProxy::doCommit):
+        * platform/graphics/chromium/cc/CCTextureUpdater.cpp:
+        (WebCore::CCTextureUpdater::CCTextureUpdater):
+        * platform/graphics/chromium/cc/CCTextureUpdater.h:
+        (WebCore):
+        (CCTextureUpdater):
+        (WebCore::CCTextureUpdater::copier):
+        * platform/graphics/chromium/cc/CCThreadProxy.cpp:
+        (WebCore::CCThreadProxy::beginFrameCompleteOnImplThread):
+
 2012-03-27  Levi Weintraub  <leviw@chromium.org>
 
         Correct SVG paint functions that are still using IntPoints
index 908034d..c5ba637 100644 (file)
             'platform/graphics/chromium/SkPictureCanvasLayerTextureUpdater.h',
             'platform/graphics/chromium/TrackingTextureAllocator.cpp',
             'platform/graphics/chromium/TrackingTextureAllocator.h',
+            'platform/graphics/chromium/TextureCopier.cpp',
+            'platform/graphics/chromium/TextureCopier.h',
             'platform/graphics/chromium/TextureManager.cpp',
             'platform/graphics/chromium/TextureManager.h',
             'platform/graphics/chromium/TiledLayerChromium.cpp',
index 1d3d369..fcbf54a 100644 (file)
@@ -37,6 +37,7 @@
 #include "Extensions3DChromium.h"
 #include "GraphicsContext3D.h"
 #include "LayerRendererChromium.h" // For the GLC() macro
+#include "TextureCopier.h"
 #include "cc/CCLayerTreeHost.h"
 #include "cc/CCTextureLayerImpl.h"
 #include "cc/CCTextureUpdater.h"
@@ -56,18 +57,13 @@ Canvas2DLayerChromium::Canvas2DLayerChromium(PassRefPtr<GraphicsContext3D> conte
     , m_contextLost(false)
     , m_size(size)
     , m_backTextureId(0)
-    , m_fbo(0)
     , m_useDoubleBuffering(CCProxy::hasImplThread())
     , m_canvas(0)
 {
-    if (m_useDoubleBuffering)
-        GLC(m_context, m_fbo = m_context->createFramebuffer());
 }
 
 Canvas2DLayerChromium::~Canvas2DLayerChromium()
 {
-    if (m_useDoubleBuffering && m_fbo)
-       GLC(m_context, m_context->deleteFramebuffer(m_fbo));
     if (m_context && layerTreeHost())
         layerTreeHost()->stopRateLimiter(m_context.get());
 }
@@ -138,15 +134,8 @@ void Canvas2DLayerChromium::updateCompositorResources(GraphicsContext3D* context
     if (!m_backTextureId || !m_frontTexture || !m_frontTexture->isValid(m_size, GraphicsContext3D::RGBA))
         return;
 
-    m_frontTexture->bindTexture(context, updater.allocator());
-
-    GLC(context, context->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, m_fbo));
-    GLC(context, context->framebufferTexture2D(GraphicsContext3D::FRAMEBUFFER, GraphicsContext3D::COLOR_ATTACHMENT0, GraphicsContext3D::TEXTURE_2D, m_backTextureId, 0));
-    // FIXME: The copy operation will fail if the m_backTexture is allocated as BGRA since glCopyTex(Sub)Image2D doesn't
-    //        support the BGRA format. See bug https://bugs.webkit.org/show_bug.cgi?id=75142
-    GLC(context, context->copyTexSubImage2D(GraphicsContext3D::TEXTURE_2D, 0, 0, 0, 0, 0, m_size.width(), m_size.height()));
-    GLC(context, context->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, 0));
-    GLC(context, context->flush());
+    m_frontTexture->allocate(updater.allocator());
+    updater.copier()->copyTexture(context, m_backTextureId, m_frontTexture->textureId(), m_size);
 }
 
 void Canvas2DLayerChromium::pushPropertiesTo(CCLayerImpl* layer)
index 9302246..b5d0c23 100644 (file)
@@ -72,7 +72,6 @@ private:
     bool m_contextLost;
     IntSize m_size;
     unsigned m_backTextureId;
-    Platform3DObject m_fbo;
     // When m_useDoubleBuffering is true, the compositor will draw using a copy of the
     // canvas' backing texture. This option should be used with the compositor doesn't
     // synchronize its draws with the canvas updates.
index c5f5e6a..8ef63cd 100644 (file)
@@ -45,6 +45,7 @@
 #include "PlatformColor.h"
 #include "RenderSurfaceChromium.h"
 #include "TextStream.h"
+#include "TextureCopier.h"
 #include "TextureManager.h"
 #include "TraceEvent.h"
 #include "TrackingTextureAllocator.h"
@@ -1297,6 +1298,7 @@ bool LayerRendererChromium::initializeSharedObjects()
     m_renderSurfaceTextureManager = TextureManager::create(TextureManager::highLimitBytes(viewportSize()),
                                                            TextureManager::reclaimLimitBytes(viewportSize()),
                                                            m_capabilities.maxTextureSize);
+    m_textureCopier = AcceleratedTextureCopier::create(m_context.get());
     m_contentsTextureAllocator = TrackingTextureAllocator::create(m_context.get());
     m_renderSurfaceTextureAllocator = TrackingTextureAllocator::create(m_context.get());
     if (m_capabilities.usingTextureUsageHint)
@@ -1609,6 +1611,7 @@ void LayerRendererChromium::cleanupSharedObjects()
     m_streamTextureLayerProgram.clear();
     if (m_offscreenFramebufferId)
         GLC(m_context.get(), m_context->deleteFramebuffer(m_offscreenFramebufferId));
+    m_textureCopier.clear();
 
     releaseRenderSurfaceTextures();
 }
index 61c1d4a..435541b 100644 (file)
@@ -38,6 +38,7 @@
 #include "FloatQuad.h"
 #include "IntRect.h"
 #include "LayerChromium.h"
+#include "TextureCopier.h"
 #include "TrackingTextureAllocator.h"
 #include "VideoLayerChromium.h"
 #include "cc/CCDrawQuad.h"
@@ -59,7 +60,6 @@ class CCRenderPass;
 class CCTextureDrawQuad;
 class GeometryBinding;
 class GraphicsContext3D;
-class TrackingTextureAllocator;
 class LayerRendererSwapBuffersCompleteCallbackAdapter;
 class ScopedEnsureFramebufferAllocation;
 
@@ -142,6 +142,7 @@ public:
     void getFramebufferPixels(void *pixels, const IntRect&);
 
     TextureManager* renderSurfaceTextureManager() const { return m_renderSurfaceTextureManager.get(); }
+    TextureCopier* textureCopier() const { return m_textureCopier.get(); }
     TextureAllocator* renderSurfaceTextureAllocator() const { return m_renderSurfaceTextureAllocator.get(); }
     TextureAllocator* contentsTextureAllocator() const { return m_contentsTextureAllocator.get(); }
 
@@ -249,6 +250,7 @@ private:
     OwnPtr<CCVideoLayerImpl::StreamTextureProgram> m_streamTextureLayerProgram;
 
     OwnPtr<TextureManager> m_renderSurfaceTextureManager;
+    OwnPtr<AcceleratedTextureCopier> m_textureCopier;
     OwnPtr<TrackingTextureAllocator> m_contentsTextureAllocator;
     OwnPtr<TrackingTextureAllocator> m_renderSurfaceTextureAllocator;
 
index 71d4d1f..d995eda 100644 (file)
@@ -188,6 +188,19 @@ VertexShaderQuad::VertexShaderQuad()
 {
 }
 
+String VertexShaderPosTexIdentity::getShaderString() const
+{
+    return SHADER(
+        attribute vec4 a_position;
+        varying vec2 v_texCoord;
+        void main()
+        {
+            gl_Position = a_position;
+            v_texCoord = (a_position.xy + vec2(1.0)) * 0.5;
+        }
+    );
+}
+
 void VertexShaderQuad::init(GraphicsContext3D* context, unsigned program)
 {
     m_matrixLocation = context->getUniformLocation(program, "matrix");
@@ -410,6 +423,19 @@ String FragmentShaderRGBATexOpaque::getShaderString() const
     );
 }
 
+String FragmentShaderRGBATex::getShaderString() const
+{
+    return SHADER(
+        precision mediump float;
+        varying vec2 v_texCoord;
+        uniform sampler2D s_texture;
+        void main()
+        {
+            gl_FragColor = texture2D(s_texture, v_texCoord);
+        }
+    );
+}
+
 String FragmentShaderRGBATexSwizzleAlpha::getShaderString() const
 {
     return SHADER(
index 2bd760a..0e41968 100644 (file)
@@ -95,6 +95,12 @@ private:
     int m_matrixLocation;
 };
 
+class VertexShaderPosTexIdentity {
+public:
+    void init(GraphicsContext3D*, unsigned program) { }
+    String getShaderString() const;
+};
+
 class VertexShaderPosTexTransform {
 public:
     VertexShaderPosTexTransform();
@@ -213,6 +219,11 @@ public:
     String getShaderString() const;
 };
 
+class FragmentShaderRGBATex : public FragmentTexOpaqueBinding {
+public:
+    String getShaderString() const;
+};
+
 // Swizzles the red and blue component of sampled texel with alpha.
 class FragmentShaderRGBATexSwizzleAlpha : public FragmentTexAlphaBinding {
 public:
diff --git a/Source/WebCore/platform/graphics/chromium/TextureCopier.cpp b/Source/WebCore/platform/graphics/chromium/TextureCopier.cpp
new file mode 100644 (file)
index 0000000..bd687c6
--- /dev/null
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2012, 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"
+
+#include "TextureCopier.h"
+
+#include "LayerRendererChromium.h" // For the GLC() macro
+
+namespace WebCore {
+
+#if USE(ACCELERATED_COMPOSITING)
+AcceleratedTextureCopier::AcceleratedTextureCopier(PassRefPtr<GraphicsContext3D> context)
+    : m_context(context)
+{
+    GLC(m_context, m_fbo = m_context->createFramebuffer());
+    GLC(m_context, m_positionBuffer = m_context->createBuffer());
+
+    static const float kPositions[4][4] = {
+        {-1, -1, 0, 1},
+        { 1, -1, 0, 1},
+        { 1, 1, 0, 1},
+        {-1, 1, 0, 1}
+    };
+
+    GLC(m_context.get(), m_context->bindBuffer(GraphicsContext3D::ARRAY_BUFFER, m_positionBuffer));
+    GLC(m_context.get(), m_context->bufferData(GraphicsContext3D::ARRAY_BUFFER, sizeof(kPositions), kPositions, GraphicsContext3D::STATIC_DRAW));
+    GLC(m_context.get(), m_context->bindBuffer(GraphicsContext3D::ARRAY_BUFFER, 0));
+
+    m_blitProgram = adoptPtr(new BlitProgram(m_context.get()));
+    m_blitProgram->initialize(m_context.get());
+}
+
+AcceleratedTextureCopier::~AcceleratedTextureCopier()
+{
+    if (m_blitProgram)
+        m_blitProgram->cleanup(m_context.get());
+    if (m_positionBuffer)
+        GLC(m_context, m_context->deleteBuffer(m_positionBuffer));
+    if (m_fbo)
+        GLC(m_context, m_context->deleteFramebuffer(m_fbo));
+}
+
+void AcceleratedTextureCopier::copyTexture(GraphicsContext3D* context, unsigned sourceTextureId, unsigned destTextureId, const IntSize& size)
+{
+    TRACE_EVENT("TextureCopier::copyTexture", this, 0);
+
+    // Note: this code does not restore the viewport, bound program, 2D texture, framebuffer, buffer or blend enable.
+    GLC(context, context->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, m_fbo));
+    GLC(context, context->framebufferTexture2D(GraphicsContext3D::FRAMEBUFFER, GraphicsContext3D::COLOR_ATTACHMENT0, GraphicsContext3D::TEXTURE_2D, destTextureId, 0));
+
+#if OS(ANDROID)
+    // Clear destination to improve performance on tiling GPUs.
+    // TODO: Use EXT_discard_framebuffer or skip clearing if it isn't available.
+    GLC(context, context->clear(GraphicsContext3D::COLOR_BUFFER_BIT));
+#endif
+
+    GLC(context, context->bindTexture(GraphicsContext3D::TEXTURE_2D, sourceTextureId));
+    GLC(context, context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MIN_FILTER, GraphicsContext3D::NEAREST));
+    GLC(context, context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MAG_FILTER, GraphicsContext3D::NEAREST));
+
+    // TODO: Use EXT_framebuffer_blit if available.
+    GLC(context, context->useProgram(m_blitProgram->program()));
+
+    const int kPositionAttribute = 0;
+    GLC(context, context->bindBuffer(GraphicsContext3D::ARRAY_BUFFER, m_positionBuffer));
+    GLC(context, context->vertexAttribPointer(kPositionAttribute, 4, GraphicsContext3D::FLOAT, false, 0, 0));
+    GLC(context, context->enableVertexAttribArray(kPositionAttribute));
+    GLC(context, context->bindBuffer(GraphicsContext3D::ARRAY_BUFFER, 0));
+
+    GLC(context, context->viewport(0, 0, size.width(), size.height()));
+    GLC(context, context->disable(GraphicsContext3D::BLEND));
+    GLC(context, context->drawArrays(GraphicsContext3D::TRIANGLE_FAN, 0, 4));
+
+    GLC(context, context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MIN_FILTER, GraphicsContext3D::LINEAR));
+    GLC(context, context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MAG_FILTER, GraphicsContext3D::LINEAR));
+    GLC(context, context->disableVertexAttribArray(kPositionAttribute));
+
+    GLC(context, context->useProgram(0));
+
+    GLC(context, context->framebufferTexture2D(GraphicsContext3D::FRAMEBUFFER, GraphicsContext3D::COLOR_ATTACHMENT0, GraphicsContext3D::TEXTURE_2D, 0, 0));
+    GLC(context, context->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, 0));
+    GLC(context, context->bindTexture(GraphicsContext3D::TEXTURE_2D, 0));
+}
+
+}
+
+#endif // USE(ACCELERATED_COMPOSITING)
diff --git a/Source/WebCore/platform/graphics/chromium/TextureCopier.h b/Source/WebCore/platform/graphics/chromium/TextureCopier.h
new file mode 100644 (file)
index 0000000..73be5ec
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2012, 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 TextureCopier_h
+#define TextureCopier_h
+
+#include "GraphicsContext3D.h"
+#include "ProgramBinding.h"
+#include "ShaderChromium.h"
+#include <wtf/PassRefPtr.h>
+
+namespace WebCore {
+
+class TextureCopier {
+public:
+    // Copy the base level contents of |sourceTextureId| to |destTextureId|. Both texture objects
+    // must be complete and have a base level of |size| dimensions. The color formats do not need
+    // to match, but |destTextureId| must have a renderable format.
+    virtual void copyTexture(GraphicsContext3D*, unsigned sourceTextureId, unsigned destTextureId, const IntSize&) = 0;
+
+protected:
+    virtual ~TextureCopier() { }
+};
+
+#if USE(ACCELERATED_COMPOSITING)
+
+class AcceleratedTextureCopier : public TextureCopier {
+    WTF_MAKE_NONCOPYABLE(AcceleratedTextureCopier);
+public:
+    static PassOwnPtr<AcceleratedTextureCopier> create(PassRefPtr<GraphicsContext3D> context)
+    {
+        return adoptPtr(new AcceleratedTextureCopier(context));
+    }
+    virtual ~AcceleratedTextureCopier();
+
+    virtual void copyTexture(GraphicsContext3D*, unsigned sourceTextureId, unsigned destTextureId, const IntSize&);
+
+protected:
+    explicit AcceleratedTextureCopier(PassRefPtr<GraphicsContext3D>);
+
+private:
+    typedef ProgramBinding<VertexShaderPosTexIdentity, FragmentShaderRGBATex> BlitProgram;
+
+    RefPtr<GraphicsContext3D> m_context;
+    Platform3DObject m_fbo;
+    Platform3DObject m_positionBuffer;
+    OwnPtr<BlitProgram> m_blitProgram;
+};
+
+#endif // USE(ACCELERATED_COMPOSITING)
+
+}
+
+#endif
index 7652586..1b41f7e 100644 (file)
@@ -202,7 +202,7 @@ void CCSingleThreadProxy::doCommit()
         m_layerTreeHostImpl->beginCommit();
 
         m_layerTreeHost->beginCommitOnImplThread(m_layerTreeHostImpl.get());
-        CCTextureUpdater updater(m_layerTreeHostImpl->contentsTextureAllocator());
+        CCTextureUpdater updater(m_layerTreeHostImpl->contentsTextureAllocator(), m_layerTreeHostImpl->layerRenderer()->textureCopier());
         m_layerTreeHost->updateCompositorResources(m_layerTreeHostImpl->context(), updater);
         updater.update(m_layerTreeHostImpl->context(), numeric_limits<size_t>::max());
         ASSERT(!updater.hasMoreUpdates());
index 66e08c8..0ce0f6d 100644 (file)
@@ -37,8 +37,9 @@ using namespace std;
 
 namespace WebCore {
 
-CCTextureUpdater::CCTextureUpdater(TextureAllocator* allocator)
+CCTextureUpdater::CCTextureUpdater(TextureAllocator* allocator, TextureCopier* copier)
     : m_allocator(allocator)
+    , m_copier(copier)
     , m_entryIndex(0)
 {
     ASSERT(m_allocator);
index dbb52c9..d29c658 100644 (file)
@@ -34,10 +34,11 @@ namespace WebCore {
 
 class GraphicsContext3D;
 class TextureAllocator;
+class TextureCopier;
 
 class CCTextureUpdater {
 public:
-    CCTextureUpdater(TextureAllocator*);
+    CCTextureUpdater(TextureAllocator*, TextureCopier*);
     ~CCTextureUpdater();
 
     void append(LayerTextureUpdater::Texture*, const IntRect& sourceRect, const IntRect& destRect);
@@ -51,6 +52,7 @@ public:
     void clear();
 
     TextureAllocator* allocator() { return m_allocator; }
+    TextureCopier* copier() { return m_copier; }
 
 private:
     struct UpdateEntry {
@@ -62,6 +64,7 @@ private:
     static void append(LayerTextureUpdater::Texture*, const IntRect& sourceRect, const IntRect& destRect, Vector<UpdateEntry>&);
 
     TextureAllocator* m_allocator;
+    TextureCopier* m_copier;
     size_t m_entryIndex;
     Vector<UpdateEntry> m_entries;
     Vector<UpdateEntry> m_partialEntries;
index 4c988bf..20a50bb 100644 (file)
@@ -27,6 +27,7 @@
 #include "cc/CCThreadProxy.h"
 
 #include "GraphicsContext3D.h"
+#include "LayerRendererChromium.h"
 #include "SharedGraphicsContext3D.h"
 #include "TraceEvent.h"
 #include "cc/CCDelayBasedTimeSource.h"
@@ -503,7 +504,7 @@ void CCThreadProxy::beginFrameCompleteOnImplThread(CCCompletionEvent* completion
     m_commitCompletionEventOnImplThread = completion;
 
     ASSERT(!m_currentTextureUpdaterOnImplThread);
-    m_currentTextureUpdaterOnImplThread = adoptPtr(new CCTextureUpdater(m_layerTreeHostImpl->contentsTextureAllocator()));
+    m_currentTextureUpdaterOnImplThread = adoptPtr(new CCTextureUpdater(m_layerTreeHostImpl->contentsTextureAllocator(), m_layerTreeHostImpl->layerRenderer()->textureCopier()));
     m_layerTreeHost->updateCompositorResources(m_layerTreeHostImpl->context(), *m_currentTextureUpdaterOnImplThread);
 
     m_schedulerOnImplThread->beginFrameComplete();
index c03c212..ab4cf96 100644 (file)
@@ -1,3 +1,21 @@
+2012-03-27  Sami Kyostila  <skyostil@chromium.org>
+
+        [chromium] Add TextureCopier for copying texture contents
+        https://bugs.webkit.org/show_bug.cgi?id=80870
+
+        Reviewed by Stephen White.
+
+        Add new test for TextureCopier.
+
+        * WebKit.gypi:
+        * tests/Canvas2DLayerChromiumTest.cpp:
+        * tests/TextureCopierTest.cpp: Added.
+        * tests/TiledLayerChromiumTest.cpp:
+        (FakeTextureCopier):
+        (WTF::FakeTextureCopier::copyTexture):
+        (WTF):
+        (WTF::TEST):
+
 2012-03-27  Stephen White  <senorblanco@chromium.org>
 
         [chromium] Fix filter context usage in webkit_unit_tests.
index 889429b..941f8e8 100644 (file)
             'tests/RegionTest.cpp',
             'tests/RenderTableCellTest.cpp',
             'tests/ScrollbarLayerChromiumTest.cpp',
+            'tests/TextureCopierTest.cpp',
             'tests/TextureManagerTest.cpp',
             'tests/TiledLayerChromiumTest.cpp',
             'tests/TilingDataTest.cpp',
index 14c92ae..ea3d40f 100644 (file)
@@ -31,6 +31,7 @@
 #include "FakeWebGraphicsContext3D.h"
 #include "GraphicsContext3DPrivate.h"
 #include "Region.h"
+#include "TextureCopier.h"
 #include "TextureManager.h"
 #include "WebCompositor.h"
 #include "WebKit.h"
@@ -92,6 +93,11 @@ public:
     MOCK_METHOD3(deleteTexture, void(unsigned, const IntSize&, GC3Denum));
 };
 
+class MockTextureCopier : public TextureCopier {
+public:
+    MOCK_METHOD4(copyTexture, void(GraphicsContext3D*, unsigned, unsigned, const IntSize&));
+};
+
 class Canvas2DLayerChromiumTest : public Test {
 protected:
     void fullLifecycleTest(bool threaded)
@@ -101,11 +107,9 @@ protected:
         RefPtr<GraphicsContext3D> mainContext = GraphicsContext3DPrivate::createGraphicsContextFromWebContext(adoptPtr(new MockCanvasContext()), GraphicsContext3D::RenderDirectlyToHostWindow);
         RefPtr<GraphicsContext3D> implContext = GraphicsContext3DPrivate::createGraphicsContextFromWebContext(adoptPtr(new MockCanvasContext()), GraphicsContext3D::RenderDirectlyToHostWindow);
 
-        MockCanvasContext& mainMock = *static_cast<MockCanvasContext*>(GraphicsContext3DPrivate::extractWebGraphicsContext3D(mainContext.get()));
-        MockCanvasContext& implMock = *static_cast<MockCanvasContext*>(GraphicsContext3DPrivate::extractWebGraphicsContext3D(implContext.get()));
-
         MockTextureAllocator allocatorMock;
-        CCTextureUpdater updater(&allocatorMock);
+        MockTextureCopier copierMock;
+        CCTextureUpdater updater(&allocatorMock, &copierMock);
 
         const IntSize size(300, 150);
 
@@ -120,28 +124,16 @@ protected:
 
         const WebGLId backTextureId = 1;
         const WebGLId frontTextureId = 2;
-        const WebGLId fboId = 3;
         {
             InSequence sequence;
 
             // Note that the canvas backing texture is doublebuffered only when using the threaded
             // compositor.
             if (threaded) {
-                // Setup Canvas2DLayerChromium (on the main thread).
-                EXPECT_CALL(mainMock, createFramebuffer())
-                    .WillOnce(Return(fboId));
-
                 // Create texture and do the copy (on the impl thread).
                 EXPECT_CALL(allocatorMock, createTexture(size, GraphicsContext3D::RGBA))
                     .WillOnce(Return(frontTextureId));
-                EXPECT_CALL(implMock, bindTexture(GraphicsContext3D::TEXTURE_2D, frontTextureId));
-                EXPECT_CALL(implMock, bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, fboId));
-                EXPECT_CALL(implMock, framebufferTexture2D(GraphicsContext3D::FRAMEBUFFER, GraphicsContext3D::COLOR_ATTACHMENT0, GraphicsContext3D::TEXTURE_2D, backTextureId, 0));
-                EXPECT_CALL(implMock, copyTexSubImage2D(GraphicsContext3D::TEXTURE_2D, 0, 0, 0, 0, 0, 300, 150));
-                EXPECT_CALL(implMock, bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, 0));
-
-                // Teardown Canvas2DLayerChromium.
-                EXPECT_CALL(mainMock, deleteFramebuffer(fboId));
+                EXPECT_CALL(copierMock, copyTexture(implContext.get(), backTextureId, frontTextureId, size));
 
                 // Teardown TextureManager.
                 EXPECT_CALL(allocatorMock, deleteTexture(frontTextureId, size, GraphicsContext3D::RGBA));
diff --git a/Source/WebKit/chromium/tests/TextureCopierTest.cpp b/Source/WebKit/chromium/tests/TextureCopierTest.cpp
new file mode 100644 (file)
index 0000000..17173c0
--- /dev/null
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2011 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"
+
+#include "TextureCopier.h"
+
+#include "FakeWebGraphicsContext3D.h"
+#include "GraphicsContext3DPrivate.h"
+
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+#include <wtf/RefPtr.h>
+
+using namespace WebCore;
+using namespace WebKit;
+using testing::InSequence;
+using testing::Test;
+using testing::_;
+
+namespace {
+
+class MockContext : public FakeWebGraphicsContext3D {
+public:
+    MOCK_METHOD2(bindFramebuffer, void(WGC3Denum, WebGLId));
+    MOCK_METHOD3(texParameteri, void(GC3Denum target, GC3Denum pname, GC3Dint param));
+
+    MOCK_METHOD3(drawArrays, void(GC3Denum mode, GC3Dint first, GC3Dsizei count));
+};
+
+TEST(TextureCopierTest, testDrawArraysCopy)
+{
+    GraphicsContext3D::Attributes attrs;
+    RefPtr<GraphicsContext3D> context = GraphicsContext3DPrivate::createGraphicsContextFromWebContext(adoptPtr(new MockContext()), GraphicsContext3D::RenderDirectlyToHostWindow);
+    MockContext& mockContext = *static_cast<MockContext*>(GraphicsContext3DPrivate::extractWebGraphicsContext3D(context.get()));
+
+    {
+        InSequence sequence;
+
+        // Here we check just some essential properties of copyTexture() to avoid mirroring the full implementation.
+        EXPECT_CALL(mockContext, bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, _));
+
+        // Make sure linear filtering is disabled during the copy.
+        EXPECT_CALL(mockContext, texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MIN_FILTER, GraphicsContext3D::NEAREST));
+        EXPECT_CALL(mockContext, texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MAG_FILTER, GraphicsContext3D::NEAREST));
+
+        EXPECT_CALL(mockContext, drawArrays(_, _, _));
+
+        // Linear filtering should be restored.
+        EXPECT_CALL(mockContext, texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MIN_FILTER, GraphicsContext3D::LINEAR));
+        EXPECT_CALL(mockContext, texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MAG_FILTER, GraphicsContext3D::LINEAR));
+
+        // Default framebuffer should be restored
+        EXPECT_CALL(mockContext, bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, 0));
+    }
+
+    int sourceTextureId = 1;
+    int destTextureId = 2;
+    IntSize size(256, 128);
+    OwnPtr<AcceleratedTextureCopier> copier(AcceleratedTextureCopier::create(context));
+    copier->copyTexture(context.get(), sourceTextureId, destTextureId, size);
+}
+
+} // namespace
index c19ac46..47fc870 100644 (file)
@@ -31,6 +31,7 @@
 #include "FakeCCLayerTreeHostClient.h"
 #include "LayerTextureUpdater.h"
 #include "Region.h"
+#include "TextureCopier.h"
 #include "TextureManager.h"
 #include "WebCompositor.h"
 #include "cc/CCSingleThreadProxy.h" // For DebugScopedSetImplThread
@@ -75,6 +76,11 @@ public:
     virtual void deleteTexture(unsigned, const IntSize&, GC3Denum) { }
 };
 
+class FakeTextureCopier : public TextureCopier {
+public:
+    virtual void copyTexture(GraphicsContext3D*, unsigned, unsigned, const IntSize&) { }
+};
+
 class FakeTiledLayerChromium;
 
 class FakeLayerTextureUpdater : public LayerTextureUpdater {
@@ -243,6 +249,23 @@ void FakeLayerTextureUpdater::prepareToUpdate(const IntRect& contentRect, const
     *resultingOpaqueRect = m_opaquePaintRect;
 }
 
+class FakeCCTextureUpdater : public CCTextureUpdater {
+public:
+    explicit FakeCCTextureUpdater()
+        : CCTextureUpdater(&m_textureAllocator, &m_textureCopier)
+    {
+    }
+
+    FakeTextureAllocator& textureAllocator()
+    {
+        return m_textureAllocator;
+    }
+
+protected:
+    FakeTextureAllocator m_textureAllocator;
+    FakeTextureCopier m_textureCopier;
+};
+
 TEST(TiledLayerChromiumTest, pushDirtyTiles)
 {
     OwnPtr<TextureManager> textureManager = TextureManager::create(4*1024*1024, 2*1024*1024, 1024);
@@ -250,8 +273,7 @@ TEST(TiledLayerChromiumTest, pushDirtyTiles)
     DebugScopedSetImplThread implThread;
     OwnPtr<FakeCCTiledLayerImpl> layerImpl(adoptPtr(new FakeCCTiledLayerImpl(0)));
 
-    FakeTextureAllocator textureAllocator;
-    CCTextureUpdater updater(&textureAllocator);
+    FakeCCTextureUpdater updater;
 
     // The tile size is 100x100, so this invalidates and then paints two tiles.
     layer->setBounds(IntSize(100, 200));
@@ -286,8 +308,7 @@ TEST(TiledLayerChromiumTest, pushOccludedDirtyTiles)
     OwnPtr<FakeCCTiledLayerImpl> layerImpl(adoptPtr(new FakeCCTiledLayerImpl(0)));
     TestCCOcclusionTracker occluded;
 
-    FakeTextureAllocator textureAllocator;
-    CCTextureUpdater updater(&textureAllocator);
+    FakeCCTextureUpdater updater;
 
     // The tile size is 100x100, so this invalidates and then paints two tiles.
     layer->setBounds(IntSize(100, 200));
@@ -332,8 +353,7 @@ TEST(TiledLayerChromiumTest, pushDeletedTiles)
     DebugScopedSetImplThread implThread;
     OwnPtr<FakeCCTiledLayerImpl> layerImpl(adoptPtr(new FakeCCTiledLayerImpl(0)));
 
-    FakeTextureAllocator textureAllocator;
-    CCTextureUpdater updater(&textureAllocator);
+    FakeCCTextureUpdater updater;
 
     // The tile size is 100x100, so this invalidates and then paints two tiles.
     layer->setBounds(IntSize(100, 200));
@@ -346,7 +366,7 @@ TEST(TiledLayerChromiumTest, pushDeletedTiles)
     EXPECT_TRUE(layerImpl->hasTileAt(0, 0));
     EXPECT_TRUE(layerImpl->hasTileAt(0, 1));
 
-    textureManager->evictAndDeleteAllTextures(&textureAllocator);
+    textureManager->evictAndDeleteAllTextures(&updater.textureAllocator());
     textureManager->setMaxMemoryLimitBytes(4*1024*1024);
     textureManager->setPreferredMemoryLimitBytes(4*1024*1024);
 
@@ -374,8 +394,7 @@ TEST(TiledLayerChromiumTest, pushIdlePaintTiles)
     DebugScopedSetImplThread implThread;
     OwnPtr<FakeCCTiledLayerImpl> layerImpl(adoptPtr(new FakeCCTiledLayerImpl(0)));
 
-    FakeTextureAllocator textureAllocator;
-    CCTextureUpdater updater(&textureAllocator);
+    FakeCCTextureUpdater updater;
 
     // The tile size is 100x100. Setup 5x5 tiles with one visible tile in the center.
     IntSize contentBounds(500, 500);
@@ -433,8 +452,7 @@ TEST(TiledLayerChromiumTest, pushTilesAfterIdlePaintFailed)
     RefPtr<FakeTiledLayerChromium> layer2 = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
     OwnPtr<FakeCCTiledLayerImpl> layerImpl2(adoptPtr(new FakeCCTiledLayerImpl(0)));
 
-    FakeTextureAllocator textureAllocator;
-    CCTextureUpdater updater(&textureAllocator);
+    FakeCCTextureUpdater updater;
 
     // For this test we have two layers. layer1 exhausts most texture memory, leaving room for 2 more tiles from
     // layer2, but not all three tiles. First we paint layer1, and one tile from layer2. Then when we idle paint
@@ -514,8 +532,7 @@ TEST(TiledLayerChromiumTest, pushIdlePaintedOccludedTiles)
     OwnPtr<FakeCCTiledLayerImpl> layerImpl(adoptPtr(new FakeCCTiledLayerImpl(0)));
     TestCCOcclusionTracker occluded;
 
-    FakeTextureAllocator textureAllocator;
-    CCTextureUpdater updater(&textureAllocator);
+    FakeCCTextureUpdater updater;
 
     // The tile size is 100x100, so this invalidates one occluded tile, culls it during paint, but prepaints it.
     occluded.setOcclusion(IntRect(0, 0, 100, 100));
@@ -540,8 +557,7 @@ TEST(TiledLayerChromiumTest, pushTilesMarkedDirtyDuringPaint)
     DebugScopedSetImplThread implThread;
     OwnPtr<FakeCCTiledLayerImpl> layerImpl(adoptPtr(new FakeCCTiledLayerImpl(0)));
 
-    FakeTextureAllocator textureAllocator;
-    CCTextureUpdater updater(&textureAllocator);
+    FakeCCTextureUpdater updater;
 
     // The tile size is 100x100, so this invalidates and then paints two tiles.
     // However, during the paint, we invalidate one of the tiles. This should
@@ -567,8 +583,7 @@ TEST(TiledLayerChromiumTest, pushTilesLayerMarkedDirtyDuringPaintOnNextLayer)
     OwnPtr<FakeCCTiledLayerImpl> layer1Impl(adoptPtr(new FakeCCTiledLayerImpl(0)));
     OwnPtr<FakeCCTiledLayerImpl> layer2Impl(adoptPtr(new FakeCCTiledLayerImpl(0)));
 
-    FakeTextureAllocator textureAllocator;
-    CCTextureUpdater updater(&textureAllocator);
+    FakeCCTextureUpdater updater;
 
     layer1->setBounds(IntSize(100, 200));
     layer1->invalidateRect(IntRect(0, 0, 100, 200));
@@ -603,8 +618,7 @@ TEST(TiledLayerChromiumTest, pushTilesLayerMarkedDirtyDuringPaintOnPreviousLayer
     OwnPtr<FakeCCTiledLayerImpl> layer1Impl(adoptPtr(new FakeCCTiledLayerImpl(0)));
     OwnPtr<FakeCCTiledLayerImpl> layer2Impl(adoptPtr(new FakeCCTiledLayerImpl(0)));
 
-    FakeTextureAllocator textureAllocator;
-    CCTextureUpdater updater(&textureAllocator);
+    FakeCCTextureUpdater updater;
 
     layer1->setBounds(IntSize(100, 200));
     layer1->invalidateRect(IntRect(0, 0, 100, 200));
@@ -645,8 +659,7 @@ TEST(TiledLayerChromiumTest, idlePaintOutOfMemory)
     DebugScopedSetImplThread implThread;
     OwnPtr<FakeCCTiledLayerImpl> layerImpl(adoptPtr(new FakeCCTiledLayerImpl(0)));
 
-    FakeTextureAllocator textureAllocator;
-    CCTextureUpdater updater(&textureAllocator);
+    FakeCCTextureUpdater updater;
 
     // This invalidates 9 tiles and then paints one visible tile.
     layer->setBounds(contentBounds);
@@ -681,8 +694,7 @@ TEST(TiledLayerChromiumTest, idlePaintZeroSizedLayer)
     DebugScopedSetImplThread implThread;
     OwnPtr<FakeCCTiledLayerImpl> layerImpl(adoptPtr(new FakeCCTiledLayerImpl(0)));
 
-    FakeTextureAllocator textureAllocator;
-    CCTextureUpdater updater(&textureAllocator);
+    FakeCCTextureUpdater updater;
 
     // The layer's bounds are empty.
     IntRect contentRect;
@@ -724,8 +736,7 @@ TEST(TiledLayerChromiumTest, idlePaintZeroSizedAnimatingLayer)
     DebugScopedSetImplThread implThread;
     OwnPtr<FakeCCTiledLayerImpl> layerImpl(adoptPtr(new FakeCCTiledLayerImpl(0)));
 
-    FakeTextureAllocator textureAllocator;
-    CCTextureUpdater updater(&textureAllocator);
+    FakeCCTextureUpdater updater;
 
     // Pretend the layer is animating.
     layer->setDrawTransformIsAnimating(true);
@@ -773,8 +784,7 @@ TEST(TiledLayerChromiumTest, idlePaintNonVisibleLayers)
     DebugScopedSetImplThread implThread;
     OwnPtr<FakeCCTiledLayerImpl> layerImpl(adoptPtr(new FakeCCTiledLayerImpl(0)));
 
-    FakeTextureAllocator textureAllocator;
-    CCTextureUpdater updater(&textureAllocator);
+    FakeCCTextureUpdater updater;
 
     // Invalidate the layer but make none of it visible, so nothing paints.
     IntRect visibleRect;
@@ -828,8 +838,7 @@ TEST(TiledLayerChromiumTest, idlePaintNonVisibleAnimatingLayers)
     OwnPtr<TextureManager> textureManager = TextureManager::create(8000*8000*8, 8000*8000*4, 1024);
     DebugScopedSetImplThread implThread;
 
-    FakeTextureAllocator textureAllocator;
-    CCTextureUpdater updater(&textureAllocator);
+    FakeCCTextureUpdater updater;
 
     int tileWidth = FakeTiledLayerChromium::tileSize().width();
     int tileHeight = FakeTiledLayerChromium::tileSize().height();
@@ -886,8 +895,7 @@ TEST(TiledLayerChromiumTest, invalidateFromPrepare)
     DebugScopedSetImplThread implThread;
     OwnPtr<FakeCCTiledLayerImpl> layerImpl(adoptPtr(new FakeCCTiledLayerImpl(0)));
 
-    FakeTextureAllocator textureAllocator;
-    CCTextureUpdater updater(&textureAllocator);
+    FakeCCTextureUpdater updater;
 
     // The tile size is 100x100, so this invalidates and then paints two tiles.
     layer->setBounds(IntSize(100, 200));
@@ -928,8 +936,7 @@ TEST(TiledLayerChromiumTest, verifyUpdateRectWhenContentBoundsAreScaled)
     OwnPtr<TextureManager> textureManager = TextureManager::create(4*1024*1024, 2*1024*1024, 1024);
     RefPtr<FakeTiledLayerWithScaledBounds> layer = adoptRef(new FakeTiledLayerWithScaledBounds(textureManager.get()));
 
-    FakeTextureAllocator textureAllocator;
-    CCTextureUpdater updater(&textureAllocator);
+    FakeCCTextureUpdater updater;
 
     IntRect layerBounds(0, 0, 300, 200);
     IntRect contentBounds(0, 0, 200, 250);
@@ -966,8 +973,7 @@ TEST(TiledLayerChromiumTest, verifyInvalidationWhenContentsScaleChanges)
     DebugScopedSetImplThread implThread;
     OwnPtr<FakeCCTiledLayerImpl> layerImpl(adoptPtr(new FakeCCTiledLayerImpl(0)));
 
-    FakeTextureAllocator textureAllocator;
-    CCTextureUpdater updater(&textureAllocator);
+    FakeCCTextureUpdater updater;
 
     // Create a layer with one tile.
     layer->setBounds(IntSize(100, 100));
@@ -1037,8 +1043,7 @@ TEST(TiledLayerChromiumTest, skipsDrawGetsReset)
     rootLayer->invalidateRect(contentRect);
     childLayer->invalidateRect(contentRect);
 
-    FakeTextureAllocator textureAllocator;
-    CCTextureUpdater updater(&textureAllocator);
+    FakeCCTextureUpdater updater;
 
     ccLayerTreeHost->setRootLayer(rootLayer);
     ccLayerTreeHost->setViewportSize(IntSize(300, 300));
@@ -1096,8 +1101,7 @@ TEST(TiledLayerChromiumTest, partialUpdates)
     layer->setPosition(FloatPoint(150, 150));
     layer->invalidateRect(contentRect);
 
-    FakeTextureAllocator textureAllocator;
-    CCTextureUpdater updater(&textureAllocator);
+    FakeCCTextureUpdater updater;
 
     ccLayerTreeHost->setRootLayer(layer);
     ccLayerTreeHost->setViewportSize(IntSize(300, 200));