Title: [115138] trunk
Revision
115138
Author
ach...@adobe.com
Date
2012-04-24 16:55:50 -0700 (Tue, 24 Apr 2012)

Log Message

CSS Shaders: Repainting the FECustomFilter requires full source image
https://bugs.webkit.org/show_bug.cgi?id=76689

Source/WebCore:

Reviewed by Dean Jackson..

When a pixel of a filtered layer changes we need to update the whole bounding box of the layer and
not just the dirty rectangle. That's because the shader might change the color of any of the pixels inside the box.

Added tests where a shader is moving and rotating the contents and the actual
dirty box of the source image is not the same as the output dirty rectangle.

Tests: css3/filters/custom/filter-repaint-custom-clipped.html
       css3/filters/custom/filter-repaint-custom-rotated.html
       css3/filters/custom/filter-repaint-custom.html

* rendering/FilterEffectRenderer.cpp:
(WebCore::FilterEffectRenderer::FilterEffectRenderer):
(WebCore::FilterEffectRenderer::build):
(WebCore::FilterEffectRenderer::computeSourceImageRectForDirtyRect):
* rendering/FilterEffectRenderer.h:
(FilterEffectRenderer):
(WebCore::FilterEffectRenderer::hasCustomShaderFilter):
* rendering/RenderLayer.cpp:
(WebCore::RenderLayer::setFilterBackendNeedsRepaintingInRect):

LayoutTests:

Reviewed by Dean Jackson.

* css3/filters/custom/filter-repaint-custom-clipped-expected.png: Added.
* css3/filters/custom/filter-repaint-custom-clipped-expected.txt: Added.
* css3/filters/custom/filter-repaint-custom-clipped.html: Added.
* css3/filters/custom/filter-repaint-custom-expected.png: Added.
* css3/filters/custom/filter-repaint-custom-expected.txt: Added.
* css3/filters/custom/filter-repaint-custom-rotated-expected.png: Added.
* css3/filters/custom/filter-repaint-custom-rotated-expected.txt: Added.
* css3/filters/custom/filter-repaint-custom-rotated.html: Added.
* css3/filters/custom/filter-repaint-custom.html: Added.
* css3/filters/resources/color-add.fs: Added.
* css3/filters/resources/vertex-horizontal-offset.vs: Added.
* css3/filters/resources/vertex-rotate.vs: Added.
* platform/chromium-mac/css3/filters/custom/filter-repaint-custom-clipped-expected.png: Added.
* platform/chromium-mac/css3/filters/custom/filter-repaint-custom-expected.png: Added.
* platform/chromium-mac/css3/filters/custom/filter-repaint-custom-rotated-expected.png: Added.
* platform/chromium/test_expectations.txt:

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (115137 => 115138)


--- trunk/LayoutTests/ChangeLog	2012-04-24 23:52:44 UTC (rev 115137)
+++ trunk/LayoutTests/ChangeLog	2012-04-24 23:55:50 UTC (rev 115138)
@@ -1,3 +1,27 @@
+2012-04-24  Alexandru Chiculita  <ach...@adobe.com>
+
+        CSS Shaders: Repainting the FECustomFilter requires full source image
+        https://bugs.webkit.org/show_bug.cgi?id=76689
+
+        Reviewed by Dean Jackson.
+
+        * css3/filters/custom/filter-repaint-custom-clipped-expected.png: Added.
+        * css3/filters/custom/filter-repaint-custom-clipped-expected.txt: Added.
+        * css3/filters/custom/filter-repaint-custom-clipped.html: Added.
+        * css3/filters/custom/filter-repaint-custom-expected.png: Added.
+        * css3/filters/custom/filter-repaint-custom-expected.txt: Added.
+        * css3/filters/custom/filter-repaint-custom-rotated-expected.png: Added.
+        * css3/filters/custom/filter-repaint-custom-rotated-expected.txt: Added.
+        * css3/filters/custom/filter-repaint-custom-rotated.html: Added.
+        * css3/filters/custom/filter-repaint-custom.html: Added.
+        * css3/filters/resources/color-add.fs: Added.
+        * css3/filters/resources/vertex-horizontal-offset.vs: Added.
+        * css3/filters/resources/vertex-rotate.vs: Added.
+        * platform/chromium-mac/css3/filters/custom/filter-repaint-custom-clipped-expected.png: Added.
+        * platform/chromium-mac/css3/filters/custom/filter-repaint-custom-expected.png: Added.
+        * platform/chromium-mac/css3/filters/custom/filter-repaint-custom-rotated-expected.png: Added.
+        * platform/chromium/test_expectations.txt:
+
 2012-04-24  Alpha Lam  <hc...@chromium.org>
 
         [chromium] Unreviewed test expectations update.

Added: trunk/LayoutTests/css3/filters/custom/filter-repaint-custom-clipped-expected.png


(Binary files differ)
Property changes on: trunk/LayoutTests/css3/filters/custom/filter-repaint-custom-clipped-expected.png ___________________________________________________________________

Added: svn:mime-type

Added: trunk/LayoutTests/css3/filters/custom/filter-repaint-custom-clipped-expected.txt (0 => 115138)


--- trunk/LayoutTests/css3/filters/custom/filter-repaint-custom-clipped-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/css3/filters/custom/filter-repaint-custom-clipped-expected.txt	2012-04-24 23:55:50 UTC (rev 115138)
@@ -0,0 +1 @@
+

Added: trunk/LayoutTests/css3/filters/custom/filter-repaint-custom-clipped.html (0 => 115138)


--- trunk/LayoutTests/css3/filters/custom/filter-repaint-custom-clipped.html	                        (rev 0)
+++ trunk/LayoutTests/css3/filters/custom/filter-repaint-custom-clipped.html	2012-04-24 23:55:50 UTC (rev 115138)
@@ -0,0 +1,60 @@
+<!DOCTYPE html>
+<!-- 
+    This tests verifies that shader filter is repainted using the full source image of the element instead of just the dirty area.
+    Also it tests that the clipping rectangle of the box is not affecting the filter.
+    There should be one light green box on the screen. No red should be visible.
+-->
+<html>
+<head>
+    <script>
+        if (window.layoutTestController) {
+            window.layoutTestController.overridePreference("WebKitCSSCustomFilterEnabled", "1");
+            window.layoutTestController.overridePreference("WebKitWebGLEnabled", "1");
+            window.layoutTestController.dumpAsText(true);
+        }
+        function repaintTest()
+        {
+            document.querySelector(".before").classList.remove("before");
+        }
+    </script>
+    <style>
+        .clipping_box {
+            margin: 20px;
+            width: 100px;
+            height: 100px;
+            overflow: hidden;
+            background: red;
+        }
+        
+        .empty_box {
+            height: 50px;
+        }
+        
+        .box {
+            height: 150px;
+            width: 100px;
+            background-color: green;
+        }
+        
+        .before {
+            background-color: transparent;
+        }
+
+        .shader {
+            -webkit-filter: custom(url(../resources/vertex-horizontal-offset.vs) url(../resources/color-add.fs), offset -0.5, add 0.1);
+        }
+    </style>
+
+    <script src=""
+</head>
+
+<body _onload_="runRepaintTest()">
+
+    <div class="clipping_box">
+        <div class="shader">
+            <div class="empty_box"></div>
+            <div class="box before"></div>
+        </div>
+    </div>
+</body>
+</html>
\ No newline at end of file

Added: trunk/LayoutTests/css3/filters/custom/filter-repaint-custom-expected.png


(Binary files differ)
Property changes on: trunk/LayoutTests/css3/filters/custom/filter-repaint-custom-expected.png ___________________________________________________________________

Added: svn:mime-type

Added: trunk/LayoutTests/css3/filters/custom/filter-repaint-custom-expected.txt (0 => 115138)


--- trunk/LayoutTests/css3/filters/custom/filter-repaint-custom-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/css3/filters/custom/filter-repaint-custom-expected.txt	2012-04-24 23:55:50 UTC (rev 115138)
@@ -0,0 +1 @@
+

Added: trunk/LayoutTests/css3/filters/custom/filter-repaint-custom-rotated-expected.png


(Binary files differ)
Property changes on: trunk/LayoutTests/css3/filters/custom/filter-repaint-custom-rotated-expected.png ___________________________________________________________________

Added: svn:mime-type

Added: trunk/LayoutTests/css3/filters/custom/filter-repaint-custom-rotated-expected.txt (0 => 115138)


--- trunk/LayoutTests/css3/filters/custom/filter-repaint-custom-rotated-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/css3/filters/custom/filter-repaint-custom-rotated-expected.txt	2012-04-24 23:55:50 UTC (rev 115138)
@@ -0,0 +1 @@
+

Added: trunk/LayoutTests/css3/filters/custom/filter-repaint-custom-rotated.html (0 => 115138)


--- trunk/LayoutTests/css3/filters/custom/filter-repaint-custom-rotated.html	                        (rev 0)
+++ trunk/LayoutTests/css3/filters/custom/filter-repaint-custom-rotated.html	2012-04-24 23:55:50 UTC (rev 115138)
@@ -0,0 +1,62 @@
+<!DOCTYPE html>
+<!-- 
+    This tests verifies that filter shader is repainted using the full source image of the element instead of just the dirty area.
+    Also it tests that the clipping or the transform rectangle of the box is not affecting the filter.
+    There should be one light green boxes on the screen. No red should be visible.
+-->
+<html>
+<head>
+    <script>
+        if (window.layoutTestController) {
+            window.layoutTestController.overridePreference("WebKitCSSCustomFilterEnabled", "1");
+            window.layoutTestController.overridePreference("WebKitWebGLEnabled", "1");
+            window.layoutTestController.dumpAsText(true);
+        }
+        function repaintTest()
+        {
+            document.querySelector(".before").classList.remove("before");
+        }
+    </script>
+    <style>
+        .clipping_box {
+            margin: 100px;
+            width: 100px;
+            height: 100px;
+            overflow: hidden;
+            background: red;
+        }
+        
+        .empty_box {
+            height: 50px;
+        }
+        
+        .box {
+            height: 150px;
+            width: 100px;
+            background-color: green;
+        }
+        
+        .before {
+            background-color: transparent;
+        }
+
+        .shader {
+            -webkit-filter: custom(url(../resources/vertex-horizontal-offset.vs) url(../resources/color-add.fs), offset -0.5, add 0.1);
+            -webkit-transform-origin: 50px 50px;
+            -webkit-transform: rotate(90deg);
+        }
+    </style>
+
+    <script src=""
+</head>
+
+<body _onload_="runRepaintTest()">
+
+    <div class="clipping_box">
+        <div class="shader">
+            <div class="empty_box"></div>
+            <div class="box before"></div>
+        </div>
+    </div>
+</body>
+</html>
\ No newline at end of file

Added: trunk/LayoutTests/css3/filters/custom/filter-repaint-custom.html (0 => 115138)


--- trunk/LayoutTests/css3/filters/custom/filter-repaint-custom.html	                        (rev 0)
+++ trunk/LayoutTests/css3/filters/custom/filter-repaint-custom.html	2012-04-24 23:55:50 UTC (rev 115138)
@@ -0,0 +1,51 @@
+<!DOCTYPE html>
+<!-- 
+    This tests verifies that the shader filter is repainted using the full source image of the element instead of just the dirty area. 
+    There should be 4 boxes of same size. 3 of them are green and the last one on the right is blue.
+-->
+<html>
+<head>
+    <script>
+        if (window.layoutTestController) {
+            window.layoutTestController.overridePreference("WebKitCSSCustomFilterEnabled", "1");
+            window.layoutTestController.overridePreference("WebKitWebGLEnabled", "1");
+            window.layoutTestController.dumpAsText(true);
+        }
+        function repaintTest()
+        {
+            document.querySelector(".before").classList.remove("before");
+        }
+    </script>
+    <style>
+        .box {
+            margin-top: 10px;
+            margin-bottom: 10px;
+            height: 50px;
+            width: 50px;
+            background-color: green;
+        }
+
+        .before {
+            background-color: red;
+        }
+
+        .shader {
+            border-top: 50px solid blue;
+            width: 50px;
+            -webkit-filter: custom(url(../resources/vertex-rotate.vs) url(../resources/color-add.fs), rotateBy 90, add 0.1);
+        }
+    </style>
+
+    <script src=""
+</head>
+
+<body _onload_="runRepaintTest()">
+
+    <div class="shader">
+        <div class="box"></div>
+        <div class="box before"></div>
+        <div class="box"></div>
+    </div>
+
+</body>
+</html>
\ No newline at end of file

Added: trunk/LayoutTests/css3/filters/resources/color-add.fs (0 => 115138)


--- trunk/LayoutTests/css3/filters/resources/color-add.fs	                        (rev 0)
+++ trunk/LayoutTests/css3/filters/resources/color-add.fs	2012-04-24 23:55:50 UTC (rev 115138)
@@ -0,0 +1,10 @@
+precision mediump float;
+varying vec2 v_texCoord;
+uniform sampler2D s_texture;
+uniform float add;
+
+void main()
+{
+    // Offset the color value with "add" on each color channel.
+    gl_FragColor = texture2D(s_texture, v_texCoord) + add;
+}
\ No newline at end of file

Added: trunk/LayoutTests/css3/filters/resources/vertex-horizontal-offset.vs (0 => 115138)


--- trunk/LayoutTests/css3/filters/resources/vertex-horizontal-offset.vs	                        (rev 0)
+++ trunk/LayoutTests/css3/filters/resources/vertex-horizontal-offset.vs	2012-04-24 23:55:50 UTC (rev 115138)
@@ -0,0 +1,15 @@
+precision mediump float;
+
+attribute vec4 a_position;
+attribute vec2 a_texCoord;
+
+uniform mat4 u_projectionMatrix;
+uniform float offset;
+
+varying vec2 v_texCoord;
+
+void main()
+{
+    gl_Position = u_projectionMatrix * (a_position + vec4(0.0, offset, 0.0, 0.0));
+    v_texCoord = a_texCoord;
+}
\ No newline at end of file

Added: trunk/LayoutTests/css3/filters/resources/vertex-rotate.vs (0 => 115138)


--- trunk/LayoutTests/css3/filters/resources/vertex-rotate.vs	                        (rev 0)
+++ trunk/LayoutTests/css3/filters/resources/vertex-rotate.vs	2012-04-24 23:55:50 UTC (rev 115138)
@@ -0,0 +1,22 @@
+precision mediump float;
+
+attribute vec4 a_position;
+attribute vec2 a_texCoord;
+
+uniform mat4 u_projectionMatrix;
+uniform float rotateBy;
+
+varying vec2 v_texCoord;
+
+mat4 rotateZMatrix(float f) {
+    return mat4(cos(f), sin(f), 0.0, 0.0,
+                -sin(f), cos(f), 0.0, 0.0,
+                0.0, 0.0, 1.0, 0.0,
+                0.0, 0.0, 0.0, 1.0);
+}
+
+void main()
+{
+    gl_Position = u_projectionMatrix * rotateZMatrix(rotateBy * 3.14 / 180.0) * a_position;
+    v_texCoord = a_texCoord;
+}
\ No newline at end of file

Modified: trunk/LayoutTests/platform/chromium/test_expectations.txt (115137 => 115138)


--- trunk/LayoutTests/platform/chromium/test_expectations.txt	2012-04-24 23:52:44 UTC (rev 115137)
+++ trunk/LayoutTests/platform/chromium/test_expectations.txt	2012-04-24 23:55:50 UTC (rev 115138)
@@ -2805,6 +2805,11 @@
 
 BUGWK84067 : css3/filters/custom/custom-filter-property-computed-style.html = TEXT
 
+// Following tests need baselines on Win and Linux
+BUGWK84800 SKIP WIN LINUX : css3/filters/custom/filter-repaint-custom-clipped.html = FAIL
+BUGWK84800 SKIP WIN LINUX : css3/filters/custom/filter-repaint-custom-rotated.html = FAIL
+BUGWK84800 SKIP WIN LINUX : css3/filters/custom/filter-repaint-custom.html = FAIL
+
 // <style scoped> not yet enabled.
 BUGWK49142 SKIP : fast/css/style-scoped = PASS
 // CSS Regions tests for region styling and scoped styles

Added: trunk/LayoutTests/platform/chromium-mac/css3/filters/custom/filter-repaint-custom-clipped-expected.png


(Binary files differ)
Property changes on: trunk/LayoutTests/platform/chromium-mac/css3/filters/custom/filter-repaint-custom-clipped-expected.png ___________________________________________________________________

Added: svn:mime-type

Added: trunk/LayoutTests/platform/chromium-mac/css3/filters/custom/filter-repaint-custom-expected.png


(Binary files differ)
Property changes on: trunk/LayoutTests/platform/chromium-mac/css3/filters/custom/filter-repaint-custom-expected.png ___________________________________________________________________

Added: svn:mime-type

Added: trunk/LayoutTests/platform/chromium-mac/css3/filters/custom/filter-repaint-custom-rotated-expected.png


(Binary files differ)
Property changes on: trunk/LayoutTests/platform/chromium-mac/css3/filters/custom/filter-repaint-custom-rotated-expected.png ___________________________________________________________________

Added: svn:mime-type

Modified: trunk/Source/WebCore/ChangeLog (115137 => 115138)


--- trunk/Source/WebCore/ChangeLog	2012-04-24 23:52:44 UTC (rev 115137)
+++ trunk/Source/WebCore/ChangeLog	2012-04-24 23:55:50 UTC (rev 115138)
@@ -1,3 +1,30 @@
+2012-04-24  Alexandru Chiculita  <ach...@adobe.com>
+
+        CSS Shaders: Repainting the FECustomFilter requires full source image
+        https://bugs.webkit.org/show_bug.cgi?id=76689
+
+        Reviewed by Dean Jackson..
+
+        When a pixel of a filtered layer changes we need to update the whole bounding box of the layer and
+        not just the dirty rectangle. That's because the shader might change the color of any of the pixels inside the box.
+
+        Added tests where a shader is moving and rotating the contents and the actual
+        dirty box of the source image is not the same as the output dirty rectangle.
+
+        Tests: css3/filters/custom/filter-repaint-custom-clipped.html
+               css3/filters/custom/filter-repaint-custom-rotated.html
+               css3/filters/custom/filter-repaint-custom.html
+
+        * rendering/FilterEffectRenderer.cpp:
+        (WebCore::FilterEffectRenderer::FilterEffectRenderer):
+        (WebCore::FilterEffectRenderer::build):
+        (WebCore::FilterEffectRenderer::computeSourceImageRectForDirtyRect):
+        * rendering/FilterEffectRenderer.h:
+        (FilterEffectRenderer):
+        (WebCore::FilterEffectRenderer::hasCustomShaderFilter):
+        * rendering/RenderLayer.cpp:
+        (WebCore::RenderLayer::setFilterBackendNeedsRepaintingInRect):
+
 2012-04-24  Alexis Menard  <alexis.men...@openbossa.org>
 
         Replace occurences of style selector from variables and methods names by style resolver.

Modified: trunk/Source/WebCore/rendering/FilterEffectRenderer.cpp (115137 => 115138)


--- trunk/Source/WebCore/rendering/FilterEffectRenderer.cpp	2012-04-24 23:52:44 UTC (rev 115137)
+++ trunk/Source/WebCore/rendering/FilterEffectRenderer.cpp	2012-04-24 23:55:50 UTC (rev 115138)
@@ -90,6 +90,9 @@
     , m_leftOutset(0)
     , m_graphicsBufferAttached(false)
     , m_hasFilterThatMovesPixels(false)
+#if ENABLE(CSS_SHADERS)
+    , m_hasCustomShaderFilter(false)
+#endif
 {
     setFilterResolution(FloatSize(1, 1));
     m_sourceGraphic = SourceGraphic::create(this);
@@ -110,6 +113,9 @@
     UNUSED_PARAM(document);
 #endif
 
+#if ENABLE(CSS_SHADERS)
+    m_hasCustomShaderFilter = false;
+#endif
     m_hasFilterThatMovesPixels = operations.hasFilterThatMovesPixels();
     if (m_hasFilterThatMovesPixels)
         operations.getOutsets(m_topOutset, m_rightOutset, m_bottomOutset, m_leftOutset);
@@ -268,6 +274,7 @@
                 effect = FECustomFilter::create(this, document->view()->root()->hostWindow(), program, customFilterOperation->parameters(),
                                                 customFilterOperation->meshRows(), customFilterOperation->meshColumns(),
                                                 customFilterOperation->meshBoxType(), customFilterOperation->meshType());
+                m_hasCustomShaderFilter = true;
             }
 #endif
             break;
@@ -337,6 +344,13 @@
 
 LayoutRect FilterEffectRenderer::computeSourceImageRectForDirtyRect(const LayoutRect& filterBoxRect, const LayoutRect& dirtyRect)
 {
+#if ENABLE(CSS_SHADERS)
+    if (hasCustomShaderFilter()) {
+        // When we have at least a custom shader in the chain, we need to compute the whole source image, because the shader can
+        // reference any pixel and we cannot control that.
+        return filterBoxRect;
+    }
+#endif
     // The result of this function is the area in the "filterBoxRect" that needs to be repainted, so that we fully cover the "dirtyRect".
     LayoutRect rectForRepaint = dirtyRect;
     if (hasFilterThatMovesPixels()) {

Modified: trunk/Source/WebCore/rendering/FilterEffectRenderer.h (115137 => 115138)


--- trunk/Source/WebCore/rendering/FilterEffectRenderer.h	2012-04-24 23:52:44 UTC (rev 115137)
+++ trunk/Source/WebCore/rendering/FilterEffectRenderer.h	2012-04-24 23:55:50 UTC (rev 115138)
@@ -110,6 +110,9 @@
     bool hasFilterThatMovesPixels() const { return m_hasFilterThatMovesPixels; }
     LayoutRect computeSourceImageRectForDirtyRect(const LayoutRect& filterBoxRect, const LayoutRect& dirtyRect);
 
+#if ENABLE(CSS_SHADERS)
+    bool hasCustomShaderFilter() const { return m_hasCustomShaderFilter; }
+#endif
 private:
     void setMaxEffectRects(const FloatRect& effectRect)
     {
@@ -141,6 +144,9 @@
     
     bool m_graphicsBufferAttached;
     bool m_hasFilterThatMovesPixels;
+#if ENABLE(CSS_SHADERS)
+    bool m_hasCustomShaderFilter;
+#endif
 };
 
 } // namespace WebCore

Modified: trunk/Source/WebCore/rendering/RenderLayer.cpp (115137 => 115138)


--- trunk/Source/WebCore/rendering/RenderLayer.cpp	2012-04-24 23:52:44 UTC (rev 115137)
+++ trunk/Source/WebCore/rendering/RenderLayer.cpp	2012-04-24 23:55:50 UTC (rev 115138)
@@ -1019,6 +1019,16 @@
     ASSERT(filterInfo);
     filterInfo->expandDirtySourceRect(rectForRepaint);
     
+#if ENABLE(CSS_SHADERS)
+    ASSERT(filterInfo->renderer());
+    if (filterInfo->renderer()->hasCustomShaderFilter()) {
+        // If we have at least one custom shader, we need to update the whole bounding box of the layer, because the
+        // shader can address any ouput pixel.
+        // Note: This is only for output rect, so there's no need to expand the dirty source rect.
+        rectForRepaint.unite(calculateLayerBounds(this, this));
+    }
+#endif
+    
     RenderLayer* parentLayer = enclosingFilterRepaintLayer();
     ASSERT(parentLayer);
     FloatQuad repaintQuad(rectForRepaint);
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to