Bug 1632310 [wpt PR 23186] - Add test for computed versus resolved style., a=testonly
[gecko.git] / gfx / layers / BSPTree.cpp
blobd181b05e80d329e589b8ccc9b7ef5a123aeeda1f
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "BSPTree.h"
8 #include "mozilla/gfx/Polygon.h"
10 namespace mozilla {
11 namespace layers {
13 void BSPTree::BuildDrawOrder(BSPTreeNode* aNode,
14 nsTArray<LayerPolygon>& aLayers) const {
15 const gfx::Point4D& normal = aNode->First().GetNormal();
17 BSPTreeNode* front = aNode->front;
18 BSPTreeNode* back = aNode->back;
20 // Since the goal is to return the draw order from back to front, we reverse
21 // the traversal order if the current polygon is facing towards the camera.
22 const bool reverseOrder = normal.z > 0.0f;
24 if (reverseOrder) {
25 std::swap(front, back);
28 if (front) {
29 BuildDrawOrder(front, aLayers);
32 for (LayerPolygon& layer : aNode->layers) {
33 MOZ_ASSERT(layer.geometry);
35 if (layer.geometry->GetPoints().Length() >= 3) {
36 aLayers.AppendElement(std::move(layer));
40 if (back) {
41 BuildDrawOrder(back, aLayers);
45 void BSPTree::BuildTree(BSPTreeNode* aRoot, std::list<LayerPolygon>& aLayers) {
46 MOZ_ASSERT(!aLayers.empty());
48 aRoot->layers.push_back(std::move(aLayers.front()));
49 aLayers.pop_front();
51 if (aLayers.empty()) {
52 return;
55 const gfx::Polygon& plane = aRoot->First();
56 MOZ_ASSERT(!plane.IsEmpty());
58 const gfx::Point4D& planeNormal = plane.GetNormal();
59 const gfx::Point4D& planePoint = plane.GetPoints()[0];
61 std::list<LayerPolygon> backLayers, frontLayers;
62 for (LayerPolygon& layerPolygon : aLayers) {
63 const nsTArray<gfx::Point4D>& geometry = layerPolygon.geometry->GetPoints();
65 // Calculate the plane-point distances for the polygon classification.
66 size_t pos = 0, neg = 0;
67 nsTArray<float> distances = CalculatePointPlaneDistances(
68 geometry, planeNormal, planePoint, pos, neg);
70 // Back polygon
71 if (pos == 0 && neg > 0) {
72 backLayers.push_back(std::move(layerPolygon));
74 // Front polygon
75 else if (pos > 0 && neg == 0) {
76 frontLayers.push_back(std::move(layerPolygon));
78 // Coplanar polygon
79 else if (pos == 0 && neg == 0) {
80 aRoot->layers.push_back(std::move(layerPolygon));
82 // Polygon intersects with the splitting plane.
83 else if (pos > 0 && neg > 0) {
84 nsTArray<gfx::Point4D> backPoints, frontPoints;
85 // Clip the polygon against the plane. We reuse the previously calculated
86 // distances to find the plane-edge intersections.
87 ClipPointsWithPlane(geometry, planeNormal, distances, backPoints,
88 frontPoints);
90 const gfx::Point4D& normal = layerPolygon.geometry->GetNormal();
91 Layer* layer = layerPolygon.layer;
93 if (backPoints.Length() >= 3) {
94 backLayers.emplace_back(layer, std::move(backPoints), normal);
97 if (frontPoints.Length() >= 3) {
98 frontLayers.emplace_back(layer, std::move(frontPoints), normal);
103 if (!backLayers.empty()) {
104 aRoot->back = new (mPool) BSPTreeNode(mListPointers);
105 BuildTree(aRoot->back, backLayers);
108 if (!frontLayers.empty()) {
109 aRoot->front = new (mPool) BSPTreeNode(mListPointers);
110 BuildTree(aRoot->front, frontLayers);
114 } // namespace layers
115 } // namespace mozilla