Bug 983084 - Correctly handle z-order only changes by removing opacity through a dynamic change; r=dbaron
authorEhsan Akhgari <ehsan@mozilla.com>
Thu, 13 Mar 2014 19:14:35 -0400
changeset 190699 905e547383b8c4fe573fdd12a3eb40d302c6a12e
parent 190698 9539d6f3af4ecc533d99b29f83f9fc1e5e766f06
child 190700 e220d12f5d8d472c72622cf84ca45a26772d0599
push id3503
push userraliiev@mozilla.com
push dateMon, 28 Apr 2014 18:51:11 +0000
treeherdermozilla-beta@c95ac01e332e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdbaron
bugs983084
milestone30.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 983084 - Correctly handle z-order only changes by removing opacity through a dynamic change; r=dbaron
layout/reftests/bugs/983084-1-ref.html
layout/reftests/bugs/983084-1.html
layout/reftests/bugs/983084-2-ref.html
layout/reftests/bugs/983084-2.html
layout/reftests/bugs/983084-3.html
layout/reftests/bugs/reftest.list
layout/style/nsStyleStruct.cpp
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/983084-1-ref.html
@@ -0,0 +1,6 @@
+<html>
+    <body>
+        <div id="one" style="width:50px; height:50px; background-color:blue; position:absolute"></div>
+        <div id="two" style="width:500px; height:500px; background-color:red"></div>
+    </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/983084-1.html
@@ -0,0 +1,17 @@
+<html class="reftest-wait">
+    <head>
+        <script>
+            function showItem() {
+                var el = document.getElementById("two");
+                getComputedStyle(el).opacity; // flush styles
+                el.style.opacity = 1;
+                document.documentElement.removeAttribute("class");
+            }
+            window.addEventListener("MozReftestInvalidate", showItem, false);
+        </script>
+    </head>
+    <body>
+        <div id="one" style="width:50px; height:50px; background-color:blue; position:absolute"></div>
+        <div id="two" style="width:500px; height:500px; background-color:red; opacity:0.99"></div>
+    </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/983084-2-ref.html
@@ -0,0 +1,6 @@
+<html>
+    <body>
+        <div id="one" style="width:50px; height:50px; background-color:blue; position:absolute"></div>
+        <div id="two" style="width:500px; height:500px; background-color:red; opacity:0.99"></div>
+    </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/983084-2.html
@@ -0,0 +1,24 @@
+<html class="reftest-wait">
+    <head>
+        <style>
+          div {
+            transition: opacity 0.1s;
+          }
+        </style>
+        <script>
+            function showItem() {
+                var el = document.getElementById("two");
+                getComputedStyle(el).opacity; // flush styles
+                el.style.opacity = 0.99;
+                document.addEventListener("transitionend", function() {
+                  document.documentElement.removeAttribute("class");
+                }, false);
+            }
+            window.addEventListener("MozReftestInvalidate", showItem, false);
+        </script>
+    </head>
+    <body>
+        <div id="one" style="width:50px; height:50px; background-color:blue; position:absolute"></div>
+        <div id="two" style="width:500px; height:500px; background-color:red; opacity:0.5"></div>
+    </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/983084-3.html
@@ -0,0 +1,24 @@
+<html class="reftest-wait">
+    <head>
+        <style>
+          div {
+            transition: opacity 0.1s;
+          }
+        </style>
+        <script>
+            function showItem() {
+                var el = document.getElementById("two");
+                getComputedStyle(el).opacity; // flush styles
+                el.style.opacity = 1;
+                document.addEventListener("transitionend", function() {
+                  document.documentElement.removeAttribute("class");
+                }, false);
+            }
+            window.addEventListener("MozReftestInvalidate", showItem, false);
+        </script>
+    </head>
+    <body>
+        <div id="one" style="width:50px; height:50px; background-color:blue; position:absolute"></div>
+        <div id="two" style="width:500px; height:500px; background-color:red; opacity:0.5"></div>
+    </body>
+</html>
--- a/layout/reftests/bugs/reftest.list
+++ b/layout/reftests/bugs/reftest.list
@@ -1794,8 +1794,11 @@ fuzzy-if(OSX==10.6,2,30) skip-if(B2G&&br
 == 956513-1.svg 956513-1-ref.svg
 == 944291-1.html 944291-1-ref.html
 == 957770-1.svg 957770-1-ref.svg
 == 960277-1.html 960277-1-ref.html
 pref(layout.css.overflow-clip-box.enabled,true) fuzzy(50,10) == 966992-1.html 966992-1-ref.html
 skip-if(Android) == 966510-1.html 966510-1-ref.html # scrollable elements other than the root probably won't work well on android until bug 776030 is fixed
 skip-if(Android) == 966510-2.html 966510-2-ref.html # same as above
 == 978911-1.svg 978911-1-ref.svg
+== 983084-1.html 983084-1-ref.html
+== 983084-2.html 983084-2-ref.html
+== 983084-3.html 983084-1-ref.html
--- a/layout/style/nsStyleStruct.cpp
+++ b/layout/style/nsStyleStruct.cpp
@@ -2488,17 +2488,25 @@ nsChangeHint nsStyleDisplay::CalcDiffere
       || mAppearance != aOther.mAppearance
       || mOrient != aOther.mOrient
       || mOverflowClipBox != aOther.mOverflowClipBox
       || mClipFlags != aOther.mClipFlags || !mClip.IsEqualInterior(aOther.mClip))
     NS_UpdateHint(hint, NS_CombineHint(nsChangeHint_AllReflowHints,
                                        nsChangeHint_RepaintFrame));
 
   if (mOpacity != aOther.mOpacity) {
-    NS_UpdateHint(hint, nsChangeHint_UpdateOpacityLayer);
+    // If we're going from the optimized >=0.99 opacity value to 1.0 or back, then
+    // repaint the frame because DLBI will not catch the invalidation.  Otherwise,
+    // just update the opacity layer.
+    if ((mOpacity >= 0.99f && mOpacity < 1.0f && aOther.mOpacity == 1.0f) ||
+        (aOther.mOpacity >= 0.99f && aOther.mOpacity < 1.0f && mOpacity == 1.0f)) {
+      NS_UpdateHint(hint, nsChangeHint_RepaintFrame);
+    } else {
+      NS_UpdateHint(hint, nsChangeHint_UpdateOpacityLayer);
+    }
   }
 
   /* If we've added or removed the transform property, we need to reconstruct the frame to add
    * or remove the view object, and also to handle abs-pos and fixed-pos containers.
    */
   if (HasTransformStyle() != aOther.HasTransformStyle()) {
     // We do not need to apply nsChangeHint_UpdateTransformLayer since
     // nsChangeHint_RepaintFrame will forcibly invalidate the frame area and