зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1351426 - Part 3: Refactor BSPTree to use list instead of deque r=kip
MozReview-Commit-ID: F4ezRzbGihI --HG-- extra : rebase_source : 6875c63a321a645e84d4cff3ccac71cc570b50a6
This commit is contained in:
Родитель
c17d5105ae
Коммит
a84879bcbd
|
@ -9,21 +9,14 @@
|
|||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
LayerPolygon PopFront(std::deque<LayerPolygon>& aLayers)
|
||||
{
|
||||
LayerPolygon layer = Move(aLayers.front());
|
||||
aLayers.pop_front();
|
||||
return layer;
|
||||
}
|
||||
|
||||
void
|
||||
BSPTree::BuildDrawOrder(const UniquePtr<BSPTreeNode>& aNode,
|
||||
BSPTree::BuildDrawOrder(BSPTreeNode* aNode,
|
||||
nsTArray<LayerPolygon>& aLayers) const
|
||||
{
|
||||
const gfx::Point4D& normal = aNode->First().GetNormal();
|
||||
|
||||
UniquePtr<BSPTreeNode> *front = &aNode->front;
|
||||
UniquePtr<BSPTreeNode> *back = &aNode->back;
|
||||
BSPTreeNode* front = aNode->front;
|
||||
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.
|
||||
|
@ -33,8 +26,8 @@ BSPTree::BuildDrawOrder(const UniquePtr<BSPTreeNode>& aNode,
|
|||
std::swap(front, back);
|
||||
}
|
||||
|
||||
if (*front) {
|
||||
BuildDrawOrder(*front, aLayers);
|
||||
if (front) {
|
||||
BuildDrawOrder(front, aLayers);
|
||||
}
|
||||
|
||||
for (LayerPolygon& layer : aNode->layers) {
|
||||
|
@ -45,22 +38,27 @@ BSPTree::BuildDrawOrder(const UniquePtr<BSPTreeNode>& aNode,
|
|||
}
|
||||
}
|
||||
|
||||
if (*back) {
|
||||
BuildDrawOrder(*back, aLayers);
|
||||
if (back) {
|
||||
BuildDrawOrder(back, aLayers);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
BSPTree::BuildTree(UniquePtr<BSPTreeNode>& aRoot,
|
||||
std::deque<LayerPolygon>& aLayers)
|
||||
BSPTree::BuildTree(BSPTreeNode* aRoot,
|
||||
std::list<LayerPolygon>& aLayers)
|
||||
{
|
||||
MOZ_ASSERT(!aLayers.empty());
|
||||
|
||||
aRoot->layers.push_back(Move(aLayers.front()));
|
||||
aLayers.pop_front();
|
||||
|
||||
if (aLayers.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
const gfx::Polygon& plane = aRoot->First();
|
||||
std::deque<LayerPolygon> backLayers, frontLayers;
|
||||
|
||||
std::list<LayerPolygon> backLayers, frontLayers;
|
||||
for (LayerPolygon& layerPolygon : aLayers) {
|
||||
const Maybe<gfx::Polygon>& geometry = layerPolygon.geometry;
|
||||
|
||||
|
@ -88,22 +86,22 @@ BSPTree::BuildTree(UniquePtr<BSPTreeNode>& aRoot,
|
|||
Layer *layer = layerPolygon.layer;
|
||||
|
||||
if (backPoints.Length() >= 3) {
|
||||
backLayers.push_back(LayerPolygon(layer, Move(backPoints), normal));
|
||||
backLayers.emplace_back(layer, Move(backPoints), normal);
|
||||
}
|
||||
|
||||
if (frontPoints.Length() >= 3) {
|
||||
frontLayers.push_back(LayerPolygon(layer, Move(frontPoints), normal));
|
||||
frontLayers.emplace_back(layer, Move(frontPoints), normal);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!backLayers.empty()) {
|
||||
aRoot->back.reset(new BSPTreeNode(PopFront(backLayers)));
|
||||
aRoot->back = new (mPool) BSPTreeNode();
|
||||
BuildTree(aRoot->back, backLayers);
|
||||
}
|
||||
|
||||
if (!frontLayers.empty()) {
|
||||
aRoot->front.reset(new BSPTreeNode(PopFront(frontLayers)));
|
||||
aRoot->front = new (mPool) BSPTreeNode();
|
||||
BuildTree(aRoot->front, frontLayers);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,12 +6,13 @@
|
|||
#ifndef MOZILLA_LAYERS_BSPTREE_H
|
||||
#define MOZILLA_LAYERS_BSPTREE_H
|
||||
|
||||
#include "mozilla/ArenaAllocator.h"
|
||||
#include "mozilla/gfx/Polygon.h"
|
||||
#include "mozilla/Move.h"
|
||||
#include "mozilla/UniquePtr.h"
|
||||
#include "nsTArray.h"
|
||||
|
||||
#include <deque>
|
||||
#include <list>
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
@ -25,37 +26,50 @@ struct LayerPolygon {
|
|||
|
||||
LayerPolygon(Layer *aLayer,
|
||||
gfx::Polygon&& aGeometry)
|
||||
: layer(aLayer), geometry(Some(aGeometry)) {}
|
||||
: layer(aLayer), geometry(Some(Move(aGeometry))) {}
|
||||
|
||||
LayerPolygon(Layer *aLayer,
|
||||
nsTArray<gfx::Point4D>&& aPoints,
|
||||
const gfx::Point4D& aNormal)
|
||||
: layer(aLayer), geometry(Some(gfx::Polygon(Move(aPoints), aNormal))) {}
|
||||
: layer(aLayer)
|
||||
{
|
||||
geometry.emplace(Move(aPoints), aNormal);
|
||||
}
|
||||
|
||||
Layer *layer;
|
||||
Maybe<gfx::Polygon> geometry;
|
||||
};
|
||||
|
||||
LayerPolygon PopFront(std::deque<LayerPolygon>& aLayers);
|
||||
/**
|
||||
* Allocate BSPTreeNodes from a memory arena to improve performance with
|
||||
* complex scenes.
|
||||
* The arena size of 4096 bytes was selected as an arbitrary power of two.
|
||||
* Depending on the platform, this size accommodates roughly 100 BSPTreeNodes.
|
||||
*/
|
||||
typedef mozilla::ArenaAllocator<4096, 8> BSPTreeArena;
|
||||
|
||||
// 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));
|
||||
}
|
||||
BSPTreeNode()
|
||||
: front(nullptr), back(nullptr) {}
|
||||
|
||||
const gfx::Polygon& First() const
|
||||
{
|
||||
MOZ_ASSERT(layers[0].geometry);
|
||||
return *layers[0].geometry;
|
||||
MOZ_ASSERT(!layers.empty());
|
||||
MOZ_ASSERT(layers.front().geometry);
|
||||
return *layers.front().geometry;
|
||||
}
|
||||
|
||||
UniquePtr<BSPTreeNode> front;
|
||||
UniquePtr<BSPTreeNode> back;
|
||||
std::deque<LayerPolygon> layers;
|
||||
static void* operator new(size_t aSize, BSPTreeArena& mPool)
|
||||
{
|
||||
return mPool.Allocate(aSize);
|
||||
}
|
||||
|
||||
BSPTreeNode* front;
|
||||
BSPTreeNode* back;
|
||||
std::list<LayerPolygon> layers;
|
||||
};
|
||||
|
||||
// BSPTree class takes a list of layers as an input and uses binary space
|
||||
|
@ -67,21 +81,17 @@ struct BSPTreeNode {
|
|||
// ftp://ftp.sgi.com/other/bspfaq/faq/bspfaq.html
|
||||
class BSPTree {
|
||||
public:
|
||||
// This constructor takes the ownership of layers in the given list.
|
||||
explicit BSPTree(std::deque<LayerPolygon>& aLayers)
|
||||
/**
|
||||
* The constructor modifies layers in the given list.
|
||||
*/
|
||||
explicit BSPTree(std::list<LayerPolygon>& aLayers)
|
||||
{
|
||||
MOZ_ASSERT(!aLayers.empty());
|
||||
mRoot.reset(new BSPTreeNode(PopFront(aLayers)));
|
||||
|
||||
mRoot = new (mPool) BSPTreeNode();
|
||||
BuildTree(mRoot, aLayers);
|
||||
}
|
||||
|
||||
// Returns the root node of the BSP tree.
|
||||
const UniquePtr<BSPTreeNode>& GetRoot() const
|
||||
{
|
||||
return mRoot;
|
||||
}
|
||||
|
||||
// Builds and returns the back-to-front draw order for the created BSP tree.
|
||||
nsTArray<LayerPolygon> GetDrawOrder() const
|
||||
{
|
||||
|
@ -91,14 +101,16 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
UniquePtr<BSPTreeNode> mRoot;
|
||||
BSPTreeArena mPool;
|
||||
BSPTreeNode* mRoot;
|
||||
|
||||
// BuildDrawOrder and BuildTree are called recursively. The depth of the
|
||||
// recursion depends on the amount of polygons and their intersections.
|
||||
void BuildDrawOrder(const UniquePtr<BSPTreeNode>& aNode,
|
||||
void BuildDrawOrder(BSPTreeNode* aNode,
|
||||
nsTArray<LayerPolygon>& aLayers) const;
|
||||
void BuildTree(UniquePtr<BSPTreeNode>& aRoot,
|
||||
std::deque<LayerPolygon>& aLayers);
|
||||
|
||||
void BuildTree(BSPTreeNode* aRoot,
|
||||
std::list<LayerPolygon>& aLayers);
|
||||
};
|
||||
|
||||
} // namespace layers
|
||||
|
|
|
@ -50,7 +50,7 @@
|
|||
#include "mozilla/Compression.h"
|
||||
#include "TreeTraversal.h" // for ForEachNode
|
||||
|
||||
#include <deque>
|
||||
#include <list>
|
||||
#include <set>
|
||||
|
||||
uint8_t gLayerManagerLayerBuilder;
|
||||
|
@ -1158,8 +1158,7 @@ ContainerLayer::Collect3DContextLeaves(nsTArray<Layer*>& aToSort)
|
|||
static nsTArray<LayerPolygon>
|
||||
SortLayersWithBSPTree(nsTArray<Layer*>& aArray)
|
||||
{
|
||||
std::deque<LayerPolygon> inputLayers;
|
||||
nsTArray<LayerPolygon> orderedLayers;
|
||||
std::list<LayerPolygon> inputLayers;
|
||||
|
||||
// Build a list of polygons to be sorted.
|
||||
for (Layer* layer : aArray) {
|
||||
|
@ -1189,12 +1188,13 @@ SortLayersWithBSPTree(nsTArray<Layer*>& aArray)
|
|||
}
|
||||
|
||||
if (inputLayers.empty()) {
|
||||
return orderedLayers;
|
||||
return nsTArray<LayerPolygon>();
|
||||
}
|
||||
|
||||
// Build a BSP tree from the list of polygons.
|
||||
BSPTree tree(inputLayers);
|
||||
orderedLayers = Move(tree.GetDrawOrder());
|
||||
|
||||
nsTArray<LayerPolygon> orderedLayers(tree.GetDrawOrder());
|
||||
|
||||
// Transform the polygons back to layer space.
|
||||
for (LayerPolygon& layerPolygon : orderedLayers) {
|
||||
|
|
|
@ -21,7 +21,7 @@ namespace {
|
|||
static void RunTest(std::deque<MozPolygon> aPolygons,
|
||||
std::deque<MozPolygon> aExpected)
|
||||
{
|
||||
std::deque<LayerPolygon> layers;
|
||||
std::list<LayerPolygon> layers;
|
||||
for (MozPolygon& polygon : aPolygons) {
|
||||
layers.push_back(LayerPolygon(nullptr, Move(polygon)));
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче