Bug 1269184 - Make sure we create an nsDisplayWrapList around nsDisplayPerspective items so that the z-index of the perspective frame gets taken into account. r=mstange a=ritu
authorMatt Woodrow <mwoodrow@mozilla.com>
Wed, 04 May 2016 12:56:50 +1200
changeset 332814 7d65f322abdbd49af0b4b12267de5123b672b4ff
parent 332813 7772a4493512048d88004e020e1a13eda7a6d857
child 332815 ba62a7d1c20dbf3d06ead5912b0d0f689bb79000
push id6048
push userkmoir@mozilla.com
push dateMon, 06 Jun 2016 19:02:08 +0000
treeherdermozilla-beta@46d72a56c57d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmstange, ritu
bugs1269184
milestone48.0a2
Bug 1269184 - Make sure we create an nsDisplayWrapList around nsDisplayPerspective items so that the z-index of the perspective frame gets taken into account. r=mstange a=ritu
layout/generic/nsFrame.cpp
layout/reftests/transform-3d/perspective-zindex-2.html
layout/reftests/transform-3d/reftest.list
--- a/layout/generic/nsFrame.cpp
+++ b/layout/generic/nsFrame.cpp
@@ -2568,18 +2568,31 @@ nsIFrame::BuildDisplayListForStackingCon
   aList->AppendToTop(&resultList);
 }
 
 static nsDisplayItem*
 WrapInWrapList(nsDisplayListBuilder* aBuilder,
                nsIFrame* aFrame, nsDisplayList* aList)
 {
   nsDisplayItem* item = aList->GetBottom();
-  if (!item || item->GetAbove() ||
-      (item->Frame() != aFrame && item->GetType() != nsDisplayItem::TYPE_PERSPECTIVE)) {
+  if (!item) {
+    return nullptr;
+  }
+
+  // For perspective items we want to treat the 'frame' as being the transform
+  // frame that created it. This stops the transform frame from wrapping another
+  // nsDisplayWrapList around it (with mismatching reference frames), but still
+  // makes the perspective frame create one (so we have an atomic entry for z-index
+  // sorting).
+  nsIFrame *itemFrame = item->Frame();
+  if (item->GetType() == nsDisplayItem::TYPE_PERSPECTIVE) {
+    itemFrame = static_cast<nsDisplayPerspective*>(item)->TransformFrame();
+  }
+
+  if (item->GetAbove() || itemFrame != aFrame) {
     return new (aBuilder) nsDisplayWrapList(aBuilder, aFrame, aList);
   }
   aList->RemoveBottom();
   return item;
 }
 
 void
 nsIFrame::BuildDisplayListForChild(nsDisplayListBuilder*   aBuilder,
new file mode 100644
--- /dev/null
+++ b/layout/reftests/transform-3d/perspective-zindex-2.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<html lang="en">
+<meta charset="utf-8">
+<title>z-index should work correctly for elements with perspective</title>
+
+<style>
+
+#perspective {
+  z-index: 2;
+  perspective: 300px;
+  perspective-origin: top left;
+}
+
+#front {
+  width: 100px;
+  height: 100px;
+  background-color: #00FF00;
+  transform: translateX(0px);
+}
+
+#back {
+  z-index: 1;
+  width: 100px;
+  height: 100px;
+  background-color: #FF0000;
+  transform: translateY(-100px);
+}
+
+</style>
+
+<div id="perspective">
+  <div id="front"></div>
+</div>
+<div id="back"></div>
--- a/layout/reftests/transform-3d/reftest.list
+++ b/layout/reftests/transform-3d/reftest.list
@@ -40,16 +40,17 @@ fuzzy-if(winWidget&&!layersGPUAccelerate
 == backface-visibility-3.html backface-visibility-3-ref.html
 == perspective-clipping-1.html perspective-clipping-1-ref.html
 != perspective-origin-1a.html rotatex-perspective-1a.html
 == perspective-origin-1b.html perspective-origin-1a.html
 fuzzy(3,99) random-if(Android&&!browserIsRemote) == perspective-origin-2a.html perspective-origin-2-ref.html # subpixel AA, bug 732568
 fuzzy-if(winWidget&&!layersGPUAccelerated,1,61) == perspective-origin-3a.html perspective-origin-3-ref.html
 == perspective-origin-4a.html perspective-origin-4-ref.html
 == perspective-zindex.html green-rect.html
+== perspective-zindex-2.html green-rect.html
 != sorting-1a.html sorting-1-ref.html
 # Parallel planes, different z depth
 == sorting-2a.html sorting-2-ref.html
 # Parallel planes, same z depth (shouldn't be sorted!)
 == sorting-2b.html sorting-2-ref.html
 == sorting-3a.html green-rect.html
 # Different, but equivalent (for the given transform) transform origins
 == rotatex-transformorigin-1a.html rotatex-transformorigin-1-ref.html