Bug 1596610 - Set WillChangeBits::TRANSFORM for offset-path and add tests for it. r=hiro
authorBoris Chiou <boris.chiou@gmail.com>
Sat, 16 Nov 2019 01:52:32 +0000
changeset 502315 7dc52ca0f1de82924ef9ac2b8d04e8852ed08ab1
parent 502314 4fe43f4966b277eb66d5dfcf534329c92d166afb
child 502316 1603f5abc56e6c2483e46ce577f6450e4c58733b
push id114172
push userdluca@mozilla.com
push dateTue, 19 Nov 2019 11:31:10 +0000
treeherdermozilla-inbound@b5c5ba07d3db [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewershiro
bugs1596610
milestone72.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 1596610 - Set WillChangeBits::TRANSFORM for offset-path and add tests for it. r=hiro Differential Revision: https://phabricator.services.mozilla.com/D53109
layout/base/tests/chrome/chrome.ini
layout/base/tests/chrome/test_will_change.html
layout/reftests/w3c-css/submitted/will-change/reftest.list
layout/reftests/w3c-css/submitted/will-change/will-change-fixpos-cb-offset-path-1.html
layout/reftests/w3c-css/submitted/will-change/will-change-stacking-context-offset-path-1.html
servo/components/style/values/specified/box.rs
testing/web-platform/meta/css/vendor-imports/mozilla/mozilla-central-reftests/will-change/__dir__.ini
--- a/layout/base/tests/chrome/chrome.ini
+++ b/layout/base/tests/chrome/chrome.ini
@@ -1,11 +1,12 @@
 [DEFAULT]
 prefs =
   layout.css.individual-transform.enabled=true
+  layout.css.motion-path.enabled=true
   plugin.load_flash_only=false
 skip-if = os == 'android'
 support-files =
   animated.gif
   blue-32x32.png
   bug551434_childframe.html
   chrome_content_integration_window.xhtml
   default_background_window.xhtml
--- a/layout/base/tests/chrome/test_will_change.html
+++ b/layout/base/tests/chrome/test_will_change.html
@@ -1,120 +1,140 @@
 <!DOCTYPE HTML>
 <html>
 <head>
   <title>Tests for MozAfterPaint</title>
   <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
   <script src="chrome://mochikit/content/tests/SimpleTest/paint_listener.js"></script>
   <style>
-    #checkOpacityRepaint {
-      will-change: opacity;
-    }
-    #checkTransformRepaint {
-      will-change: transform;
-    }
-    #checkTranslateRepaint {
-      will-change: translate;
-    }
     div {
       width: 100px;
       height: 100px;
       background: radial-gradient(ellipse at center, #87e0fd 0%,#53cbf1 40%,#05abe0 100%);
     }
   </style>
 </head>
 <body>
-  <div id="checkRepaint">
-    Check repaint without will-change
-  </div>
-  <div id="checkOpacityRepaint">
-    Check repaint with will-change
-  </div>
-  <div id="checkTransformRepaint">
-    Check repaint with will-change
-  </div>
-  <div id="checkTranslateRepaint">
-    Check repaint with will-change
-  </div>
 </body>
 <script>
 
 var utils = window.windowUtils;
 
 function waitForPaints() {
   return new Promise(function(resolve, reject) {
     waitForAllPaintsFlushed(resolve);
   });
 }
 
 add_task(async () => {
-  var element = document.getElementById("checkRepaint");
+  var element = document.createElement("div");
+  document.body.appendChild(element);
 
   await waitForPaints();
 
   utils.checkAndClearPaintedState(element);
   element.style.opacity = "0.5";
 
   await waitForPaints();
 
   var painted = utils.checkAndClearPaintedState(element);
   // *** We check that this repaints because the test is relying
   //     on this property. If this is broken then this test wont
   //     be reliable check for will-change.
   is(painted, true, "element should have been painted");
+
+  element.remove();
 });
 
 add_task(async () => {
-  var element = document.getElementById("checkOpacityRepaint");
+  var element = document.createElement("div");
+  document.body.appendChild(element);
+
+  element.style.willChange = "opacity";
 
   await waitForPaints();
 
   utils.checkAndClearPaintedState(element);
   element.style.opacity = "0.5";
 
   await waitForPaints();
 
   var painted = utils.checkAndClearPaintedState(element);
   // BasicLayers' heuristics are so that even with will-change:opacity,
   // we can still have repaints.
   if (utils.layerManagerType != "Basic") {
-    is(painted, false, "will-change checkOpacityRepaint element should not have been painted");
+    is(painted, false, "will-change:opacity element should not have been painted");
   }
+
+  element.remove();
 });
 
 add_task(async () => {
-  var element = document.getElementById("checkTransformRepaint");
+  var element = document.createElement("div");
+  document.body.appendChild(element);
+
+  element.style.willChange = "transform";
 
   await waitForPaints();
 
   utils.checkAndClearPaintedState(element);
   element.style.transform = "translateY(-5px)";
 
   await waitForPaints();
 
   var painted = utils.checkAndClearPaintedState(element);
   // BasicLayers' heuristics are so that even with will-change:transform,
   // we can still have repaints.
   if (utils.layerManagerType != "Basic") {
-    is(painted, false, "will-change checkTransformRepaint element should not have been painted");
+    is(painted, false, "will-change:transform element should not have been painted");
   }
+
+  element.remove();
 });
 
 add_task(async () => {
-  var element = document.getElementById("checkTranslateRepaint");
+  var element = document.createElement("div");
+  document.body.appendChild(element);
+
+  element.style.willChange = "translate";
 
   await waitForPaints();
 
   utils.checkAndClearPaintedState(element);
   element.style.translate = "5px";
 
   await waitForPaints();
 
   var painted = utils.checkAndClearPaintedState(element);
   // BasicLayers' heuristics are so that even with will-change:translate,
   // we can still have repaints.
   if (utils.layerManagerType != "Basic") {
-    is(painted, false, "will-change checkTranslateRepaint element should not have been painted");
+    is(painted, false, "will-change:translate element should not have been painted");
   }
+
+  element.remove();
+});
+
+add_task(async () => {
+  var element = document.createElement("div");
+  document.body.appendChild(element);
+
+  element.style.willChange = "offset-path";
+
+  await waitForPaints();
+
+  utils.checkAndClearPaintedState(element);
+  element.style.offsetPath = "path('M55 50 h1')";
+
+  await waitForPaints();
+
+  var painted = utils.checkAndClearPaintedState(element);
+  // BasicLayers' heuristics are so that even with will-change:offset-path,
+  // we can still have repaints.
+  if (utils.layerManagerType != "Basic") {
+    is(painted, false, "will-change:offset-path element should not have been painted");
+  }
+
+  element.remove();
 });
 
 </script>
 </html>
--- a/layout/reftests/w3c-css/submitted/will-change/reftest.list
+++ b/layout/reftests/w3c-css/submitted/will-change/reftest.list
@@ -4,18 +4,20 @@
 == will-change-stacking-context-isolation-1.html green-square-100-by-100-ref.html
 == will-change-stacking-context-mask-1.html green-square-100-by-100-ref.html
 == will-change-stacking-context-mix-blend-mode-1.html green-square-100-by-100-ref.html
 == will-change-stacking-context-opacity-1.html green-square-100-by-100-ref.html
 == will-change-stacking-context-perspective-1.html green-square-100-by-100-ref.html
 == will-change-stacking-context-position-1.html green-square-100-by-100-ref.html
 == will-change-stacking-context-transform-1.html green-square-100-by-100-ref.html
 test-pref(layout.css.individual-transform.enabled,true) == will-change-stacking-context-translate-1.html green-square-100-by-100-ref.html
+test-pref(layout.css.motion-path.enabled,true) == will-change-stacking-context-offset-path-1.html green-square-100-by-100-ref.html
 == will-change-stacking-context-transform-style-1.html green-square-100-by-100-ref.html
 == will-change-stacking-context-z-index-1.html green-square-100-by-100-ref.html
 test-pref(layout.css.contain.enabled,true) == will-change-fixpos-cb-contain-1.html green-square-100-by-100-offset-ref.html
 == will-change-fixpos-cb-filter-1.html green-square-100-by-100-offset-ref.html
 == will-change-fixpos-cb-height-1.html green-square-100-by-100-offset-ref.html
 == will-change-fixpos-cb-perspective-1.html green-square-100-by-100-offset-ref.html
 == will-change-fixpos-cb-position-1.html green-square-100-by-100-offset-ref.html
 == will-change-fixpos-cb-transform-1.html green-square-100-by-100-offset-ref.html
 test-pref(layout.css.individual-transform.enabled,true) == will-change-fixpos-cb-translate-1.html green-square-100-by-100-offset-ref.html
+test-pref(layout.css.motion-path.enabled,true) == will-change-fixpos-cb-offset-path-1.html green-square-100-by-100-offset-ref.html
 == will-change-fixpos-cb-transform-style-1.html green-square-100-by-100-offset-ref.html
new file mode 100644
--- /dev/null
+++ b/layout/reftests/w3c-css/submitted/will-change/will-change-fixpos-cb-offset-path-1.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS will-change: 'will-change: offset-path' creates a containing block for fixed positioned elements</title>
+<link rel="author" title="Mozilla" href="http://www.mozilla.org/">
+<link rel="help" href="https://drafts.csswg.org/css-will-change-1/#will-change">
+<link rel="help" href="https://drafts.fxtf.org/motion-1/#offset-path-property">
+<link rel="match" href="green-square-100-by-100-offset-ref.html">
+<meta name="assert" content="If any non-initial value of a property would cause the element to generate a containing block for fixed-position elements, specifying that property in will-change must cause the element to generate a containing block for fixed-position elements.">
+<style>
+html, body { margin: 0; padding: 0; }
+div { width: 100px; height: 100px }
+#wc { will-change: offset-path; margin: 100px 0 0 100px; background: red }
+.child { top: 0; left: 0; width: 50px; background: green }
+#fixpos { position: fixed }
+#abspos { position: absolute; left: 50px }
+</style>
+<body>
+  <div id="wc">
+    <div class="child" id="fixpos">
+    </div>
+    <div class="child" id="abspos">
+    </div>
+  </div>
+</body>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/w3c-css/submitted/will-change/will-change-stacking-context-offset-path-1.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS will-change: 'will-change: offset-path' creates a stacking context</title>
+<link rel="author" title="Mozilla" href="http://www.mozilla.org/">
+<link rel="help" href="https://drafts.csswg.org/css-will-change-1/#will-change">
+<link rel="help" href="https://drafts.fxtf.org/motion-1/#offset-path-property">
+<link rel="match" href="green-square-100-by-100-ref.html">
+<meta name="assert" content="If any non-initial value of a property would create a stacking context on the element, specifying that property in will-change must create a stacking context on the element.">
+<style>
+html, body { margin: 0; padding: 0; }
+div { width: 100px; height: 100px }
+#wc { will-change: offset-path; background: red }
+#child { position: absolute; top: 0; left: 0; z-index: -1; background: green }
+</style>
+<body>
+  <div id="wc">
+    <div id="child">
+    </div>
+  </div>
+</body>
--- a/servo/components/style/values/specified/box.rs
+++ b/servo/components/style/values/specified/box.rs
@@ -1146,17 +1146,19 @@ bitflags! {
     }
 }
 
 fn change_bits_for_longhand(longhand: LonghandId) -> WillChangeBits {
     let mut flags = match longhand {
         LonghandId::Opacity => WillChangeBits::OPACITY,
         LonghandId::Transform => WillChangeBits::TRANSFORM,
         #[cfg(feature = "gecko")]
-        LonghandId::Translate | LonghandId::Rotate | LonghandId::Scale => WillChangeBits::TRANSFORM,
+        LonghandId::Translate | LonghandId::Rotate | LonghandId::Scale | LonghandId::OffsetPath => {
+            WillChangeBits::TRANSFORM
+        }
         _ => WillChangeBits::empty(),
     };
 
     let property_flags = longhand.flags();
     if property_flags.contains(PropertyFlags::CREATES_STACKING_CONTEXT) {
         flags |= WillChangeBits::STACKING_CONTEXT;
     }
     if property_flags.contains(PropertyFlags::FIXPOS_CB) {
--- a/testing/web-platform/meta/css/vendor-imports/mozilla/mozilla-central-reftests/will-change/__dir__.ini
+++ b/testing/web-platform/meta/css/vendor-imports/mozilla/mozilla-central-reftests/will-change/__dir__.ini
@@ -1,1 +1,1 @@
-prefs: [layout.css.individual-transform.enabled:true]
+prefs: [layout.css.individual-transform.enabled:true, layout.css.motion-path.enabled:true]