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
authorMatt Woodrow <mwoodrow@mozilla.com>
Wed, 04 May 2016 12:56:50 +1200
changeset 363215 51a3298d499ed6f77247919715784b991f6054ce
parent 363214 aef562eaad80d8c5bc4b1ba97c653e71593c6b79
child 363216 23bf1e82cc3425e7e1d1224dd1723916a084507e
push id17139
push userbmo:jbeich@FreeBSD.org
push dateWed, 04 May 2016 07:51:34 +0000
reviewersmstange
bugs1269184
milestone49.0a1
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
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