Bug 1541920. Handle blend mode activeness properly. r=mstange
authorJeff Muizelaar <jrmuizel@gmail.com>
Mon, 08 Apr 2019 22:37:26 +0000
changeset 468438 57538e81d06b0cb09b086b15c88c826d27124b34
parent 468437 ed722cf1b2d96bd3b511b04993cd52d4d528d679
child 468439 707da9fd9d959cd881df8f4899d88b16a2d8635b
push id35837
push userrmaries@mozilla.com
push dateTue, 09 Apr 2019 03:43:40 +0000
treeherdermozilla-central@9eb55c9bf557 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmstange
bugs1541920
milestone68.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1541920. Handle blend mode activeness properly. r=mstange Differential Revision: https://phabricator.services.mozilla.com/D26364
gfx/layers/wr/WebRenderCommandBuilder.cpp
layout/reftests/css-blending/reftest.list
layout/reftests/svg/active-transform-blend-mode-ref.html
layout/reftests/svg/active-transform-blend-mode.html
layout/reftests/svg/reftest.list
--- a/gfx/layers/wr/WebRenderCommandBuilder.cpp
+++ b/gfx/layers/wr/WebRenderCommandBuilder.cpp
@@ -1078,37 +1078,39 @@ class WebRenderGroupData : public WebRen
   virtual UserDataType GetType() override { return UserDataType::eGroup; }
   static UserDataType Type() { return UserDataType::eGroup; }
 
   DIGroup mSubGroup;
   DIGroup mFollowingGroup;
 };
 
 static bool IsItemProbablyActive(nsDisplayItem* aItem,
-                                 nsDisplayListBuilder* aDisplayListBuilder);
+                                 nsDisplayListBuilder* aDisplayListBuilder,
+                                 bool aParentActive = true);
 
 static bool HasActiveChildren(const nsDisplayList& aList,
                               nsDisplayListBuilder* aDisplayListBuilder) {
   for (nsDisplayItem* i = aList.GetBottom(); i; i = i->GetAbove()) {
-    if (IsItemProbablyActive(i, aDisplayListBuilder)) {
+    if (IsItemProbablyActive(i, aDisplayListBuilder, false)) {
       return true;
     }
   }
   return false;
 }
 
 // This function decides whether we want to treat this item as "active", which
 // means that it's a container item which we will turn into a WebRender
 // StackingContext, or whether we treat it as "inactive" and include it inside
 // the parent blob image.
 //
 // We can't easily use GetLayerState because it wants a bunch of layers related
 // information.
 static bool IsItemProbablyActive(nsDisplayItem* aItem,
-                                 nsDisplayListBuilder* aDisplayListBuilder) {
+                                 nsDisplayListBuilder* aDisplayListBuilder,
+                                 bool aParentActive) {
   switch (aItem->GetType()) {
     case DisplayItemType::TYPE_TRANSFORM: {
       nsDisplayTransform* transformItem =
           static_cast<nsDisplayTransform*>(aItem);
       const Matrix4x4Flagged& t = transformItem->GetTransform();
       Matrix t2d;
       bool is2D = t.Is2D(&t2d);
       GP("active: %d\n", transformItem->MayBeAnimated(aDisplayListBuilder));
@@ -1123,16 +1125,23 @@ static bool IsItemProbablyActive(nsDispl
                                                   opacityItem->Frame(), false);
       GP("active: %d\n", active);
       return active || HasActiveChildren(*opacityItem->GetChildren(),
                                          aDisplayListBuilder);
     }
     case DisplayItemType::TYPE_FOREIGN_OBJECT: {
       return true;
     }
+    case DisplayItemType::TYPE_BLEND_MODE: {
+      /* BLEND_MODE needs to be active if it might have a previous sibling
+       * that is active. We use the activeness of the parent as a rough
+       * proxy for this situation. */
+      return aParentActive || HasActiveChildren(*aItem->GetChildren(),
+                                                aDisplayListBuilder);
+    }
     case DisplayItemType::TYPE_WRAP_LIST:
     case DisplayItemType::TYPE_PERSPECTIVE: {
       if (aItem->GetChildren()) {
         return HasActiveChildren(*aItem->GetChildren(), aDisplayListBuilder);
       }
       return false;
     }
     case DisplayItemType::TYPE_FILTER: {
--- a/layout/reftests/css-blending/reftest.list
+++ b/layout/reftests/css-blending/reftest.list
@@ -36,17 +36,17 @@ fuzzy-if(d2d||azureSkia||gtkWidget,0-1,0
 fuzzy-if(d2d||azureSkia||gtkWidget,0-10,0-4800) == background-blending-soft-light.html background-blending-soft-light-ref.svg
 
 fuzzy-if(azureSkia||d2d||gtkWidget,0-1,0-40000) == 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(0-65,0-53) == mix-blend-mode-952051.html mix-blend-mode-952051-ref.html
 
 fuzzy-if(d3d11,0-49,0-200) == mix-blend-mode-and-filter.html mix-blend-mode-and-filter-ref.html
-fuzzy-if(webrender,9-9,2531-2716) fuzzy-if(d3d11,0-1,0-5) == mix-blend-mode-and-filter.svg mix-blend-mode-and-filter-ref.svg
+fuzzy-if(d3d11,0-1,0-5) == mix-blend-mode-and-filter.svg mix-blend-mode-and-filter-ref.svg
 
 fuzzy(0-2,0-14400) == mix-blend-mode-child-of-blended-has-opacity.html mix-blend-mode-child-of-blended-has-opacity-ref.html
 
 == mix-blend-mode-nested-976533.html mix-blend-mode-nested-976533-ref.html
 == mix-blend-mode-culling-1207041.html mix-blend-mode-culling-1207041-ref.html
 == mix-blend-mode-dest-alpha-1135271.html mix-blend-mode-dest-alpha-1135271-ref.html
 == clipped-mixblendmode-containing-unclipped-stuff.html clipped-mixblendmode-containing-unclipped-stuff-ref.html
 fuzzy(0-1,0-6800) == clipped-opacity-containing-unclipped-mixblendmode.html clipped-opacity-containing-unclipped-mixblendmode-ref.html
new file mode 100644
--- /dev/null
+++ b/layout/reftests/svg/active-transform-blend-mode-ref.html
@@ -0,0 +1,8 @@
+<svg width=1000 height=1000>
+    <g style="transform: translateY(-2px) translateX(0px) translateZ(0px);">
+        <rect fill="#0000ff" height="93" width="32" x="100" y="163"></rect>
+    </g>
+    <g style="mix-blend-mode: multiply;">
+        <rect fill="#ff0000" height="93" width="32" x="100" y="161"></rect>
+    </g>
+</svg>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/svg/active-transform-blend-mode.html
@@ -0,0 +1,8 @@
+<svg width=1000 height=1000>
+    <g style="transform: translateY(-2px) translateX(0px) translateZ(0px); will-change: transform;">
+        <rect fill="#0000ff" height="93" width="32" x="100" y="163"></rect>
+    </g>
+    <g style="mix-blend-mode: multiply;">
+        <rect fill="#ff0000" height="93" width="32" x="100" y="161"></rect>
+    </g>
+</svg>
--- a/layout/reftests/svg/reftest.list
+++ b/layout/reftests/svg/reftest.list
@@ -48,16 +48,17 @@ skip-if(Android) == blend-lighten.svg bl
 #skip-if(Android) == blend-multiply-alpha.svg blend-multiply-alpha-ref.svg
 fuzzy-if(skiaContent,0-1,0-1600) skip-if(Android) == blend-multiply.svg blend-multiply-ref.svg
 == blend-normal.svg blend-normal-ref.svg
 #skip-if(Android) == blend-overlay.svg blend-overlay-ref.svg
 #skip-if(Android)  == blend-saturation.svg blend-saturation-ref.svg
 #skip-if(Android) == blend-screen.svg blend-screen-ref.svg
 #skip-if(Android) == blend-soft-light.svg blend-soft-light-ref.svg
 skip == blend-difference-stacking.html blend-difference-stacking-ref.html # bug 1458353
+== active-transform-blend-mode.html active-transform-blend-mode-ref.html
 
 fuzzy(0-11,0-7155) == blur-inside-clipPath.svg blur-inside-clipPath-ref.svg
 
 == border-radius-01.html pass.svg
 
 == clip-01.svg pass.svg
 == clip-02a.svg clip-02-ref.svg
 == clip-02b.svg clip-02-ref.svg