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

vangelis at chromium.org vangelis at chromium.org
Wed Dec 22 12:21:56 UTC 2010


The following commit has been merged in the debian/experimental branch:
commit 3ffb2e6b5bfffa83a2ade1cd862349764b32ca52
Author: vangelis at chromium.org <vangelis at chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Fri Aug 20 00:46:30 2010 +0000

    2010-08-19  Vangelis Kokkevis  <vangelis at chromium.org>
    
            Reviewed by Kenneth Russell.
    
            [chromium] Rearranging the accelerated compositing code such that the
            layer rendering logic now lives in the layer classes rather than the
            compositor. This lifts the restriction of having one texture per layer
            and significantly cleans up the compositor code. This change mostly
            resulted in a lot of code moving around files. Noteworthy changes
            include:
            * Made LayerChromium a proper based class for layers that mostly handles
              the updates to the layer properties and superlayer / sublayer updates.
            * Introduced a new layer type, ContentLayerChromium, which handles
              layers that require a GraphicsContext to render their content.
            * ImageLayerChromium and VideoLayerChromium now derive from
              ContentLayerChromium as they share the same shader and draw function.
            * Removed TransformLayerChromium as its functionality is now replaced by
              the base LayerChromium class.
            * Re-arranged the order in which the members of LayerChromium are defined
              in the header file to form a more reasonable logical grouping.
            * Changed LayerRendererChromium to use the shader creation and drawing
              methods defined in the layer classes. As a result, a lot of GL code was
              removed from the implementation file.
            * Eliminated randomly dispersed calls to check for GL errors by a macro (GLC)
              which allows turning error testing on/off with a single define (DEBUG_GL_CALLS
              defined in LayerRendererChromium.h)
            * Replaced the previous layer render loop with two traversals of the layer
              hierarchy, the first to update transforms and opacity values and the
              second to render the layers. Eliminated global Z sorting of all layers as
              it was wrong.
            https://bugs.webkit.org/show_bug.cgi?id=44148
    
            Test: Verified that pages using the compositor and compositor
                  layout tests have not regressed.
    
            * WebCore.gypi:
            * platform/graphics/chromium/CanvasLayerChromium.cpp:
            (WebCore::CanvasLayerChromium::SharedValues::SharedValues):
            (WebCore::CanvasLayerChromium::SharedValues::~SharedValues):
            (WebCore::CanvasLayerChromium::updateContents):
            (WebCore::CanvasLayerChromium::draw):
            * platform/graphics/chromium/CanvasLayerChromium.h:
            (WebCore::CanvasLayerChromium::SharedValues::canvasShaderProgram):
            (WebCore::CanvasLayerChromium::SharedValues::shaderSamplerLocation):
            (WebCore::CanvasLayerChromium::SharedValues::shaderMatrixLocation):
            (WebCore::CanvasLayerChromium::SharedValues::shaderAlphaLocation):
            (WebCore::CanvasLayerChromium::SharedValues::initialized):
            * platform/graphics/chromium/ContentLayerChromium.cpp: Added.
            (WebCore::ContentLayerChromium::SharedValues::SharedValues):
            (WebCore::ContentLayerChromium::SharedValues::~SharedValues):
            (WebCore::ContentLayerChromium::create):
            (WebCore::ContentLayerChromium::ContentLayerChromium):
            (WebCore::ContentLayerChromium::~ContentLayerChromium):
            (WebCore::ContentLayerChromium::updateContents):
            (WebCore::ContentLayerChromium::updateTextureRect):
            (WebCore::ContentLayerChromium::draw):
            * platform/graphics/chromium/ContentLayerChromium.h: Added.
            (WebCore::ContentLayerChromium::drawsContent):
            (WebCore::ContentLayerChromium::SharedValues::contentShaderProgram):
            (WebCore::ContentLayerChromium::SharedValues::shaderSamplerLocation):
            (WebCore::ContentLayerChromium::SharedValues::shaderMatrixLocation):
            (WebCore::ContentLayerChromium::SharedValues::shaderAlphaLocation):
            (WebCore::ContentLayerChromium::SharedValues::initialized):
            * platform/graphics/chromium/GraphicsLayerChromium.cpp:
            (WebCore::GraphicsLayerChromium::GraphicsLayerChromium):
            (WebCore::GraphicsLayerChromium::updateLayerPreserves3D):
            * platform/graphics/chromium/ImageLayerChromium.cpp:
            (WebCore::ImageLayerChromium::ImageLayerChromium):
            (WebCore::ImageLayerChromium::updateContents):
            * platform/graphics/chromium/ImageLayerChromium.h:
            * platform/graphics/chromium/LayerChromium.cpp:
            (WebCore::loadShader):
            (WebCore::LayerChromium::SharedValues::SharedValues):
            (WebCore::LayerChromium::SharedValues::~SharedValues):
            (WebCore::LayerChromium::LayerChromium):
            (WebCore::LayerChromium::~LayerChromium):
            (WebCore::LayerChromium::createShaderProgram):
            (WebCore::LayerChromium::toGLMatrix):
            (WebCore::LayerChromium::drawTexturedQuad):
            (WebCore::LayerChromium::drawDebugBorder):
            (WebCore::LayerChromium::prepareForDraw):
            * platform/graphics/chromium/LayerChromium.h:
            (WebCore::LayerChromium::getSublayers):
            (WebCore::LayerChromium::setPosition):
            (WebCore::LayerChromium::contentsDirty):
            (WebCore::LayerChromium::drawsContent):
            (WebCore::LayerChromium::updateContents):
            (WebCore::LayerChromium::draw):
            (WebCore::LayerChromium::SharedValues::quadVerticesVbo):
            (WebCore::LayerChromium::SharedValues::quadElementsVbo):
            (WebCore::LayerChromium::SharedValues::maxTextureSize):
            (WebCore::LayerChromium::SharedValues::borderShaderProgram):
            (WebCore::LayerChromium::SharedValues::borderShaderMatrixLocation):
            (WebCore::LayerChromium::SharedValues::borderShaderColorLocation):
            (WebCore::LayerChromium::SharedValues::initialized):
            (WebCore::LayerChromium::layerRenderer):
            * platform/graphics/chromium/LayerRendererChromium.cpp:
            (WebCore::LayerRendererChromium::LayerRendererChromium):
            (WebCore::LayerRendererChromium::~LayerRendererChromium):
            (WebCore::LayerRendererChromium::debugGLCall):
            (WebCore::LayerRendererChromium::useShader):
            (WebCore::LayerRendererChromium::drawLayers):
            (WebCore::LayerRendererChromium::createLayerTexture):
            (WebCore::LayerRendererChromium::updateLayersRecursive):
            (WebCore::LayerRendererChromium::drawLayersRecursive):
            (WebCore::LayerRendererChromium::drawLayer):
            (WebCore::LayerRendererChromium::checkTextureSize):
            (WebCore::LayerRendererChromium::initializeSharedObjects):
            (WebCore::LayerRendererChromium::cleanupSharedObjects):
            * platform/graphics/chromium/LayerRendererChromium.h:
            (WebCore::LayerRendererChromium::projectionMatrix):
            (WebCore::LayerRendererChromium::layerSharedValues):
            (WebCore::LayerRendererChromium::contentLayerSharedValues):
            (WebCore::LayerRendererChromium::canvasLayerSharedValues):
            * platform/graphics/chromium/TransformLayerChromium.cpp: Removed.
            * platform/graphics/chromium/TransformLayerChromium.h: Removed.
            * platform/graphics/chromium/VideoLayerChromium.cpp:
            (WebCore::VideoLayerChromium::VideoLayerChromium):
            (WebCore::VideoLayerChromium::updateContents):
            (WebCore::VideoLayerChromium::createTextureRect):
            * platform/graphics/chromium/VideoLayerChromium.h:
    
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@65717 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index d0108e8..d2b8c34 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,125 @@
+2010-08-19  Vangelis Kokkevis  <vangelis at chromium.org>
+
+        Reviewed by Kenneth Russell.
+
+        [chromium] Rearranging the accelerated compositing code such that the
+        layer rendering logic now lives in the layer classes rather than the
+        compositor. This lifts the restriction of having one texture per layer
+        and significantly cleans up the compositor code. This change mostly
+        resulted in a lot of code moving around files. Noteworthy changes
+        include:
+        * Made LayerChromium a proper based class for layers that mostly handles
+          the updates to the layer properties and superlayer / sublayer updates.
+        * Introduced a new layer type, ContentLayerChromium, which handles
+          layers that require a GraphicsContext to render their content.
+        * ImageLayerChromium and VideoLayerChromium now derive from
+          ContentLayerChromium as they share the same shader and draw function.
+        * Removed TransformLayerChromium as its functionality is now replaced by
+          the base LayerChromium class.
+        * Re-arranged the order in which the members of LayerChromium are defined
+          in the header file to form a more reasonable logical grouping.
+        * Changed LayerRendererChromium to use the shader creation and drawing
+          methods defined in the layer classes. As a result, a lot of GL code was
+          removed from the implementation file.
+        * Eliminated randomly dispersed calls to check for GL errors by a macro (GLC)
+          which allows turning error testing on/off with a single define (DEBUG_GL_CALLS
+          defined in LayerRendererChromium.h)
+        * Replaced the previous layer render loop with two traversals of the layer
+          hierarchy, the first to update transforms and opacity values and the
+          second to render the layers. Eliminated global Z sorting of all layers as
+          it was wrong.
+        https://bugs.webkit.org/show_bug.cgi?id=44148
+
+        Test: Verified that pages using the compositor and compositor
+              layout tests have not regressed.
+
+        * WebCore.gypi:
+        * platform/graphics/chromium/CanvasLayerChromium.cpp:
+        (WebCore::CanvasLayerChromium::SharedValues::SharedValues):
+        (WebCore::CanvasLayerChromium::SharedValues::~SharedValues):
+        (WebCore::CanvasLayerChromium::updateContents):
+        (WebCore::CanvasLayerChromium::draw):
+        * platform/graphics/chromium/CanvasLayerChromium.h:
+        (WebCore::CanvasLayerChromium::SharedValues::canvasShaderProgram):
+        (WebCore::CanvasLayerChromium::SharedValues::shaderSamplerLocation):
+        (WebCore::CanvasLayerChromium::SharedValues::shaderMatrixLocation):
+        (WebCore::CanvasLayerChromium::SharedValues::shaderAlphaLocation):
+        (WebCore::CanvasLayerChromium::SharedValues::initialized):
+        * platform/graphics/chromium/ContentLayerChromium.cpp: Added.
+        (WebCore::ContentLayerChromium::SharedValues::SharedValues):
+        (WebCore::ContentLayerChromium::SharedValues::~SharedValues):
+        (WebCore::ContentLayerChromium::create):
+        (WebCore::ContentLayerChromium::ContentLayerChromium):
+        (WebCore::ContentLayerChromium::~ContentLayerChromium):
+        (WebCore::ContentLayerChromium::updateContents):
+        (WebCore::ContentLayerChromium::updateTextureRect):
+        (WebCore::ContentLayerChromium::draw):
+        * platform/graphics/chromium/ContentLayerChromium.h: Added.
+        (WebCore::ContentLayerChromium::drawsContent):
+        (WebCore::ContentLayerChromium::SharedValues::contentShaderProgram):
+        (WebCore::ContentLayerChromium::SharedValues::shaderSamplerLocation):
+        (WebCore::ContentLayerChromium::SharedValues::shaderMatrixLocation):
+        (WebCore::ContentLayerChromium::SharedValues::shaderAlphaLocation):
+        (WebCore::ContentLayerChromium::SharedValues::initialized):
+        * platform/graphics/chromium/GraphicsLayerChromium.cpp:
+        (WebCore::GraphicsLayerChromium::GraphicsLayerChromium):
+        (WebCore::GraphicsLayerChromium::updateLayerPreserves3D):
+        * platform/graphics/chromium/ImageLayerChromium.cpp:
+        (WebCore::ImageLayerChromium::ImageLayerChromium):
+        (WebCore::ImageLayerChromium::updateContents):
+        * platform/graphics/chromium/ImageLayerChromium.h:
+        * platform/graphics/chromium/LayerChromium.cpp:
+        (WebCore::loadShader):
+        (WebCore::LayerChromium::SharedValues::SharedValues):
+        (WebCore::LayerChromium::SharedValues::~SharedValues):
+        (WebCore::LayerChromium::LayerChromium):
+        (WebCore::LayerChromium::~LayerChromium):
+        (WebCore::LayerChromium::createShaderProgram):
+        (WebCore::LayerChromium::toGLMatrix):
+        (WebCore::LayerChromium::drawTexturedQuad):
+        (WebCore::LayerChromium::drawDebugBorder):
+        (WebCore::LayerChromium::prepareForDraw):
+        * platform/graphics/chromium/LayerChromium.h:
+        (WebCore::LayerChromium::getSublayers):
+        (WebCore::LayerChromium::setPosition):
+        (WebCore::LayerChromium::contentsDirty):
+        (WebCore::LayerChromium::drawsContent):
+        (WebCore::LayerChromium::updateContents):
+        (WebCore::LayerChromium::draw):
+        (WebCore::LayerChromium::SharedValues::quadVerticesVbo):
+        (WebCore::LayerChromium::SharedValues::quadElementsVbo):
+        (WebCore::LayerChromium::SharedValues::maxTextureSize):
+        (WebCore::LayerChromium::SharedValues::borderShaderProgram):
+        (WebCore::LayerChromium::SharedValues::borderShaderMatrixLocation):
+        (WebCore::LayerChromium::SharedValues::borderShaderColorLocation):
+        (WebCore::LayerChromium::SharedValues::initialized):
+        (WebCore::LayerChromium::layerRenderer):
+        * platform/graphics/chromium/LayerRendererChromium.cpp:
+        (WebCore::LayerRendererChromium::LayerRendererChromium):
+        (WebCore::LayerRendererChromium::~LayerRendererChromium):
+        (WebCore::LayerRendererChromium::debugGLCall):
+        (WebCore::LayerRendererChromium::useShader):
+        (WebCore::LayerRendererChromium::drawLayers):
+        (WebCore::LayerRendererChromium::createLayerTexture):
+        (WebCore::LayerRendererChromium::updateLayersRecursive):
+        (WebCore::LayerRendererChromium::drawLayersRecursive):
+        (WebCore::LayerRendererChromium::drawLayer):
+        (WebCore::LayerRendererChromium::checkTextureSize):
+        (WebCore::LayerRendererChromium::initializeSharedObjects):
+        (WebCore::LayerRendererChromium::cleanupSharedObjects):
+        * platform/graphics/chromium/LayerRendererChromium.h:
+        (WebCore::LayerRendererChromium::projectionMatrix):
+        (WebCore::LayerRendererChromium::layerSharedValues):
+        (WebCore::LayerRendererChromium::contentLayerSharedValues):
+        (WebCore::LayerRendererChromium::canvasLayerSharedValues):
+        * platform/graphics/chromium/TransformLayerChromium.cpp: Removed.
+        * platform/graphics/chromium/TransformLayerChromium.h: Removed.
+        * platform/graphics/chromium/VideoLayerChromium.cpp:
+        (WebCore::VideoLayerChromium::VideoLayerChromium):
+        (WebCore::VideoLayerChromium::updateContents):
+        (WebCore::VideoLayerChromium::createTextureRect):
+        * platform/graphics/chromium/VideoLayerChromium.h:
+
 2010-08-19  David Kilzer  <ddkilzer at apple.com>
 
         BUILD FIX: Fix Mac build after Windows WebKit2 changes for Netscape Plug-ins
diff --git a/WebCore/WebCore.gypi b/WebCore/WebCore.gypi
index 26557d7..7175fb0 100644
--- a/WebCore/WebCore.gypi
+++ b/WebCore/WebCore.gypi
@@ -2231,6 +2231,8 @@
             'platform/graphics/cg/TransformationMatrixCG.cpp',
             'platform/graphics/chromium/CanvasLayerChromium.cpp',
             'platform/graphics/chromium/CanvasLayerChromium.h',
+            'platform/graphics/chromium/ContentLayerChromium.cpp',
+            'platform/graphics/chromium/ContentLayerChromium.h',
             'platform/graphics/chromium/FontCacheChromiumWin.cpp',
             'platform/graphics/chromium/FontCacheLinux.cpp',
             'platform/graphics/chromium/FontChromiumWin.cpp',
@@ -2270,8 +2272,6 @@
             'platform/graphics/chromium/SimpleFontDataLinux.cpp',
             'platform/graphics/chromium/TilingData.h',
             'platform/graphics/chromium/TilingData.cpp',
-            'platform/graphics/chromium/TransformLayerChromium.cpp',
-            'platform/graphics/chromium/TransformLayerChromium.h',
             'platform/graphics/chromium/TransparencyWin.cpp',
             'platform/graphics/chromium/TransparencyWin.h',
             'platform/graphics/chromium/UniscribeHelper.cpp',
diff --git a/WebCore/platform/graphics/chromium/CanvasLayerChromium.cpp b/WebCore/platform/graphics/chromium/CanvasLayerChromium.cpp
index 7e732d1..bbf091c 100644
--- a/WebCore/platform/graphics/chromium/CanvasLayerChromium.cpp
+++ b/WebCore/platform/graphics/chromium/CanvasLayerChromium.cpp
@@ -35,11 +35,63 @@
 #include "CanvasLayerChromium.h"
 
 #include "GraphicsContext3D.h"
+#include "LayerRendererChromium.h"
 #include <GLES2/gl2.h>
 
 namespace WebCore {
 
-unsigned CanvasLayerChromium::m_shaderProgramId = 0;
+CanvasLayerChromium::SharedValues::SharedValues()
+    : m_canvasShaderProgram(0)
+    , m_shaderSamplerLocation(-1)
+    , m_shaderMatrixLocation(-1)
+    , m_shaderAlphaLocation(-1)
+    , m_initialized(false)
+{
+    char vertexShaderString[] =
+        "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";
+
+    // Canvas layers need to be flipped vertically and their colors shouldn't be
+    // swizzled.
+    char fragmentShaderString[] =
+        "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, vec2(v_texCoord.x, 1.0 - v_texCoord.y)); \n"
+        "  gl_FragColor = vec4(texColor.x, texColor.y, texColor.z, texColor.w) * alpha; \n"
+        "}                                                   \n";
+
+    m_canvasShaderProgram = createShaderProgram(vertexShaderString, fragmentShaderString);
+    if (!m_canvasShaderProgram) {
+        LOG_ERROR("CanvasLayerChromium: Failed to create shader program");
+        return;
+    }
+
+    m_shaderSamplerLocation = glGetUniformLocation(m_canvasShaderProgram, "s_texture");
+    m_shaderMatrixLocation = glGetUniformLocation(m_canvasShaderProgram, "matrix");
+    m_shaderAlphaLocation = glGetUniformLocation(m_canvasShaderProgram, "alpha");
+    ASSERT(m_shaderSamplerLocation != -1);
+    ASSERT(m_shaderMatrixLocation != -1);
+    ASSERT(m_shaderAlphaLocation != -1);
+
+    m_initialized = true;
+}
+
+CanvasLayerChromium::SharedValues::~SharedValues()
+{
+    if (m_canvasShaderProgram)
+        GLC(glDeleteProgram(m_canvasShaderProgram));
+}
 
 PassRefPtr<CanvasLayerChromium> CanvasLayerChromium::create(GraphicsLayerChromium* owner)
 {
@@ -54,14 +106,8 @@ CanvasLayerChromium::CanvasLayerChromium(GraphicsLayerChromium* owner)
 {
 }
 
-unsigned CanvasLayerChromium::textureId()
-{
-    return m_textureId;
-}
-
-void CanvasLayerChromium::updateTextureContents(unsigned textureId)
+void CanvasLayerChromium::updateContents()
 {
-    ASSERT(textureId == m_textureId);
     ASSERT(m_context);
     if (m_textureChanged) {
         glBindTexture(GL_TEXTURE_2D, m_textureId);
@@ -92,5 +138,19 @@ void CanvasLayerChromium::setContext(const GraphicsContext3D* context)
     m_textureId = textureId;
 }
 
+void CanvasLayerChromium::draw()
+{
+    ASSERT(layerRenderer());
+    const CanvasLayerChromium::SharedValues* sv = layerRenderer()->canvasLayerSharedValues();
+    ASSERT(sv && sv->initialized());
+    GLC(glActiveTexture(GL_TEXTURE0));
+    GLC(glBindTexture(GL_TEXTURE_2D, m_textureId));
+    layerRenderer()->useShader(sv->canvasShaderProgram());
+    GLC(glUniform1i(sv->shaderSamplerLocation(), 0));
+    drawTexturedQuad(layerRenderer()->projectionMatrix(), drawTransform(),
+                     bounds().width(), bounds().height(), drawOpacity(),
+                     sv->shaderMatrixLocation(), sv->shaderAlphaLocation());
+}
+
 }
 #endif // USE(ACCELERATED_COMPOSITING)
diff --git a/WebCore/platform/graphics/chromium/CanvasLayerChromium.h b/WebCore/platform/graphics/chromium/CanvasLayerChromium.h
index 98be270..053efff 100644
--- a/WebCore/platform/graphics/chromium/CanvasLayerChromium.h
+++ b/WebCore/platform/graphics/chromium/CanvasLayerChromium.h
@@ -45,14 +45,29 @@ class CanvasLayerChromium : public LayerChromium {
 public:
     static PassRefPtr<CanvasLayerChromium> create(GraphicsLayerChromium* owner = 0);
     virtual bool drawsContent() { return m_context; }
-    virtual bool ownsTexture() { return true; }
-    virtual void updateTextureContents(unsigned);
-    virtual unsigned textureId();
-    virtual unsigned shaderProgramId() { return m_shaderProgramId; }
+    virtual void updateContents();
+    virtual void draw();
 
     void setContext(const GraphicsContext3D* context);
 
-    static void setShaderProgramId(unsigned shaderProgramId) { m_shaderProgramId = shaderProgramId; }
+    class SharedValues {
+    public:
+        SharedValues();
+        ~SharedValues();
+
+        unsigned canvasShaderProgram() const { return m_canvasShaderProgram; }
+        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:
+        unsigned m_canvasShaderProgram;
+        int m_shaderSamplerLocation;
+        int m_shaderMatrixLocation;
+        int m_shaderAlphaLocation;
+        bool m_initialized;
+    };
 
     class PrepareTextureCallback : public Noncopyable {
     public:
@@ -66,8 +81,6 @@ private:
     unsigned m_textureId;
     bool m_textureChanged;
     OwnPtr<PrepareTextureCallback> m_prepareTextureCallback;
-
-    static unsigned m_shaderProgramId;
 };
 
 }
diff --git a/WebCore/platform/graphics/chromium/ContentLayerChromium.cpp b/WebCore/platform/graphics/chromium/ContentLayerChromium.cpp
new file mode 100644
index 0000000..974933d
--- /dev/null
+++ b/WebCore/platform/graphics/chromium/ContentLayerChromium.cpp
@@ -0,0 +1,301 @@
+/*
+ * 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:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * 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.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
+ * OWNER OR 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 "ContentLayerChromium.h"
+
+#include "LayerRendererChromium.h"
+#include "RenderLayerBacking.h"
+
+#if PLATFORM(SKIA)
+#include "NativeImageSkia.h"
+#include "PlatformContextSkia.h"
+#include "skia/ext/platform_canvas.h"
+#elif PLATFORM(CG)
+#include <CoreGraphics/CGBitmapContext.h>
+#endif
+
+#include <GLES2/gl2.h>
+
+namespace WebCore {
+
+ContentLayerChromium::SharedValues::SharedValues()
+    : m_contentShaderProgram(0)
+    , m_shaderSamplerLocation(-1)
+    , m_shaderMatrixLocation(-1)
+    , m_shaderAlphaLocation(-1)
+    , m_initialized(false)
+{
+    // Shaders for drawing the layer contents.
+    char vertexShaderString[] =
+        "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";
+
+    // Note differences between Skia and Core Graphics versions:
+    //  - Skia uses BGRA and origin is upper left
+    //  - Core Graphics uses RGBA and origin is lower left
+    char fragmentShaderString[] =
+        "precision mediump float;                            \n"
+        "varying vec2 v_texCoord;                            \n"
+        "uniform sampler2D s_texture;                        \n"
+        "uniform float alpha;                                \n"
+        "void main()                                         \n"
+        "{                                                   \n"
+#if PLATFORM(SKIA)
+        "  vec4 texColor = texture2D(s_texture, v_texCoord); \n"
+        "  gl_FragColor = vec4(texColor.z, texColor.y, texColor.x, texColor.w) * alpha; \n"
+#elif PLATFORM(CG)
+        "  vec4 texColor = texture2D(s_texture, vec2(v_texCoord.x, 1.0 - v_texCoord.y)); \n"
+        "  gl_FragColor = vec4(texColor.x, texColor.y, texColor.z, texColor.w) * alpha; \n"
+#else
+#error "Need to implement for your platform."
+#endif
+        "}                                                   \n";
+
+    m_contentShaderProgram = createShaderProgram(vertexShaderString, fragmentShaderString);
+    if (!m_contentShaderProgram) {
+        LOG_ERROR("ContentLayerChromium: Failed to create shader program");
+        return;
+    }
+
+    m_shaderSamplerLocation = glGetUniformLocation(m_contentShaderProgram, "s_texture");
+    m_shaderMatrixLocation = glGetUniformLocation(m_contentShaderProgram, "matrix");
+    m_shaderAlphaLocation = glGetUniformLocation(m_contentShaderProgram, "alpha");
+    ASSERT(m_shaderSamplerLocation != -1);
+    ASSERT(m_shaderMatrixLocation != -1);
+    ASSERT(m_shaderAlphaLocation != -1);
+
+    m_initialized = true;
+}
+
+ContentLayerChromium::SharedValues::~SharedValues()
+{
+    if (m_contentShaderProgram)
+        GLC(glDeleteProgram(m_contentShaderProgram));
+}
+
+
+PassRefPtr<ContentLayerChromium> ContentLayerChromium::create(GraphicsLayerChromium* owner)
+{
+    return adoptRef(new ContentLayerChromium(owner));
+}
+
+ContentLayerChromium::ContentLayerChromium(GraphicsLayerChromium* owner)
+    : LayerChromium(owner)
+    , m_contentsTexture(0)
+{
+}
+
+ContentLayerChromium::~ContentLayerChromium()
+{
+    if (m_contentsTexture)
+        GLC(glDeleteTextures(1, &m_contentsTexture));
+}
+
+
+void ContentLayerChromium::updateContents()
+{
+    RenderLayerBacking* backing = static_cast<RenderLayerBacking*>(m_owner->client());
+    if (!backing || backing->paintingGoesToWindow())
+        return;
+
+    ASSERT(drawsContent());
+
+    ASSERT(layerRenderer());
+
+    // FIXME: Remove this test when tiled layers are implemented.
+    m_skipsDraw = false;
+    if (!layerRenderer()->checkTextureSize(m_bounds)) {
+        m_skipsDraw = true;
+        return;
+    }
+
+    void* pixels = 0;
+    IntRect dirtyRect(m_dirtyRect);
+    IntSize requiredTextureSize;
+    IntSize bitmapSize;
+
+#if PLATFORM(SKIA)
+    const SkBitmap* skiaBitmap = 0;
+    OwnPtr<skia::PlatformCanvas> canvas;
+    OwnPtr<PlatformContextSkia> skiaContext;
+    OwnPtr<GraphicsContext> graphicsContext;
+
+    requiredTextureSize = m_bounds;
+    IntRect boundsRect(IntPoint(0, 0), m_bounds);
+
+    // If the texture needs to be reallocated then we must redraw the entire
+    // contents of the layer.
+    if (requiredTextureSize != m_allocatedTextureSize)
+        dirtyRect = boundsRect;
+    else {
+        // Clip the dirtyRect to the size of the layer to avoid drawing outside
+        // the bounds of the backing texture.
+        dirtyRect.intersect(boundsRect);
+    }
+
+    canvas.set(new skia::PlatformCanvas(dirtyRect.width(), dirtyRect.height(), false));
+    skiaContext.set(new PlatformContextSkia(canvas.get()));
+
+#if OS(WINDOWS)
+    // This is needed to get text to show up correctly. Without it,
+    // GDI renders with zero alpha and the text becomes invisible.
+    // Unfortunately, setting this to true disables cleartype.
+    // FIXME: Does this take us down a very slow text rendering path?
+    // FIXME: why is this is a windows-only call ?
+    skiaContext->setDrawingToImageBuffer(true);
+#endif
+
+    graphicsContext.set(new GraphicsContext(reinterpret_cast<PlatformGraphicsContext*>(skiaContext.get())));
+
+    // Bring the canvas into the coordinate system of the paint rect.
+    canvas->translate(static_cast<SkScalar>(-dirtyRect.x()), static_cast<SkScalar>(-dirtyRect.y()));
+
+    m_owner->paintGraphicsLayerContents(*graphicsContext, dirtyRect);
+    const SkBitmap& bitmap = canvas->getDevice()->accessBitmap(false);
+    skiaBitmap = &bitmap;
+    ASSERT(skiaBitmap);
+
+    SkAutoLockPixels lock(*skiaBitmap);
+    SkBitmap::Config skiaConfig = skiaBitmap->config();
+    // FIXME: do we need to support more image configurations?
+    if (skiaConfig == SkBitmap::kARGB_8888_Config) {
+        pixels = skiaBitmap->getPixels();
+        bitmapSize = IntSize(skiaBitmap->width(), skiaBitmap->height());
+    }
+#elif PLATFORM(CG)
+    requiredTextureSize = m_bounds;
+    IntRect boundsRect(IntPoint(0, 0), m_bounds);
+
+    // If the texture needs to be reallocated then we must redraw the entire
+    // contents of the layer.
+    if (requiredTextureSize != m_allocatedTextureSize)
+        dirtyRect = boundsRect;
+    else {
+        // Clip the dirtyRect to the size of the layer to avoid drawing outside
+        // the bounds of the backing texture.
+        dirtyRect.intersect(boundsRect);
+    }
+
+    Vector<uint8_t> tempVector;
+    int rowBytes = 4 * dirtyRect.width();
+    tempVector.resize(rowBytes * dirtyRect.height());
+    memset(tempVector.data(), 0, tempVector.size());
+    RetainPtr<CGColorSpaceRef> colorSpace(AdoptCF, CGColorSpaceCreateDeviceRGB());
+    RetainPtr<CGContextRef> contextCG(AdoptCF, CGBitmapContextCreate(tempVector.data(),
+                                                                     dirtyRect.width(), dirtyRect.height(), 8, rowBytes,
+                                                                     colorSpace.get(),
+                                                                     kCGImageAlphaPremultipliedLast));
+
+    GraphicsContext graphicsContext(contextCG.get());
+
+    // Translate the graphics contxt into the coordinate system of the dirty rect.
+    graphicsContext.translate(-dirtyRect.x(), -dirtyRect.y());
+
+    m_owner->paintGraphicsLayerContents(graphicsContext, dirtyRect);
+
+    pixels = tempVector.data();
+    bitmapSize = dirtyRect.size();
+#else
+#error "Need to implement for your platform."
+#endif
+
+    unsigned textureId = m_contentsTexture;
+    if (!textureId)
+        textureId = layerRenderer()->createLayerTexture();
+
+    if (pixels)
+        updateTextureRect(pixels, bitmapSize, requiredTextureSize,  dirtyRect, textureId);
+}
+
+void ContentLayerChromium::updateTextureRect(void* pixels, const IntSize& bitmapSize, const IntSize& requiredTextureSize, const IntRect& updateRect, unsigned textureId)
+{
+    if (!pixels)
+        return;
+
+    glBindTexture(GL_TEXTURE_2D, textureId);
+
+    // 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(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, requiredTextureSize.width(), requiredTextureSize.height(), 0, GL_RGBA, GL_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());
+#if PLATFORM(CG)
+        // The origin is at the lower left in Core Graphics' coordinate system. We need to correct for this here.
+        GLC(glTexSubImage2D(GL_TEXTURE_2D, 0,
+                            updateRect.x(), m_allocatedTextureSize.height() - updateRect.height() - updateRect.y(),
+                            updateRect.width(), updateRect.height(),
+                            GL_RGBA, GL_UNSIGNED_BYTE, pixels));
+#elif PLATFORM(SKIA)
+        GLC(glTexSubImage2D(GL_TEXTURE_2D, 0, updateRect.x(), updateRect.y(), updateRect.width(), updateRect.height(), GL_RGBA, GL_UNSIGNED_BYTE, pixels));
+#else
+#error "Need to implement for your platform."
+#endif
+    }
+
+    m_dirtyRect.setSize(FloatSize());
+    m_contentsDirty = false;
+}
+
+void ContentLayerChromium::draw()
+{
+    if (m_skipsDraw)
+        return;
+
+    ASSERT(layerRenderer());
+    const ContentLayerChromium::SharedValues* sv = layerRenderer()->contentLayerSharedValues();
+    ASSERT(sv && sv->initialized());
+    GLC(glActiveTexture(GL_TEXTURE0));
+    GLC(glBindTexture(GL_TEXTURE_2D, m_contentsTexture));
+    layerRenderer()->useShader(sv->contentShaderProgram());
+    GLC(glUniform1i(sv->shaderSamplerLocation(), 0));
+    drawTexturedQuad(layerRenderer()->projectionMatrix(), drawTransform(),
+                     bounds().width(), bounds().height(), drawOpacity(),
+                     sv->shaderMatrixLocation(), sv->shaderAlphaLocation());
+}
+
+}
+#endif // USE(ACCELERATED_COMPOSITING)
diff --git a/WebCore/platform/graphics/chromium/ContentLayerChromium.h b/WebCore/platform/graphics/chromium/ContentLayerChromium.h
new file mode 100644
index 0000000..3e15372
--- /dev/null
+++ b/WebCore/platform/graphics/chromium/ContentLayerChromium.h
@@ -0,0 +1,90 @@
+/*
+ * 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:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * 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.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
+ * OWNER OR 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 ContentLayerChromium_h
+#define ContentLayerChromium_h
+
+#if USE(ACCELERATED_COMPOSITING)
+
+#include "LayerChromium.h"
+
+namespace WebCore {
+
+// A Layer that requires a GraphicsContext to render its contents.
+class ContentLayerChromium : public LayerChromium {
+    friend class LayerRendererChromium;
+public:
+    static PassRefPtr<ContentLayerChromium> create(GraphicsLayerChromium* owner = 0);
+
+    ~ContentLayerChromium();
+
+    virtual void updateContents();
+    virtual void draw();
+    virtual bool drawsContent() { return m_owner && m_owner->drawsContent(); }
+
+    // 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:
+        SharedValues();
+        ~SharedValues();
+
+        unsigned contentShaderProgram() const { return m_contentShaderProgram; }
+        int shaderSamplerLocation() const { return m_shaderSamplerLocation; }
+        int shaderMatrixLocation() const { return m_shaderMatrixLocation; }
+        int shaderAlphaLocation() const { return m_shaderAlphaLocation; }
+        int initialized() const { return m_initialized; }
+
+    private:
+        unsigned m_contentShaderProgram;
+        int m_shaderSamplerLocation;
+        int m_shaderMatrixLocation;
+        int m_shaderAlphaLocation;
+        int m_initialized;
+    };
+
+protected:
+    ContentLayerChromium(GraphicsLayerChromium* owner);
+
+    void updateTextureRect(void* pixels, const IntSize& bitmapSize, const IntSize& requiredTextureSize,
+                           const IntRect& updateRect, unsigned textureId);
+
+    unsigned m_contentsTexture;
+    IntSize m_allocatedTextureSize;
+    bool m_skipsDraw;
+
+};
+
+}
+#endif // USE(ACCELERATED_COMPOSITING)
+
+#endif
diff --git a/WebCore/platform/graphics/chromium/GraphicsLayerChromium.cpp b/WebCore/platform/graphics/chromium/GraphicsLayerChromium.cpp
index 1d67857..648e35f 100644
--- a/WebCore/platform/graphics/chromium/GraphicsLayerChromium.cpp
+++ b/WebCore/platform/graphics/chromium/GraphicsLayerChromium.cpp
@@ -45,6 +45,7 @@
 
 #include "GraphicsLayerChromium.h"
 
+#include "ContentLayerChromium.h"
 #include "FloatConversion.h"
 #include "FloatRect.h"
 #include "Image.h"
@@ -52,7 +53,6 @@
 #include "LayerChromium.h"
 #include "PlatformString.h"
 #include "SystemTime.h"
-#include "TransformLayerChromium.h"
 
 #include <wtf/CurrentTime.h>
 #include <wtf/StringExtras.h>
@@ -97,7 +97,7 @@ GraphicsLayerChromium::GraphicsLayerChromium(GraphicsLayerClient* client)
     , m_contentsLayerPurpose(NoContentsLayer)
     , m_contentsLayerHasBackgroundColor(false)
 {
-    m_layer = LayerChromium::create(this);
+    m_layer = ContentLayerChromium::create(this);
 
     updateDebugIndicators();
 }
@@ -538,7 +538,7 @@ void GraphicsLayerChromium::updateLayerPreserves3D()
 {
     if (m_preserves3D && !m_transformLayer) {
         // Create the transform layer.
-        m_transformLayer = TransformLayerChromium::create(this);
+        m_transformLayer = LayerChromium::create(this);
 
         // Copy the position from this layer.
         updateLayerPosition();
diff --git a/WebCore/platform/graphics/chromium/ImageLayerChromium.cpp b/WebCore/platform/graphics/chromium/ImageLayerChromium.cpp
index 3cc7cad..09b388d 100644
--- a/WebCore/platform/graphics/chromium/ImageLayerChromium.cpp
+++ b/WebCore/platform/graphics/chromium/ImageLayerChromium.cpp
@@ -34,6 +34,8 @@
 
 #include "ImageLayerChromium.h"
 
+#include "LayerRendererChromium.h"
+
 #if PLATFORM(SKIA)
 #include "NativeImageSkia.h"
 #include "PlatformContextSkia.h"
@@ -54,7 +56,7 @@ PassRefPtr<ImageLayerChromium> ImageLayerChromium::create(GraphicsLayerChromium*
 }
 
 ImageLayerChromium::ImageLayerChromium(GraphicsLayerChromium* owner)
-    : LayerChromium(owner)
+    : ContentLayerChromium(owner)
     , m_contents(0)
 {
 }
@@ -68,8 +70,10 @@ void ImageLayerChromium::setContents(NativeImagePtr contents)
     setNeedsDisplay();
 }
 
-void ImageLayerChromium::updateTextureContents(unsigned textureId)
+void ImageLayerChromium::updateContents()
 {
+    ASSERT(layerRenderer());
+
     void* pixels = 0;
     IntRect dirtyRect(m_dirtyRect);
     IntSize requiredTextureSize;
@@ -129,6 +133,17 @@ void ImageLayerChromium::updateTextureContents(unsigned textureId)
 #else
 #error "Need to implement for your platform."
 #endif
+    // FIXME: Remove this test when tiled layers are implemented.
+    m_skipsDraw = false;
+    if (!layerRenderer()->checkTextureSize(requiredTextureSize)) {
+        m_skipsDraw = true;
+        return;
+    }
+
+    unsigned textureId = m_contentsTexture;
+    if (!textureId)
+        textureId = layerRenderer()->createLayerTexture();
+
     if (pixels)
         updateTextureRect(pixels, bitmapSize, requiredTextureSize,  dirtyRect, textureId);
 }
diff --git a/WebCore/platform/graphics/chromium/ImageLayerChromium.h b/WebCore/platform/graphics/chromium/ImageLayerChromium.h
index 9355b2d..e95284c 100644
--- a/WebCore/platform/graphics/chromium/ImageLayerChromium.h
+++ b/WebCore/platform/graphics/chromium/ImageLayerChromium.h
@@ -34,16 +34,18 @@
 
 #if USE(ACCELERATED_COMPOSITING)
 
-#include "LayerChromium.h"
+#include "ContentLayerChromium.h"
 
 namespace WebCore {
 
 // A Layer that contains only an Image element.
-class ImageLayerChromium : public LayerChromium {
+class ImageLayerChromium : public ContentLayerChromium {
 public:
     static PassRefPtr<ImageLayerChromium> create(GraphicsLayerChromium* owner = 0);
+
+    virtual void updateContents();
     virtual bool drawsContent() { return m_contents; }
-    virtual void updateTextureContents(unsigned textureId);
+
     void setContents(NativeImagePtr);
 
 private:
diff --git a/WebCore/platform/graphics/chromium/LayerChromium.cpp b/WebCore/platform/graphics/chromium/LayerChromium.cpp
index 21d8d12..3553878 100644
--- a/WebCore/platform/graphics/chromium/LayerChromium.cpp
+++ b/WebCore/platform/graphics/chromium/LayerChromium.cpp
@@ -48,7 +48,93 @@ namespace WebCore {
 
 using namespace std;
 
-unsigned LayerChromium::m_shaderProgramId = 0;
+const unsigned LayerChromium::s_positionAttribLocation = 0;
+const unsigned LayerChromium::s_texCoordAttribLocation = 1;
+
+static GLuint loadShader(GLenum type, const char* shaderSource)
+{
+    GLuint shader = glCreateShader(type);
+    if (!shader)
+        return 0;
+    GLC(glShaderSource(shader, 1, &shaderSource, 0));
+    GLC(glCompileShader(shader));
+    GLint compiled;
+    GLC(glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled));
+    if (!compiled) {
+        GLC(glDeleteShader(shader));
+        return 0;
+    }
+    return shader;
+}
+
+LayerChromium::SharedValues::SharedValues()
+    : m_quadVerticesVbo(0)
+    , m_quadElementsVbo(0)
+    , m_maxTextureSize(0)
+    , m_borderShaderProgram(0)
+    , m_borderShaderMatrixLocation(-1)
+    , m_borderShaderColorLocation(-1)
+    , m_initialized(false)
+{
+    // Vertex positions and texture coordinates for the 4 corners of a 1x1 quad.
+    GLfloat vertices[] = { -0.5f,  0.5f, 0.0f, 0.0f,  1.0f,
+                           -0.5f, -0.5f, 0.0f, 0.0f,  0.0f,
+                            0.5f, -0.5f, 0.0f, 1.0f,  0.0f,
+                            0.5f,  0.5f, 0.0f, 1.0f,  1.0f };
+    GLushort indices[] = { 0, 1, 2, 0, 2, 3, // The two triangles that make up the layer quad.
+                           0, 1, 2, 3}; // A line path for drawing the layer border.
+
+    GLuint vboIds[2];
+    GLC(glGenBuffers(2, vboIds));
+    m_quadVerticesVbo = vboIds[0];
+    m_quadElementsVbo = vboIds[1];
+    GLC(glBindBuffer(GL_ARRAY_BUFFER, m_quadVerticesVbo));
+    GLC(glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW));
+    GLC(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_quadElementsVbo));
+    GLC(glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW));
+
+    // Get the max texture size supported by the system.
+    GLC(glGetIntegerv(GL_MAX_TEXTURE_SIZE, &m_maxTextureSize));
+
+    // Shaders for drawing the debug borders around the layers.
+    char borderVertexShaderString[] =
+        "attribute vec4 a_position;   \n"
+        "uniform mat4 matrix;         \n"
+        "void main()                  \n"
+        "{                            \n"
+        "   gl_Position = matrix * a_position; \n"
+        "}                            \n";
+    char borderFragmentShaderString[] =
+        "precision mediump float;                            \n"
+        "uniform vec4 color;                                 \n"
+        "void main()                                         \n"
+        "{                                                   \n"
+        "  gl_FragColor = color;                             \n"
+        "}                                                   \n";
+
+    m_borderShaderProgram = createShaderProgram(borderVertexShaderString, borderFragmentShaderString);
+    if (!m_borderShaderProgram) {
+        LOG_ERROR("ContentLayerChromium: Failed to create shader program");
+        return;
+    }
+
+    m_borderShaderMatrixLocation = glGetUniformLocation(m_borderShaderProgram, "matrix");
+    m_borderShaderColorLocation = glGetUniformLocation(m_borderShaderProgram, "color");
+    ASSERT(m_borderShaderMatrixLocation != -1);
+    ASSERT(m_borderShaderColorLocation != -1);
+
+    m_initialized = true;
+}
+
+LayerChromium::SharedValues::~SharedValues()
+{
+    GLuint vboIds[2] = { m_quadVerticesVbo, m_quadElementsVbo };
+    GLC(glDeleteBuffers(2, vboIds));
+
+    if (m_borderShaderProgram)
+        GLC(glDeleteProgram(m_borderShaderProgram));
+}
+
 
 PassRefPtr<LayerChromium> LayerChromium::create(GraphicsLayerChromium* owner)
 {
@@ -62,13 +148,10 @@ LayerChromium::LayerChromium(GraphicsLayerChromium* owner)
     , m_anchorPoint(0.5, 0.5)
     , m_backgroundColor(0, 0, 0, 0)
     , m_borderColor(0, 0, 0, 0)
-    , m_layerRenderer(0)
-    , m_edgeAntialiasingMask(0)
     , m_opacity(1.0)
     , m_zPosition(0.0)
     , m_anchorPointZ(0)
     , m_borderWidth(0)
-    , m_allocatedTextureId(0)
     , m_clearsContext(false)
     , m_doubleSided(true)
     , m_hidden(false)
@@ -76,6 +159,7 @@ LayerChromium::LayerChromium(GraphicsLayerChromium* owner)
     , m_opaque(true)
     , m_geometryFlipped(false)
     , m_needsDisplayOnBoundsChange(false)
+    , m_layerRenderer(0)
 {
 }
 
@@ -87,10 +171,6 @@ LayerChromium::~LayerChromium()
 
     // Remove the superlayer reference from all sublayers.
     removeAllSublayers();
-
-    // Notify the renderer to clean up the texture associated with the layer.
-    if (m_layerRenderer)
-        m_layerRenderer->freeLayerTexture(this);
 }
 
 void LayerChromium::setLayerRenderer(LayerRendererChromium* renderer)
@@ -101,140 +181,46 @@ void LayerChromium::setLayerRenderer(LayerRendererChromium* renderer)
     m_layerRenderer = renderer;
 }
 
-void LayerChromium::updateTextureContents(unsigned textureId)
+unsigned LayerChromium::createShaderProgram(const char* vertexShaderSource, const char* fragmentShaderSource)
 {
-    RenderLayerBacking* backing = static_cast<RenderLayerBacking*>(m_owner->client());
-    if (!backing || backing->paintingGoesToWindow())
-        return;
-
-    ASSERT(drawsContent());
-
-    void* pixels = 0;
-    IntRect dirtyRect(m_dirtyRect);
-    IntSize requiredTextureSize;
-    IntSize bitmapSize;
-
-#if PLATFORM(SKIA)
-    const SkBitmap* skiaBitmap = 0;
-    OwnPtr<skia::PlatformCanvas> canvas;
-    OwnPtr<PlatformContextSkia> skiaContext;
-    OwnPtr<GraphicsContext> graphicsContext;
-
-    requiredTextureSize = m_bounds;
-    IntRect boundsRect(IntPoint(0, 0), m_bounds);
-
-    // If the texture needs to be reallocated then we must redraw the entire
-    // contents of the layer.
-    if (requiredTextureSize != m_allocatedTextureSize)
-        dirtyRect = boundsRect;
-    else {
-        // Clip the dirtyRect to the size of the layer to avoid drawing outside
-        // the bounds of the backing texture.
-        dirtyRect.intersect(boundsRect);
+    GLuint vertexShader = loadShader(GL_VERTEX_SHADER, vertexShaderSource);
+    if (!vertexShader) {
+        LOG_ERROR("Failed to create vertex shader");
+        return 0;
     }
 
-    canvas.set(new skia::PlatformCanvas(dirtyRect.width(), dirtyRect.height(), false));
-    skiaContext.set(new PlatformContextSkia(canvas.get()));
-
-#if OS(WINDOWS)
-    // This is needed to get text to show up correctly. Without it,
-    // GDI renders with zero alpha and the text becomes invisible.
-    // Unfortunately, setting this to true disables cleartype.
-    // FIXME: Does this take us down a very slow text rendering path?
-    // FIXME: why is this is a windows-only call ?
-    skiaContext->setDrawingToImageBuffer(true);
-#endif
-
-    graphicsContext.set(new GraphicsContext(reinterpret_cast<PlatformGraphicsContext*>(skiaContext.get())));
-
-    // Bring the canvas into the coordinate system of the paint rect.
-    canvas->translate(static_cast<SkScalar>(-dirtyRect.x()), static_cast<SkScalar>(-dirtyRect.y()));
-
-    m_owner->paintGraphicsLayerContents(*graphicsContext, dirtyRect);
-    const SkBitmap& bitmap = canvas->getDevice()->accessBitmap(false);
-    skiaBitmap = &bitmap;
-    ASSERT(skiaBitmap);
-
-    SkAutoLockPixels lock(*skiaBitmap);
-    SkBitmap::Config skiaConfig = skiaBitmap->config();
-    // FIXME: do we need to support more image configurations?
-    if (skiaConfig == SkBitmap::kARGB_8888_Config) {
-        pixels = skiaBitmap->getPixels();
-        bitmapSize = IntSize(skiaBitmap->width(), skiaBitmap->height());
-    }
-#elif PLATFORM(CG)
-    requiredTextureSize = m_bounds;
-    IntRect boundsRect(IntPoint(0, 0), m_bounds);
-
-    // If the texture needs to be reallocated then we must redraw the entire
-    // contents of the layer.
-    if (requiredTextureSize != m_allocatedTextureSize)
-        dirtyRect = boundsRect;
-    else {
-        // Clip the dirtyRect to the size of the layer to avoid drawing outside
-        // the bounds of the backing texture.
-        dirtyRect.intersect(boundsRect);
+    GLuint fragmentShader = loadShader(GL_FRAGMENT_SHADER, fragmentShaderSource);
+    if (!fragmentShader) {
+        GLC(glDeleteShader(vertexShader));
+        LOG_ERROR("Failed to create fragment shader");
+        return 0;
     }
 
-    Vector<uint8_t> tempVector;
-    int rowBytes = 4 * dirtyRect.width();
-    tempVector.resize(rowBytes * dirtyRect.height());
-    memset(tempVector.data(), 0, tempVector.size());
-    RetainPtr<CGColorSpaceRef> colorSpace(AdoptCF, CGColorSpaceCreateDeviceRGB());
-    RetainPtr<CGContextRef> contextCG(AdoptCF, CGBitmapContextCreate(tempVector.data(),
-                                                                     dirtyRect.width(), dirtyRect.height(), 8, rowBytes,
-                                                                     colorSpace.get(),
-                                                                     kCGImageAlphaPremultipliedLast));
-
-    GraphicsContext graphicsContext(contextCG.get());
-
-    // Translate the graphics contxt into the coordinate system of the dirty rect.
-    graphicsContext.translate(-dirtyRect.x(), -dirtyRect.y());
-
-    m_owner->paintGraphicsLayerContents(graphicsContext, dirtyRect);
-
-    pixels = tempVector.data();
-    bitmapSize = dirtyRect.size();
-#else
-#error "Need to implement for your platform."
-#endif
+    GLuint programObject = glCreateProgram();
+    if (!programObject) {
+        LOG_ERROR("Failed to create shader program");
+        return 0;
+    }
 
-    if (pixels)
-        updateTextureRect(pixels, bitmapSize, requiredTextureSize,  dirtyRect, textureId);
-}
+    GLC(glAttachShader(programObject, vertexShader));
+    GLC(glAttachShader(programObject, fragmentShader));
 
-void LayerChromium::updateTextureRect(void* pixels, const IntSize& bitmapSize, const IntSize& requiredTextureSize, const IntRect& updateRect, unsigned textureId)
-{
-    if (!pixels)
-        return;
+    // Bind the common attrib locations.
+    GLC(glBindAttribLocation(programObject, s_positionAttribLocation, "a_position"));
+    GLC(glBindAttribLocation(programObject, s_texCoordAttribLocation, "a_texCoord"));
 
-    glBindTexture(GL_TEXTURE_2D, textureId);
-    // If the texture id or size changed since last time then we need to tell GL
-    // to re-allocate a texture.
-    if (m_allocatedTextureId != textureId || requiredTextureSize != m_allocatedTextureSize) {
-        ASSERT(bitmapSize == requiredTextureSize);
-        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, requiredTextureSize.width(), requiredTextureSize.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
-
-        m_allocatedTextureId = 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());
-#if PLATFORM(CG)
-        // The origin is at the lower left in Core Graphics' coordinate system. We need to correct for this here.
-        glTexSubImage2D(GL_TEXTURE_2D, 0,
-                        updateRect.x(), m_allocatedTextureSize.height() - updateRect.height() - updateRect.y(),
-                        updateRect.width(), updateRect.height(),
-                        GL_RGBA, GL_UNSIGNED_BYTE, pixels);
-#elif PLATFORM(SKIA)
-        glTexSubImage2D(GL_TEXTURE_2D, 0, updateRect.x(), updateRect.y(), updateRect.width(), updateRect.height(), GL_RGBA, GL_UNSIGNED_BYTE, pixels);
-#else
-#error "Need to implement for your platform."
-#endif
+    GLC(glLinkProgram(programObject));
+    GLint linked;
+    GLC(glGetProgramiv(programObject, GL_LINK_STATUS, &linked));
+    if (!linked) {
+        LOG_ERROR("Failed to link shader program");
+        GLC(glDeleteProgram(programObject));
+        return 0;
     }
 
-    m_dirtyRect.setSize(FloatSize());
-    m_contentsDirty = false;
+    GLC(glDeleteShader(vertexShader));
+    GLC(glDeleteShader(fragmentShader));
+    return programObject;
 }
 
 void LayerChromium::setNeedsCommit()
@@ -377,5 +363,86 @@ void LayerChromium::setNeedsDisplay()
     m_contentsDirty = true;
 }
 
+void LayerChromium::toGLMatrix(float* flattened, const TransformationMatrix& m)
+{
+    flattened[0] = m.m11();
+    flattened[1] = m.m12();
+    flattened[2] = m.m13();
+    flattened[3] = m.m14();
+    flattened[4] = m.m21();
+    flattened[5] = m.m22();
+    flattened[6] = m.m23();
+    flattened[7] = m.m24();
+    flattened[8] = m.m31();
+    flattened[9] = m.m32();
+    flattened[10] = m.m33();
+    flattened[11] = m.m34();
+    flattened[12] = m.m41();
+    flattened[13] = m.m42();
+    flattened[14] = m.m43();
+    flattened[15] = m.m44();
+}
+
+void LayerChromium::drawTexturedQuad(const TransformationMatrix& projectionMatrix, const TransformationMatrix& drawMatrix,
+                                     float width, float height, float opacity,
+                                     int matrixLocation, int alphaLocation)
+{
+    static GLfloat glMatrix[16];
+
+    TransformationMatrix renderMatrix = drawMatrix;
+
+    // Apply a scaling factor to size the quad from 1x1 to its intended size.
+    renderMatrix.scale3d(width, height, 1);
+
+    // Apply the projection matrix before sending the transform over to the shader.
+    renderMatrix.multiply(projectionMatrix);
+
+    toGLMatrix(&glMatrix[0], renderMatrix);
+
+    GLC(glUniformMatrix4fv(matrixLocation, 1, false, &glMatrix[0]));
+
+    if (alphaLocation != -1)
+        GLC(glUniform1f(alphaLocation, opacity));
+
+    GLC(glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, 0));
+}
+
+void LayerChromium::drawDebugBorder()
+{
+    static GLfloat glMatrix[16];
+    if (!borderColor().alpha())
+        return;
+
+    ASSERT(layerRenderer());
+    const SharedValues* sv = layerRenderer()->layerSharedValues();
+    ASSERT(sv && sv->initialized());
+    layerRenderer()->useShader(sv->borderShaderProgram());
+    TransformationMatrix renderMatrix = drawTransform();
+    renderMatrix.scale3d(bounds().width(), bounds().height(), 1);
+    renderMatrix.multiply(layerRenderer()->projectionMatrix());
+    toGLMatrix(&glMatrix[0], renderMatrix);
+    GLC(glUniformMatrix4fv(sv->borderShaderMatrixLocation(), 1, false, &glMatrix[0]));
+
+    GLC(glUniform4f(sv->borderShaderColorLocation(), borderColor().red() / 255.0, borderColor().green() / 255.0, borderColor().blue() / 255.0, 1));
+
+    GLC(glLineWidth(borderWidth()));
+
+    // The indices for the line are stored in the same array as the triangle indices.
+    GLC(glDrawElements(GL_LINE_LOOP, 4, GL_UNSIGNED_SHORT, (void*)(6 * sizeof(unsigned short))));
+}
+
+// static
+void LayerChromium::prepareForDraw(const SharedValues* sv)
+{
+    GLC(glBindBuffer(GL_ARRAY_BUFFER, sv->quadVerticesVbo()));
+    GLC(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, sv->quadElementsVbo()));
+    GLuint offset = 0;
+    GLC(glVertexAttribPointer(s_positionAttribLocation, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (GLvoid*)offset));
+    offset += 3 * sizeof(GLfloat);
+    GLC(glVertexAttribPointer(s_texCoordAttribLocation, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (GLvoid*)offset));
+    GLC(glEnableVertexAttribArray(s_positionAttribLocation));
+    GLC(glEnableVertexAttribArray(s_texCoordAttribLocation));
+}
+
 }
 #endif // USE(ACCELERATED_COMPOSITING)
diff --git a/WebCore/platform/graphics/chromium/LayerChromium.h b/WebCore/platform/graphics/chromium/LayerChromium.h
index 9fba415..0d0d362 100644
--- a/WebCore/platform/graphics/chromium/LayerChromium.h
+++ b/WebCore/platform/graphics/chromium/LayerChromium.h
@@ -55,19 +55,24 @@ namespace WebCore {
 class GraphicsContext3D;
 class LayerRendererChromium;
 
-// Base class for composited layers. The implementation covers layers that require
-// a GraphicsContext to render their contents. Special layer types are derived from
+// Base class for composited layers. Special layer types are derived from
 // this class.
 class LayerChromium : public RefCounted<LayerChromium> {
+    friend class LayerRendererChromium;
 public:
     static PassRefPtr<LayerChromium> create(GraphicsLayerChromium* owner = 0);
 
     ~LayerChromium();
 
+    const LayerChromium* rootLayer() const;
+    LayerChromium* superlayer() const;
     void addSublayer(PassRefPtr<LayerChromium>);
     void insertSublayer(PassRefPtr<LayerChromium>, size_t index);
     void replaceSublayer(LayerChromium* reference, PassRefPtr<LayerChromium> newLayer);
     void removeFromSuperlayer();
+    void removeAllSublayers();
+    void setSublayers(const Vector<RefPtr<LayerChromium> >&);
+    const Vector<RefPtr<LayerChromium> >& getSublayers() const { return m_sublayers; }
 
     void setAnchorPoint(const FloatPoint& anchorPoint) { m_anchorPoint = anchorPoint; setNeedsCommit(); }
     FloatPoint anchorPoint() const { return m_anchorPoint; }
@@ -93,9 +98,6 @@ public:
     void setDoubleSided(bool doubleSided) { m_doubleSided = doubleSided; setNeedsCommit(); }
     bool doubleSided() const { return m_doubleSided; }
 
-    void setEdgeAntialiasingMask(uint32_t mask) { m_edgeAntialiasingMask = mask; setNeedsCommit(); }
-    uint32_t edgeAntialiasingMask() const { return m_edgeAntialiasingMask; }
-
     void setFrame(const FloatRect&);
     FloatRect frame() const { return m_frame; }
 
@@ -120,76 +122,99 @@ public:
     bool opaque() const { return m_opaque; }
 
     void setPosition(const FloatPoint& position) { m_position = position;  setNeedsCommit(); }
-
     FloatPoint position() const { return m_position; }
 
     void setZPosition(float zPosition) { m_zPosition = zPosition; setNeedsCommit(); }
     float zPosition() const {  return m_zPosition; }
 
-    const LayerChromium* rootLayer() const;
-
-    void removeAllSublayers();
-
-    void setSublayers(const Vector<RefPtr<LayerChromium> >&);
-
-    const Vector<RefPtr<LayerChromium> >& getSublayers() const { return m_sublayers; }
-
     void setSublayerTransform(const TransformationMatrix& transform) { m_sublayerTransform = transform; setNeedsCommit(); }
     const TransformationMatrix& sublayerTransform() const { return m_sublayerTransform; }
 
-    LayerChromium* superlayer() const;
-
-
     void setTransform(const TransformationMatrix& transform) { m_transform = transform; setNeedsCommit(); }
     const TransformationMatrix& transform() const { return m_transform; }
 
+    // FIXME: This setting is currently ignored.
     void setGeometryFlipped(bool flipped) { m_geometryFlipped = flipped; setNeedsCommit(); }
     bool geometryFlipped() const { return m_geometryFlipped; }
 
-    virtual void updateTextureContents(unsigned textureId);
-    bool contentsDirty() { return m_contentsDirty; }
-
     void setDrawTransform(const TransformationMatrix& transform) { m_drawTransform = transform; }
     const TransformationMatrix& drawTransform() const { return m_drawTransform; }
 
     void setDrawOpacity(float opacity) { m_drawOpacity = opacity; }
     float drawOpacity() const { return m_drawOpacity; }
 
-    virtual bool drawsContent() { return m_owner && m_owner->drawsContent(); }
-
-    // Return true if the layer has its own GL texture and false if the texture
-    // needs to be allocated by the compositor.
-    virtual bool ownsTexture() { return false; }
-
-    // Returns the id of the GL texture that stores the contents of this layer.
-    // Derived layer classes that own their own textures should overwrite this method.
-    virtual unsigned textureId() { return m_allocatedTextureId; }
-
     bool preserves3D() { return m_owner && m_owner->preserves3D(); }
 
     void setLayerRenderer(LayerRendererChromium*);
 
-    static void setShaderProgramId(unsigned shaderProgramId) { m_shaderProgramId = shaderProgramId; }
-    virtual unsigned shaderProgramId() { return m_shaderProgramId; }
-
     void setOwner(GraphicsLayerChromium* owner) { m_owner = owner; }
 
+    bool contentsDirty() { return m_contentsDirty; }
+
+    // These methods typically need to be overwritten by derived classes.
+    virtual bool drawsContent() { return false; }
+    virtual void updateContents() { };
+    virtual void draw() { };
+
+    void drawDebugBorder();
+
+    // 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:
+        SharedValues();
+        ~SharedValues();
+
+        unsigned quadVerticesVbo() const { return m_quadVerticesVbo; }
+        unsigned quadElementsVbo() const { return m_quadElementsVbo; }
+        int maxTextureSize() const { return m_maxTextureSize; }
+        unsigned borderShaderProgram() const { return m_borderShaderProgram; }
+        int borderShaderMatrixLocation() const { return m_borderShaderMatrixLocation; }
+        int borderShaderColorLocation() const { return m_borderShaderColorLocation; }
+        bool initialized() const { return m_initialized; }
+
+    private:
+        unsigned m_quadVerticesVbo;
+        unsigned m_quadElementsVbo;
+        int m_maxTextureSize;
+        unsigned m_borderShaderProgram;
+        int m_borderShaderMatrixLocation;
+        int m_borderShaderColorLocation;
+        bool m_initialized;
+    };
+
+    static void prepareForDraw(const SharedValues*);
+
 protected:
     GraphicsLayerChromium* m_owner;
     LayerChromium(GraphicsLayerChromium* owner);
-    void updateTextureRect(void* pixels, const IntSize& bitmapSize, const IntSize& requiredTextureSize, const IntRect& dirtyRect, unsigned textureId);
+
+    LayerRendererChromium* layerRenderer() const { return m_layerRenderer; }
+
+    static void drawTexturedQuad(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(const char* vertexShaderSource, const char* fragmentShaderSource);
 
     IntSize m_bounds;
     FloatRect m_dirtyRect;
     bool m_contentsDirty;
 
+    // All layer shaders share the same attribute locations for the vertex positions
+    // and texture coordinates. This allows switching shaders without rebinding attribute
+    // arrays.
+    static const unsigned s_positionAttribLocation;
+    static const unsigned s_texCoordAttribLocation;
+
 private:
     void setNeedsCommit();
 
     void setSuperlayer(LayerChromium* superlayer) { m_superlayer = superlayer; }
 
-    void paintMe();
-
     size_t numSublayers() const
     {
         return m_sublayers.size();
@@ -204,35 +229,17 @@ private:
     Vector<RefPtr<LayerChromium> > m_sublayers;
     LayerChromium* m_superlayer;
 
+    // Layer properties.
     IntSize m_backingStoreSize;
     FloatPoint m_position;
     FloatPoint m_anchorPoint;
     Color m_backgroundColor;
     Color m_borderColor;
-
-    LayerRendererChromium* m_layerRenderer;
-
-    FloatRect m_frame;
-    TransformationMatrix m_transform;
-    TransformationMatrix m_sublayerTransform;
-
-    TransformationMatrix m_drawTransform;
-
-    uint32_t m_edgeAntialiasingMask;
     float m_opacity;
     float m_zPosition;
     float m_anchorPointZ;
     float m_borderWidth;
-
     float m_drawOpacity;
-
-    unsigned m_allocatedTextureId;
-    IntSize m_allocatedTextureSize;
-
-    // The shader program used by all layers of this type is the same.
-    // This static can be shadowed by derived classes to use a special shader.
-    static unsigned m_shaderProgramId;
-
     bool m_clearsContext;
     bool m_doubleSided;
     bool m_hidden;
@@ -241,6 +248,14 @@ private:
     bool m_geometryFlipped;
     bool m_needsDisplayOnBoundsChange;
 
+    // Points to the layer renderer that updates and draws this layer.
+    LayerRendererChromium* m_layerRenderer;
+
+    FloatRect m_frame;
+    TransformationMatrix m_transform;
+    TransformationMatrix m_sublayerTransform;
+    TransformationMatrix m_drawTransform;
+
     String m_name;
 };
 
diff --git a/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp b/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp
index 6bb82b0..cf23871 100644
--- a/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp
+++ b/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp
@@ -35,10 +35,10 @@
 #include "LayerRendererChromium.h"
 
 #include "CanvasLayerChromium.h"
+#include "ContentLayerChromium.h"
 #include "GLES2Context.h"
 #include "LayerChromium.h"
 #include "NotImplemented.h"
-#include "TransformLayerChromium.h"
 #if PLATFORM(SKIA)
 #include "NativeImageSkia.h"
 #include "PlatformContextSkia.h"
@@ -50,101 +50,6 @@
 
 namespace WebCore {
 
-#ifndef NDEBUG
-static WTFLogChannel LogLayerRenderer = { 0x00000000, "LayerRenderer", WTFLogChannelOn };
-#endif
-
-static void checkGLError()
-{
-#ifndef NDEBUG
-    GLenum error = glGetError();
-    if (error)
-        LOG_ERROR("GL Error: %d " , error);
-#endif
-}
-
-static GLuint loadShader(GLenum type, const char* shaderSource)
-{
-    GLuint shader = glCreateShader(type);
-    if (!shader)
-        return 0;
-    glShaderSource(shader, 1, &shaderSource, 0);
-    glCompileShader(shader);
-    GLint compiled;
-    glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
-    if (!compiled) {
-        glDeleteShader(shader);
-        return 0;
-    }
-    return shader;
-}
-
-static GLuint loadShaderProgram(const char* vertexShaderSource, const char* fragmentShaderSource)
-{
-    GLuint vertexShader;
-    GLuint fragmentShader;
-    GLuint programObject;
-    GLint linked;
-    vertexShader = loadShader(GL_VERTEX_SHADER, vertexShaderSource);
-    if (!vertexShader)
-        return 0;
-    fragmentShader = loadShader(GL_FRAGMENT_SHADER, fragmentShaderSource);
-    if (!fragmentShader) {
-        glDeleteShader(vertexShader);
-        return 0;
-    }
-    programObject = glCreateProgram();
-    if (!programObject)
-        return 0;
-    glAttachShader(programObject, vertexShader);
-    glAttachShader(programObject, fragmentShader);
-    glLinkProgram(programObject);
-    glGetProgramiv(programObject, GL_LINK_STATUS, &linked);
-    if (!linked) {
-        glDeleteProgram(programObject);
-        return 0;
-    }
-    glDeleteShader(vertexShader);
-    glDeleteShader(fragmentShader);
-    return programObject;
-}
-
-bool LayerRendererChromium::createLayerShader(ShaderProgramType type, const char* vertexShaderSource, const char* fragmentShaderSource)
-{
-    unsigned programId = loadShaderProgram(vertexShaderSource, fragmentShaderSource);
-    ASSERT(programId);
-
-    ShaderProgram* program = &m_shaderPrograms[type];
-
-    program->m_shaderProgramId = programId;
-    program->m_samplerLocation = glGetUniformLocation(programId, "s_texture");
-    program->m_matrixLocation = glGetUniformLocation(programId, "matrix");
-    program->m_alphaLocation = glGetUniformLocation(programId, "alpha");
-
-    return programId;
-}
-
-
-static void toGLMatrix(float* flattened, const TransformationMatrix& m)
-{
-    flattened[0] = m.m11();
-    flattened[1] = m.m12();
-    flattened[2] = m.m13();
-    flattened[3] = m.m14();
-    flattened[4] = m.m21();
-    flattened[5] = m.m22();
-    flattened[6] = m.m23();
-    flattened[7] = m.m24();
-    flattened[8] = m.m31();
-    flattened[9] = m.m32();
-    flattened[10] = m.m33();
-    flattened[11] = m.m34();
-    flattened[12] = m.m41();
-    flattened[13] = m.m42();
-    flattened[14] = m.m43();
-    flattened[15] = m.m44();
-}
-
 static TransformationMatrix orthoMatrix(float left, float right, float bottom, float top, float nearZ, float farZ)
 {
     float deltaX = right - left;
@@ -162,21 +67,6 @@ static TransformationMatrix orthoMatrix(float left, float right, float bottom, f
     return ortho;
 }
 
-// Creates a GL texture object to be used for transfering the layer's bitmap into.
-static GLuint createLayerTexture()
-{
-    GLuint textureId = 0;
-    glGenTextures(1, &textureId);
-    glBindTexture(GL_TEXTURE_2D, textureId);
-    // Do basic linear filtering on resize.
-    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
-    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
-    // NPOT textures in GL ES only work when the wrap mode is set to GL_CLAMP_TO_EDGE.
-    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
-    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
-    return textureId;
-}
-
 static inline bool compareLayerZ(const LayerChromium* a, const LayerChromium* b)
 {
     const TransformationMatrix& transformA = a->drawTransform();
@@ -185,51 +75,35 @@ static inline bool compareLayerZ(const LayerChromium* a, const LayerChromium* b)
     return transformA.m43() < transformB.m43();
 }
 
-ShaderProgram::ShaderProgram()
-    : m_shaderProgramId(0)
-    , m_samplerLocation(-1)
-    , m_matrixLocation(-1)
-    , m_alphaLocation(-1)
-{
-}
-
 PassOwnPtr<LayerRendererChromium> LayerRendererChromium::create(PassOwnPtr<GLES2Context> gles2Context)
 {
     return new LayerRendererChromium(gles2Context);
 }
 
 LayerRendererChromium::LayerRendererChromium(PassOwnPtr<GLES2Context> gles2Context)
-    : m_rootLayerTextureWidth(0)
+    : m_rootLayerTextureId(0)
+    , m_rootLayerTextureWidth(0)
     , m_rootLayerTextureHeight(0)
-    , m_positionLocation(0)
-    , m_texCoordLocation(1)
+    , m_scrollShaderProgram(0)
     , m_rootLayer(0)
     , m_needsDisplay(false)
     , m_scrollPosition(IntPoint(-1, -1))
-    , m_currentShaderProgramType(NumShaderProgramTypes)
+    , m_currentShader(0)
     , m_gles2Context(gles2Context)
 {
-    m_quadVboIds[Vertices] = m_quadVboIds[LayerElements] = 0;
-    m_hardwareCompositing = (m_gles2Context && initializeSharedGLObjects());
+    m_hardwareCompositing = (m_gles2Context && initializeSharedObjects());
 }
 
 LayerRendererChromium::~LayerRendererChromium()
 {
-    if (m_hardwareCompositing) {
-        makeContextCurrent();
-        glDeleteBuffers(3, m_quadVboIds);
-
-        for (int i = 0; i < NumShaderProgramTypes; i++) {
-            if (m_shaderPrograms[i].m_shaderProgramId)
-                glDeleteProgram(m_shaderPrograms[i].m_shaderProgramId);
-        }
-    }
+    cleanupSharedObjects();
+}
 
-    // Free up all GL textures.
-    for (TextureIdMap::iterator iter = m_textureIdMap.begin(); iter != m_textureIdMap.end(); ++iter) {
-        glDeleteTextures(1, &(iter->second));
-        iter->first->setLayerRenderer(0);
-    }
+void LayerRendererChromium::debugGLCall(const char* command, const char* file, int line)
+{
+    GLenum error = glGetError();
+    if (error != GL_NO_ERROR)
+        LOG_ERROR("GL command failed: File: %s\n\tLine %d\n\tcommand: %s, error %x\n", file, line, command, error);
 }
 
 // Creates a canvas and an associated graphics context that the root layer will
@@ -268,43 +142,14 @@ void LayerRendererChromium::setRootLayerCanvasSize(const IntSize& size)
     m_rootLayerCanvasSize = size;
 }
 
-void LayerRendererChromium::useShaderProgram(ShaderProgramType programType)
+void LayerRendererChromium::useShader(unsigned programId)
 {
-    if (programType != m_currentShaderProgramType) {
-        ShaderProgram* program = &m_shaderPrograms[programType];
-        glUseProgram(program->m_shaderProgramId);
-        m_currentShaderProgramType = programType;
-
-        // Set the uniform locations matching the program.
-        m_samplerLocation = program->m_samplerLocation;
-        m_matrixLocation = program->m_matrixLocation;
-        m_alphaLocation = program->m_alphaLocation;
+    if (programId != m_currentShader) {
+        GLC(glUseProgram(programId));
+        m_currentShader = programId;
     }
 }
 
-void LayerRendererChromium::drawTexturedQuad(const TransformationMatrix& matrix, float width, float height, float opacity)
-{
-    static GLfloat glMatrix[16];
-
-    TransformationMatrix renderMatrix = matrix;
-
-    // Apply a scaling factor to size the quad from 1x1 to its intended size.
-    renderMatrix.scale3d(width, height, 1);
-
-    // Apply the projection matrix before sending the transform over to the shader.
-    renderMatrix.multiply(m_projectionMatrix);
-
-    toGLMatrix(&glMatrix[0], renderMatrix);
-
-    glUniformMatrix4fv(m_matrixLocation, 1, false, &glMatrix[0]);
-
-    if (m_alphaLocation != -1)
-        glUniform1f(m_alphaLocation, opacity);
-
-    glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, 0);
-}
-
-
 // Updates the contents of the root layer texture that fall inside the updateRect
 // and re-composits all sublayers.
 void LayerRendererChromium::drawLayers(const IntRect& updateRect, const IntRect& visibleRect,
@@ -315,17 +160,13 @@ void LayerRendererChromium::drawLayers(const IntRect& updateRect, const IntRect&
     if (!m_rootLayer)
         return;
 
-    // If the size of the visible area has changed then allocate a new texture
-    // to store the contents of the root layer and adjust the projection matrix
-    // and viewport.
     makeContextCurrent();
 
-    checkGLError();
-
-    glBindTexture(GL_TEXTURE_2D, m_rootLayerTextureId);
-
-    checkGLError();
+    GLC(glBindTexture(GL_TEXTURE_2D, m_rootLayerTextureId));
 
+    // If the size of the visible area has changed then allocate a new texture
+    // to store the contents of the root layer and adjust the projection matrix
+    // and viewport.
     int visibleRectWidth = visibleRect.width();
     int visibleRectHeight = visibleRect.height();
     if (visibleRectWidth != m_rootLayerTextureWidth || visibleRectHeight != m_rootLayerTextureHeight) {
@@ -333,38 +174,18 @@ void LayerRendererChromium::drawLayers(const IntRect& updateRect, const IntRect&
         m_rootLayerTextureHeight = visibleRect.height();
 
         m_projectionMatrix = orthoMatrix(0, visibleRectWidth, visibleRectHeight, 0, -1000, 1000);
-        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_rootLayerTextureWidth, m_rootLayerTextureHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
-
-        checkGLError();
+        GLC(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_rootLayerTextureWidth, m_rootLayerTextureHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0));
     }
 
     // The GL viewport covers the entire visible area, including the scrollbars.
-    glViewport(0, 0, visibleRectWidth, visibleRectHeight);
-
-    checkGLError();
-
-    // The layer, scroll and debug border shaders all use the same vertex attributes
-    // so we can bind them only once.
-    glBindBuffer(GL_ARRAY_BUFFER, m_quadVboIds[Vertices]);
-    checkGLError();
-    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_quadVboIds[LayerElements]);
-    checkGLError();
-    GLuint offset = 0;
-    glVertexAttribPointer(m_positionLocation, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (GLvoid*)(offset));
-    checkGLError();
-    offset += 3 * sizeof(GLfloat);
-    glVertexAttribPointer(m_texCoordLocation, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (GLvoid*)(offset));
-    checkGLError();
-    glEnableVertexAttribArray(m_positionLocation);
-    checkGLError();
-    glEnableVertexAttribArray(m_texCoordLocation);
-    checkGLError();
-    glActiveTexture(GL_TEXTURE0);
-    checkGLError();
-    glDisable(GL_DEPTH_TEST);
-    checkGLError();
-    glDisable(GL_CULL_FACE);
-    checkGLError();
+    GLC(glViewport(0, 0, visibleRectWidth, visibleRectHeight));
+
+    // Bind the common vertex attributes used for drawing all the layers.
+    LayerChromium::prepareForDraw(layerSharedValues());
+
+    GLC(glDisable(GL_DEPTH_TEST));
+    GLC(glDisable(GL_CULL_FACE));
+    GLC(glDepthFunc(GL_LEQUAL));
 
     if (m_scrollPosition == IntPoint(-1, -1))
         m_scrollPosition = scrollPosition;
@@ -394,17 +215,13 @@ void LayerRendererChromium::drawLayers(const IntRect& updateRect, const IntRect&
             0.5 * visibleRect.height() + scaleFactor * scrollDelta.y(), 0);
         scrolledLayerMatrix.scale3d(1, -1, 1);
 
-        // Switch shaders to avoid RGB swizzling.
-        useShaderProgram(ScrollLayerProgram);
-        glUniform1i(m_shaderPrograms[ScrollLayerProgram].m_samplerLocation, 0);
-        checkGLError();
-
-        drawTexturedQuad(scrolledLayerMatrix, visibleRect.width(), visibleRect.height(), 1);
-        checkGLError();
+        useShader(m_scrollShaderProgram);
+        GLC(glUniform1i(m_scrollShaderSamplerLocation, 0));
+        LayerChromium::drawTexturedQuad(m_projectionMatrix, scrolledLayerMatrix,
+                                        visibleRect.width(), visibleRect.height(), 1,
+                                        m_scrollShaderMatrixLocation, -1);
 
-        glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, contentRect.width(), contentRect.height());
-
-        checkGLError();
+        GLC(glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, contentRect.width(), contentRect.height()));
         m_scrollPosition = scrollPosition;
     } else if (abs(scrollDelta.y()) > contentRect.height() || abs(scrollDelta.x()) > contentRect.width()) {
         // Scrolling larger than the contentRect size does not preserve any of the pixels, so there is
@@ -427,154 +244,92 @@ void LayerRendererChromium::drawLayers(const IntRect& updateRect, const IntRect&
         ASSERT(rootLayerWidth == updateRect.width() && rootLayerHeight == updateRect.height());
         void* pixels = bitmap.getPixels();
 
-        checkGLError();
         // Copy the contents of the updated rect to the root layer texture.
-        glTexSubImage2D(GL_TEXTURE_2D, 0, updateRect.x(), updateRect.y(), updateRect.width(), updateRect.height(), GL_RGBA, GL_UNSIGNED_BYTE, pixels);
-        checkGLError();
+        GLC(glTexSubImage2D(GL_TEXTURE_2D, 0, updateRect.x(), updateRect.y(), updateRect.width(), updateRect.height(), GL_RGBA, GL_UNSIGNED_BYTE, pixels));
 #elif PLATFORM(CG)
         // Get the contents of the updated rect.
         ASSERT(static_cast<int>(CGBitmapContextGetWidth(m_rootLayerCGContext.get())) == updateRect.width() && static_cast<int>(CGBitmapContextGetHeight(m_rootLayerCGContext.get())) == updateRect.height());
         void* pixels = m_rootLayerBackingStore.data();
 
-        checkGLError();
         // Copy the contents of the updated rect to the root layer texture.
         // The origin is at the lower left in Core Graphics' coordinate system. We need to correct for this here.
-        glTexSubImage2D(GL_TEXTURE_2D, 0,
-                        updateRect.x(), m_rootLayerTextureHeight - updateRect.y() - updateRect.height(),
-                        updateRect.width(), updateRect.height(),
-                        GL_RGBA, GL_UNSIGNED_BYTE, pixels);
-        checkGLError();
+        GLC(glTexSubImage2D(GL_TEXTURE_2D, 0,
+                            updateRect.x(), m_rootLayerTextureHeight - updateRect.y() - updateRect.height(),
+                            updateRect.width(), updateRect.height(),
+                            GL_RGBA, GL_UNSIGNED_BYTE, pixels));
 #else
 #error "Need to implement for your platform."
 #endif
     }
 
     glClearColor(0, 0, 1, 1);
-    checkGLError();
     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
-    checkGLError();
 
     // Render the root layer using a quad that takes up the entire visible area of the window.
-    useShaderProgram(ContentLayerProgram);
-    checkGLError();
-    glUniform1i(m_samplerLocation, 0);
-    checkGLError();
+    // We reuse the shader program used by ContentLayerChromium.
+    const ContentLayerChromium::SharedValues* contentLayerValues = contentLayerSharedValues();
+    useShader(contentLayerValues->contentShaderProgram());
+    GLC(glUniform1i(contentLayerValues->shaderSamplerLocation(), 0));
     TransformationMatrix layerMatrix;
     layerMatrix.translate3d(visibleRect.width() * 0.5f, visibleRect.height() * 0.5f, 0);
-    drawTexturedQuad(layerMatrix, visibleRect.width(), visibleRect.height(), 1);
-    checkGLError();
+    LayerChromium::drawTexturedQuad(m_projectionMatrix, layerMatrix,
+                                    visibleRect.width(), visibleRect.height(), 1,
+                                    contentLayerValues->shaderMatrixLocation(), contentLayerValues->shaderAlphaLocation());
 
     // If culling is enabled then we will cull the backface.
-    glCullFace(GL_BACK);
-    checkGLError();
+    GLC(glCullFace(GL_BACK));
     // The orthographic projection is setup such that Y starts at zero and
     // increases going down the page so we need to adjust the winding order of
     // front facing triangles.
-    glFrontFace(GL_CW);
-    checkGLError();
+    GLC(glFrontFace(GL_CW));
 
     // The shader used to render layers returns pre-multiplied alpha colors
     // so we need to send the blending mode appropriately.
-    glEnable(GL_BLEND);
-    checkGLError();
-    glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
-
-    checkGLError();
+    GLC(glEnable(GL_BLEND));
+    GLC(glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA));
 
     // Translate all the composited layers by the scroll position.
     TransformationMatrix matrix;
     matrix.translate3d(-m_scrollPosition.x(), -m_scrollPosition.y(), 0);
 
+    // Traverse the layer tree and update the layer transforms.
     float opacity = 1;
-    m_layerList.shrink(0);
     const Vector<RefPtr<LayerChromium> >& sublayers = m_rootLayer->getSublayers();
-    for (size_t i = 0; i < sublayers.size(); i++)
-        updateLayersRecursive(sublayers[i].get(), matrix, opacity, visibleRect);
-
-    // Sort layers by the z coordinate of their center so that layers further
-    // away get drawn first.
-    std::stable_sort(m_layerList.begin(), m_layerList.end(), compareLayerZ);
+    size_t i;
+    for (i = 0; i < sublayers.size(); i++)
+        updateLayersRecursive(sublayers[i].get(), matrix, opacity);
 
     // Enable scissoring to avoid rendering composited layers over the scrollbars.
-    glEnable(GL_SCISSOR_TEST);
-    glScissor(0, visibleRect.height() - contentRect.height(), contentRect.width(), contentRect.height());
+    GLC(glEnable(GL_SCISSOR_TEST));
+    GLC(glScissor(0, visibleRect.height() - contentRect.height(), contentRect.width(), contentRect.height()));
 
-    for (size_t j = 0; j < m_layerList.size(); j++)
-        drawLayer(m_layerList[j]);
+    // Traverse the layer tree one more time to draw the layers.
+    m_visibleRect = visibleRect;
+    for (i = 0; i < sublayers.size(); i++)
+        drawLayersRecursive(sublayers[i].get());
 
-    glDisable(GL_SCISSOR_TEST);
+    GLC(glDisable(GL_SCISSOR_TEST));
 
-    glFlush();
     m_gles2Context->swapBuffers();
 
     m_needsDisplay = false;
 }
 
-// Returns the id of the texture currently associated with the layer or
-// -1 if the id hasn't been registered yet.
-int LayerRendererChromium::getTextureId(LayerChromium* layer)
+// FIXME: This method should eventually be replaced by a proper texture manager.
+unsigned LayerRendererChromium::createLayerTexture()
 {
-    TextureIdMap::iterator textureId = m_textureIdMap.find(layer);
-    if (textureId != m_textureIdMap.end())
-        return textureId->second;
-
-    return -1;
-}
-
-// Allocates a new texture for the layer and registers it in the textureId map.
-// FIXME: We will need to come up with a more sophisticated allocation strategy here.
-int LayerRendererChromium::assignTextureForLayer(LayerChromium* layer)
-{
-    GLuint textureId = createLayerTexture();
-
-    // FIXME: Check that textureId is valid
-    m_textureIdMap.set(layer, textureId);
-
-    layer->setLayerRenderer(this);
-
+    GLuint textureId = 0;
+    GLC(glGenTextures(1, &textureId));
+    GLC(glBindTexture(GL_TEXTURE_2D, textureId));
+    // Do basic linear filtering on resize.
+    GLC(glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
+    GLC(glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
+    // NPOT textures in GL ES only work when the wrap mode is set to GL_CLAMP_TO_EDGE.
+    GLC(glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
+    GLC(glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
     return textureId;
 }
 
-bool LayerRendererChromium::freeLayerTexture(LayerChromium* layer)
-{
-    TextureIdMap::iterator textureId = m_textureIdMap.find(layer);
-    if (textureId == m_textureIdMap.end())
-        return false;
-    // Free up the texture.
-    glDeleteTextures(1, &(textureId->second));
-    m_textureIdMap.remove(textureId);
-    return true;
-}
-
-// Draws a debug border around the layer's bounds.
-void LayerRendererChromium::drawDebugBorder(LayerChromium* layer, const TransformationMatrix& matrix)
-{
-    static GLfloat glMatrix[16];
-    Color borderColor = layer->borderColor();
-    if (!borderColor.alpha())
-        return;
-
-    useShaderProgram(DebugBorderProgram);
-    TransformationMatrix renderMatrix = matrix;
-    IntSize bounds = layer->bounds();
-    renderMatrix.scale3d(bounds.width(), bounds.height(), 1);
-    renderMatrix.multiply(m_projectionMatrix);
-    toGLMatrix(&glMatrix[0], renderMatrix);
-    unsigned borderMatrixLocation = m_shaderPrograms[DebugBorderProgram].m_matrixLocation;
-    glUniformMatrix4fv(borderMatrixLocation, 1, false, &glMatrix[0]);
-
-    glUniform4f(m_borderColorLocation, borderColor.red() / 255.0,
-                                       borderColor.green() / 255.0,
-                                       borderColor.blue() / 255.0,
-                                       1);
-
-    glLineWidth(layer->borderWidth());
-
-    // The indices for the line are stored in the same array as the triangle indices.
-    glDrawElements(GL_LINE_LOOP, 4, GL_UNSIGNED_SHORT, (void*)(6 * sizeof(unsigned short)));
-    checkGLError();
-}
-
 // Returns true if any part of the layer falls within the visibleRect
 bool LayerRendererChromium::isLayerVisible(LayerChromium* layer, const TransformationMatrix& matrix, const IntRect& visibleRect)
 {
@@ -592,9 +347,9 @@ bool LayerRendererChromium::isLayerVisible(LayerChromium* layer, const Transform
     return mappedRect.intersects(FloatRect(-1, -1, 2, 2));
 }
 
-// Updates and caches the layer transforms and opacity values that will be used
-// when rendering them.
-void LayerRendererChromium::updateLayersRecursive(LayerChromium* layer, const TransformationMatrix& parentMatrix, float opacity, const IntRect& visibleRect)
+// Recursively walks the layer tree starting at the given node and updates the 
+// transform and opacity values.
+void LayerRendererChromium::updateLayersRecursive(LayerChromium* layer, const TransformationMatrix& parentMatrix, float opacity)
 {
     // Compute the new matrix transformation that will be applied to this layer and
     // all its sublayers. It's important to remember that the layer's position
@@ -631,23 +386,11 @@ void LayerRendererChromium::updateLayersRecursive(LayerChromium* layer, const Tr
     // M = M[p] * Tr[l] * M[l] * Tr[c]
     localMatrix.translate3d(centerOffsetX, centerOffsetY, -layer->anchorPointZ());
 
-    // Check if the layer falls within the visible bounds of the page.
-    bool layerVisible = isLayerVisible(layer, localMatrix, visibleRect);
-
-    bool skipLayer = false;
-    if (bounds.width() > 2048 || bounds.height() > 2048) {
-        if (layer->drawsContent())
-            LOG(LayerRenderer, "Skipping layer with size %d %d", bounds.width(), bounds.height());
-        skipLayer = true;
-    }
-
     // Calculate the layer's opacity.
     opacity *= layer->opacity();
 
     layer->setDrawTransform(localMatrix);
     layer->setDrawOpacity(opacity);
-    if (layerVisible && !skipLayer)
-        m_layerList.append(layer);
 
     // Flatten to 2D if the layer doesn't preserve 3D.
     if (!layer->preserves3D()) {
@@ -671,29 +414,71 @@ void LayerRendererChromium::updateLayersRecursive(LayerChromium* layer, const Tr
 
     const Vector<RefPtr<LayerChromium> >& sublayers = layer->getSublayers();
     for (size_t i = 0; i < sublayers.size(); i++)
-        updateLayersRecursive(sublayers[i].get(), localMatrix, opacity, visibleRect);
+        updateLayersRecursive(sublayers[i].get(), localMatrix, opacity);
+
+    layer->setLayerRenderer(this);
+}
+
+// Recursively walk the layer tree and draw the layers.
+void LayerRendererChromium::drawLayersRecursive(LayerChromium* layer)
+{
+    static bool depthTestEnabledForSubtree = false;
+
+    // Check if the layer falls within the visible bounds of the page.
+    bool layerVisible = isLayerVisible(layer, layer->drawTransform(), m_visibleRect);
+
+    // Enable depth testing for this layer and all its descendants if preserves3D is set.
+    bool mustClearDepth = false;
+    if (layer->preserves3D()) {
+        if (!depthTestEnabledForSubtree) {
+            GLC(glEnable(GL_DEPTH_TEST));
+            depthTestEnabledForSubtree = true;
+
+            // Need to clear the depth buffer when we're done rendering this subtree.
+            mustClearDepth = true;
+        }
+    }
+
+    if (layerVisible)
+        drawLayer(layer);
+
+    // If we're using depth testing then we need to sort the children in Z to
+    // get the transparency to work properly.
+    if (depthTestEnabledForSubtree) {
+        const Vector<RefPtr<LayerChromium> >& sublayers = layer->getSublayers();
+        Vector<LayerChromium*> sublayerList;
+        size_t i;
+        for (i = 0; i < sublayers.size(); i++)
+            sublayerList.append(sublayers[i].get());
+
+        // Sort by the z coordinate of the layer center so that layers further away
+        // are drawn first.
+        std::stable_sort(sublayerList.begin(), sublayerList.end(), compareLayerZ);
+
+        for (i = 0; i < sublayerList.size(); i++)
+            drawLayersRecursive(sublayerList[i]);
+    } else {
+        const Vector<RefPtr<LayerChromium> >& sublayers = layer->getSublayers();
+        for (size_t i = 0; i < sublayers.size(); i++)
+            drawLayersRecursive(sublayers[i].get());
+    }
+
+    if (mustClearDepth) {
+        GLC(glDisable(GL_DEPTH_TEST));
+        GLC(glClear(GL_DEPTH_BUFFER_BIT));
+        depthTestEnabledForSubtree = false;
+    }
 }
 
 void LayerRendererChromium::drawLayer(LayerChromium* layer)
 {
-    const TransformationMatrix& localMatrix = layer->drawTransform();
     IntSize bounds = layer->bounds();
 
     if (layer->drawsContent()) {
-        int textureId;
-        if (layer->ownsTexture())
-            textureId = layer->textureId();
-        else {
-            textureId = getTextureId(layer);
-            // If no texture has been created for the layer yet then create one now.
-            if (textureId == -1)
-                textureId = assignTextureForLayer(layer);
-        }
-
-        // Redraw the contents of the layer if necessary.
+        // Update the contents of the layer if necessary.
         if (layer->contentsDirty()) {
             // Update the backing texture contents for any dirty portion of the layer.
-            layer->updateTextureContents(textureId);
+            layer->updateContents();
             m_gles2Context->makeCurrent();
         }
 
@@ -702,13 +487,11 @@ void LayerRendererChromium::drawLayer(LayerChromium* layer)
         else
             glEnable(GL_CULL_FACE);
 
-        glBindTexture(GL_TEXTURE_2D, textureId);
-        useShaderProgram(static_cast<ShaderProgramType>(layer->shaderProgramId()));
-        drawTexturedQuad(localMatrix, bounds.width(), bounds.height(), layer->drawOpacity());
+        layer->draw();
     }
 
     // Draw the debug border if there is one.
-    drawDebugBorder(layer, localMatrix);
+    layer->drawDebugBorder();
 }
 
 bool LayerRendererChromium::makeContextCurrent()
@@ -716,21 +499,22 @@ bool LayerRendererChromium::makeContextCurrent()
     return m_gles2Context->makeCurrent();
 }
 
-void LayerRendererChromium::bindCommonAttribLocations(ShaderProgramType program)
+// Checks whether a given size is within the maximum allowed texture size range.
+bool LayerRendererChromium::checkTextureSize(const IntSize& textureSize)
 {
-    unsigned programId = m_shaderPrograms[program].m_shaderProgramId;
-    glBindAttribLocation(programId, m_positionLocation, "a_position");
-    glBindAttribLocation(programId, m_texCoordLocation, "a_texCoord");
-
-    // Re-link the program for the new attribute locations to take effect.
-    glLinkProgram(programId);
-    checkGLError();
+    if (textureSize.width() > m_maxTextureSize || textureSize.height() > m_maxTextureSize)
+        return false;
+    return true;
 }
 
-bool LayerRendererChromium::initializeSharedGLObjects()
+bool LayerRendererChromium::initializeSharedObjects()
 {
-    // Shaders for drawing the layer contents.
-    char vertexShaderString[] =
+    makeContextCurrent();
+
+    // Vertex and fragment shaders for rendering the scrolled root layer quad.
+    // They differ from a regular content layer shader in that they don't swizzle
+    // the colors or take an alpha value.
+    char scrollVertexShaderString[] =
         "attribute vec4 a_position;   \n"
         "attribute vec2 a_texCoord;   \n"
         "uniform mat4 matrix;         \n"
@@ -740,30 +524,6 @@ bool LayerRendererChromium::initializeSharedGLObjects()
         "  gl_Position = matrix * a_position; \n"
         "  v_texCoord = a_texCoord;   \n"
         "}                            \n";
-    // Note differences between Skia and Core Graphics versions:
-    //  - Skia uses BGRA and origin is upper left
-    //  - Core Graphics uses RGBA and origin is lower left
-    char fragmentShaderString[] =
-        "precision mediump float;                            \n"
-        "varying vec2 v_texCoord;                            \n"
-        "uniform sampler2D s_texture;                        \n"
-        "uniform float alpha;                                \n"
-        "void main()                                         \n"
-        "{                                                   \n"
-#if PLATFORM(SKIA)
-        "  vec4 texColor = texture2D(s_texture, v_texCoord); \n"
-        "  gl_FragColor = vec4(texColor.z, texColor.y, texColor.x, texColor.w) * alpha; \n"
-#elif PLATFORM(CG)
-        "  vec4 texColor = texture2D(s_texture, vec2(v_texCoord.x, 1.0 - v_texCoord.y)); \n"
-        "  gl_FragColor = vec4(texColor.x, texColor.y, texColor.z, texColor.w) * alpha; \n"
-#else
-#error "Need to implement for your platform."
-#endif
-        "}                                                   \n";
-
-    // Fragment shader used for rendering the scrolled root layer quad. It differs
-    // from fragmentShaderString in that it doesn't swizzle the colors and doesn't
-    // take an alpha value.
     char scrollFragmentShaderString[] =
         "precision mediump float;                            \n"
         "varying vec2 v_texCoord;                            \n"
@@ -774,101 +534,67 @@ bool LayerRendererChromium::initializeSharedGLObjects()
         "  gl_FragColor = vec4(texColor.x, texColor.y, texColor.z, texColor.w); \n"
         "}                                                   \n";
 
-    // Canvas layers need to be flipped vertically and their colors shouldn't be
-    // swizzled.
-    char canvasFragmentShaderString[] =
-        "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, vec2(v_texCoord.x, 1.0 - v_texCoord.y)); \n"
-        "  gl_FragColor = vec4(texColor.x, texColor.y, texColor.z, texColor.w) * alpha; \n"
-        "}                                                   \n";
-
-    // Shaders for drawing the debug borders around the layers.
-    char borderVertexShaderString[] =
-        "attribute vec4 a_position;   \n"
-        "uniform mat4 matrix;         \n"
-        "void main()                  \n"
-        "{                            \n"
-        "   gl_Position = matrix * a_position; \n"
-        "}                            \n";
-    char borderFragmentShaderString[] =
-        "precision mediump float;                            \n"
-        "uniform vec4 color;                                 \n"
-        "void main()                                         \n"
-        "{                                                   \n"
-        "  gl_FragColor = color;                             \n"
-        "}                                                   \n";
-
-    GLfloat vertices[] = { -0.5f,  0.5f, 0.0f, // Position 0
-                            0.0f,  1.0f, // TexCoord 0 
-                           -0.5f, -0.5f, 0.0f, // Position 1
-                            0.0f,  0.0f, // TexCoord 1
-                            0.5f, -0.5f, 0.0f, // Position 2
-                            1.0f,  0.0f, // TexCoord 2
-                            0.5f,  0.5f, 0.0f, // Position 3
-                            1.0f,  1.0f // TexCoord 3
-                         };
-    GLushort indices[] = { 0, 1, 2, 0, 2, 3, // The two triangles that make up the layer quad.
-                           0, 1, 2, 3}; // A line path for drawing the layer border.
-
-    makeContextCurrent();
-
-    if (!createLayerShader(ContentLayerProgram, vertexShaderString, fragmentShaderString)) {
-        LOG_ERROR("Failed to create shader program for content layers");
-        return false;
-    }
-    LayerChromium::setShaderProgramId(ContentLayerProgram);
-
-    if (!createLayerShader(CanvasLayerProgram, vertexShaderString, canvasFragmentShaderString)) {
-        LOG_ERROR("Failed to create shader program for Canvas layers");
+    m_scrollShaderProgram = LayerChromium::createShaderProgram(scrollVertexShaderString, scrollFragmentShaderString);
+    if (!m_scrollShaderProgram) {
+        LOG_ERROR("LayerRendererChromium: Failed to create scroll shader program");
+        cleanupSharedObjects();
         return false;
     }
-    CanvasLayerChromium::setShaderProgramId(CanvasLayerProgram);
 
-    if (!createLayerShader(ScrollLayerProgram, vertexShaderString, scrollFragmentShaderString)) {
-        LOG_ERROR("Failed to create shader program for scrolling layer");
+    GLC(m_scrollShaderSamplerLocation = glGetUniformLocation(m_scrollShaderProgram, "s_texture"));
+    GLC(m_scrollShaderMatrixLocation = glGetUniformLocation(m_scrollShaderProgram, "matrix"));
+    if (m_scrollShaderSamplerLocation == -1 || m_scrollShaderMatrixLocation == -1) {
+        LOG_ERROR("Failed to initialize scroll shader.");
+        cleanupSharedObjects();
         return false;
     }
 
-    if (!createLayerShader(DebugBorderProgram, borderVertexShaderString, borderFragmentShaderString)) {
-        LOG_ERROR("Failed to create shader program for debug borders");
-        return false;
-    }
-
-    // Specify the attrib location for the position and texCoord and make it the same for all programs to
-    // avoid binding re-binding the vertex attributes.
-    bindCommonAttribLocations(ContentLayerProgram);
-    bindCommonAttribLocations(CanvasLayerProgram);
-    bindCommonAttribLocations(DebugBorderProgram);
-    bindCommonAttribLocations(ScrollLayerProgram);
-
-    // Get the location of the color uniform for the debug border shader program.
-    m_borderColorLocation = glGetUniformLocation(m_shaderPrograms[DebugBorderProgram].m_shaderProgramId, "color");
-
-    glGenBuffers(3, m_quadVboIds);
-    glBindBuffer(GL_ARRAY_BUFFER, m_quadVboIds[Vertices]);
-    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
-    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_quadVboIds[LayerElements]);
-    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
-
     // Create a texture object to hold the contents of the root layer.
     m_rootLayerTextureId = createLayerTexture();
     if (!m_rootLayerTextureId) {
         LOG_ERROR("Failed to create texture for root layer");
+        cleanupSharedObjects();
         return false;
     }
     // Turn off filtering for the root layer to avoid blurring from the repeated
     // writes and reads to the framebuffer that happen while scrolling.
-    glBindTexture(GL_TEXTURE_2D, m_rootLayerTextureId);
-    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+    GLC(glBindTexture(GL_TEXTURE_2D, m_rootLayerTextureId));
+    GLC(glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST));
+    GLC(glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST));
+
+    // Get the max texture size supported by the system.
+    GLC(glGetIntegerv(GL_MAX_TEXTURE_SIZE, &m_maxTextureSize));
+
+    m_layerSharedValues = adoptPtr(new LayerChromium::SharedValues());
+    m_contentLayerSharedValues = adoptPtr(new ContentLayerChromium::SharedValues());
+    m_canvasLayerSharedValues = adoptPtr(new CanvasLayerChromium::SharedValues());
+    if (!m_layerSharedValues->initialized() || !m_contentLayerSharedValues->initialized() || !m_canvasLayerSharedValues->initialized()) {
+        cleanupSharedObjects();
+        return false;
+    }
 
     return true;
 }
+
+void LayerRendererChromium::cleanupSharedObjects()
+{
+    makeContextCurrent();
+
+    m_layerSharedValues.clear();
+    m_contentLayerSharedValues.clear();
+    m_canvasLayerSharedValues.clear();
+
+    if (m_scrollShaderProgram) {
+        GLC(glDeleteProgram(m_scrollShaderProgram));
+        m_scrollShaderProgram = 0;
+    }
+
+    if (m_rootLayerTextureId) {
+        GLC(glDeleteTextures(1, &m_rootLayerTextureId));
+        m_rootLayerTextureId = 0;
+    }
+}
+
 } // namespace WebCore
 
 #endif // USE(ACCELERATED_COMPOSITING)
diff --git a/WebCore/platform/graphics/chromium/LayerRendererChromium.h b/WebCore/platform/graphics/chromium/LayerRendererChromium.h
index e4474b5..24bbe65 100644
--- a/WebCore/platform/graphics/chromium/LayerRendererChromium.h
+++ b/WebCore/platform/graphics/chromium/LayerRendererChromium.h
@@ -34,6 +34,8 @@
 
 #if USE(ACCELERATED_COMPOSITING)
 
+#include "CanvasLayerChromium.h"
+#include "ContentLayerChromium.h"
 #include "IntRect.h"
 #include "LayerChromium.h"
 #include "SkBitmap.h"
@@ -51,16 +53,6 @@ namespace WebCore {
 
 class GLES2Context;
 
-class ShaderProgram {
-public:
-    ShaderProgram();
-
-    unsigned m_shaderProgramId;
-    int m_samplerLocation;
-    int m_matrixLocation;
-    int m_alphaLocation;
-};
-
 // Class that handles drawing of composited render layers using GL.
 class LayerRendererChromium : public Noncopyable {
 public:
@@ -78,73 +70,58 @@ public:
 
     void setNeedsDisplay() { m_needsDisplay = true; }
 
-    // Frees the texture associated with the given layer.
-    bool freeLayerTexture(LayerChromium*);
-
     bool hardwareCompositing() const { return m_hardwareCompositing; }
 
     void setRootLayerCanvasSize(const IntSize&);
 
     GraphicsContext* rootLayerGraphicsContext() const { return m_rootLayerGraphicsContext.get(); }
 
-private:
-    enum ShaderProgramType { DebugBorderProgram, ScrollLayerProgram, ContentLayerProgram, CanvasLayerProgram, NumShaderProgramTypes };
+    unsigned createLayerTexture();
 
-    void updateLayersRecursive(LayerChromium* layer, const TransformationMatrix& parentMatrix, float opacity, const IntRect& visibleRect);
+    static void debugGLCall(const char* command, const char* file, int line);
 
-    void drawLayer(LayerChromium*);
+    const TransformationMatrix& projectionMatrix() const { return m_projectionMatrix; }
 
-    void drawDebugBorder(LayerChromium*, const TransformationMatrix&);
+    void useShader(unsigned);
 
-    void drawTexturedQuad(const TransformationMatrix& matrix, float width, float height, float opacity);
+    bool checkTextureSize(const IntSize&);
 
-    bool isLayerVisible(LayerChromium*, const TransformationMatrix&, const IntRect& visibleRect);
+    const LayerChromium::SharedValues* layerSharedValues() const { return m_layerSharedValues.get(); }
+    const ContentLayerChromium::SharedValues* contentLayerSharedValues() const { return m_contentLayerSharedValues.get(); }
+    const CanvasLayerChromium::SharedValues* canvasLayerSharedValues() const { return m_canvasLayerSharedValues.get(); }
 
-    bool createLayerShader(ShaderProgramType, const char* vertexShaderSource, const char* fragmentShaderSource);
+private:
+    void updateLayersRecursive(LayerChromium* layer, const TransformationMatrix& parentMatrix, float opacity);
 
-    void useShaderProgram(ShaderProgramType);
+    void drawLayersRecursive(LayerChromium*);
 
-    void bindCommonAttribLocations(ShaderProgramType);
+    void drawLayer(LayerChromium*);
 
-    enum VboIds { Vertices, LayerElements };
+    bool isLayerVisible(LayerChromium*, const TransformationMatrix&, const IntRect& visibleRect);
 
-    // These are here only temporarily and should be removed once we switch over to GGL
     bool makeContextCurrent();
 
-    bool initializeSharedGLObjects();
-    int getTextureId(LayerChromium*);
-    int assignTextureForLayer(LayerChromium*);
-
-    ShaderProgram m_shaderPrograms[NumShaderProgramTypes];
+    bool initializeSharedObjects();
+    void cleanupSharedObjects();
 
     unsigned m_rootLayerTextureId;
     int m_rootLayerTextureWidth;
     int m_rootLayerTextureHeight;
 
-    // Shader uniform and attribute locations.
-    const int m_positionLocation;
-    const int m_texCoordLocation;
-    int m_samplerLocation;
-    int m_matrixLocation;
-    int m_alphaLocation;
-    int m_borderColorLocation;
+    // Scroll shader uniform locations.
+    unsigned m_scrollShaderProgram;
+    int m_scrollShaderSamplerLocation;
+    int m_scrollShaderMatrixLocation;
 
-    unsigned m_quadVboIds[3];
     TransformationMatrix m_projectionMatrix;
 
     RefPtr<LayerChromium> m_rootLayer;
 
-    Vector<LayerChromium*> m_layerList;
-
     bool m_needsDisplay;
     IntPoint m_scrollPosition;
     bool m_hardwareCompositing;
 
-    ShaderProgramType m_currentShaderProgramType;
-
-    // Map associating layers with textures ids used by the GL compositor.
-    typedef HashMap<LayerChromium*, unsigned> TextureIdMap;
-    TextureIdMap m_textureIdMap;
+    unsigned int m_currentShader;
 
 #if PLATFORM(SKIA)
     OwnPtr<skia::PlatformCanvas> m_rootLayerCanvas;
@@ -158,9 +135,33 @@ private:
 
     IntSize m_rootLayerCanvasSize;
 
+    IntRect m_visibleRect;
+
+    int m_maxTextureSize;
+
+    // Store values that are shared between instances of each layer type
+    // associated with this instance of the compositor. Since there can be
+    // multiple instances of the compositor running in the same renderer process
+    // we cannot store these values in static variables.
+    OwnPtr<LayerChromium::SharedValues> m_layerSharedValues;
+    OwnPtr<ContentLayerChromium::SharedValues> m_contentLayerSharedValues;
+    OwnPtr<CanvasLayerChromium::SharedValues> m_canvasLayerSharedValues;
+
     OwnPtr<GLES2Context> m_gles2Context;
 };
 
+// Setting DEBUG_GL_CALLS to 1 will call glGetError() after almost every GL
+// call made by the compositor. Useful for debugging rendering issues but
+// will significantly degrade performance.
+#define DEBUG_GL_CALLS 0
+
+#if DEBUG_GL_CALLS && !defined ( NDEBUG )
+#define GLC(x) { (x), LayerRendererChromium::debugGLCall(#x, __FILE__, __LINE__); }
+#else
+#define GLC(x) (x)
+#endif
+
+
 }
 
 #endif // USE(ACCELERATED_COMPOSITING)
diff --git a/WebCore/platform/graphics/chromium/TransformLayerChromium.cpp b/WebCore/platform/graphics/chromium/TransformLayerChromium.cpp
deleted file mode 100644
index 6427eeb..0000000
--- a/WebCore/platform/graphics/chromium/TransformLayerChromium.cpp
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * 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:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * 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.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
- * OWNER OR 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 "TransformLayerChromium.h"
-
-namespace WebCore {
-
-PassRefPtr<TransformLayerChromium> TransformLayerChromium::create(GraphicsLayerChromium* owner)
-{
-    return adoptRef(new TransformLayerChromium(owner));
-}
-
-TransformLayerChromium::TransformLayerChromium(GraphicsLayerChromium* owner)
-    : LayerChromium(owner)
-{
-}
-
-}
-#endif // USE(ACCELERATED_COMPOSITING)
diff --git a/WebCore/platform/graphics/chromium/TransformLayerChromium.h b/WebCore/platform/graphics/chromium/TransformLayerChromium.h
deleted file mode 100644
index 3d5ce94..0000000
--- a/WebCore/platform/graphics/chromium/TransformLayerChromium.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * 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:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * 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.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
- * OWNER OR 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 TransformLayerChromium_h
-#define TransformLayerChromium_h
-
-#if USE(ACCELERATED_COMPOSITING)
-
-#include "LayerChromium.h"
-
-namespace WebCore {
-
-// A Layer that doesn't draw any content but simply exists to group and
-// transform its descendants.
-class TransformLayerChromium : public LayerChromium {
-public:
-    static PassRefPtr<TransformLayerChromium> create(GraphicsLayerChromium* owner = 0);
-    virtual bool drawsContent() { return false; }
-
-private:
-    TransformLayerChromium(GraphicsLayerChromium* owner);
-};
-
-}
-#endif // USE(ACCELERATED_COMPOSITING)
-
-#endif
diff --git a/WebCore/platform/graphics/chromium/VideoLayerChromium.cpp b/WebCore/platform/graphics/chromium/VideoLayerChromium.cpp
index 89b6ec1..ebb8bce 100644
--- a/WebCore/platform/graphics/chromium/VideoLayerChromium.cpp
+++ b/WebCore/platform/graphics/chromium/VideoLayerChromium.cpp
@@ -54,8 +54,7 @@ PassRefPtr<VideoLayerChromium> VideoLayerChromium::create(GraphicsLayerChromium*
 }
 
 VideoLayerChromium::VideoLayerChromium(GraphicsLayerChromium* owner)
-    : LayerChromium(owner)
-    , m_allocatedTextureId(0)
+    : ContentLayerChromium(owner)
 #if PLATFORM(SKIA)
     , m_canvas(0)
     , m_skiaContext(0)
@@ -64,7 +63,7 @@ VideoLayerChromium::VideoLayerChromium(GraphicsLayerChromium* owner)
 {
 }
 
-void VideoLayerChromium::updateTextureContents(unsigned textureId)
+void VideoLayerChromium::updateContents()
 {
     RenderLayerBacking* backing = static_cast<RenderLayerBacking*>(m_owner->client());
     if (!backing || backing->paintingGoesToWindow())
@@ -109,9 +108,20 @@ void VideoLayerChromium::updateTextureContents(unsigned textureId)
     // Bring the canvas into the coordinate system of the paint rect.
     m_canvas->translate(static_cast<SkScalar>(-dirtyRect.x()), static_cast<SkScalar>(-dirtyRect.y()));
 
+    // FIXME: Remove this test when tiled layers are implemented.
+    m_skipsDraw = false;
+    if (!layerRenderer()->checkTextureSize(requiredTextureSize)) {
+        m_skipsDraw = true;
+        return;
+    }
+
+    unsigned textureId = m_contentsTexture;
+    if (!textureId)
+        textureId = layerRenderer()->createLayerTexture();
+
     // If the texture id or size changed since last time, then we need to tell GL
     // to re-allocate a texture.
-    if (m_allocatedTextureId != textureId || requiredTextureSize != m_allocatedTextureSize)
+    if (m_contentsTexture != textureId || requiredTextureSize != m_allocatedTextureSize)
         createTextureRect(requiredTextureSize, dirtyRect, textureId);
     else
         updateTextureRect(dirtyRect, textureId);
@@ -150,7 +160,7 @@ void VideoLayerChromium::createTextureRect(const IntSize& requiredTextureSize, c
     ASSERT(bitmapSize == requiredTextureSize);
     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, requiredTextureSize.width(), requiredTextureSize.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
 
-    m_allocatedTextureId = textureId;
+    m_contentsTexture = textureId;
     m_allocatedTextureSize = requiredTextureSize;
 
     updateCompleted();
diff --git a/WebCore/platform/graphics/chromium/VideoLayerChromium.h b/WebCore/platform/graphics/chromium/VideoLayerChromium.h
index 746299f..b062e62 100644
--- a/WebCore/platform/graphics/chromium/VideoLayerChromium.h
+++ b/WebCore/platform/graphics/chromium/VideoLayerChromium.h
@@ -34,16 +34,16 @@
 
 #if USE(ACCELERATED_COMPOSITING)
 
-#include "LayerChromium.h"
+#include "ContentLayerChromium.h"
 
 namespace WebCore {
 
 // A Layer that contains a Video element.
-class VideoLayerChromium : public LayerChromium {
+class VideoLayerChromium : public ContentLayerChromium {
 public:
     static PassRefPtr<VideoLayerChromium> create(GraphicsLayerChromium* owner = 0);
     virtual bool drawsContent() { return true; }
-    virtual void updateTextureContents(unsigned textureId);
+    virtual void updateContents();
 
 private:
     VideoLayerChromium(GraphicsLayerChromium* owner);
@@ -51,8 +51,6 @@ private:
     void updateTextureRect(const IntRect& updateRect, unsigned textureId);
     void updateCompleted();
 
-    unsigned m_allocatedTextureId;
-    IntSize m_allocatedTextureSize;
 #if PLATFORM(SKIA)
     OwnPtr<skia::PlatformCanvas> m_canvas;
     OwnPtr<PlatformContextSkia> m_skiaContext;

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list