Bug 1505222 - Pass TransformStyle::Preserve3d to WebRender more often for perspective display items. r=mattwoodrow
authorEmilio Cobos Álvarez <emilio@crisal.io>
Mon, 21 Jan 2019 22:24:06 +0100
changeset 454740 2195f346d368042482357dc178255030ca610265
parent 454739 f722c4dbd4ccc19911de8ad05423363e0b5b2da7
child 454741 ada22b635f8d13adb7725c2fcac51d0e12e3ed59
push id35411
push usercsabou@mozilla.com
push dateTue, 22 Jan 2019 03:53:40 +0000
treeherdermozilla-central@ada22b635f8d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmattwoodrow
bugs1505222
milestone66.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 1505222 - Pass TransformStyle::Preserve3d to WebRender more often for perspective display items. r=mattwoodrow See the comment. Differential Revision: https://phabricator.services.mozilla.com/D16768
layout/painting/nsDisplayList.cpp
testing/web-platform/tests/css/css-transforms/preserve3d-nested-perspective-ref.html
testing/web-platform/tests/css/css-transforms/preserve3d-nested-perspective.html
--- a/layout/painting/nsDisplayList.cpp
+++ b/layout/painting/nsDisplayList.cpp
@@ -8478,22 +8478,35 @@ bool nsDisplayPerspective::CreateWebRend
               0.0f);
   Point3D roundedOrigin(NS_round(newOrigin.x), NS_round(newOrigin.y), 0);
 
   perspectiveMatrix.PostTranslate(roundedOrigin);
 
   nsIFrame* perspectiveFrame =
       mFrame->GetContainingBlock(nsIFrame::SKIP_SCROLLED_FRAME);
 
+  // Passing true here is always correct, since perspective always combines
+  // transforms with the descendants. However that'd make WR do a lot of work
+  // that it doesn't really need to do if there aren't other transforms forming
+  // part of the 3D context.
+  //
+  // WR knows how to treat perspective in that case, so the only thing we need
+  // to do is to ensure we pass true when we're involved in a 3d context in any
+  // other way via the transform-style property on either the transformed frame
+  // or the perspective frame in order to not confuse WR's preserve-3d code in
+  // very awful ways.
+  bool preserve3D =
+      mFrame->Extend3DContext() || perspectiveFrame->Extend3DContext();
+
   nsTArray<mozilla::wr::FilterOp> filters;
   StackingContextHelper sc(
       aSc, GetActiveScrolledRoot(), mFrame, this, aBuilder, filters,
       LayoutDeviceRect(), nullptr, nullptr, nullptr, &perspectiveMatrix,
       wr::ReferenceFrameKind::Perspective, gfx::CompositionOp::OP_OVER,
-      !BackfaceIsHidden(), perspectiveFrame->Extend3DContext());
+      !BackfaceIsHidden(), preserve3D);
 
   return mList.CreateWebRenderCommands(aBuilder, aResources, sc, aManager,
                                        aDisplayListBuilder);
 }
 
 nsDisplayItemGeometry* nsCharClipDisplayItem::AllocateGeometry(
     nsDisplayListBuilder* aBuilder) {
   return new nsCharClipGeometry(this, aBuilder);
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/css/css-transforms/preserve3d-nested-perspective-ref.html
@@ -0,0 +1,13 @@
+<!doctype html>
+<title>CSS Test Reference</title>
+<link rel="author" href="mailto:emilio@crisal.io" title="Emilio Cobos Álvarez">
+<link rel="author" href="https://mozilla.org" title="Mozilla">
+<style>
+  html, body { margin: 0 }
+  #box {
+    width: 100px;
+    height: 100px;
+    background: green;
+  }
+</style>
+<div id="box"></div>
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/css/css-transforms/preserve3d-nested-perspective.html
@@ -0,0 +1,24 @@
+<!doctype html>
+<title>CSS Test: nested preserve-3d and perspective without transformed items</title>
+<link rel="author" href="mailto:emilio@crisal.io" title="Emilio Cobos Álvarez">
+<link rel="author" href="https://mozilla.org" title="Mozilla">
+<link rel="help" href="https://drafts.csswg.org/css-transforms-2/#perspective">
+<link rel="help" href="https://drafts.csswg.org/css-transforms-2/#transform-style-property">
+<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1505222">
+<link rel="match" href="preserve3d-nested-perspective-ref.html">
+<style>
+  html, body { margin: 0 }
+  #box {
+    width: 100px;
+    height: 100px;
+    background: green;
+  }
+</style>
+<!-- Since we don't specify any transform, this should render just a 100x100px red box -->
+<div style="perspective: 1200px">
+  <div style="transform-style: preserve-3d">
+    <div style="transform-style: flat">
+      <div id="box" style="transform-style: preserve-3d"></div>
+    </div>
+  </div>
+</div>