[Chromium] Avoid color mask operations for root layers
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 17 Nov 2011 01:29:50 +0000 (01:29 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 17 Nov 2011 01:29:50 +0000 (01:29 +0000)
https://bugs.webkit.org/show_bug.cgi?id=72452

Instead of relying on the combination of clearing the surface and initializing
the alpha channel to 1.0 followed by disabling alpha in the color mask when
rendering the root layer tiles, add shaders to support writing out opaque layers
(alpha channel values written as 1.0).

Patch by Daniel Sievers <sievers@chromium.org> on 2011-11-16
Reviewed by James Robinson.

No functional change made that requires new tests.

* platform/graphics/chromium/LayerRendererChromium.cpp:
(WebCore::LayerRendererChromium::drawLayersInternal):
(WebCore::LayerRendererChromium::initializeSharedObjects):
(WebCore::LayerRendererChromium::tilerProgramOpaque):
(WebCore::LayerRendererChromium::tilerProgramOpaqueAA):
(WebCore::LayerRendererChromium::tilerProgramSwizzleOpaque):
(WebCore::LayerRendererChromium::tilerProgramSwizzleOpaqueAA):
(WebCore::LayerRendererChromium::cleanupSharedObjects):
* platform/graphics/chromium/LayerRendererChromium.h:
* platform/graphics/chromium/ShaderChromium.cpp:
(WebCore::FragmentTexOpaqueBinding::FragmentTexOpaqueBinding):
(WebCore::FragmentTexOpaqueBinding::init):
(WebCore::FragmentShaderRGBATexOpaque::getShaderString):
(WebCore::FragmentShaderRGBATexSwizzleOpaque::getShaderString):
(WebCore::FragmentTexClampOpaqueAABinding::FragmentTexClampOpaqueAABinding):
(WebCore::FragmentTexClampOpaqueAABinding::init):
(WebCore::FragmentShaderRGBATexClampOpaqueAA::getShaderString):
(WebCore::FragmentShaderRGBATexClampSwizzleOpaqueAA::getShaderString):
* platform/graphics/chromium/ShaderChromium.h:
(WebCore::FragmentTexOpaqueBinding::alphaLocation):
(WebCore::FragmentTexOpaqueBinding::samplerLocation):
(WebCore::FragmentTexClampOpaqueAABinding::alphaLocation):
(WebCore::FragmentTexClampOpaqueAABinding::samplerLocation):
(WebCore::FragmentTexClampOpaqueAABinding::fragmentTexTransformLocation):
(WebCore::FragmentTexClampOpaqueAABinding::edgeLocation):
* platform/graphics/chromium/cc/CCTiledLayerImpl.cpp:
(WebCore::CCTiledLayerImpl::draw):
* platform/graphics/chromium/cc/CCTiledLayerImpl.h:

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

Source/WebCore/ChangeLog
Source/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp
Source/WebCore/platform/graphics/chromium/LayerRendererChromium.h
Source/WebCore/platform/graphics/chromium/ShaderChromium.cpp
Source/WebCore/platform/graphics/chromium/ShaderChromium.h
Source/WebCore/platform/graphics/chromium/cc/CCTiledLayerImpl.cpp
Source/WebCore/platform/graphics/chromium/cc/CCTiledLayerImpl.h

index 47f26e56ce7c408683c11f9361270f1714155823..c6fe6403a29358a664f285944a18e047db394b46 100644 (file)
@@ -1,3 +1,46 @@
+2011-11-16  Daniel Sievers  <sievers@chromium.org>
+
+        [Chromium] Avoid color mask operations for root layers
+        https://bugs.webkit.org/show_bug.cgi?id=72452
+
+        Instead of relying on the combination of clearing the surface and initializing
+        the alpha channel to 1.0 followed by disabling alpha in the color mask when
+        rendering the root layer tiles, add shaders to support writing out opaque layers
+        (alpha channel values written as 1.0).
+
+        Reviewed by James Robinson.
+
+        No functional change made that requires new tests.
+
+        * platform/graphics/chromium/LayerRendererChromium.cpp:
+        (WebCore::LayerRendererChromium::drawLayersInternal):
+        (WebCore::LayerRendererChromium::initializeSharedObjects):
+        (WebCore::LayerRendererChromium::tilerProgramOpaque):
+        (WebCore::LayerRendererChromium::tilerProgramOpaqueAA):
+        (WebCore::LayerRendererChromium::tilerProgramSwizzleOpaque):
+        (WebCore::LayerRendererChromium::tilerProgramSwizzleOpaqueAA):
+        (WebCore::LayerRendererChromium::cleanupSharedObjects):
+        * platform/graphics/chromium/LayerRendererChromium.h:
+        * platform/graphics/chromium/ShaderChromium.cpp:
+        (WebCore::FragmentTexOpaqueBinding::FragmentTexOpaqueBinding):
+        (WebCore::FragmentTexOpaqueBinding::init):
+        (WebCore::FragmentShaderRGBATexOpaque::getShaderString):
+        (WebCore::FragmentShaderRGBATexSwizzleOpaque::getShaderString):
+        (WebCore::FragmentTexClampOpaqueAABinding::FragmentTexClampOpaqueAABinding):
+        (WebCore::FragmentTexClampOpaqueAABinding::init):
+        (WebCore::FragmentShaderRGBATexClampOpaqueAA::getShaderString):
+        (WebCore::FragmentShaderRGBATexClampSwizzleOpaqueAA::getShaderString):
+        * platform/graphics/chromium/ShaderChromium.h:
+        (WebCore::FragmentTexOpaqueBinding::alphaLocation):
+        (WebCore::FragmentTexOpaqueBinding::samplerLocation):
+        (WebCore::FragmentTexClampOpaqueAABinding::alphaLocation):
+        (WebCore::FragmentTexClampOpaqueAABinding::samplerLocation):
+        (WebCore::FragmentTexClampOpaqueAABinding::fragmentTexTransformLocation):
+        (WebCore::FragmentTexClampOpaqueAABinding::edgeLocation):
+        * platform/graphics/chromium/cc/CCTiledLayerImpl.cpp:
+        (WebCore::CCTiledLayerImpl::draw):
+        * platform/graphics/chromium/cc/CCTiledLayerImpl.h:
+
 2011-11-16  Tim Horton  <timothy_horton@apple.com>
 
         Implement CSS3 Images cross-fade() image function
index 0038a05a156c4cfa1b4b7be52a63e01eb96a0690..f6c62ee9169eaade31cea5619aca8c0a2c0b8b73 100644 (file)
@@ -664,6 +664,7 @@ bool LayerRendererChromium::initializeSharedObjects()
     m_sharedGeometry = adoptPtr(new GeometryBinding(m_context.get()));
     m_renderSurfaceProgram = adoptPtr(new CCRenderSurface::Program(m_context.get()));
     m_tilerProgram = adoptPtr(new CCTiledLayerImpl::Program(m_context.get()));
+    m_tilerProgramOpaque = adoptPtr(new CCTiledLayerImpl::ProgramOpaque(m_context.get()));
 
     GLC(m_context.get(), m_context->flush());
 
@@ -748,6 +749,16 @@ const CCTiledLayerImpl::Program* LayerRendererChromium::tilerProgram()
     return m_tilerProgram.get();
 }
 
+const CCTiledLayerImpl::ProgramOpaque* LayerRendererChromium::tilerProgramOpaque()
+{
+    ASSERT(m_tilerProgramOpaque);
+    if (!m_tilerProgramOpaque->initialized()) {
+        TRACE_EVENT("LayerRendererChromium::tilerProgramOpaque::initialize", this, 0);
+        m_tilerProgramOpaque->initialize(m_context.get());
+    }
+    return m_tilerProgramOpaque.get();
+}
+
 const CCTiledLayerImpl::ProgramAA* LayerRendererChromium::tilerProgramAA()
 {
     if (!m_tilerProgramAA)
@@ -770,6 +781,17 @@ const CCTiledLayerImpl::ProgramSwizzle* LayerRendererChromium::tilerProgramSwizz
     return m_tilerProgramSwizzle.get();
 }
 
+const CCTiledLayerImpl::ProgramSwizzleOpaque* LayerRendererChromium::tilerProgramSwizzleOpaque()
+{
+    if (!m_tilerProgramSwizzleOpaque)
+        m_tilerProgramSwizzleOpaque = adoptPtr(new CCTiledLayerImpl::ProgramSwizzleOpaque(m_context.get()));
+    if (!m_tilerProgramSwizzleOpaque->initialized()) {
+        TRACE_EVENT("LayerRendererChromium::tilerProgramSwizzleOpaque::initialize", this, 0);
+        m_tilerProgramSwizzleOpaque->initialize(m_context.get());
+    }
+    return m_tilerProgramSwizzleOpaque.get();
+}
+
 const CCTiledLayerImpl::ProgramSwizzleAA* LayerRendererChromium::tilerProgramSwizzleAA()
 {
     if (!m_tilerProgramSwizzleAA)
@@ -849,10 +871,14 @@ void LayerRendererChromium::cleanupSharedObjects()
         m_headsUpDisplayProgram->cleanup(m_context.get());
     if (m_tilerProgram)
         m_tilerProgram->cleanup(m_context.get());
+    if (m_tilerProgramOpaque)
+        m_tilerProgramOpaque->cleanup(m_context.get());
     if (m_tilerProgramAA)
         m_tilerProgramAA->cleanup(m_context.get());
     if (m_tilerProgramSwizzle)
         m_tilerProgramSwizzle->cleanup(m_context.get());
+    if (m_tilerProgramSwizzleOpaque)
+        m_tilerProgramSwizzleOpaque->cleanup(m_context.get());
     if (m_tilerProgramSwizzleAA)
         m_tilerProgramSwizzleAA->cleanup(m_context.get());
     if (m_canvasLayerProgram)
@@ -877,8 +903,10 @@ void LayerRendererChromium::cleanupSharedObjects()
     m_borderProgram.clear();
     m_headsUpDisplayProgram.clear();
     m_tilerProgram.clear();
+    m_tilerProgramOpaque.clear();
     m_tilerProgramAA.clear();
     m_tilerProgramSwizzle.clear();
+    m_tilerProgramSwizzleOpaque.clear();
     m_tilerProgramSwizzleAA.clear();
     m_canvasLayerProgram.clear();
     m_pluginLayerProgram.clear();
index 174c8844025393b6a56dd8f6b15ba05662c54887..195117f0d5487010d9a5042d82f40b5975eba8fc 100644 (file)
@@ -120,8 +120,10 @@ public:
     const CCRenderSurface::MaskProgram* renderSurfaceMaskProgram();
     const CCRenderSurface::MaskProgramAA* renderSurfaceMaskProgramAA();
     const CCTiledLayerImpl::Program* tilerProgram();
+    const CCTiledLayerImpl::ProgramOpaque* tilerProgramOpaque();
     const CCTiledLayerImpl::ProgramAA* tilerProgramAA();
     const CCTiledLayerImpl::ProgramSwizzle* tilerProgramSwizzle();
+    const CCTiledLayerImpl::ProgramSwizzleOpaque* tilerProgramSwizzleOpaque();
     const CCTiledLayerImpl::ProgramSwizzleAA* tilerProgramSwizzleAA();
     const CCCanvasLayerImpl::Program* canvasLayerProgram();
     const CCPluginLayerImpl::Program* pluginLayerProgram();
@@ -205,7 +207,9 @@ private:
     OwnPtr<LayerChromium::BorderProgram> m_borderProgram;
     OwnPtr<CCHeadsUpDisplay::Program> m_headsUpDisplayProgram;
     OwnPtr<CCTiledLayerImpl::Program> m_tilerProgram;
+    OwnPtr<CCTiledLayerImpl::ProgramOpaque> m_tilerProgramOpaque;
     OwnPtr<CCTiledLayerImpl::ProgramSwizzle> m_tilerProgramSwizzle;
+    OwnPtr<CCTiledLayerImpl::ProgramSwizzleOpaque> m_tilerProgramSwizzleOpaque;
     OwnPtr<CCTiledLayerImpl::ProgramAA> m_tilerProgramAA;
     OwnPtr<CCTiledLayerImpl::ProgramSwizzleAA> m_tilerProgramSwizzleAA;
     OwnPtr<CCCanvasLayerImpl::Program> m_canvasLayerProgram;
index 22f677733d7a3da283b0d7fd618c80de2d4b1bc1..d7cfda529b49e1d857e0027e12bb1ae5c6c91ab8 100644 (file)
@@ -269,6 +269,18 @@ void FragmentTexAlphaBinding::init(GraphicsContext3D* context, unsigned program)
     ASSERT(m_samplerLocation != -1 && m_alphaLocation != -1);
 }
 
+FragmentTexOpaqueBinding::FragmentTexOpaqueBinding()
+    : m_samplerLocation(-1)
+{
+}
+
+void FragmentTexOpaqueBinding::init(GraphicsContext3D* context, unsigned program)
+{
+    m_samplerLocation = context->getUniformLocation(program, "s_texture");
+
+    ASSERT(m_samplerLocation != -1);
+}
+
 String FragmentShaderRGBATexFlipAlpha::getShaderString() const
 {
     return SHADER(
@@ -299,6 +311,20 @@ String FragmentShaderRGBATexAlpha::getShaderString() const
     );
 }
 
+String FragmentShaderRGBATexOpaque::getShaderString() const
+{
+    return SHADER(
+        precision mediump float;
+        varying vec2 v_texCoord;
+        uniform sampler2D s_texture;
+        void main()
+        {
+            vec4 texColor = texture2D(s_texture, v_texCoord);
+            gl_FragColor = vec4(texColor.rgb, 1.0);
+        }
+    );
+}
+
 String FragmentShaderRGBATexSwizzleAlpha::getShaderString() const
 {
     return SHADER(
@@ -314,6 +340,20 @@ String FragmentShaderRGBATexSwizzleAlpha::getShaderString() const
     );
 }
 
+String FragmentShaderRGBATexSwizzleOpaque::getShaderString() const
+{
+    return SHADER(
+        precision mediump float;
+        varying vec2 v_texCoord;
+        uniform sampler2D s_texture;
+        void main()
+        {
+            vec4 texColor = texture2D(s_texture, v_texCoord);
+            gl_FragColor = vec4(texColor.z, texColor.y, texColor.x, 1.0);
+        }
+    );
+}
+
 FragmentShaderRGBATexAlphaAA::FragmentShaderRGBATexAlphaAA()
     : m_samplerLocation(-1)
     , m_alphaLocation(-1)
index 9f56dc711b7d52873430851ddef9fdbe2537fcf2..e6a43488914a0db263d87727fee28b7470bebccd 100644 (file)
@@ -158,6 +158,18 @@ private:
     int m_alphaLocation;
 };
 
+class FragmentTexOpaqueBinding {
+public:
+    FragmentTexOpaqueBinding();
+
+    void init(GraphicsContext3D*, unsigned program);
+    int alphaLocation() const { return -1; }
+    int samplerLocation() const { return m_samplerLocation; }
+
+private:
+    int m_samplerLocation;
+};
+
 class FragmentShaderRGBATexFlipAlpha : public FragmentTexAlphaBinding {
 public:
     String getShaderString() const;
@@ -168,12 +180,23 @@ public:
     String getShaderString() const;
 };
 
-// Swizzles the red and blue component of sampled texel.
+class FragmentShaderRGBATexOpaque : public FragmentTexOpaqueBinding {
+public:
+    String getShaderString() const;
+};
+
+// Swizzles the red and blue component of sampled texel with alpha.
 class FragmentShaderRGBATexSwizzleAlpha : public FragmentTexAlphaBinding {
 public:
     String getShaderString() const;
 };
 
+// Swizzles the red and blue component of sampled texel without alpha.
+class FragmentShaderRGBATexSwizzleOpaque : public FragmentTexOpaqueBinding {
+public:
+    String getShaderString() const;
+};
+
 class FragmentShaderRGBATexAlphaAA {
 public:
     FragmentShaderRGBATexAlphaAA();
index 4e6ef97bdb72aace31d64b389b46617fd3072961..2209c8a4b105e710e9df18d506b3c90395125fb7 100644 (file)
@@ -139,10 +139,8 @@ void CCTiledLayerImpl::draw(LayerRendererChromium* layerRenderer)
     }
 
     GraphicsContext3D* context = layerRenderer->context();
-    if (isNonCompositedContent()) {
-        context->colorMask(true, true, true, false);
+    if (isNonCompositedContent())
         GLC(context, context->disable(GraphicsContext3D::BLEND));
-    }
 
     switch (m_sampledTexelFormat) {
     case LayerTextureUpdater::SampledTexelFormatRGBA:
@@ -150,8 +148,13 @@ void CCTiledLayerImpl::draw(LayerRendererChromium* layerRenderer)
             const ProgramAA* program = layerRenderer->tilerProgramAA();
             drawTiles(layerRenderer, layerRect, layerTransform, deviceMatrix, deviceRect, layerQuad, drawOpacity(), program, program->fragmentShader().fragmentTexTransformLocation(), program->fragmentShader().edgeLocation());
         } else {
-            const Program* program = layerRenderer->tilerProgram();
-            drawTiles(layerRenderer, layerRect, layerTransform, deviceMatrix, deviceRect, layerQuad, drawOpacity(), program, -1, -1);
+            if (isNonCompositedContent()) {
+                const ProgramOpaque* program = layerRenderer->tilerProgramOpaque();
+                drawTiles(layerRenderer, layerRect, layerTransform, deviceMatrix, deviceRect, layerQuad, drawOpacity(), program, -1, -1);
+            } else {
+                const Program* program = layerRenderer->tilerProgram();
+                drawTiles(layerRenderer, layerRect, layerTransform, deviceMatrix, deviceRect, layerQuad, drawOpacity(), program, -1, -1);
+            }
         }
         break;
     case LayerTextureUpdater::SampledTexelFormatBGRA:
@@ -159,18 +162,21 @@ void CCTiledLayerImpl::draw(LayerRendererChromium* layerRenderer)
             const ProgramSwizzleAA* program = layerRenderer->tilerProgramSwizzleAA();
             drawTiles(layerRenderer, layerRect, layerTransform, deviceMatrix, deviceRect, layerQuad, drawOpacity(), program, program->fragmentShader().fragmentTexTransformLocation(), program->fragmentShader().edgeLocation());
         } else {
-            const ProgramSwizzle* program = layerRenderer->tilerProgramSwizzle();
-            drawTiles(layerRenderer, layerRect, layerTransform, deviceMatrix, deviceRect, layerQuad, drawOpacity(), program, -1, -1);
+            if (isNonCompositedContent()) {
+                const ProgramSwizzleOpaque* program = layerRenderer->tilerProgramSwizzleOpaque();
+                drawTiles(layerRenderer, layerRect, layerTransform, deviceMatrix, deviceRect, layerQuad, drawOpacity(), program, -1, -1);
+            } else {
+                const ProgramSwizzle* program = layerRenderer->tilerProgramSwizzle();
+                drawTiles(layerRenderer, layerRect, layerTransform, deviceMatrix, deviceRect, layerQuad, drawOpacity(), program, -1, -1);
+            }
         }
         break;
     default:
         ASSERT_NOT_REACHED();
     }
 
-    if (isNonCompositedContent()) {
-        context->colorMask(true, true, true, true);
+    if (isNonCompositedContent())
         GLC(context, context->enable(GraphicsContext3D::BLEND));
-    }
 }
 
 void CCTiledLayerImpl::setTilingData(const CCLayerTilingData& tiler)
index dd1c29087e29b44633f749dd4a4fe4502f17affb..56ecb4d6ad46d3ec65a5d8a9e7c3167e468f3f07 100644 (file)
@@ -59,6 +59,10 @@ public:
     // Used when texture format does not match native color format.
     typedef ProgramBinding<VertexShaderTile, FragmentShaderRGBATexSwizzleAlpha> ProgramSwizzle;
 
+    // Same as above but ignoring alpha and writing out 1.0 for the alpha channel.
+    typedef ProgramBinding<VertexShaderTile, FragmentShaderRGBATexOpaque> ProgramOpaque;
+    typedef ProgramBinding<VertexShaderTile, FragmentShaderRGBATexSwizzleOpaque> ProgramSwizzleOpaque;
+
     // Shader program that produces anti-aliased layer edges.
     typedef ProgramBinding<VertexShaderTile, FragmentShaderRGBATexClampAlphaAA> ProgramAA;
     typedef ProgramBinding<VertexShaderTile, FragmentShaderRGBATexClampSwizzleAlphaAA> ProgramSwizzleAA;