[Safari] Crash with opacity + drop shadow filter + child element extending beyond...
authorsimon.fraser@apple.com <simon.fraser@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 21 Feb 2013 23:29:17 +0000 (23:29 +0000)
committersimon.fraser@apple.com <simon.fraser@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 21 Feb 2013 23:29:17 +0000 (23:29 +0000)
https://bugs.webkit.org/show_bug.cgi?id=107467

Source/WebCore:

Reviewed by Dean Jackson.

The filter code plays games with the current GraphicsContext, replacing the current
context with one which will get filtered.

This doesn't play nicely with the RenderLayer code which lazily starts transparency
layers. If we don't start a transparency layer until painting a child of the filtered
layer, then the transparency layer is started using the wrong context.

Fix by eagerly starting transparency layers if we have both a filter and opacity.

Test: css3/filters/filter-with-opacity-and-children.html

* rendering/RenderLayer.cpp:
(WebCore::RenderLayer::paintLayerContents):

LayoutTests:

Reviewed by Dean Jackson.

Testcase with filtered element with opacity, and layer child.

* css3/filters/filter-with-opacity-and-children-expected.txt: Added.
* css3/filters/filter-with-opacity-and-children.html: Added.

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

LayoutTests/ChangeLog
LayoutTests/css3/filters/filter-with-opacity-and-children-expected.txt [new file with mode: 0644]
LayoutTests/css3/filters/filter-with-opacity-and-children.html [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/rendering/RenderLayer.cpp

index 288df97..b1da66c 100644 (file)
@@ -1,3 +1,15 @@
+2013-02-21  Simon Fraser  <simon.fraser@apple.com>
+
+        [Safari] Crash with opacity + drop shadow filter + child element extending beyond filter outsets
+        https://bugs.webkit.org/show_bug.cgi?id=107467
+
+        Reviewed by Dean Jackson.
+        
+        Testcase with filtered element with opacity, and layer child.
+
+        * css3/filters/filter-with-opacity-and-children-expected.txt: Added.
+        * css3/filters/filter-with-opacity-and-children.html: Added.
+
 2013-02-21  Philip Rogers  <pdr@google.com>
 
         Rebaseline 4 SVG tests after an aspect ratio change in r143389
diff --git a/LayoutTests/css3/filters/filter-with-opacity-and-children-expected.txt b/LayoutTests/css3/filters/filter-with-opacity-and-children-expected.txt
new file mode 100644 (file)
index 0000000..31fcc57
--- /dev/null
@@ -0,0 +1,3 @@
+This test should not assert or crash.
+
+
diff --git a/LayoutTests/css3/filters/filter-with-opacity-and-children.html b/LayoutTests/css3/filters/filter-with-opacity-and-children.html
new file mode 100644 (file)
index 0000000..5073971
--- /dev/null
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <style>
+    .parent {
+        position: relative;
+        background-color: black;
+        width: 100px;
+        height: 100px;
+        margin: 100px;
+        opacity: 0.5;
+        -webkit-filter: drop-shadow(50px 50px 10px #0f0);
+    }
+    .child {
+        position: absolute;
+        top: 113px;
+        left: 113px;
+        width: 50px;
+        height: 50px;
+        background-color: red;
+    }
+    </style>
+    <script>
+        if (window.testRunner)
+            testRunner.dumpAsText();
+    </script>
+</head>
+<body>
+    <p>This test should not assert or crash.</p>
+    <div class="parent">
+        <div class="child"></div>
+    </div>
+    <div class="parent">
+        <div class="child"></div>
+    </div>
+</body>
index ebec5e2..7eec32f 100644 (file)
@@ -1,3 +1,24 @@
+2013-02-21  Simon Fraser  <simon.fraser@apple.com>
+
+        [Safari] Crash with opacity + drop shadow filter + child element extending beyond filter outsets
+        https://bugs.webkit.org/show_bug.cgi?id=107467
+
+        Reviewed by Dean Jackson.
+        
+        The filter code plays games with the current GraphicsContext, replacing the current
+        context with one which will get filtered.
+        
+        This doesn't play nicely with the RenderLayer code which lazily starts transparency
+        layers. If we don't start a transparency layer until painting a child of the filtered
+        layer, then the transparency layer is started using the wrong context.
+        
+        Fix by eagerly starting transparency layers if we have both a filter and opacity.
+
+        Test: css3/filters/filter-with-opacity-and-children.html
+
+        * rendering/RenderLayer.cpp:
+        (WebCore::RenderLayer::paintLayerContents):
+
 2013-02-21  Tony Chang  <tony@chromium.org>
 
         Autogenerate Settings that call setNeedsRecalcStyleInAllFrames when set
index c3ac2ba..47e2cf2 100644 (file)
@@ -3724,7 +3724,14 @@ void RenderLayer::paintLayerContents(GraphicsContext* context, const LayerPainti
     // We want to paint our layer, but only if we intersect the damage rect.
     if (this != localPaintingInfo.rootLayer || !(localPaintFlags & PaintLayerPaintingOverflowContents))
         shouldPaintContent &= intersectsDamageRect(layerBounds, damageRect.rect(), localPaintingInfo.rootLayer, &offsetFromRoot);
-    
+
+#if ENABLE(CSS_FILTERS)
+    if (filterPainter.hasStartedFilterEffect() && haveTransparency) {
+        // If we have a filter and transparency, we have to eagerly start a transparency layer here, rather than risk a child layer lazily starts one with the wrong context.
+        beginTransparencyLayers(transparencyLayerContext, localPaintingInfo.rootLayer, paintingInfo.paintDirtyRect, localPaintingInfo.paintBehavior);
+    }
+#endif
+
     if (localPaintFlags & PaintLayerPaintingCompositingBackgroundPhase) {
         if (shouldPaintContent && !selectionOnly) {
             // Begin transparency layers lazily now that we know we have to paint something.