Bug 1083241 - Call gfx->Paint in PaintFrameWithEffects when there is blending. r=roc, a=lsblakk
authorMax Vujovic <mvujovic@adobe.com>
Fri, 17 Oct 2014 11:37:54 -0700
changeset 225661 1d9623f1fdee9f0d54705f97c43bee98bce0112f
parent 225660 ecf3137f24acc8eec1b2ae73781d0195095101f3
child 225662 28cee61603fada4b58faa767b50d63e487d57e90
push id7144
push userryanvm@gmail.com
push dateThu, 23 Oct 2014 00:06:09 +0000
treeherdermozilla-aurora@1d9623f1fdee [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersroc, lsblakk
bugs1083241
milestone35.0a2
Bug 1083241 - Call gfx->Paint in PaintFrameWithEffects when there is blending. r=roc, a=lsblakk
layout/reftests/css-blending/mix-blend-mode-and-filter-ref.html
layout/reftests/css-blending/mix-blend-mode-and-filter-ref.svg
layout/reftests/css-blending/mix-blend-mode-and-filter.html
layout/reftests/css-blending/mix-blend-mode-and-filter.svg
layout/reftests/css-blending/reftest.list
layout/svg/nsSVGIntegrationUtils.cpp
layout/svg/nsSVGUtils.cpp
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-blending/mix-blend-mode-and-filter-ref.html
@@ -0,0 +1,41 @@
+<!--
+     Any copyright is dedicated to the Public Domain.
+     http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<!DOCTYPE HTML>
+<html>
+<head>
+  <style>
+    .parent {
+      position: relative;
+      width: 100px;
+      height: 100px;
+    }
+
+    .child {
+      filter: blur(3px);
+      background: #0f0;
+      width: 100px;
+      height: 100px;
+    }
+
+    .black-rect {
+      position: absolute;
+      top: 50px;
+      width: 100px;
+      height: 50px;
+      background: #000;
+    }
+  </style>
+</head>
+<body>
+  <!--
+    You should see a blurred green square, with its bottom half mostly
+    covered by a black rectangle.
+  -->
+  <div class="parent">
+    <div class="child"></div>
+    <div class="black-rect"></div>
+  </div>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-blending/mix-blend-mode-and-filter-ref.svg
@@ -0,0 +1,14 @@
+<!--
+     Any copyright is dedicated to the Public Domain.
+     http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<svg xmlns="http://www.w3.org/2000/svg">
+  <defs>
+    <filter id="blur">
+      <feGaussianBlur stdDeviation="3"/>
+    </filter>
+  </defs>
+  <rect x="0" y="0" width="100" height="50" fill="#fff"/>
+  <rect x="0" y="0" width="100" height="100" fill="#0f0" filter="url(#blur)"/>
+  <rect x="0" y="50" width="100" height="50" fill="#000"/>
+</svg>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-blending/mix-blend-mode-and-filter.html
@@ -0,0 +1,37 @@
+<!--
+     Any copyright is dedicated to the Public Domain.
+     http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<!DOCTYPE HTML>
+<html>
+<head>
+  <style>
+    .parent {
+      /*
+        With the darken blend mode, green will overwrite white parts of this
+        background, while black parts of this background will show through.
+      */
+      background: linear-gradient(#fff 0%, #fff 50%, #000 50%, #000 100%);
+      width: 100px;
+      height: 100px;
+    }
+
+    .child {
+      filter: blur(3px);
+      mix-blend-mode: darken;
+      background: #0f0;
+      width: 100px;
+      height: 100px;
+    }
+  </style>
+</head>
+<body>
+  <!--
+    You should see a blurred green square, with its bottom half mostly
+    covered by a black rectangle.
+  -->
+  <div class="parent">
+    <div class="child"></div>
+  </div>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-blending/mix-blend-mode-and-filter.svg
@@ -0,0 +1,21 @@
+<!--
+     Any copyright is dedicated to the Public Domain.
+     http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<svg xmlns="http://www.w3.org/2000/svg">
+  <defs>
+    <filter id="blur">
+      <feGaussianBlur stdDeviation="3"/>
+    </filter>
+  </defs>
+  <!-- Background consists of a white rect and a black rect. -->
+  <rect x="0" y="0" width="100" height="50" fill="#fff"/>
+  <rect x="0" y="50" width="100" height="50" fill="#000"/>
+  <!--
+    Foreground consists of a blurred green square, blended with the background
+    using the darken blend mode. Green should overwrite the white rect, while
+    the black rect should show through.
+  -->
+  <rect x="0" y="0" width="100" height="100" fill="#0f0" filter="url(#blur)"
+        style="mix-blend-mode: darken;"/>
+</svg>
--- a/layout/reftests/css-blending/reftest.list
+++ b/layout/reftests/css-blending/reftest.list
@@ -35,16 +35,19 @@ fuzzy-if(d2d,1,1600) fuzzy-if(azureSkia|
 fuzzy-if(d2d||azureSkia||gtk2Widget,1,1600) pref(layout.css.background-blend-mode.enabled,true) == background-blending-screen.html background-blending-screen-ref.svg
 fuzzy-if(azureQuartz,1,1600) fuzzy-if(d2d||azureSkia||gtk2Widget,10,4800) pref(layout.css.background-blend-mode.enabled,true) == background-blending-soft-light.html background-blending-soft-light-ref.svg
 
 fuzzy-if(azureQuartz,2,40000) fuzzy-if(azureSkia||d2d||gtk2Widget,1,40000) pref(layout.css.background-blend-mode.enabled,true) == background-blending-image-color-959674.html background-blending-image-color-959674-ref.html
 
 #fuzzy due to inconsistencies in rounded rect cliping between parent and child; may be related to antialiasing. Between platforms, the max difference is the same, and the number of different pixels is either 36 or 37. (Win, Mac and Lin)
 fuzzy(64,37) pref(layout.css.mix-blend-mode.enabled,true) == mix-blend-mode-952051.html mix-blend-mode-952051-ref.html
 
+pref(layout.css.mix-blend-mode.enabled,true) pref(layout.css.filters.enabled,true) == mix-blend-mode-and-filter.html mix-blend-mode-and-filter-ref.html
+pref(layout.css.mix-blend-mode.enabled,true) pref(layout.css.filters.enabled,true) == mix-blend-mode-and-filter.svg mix-blend-mode-and-filter-ref.svg
+
 pref(layout.css.mix-blend-mode.enabled,true) == mix-blend-mode-child-of-blended-has-opacity.html mix-blend-mode-child-of-blended-has-opacity-ref.html
 
 pref(layout.css.mix-blend-mode.enabled,true) == mix-blend-mode-nested-976533.html mix-blend-mode-nested-976533-ref.html
 
 # Test plan 5.3.1 Blending between the background layers and the background color for an element with background-blend-mode
 # Test 9
 pref(layout.css.background-blend-mode.enabled,true) == background-blending-image-color-svg-as-data-uri.html background-blending-image-color-ref.html
 # Test 10
--- a/layout/svg/nsSVGIntegrationUtils.cpp
+++ b/layout/svg/nsSVGIntegrationUtils.cpp
@@ -580,17 +580,18 @@ nsSVGIntegrationUtils::PaintFramesWithEf
       } else {
         gfx->Mask(clipMaskSurface, clippedMaskTransform);
       }
     }
   }
 
   if (maskSurface) {
     gfx->Mask(maskSurface, maskTransform);
-  } else if (opacity != 1.0f) {
+  } else if (opacity != 1.0f ||
+             aFrame->StyleDisplay()->mMixBlendMode != NS_STYLE_BLEND_NORMAL) {
     gfx->Paint(opacity);
   }
 
   gfx->Restore();
 }
 
 gfxMatrix
 nsSVGIntegrationUtils::GetCSSPxToDevPxMatrix(nsIFrame* aNonSVGFrame)
--- a/layout/svg/nsSVGUtils.cpp
+++ b/layout/svg/nsSVGUtils.cpp
@@ -661,17 +661,18 @@ nsSVGUtils::PaintFrameWithEffects(nsIFra
       } else {
         gfx->Mask(clipMaskSurface, clippedMaskTransform);
       }
     }
   }
 
   if (maskSurface) {
     gfx->Mask(maskSurface, maskTransform);
-  } else if (opacity != 1.0f) {
+  } else if (opacity != 1.0f ||
+             aFrame->StyleDisplay()->mMixBlendMode != NS_STYLE_BLEND_NORMAL) {
     gfx->Paint(opacity);
   }
 
   gfx->Restore();
 }
 
 bool
 nsSVGUtils::HitTestClip(nsIFrame *aFrame, const gfxPoint &aPoint)