Bug 1274673 - Use binary space partitioning for sorting/drawing layers - Part 2: Rename Polygon3D to Polygon, and use 4D points for all calculations draft
authorMiko Mynttinen <mikokm@gmail.com>
Sun, 04 Dec 2016 17:49:32 +0100
changeset 447647 18ccb6d417b73dbf7e72054a03cbaf4d90d05273
parent 447639 31a7cd87166ed0b62832b32211bf6579f445b145
child 447648 c16e6ef142ba3183a7d267946234621c84d47dc2
child 448039 496afa29b582ce2bc7c085621aa3e008bc84a718
child 448040 d5aab658055ab80150365a20a0ece27efd1c0b73
child 448073 8da11dc9e77ec97980a9aad31aafa95d8df7308d
child 448080 7cb49606c854802faee278180d2995cb8033684f
child 448379 c93bc9220a15542756db8b904844fd630264379b
child 448579 ecc158cd61b6aea2f854fbdc59707b1bcaf265c4
push id38102
push userbmo:mikokm@gmail.com
push dateWed, 07 Dec 2016 00:26:57 +0000
bugs1274673
milestone53.0a1
Bug 1274673 - Use binary space partitioning for sorting/drawing layers - Part 2: Rename Polygon3D to Polygon, and use 4D points for all calculations MozReview-Commit-ID: I6DB8xldpjO
gfx/2d/Polygon.h
gfx/layers/BSPTree.cpp
gfx/layers/BSPTree.h
gfx/layers/Compositor.cpp
gfx/layers/Compositor.h
gfx/tests/gtest/PolygonTestUtils.cpp
gfx/tests/gtest/PolygonTestUtils.h
gfx/tests/gtest/TestBSPTree.cpp
gfx/tests/gtest/TestPolygon.cpp
--- a/gfx/2d/Polygon.h
+++ b/gfx/2d/Polygon.h
@@ -12,84 +12,136 @@
 #include "Point.h"
 #include "Triangle.h"
 
 #include <initializer_list>
 
 namespace mozilla {
 namespace gfx {
 
-// Polygon3DTyped stores the points of a convex planar polygon.
+template<class Units>
+Point4DTyped<Units>
+CalculateEdgeIntersect(const Point4DTyped<Units>& aFirst,
+                       const Point4DTyped<Units>& aSecond)
+{
+  static const float w = 0.00001f;
+  const float t = (w - aFirst.w) / (aSecond.w - aFirst.w);
+  return aFirst + (aSecond - aFirst) * t;
+}
+
 template<class Units>
-class Polygon3DTyped {
+nsTArray<Point4DTyped<Units>>
+ClipHomogeneous(const nsTArray<Point4DTyped<Units>>& aPoints)
+{
+  nsTArray<Point4DTyped<Units>> outPoints;
+
+  const size_t pointCount = aPoints.Length();
+  for (size_t i = 0; i < pointCount; ++i) {
+    const Point4DTyped<Units>& first = aPoints[i];
+    const Point4DTyped<Units>& second = aPoints[(i + 1) % pointCount];
+
+    MOZ_ASSERT(first.w != 0.0f || second.w != 0.0f);
+
+    if (first.w > 0.0f) {
+      outPoints.AppendElement(first);
+    }
+
+    if ((first.w <= 0.0f) ^ (second.w <= 0.0f)) {
+      outPoints.AppendElement(CalculateEdgeIntersect(first, second));
+    }
+  }
+
+  return outPoints;
+}
+
+template<class Units>
+nsTArray<Point4DTyped<Units>>
+ToPoints4D(const nsTArray<Point3DTyped<Units>>& aPoints)
+{
+  nsTArray<Point4DTyped<Units>> points;
+
+  for (const Point3DTyped<Units>& point : aPoints) {
+    points.AppendElement(Point4DTyped<Units>(point));
+  }
+
+  return points;
+}
+
+// PolygonTyped stores the points of a convex planar polygon.
+template<class Units>
+class PolygonTyped {
+  typedef Point3DTyped<Units> Point3DType;
+  typedef Point4DTyped<Units> Point4DType;
+
 public:
-  Polygon3DTyped() {}
+  PolygonTyped() {}
 
-  explicit Polygon3DTyped(const std::initializer_list<Point3DTyped<Units>>& aPoints,
-                          Point3DTyped<Units> aNormal =
-                            Point3DTyped<Units>(0.0f, 0.0f, 1.0f))
-    : mNormal(aNormal), mPoints(aPoints)
+  explicit PolygonTyped(const std::initializer_list<Point3DType>& aPoints)
+    : mNormal(DefaultNormal()),
+      mPoints(ToPoints4D(nsTArray<Point3DType>(aPoints)))
   {
 #ifdef DEBUG
     EnsurePlanarPolygon();
 #endif
   }
 
-  explicit Polygon3DTyped(nsTArray<Point3DTyped<Units>>&& aPoints,
-                          Point3DTyped<Units> aNormal =
-                            Point3DTyped<Units>(0.0f, 0.0f, 1.0f))
-    : mNormal(aNormal), mPoints(Move(aPoints))
+  explicit PolygonTyped(const nsTArray<Point3DType>& aPoints)
+    : mNormal(DefaultNormal()), mPoints(ToPoints4D(aPoints))
   {
 #ifdef DEBUG
     EnsurePlanarPolygon();
 #endif
   }
 
-  explicit Polygon3DTyped(const nsTArray<Point3DTyped<Units>>& aPoints,
-                          Point3DTyped<Units> aNormal =
-                            Point3DTyped<Units>(0.0f, 0.0f, 1.0f))
+  explicit PolygonTyped(const nsTArray<Point4DType>& aPoints,
+                          const Point4DType& aNormal = DefaultNormal())
     : mNormal(aNormal), mPoints(aPoints)
-  {
-#ifdef DEBUG
-    EnsurePlanarPolygon();
-#endif
-  }
+  {}
+
+  explicit PolygonTyped(nsTArray<Point4DType>&& aPoints,
+                          const Point4DType& aNormal = DefaultNormal())
+    : mNormal(aNormal), mPoints(Move(aPoints))
+  {}
 
   RectTyped<Units> BoundingBox() const
   {
+    if (mPoints.IsEmpty()) {
+      return RectTyped<Units>();
+    }
+
     float minX, maxX, minY, maxY;
     minX = maxX = mPoints[0].x;
     minY = maxY = mPoints[0].y;
 
-    for (const Point3DTyped<Units>& point : mPoints) {
+    for (const Point4DType& point : mPoints) {
       minX = std::min(point.x, minX);
       maxX = std::max(point.x, maxX);
 
       minY = std::min(point.y, minY);
       maxY = std::max(point.y, maxY);
     }
 
     return RectTyped<Units>(minX, minY, maxX - minX, maxY - minY);
   }
 
-  nsTArray<float>
-  CalculateDotProducts(const Polygon3DTyped<Units>& aPlane,
-                       size_t& aPos, size_t& aNeg) const
+  nsTArray<float> CalculateDotProducts(const PolygonTyped<Units>& aPlane,
+                                       size_t& aPos, size_t& aNeg) const
   {
     // Point classification might produce incorrect results due to numerical
     // inaccuracies. Using an epsilon value makes the splitting plane "thicker".
     const float epsilon = 0.05f;
 
     MOZ_ASSERT(!aPlane.GetPoints().IsEmpty());
-    const Point3DTyped<Units>& planeNormal = aPlane.GetNormal();
-    const Point3DTyped<Units>& planePoint = aPlane[0];
+    const Point4DType& planeNormal = aPlane.GetNormal();
+    const Point4DType& planePoint = aPlane[0];
 
     aPos = aNeg = 0;
     nsTArray<float> dotProducts;
-    for (const Point3DTyped<Units>& point : mPoints) {
+
+    for (const Point4DType& point : mPoints) {
       float dot = (point - planePoint).DotProduct(planeNormal);
 
       if (dot > epsilon) {
         aPos++;
       } else if (dot < -epsilon) {
         aNeg++;
       } else {
         // The point is within the thick plane.
@@ -98,70 +150,97 @@ public:
 
       dotProducts.AppendElement(dot);
     }
 
     return dotProducts;
   }
 
   // Clips the polygon against the given 2D rectangle.
-  Polygon3DTyped<Units> ClipPolygon(const RectTyped<Units>& aRect) const
+  PolygonTyped<Units> ClipPolygon(const RectTyped<Units>& aRect) const
   {
-    Polygon3DTyped<Units> polygon(mPoints, mNormal);
+    if (aRect.IsEmpty()) {
+      return PolygonTyped<Units>();
+    }
 
-    // Left edge
-    ClipPolygonWithEdge(polygon, aRect.BottomLeft(), aRect.TopLeft());
+    return ClipPolygon(FromRect(aRect));
+  }
+
+  // Clips the polygon against the given polygon in 2D.
+  PolygonTyped<Units> ClipPolygon(const PolygonTyped<Units>& aPolygon) const
+  {
+    const nsTArray<Point4DType>& points = aPolygon.GetPoints();
 
-    // Bottom edge
-    ClipPolygonWithEdge(polygon, aRect.BottomRight(), aRect.BottomLeft());
+    if (mPoints.IsEmpty() || points.IsEmpty()) {
+      return PolygonTyped<Units>();
+    }
+
+    PolygonTyped<Units> polygon(mPoints, mNormal);
 
-    // Right edge
-    ClipPolygonWithEdge(polygon, aRect.TopRight(), aRect.BottomRight());
+    const size_t pointCount = points.Length();
+    for (size_t i = 0; i < pointCount; ++i) {
+      const Point4DType p1 = points[(i + 1) % pointCount];
+      const Point4DType p2 = points[i];
 
-    // Top edge
-    ClipPolygonWithEdge(polygon, aRect.TopLeft(), aRect.TopRight());
+      const Point4DType normal(p2.y - p1.y, p1.x - p2.x, 0.0f, 0.0f);
+      const PolygonTyped<Units> plane({p1, p2}, normal);
+
+      ClipPolygonWithPlane(polygon, plane);
+    }
+
+    if (polygon.GetPoints().Length() < 3) {
+      return PolygonTyped<Units>();
+    }
 
     return polygon;
   }
 
-  const Point3DTyped<Units>& GetNormal() const
+  static PolygonTyped<Units> FromRect(const RectTyped<Units>& aRect)
+  {
+    return PolygonTyped<Units> {
+      Point3DType(aRect.x, aRect.y, 0.0f),
+      Point3DType(aRect.x, aRect.y + aRect.height, 0.0f),
+      Point3DType(aRect.x + aRect.width, aRect.y + aRect.height, 0.0f),
+      Point3DType(aRect.x + aRect.width, aRect.y, 0.0f)
+    };
+  }
+
+  const Point4DType& GetNormal() const
   {
     return mNormal;
   }
 
-  const nsTArray<Point3DTyped<Units>>& GetPoints() const
+  const nsTArray<Point4DType>& GetPoints() const
   {
     return mPoints;
   }
 
-  const Point3DTyped<Units>& operator[](size_t aIndex) const
+  const Point4DType& operator[](size_t aIndex) const
   {
     MOZ_ASSERT(mPoints.Length() > aIndex);
     return mPoints[aIndex];
   }
 
-  void SplitPolygon(const Polygon3DTyped<Units>& aSplittingPlane,
+  void SplitPolygon(const Point4DType& aNormal,
                     const nsTArray<float>& aDots,
-                    nsTArray<Point3DTyped<Units>>& aBackPoints,
-                    nsTArray<Point3DTyped<Units>>& aFrontPoints) const
+                    nsTArray<Point4DType>& aBackPoints,
+                    nsTArray<Point4DType>& aFrontPoints) const
   {
     static const auto Sign = [](const float& f) {
       if (f > 0.0f) return 1;
       if (f < 0.0f) return -1;
       return 0;
     };
 
-    const Point3DTyped<Units>& normal = aSplittingPlane.GetNormal();
     const size_t pointCount = mPoints.Length();
-
     for (size_t i = 0; i < pointCount; ++i) {
       size_t j = (i + 1) % pointCount;
 
-      const Point3DTyped<Units>& a = mPoints[i];
-      const Point3DTyped<Units>& b = mPoints[j];
+      const Point4DType& a = mPoints[i];
+      const Point4DType& b = mPoints[j];
       const float dotA = aDots[i];
       const float dotB = aDots[j];
 
       // The point is in front of or on the plane.
       if (dotA >= 0) {
         aFrontPoints.AppendElement(a);
       }
 
@@ -170,20 +249,20 @@ public:
         aBackPoints.AppendElement(a);
       }
 
       // If the sign of the dot products changes between two consecutive
       // vertices, then the plane intersects with the polygon edge.
       // The case where the polygon edge is within the plane is handled above.
       if (Sign(dotA) && Sign(dotB) && Sign(dotA) != Sign(dotB)) {
         // Calculate the line segment and plane intersection point.
-        const Point3DTyped<Units> ab = b - a;
-        const float dotAB = ab.DotProduct(normal);
+        const Point4DType ab = b - a;
+        const float dotAB = ab.DotProduct(aNormal);
         const float t = -dotA / dotAB;
-        const Point3DTyped<Units> p = a + (ab * t);
+        const Point4DType p = a + (ab * t);
 
         // Add the intersection point to both polygons.
         aBackPoints.AppendElement(p);
         aFrontPoints.AppendElement(p);
       }
     }
   }
 
@@ -202,94 +281,107 @@ public:
       triangles.AppendElement(Move(triangle));
     }
 
     return triangles;
   }
 
   void TransformToLayerSpace(const Matrix4x4Typed<Units, Units>& aTransform)
   {
-    TransformPoints(aTransform);
-    mNormal = Point3DTyped<Units>(0.0f, 0.0f, 1.0f);
+    TransformPoints(aTransform, true);
+    mNormal = DefaultNormal();
   }
 
   void TransformToScreenSpace(const Matrix4x4Typed<Units, Units>& aTransform)
   {
-    TransformPoints(aTransform);
+    TransformPoints(aTransform, false);
+    mPoints = ClipHomogeneous(mPoints);
 
     // Normal vectors should be transformed using inverse transpose.
     mNormal = aTransform.Inverse().Transpose().TransformPoint(mNormal);
   }
 
 private:
-  void ClipPolygonWithEdge(Polygon3DTyped<Units>& aPolygon,
-                           const PointTyped<Units>& aFirst,
-                           const PointTyped<Units>& aSecond) const
+  void ClipPolygonWithPlane(PolygonTyped<Units>& aPolygon,
+                            const PolygonTyped<Units>& aPlane) const
   {
-    const Point3DTyped<Units> a(aFirst.x, aFirst.y, 0.0f);
-    const Point3DTyped<Units> b(aSecond.x, aSecond.y, 0.0f);
-    const Point3DTyped<Units> normal(b.y - a.y, a.x - b.x, 0.0f);
-    Polygon3DTyped<Units> plane({a, b}, normal);
+    size_t pos, neg;
+    const nsTArray<float> dots =
+      aPolygon.CalculateDotProducts(aPlane, pos, neg);
 
-    size_t pos, neg;
-    nsTArray<float> dots = aPolygon.CalculateDotProducts(plane, pos, neg);
-
-    nsTArray<Point3DTyped<Units>> backPoints, frontPoints;
-    aPolygon.SplitPolygon(plane, dots, backPoints, frontPoints);
+    nsTArray<Point4DType> backPoints, frontPoints;
+    aPolygon.SplitPolygon(aPlane.GetNormal(), dots, backPoints, frontPoints);
 
     // Only use the points that are behind the clipping plane.
-    aPolygon = Polygon3DTyped<Units>(Move(backPoints), aPolygon.GetNormal());
+    aPolygon = PolygonTyped<Units>(Move(backPoints), aPolygon.GetNormal());
+  }
+
+  static Point4DType DefaultNormal()
+  {
+    return Point4DType(0.0f, 0.0f, 1.0f, 0.0f);
   }
 
 #ifdef DEBUG
   void EnsurePlanarPolygon() const
   {
     if (mPoints.Length() <= 3) {
       // Polygons with three or less points are guaranteed to be planar.
       return;
     }
 
     // This normal calculation method works only for planar polygons.
     // The resulting normal vector will point towards the viewer when the
     // polygon has a counter-clockwise winding order from the perspective
     // of the viewer.
-    Point3DTyped<Units> normal;
+    Point3DType normal;
+    const Point3DType p0 = mPoints[0].As3DPoint();
 
     for (size_t i = 1; i < mPoints.Length() - 1; ++i) {
-      normal +=
-        (mPoints[i] - mPoints[0]).CrossProduct(mPoints[i + 1] - mPoints[0]);
+      const Point3DType p1 = mPoints[i].As3DPoint();
+      const Point3DType p2 = mPoints[i + 1].As3DPoint();
+
+      normal += (p1 - p0).CrossProduct(p2 - p0);
     }
 
     // Ensure that at least one component is greater than zero.
     // This avoids division by zero when normalizing the vector.
     bool hasNonZeroComponent = std::abs(normal.x) > 0.0f ||
                                std::abs(normal.y) > 0.0f ||
                                std::abs(normal.z) > 0.0f;
+
     MOZ_ASSERT(hasNonZeroComponent);
 
     normal.Normalize();
 
     // Ensure that the polygon is planar.
     // http://mathworld.wolfram.com/Point-PlaneDistance.html
     const float epsilon = 0.01f;
-    for (const Point3DTyped<Units>& point : mPoints) {
-      float d = normal.DotProduct(point - mPoints[0]);
+    for (const Point4DType& point : mPoints) {
+      const Point3DType p1 = point.As3DPoint();
+      const float d = normal.DotProduct(p1 - p0);
+
       MOZ_ASSERT(std::abs(d) < epsilon);
     }
   }
 #endif
-  void TransformPoints(const Matrix4x4Typed<Units, Units>& aTransform)
+
+  void TransformPoints(const Matrix4x4Typed<Units, Units>& aTransform,
+                       const bool aDivideByW)
   {
-    for (Point3DTyped<Units>& point : mPoints) {
+    for (Point4DType& point : mPoints) {
       point = aTransform.TransformPoint(point);
+
+      if (aDivideByW && point.w > 0.0f) {
+          point = point / point.w;
+      }
     }
   }
 
-  Point3DTyped<Units> mNormal;
-  nsTArray<Point3DTyped<Units>> mPoints;
+  Point4DType mNormal;
+  nsTArray<Point4DType> mPoints;
 };
 
-typedef Polygon3DTyped<UnknownUnits> Polygon3D;
+typedef PolygonTyped<UnknownUnits> Polygon;
 
 } // namespace gfx
 } // namespace mozilla
 
 #endif /* MOZILLA_GFX_POLYGON_H */
--- a/gfx/layers/BSPTree.cpp
+++ b/gfx/layers/BSPTree.cpp
@@ -15,17 +15,17 @@ LayerPolygon PopFront(std::deque<LayerPo
   aLayers.pop_front();
   return layer;
 }
 
 void
 BSPTree::BuildDrawOrder(const UniquePtr<BSPTreeNode>& aNode,
                         nsTArray<LayerPolygon>& aLayers) const
 {
-  const gfx::Point3D& normal = aNode->First().GetNormal();
+  const gfx::Point4D& normal = aNode->First().GetNormal();
 
   UniquePtr<BSPTreeNode> *front = &aNode->front;
   UniquePtr<BSPTreeNode> *back = &aNode->back;
 
   // Since the goal is to return the draw order from back to front, we reverse
   // the traversal order if the current polygon is facing towards the camera.
   const bool reverseOrder = normal.z > 0.0f;
 
@@ -53,21 +53,21 @@ BSPTree::BuildDrawOrder(const UniquePtr<
 void
 BSPTree::BuildTree(UniquePtr<BSPTreeNode>& aRoot,
                    std::deque<LayerPolygon>& aLayers)
 {
   if (aLayers.empty()) {
     return;
   }
 
-  const gfx::Polygon3D& plane = aRoot->First();
+  const gfx::Polygon& plane = aRoot->First();
   std::deque<LayerPolygon> backLayers, frontLayers;
 
   for (LayerPolygon& layerPolygon : aLayers) {
-    const Maybe<gfx::Polygon3D>& geometry = layerPolygon.geometry;
+    const Maybe<gfx::Polygon>& geometry = layerPolygon.geometry;
 
     size_t pos = 0, neg = 0;
     nsTArray<float> dots = geometry->CalculateDotProducts(plane, pos, neg);
 
     // Back polygon
     if (pos == 0 && neg > 0) {
       backLayers.push_back(Move(layerPolygon));
     }
@@ -76,24 +76,29 @@ BSPTree::BuildTree(UniquePtr<BSPTreeNode
       frontLayers.push_back(Move(layerPolygon));
     }
     // Coplanar polygon
     else if (pos == 0 && neg == 0) {
       aRoot->layers.push_back(Move(layerPolygon));
     }
     // Polygon intersects with the splitting plane.
     else if (pos > 0 && neg > 0) {
-      nsTArray<gfx::Point3D> backPoints, frontPoints;
-      geometry->SplitPolygon(plane, dots, backPoints, frontPoints);
+      nsTArray<gfx::Point4D> backPoints, frontPoints;
+      geometry->SplitPolygon(plane.GetNormal(), dots, backPoints, frontPoints);
 
-      const gfx::Point3D& normal = geometry->GetNormal();
+      const gfx::Point4D& normal = geometry->GetNormal();
       Layer *layer = layerPolygon.layer;
 
-      backLayers.push_back(LayerPolygon(layer, Move(backPoints), normal));
-      frontLayers.push_back(LayerPolygon(layer, Move(frontPoints), normal));
+      if (backPoints.Length() >= 3) {
+        backLayers.push_back(LayerPolygon(layer, Move(backPoints), normal));
+      }
+
+      if (frontPoints.Length() >= 3) {
+        frontLayers.push_back(LayerPolygon(layer, Move(frontPoints), normal));
+      }
     }
   }
 
   if (!backLayers.empty()) {
     aRoot->back.reset(new BSPTreeNode(PopFront(backLayers)));
     BuildTree(aRoot->back, backLayers);
   }
 
--- a/gfx/layers/BSPTree.h
+++ b/gfx/layers/BSPTree.h
@@ -19,39 +19,40 @@ namespace layers {
 class Layer;
 
 // Represents a layer that might have a non-rectangular geometry.
 struct LayerPolygon {
   explicit LayerPolygon(Layer *aLayer)
     : layer(aLayer) {}
 
   LayerPolygon(Layer *aLayer,
-               gfx::Polygon3D&& aGeometry)
+               gfx::Polygon&& aGeometry)
     : layer(aLayer), geometry(Some(aGeometry)) {}
 
   LayerPolygon(Layer *aLayer,
-               nsTArray<gfx::Point3D>&& aPoints, const gfx::Point3D& aNormal)
-    : layer(aLayer), geometry(Some(gfx::Polygon3D(Move(aPoints), aNormal))) {}
+               nsTArray<gfx::Point4D>&& aPoints,
+               const gfx::Point4D& aNormal)
+    : layer(aLayer), geometry(Some(gfx::Polygon(Move(aPoints), aNormal))) {}
 
   Layer *layer;
-  Maybe<gfx::Polygon3D> geometry;
+  Maybe<gfx::Polygon> geometry;
 };
 
 LayerPolygon PopFront(std::deque<LayerPolygon>& aLayers);
 
 // Represents a node in a BSP tree. The node contains at least one layer with
 // associated geometry that is used as a splitting plane, and at most two child
 // nodes that represent the splitting planes that further subdivide the space.
 struct BSPTreeNode {
   explicit BSPTreeNode(LayerPolygon&& layer)
   {
     layers.push_back(Move(layer));
   }
 
-  const gfx::Polygon3D& First() const
+  const gfx::Polygon& First() const
   {
     MOZ_ASSERT(layers[0].geometry);
     return *layers[0].geometry;
   }
 
   UniquePtr<BSPTreeNode> front;
   UniquePtr<BSPTreeNode> back;
   std::deque<LayerPolygon> layers;
--- a/gfx/layers/Compositor.cpp
+++ b/gfx/layers/Compositor.cpp
@@ -222,101 +222,101 @@ Compositor::DrawDiagnosticsInternal(Diag
 
   SlowDrawRect(aVisibleRect, color, aClipRect, aTransform, lWidth);
 }
 
 static void
 UpdateTextureCoordinates(gfx::TexturedTriangle& aTriangle,
                          const gfx::Rect& aRect,
                          const gfx::Rect& aIntersection,
-                         gfx::Rect aTextureCoords)
+                         const gfx::Rect& aTextureCoords)
 {
   // Calculate the relative offset of the intersection within the layer.
   float dx = (aIntersection.x - aRect.x) / aRect.width;
   float dy = (aIntersection.y - aRect.y) / aRect.height;
 
   // Update the texture offset.
   float x = aTextureCoords.x + dx * aTextureCoords.width;
   float y = aTextureCoords.y + dy * aTextureCoords.height;
 
   // Scale the texture width and height.
   float w = aTextureCoords.width * aIntersection.width / aRect.width;
   float h = aTextureCoords.height * aIntersection.height / aRect.height;
 
-  static const auto ValidateAndClamp = [](float& f) {
-    // Allow some numerical inaccuracy.
-    MOZ_ASSERT(f >= -0.0001f && f <= 1.0001f);
-
+  static const auto Clamp = [](float& f)
+  {
     if (f >= 1.0f) f = 1.0f;
     if (f <= 0.0f) f = 0.0f;
   };
 
   auto UpdatePoint = [&](const gfx::Point& p, gfx::Point& t)
   {
     t.x = x + (p.x - aIntersection.x) / aIntersection.width * w;
     t.y = y + (p.y - aIntersection.y) / aIntersection.height * h;
 
-    ValidateAndClamp(t.x);
-    ValidateAndClamp(t.y);
+    Clamp(t.x);
+    Clamp(t.y);
   };
 
   UpdatePoint(aTriangle.p1, aTriangle.textureCoords.p1);
   UpdatePoint(aTriangle.p2, aTriangle.textureCoords.p2);
   UpdatePoint(aTriangle.p3, aTriangle.textureCoords.p3);
 }
 
 void
 Compositor::DrawGeometry(const gfx::Rect& aRect,
                          const gfx::IntRect& aClipRect,
                          const EffectChain& aEffectChain,
                          gfx::Float aOpacity,
                          const gfx::Matrix4x4& aTransform,
                          const gfx::Rect& aVisibleRect,
-                         const Maybe<gfx::Polygon3D>& aGeometry)
+                         const Maybe<gfx::Polygon>& aGeometry)
 {
   if (!aGeometry) {
     DrawQuad(aRect, aClipRect, aEffectChain,
              aOpacity, aTransform, aVisibleRect);
     return;
   }
 
   // Cull invisible polygons.
   if (aRect.Intersect(aGeometry->BoundingBox()).IsEmpty()) {
     return;
   }
 
-  gfx::Polygon3D clipped = aGeometry->ClipPolygon(aRect);
-  nsTArray<gfx::Triangle> triangles = clipped.ToTriangles();
+  const gfx::Polygon clipped = aGeometry->ClipPolygon(aRect);
 
-  for (gfx::Triangle& geometry : triangles) {
-    const gfx::Rect intersection = aRect.Intersect(geometry.BoundingBox());
+  for (gfx::Triangle& triangle : clipped.ToTriangles()) {
+    const gfx::Rect intersection = aRect.Intersect(triangle.BoundingBox());
 
     // Cull invisible triangles.
     if (intersection.IsEmpty()) {
       continue;
     }
 
     MOZ_ASSERT(aRect.width > 0.0f && aRect.height > 0.0f);
     MOZ_ASSERT(intersection.width > 0.0f && intersection.height > 0.0f);
 
-    gfx::TexturedTriangle triangle(Move(geometry));
-    triangle.width = aRect.width;
-    triangle.height = aRect.height;
+    gfx::TexturedTriangle texturedTriangle(Move(triangle));
+    texturedTriangle.width = aRect.width;
+    texturedTriangle.height = aRect.height;
 
     // Since the texture was created for non-split geometry, we need to
     // update the texture coordinates to account for the split.
-    if (aEffectChain.mPrimaryEffect->mType == EffectTypes::RGB) {
+    const EffectTypes type = aEffectChain.mPrimaryEffect->mType;
+
+    if (type == EffectTypes::RGB || type == EffectTypes::YCBCR ||
+        type == EffectTypes::NV12 || type == EffectTypes::RENDER_TARGET) {
       TexturedEffect* texturedEffect =
         static_cast<TexturedEffect*>(aEffectChain.mPrimaryEffect.get());
 
-      UpdateTextureCoordinates(triangle, aRect, intersection,
+      UpdateTextureCoordinates(texturedTriangle, aRect, intersection,
                                texturedEffect->mTextureCoords);
     }
 
-    DrawTriangle(triangle, aClipRect, aEffectChain,
+    DrawTriangle(texturedTriangle, aClipRect, aEffectChain,
                  aOpacity, aTransform, aVisibleRect);
   }
 }
 
 void
 Compositor::SlowDrawRect(const gfx::Rect& aRect, const gfx::Color& aColor,
                      const gfx::IntRect& aClipRect,
                      const gfx::Matrix4x4& aTransform, int aStrokeWidth)
--- a/gfx/layers/Compositor.h
+++ b/gfx/layers/Compositor.h
@@ -7,17 +7,17 @@
 #define MOZILLA_GFX_COMPOSITOR_H
 
 #include "Units.h"                      // for ScreenPoint
 #include "mozilla/Assertions.h"         // for MOZ_ASSERT, etc
 #include "mozilla/RefPtr.h"             // for already_AddRefed, RefCounted
 #include "mozilla/gfx/2D.h"             // for DrawTarget
 #include "mozilla/gfx/MatrixFwd.h"      // for Matrix4x4
 #include "mozilla/gfx/Point.h"          // for IntSize, Point
-#include "mozilla/gfx/Polygon.h"        // for Polygon3D
+#include "mozilla/gfx/Polygon.h"        // for Polygon
 #include "mozilla/gfx/Rect.h"           // for Rect, IntRect
 #include "mozilla/gfx/Types.h"          // for Float
 #include "mozilla/gfx/Triangle.h"       // for Triangle, TexturedTriangle
 #include "mozilla/layers/CompositorTypes.h"  // for DiagnosticTypes, etc
 #include "mozilla/layers/LayersTypes.h"  // for LayersBackend
 #include "mozilla/widget/CompositorWidget.h"
 #include "nsISupportsImpl.h"            // for MOZ_COUNT_CTOR, etc
 #include "nsRegion.h"
@@ -307,24 +307,24 @@ public:
   virtual void SetScreenRenderOffset(const ScreenPoint& aOffset) = 0;
 
   void DrawGeometry(const gfx::Rect& aRect,
                     const gfx::IntRect& aClipRect,
                     const EffectChain &aEffectChain,
                     gfx::Float aOpacity,
                     const gfx::Matrix4x4& aTransform,
                     const gfx::Rect& aVisibleRect,
-                    const Maybe<gfx::Polygon3D>& aGeometry);
+                    const Maybe<gfx::Polygon>& aGeometry);
 
   void DrawGeometry(const gfx::Rect& aRect,
                     const gfx::IntRect& aClipRect,
                     const EffectChain &aEffectChain,
                     gfx::Float aOpacity,
                     const gfx::Matrix4x4& aTransform,
-                    const Maybe<gfx::Polygon3D>& aGeometry)
+                    const Maybe<gfx::Polygon>& aGeometry)
   {
     DrawGeometry(aRect, aClipRect, aEffectChain, aOpacity,
                  aTransform, aRect, aGeometry);
   }
 
   /**
    * Tell the compositor to draw a quad. What to do draw and how it is
    * drawn is specified by aEffectChain. aRect is the quad to draw, in user space.
--- a/gfx/tests/gtest/PolygonTestUtils.cpp
+++ b/gfx/tests/gtest/PolygonTestUtils.cpp
@@ -8,46 +8,56 @@
 #include <cmath>
 
 namespace mozilla {
 namespace gfx {
 
 const float kEpsilon = 0.001f;
 
 // Compares two points while allowing some numerical inaccuracy.
+bool FuzzyEquals(const Point4D& lhs, const Point4D& rhs)
+{
+  const auto d = lhs - rhs;
+
+  return std::abs(d.x) < kEpsilon &&
+         std::abs(d.y) < kEpsilon &&
+         std::abs(d.z) < kEpsilon &&
+         std::abs(d.w) < kEpsilon;
+}
+
 bool FuzzyEquals(const Point3D& lhs, const Point3D& rhs)
 {
-  const Point3D d = lhs - rhs;
+  const auto d = lhs - rhs;
 
   return std::abs(d.x) < kEpsilon &&
          std::abs(d.y) < kEpsilon &&
          std::abs(d.z) < kEpsilon;
 }
 
 bool FuzzyEquals(const Point& lhs, const Point& rhs)
 {
-  const Point d = lhs - rhs;
+  const auto d = lhs - rhs;
 
   return std::abs(d.x) < kEpsilon &&
          std::abs(d.y) < kEpsilon;
 }
 
 bool operator==(const Triangle& lhs, const Triangle& rhs)
 {
   return FuzzyEquals(lhs.p1, rhs.p1) &&
          FuzzyEquals(lhs.p2, rhs.p2) &&
          FuzzyEquals(lhs.p3, rhs.p3);
 }
 
 // Compares the points of two polygons and ensures
 // that the points are in the same winding order.
-bool operator==(const Polygon3D& lhs, const Polygon3D& rhs)
+bool operator==(const Polygon& lhs, const Polygon& rhs)
 {
-  const nsTArray<Point3D>& left = lhs.GetPoints();
-  const nsTArray<Point3D>& right = rhs.GetPoints();
+  const auto& left = lhs.GetPoints();
+  const auto& right = rhs.GetPoints();
 
   // Polygons do not have the same amount of points.
   if (left.Length() != right.Length()) {
     return false;
   }
 
   const size_t pointCount = left.Length();
 
@@ -94,39 +104,39 @@ TEST(PolygonTestUtils, TestSanity)
                           Point3D(0.0f, 0.0f, 0.0f)));
 
   EXPECT_FALSE(FuzzyEquals(Point3D(0.0f, 0.0f, 0.0f),
                            Point3D(0.01f, 0.01f, 0.01f)));
 
   EXPECT_FALSE(FuzzyEquals(Point3D(0.01f, 0.01f, 0.01f),
                            Point3D(0.0f, 0.0f, 0.0f)));
 
-  Polygon3D p1 {
+  Polygon p1 {
     Point3D(0.0f, 0.0f, 1.0f),
     Point3D(1.0f, 0.0f, 1.0f),
     Point3D(1.0f, 1.0f, 1.0f),
     Point3D(0.0f, 1.0f, 1.0f)
   };
 
   // Same points as above shifted forward by one position.
-  Polygon3D shifted {
+  Polygon shifted {
     Point3D(0.0f, 1.0f, 1.0f),
     Point3D(0.0f, 0.0f, 1.0f),
     Point3D(1.0f, 0.0f, 1.0f),
     Point3D(1.0f, 1.0f, 1.0f)
   };
 
-  Polygon3D p2 {
+  Polygon p2 {
     Point3D(0.00001f, 0.00001f, 1.00001f),
     Point3D(1.00001f, 0.00001f, 1.00001f),
     Point3D(1.00001f, 1.00001f, 1.00001f),
     Point3D(0.00001f, 1.00001f, 1.00001f)
   };
 
-  Polygon3D p3 {
+  Polygon p3 {
     Point3D(0.01f, 0.01f, 1.01f),
     Point3D(1.01f, 0.01f, 1.01f),
     Point3D(1.01f, 1.01f, 1.01f),
     Point3D(0.01f, 1.01f, 1.01f)
   };
 
   // Trivial equals
   EXPECT_TRUE(p1 == p1);
--- a/gfx/tests/gtest/PolygonTestUtils.h
+++ b/gfx/tests/gtest/PolygonTestUtils.h
@@ -11,21 +11,22 @@
 #include "nsTArray.h"
 #include "Point.h"
 #include "Polygon.h"
 #include "Triangle.h"
 
 namespace mozilla {
 namespace gfx {
 
+bool FuzzyEquals(const Point4D& lhs, const Point4D& rhs);
 bool FuzzyEquals(const Point3D& lhs, const Point3D& rhs);
 bool FuzzyEquals(const Point& lhs, const Point& rhs);
 
 bool operator==(const Triangle& lhs, const Triangle& rhs);
-bool operator==(const Polygon3D& lhs, const Polygon3D& rhs);
+bool operator==(const Polygon& lhs, const Polygon& rhs);
 
 // Compares two arrays with the equality operator.
 template<typename T>
 void AssertArrayEQ(const nsTArray<T>& rhs, const nsTArray<T>& lhs)
 {
   ASSERT_EQ(lhs.Length(), rhs.Length());
 
   for (size_t i = 0; i < lhs.Length(); ++i) {
--- a/gfx/tests/gtest/TestBSPTree.cpp
+++ b/gfx/tests/gtest/TestBSPTree.cpp
@@ -11,21 +11,21 @@
 
 #include <deque>
 
 using namespace mozilla::gfx;
 using namespace mozilla::layers;
 
 namespace {
 
-static void RunTest(std::deque<Polygon3D> aPolygons,
-                    std::deque<Polygon3D> aExpected)
+static void RunTest(std::deque<Polygon> aPolygons,
+                    std::deque<Polygon> aExpected)
 {
   std::deque<LayerPolygon> layers;
-  for (Polygon3D& polygon : aPolygons) {
+  for (Polygon& polygon : aPolygons) {
     layers.push_back(LayerPolygon(nullptr, Move(polygon)));
   }
 
   const BSPTree tree(layers);
   const nsTArray<LayerPolygon> order = tree.GetDrawOrder();
 
   EXPECT_EQ(aExpected.size(), order.Length());
 
@@ -34,926 +34,926 @@ static void RunTest(std::deque<Polygon3D
   }
 }
 
 } // namespace
 
 
 TEST(BSPTree, SameNode)
 {
-  const std::deque<Polygon3D> polygons {
-    Polygon3D {
+  const std::deque<Polygon> polygons {
+    Polygon {
       Point3D(0.0f, 0.0f, 0.0f),
       Point3D(1.0f, 0.0f, 0.0f),
       Point3D(1.0f, 1.0f, 0.0f),
       Point3D(0.0f, 1.0f, 0.0f)
     },
-    Polygon3D {
+    Polygon {
       Point3D(0.0f, 0.0f, 0.0f),
       Point3D(1.0f, 0.0f, 0.0f),
       Point3D(1.0f, 1.0f, 0.0f),
       Point3D(0.0f, 1.0f, 0.0f)
     }
   };
 
   ::RunTest(polygons, polygons);
 }
 
 TEST(BSPTree, OneChild)
 {
-  const Polygon3D p1 {
+  const Polygon p1 {
     Point3D(0.0f, 0.0f, 0.0f),
     Point3D(1.0f, 0.0f, 0.0f),
     Point3D(1.0f, 1.0f, 0.0f),
     Point3D(0.0f, 1.0f, 0.0f)
   };
 
-  const Polygon3D p2 {
+  const Polygon p2 {
     Point3D(0.0f, 0.0f, 1.0f),
     Point3D(1.0f, 0.0f, 1.0f),
     Point3D(1.0f, 1.0f, 1.0f),
     Point3D(0.0f, 1.0f, 1.0f)
   };
 
   ::RunTest({p1, p2}, {p1, p2});
   ::RunTest({p2, p1}, {p1, p2});
 }
 
 TEST(BSPTree, SharedEdge1)
 {
-  Polygon3D p1 {
+  Polygon p1 {
     Point3D(1.0f, 0.0f, 1.0f),
     Point3D(0.0f, 0.0f, 1.0f),
     Point3D(0.0f, 1.0f, 1.0f),
     Point3D(1.0f, 1.0f, 1.0f)
   };
 
-  Polygon3D p2 {
+  Polygon p2 {
     Point3D(1.0f, 0.0f, 1.0f),
     Point3D(1.0f, 1.0f, 1.0f),
     Point3D(2.0f, 2.0f, 1.0f),
     Point3D(2.0f, 0.0f, 1.0f)
   };
 
   ::RunTest({p1, p2}, {p1, p2});
 }
 
 TEST(BSPTree, SharedEdge2)
 {
-  Polygon3D p1 {
+  Polygon p1 {
     Point3D(1.0f, 0.0f, 1.0f),
     Point3D(0.0f, 0.0f, 1.0f),
     Point3D(0.0f, 1.0f, 1.0f),
     Point3D(1.0f, 1.0f, 1.0f)
   };
 
-  Polygon3D p2 {
+  Polygon p2 {
     Point3D(1.0f, 0.0f, 1.0f),
     Point3D(1.0f, 1.0f, 1.0f),
     Point3D(2.0f, 2.0f, 0.0f),
     Point3D(2.0f, 0.0f, 0.0f)
   };
 
   ::RunTest({p1, p2}, {p2, p1});
 }
 
 TEST(BSPTree, SplitSharedEdge)
 {
-  Polygon3D p1 {
+  Polygon p1 {
     Point3D(1.0f, 0.0f, 1.0f),
     Point3D(0.0f, 0.0f, 1.0f),
     Point3D(0.0f, 1.0f, 1.0f),
     Point3D(1.0f, 1.0f, 1.0f)
   };
 
-  Polygon3D p2 {
+  Polygon p2 {
     Point3D(1.0f, 0.0f, 2.0f),
     Point3D(1.0f, 1.0f, 2.0f),
     Point3D(1.0f, 1.0f, 0.0f),
     Point3D(1.0f, 0.0f, 0.0f)
   };
 
-  const std::deque<Polygon3D> expected {
-    Polygon3D {
+  const std::deque<Polygon> expected {
+    Polygon {
       Point3D(1.0f, 1.0f, 1.0f),
       Point3D(1.0f, 1.0f, 0.0f),
       Point3D(1.0f, 0.0f, 0.0f),
       Point3D(1.0f, 0.0f, 1.0f)
     },
-    Polygon3D {
+    Polygon {
       Point3D(1.0f, 0.0f, 1.0f),
       Point3D(0.0f, 0.0f, 1.0f),
       Point3D(0.0f, 1.0f, 1.0f),
       Point3D(1.0f, 1.0f, 1.0f)
     },
-    Polygon3D {
+    Polygon {
       Point3D(1.0f, 0.0f, 2.0f),
       Point3D(1.0f, 1.0f, 2.0f),
       Point3D(1.0f, 1.0f, 1.0f),
       Point3D(1.0f, 0.0f, 1.0f)
     }
   };
 
   ::RunTest({p1, p2}, expected);
 }
 
 TEST(BSPTree, SplitSimple1)
 {
-  Polygon3D p1 {
+  Polygon p1 {
     Point3D(0.0f, 0.0f, 1.0f),
     Point3D(1.0f, 0.0f, 1.0f),
     Point3D(1.0f, 1.0f, 1.0f),
     Point3D(0.0f, 1.0f, 1.0f)
   };
 
-  Polygon3D p2 {
+  Polygon p2 {
     Point3D(0.0f, 0.0f, 2.0f),
     Point3D(1.0f, 0.0f, 2.0f),
     Point3D(1.0f, 1.0f, 0.0f),
     Point3D(0.0f, 1.0f, 0.0f)
   };
 
-  const std::deque<Polygon3D> expected {
-    Polygon3D {
+  const std::deque<Polygon> expected {
+    Polygon {
       Point3D(0.0f, 1.0f, 0.0f),
       Point3D(0.0f, 0.5f, 1.0f),
       Point3D(1.0f, 0.5f, 1.0f),
       Point3D(1.0f, 1.0f, 0.0f)
     },
     p1,
-    Polygon3D {
+    Polygon {
       Point3D(0.0f, 0.0f, 2.0f),
       Point3D(1.0f, 0.0f, 2.0f),
       Point3D(1.0f, 0.5f, 1.0f),
       Point3D(0.0f, 0.5f, 1.0f)
     }
   };
 
   ::RunTest({p1, p2}, expected);
 }
 
 TEST(BSPTree, SplitSimple2) {
-  const std::deque<Polygon3D> polygons {
-    Polygon3D {
+  const std::deque<Polygon> polygons {
+    Polygon {
       Point3D(-5.00000f, -5.00000f, 0.00000f),
       Point3D(-5.00000f, 5.00000f, 0.00000f),
       Point3D(5.00000f, 5.00000f, 0.00000f),
       Point3D(5.00000f, -5.00000f, 0.00000f)
     },
-    Polygon3D {
+    Polygon {
       Point3D(0.00000f, -5.00000f, -5.00000f),
       Point3D(0.00000f, 5.00000f, -5.00000f),
       Point3D(0.00000f, 5.00000f, 5.00000f),
       Point3D(0.00000f, -5.00000f, 5.00000f)
     }
   };
 
-  const std::deque<Polygon3D> expected {
-    Polygon3D {
+  const std::deque<Polygon> expected {
+    Polygon {
       Point3D(0.00000f, -5.00000f, 0.00000f),
       Point3D(0.00000f, -5.00000f, -5.00000f),
       Point3D(0.00000f, 5.00000f, -5.00000f),
       Point3D(0.00000f, 5.00000f, 0.00000f)
     },
-    Polygon3D {
+    Polygon {
       Point3D(-5.00000f, -5.00000f, 0.00000f),
       Point3D(-5.00000f, 5.00000f, 0.00000f),
       Point3D(5.00000f, 5.00000f, 0.00000f),
       Point3D(5.00000f, -5.00000f, 0.00000f)
     },
-    Polygon3D {
+    Polygon {
       Point3D(0.00000f, 5.00000f, 0.00000f),
       Point3D(0.00000f, 5.00000f, 5.00000f),
       Point3D(0.00000f, -5.00000f, 5.00000f),
       Point3D(0.00000f, -5.00000f, 0.00000f)
     }
   };
   ::RunTest(polygons, expected);
 }
 
 TEST(BSPTree, NoSplit1) {
-  const std::deque<Polygon3D> polygons {
-    Polygon3D {
+  const std::deque<Polygon> polygons {
+    Polygon {
       Point3D(0.00000f, 10.00000f, 0.00000f),
       Point3D(0.00000f, 0.00000f, 0.00000f),
       Point3D(10.00000f, 0.00000f, 0.00000f),
       Point3D(10.00000f, 10.00000f, 0.00000f)
     },
-    Polygon3D {
+    Polygon {
       Point3D(0.00000f, 10.00000f, -5.00000f),
       Point3D(0.00000f, 0.00000f, -5.00000f),
       Point3D(10.00000f, 0.00000f, -5.00000f),
       Point3D(10.00000f, 10.00000f, -5.00000f)
     },
-    Polygon3D {
+    Polygon {
       Point3D(0.00000f, 10.00000f, 5.00000f),
       Point3D(0.00000f, 0.00000f, 5.00000f),
       Point3D(10.00000f, 0.00000f, 5.00000f),
       Point3D(10.00000f, 10.00000f, 5.00000f)
     }
   };
 
-  const std::deque<Polygon3D> expected {
-    Polygon3D {
+  const std::deque<Polygon> expected {
+    Polygon {
       Point3D(0.00000f, 10.00000f, -5.00000f),
       Point3D(0.00000f, 0.00000f, -5.00000f),
       Point3D(10.00000f, 0.00000f, -5.00000f),
       Point3D(10.00000f, 10.00000f, -5.00000f)
     },
-    Polygon3D {
+    Polygon {
       Point3D(0.00000f, 10.00000f, 0.00000f),
       Point3D(0.00000f, 0.00000f, 0.00000f),
       Point3D(10.00000f, 0.00000f, 0.00000f),
       Point3D(10.00000f, 10.00000f, 0.00000f)
     },
-    Polygon3D {
+    Polygon {
       Point3D(0.00000f, 10.00000f, 5.00000f),
       Point3D(0.00000f, 0.00000f, 5.00000f),
       Point3D(10.00000f, 0.00000f, 5.00000f),
       Point3D(10.00000f, 10.00000f, 5.00000f)
     }
   };
   ::RunTest(polygons, expected);
 }
 
 TEST(BSPTree, NoSplit2) {
-  const std::deque<Polygon3D> polygons {
-    Polygon3D {
+  const std::deque<Polygon> polygons {
+    Polygon {
       Point3D(-5.00000f, -5.00000f, 0.00000f),
       Point3D(-5.00000f, 5.00000f, 0.00000f),
       Point3D(5.00000f, 5.00000f, 0.00000f),
       Point3D(5.00000f, -5.00000f, 0.00000f)
     },
-    Polygon3D {
+    Polygon {
       Point3D(0.00000f, 5.00000f, -15.00000f),
       Point3D(0.00000f, -5.00000f, -15.00000f),
       Point3D(0.00000f, -5.00000f, -10.00000f),
       Point3D(0.00000f, 5.00000f, -10.00000f)
     }
   };
 
-  const std::deque<Polygon3D> expected {
-    Polygon3D {
+  const std::deque<Polygon> expected {
+    Polygon {
       Point3D(0.00000f, 5.00000f, -15.00000f),
       Point3D(0.00000f, -5.00000f, -15.00000f),
       Point3D(0.00000f, -5.00000f, -10.00000f),
       Point3D(0.00000f, 5.00000f, -10.00000f)
     },
-    Polygon3D {
+    Polygon {
       Point3D(-5.00000f, -5.00000f, 0.00000f),
       Point3D(-5.00000f, 5.00000f, 0.00000f),
       Point3D(5.00000f, 5.00000f, 0.00000f),
       Point3D(5.00000f, -5.00000f, 0.00000f)
     }
   };
   ::RunTest(polygons, expected);
 }
 
 TEST(BSPTree, TwoPlaneIntersectRotate0degrees) {
-  const std::deque<Polygon3D> polygons {
-    Polygon3D {
+  const std::deque<Polygon> polygons {
+    Polygon {
       Point3D(-0.00000f, 2.00000f, 2.00000f),
       Point3D(-0.00000f, -2.00000f, 2.00000f),
       Point3D(0.00010f, -2.00000f, -2.00000f),
       Point3D(0.00010f, 2.00000f, -2.00000f)
     },
-    Polygon3D {
+    Polygon {
       Point3D(2.00000f, 0.00000f, 2.00000f),
       Point3D(2.00000f, -0.00000f, -2.00000f),
       Point3D(-2.00000f, 0.00000f, -2.00000f),
       Point3D(-2.00000f, 0.00010f, 2.00000f)
     }
   };
 
-  const std::deque<Polygon3D> expected {
-    Polygon3D {
+  const std::deque<Polygon> expected {
+    Polygon {
       Point3D(2.00000f, 0.00000f, 2.00000f),
       Point3D(2.00000f, -0.00000f, -2.00000f),
       Point3D(-2.00000f, 0.00000f, -2.00000f),
       Point3D(-2.00000f, 0.00010f, 2.00000f)
     },
-    Polygon3D {
+    Polygon {
       Point3D(-0.00000f, 2.00000f, 2.00000f),
       Point3D(-0.00000f, -2.00000f, 2.00000f),
       Point3D(0.00010f, -2.00000f, -2.00000f),
       Point3D(0.00010f, 2.00000f, -2.00000f)
     }
   };
   ::RunTest(polygons, expected);
 }
 
 TEST(BSPTree, TwoPlaneIntersectRotate20degrees) {
-  const std::deque<Polygon3D> polygons {
-    Polygon3D {
+  const std::deque<Polygon> polygons {
+    Polygon {
       Point3D(-0.00000f, 1.19540f, 2.56350f),
       Point3D(-0.00000f, -2.56340f, 1.19540f),
       Point3D(0.00010f, -1.19530f, -2.56340f),
       Point3D(0.00010f, 2.56350f, -1.19530f)
     },
-    Polygon3D {
+    Polygon {
       Point3D(2.00000f, -0.68400f, 1.87940f),
       Point3D(2.00000f, 0.68410f, -1.87930f),
       Point3D(-2.00000f, 0.68410f, -1.87930f),
       Point3D(-2.00000f, -0.68400f, 1.87940f)
     }
   };
 
-  const std::deque<Polygon3D> expected {
-    Polygon3D {
+  const std::deque<Polygon> expected {
+    Polygon {
       Point3D(2.00000f, -0.68400f, 1.87940f),
       Point3D(2.00000f, 0.68410f, -1.87930f),
       Point3D(-2.00000f, 0.68410f, -1.87930f),
       Point3D(-2.00000f, -0.68400f, 1.87940f)
     },
-    Polygon3D {
+    Polygon {
       Point3D(-0.00000f, 1.19540f, 2.56350f),
       Point3D(-0.00000f, -2.56340f, 1.19540f),
       Point3D(0.00010f, -1.19530f, -2.56340f),
       Point3D(0.00010f, 2.56350f, -1.19530f)
     }
   };
   ::RunTest(polygons, expected);
 }
 
 TEST(BSPTree, TwoPlaneIntersectRotate40degrees) {
-  const std::deque<Polygon3D> polygons {
-    Polygon3D {
+  const std::deque<Polygon> polygons {
+    Polygon {
       Point3D(-0.00000f, -0.73200f, 2.73210f),
       Point3D(-0.00000f, -2.73200f, -0.73200f),
       Point3D(0.00010f, 0.73210f, -2.73200f),
       Point3D(0.00010f, 2.73210f, 0.73210f)
     },
-    Polygon3D {
+    Polygon {
       Point3D(2.00000f, -1.73200f, 1.00000f),
       Point3D(2.00000f, 1.73210f, -0.99990f),
       Point3D(-2.00000f, 1.73210f, -0.99990f),
       Point3D(-2.00000f, -1.73200f, 1.00000f)
     }
   };
 
-  const std::deque<Polygon3D> expected {
-    Polygon3D {
+  const std::deque<Polygon> expected {
+    Polygon {
       Point3D(2.00000f, -1.73200f, 1.00000f),
       Point3D(2.00000f, 1.73210f, -0.99990f),
       Point3D(-2.00000f, 1.73210f, -0.99990f),
       Point3D(-2.00000f, -1.73200f, 1.00000f)
     },
-    Polygon3D {
+    Polygon {
       Point3D(-0.00000f, -0.73200f, 2.73210f),
       Point3D(-0.00000f, -2.73200f, -0.73200f),
       Point3D(0.00010f, 0.73210f, -2.73200f),
       Point3D(0.00010f, 2.73210f, 0.73210f)
     }
   };
   ::RunTest(polygons, expected);
 }
 
 TEST(BSPTree, TwoPlaneIntersectRotate60degrees) {
-  const std::deque<Polygon3D> polygons {
-    Polygon3D {
+  const std::deque<Polygon> polygons {
+    Polygon {
       Point3D(-0.00000f, -2.73200f, 0.73210f),
       Point3D(-0.00000f, -0.73200f, -2.73200f),
       Point3D(0.00010f, 2.73210f, -0.73200f),
       Point3D(0.00010f, 0.73210f, 2.73210f)
     },
-    Polygon3D {
+    Polygon {
       Point3D(2.00000f, -1.73200f, -1.00000f),
       Point3D(2.00000f, 1.73210f, 1.00010f),
       Point3D(-2.00000f, 1.73210f, 1.00010f),
       Point3D(-2.00000f, -1.73200f, -1.00000f)
     }
   };
 
-  const std::deque<Polygon3D> expected {
-    Polygon3D {
+  const std::deque<Polygon> expected {
+    Polygon {
       Point3D(-2.00000f, 1.26793f, 0.73210f),
       Point3D(-2.00000f, -1.73200f, -1.00000f),
       Point3D(2.00000f, -1.73200f, -1.00000f),
       Point3D(2.00000f, 1.26793f, 0.73210f)
     },
-    Polygon3D {
+    Polygon {
       Point3D(-0.00000f, -2.73200f, 0.73210f),
       Point3D(-0.00000f, -0.73200f, -2.73200f),
       Point3D(0.00010f, 2.73210f, -0.73200f),
       Point3D(0.00010f, 0.73210f, 2.73210f)
     },
-    Polygon3D {
+    Polygon {
       Point3D(2.00000f, 1.26793f, 0.73210f),
       Point3D(2.00000f, 1.73210f, 1.00010f),
       Point3D(-2.00000f, 1.73210f, 1.00010f),
       Point3D(-2.00000f, 1.26793f, 0.73210f)
     }
   };
   ::RunTest(polygons, expected);
 }
 
 TEST(BSPTree, TwoPlaneIntersectRotate80degrees) {
-  const std::deque<Polygon3D> polygons {
-    Polygon3D {
+  const std::deque<Polygon> polygons {
+    Polygon {
       Point3D(-0.00000f, -1.19530f, -2.56340f),
       Point3D(-0.00000f, 2.56350f, -1.19530f),
       Point3D(0.00010f, 1.19540f, 2.56350f),
       Point3D(0.00010f, -2.56340f, 1.19540f)
     },
-    Polygon3D {
+    Polygon {
       Point3D(2.00000f, 0.68410f, -1.87930f),
       Point3D(2.00000f, -0.68400f, 1.87940f),
       Point3D(-2.00000f, -0.68400f, 1.87940f),
       Point3D(-2.00000f, 0.68410f, -1.87930f)
     }
   };
 
-  const std::deque<Polygon3D> expected {
-    Polygon3D {
+  const std::deque<Polygon> expected {
+    Polygon {
       Point3D(-0.00000f, -1.19530f, -2.56340f),
       Point3D(-0.00000f, 2.56350f, -1.19530f),
       Point3D(0.00010f, 1.19540f, 2.56350f),
       Point3D(0.00010f, -2.56340f, 1.19540f)
     },
-    Polygon3D {
+    Polygon {
       Point3D(2.00000f, 0.68410f, -1.87930f),
       Point3D(2.00000f, -0.68400f, 1.87940f),
       Point3D(-2.00000f, -0.68400f, 1.87940f),
       Point3D(-2.00000f, 0.68410f, -1.87930f)
     }
   };
   ::RunTest(polygons, expected);
 }
 
 TEST(BSPTree, TwoPlaneIntersectRotate100degrees) {
-  const std::deque<Polygon3D> polygons {
-    Polygon3D {
+  const std::deque<Polygon> polygons {
+    Polygon {
       Point3D(-0.00000f, 2.73210f, -0.73200f),
       Point3D(-0.00000f, 0.73210f, 2.73210f),
       Point3D(0.00010f, -2.73200f, 0.73210f),
       Point3D(0.00010f, -0.73200f, -2.73200f)
     },
-    Polygon3D {
+    Polygon {
       Point3D(2.00000f, 1.73210f, 1.00010f),
       Point3D(2.00000f, -1.73200f, -1.00000f),
       Point3D(-2.00000f, -1.73200f, -1.00000f),
       Point3D(-2.00000f, 1.73210f, 1.00010f)
     }
   };
 
-  const std::deque<Polygon3D> expected {
-    Polygon3D {
+  const std::deque<Polygon> expected {
+    Polygon {
       Point3D(2.00000f, -1.26783f, -0.73200f),
       Point3D(2.00000f, -1.73200f, -1.00000f),
       Point3D(-2.00000f, -1.73200f, -1.00000f),
       Point3D(-2.00000f, -1.26783f, -0.73200f)
     },
-    Polygon3D {
+    Polygon {
       Point3D(-0.00000f, 2.73210f, -0.73200f),
       Point3D(-0.00000f, 0.73210f, 2.73210f),
       Point3D(0.00010f, -2.73200f, 0.73210f),
       Point3D(0.00010f, -0.73200f, -2.73200f)
     },
-    Polygon3D {
+    Polygon {
       Point3D(-2.00000f, -1.26783f, -0.73200f),
       Point3D(-2.00000f, 1.73210f, 1.00010f),
       Point3D(2.00000f, 1.73210f, 1.00010f),
       Point3D(2.00000f, -1.26783f, -0.73200f)
     }
   };
   ::RunTest(polygons, expected);
 }
 
 TEST(BSPTree, TwoPlaneIntersectRotate120degrees) {
-  const std::deque<Polygon3D> polygons {
-    Polygon3D {
+  const std::deque<Polygon> polygons {
+    Polygon {
       Point3D(-0.00000f, -0.73200f, 2.73210f),
       Point3D(-0.00000f, -2.73200f, -0.73200f),
       Point3D(0.00010f, 0.73210f, -2.73200f),
       Point3D(0.00010f, 2.73210f, 0.73210f)
     },
-    Polygon3D {
+    Polygon {
       Point3D(2.00000f, -1.73200f, 1.00000f),
       Point3D(2.00000f, 1.73210f, -0.99990f),
       Point3D(-2.00000f, 1.73210f, -0.99990f),
       Point3D(-2.00000f, -1.73200f, 1.00000f)
     }
   };
 
-  const std::deque<Polygon3D> expected {
-    Polygon3D {
+  const std::deque<Polygon> expected {
+    Polygon {
       Point3D(2.00000f, -1.73200f, 1.00000f),
       Point3D(2.00000f, 1.73210f, -0.99990f),
       Point3D(-2.00000f, 1.73210f, -0.99990f),
       Point3D(-2.00000f, -1.73200f, 1.00000f)
     },
-    Polygon3D {
+    Polygon {
       Point3D(-0.00000f, -0.73200f, 2.73210f),
       Point3D(-0.00000f, -2.73200f, -0.73200f),
       Point3D(0.00010f, 0.73210f, -2.73200f),
       Point3D(0.00010f, 2.73210f, 0.73210f)
     }
   };
   ::RunTest(polygons, expected);
 }
 
 TEST(BSPTree, TwoPlaneIntersectRotate140degrees) {
-  const std::deque<Polygon3D> polygons {
-    Polygon3D {
+  const std::deque<Polygon> polygons {
+    Polygon {
       Point3D(-0.00000f, -1.19530f, -2.56340f),
       Point3D(-0.00000f, 2.56350f, -1.19530f),
       Point3D(0.00010f, 1.19540f, 2.56350f),
       Point3D(0.00010f, -2.56340f, 1.19540f)
     },
-    Polygon3D {
+    Polygon {
       Point3D(2.00000f, 0.68410f, -1.87930f),
       Point3D(2.00000f, -0.68400f, 1.87940f),
       Point3D(-2.00000f, -0.68400f, 1.87940f),
       Point3D(-2.00000f, 0.68410f, -1.87930f)
     }
   };
 
-  const std::deque<Polygon3D> expected {
-    Polygon3D {
+  const std::deque<Polygon> expected {
+    Polygon {
       Point3D(-0.00000f, -1.19530f, -2.56340f),
       Point3D(-0.00000f, 2.56350f, -1.19530f),
       Point3D(0.00010f, 1.19540f, 2.56350f),
       Point3D(0.00010f, -2.56340f, 1.19540f)
     },
-    Polygon3D {
+    Polygon {
       Point3D(2.00000f, 0.68410f, -1.87930f),
       Point3D(2.00000f, -0.68400f, 1.87940f),
       Point3D(-2.00000f, -0.68400f, 1.87940f),
       Point3D(-2.00000f, 0.68410f, -1.87930f)
     }
   };
   ::RunTest(polygons, expected);
 }
 
 TEST(BSPTree, TwoPlaneIntersectRotate160degrees) {
-  const std::deque<Polygon3D> polygons {
-    Polygon3D {
+  const std::deque<Polygon> polygons {
+    Polygon {
       Point3D(-0.00000f, 2.00000f, 2.00000f),
       Point3D(-0.00000f, -2.00000f, 2.00000f),
       Point3D(0.00010f, -2.00000f, -2.00000f),
       Point3D(0.00010f, 2.00000f, -2.00000f)
     },
-    Polygon3D {
+    Polygon {
       Point3D(2.00000f, -0.00000f, 2.00000f),
       Point3D(2.00000f, 0.00010f, -2.00000f),
       Point3D(-2.00000f, 0.00010f, -2.00000f),
       Point3D(-2.00000f, -0.00000f, 2.00000f)
     }
   };
 
-  const std::deque<Polygon3D> expected {
-    Polygon3D {
+  const std::deque<Polygon> expected {
+    Polygon {
       Point3D(2.00000f, -0.00000f, 2.00000f),
       Point3D(2.00000f, 0.00010f, -2.00000f),
       Point3D(-2.00000f, 0.00010f, -2.00000f),
       Point3D(-2.00000f, -0.00000f, 2.00000f)
     },
-    Polygon3D {
+    Polygon {
       Point3D(-0.00000f, 2.00000f, 2.00000f),
       Point3D(-0.00000f, -2.00000f, 2.00000f),
       Point3D(0.00010f, -2.00000f, -2.00000f),
       Point3D(0.00010f, 2.00000f, -2.00000f)
     }
   };
   ::RunTest(polygons, expected);
 }
 
 TEST(BSPTree, TwoPlaneIntersectRotate180degrees) {
-  const std::deque<Polygon3D> polygons {
-    Polygon3D {
+  const std::deque<Polygon> polygons {
+    Polygon {
       Point3D(-0.00000f, -2.00000f, -2.00000f),
       Point3D(-0.00000f, 2.00000f, -2.00000f),
       Point3D(0.00010f, 2.00000f, 2.00000f),
       Point3D(0.00010f, -2.00000f, 2.00000f)
     },
-    Polygon3D {
+    Polygon {
       Point3D(2.00000f, 0.00010f, -2.00000f),
       Point3D(2.00000f, -0.00000f, 2.00000f),
       Point3D(-2.00000f, -0.00000f, 2.00000f),
       Point3D(-2.00000f, 0.00010f, -2.00000f)
     }
   };
 
-  const std::deque<Polygon3D> expected {
-    Polygon3D {
+  const std::deque<Polygon> expected {
+    Polygon {
       Point3D(-0.00000f, -2.00000f, -2.00000f),
       Point3D(-0.00000f, 2.00000f, -2.00000f),
       Point3D(0.00010f, 2.00000f, 2.00000f),
       Point3D(0.00010f, -2.00000f, 2.00000f)
     },
-    Polygon3D {
+    Polygon {
       Point3D(2.00000f, 0.00010f, -2.00000f),
       Point3D(2.00000f, -0.00000f, 2.00000f),
       Point3D(-2.00000f, -0.00000f, 2.00000f),
       Point3D(-2.00000f, 0.00010f, -2.00000f)
     }
   };
   ::RunTest(polygons, expected);
 }
 
 TEST(BSPTree, TwoPlaneIntersectRotate200degrees) {
-  const std::deque<Polygon3D> polygons {
-    Polygon3D {
+  const std::deque<Polygon> polygons {
+    Polygon {
       Point3D(-0.00000f, 1.19540f, 2.56350f),
       Point3D(-0.00000f, -2.56340f, 1.19540f),
       Point3D(0.00010f, -1.19530f, -2.56340f),
       Point3D(0.00010f, 2.56350f, -1.19530f)
     },
-    Polygon3D {
+    Polygon {
       Point3D(2.00000f, -0.68400f, 1.87940f),
       Point3D(2.00000f, 0.68410f, -1.87930f),
       Point3D(-2.00000f, 0.68410f, -1.87930f),
       Point3D(-2.00000f, -0.68400f, 1.87940f)
     }
   };
 
-  const std::deque<Polygon3D> expected {
-    Polygon3D {
+  const std::deque<Polygon> expected {
+    Polygon {
       Point3D(2.00000f, -0.68400f, 1.87940f),
       Point3D(2.00000f, 0.68410f, -1.87930f),
       Point3D(-2.00000f, 0.68410f, -1.87930f),
       Point3D(-2.00000f, -0.68400f, 1.87940f)
     },
-    Polygon3D {
+    Polygon {
       Point3D(-0.00000f, 1.19540f, 2.56350f),
       Point3D(-0.00000f, -2.56340f, 1.19540f),
       Point3D(0.00010f, -1.19530f, -2.56340f),
       Point3D(0.00010f, 2.56350f, -1.19530f)
     }
   };
   ::RunTest(polygons, expected);
 }
 
 TEST(BSPTree, TwoPlaneIntersectRotate220degrees) {
-  const std::deque<Polygon3D> polygons {
-    Polygon3D {
+  const std::deque<Polygon> polygons {
+    Polygon {
       Point3D(-0.00000f, 0.73210f, -2.73200f),
       Point3D(-0.00000f, 2.73210f, 0.73210f),
       Point3D(0.00010f, -0.73200f, 2.73210f),
       Point3D(0.00010f, -2.73200f, -0.73200f)
     },
-    Polygon3D {
+    Polygon {
       Point3D(2.00000f, 1.73210f, -0.99990f),
       Point3D(2.00000f, -1.73200f, 1.00000f),
       Point3D(-2.00000f, -1.73200f, 1.00000f),
       Point3D(-2.00000f, 1.73210f, -0.99990f)
     }
   };
 
-  const std::deque<Polygon3D> expected {
-    Polygon3D {
+  const std::deque<Polygon> expected {
+    Polygon {
       Point3D(-0.00000f, 0.73210f, -2.73200f),
       Point3D(-0.00000f, 2.73210f, 0.73210f),
       Point3D(0.00010f, -0.73200f, 2.73210f),
       Point3D(0.00010f, -2.73200f, -0.73200f)
     },
-    Polygon3D {
+    Polygon {
       Point3D(2.00000f, 1.73210f, -0.99990f),
       Point3D(2.00000f, -1.73200f, 1.00000f),
       Point3D(-2.00000f, -1.73200f, 1.00000f),
       Point3D(-2.00000f, 1.73210f, -0.99990f)
     }
   };
   ::RunTest(polygons, expected);
 }
 
 TEST(BSPTree, TwoPlaneIntersectRotate240degrees) {
-  const std::deque<Polygon3D> polygons {
-    Polygon3D {
+  const std::deque<Polygon> polygons {
+    Polygon {
       Point3D(-0.00000f, -2.73200f, 0.73210f),
       Point3D(-0.00000f, -0.73200f, -2.73200f),
       Point3D(0.00010f, 2.73210f, -0.73200f),
       Point3D(0.00010f, 0.73210f, 2.73210f)
     },
-    Polygon3D {
+    Polygon {
       Point3D(2.00000f, -1.73200f, -1.00000f),
       Point3D(2.00000f, 1.73210f, 1.00010f),
       Point3D(-2.00000f, 1.73210f, 1.00010f),
       Point3D(-2.00000f, -1.73200f, -1.00000f)
     }
   };
 
-  const std::deque<Polygon3D> expected {
-    Polygon3D {
+  const std::deque<Polygon> expected {
+    Polygon {
       Point3D(-2.00000f, 1.26793f, 0.73210f),
       Point3D(-2.00000f, -1.73200f, -1.00000f),
       Point3D(2.00000f, -1.73200f, -1.00000f),
       Point3D(2.00000f, 1.26793f, 0.73210f)
     },
-    Polygon3D {
+    Polygon {
       Point3D(-0.00000f, -2.73200f, 0.73210f),
       Point3D(-0.00000f, -0.73200f, -2.73200f),
       Point3D(0.00010f, 2.73210f, -0.73200f),
       Point3D(0.00010f, 0.73210f, 2.73210f)
     },
-    Polygon3D {
+    Polygon {
       Point3D(2.00000f, 1.26793f, 0.73210f),
       Point3D(2.00000f, 1.73210f, 1.00010f),
       Point3D(-2.00000f, 1.73210f, 1.00010f),
       Point3D(-2.00000f, 1.26793f, 0.73210f)
     }
   };
   ::RunTest(polygons, expected);
 }
 
 TEST(BSPTree, TwoPlaneIntersectRotate260degrees) {
-  const std::deque<Polygon3D> polygons {
-    Polygon3D {
+  const std::deque<Polygon> polygons {
+    Polygon {
       Point3D(-0.00000f, 1.19540f, 2.56350f),
       Point3D(-0.00000f, -2.56340f, 1.19540f),
       Point3D(0.00010f, -1.19530f, -2.56340f),
       Point3D(0.00010f, 2.56350f, -1.19530f)
     },
-    Polygon3D {
+    Polygon {
       Point3D(2.00000f, -0.68400f, 1.87940f),
       Point3D(2.00000f, 0.68410f, -1.87930f),
       Point3D(-2.00000f, 0.68410f, -1.87930f),
       Point3D(-2.00000f, -0.68400f, 1.87940f)
     }
   };
 
-  const std::deque<Polygon3D> expected {
-    Polygon3D {
+  const std::deque<Polygon> expected {
+    Polygon {
       Point3D(2.00000f, -0.68400f, 1.87940f),
       Point3D(2.00000f, 0.68410f, -1.87930f),
       Point3D(-2.00000f, 0.68410f, -1.87930f),
       Point3D(-2.00000f, -0.68400f, 1.87940f)
     },
-    Polygon3D {
+    Polygon {
       Point3D(-0.00000f, 1.19540f, 2.56350f),
       Point3D(-0.00000f, -2.56340f, 1.19540f),
       Point3D(0.00010f, -1.19530f, -2.56340f),
       Point3D(0.00010f, 2.56350f, -1.19530f)
     }
   };
   ::RunTest(polygons, expected);
 }
 
 TEST(BSPTree, TwoPlaneIntersectRotate280degrees) {
-  const std::deque<Polygon3D> polygons {
-    Polygon3D {
+  const std::deque<Polygon> polygons {
+    Polygon {
       Point3D(-0.00000f, 2.73210f, -0.73200f),
       Point3D(-0.00000f, 0.73210f, 2.73210f),
       Point3D(0.00010f, -2.73200f, 0.73210f),
       Point3D(0.00010f, -0.73200f, -2.73200f)
     },
-    Polygon3D {
+    Polygon {
       Point3D(2.00000f, 1.73210f, 1.00010f),
       Point3D(2.00000f, -1.73200f, -1.00000f),
       Point3D(-2.00000f, -1.73200f, -1.00000f),
       Point3D(-2.00000f, 1.73210f, 1.00010f)
     }
   };
 
-  const std::deque<Polygon3D> expected {
-    Polygon3D {
+  const std::deque<Polygon> expected {
+    Polygon {
       Point3D(2.00000f, -1.26783f, -0.73200f),
       Point3D(2.00000f, -1.73200f, -1.00000f),
       Point3D(-2.00000f, -1.73200f, -1.00000f),
       Point3D(-2.00000f, -1.26783f, -0.73200f)
     },
-    Polygon3D {
+    Polygon {
       Point3D(-0.00000f, 2.73210f, -0.73200f),
       Point3D(-0.00000f, 0.73210f, 2.73210f),
       Point3D(0.00010f, -2.73200f, 0.73210f),
       Point3D(0.00010f, -0.73200f, -2.73200f)
     },
-    Polygon3D {
+    Polygon {
       Point3D(-2.00000f, -1.26783f, -0.73200f),
       Point3D(-2.00000f, 1.73210f, 1.00010f),
       Point3D(2.00000f, 1.73210f, 1.00010f),
       Point3D(2.00000f, -1.26783f, -0.73200f)
     }
   };
   ::RunTest(polygons, expected);
 }
 
 TEST(BSPTree, TwoPlaneIntersectRotate300degrees) {
-  const std::deque<Polygon3D> polygons {
-    Polygon3D {
+  const std::deque<Polygon> polygons {
+    Polygon {
       Point3D(-0.00000f, 0.73210f, -2.73200f),
       Point3D(-0.00000f, 2.73210f, 0.73210f),
       Point3D(0.00010f, -0.73200f, 2.73210f),
       Point3D(0.00010f, -2.73200f, -0.73200f)
     },
-    Polygon3D {
+    Polygon {
       Point3D(2.00000f, 1.73210f, -0.99990f),
       Point3D(2.00000f, -1.73200f, 1.00000f),
       Point3D(-2.00000f, -1.73200f, 1.00000f),
       Point3D(-2.00000f, 1.73210f, -0.99990f)
     }
   };
 
-  const std::deque<Polygon3D> expected {
-    Polygon3D {
+  const std::deque<Polygon> expected {
+    Polygon {
       Point3D(-0.00000f, 0.73210f, -2.73200f),
       Point3D(-0.00000f, 2.73210f, 0.73210f),
       Point3D(0.00010f, -0.73200f, 2.73210f),
       Point3D(0.00010f, -2.73200f, -0.73200f)
     },
-    Polygon3D {
+    Polygon {
       Point3D(2.00000f, 1.73210f, -0.99990f),
       Point3D(2.00000f, -1.73200f, 1.00000f),
       Point3D(-2.00000f, -1.73200f, 1.00000f),
       Point3D(-2.00000f, 1.73210f, -0.99990f)
     }
   };
   ::RunTest(polygons, expected);
 }
 
 TEST(BSPTree, TwoPlaneIntersectRotate320degrees) {
-  const std::deque<Polygon3D> polygons {
-    Polygon3D {
+  const std::deque<Polygon> polygons {
+    Polygon {
       Point3D(-0.00000f, -1.19530f, -2.56340f),
       Point3D(-0.00000f, 2.56350f, -1.19530f),
       Point3D(0.00010f, 1.19540f, 2.56350f),
       Point3D(0.00010f, -2.56340f, 1.19540f)
     },
-    Polygon3D {
+    Polygon {
       Point3D(2.00000f, 0.68410f, -1.87930f),
       Point3D(2.00000f, -0.68400f, 1.87940f),
       Point3D(-2.00000f, -0.68400f, 1.87940f),
       Point3D(-2.00000f, 0.68410f, -1.87930f)
     }
   };
 
-  const std::deque<Polygon3D> expected {
-    Polygon3D {
+  const std::deque<Polygon> expected {
+    Polygon {
       Point3D(-0.00000f, -1.19530f, -2.56340f),
       Point3D(-0.00000f, 2.56350f, -1.19530f),
       Point3D(0.00010f, 1.19540f, 2.56350f),
       Point3D(0.00010f, -2.56340f, 1.19540f)
     },
-    Polygon3D {
+    Polygon {
       Point3D(2.00000f, 0.68410f, -1.87930f),
       Point3D(2.00000f, -0.68400f, 1.87940f),
       Point3D(-2.00000f, -0.68400f, 1.87940f),
       Point3D(-2.00000f, 0.68410f, -1.87930f)
     }
   };
   ::RunTest(polygons, expected);
 }
 
 TEST(BSPTree, TwoPlaneIntersectRotate340degrees) {
-  const std::deque<Polygon3D> polygons {
-    Polygon3D {
+  const std::deque<Polygon> polygons {
+    Polygon {
       Point3D(-0.00000f, -2.00000f, -2.00000f),
       Point3D(-0.00000f, 2.00000f, -2.00000f),
       Point3D(0.00010f, 2.00000f, 2.00000f),
       Point3D(0.00010f, -2.00000f, 2.00000f)
     },
-    Polygon3D {
+    Polygon {
       Point3D(2.00000f, 0.00010f, -2.00000f),
       Point3D(2.00000f, -0.00000f, 2.00000f),
       Point3D(-2.00000f, -0.00000f, 2.00000f),
       Point3D(-2.00000f, 0.00010f, -2.00000f)
     }
   };
 
-  const std::deque<Polygon3D> expected {
-    Polygon3D {
+  const std::deque<Polygon> expected {
+    Polygon {
       Point3D(-0.00000f, -2.00000f, -2.00000f),
       Point3D(-0.00000f, 2.00000f, -2.00000f),
       Point3D(0.00010f, 2.00000f, 2.00000f),
       Point3D(0.00010f, -2.00000f, 2.00000f)
     },
-    Polygon3D {
+    Polygon {
       Point3D(2.00000f, 0.00010f, -2.00000f),
       Point3D(2.00000f, -0.00000f, 2.00000f),
       Point3D(-2.00000f, -0.00000f, 2.00000f),
       Point3D(-2.00000f, 0.00010f, -2.00000f)
     }
   };
   ::RunTest(polygons, expected);
 }
 
 TEST(BSPTree, TwoPlaneIntersectRotate360degrees) {
-  const std::deque<Polygon3D> polygons {
-    Polygon3D {
+  const std::deque<Polygon> polygons {
+    Polygon {
       Point3D(-0.00000f, -2.00000f, -2.00000f),
       Point3D(-0.00000f, 2.00000f, -2.00000f),
       Point3D(0.00010f, 2.00000f, 2.00000f),
       Point3D(0.00010f, -2.00000f, 2.00000f)
     },
-    Polygon3D {
+    Polygon {
       Point3D(2.00000f, 0.00010f, -2.00000f),
       Point3D(2.00000f, -0.00000f, 2.00000f),
       Point3D(-2.00000f, -0.00000f, 2.00000f),
       Point3D(-2.00000f, 0.00010f, -2.00000f)
     }
   };
 
-  const std::deque<Polygon3D> expected {
-    Polygon3D {
+  const std::deque<Polygon> expected {
+    Polygon {
       Point3D(-0.00000f, -2.00000f, -2.00000f),
       Point3D(-0.00000f, 2.00000f, -2.00000f),
       Point3D(0.00010f, 2.00000f, 2.00000f),
       Point3D(0.00010f, -2.00000f, 2.00000f)
     },
-    Polygon3D {
+    Polygon {
       Point3D(2.00000f, 0.00010f, -2.00000f),
       Point3D(2.00000f, -0.00000f, 2.00000f),
       Point3D(-2.00000f, -0.00000f, 2.00000f),
       Point3D(-2.00000f, 0.00010f, -2.00000f)
     }
   };
   ::RunTest(polygons, expected);
 }
--- a/gfx/tests/gtest/TestPolygon.cpp
+++ b/gfx/tests/gtest/TestPolygon.cpp
@@ -9,37 +9,37 @@
 
 #include "nsTArray.h"
 #include "Point.h"
 #include "Polygon.h"
 #include "Triangle.h"
 
 using namespace mozilla::gfx;
 
-TEST(Polygon3D, TriangulateRectangle)
+TEST(Polygon, TriangulateRectangle)
 {
-  const Polygon3D p {
+  const Polygon p {
     Point3D(0.0f, 0.0f, 1.0f),
     Point3D(0.0f, 1.0f, 1.0f),
     Point3D(1.0f, 1.0f, 1.0f),
     Point3D(1.0f, 0.0f, 1.0f)
   };
 
   const nsTArray<Triangle> triangles = p.ToTriangles();
   const nsTArray<Triangle> expected = {
     Triangle(Point(0.0f, 0.0f), Point(0.0f, 1.0f), Point(1.0f, 1.0f)),
     Triangle(Point(0.0f, 0.0f), Point(1.0f, 1.0f), Point(1.0f, 0.0f))
   };
 
   AssertArrayEQ(triangles, expected);
 }
 
-TEST(Polygon3D, TriangulatePentagon)
+TEST(Polygon, TriangulatePentagon)
 {
-  const Polygon3D p {
+  const Polygon p {
     Point3D(0.0f, 0.0f, 1.0f),
     Point3D(0.0f, 1.0f, 1.0f),
     Point3D(0.5f, 1.5f, 1.0f),
     Point3D(1.0f, 1.0f, 1.0f),
     Point3D(1.0f, 0.0f, 1.0f)
   };
 
   const nsTArray<Triangle> triangles = p.ToTriangles();
@@ -47,97 +47,89 @@ TEST(Polygon3D, TriangulatePentagon)
     Triangle(Point(0.0f, 0.0f), Point(0.0f, 1.0f), Point(0.5f, 1.5f)),
     Triangle(Point(0.0f, 0.0f), Point(0.5f, 1.5f), Point(1.0f, 1.0f)),
     Triangle(Point(0.0f, 0.0f), Point(1.0f, 1.0f), Point(1.0f, 0.0f))
   };
 
   AssertArrayEQ(triangles, expected);
 }
 
-TEST(Polygon3D, ClipRectangle)
+void
+TestClipRect(const Polygon& aPolygon,
+             const Polygon& aExpected,
+             const Rect& aRect)
 {
-  Polygon3D clipped, expected;
+  const Polygon res = aPolygon.ClipPolygon(Polygon::FromRect(aRect));
+  EXPECT_TRUE(res == aExpected);
+}
 
-  Polygon3D polygon {
+TEST(Polygon, ClipRectangle)
+{
+  Polygon polygon {
     Point3D(0.0f, 0.0f, 0.0f),
     Point3D(0.0f, 1.0f, 0.0f),
     Point3D(1.0f, 1.0f, 0.0f),
     Point3D(1.0f, 0.0f, 0.0f)
   };
-
-  clipped = polygon.ClipPolygon(Rect(0.0f, 0.0f, 1.0f, 1.0f));
-  EXPECT_TRUE(clipped == polygon);
+  TestClipRect(polygon, polygon, Rect(0.0f, 0.0f, 1.0f, 1.0f));
 
-
-  clipped = polygon.ClipPolygon(Rect(0.0f, 0.0f, 0.8f, 0.8f));
-  expected = Polygon3D {
+  Polygon expected = Polygon {
     Point3D(0.0f, 0.0f, 0.0f),
     Point3D(0.0f, 0.8f, 0.0f),
     Point3D(0.8f, 0.8f, 0.0f),
     Point3D(0.8f, 0.0f, 0.0f)
   };
-  EXPECT_TRUE(clipped == expected);
-
+  TestClipRect(polygon, expected, Rect(0.0f, 0.0f, 0.8f, 0.8f));
 
-  clipped = polygon.ClipPolygon(Rect(0.2f, 0.2f, 0.8f, 0.8f));
-  expected = Polygon3D {
+  expected = Polygon {
     Point3D(0.2f, 0.2f, 0.0f),
     Point3D(0.2f, 1.0f, 0.0f),
     Point3D(1.0f, 1.0f, 0.0f),
     Point3D(1.0f, 0.2f, 0.0f)
   };
-  EXPECT_TRUE(clipped == expected);
-
+  TestClipRect(polygon, expected, Rect(0.2f, 0.2f, 0.8f, 0.8f));
 
-  clipped = polygon.ClipPolygon(Rect(0.2f, 0.2f, 0.6f, 0.6f));
-  expected = Polygon3D {
+  expected = Polygon {
     Point3D(0.2f, 0.2f, 0.0f),
     Point3D(0.2f, 0.8f, 0.0f),
     Point3D(0.8f, 0.8f, 0.0f),
     Point3D(0.8f, 0.2f, 0.0f)
   };
-  EXPECT_TRUE(clipped == expected);
+  TestClipRect(polygon, expected, Rect(0.2f, 0.2f, 0.6f, 0.6f));
 }
 
-TEST(Polygon3D, ClipTriangle)
+TEST(Polygon, ClipTriangle)
 {
-  Polygon3D clipped, expected;
-  const Polygon3D polygon {
+  Polygon clipped, expected;
+  const Polygon polygon {
     Point3D(0.0f, 0.0f, 0.0f),
     Point3D(0.0f, 1.0f, 0.0f),
     Point3D(1.0f, 1.0f, 0.0f)
   };
 
-  clipped = polygon.ClipPolygon(Rect(0.0f, 0.0f, 1.0f, 1.0f));
-  expected = Polygon3D {
+  expected = Polygon {
     Point3D(0.0f, 0.0f, 0.0f),
     Point3D(0.0f, 1.0f, 0.0f),
     Point3D(1.0f, 1.0f, 0.0f)
   };
-  EXPECT_TRUE(clipped == expected);
-
+  TestClipRect(polygon, expected, Rect(0.0f, 0.0f, 1.0f, 1.0f));
 
-  clipped = polygon.ClipPolygon(Rect(0.0f, 0.0f, 0.8f, 0.8f));
-  expected = Polygon3D {
+  expected = Polygon {
     Point3D(0.0f, 0.0f, 0.0f),
     Point3D(0.0f, 0.8f, 0.0f),
     Point3D(0.8f, 0.8f, 0.0f)
   };
-  EXPECT_TRUE(clipped == expected);
-
+  TestClipRect(polygon, expected, Rect(0.0f, 0.0f, 0.8f, 0.8f));
 
-  clipped = polygon.ClipPolygon(Rect(0.2f, 0.2f, 0.8f, 0.8f));
-  expected = Polygon3D {
+  expected = Polygon {
     Point3D(0.2f, 0.2f, 0.0f),
     Point3D(0.2f, 1.0f, 0.0f),
     Point3D(1.0f, 1.0f, 0.0f)
   };
-  EXPECT_TRUE(clipped == expected);
-
+  TestClipRect(polygon, expected, Rect(0.2f, 0.2f, 0.8f, 0.8f));
 
-  clipped = polygon.ClipPolygon(Rect(0.2f, 0.2f, 0.6f, 0.6f));
-  expected = Polygon3D {
+  expected = Polygon {
     Point3D(0.2f, 0.2f, 0.0f),
     Point3D(0.2f, 0.8f, 0.0f),
     Point3D(0.8f, 0.8f, 0.0f)
   };
-  EXPECT_TRUE(clipped == expected);
-}
+  TestClipRect(polygon, expected, Rect(0.2f, 0.2f, 0.6f, 0.6f));
+}
\ No newline at end of file