Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/gfx/layers/BSPTree.cpp
Line
Count
Source (jump to first uncovered line)
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/. */
6
7
#include "BSPTree.h"
8
#include "mozilla/gfx/Polygon.h"
9
10
namespace mozilla {
11
namespace layers {
12
13
void
14
BSPTree::BuildDrawOrder(BSPTreeNode* aNode,
15
                        nsTArray<LayerPolygon>& aLayers) const
16
0
{
17
0
  const gfx::Point4D& normal = aNode->First().GetNormal();
18
0
19
0
  BSPTreeNode* front = aNode->front;
20
0
  BSPTreeNode* back = aNode->back;
21
0
22
0
  // Since the goal is to return the draw order from back to front, we reverse
23
0
  // the traversal order if the current polygon is facing towards the camera.
24
0
  const bool reverseOrder = normal.z > 0.0f;
25
0
26
0
  if (reverseOrder) {
27
0
    std::swap(front, back);
28
0
  }
29
0
30
0
  if (front) {
31
0
    BuildDrawOrder(front, aLayers);
32
0
  }
33
0
34
0
  for (LayerPolygon& layer : aNode->layers) {
35
0
    MOZ_ASSERT(layer.geometry);
36
0
37
0
    if (layer.geometry->GetPoints().Length() >= 3) {
38
0
      aLayers.AppendElement(std::move(layer));
39
0
    }
40
0
  }
41
0
42
0
  if (back) {
43
0
    BuildDrawOrder(back, aLayers);
44
0
  }
45
0
}
46
47
void
48
BSPTree::BuildTree(BSPTreeNode* aRoot,
49
                   std::list<LayerPolygon>& aLayers)
50
0
{
51
0
  MOZ_ASSERT(!aLayers.empty());
52
0
53
0
  aRoot->layers.push_back(std::move(aLayers.front()));
54
0
  aLayers.pop_front();
55
0
56
0
  if (aLayers.empty()) {
57
0
    return;
58
0
  }
59
0
60
0
  const gfx::Polygon& plane = aRoot->First();
61
0
  MOZ_ASSERT(!plane.IsEmpty());
62
0
63
0
  const gfx::Point4D& planeNormal = plane.GetNormal();
64
0
  const gfx::Point4D& planePoint = plane.GetPoints()[0];
65
0
66
0
  std::list<LayerPolygon> backLayers, frontLayers;
67
0
  for (LayerPolygon& layerPolygon : aLayers) {
68
0
    const nsTArray<gfx::Point4D>& geometry = layerPolygon.geometry->GetPoints();
69
0
70
0
    // Calculate the plane-point distances for the polygon classification.
71
0
    size_t pos = 0, neg = 0;
72
0
    nsTArray<float> distances =
73
0
      CalculatePointPlaneDistances(geometry, planeNormal, planePoint, pos, neg);
74
0
75
0
    // Back polygon
76
0
    if (pos == 0 && neg > 0) {
77
0
      backLayers.push_back(std::move(layerPolygon));
78
0
    }
79
0
    // Front polygon
80
0
    else if (pos > 0 && neg == 0) {
81
0
      frontLayers.push_back(std::move(layerPolygon));
82
0
    }
83
0
    // Coplanar polygon
84
0
    else if (pos == 0 && neg == 0) {
85
0
      aRoot->layers.push_back(std::move(layerPolygon));
86
0
    }
87
0
    // Polygon intersects with the splitting plane.
88
0
    else if (pos > 0 && neg > 0) {
89
0
      nsTArray<gfx::Point4D> backPoints, frontPoints;
90
0
      // Clip the polygon against the plane. We reuse the previously calculated
91
0
      // distances to find the plane-edge intersections.
92
0
      ClipPointsWithPlane(geometry, planeNormal, distances,
93
0
                          backPoints, frontPoints);
94
0
95
0
      const gfx::Point4D& normal = layerPolygon.geometry->GetNormal();
96
0
      Layer* layer = layerPolygon.layer;
97
0
98
0
      if (backPoints.Length() >= 3) {
99
0
        backLayers.emplace_back(layer, std::move(backPoints), normal);
100
0
      }
101
0
102
0
      if (frontPoints.Length() >= 3) {
103
0
        frontLayers.emplace_back(layer, std::move(frontPoints), normal);
104
0
      }
105
0
    }
106
0
  }
107
0
108
0
  if (!backLayers.empty()) {
109
0
    aRoot->back = new (mPool) BSPTreeNode(mListPointers);
110
0
    BuildTree(aRoot->back, backLayers);
111
0
  }
112
0
113
0
  if (!frontLayers.empty()) {
114
0
    aRoot->front = new (mPool) BSPTreeNode(mListPointers);
115
0
    BuildTree(aRoot->front, frontLayers);
116
0
  }
117
0
}
118
119
} // namespace layers
120
} // namespace mozilla