Bug 601894 - Compare covered rects when computing whether a transform display list item is opaque / uniform. r=roc, a=betaN
authorMarkus Stange <mstange@themasta.com>
Sat, 27 Nov 2010 00:31:08 +0100
changeset 58321 6aad676f008c2647ef32d474aa0a44d4480bdfa4
parent 58320 64188998417c19a5764d89aab9f56d1c70effe07
child 58322 4d4065d46e80674cb32d5a3a2ca35114e64f4997
push id17244
push usermstange@themasta.com
push dateMon, 29 Nov 2010 14:19:11 +0000
treeherdermozilla-central@a5500a756268 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersroc, betaN
bugs601894
milestone2.0b8pre
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 601894 - Compare covered rects when computing whether a transform display list item is opaque / uniform. r=roc, a=betaN
layout/base/nsDisplayList.cpp
layout/reftests/transform/601894-1.html
layout/reftests/transform/601894-2.html
layout/reftests/transform/601894-ref.html
layout/reftests/transform/reftest.list
--- a/layout/base/nsDisplayList.cpp
+++ b/layout/base/nsDisplayList.cpp
@@ -1980,46 +1980,58 @@ void nsDisplayTransform::HitTest(nsDispl
  * by the reference point.
  */
 nsRect nsDisplayTransform::GetBounds(nsDisplayListBuilder *aBuilder)
 {
   return mFrame->GetVisualOverflowRect() + ToReferenceFrame();
 }
 
 /* The transform is opaque iff the transform consists solely of scales and
- * transforms and if the underlying content is opaque.  Thus if the transform
+ * translations and if the underlying content is opaque.  Thus if the transform
  * is of the form
  *
  * |a c e|
  * |b d f|
  * |0 0 1|
  *
  * We need b and c to be zero.
+ *
+ * We also need to check whether the underlying opaque content completely fills
+ * our visible rect. We use UntransformRect which expands to the axis-aligned
+ * bounding rect, but that's OK since if
+ * mStoredList.GetVisibleRect().Contains(untransformedVisible), then it
+ * certainly contains the actual (non-axis-aligned) untransformed rect.
  */
 PRBool nsDisplayTransform::IsOpaque(nsDisplayListBuilder *aBuilder,
                                     PRBool* aForceTransparentSurface)
 {
   if (aForceTransparentSurface) {
     *aForceTransparentSurface = PR_FALSE;
   }
   const nsStyleDisplay* disp = mFrame->GetStyleDisplay();
+  nsRect untransformedVisible =
+    UntransformRect(mVisibleRect, mFrame, ToReferenceFrame());
   return disp->mTransform.GetMainMatrixEntry(1) == 0.0f &&
     disp->mTransform.GetMainMatrixEntry(2) == 0.0f &&
+    mStoredList.GetVisibleRect().Contains(untransformedVisible) &&
     mStoredList.IsOpaque(aBuilder);
 }
 
 /* The transform is uniform if it fills the entire bounding rect and the
  * wrapped list is uniform.  See IsOpaque for discussion of why this
  * works.
  */
 PRBool nsDisplayTransform::IsUniform(nsDisplayListBuilder *aBuilder, nscolor* aColor)
 {
   const nsStyleDisplay* disp = mFrame->GetStyleDisplay();
+  nsRect untransformedVisible =
+    UntransformRect(mVisibleRect, mFrame, ToReferenceFrame());
   return disp->mTransform.GetMainMatrixEntry(1) == 0.0f &&
     disp->mTransform.GetMainMatrixEntry(2) == 0.0f &&
+    mStoredList.GetVisibleRect().Contains(untransformedVisible) &&
     mStoredList.IsUniform(aBuilder, aColor);
 }
 
 /* If UNIFIED_CONTINUATIONS is defined, we can merge two display lists that
  * share the same underlying content.  Otherwise, doing so results in graphical
  * glitches.
  */
 #ifndef UNIFIED_CONTINUATIONS
new file mode 100644
--- /dev/null
+++ b/layout/reftests/transform/601894-1.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html>
+  <body style="background: -moz-linear-gradient(lime, lime) fixed; overflow: hidden;">
+    <div style="position: absolute; left: 21.0138px; top: 507.24px; z-index: 17567; -moz-transform: scale(8);">
+      <div style="height: 128px; left: -64px; position: absolute; top: -64px; visibility: visible; width: 128px;"></div>
+    </div>
+    <div style="position: absolute; left: 640.572px; top: 386.574px; -moz-transform: scale(1); z-index: -157863;">
+      <div style="position: absolute; top: -64px; left: -64px; width: 128px; height: 128px; visibility: visible;"></div>
+    </div>
+    <div style="position: absolute; left: 568.346px; top: 582.669px; -moz-transform: scale(1); z-index: -62592;">
+      <div style="position: absolute; top: -64px; left: -64px; width: 128px; height: 128px; visibility: visible;"></div>
+    </div>
+    <div style="position: absolute; left: 573.27px; top: 168.861px; -moz-transform: scale(1); z-index: -137632;">
+      <div style="position: absolute; top: -64px; left: -64px; width: 128px; height: 128px; visibility: visible;"></div>
+    </div>
+    <div style="position: absolute; left: 519.063px; top: 182.9px; -moz-transform: scale(1); z-index: -50558;">
+      <div style="position: absolute; top: -64px; left: -64px; width: 128px; height: 128px; visibility: visible;"></div>
+    </div>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/transform/601894-2.html
@@ -0,0 +1,8 @@
+<!DOCTYPE html>
+<html>
+  <body style="background: -moz-linear-gradient(lime, lime) fixed;">
+    <div style="position: absolute; left: 0; top: 0; -moz-transform: scale(1)">
+      <div style="position: absolute; width: 200px; height: 200px;"></div>
+    </div>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/transform/601894-ref.html
@@ -0,0 +1,2 @@
+<!DOCTYPE html>
+<body style="background: lime;">
--- a/layout/reftests/transform/reftest.list
+++ b/layout/reftests/transform/reftest.list
@@ -100,8 +100,11 @@ fails-if(d2d) == abspos-1d.html abspos-1
 == scale-1a.html scale-1-ref.html
 == scale-1b.html scale-1-ref.html
 == scale-percent-1.html scale-percent-1-ref.html
 # Some simple checks that it obeys selector operations
 == descendant-1.html descendant-1-ref.html
 == propagate-inherit-boolean.html propagate-inherit-boolean-ref.html
 # Ensure you can't move outside an iframe
 == iframe-1.html iframe-1-ref.html
+# Bugs
+== 601894-1.html 601894-ref.html
+== 601894-2.html 601894-ref.html