2011-01-21 Vangelis Kokkevis <vangelis@chromium.org>
authorvangelis@chromium.org <vangelis@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 24 Jan 2011 01:53:35 +0000 (01:53 +0000)
committervangelis@chromium.org <vangelis@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 24 Jan 2011 01:53:35 +0000 (01:53 +0000)
        Reviewed by Kenneth Russell.

        [chromium] Add support for -webkit-mask properties to the
        accelerated compositing path.
        https://bugs.webkit.org/show_bug.cgi?id=49780

        Tests: Existing tests in LayoutTests/compositing/masks

        * platform/graphics/chromium/ContentLayerChromium.cpp:
        (WebCore::ContentLayerChromium::draw):
        (WebCore::ContentLayerChromium::unreserveContentsTexture):
        (WebCore::ContentLayerChromium::bindContentsTexture):
        * platform/graphics/chromium/ContentLayerChromium.h:
        * platform/graphics/chromium/GraphicsLayerChromium.cpp:
        (WebCore::GraphicsLayerChromium::setMaskLayer):
        * platform/graphics/chromium/GraphicsLayerChromium.h:
        * platform/graphics/chromium/LayerChromium.cpp:
        (WebCore::LayerChromium::LayerChromium):
        * platform/graphics/chromium/LayerChromium.h:
        (WebCore::LayerChromium::setMaskLayer):
        (WebCore::LayerChromium::maskLayer):
        (WebCore::LayerChromium::unreserveContentsTexture):
        (WebCore::LayerChromium::bindContentsTexture):
        * platform/graphics/chromium/LayerRendererChromium.cpp:
        (WebCore::LayerRendererChromium::updateLayersRecursive):
        * platform/graphics/chromium/LayerTexture.cpp:
        (WebCore::LayerTexture::bindTexture):
        * platform/graphics/chromium/RenderSurfaceChromium.cpp:
        (WebCore::RenderSurfaceChromium::SharedValues::SharedValues):
        (WebCore::RenderSurfaceChromium::SharedValues::~SharedValues):
        (WebCore::RenderSurfaceChromium::RenderSurfaceChromium):
        (WebCore::RenderSurfaceChromium::draw):
        * platform/graphics/chromium/RenderSurfaceChromium.h:
        (WebCore::RenderSurfaceChromium::SharedValues::maskShaderProgram):
        (WebCore::RenderSurfaceChromium::SharedValues::maskShaderSamplerLocation):
        (WebCore::RenderSurfaceChromium::SharedValues::maskShaderMaskSamplerLocation):
        (WebCore::RenderSurfaceChromium::SharedValues::maskShaderMatrixLocation):
        (WebCore::RenderSurfaceChromium::SharedValues::maskShaderAlphaLocation):

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

Source/WebCore/ChangeLog
Source/WebCore/platform/graphics/chromium/ContentLayerChromium.cpp
Source/WebCore/platform/graphics/chromium/ContentLayerChromium.h
Source/WebCore/platform/graphics/chromium/GraphicsLayerChromium.cpp
Source/WebCore/platform/graphics/chromium/GraphicsLayerChromium.h
Source/WebCore/platform/graphics/chromium/LayerChromium.cpp
Source/WebCore/platform/graphics/chromium/LayerChromium.h
Source/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp
Source/WebCore/platform/graphics/chromium/LayerTexture.cpp
Source/WebCore/platform/graphics/chromium/RenderSurfaceChromium.cpp
Source/WebCore/platform/graphics/chromium/RenderSurfaceChromium.h

index 22b8609..99f5b76 100644 (file)
@@ -1,3 +1,44 @@
+2011-01-21  Vangelis Kokkevis  <vangelis@chromium.org>
+
+        Reviewed by Kenneth Russell.
+
+        [chromium] Add support for -webkit-mask properties to the
+        accelerated compositing path.
+        https://bugs.webkit.org/show_bug.cgi?id=49780
+         
+        Tests: Existing tests in LayoutTests/compositing/masks
+
+        * platform/graphics/chromium/ContentLayerChromium.cpp:
+        (WebCore::ContentLayerChromium::draw):
+        (WebCore::ContentLayerChromium::unreserveContentsTexture):
+        (WebCore::ContentLayerChromium::bindContentsTexture):
+        * platform/graphics/chromium/ContentLayerChromium.h:
+        * platform/graphics/chromium/GraphicsLayerChromium.cpp:
+        (WebCore::GraphicsLayerChromium::setMaskLayer):
+        * platform/graphics/chromium/GraphicsLayerChromium.h:
+        * platform/graphics/chromium/LayerChromium.cpp:
+        (WebCore::LayerChromium::LayerChromium):
+        * platform/graphics/chromium/LayerChromium.h:
+        (WebCore::LayerChromium::setMaskLayer):
+        (WebCore::LayerChromium::maskLayer):
+        (WebCore::LayerChromium::unreserveContentsTexture):
+        (WebCore::LayerChromium::bindContentsTexture):
+        * platform/graphics/chromium/LayerRendererChromium.cpp:
+        (WebCore::LayerRendererChromium::updateLayersRecursive):
+        * platform/graphics/chromium/LayerTexture.cpp:
+        (WebCore::LayerTexture::bindTexture):
+        * platform/graphics/chromium/RenderSurfaceChromium.cpp:
+        (WebCore::RenderSurfaceChromium::SharedValues::SharedValues):
+        (WebCore::RenderSurfaceChromium::SharedValues::~SharedValues):
+        (WebCore::RenderSurfaceChromium::RenderSurfaceChromium):
+        (WebCore::RenderSurfaceChromium::draw):
+        * platform/graphics/chromium/RenderSurfaceChromium.h:
+        (WebCore::RenderSurfaceChromium::SharedValues::maskShaderProgram):
+        (WebCore::RenderSurfaceChromium::SharedValues::maskShaderSamplerLocation):
+        (WebCore::RenderSurfaceChromium::SharedValues::maskShaderMaskSamplerLocation):
+        (WebCore::RenderSurfaceChromium::SharedValues::maskShaderMatrixLocation):
+        (WebCore::RenderSurfaceChromium::SharedValues::maskShaderAlphaLocation):
+
 2011-01-23  Patrick Gansterer  <paroga@webkit.org>
 
         Reviewed by Darin Adler.
index d00faf8..a38f6bd 100644 (file)
@@ -343,7 +343,7 @@ void ContentLayerChromium::draw()
     ASSERT(sv && sv->initialized());
     GraphicsContext3D* context = layerRendererContext();
     GLC(context, context->activeTexture(GraphicsContext3D::TEXTURE0));
-    m_contentsTexture->bindTexture();
+    bindContentsTexture();
     layerRenderer()->useShader(sv->contentShaderProgram());
     GLC(context, context->uniform1i(sv->shaderSamplerLocation(), 0));
 
@@ -361,8 +361,21 @@ void ContentLayerChromium::draw()
                          drawOpacity(), sv->shaderMatrixLocation(),
                          sv->shaderAlphaLocation());
     }
-    m_contentsTexture->unreserve();
+    unreserveContentsTexture();
+}
+
+void ContentLayerChromium::unreserveContentsTexture()
+{
+    if (m_contentsTexture)
+        m_contentsTexture->unreserve();
 }
 
+void ContentLayerChromium::bindContentsTexture()
+{
+    if (m_contentsTexture)
+        m_contentsTexture->bindTexture();
+}
+
+
 }
 #endif // USE(ACCELERATED_COMPOSITING)
index dc1630b..3363518 100644 (file)
@@ -50,6 +50,9 @@ public:
     virtual ~ContentLayerChromium();
 
     virtual void updateContentsIfDirty();
+    virtual void unreserveContentsTexture();
+    virtual void bindContentsTexture();
+
     virtual void draw();
     virtual bool drawsContent() { return m_owner && m_owner->drawsContent(); }
 
index 5e8d148..e6f1c9b 100644 (file)
@@ -263,6 +263,17 @@ void GraphicsLayerChromium::setContentsOpaque(bool opaque)
     updateContentsOpaque();
 }
 
+void GraphicsLayerChromium::setMaskLayer(GraphicsLayer* maskLayer)
+{
+    if (maskLayer == m_maskLayer)
+        return;
+
+    GraphicsLayer::setMaskLayer(maskLayer);
+
+    LayerChromium* maskLayerChromium = m_maskLayer ? m_maskLayer->platformLayer() : 0;
+    m_layer->setMaskLayer(maskLayerChromium);
+}
+
 void GraphicsLayerChromium::setBackfaceVisibility(bool visible)
 {
     if (m_backfaceVisibility == visible)
index 130c25c..f39dc0f 100644 (file)
@@ -67,6 +67,7 @@ public:
     virtual void setPreserves3D(bool);
     virtual void setMasksToBounds(bool);
     virtual void setDrawsContent(bool);
+    virtual void setMaskLayer(GraphicsLayer*);
 
     virtual void setBackgroundColor(const Color&);
     virtual void clearBackgroundColor();
index b7ab098..f7742a3 100644 (file)
@@ -143,6 +143,7 @@ PassRefPtr<LayerChromium> LayerChromium::create(GraphicsLayerChromium* owner)
 LayerChromium::LayerChromium(GraphicsLayerChromium* owner)
     : m_owner(owner)
     , m_contentsDirty(false)
+    , m_maskLayer(0)
     , m_targetRenderSurface(0)
     , m_superlayer(0)
     , m_anchorPoint(0.5, 0.5)
index a0a690f..579ca7a 100644 (file)
@@ -112,6 +112,9 @@ public:
     void setName(const String& name) { m_name = name; }
     String name() const { return m_name; }
 
+    void setMaskLayer(LayerChromium* maskLayer) { m_maskLayer = maskLayer; }
+    LayerChromium* maskLayer() const { return m_maskLayer.get(); }
+
     void setNeedsDisplay(const FloatRect& dirtyRect);
     void setNeedsDisplay();
     const FloatRect& dirtyRect() const { return m_dirtyRect; }
@@ -158,6 +161,8 @@ public:
     // These methods typically need to be overwritten by derived classes.
     virtual bool drawsContent() { return false; }
     virtual void updateContentsIfDirty() { }
+    virtual void unreserveContentsTexture() { }
+    virtual void bindContentsTexture() { }
     virtual void draw() { }
 
     void drawDebugBorder();
@@ -222,6 +227,8 @@ protected:
     FloatRect m_dirtyRect;
     bool m_contentsDirty;
 
+    RefPtr<LayerChromium> m_maskLayer;
+
     // Render surface this layer draws into. This is a surface that can belong
     // either to this layer (if m_targetRenderSurface == m_renderSurface) or
     // to an ancestor of this layer. The target render surface determines the
index 9b47635..dd36aa8 100644 (file)
@@ -452,7 +452,9 @@ void LayerRendererChromium::updateLayersRecursive(LayerChromium* layer, const Tr
     // of their parent.
     bool useSurfaceForClipping = layer->masksToBounds() && !isScaleOrTranslation(combinedTransform);
     bool useSurfaceForOpacity = layer->opacity() != 1 && !layer->preserves3D();
-    if ((useSurfaceForClipping || useSurfaceForOpacity) && layer->descendantsDrawContent()) {
+    bool useSurfaceForMasking = layer->maskLayer();
+    if (((useSurfaceForClipping || useSurfaceForOpacity) && layer->descendantsDrawContent())
+        || useSurfaceForMasking) {
         RenderSurfaceChromium* renderSurface = layer->m_renderSurface.get();
         if (!renderSurface)
             renderSurface = layer->createRenderSurface();
@@ -486,6 +488,13 @@ void LayerRendererChromium::updateLayersRecursive(LayerChromium* layer, const Tr
 
         renderSurface->m_layerList.clear();
 
+        if (layer->maskLayer()) {
+            renderSurface->m_maskLayer = layer->maskLayer();
+            layer->maskLayer()->setLayerRenderer(this);
+            layer->maskLayer()->m_targetRenderSurface = renderSurface;
+        } else
+            renderSurface->m_maskLayer = 0;
+
         renderSurfaceLayerList.append(layer);
     } else {
         // DT = M[p] * LT
@@ -566,7 +575,7 @@ void LayerRendererChromium::updateLayersRecursive(LayerChromium* layer, const Tr
             layer->m_drawableContentRect.unite(sublayer->m_drawableContentRect);
     }
 
-    if (layer->masksToBounds())
+    if (layer->masksToBounds() || useSurfaceForMasking)
         layer->m_drawableContentRect.intersect(transformedLayerRect);
 
     if (layer->m_renderSurface && layer != m_rootLayer) {
index 32bfa0b..23cb4b3 100644 (file)
@@ -79,6 +79,7 @@ void LayerTexture::unreserve()
 
 void LayerTexture::bindTexture()
 {
+    ASSERT(m_textureManager->hasTexture(m_token));
     m_context->bindTexture(GraphicsContext3D::TEXTURE_2D, m_textureId);
 }
 
index 696828f..a3b660f 100644 (file)
@@ -38,15 +38,17 @@ namespace WebCore {
 RenderSurfaceChromium::SharedValues::SharedValues(GraphicsContext3D* context)
     : m_context(context)
     , m_shaderProgram(0)
+    , m_maskShaderProgram(0)
     , m_shaderSamplerLocation(-1)
     , m_shaderMatrixLocation(-1)
     , m_shaderAlphaLocation(-1)
+    , m_maskShaderSamplerLocation(-1)
+    , m_maskShaderMaskSamplerLocation(-1)
+    , m_maskShaderMatrixLocation(-1)
+    , m_maskShaderAlphaLocation(-1)
     , m_initialized(false)
 {
-    // The following program composites layers whose contents are the results of a previous
-    // render operation and therefore doesn't perform any color swizzling. It is used
-    // in scrolling and for compositing offscreen textures.
-    char renderSurfaceVertexShaderString[] =
+    char vertexShaderString[] =
         "attribute vec4 a_position;   \n"
         "attribute vec2 a_texCoord;   \n"
         "uniform mat4 matrix;         \n"
@@ -56,7 +58,7 @@ RenderSurfaceChromium::SharedValues::SharedValues(GraphicsContext3D* context)
         "  gl_Position = matrix * a_position; \n"
         "  v_texCoord = a_texCoord;   \n"
         "}                            \n";
-    char renderSurfaceFragmentShaderString[] =
+    char fragmentShaderString[] =
         "precision mediump float;                            \n"
         "varying vec2 v_texCoord;                            \n"
         "uniform sampler2D s_texture;                        \n"
@@ -66,9 +68,22 @@ RenderSurfaceChromium::SharedValues::SharedValues(GraphicsContext3D* context)
         "  vec4 texColor = texture2D(s_texture, v_texCoord); \n"
         "  gl_FragColor = vec4(texColor.x, texColor.y, texColor.z, texColor.w) * alpha; \n"
         "}                                                   \n";
+    char fragmentShaderWithMaskString[] =
+        "precision mediump float;                            \n"
+        "varying vec2 v_texCoord;                            \n"
+        "uniform sampler2D s_texture;                        \n"
+        "uniform sampler2D s_mask;                           \n"
+        "uniform float alpha;                                \n"
+        "void main()                                         \n"
+        "{                                                   \n"
+        "  vec4 texColor = texture2D(s_texture, v_texCoord); \n"
+        "  vec4 maskColor = texture2D(s_mask, v_texCoord);   \n"
+        "  gl_FragColor = vec4(texColor.x, texColor.y, texColor.z, texColor.w) * alpha * maskColor.w; \n"
+        "}                                                   \n";
 
-    m_shaderProgram = LayerChromium::createShaderProgram(m_context, renderSurfaceVertexShaderString, renderSurfaceFragmentShaderString);
-    if (!m_shaderProgram) {
+    m_shaderProgram = LayerChromium::createShaderProgram(m_context, vertexShaderString, fragmentShaderString);
+    m_maskShaderProgram = LayerChromium::createShaderProgram(m_context, vertexShaderString, fragmentShaderWithMaskString);
+    if (!m_shaderProgram || !m_maskShaderProgram) {
         LOG_ERROR("RenderSurfaceChromium: Failed to create shader program");
         return;
     }
@@ -76,10 +91,24 @@ RenderSurfaceChromium::SharedValues::SharedValues(GraphicsContext3D* context)
     GLC(m_context, m_shaderSamplerLocation = m_context->getUniformLocation(m_shaderProgram, "s_texture"));
     GLC(m_context, m_shaderMatrixLocation = m_context->getUniformLocation(m_shaderProgram, "matrix"));
     GLC(m_context, m_shaderAlphaLocation = m_context->getUniformLocation(m_shaderProgram, "alpha"));
-    if (m_shaderSamplerLocation == -1 || m_shaderMatrixLocation == -1 || m_shaderAlphaLocation == -1) {
-        LOG_ERROR("Failed to initialize texture layer shader.");
+
+    GLC(m_context, m_maskShaderSamplerLocation = m_context->getUniformLocation(m_maskShaderProgram, "s_texture"));
+    GLC(m_context, m_maskShaderMaskSamplerLocation = m_context->getUniformLocation(m_maskShaderProgram, "s_mask"));
+    GLC(m_context, m_maskShaderMatrixLocation = m_context->getUniformLocation(m_maskShaderProgram, "matrix"));
+    GLC(m_context, m_maskShaderAlphaLocation = m_context->getUniformLocation(m_maskShaderProgram, "alpha"));
+
+    if (m_shaderSamplerLocation == -1 || m_shaderMatrixLocation == -1 || m_shaderAlphaLocation == -1
+        || m_maskShaderSamplerLocation == -1 || m_maskShaderMaskSamplerLocation == -1 || m_maskShaderMatrixLocation == -1 || m_maskShaderAlphaLocation == -1) {
+        LOG_ERROR("Failed to initialize render surface shaders.");
         return;
     }
+
+    GLC(m_context, m_context->useProgram(m_shaderProgram));
+    GLC(m_context, m_context->uniform1i(m_shaderSamplerLocation, 0));
+    GLC(m_context, m_context->useProgram(m_maskShaderProgram));
+    GLC(m_context, m_context->uniform1i(m_maskShaderSamplerLocation, 0));
+    GLC(m_context, m_context->uniform1i(m_maskShaderMaskSamplerLocation, 1));
+    GLC(m_context, m_context->useProgram(0));
     m_initialized = true;
 }
 
@@ -87,10 +116,13 @@ RenderSurfaceChromium::SharedValues::~SharedValues()
 {
     if (m_shaderProgram)
         GLC(m_context, m_context->deleteProgram(m_shaderProgram));
+    if (m_maskShaderProgram)
+        GLC(m_context, m_context->deleteProgram(m_maskShaderProgram));
 }
 
 RenderSurfaceChromium::RenderSurfaceChromium(LayerChromium* owningLayer)
     : m_owningLayer(owningLayer)
+    , m_maskLayer(0)
     , m_skipsDraw(false)
 {
 }
@@ -141,19 +173,44 @@ void RenderSurfaceChromium::draw()
     if (m_skipsDraw || !m_contentsTexture)
         return;
 
-    m_contentsTexture->bindTexture();
-
+    GraphicsContext3D* context3D = layerRenderer()->context();
+    int shaderMatrixLocation = -1;
+    int shaderAlphaLocation = -1;
     const RenderSurfaceChromium::SharedValues* sv = layerRenderer()->renderSurfaceSharedValues();
     ASSERT(sv && sv->initialized());
+    bool useMask = false;
+    if (m_maskLayer && m_maskLayer->drawsContent()) {
+        m_maskLayer->updateContentsIfDirty();
+        if (!m_maskLayer->bounds().isEmpty()) {
+            context3D->makeContextCurrent();
+            layerRenderer()->useShader(sv->maskShaderProgram());
+            GLC(context3D, context3D->activeTexture(GraphicsContext3D::TEXTURE0));
+            m_contentsTexture->bindTexture();
+            GLC(context3D, context3D->activeTexture(GraphicsContext3D::TEXTURE1));
+            m_maskLayer->bindContentsTexture();
+            GLC(context3D, context3D->activeTexture(GraphicsContext3D::TEXTURE0));
+            shaderMatrixLocation = sv->maskShaderMatrixLocation();
+            shaderAlphaLocation = sv->maskShaderAlphaLocation();
+            useMask = true;
+        }
+    }
+
+    if (!useMask) {
+        layerRenderer()->useShader(sv->shaderProgram());
+        m_contentsTexture->bindTexture();
+        shaderMatrixLocation = sv->shaderMatrixLocation();
+        shaderAlphaLocation = sv->shaderAlphaLocation();
+    }
 
-    layerRenderer()->useShader(sv->shaderProgram());
     layerRenderer()->setScissorToRect(m_scissorRect);
 
     LayerChromium::drawTexturedQuad(layerRenderer()->context(), layerRenderer()->projectionMatrix(), m_drawTransform,
                                     m_contentRect.width(), m_contentRect.height(), m_drawOpacity,
-                                    sv->shaderMatrixLocation(), sv->shaderAlphaLocation());
+                                    shaderMatrixLocation, shaderAlphaLocation);
 
     m_contentsTexture->unreserve();
+    if (m_maskLayer)
+        m_maskLayer->unreserveContentsTexture();
 }
 
 }
index 689a6eb..42ab593 100644 (file)
@@ -64,18 +64,28 @@ public:
         ~SharedValues();
 
         unsigned shaderProgram() const { return m_shaderProgram; }
+        unsigned maskShaderProgram() const { return m_maskShaderProgram; }
         int shaderSamplerLocation() const { return m_shaderSamplerLocation; }
         int shaderMatrixLocation() const { return m_shaderMatrixLocation; }
         int shaderAlphaLocation() const { return m_shaderAlphaLocation; }
+        int maskShaderSamplerLocation() const { return m_maskShaderSamplerLocation; }
+        int maskShaderMaskSamplerLocation() const { return m_maskShaderMaskSamplerLocation; }
+        int maskShaderMatrixLocation() const { return m_maskShaderMatrixLocation; }
+        int maskShaderAlphaLocation() const { return m_maskShaderAlphaLocation; }
         bool initialized() const { return m_initialized; }
 
     private:
         GraphicsContext3D* m_context;
 
         unsigned m_shaderProgram;
+        unsigned m_maskShaderProgram;
         int m_shaderSamplerLocation;
         int m_shaderMatrixLocation;
         int m_shaderAlphaLocation;
+        int m_maskShaderSamplerLocation;
+        int m_maskShaderMaskSamplerLocation;
+        int m_maskShaderMatrixLocation;
+        int m_maskShaderAlphaLocation;
         bool m_initialized;
     };
 
@@ -83,6 +93,8 @@ private:
     LayerRendererChromium* layerRenderer();
 
     LayerChromium* m_owningLayer;
+    LayerChromium* m_maskLayer;
+
     IntRect m_contentRect;
     bool m_skipsDraw;
     OwnPtr<LayerTexture> m_contentsTexture;