Move various static GrTriangulator functions into structs

Bug: skia:10419
Change-Id: I43fc724de1476cbfda95b9ddd3611ec2ec547a37
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/352900
Reviewed-by: Jim Van Verth <jvanverth@google.com>
Commit-Queue: Chris Dalton <csmartdalton@google.com>
This commit is contained in:
Chris Dalton 2021-01-11 20:05:00 -07:00 committed by Skia Commit-Bot
parent ace3f2939f
commit 24472afdb6
2 changed files with 66 additions and 68 deletions

View File

@ -23,7 +23,7 @@
#if TRIANGULATOR_LOGGING
#define TESS_LOG printf
#define DUMP_MESH(M) dump_mesh(M)
#define DUMP_MESH(M) (M).dump()
#else
#define TESS_LOG(...)
#define DUMP_MESH(M)
@ -213,7 +213,10 @@ typedef std::vector<SSEdge*> SSEdgeList;
void GrTriangulator::EdgeList::insert(Edge* edge, Edge* prev, Edge* next) {
list_insert<Edge, &Edge::fLeft, &Edge::fRight>(edge, prev, next, &fHead, &fTail);
}
void GrTriangulator::EdgeList::remove(Edge* edge) {
TESS_LOG("removing edge %g -> %g\n", edge->fTop->fID, edge->fBottom->fID);
SkASSERT(this->contains(edge));
list_remove<Edge, &Edge::fLeft, &Edge::fRight>(edge, &fHead, &fTail);
}
@ -570,17 +573,11 @@ Edge* GrTriangulator::makeEdge(Vertex* prev, Vertex* next, EdgeType type, const
return fAlloc.make<Edge>(top, bottom, winding, type);
}
static void remove_edge(Edge* edge, EdgeList* edges) {
TESS_LOG("removing edge %g -> %g\n", edge->fTop->fID, edge->fBottom->fID);
SkASSERT(edges->contains(edge));
edges->remove(edge);
}
static void insert_edge(Edge* edge, Edge* prev, EdgeList* edges) {
void EdgeList::insert(Edge* edge, Edge* prev) {
TESS_LOG("inserting edge %g -> %g\n", edge->fTop->fID, edge->fBottom->fID);
SkASSERT(!edges->contains(edge));
Edge* next = prev ? prev->fRight : edges->fHead;
edges->insert(edge, prev, next);
SkASSERT(!this->contains(edge));
Edge* next = prev ? prev->fRight : fHead;
this->insert(edge, prev, next);
}
static void find_enclosing_edges(Vertex* v, EdgeList* edges, Edge** left, Edge** right) {
@ -601,42 +598,40 @@ static void find_enclosing_edges(Vertex* v, EdgeList* edges, Edge** left, Edge**
*right = next;
}
static void insert_edge_above(Edge* edge, Vertex* v, const Comparator& c) {
if (edge->fTop->fPoint == edge->fBottom->fPoint ||
c.sweep_lt(edge->fBottom->fPoint, edge->fTop->fPoint)) {
void GrTriangulator::Edge::insertAbove(Vertex* v, const Comparator& c) {
if (fTop->fPoint == fBottom->fPoint ||
c.sweep_lt(fBottom->fPoint, fTop->fPoint)) {
return;
}
TESS_LOG("insert edge (%g -> %g) above vertex %g\n",
edge->fTop->fID, edge->fBottom->fID, v->fID);
TESS_LOG("insert edge (%g -> %g) above vertex %g\n", fTop->fID, fBottom->fID, v->fID);
Edge* prev = nullptr;
Edge* next;
for (next = v->fFirstEdgeAbove; next; next = next->fNextEdgeAbove) {
if (next->isRightOf(edge->fTop)) {
if (next->isRightOf(fTop)) {
break;
}
prev = next;
}
list_insert<Edge, &Edge::fPrevEdgeAbove, &Edge::fNextEdgeAbove>(
edge, prev, next, &v->fFirstEdgeAbove, &v->fLastEdgeAbove);
this, prev, next, &v->fFirstEdgeAbove, &v->fLastEdgeAbove);
}
static void insert_edge_below(Edge* edge, Vertex* v, const Comparator& c) {
if (edge->fTop->fPoint == edge->fBottom->fPoint ||
c.sweep_lt(edge->fBottom->fPoint, edge->fTop->fPoint)) {
void GrTriangulator::Edge::insertBelow(Vertex* v, const Comparator& c) {
if (fTop->fPoint == fBottom->fPoint ||
c.sweep_lt(fBottom->fPoint, fTop->fPoint)) {
return;
}
TESS_LOG("insert edge (%g -> %g) below vertex %g\n",
edge->fTop->fID, edge->fBottom->fID, v->fID);
TESS_LOG("insert edge (%g -> %g) below vertex %g\n", fTop->fID, fBottom->fID, v->fID);
Edge* prev = nullptr;
Edge* next;
for (next = v->fFirstEdgeBelow; next; next = next->fNextEdgeBelow) {
if (next->isRightOf(edge->fBottom)) {
if (next->isRightOf(fBottom)) {
break;
}
prev = next;
}
list_insert<Edge, &Edge::fPrevEdgeBelow, &Edge::fNextEdgeBelow>(
edge, prev, next, &v->fFirstEdgeBelow, &v->fLastEdgeBelow);
this, prev, next, &v->fFirstEdgeBelow, &v->fLastEdgeBelow);
}
static void remove_edge_above(Edge* edge) {
@ -655,10 +650,9 @@ static void remove_edge_below(Edge* edge) {
edge, &edge->fTop->fFirstEdgeBelow, &edge->fTop->fLastEdgeBelow);
}
static void disconnect(Edge* edge)
{
remove_edge_above(edge);
remove_edge_below(edge);
void GrTriangulator::Edge::disconnect() {
remove_edge_above(this);
remove_edge_below(this);
}
static void merge_collinear_edges(Edge* edge, EdgeList* activeEdges, Vertex** current,
@ -673,11 +667,11 @@ static void rewind(EdgeList* activeEdges, Vertex** current, Vertex* dst, const C
while (v != dst) {
v = v->fPrev;
for (Edge* e = v->fFirstEdgeBelow; e; e = e->fNextEdgeBelow) {
remove_edge(e, activeEdges);
activeEdges->remove(e);
}
Edge* leftEdge = v->fLeftEnclosingEdge;
for (Edge* e = v->fFirstEdgeAbove; e; e = e->fNextEdgeAbove) {
insert_edge(e, leftEdge, activeEdges);
activeEdges->insert(e, leftEdge);
leftEdge = e;
Vertex* top = e->fTop;
if (c.sweep_lt(top->fPoint, dst->fPoint) &&
@ -733,7 +727,7 @@ static void set_top(Edge* edge, Vertex* v, EdgeList* activeEdges, Vertex** curre
remove_edge_below(edge);
edge->fTop = v;
edge->recompute();
insert_edge_below(edge, v, c);
edge->insertBelow(v, c);
rewind_if_necessary(edge, activeEdges, current, c);
merge_collinear_edges(edge, activeEdges, current, c);
}
@ -743,7 +737,7 @@ static void set_bottom(Edge* edge, Vertex* v, EdgeList* activeEdges, Vertex** cu
remove_edge_above(edge);
edge->fBottom = v;
edge->recompute();
insert_edge_above(edge, v, c);
edge->insertAbove(v, c);
rewind_if_necessary(edge, activeEdges, current, c);
merge_collinear_edges(edge, activeEdges, current, c);
}
@ -756,7 +750,7 @@ static void merge_edges_above(Edge* edge, Edge* other, EdgeList* activeEdges, Ve
edge->fBottom->fPoint.fX, edge->fBottom->fPoint.fY);
rewind(activeEdges, current, edge->fTop, c);
other->fWinding += edge->fWinding;
disconnect(edge);
edge->disconnect();
edge->fTop = edge->fBottom = nullptr;
} else if (c.sweep_lt(edge->fTop->fPoint, other->fTop->fPoint)) {
rewind(activeEdges, current, edge->fTop, c);
@ -777,7 +771,7 @@ static void merge_edges_below(Edge* edge, Edge* other, EdgeList* activeEdges, Ve
edge->fBottom->fPoint.fX, edge->fBottom->fPoint.fY);
rewind(activeEdges, current, edge->fTop, c);
other->fWinding += edge->fWinding;
disconnect(edge);
edge->disconnect();
edge->fTop = edge->fBottom = nullptr;
} else if (c.sweep_lt(edge->fBottom->fPoint, other->fBottom->fPoint)) {
rewind(activeEdges, current, other->fTop, c);
@ -851,8 +845,8 @@ bool GrTriangulator::splitEdge(Edge* edge, Vertex* v, EdgeList* activeEdges, Ver
set_bottom(edge, v, activeEdges, current, c);
}
Edge* newEdge = fAlloc.make<Edge>(top, bottom, winding, edge->fType);
insert_edge_below(newEdge, top, c);
insert_edge_above(newEdge, bottom, c);
newEdge->insertBelow(top, c);
newEdge->insertAbove(bottom, c);
merge_collinear_edges(newEdge, activeEdges, current, c);
return true;
}
@ -896,8 +890,8 @@ Edge* GrTriangulator::makeConnectingEdge(Vertex* prev, Vertex* next, EdgeType ty
return nullptr;
}
Edge* edge = this->makeEdge(prev, next, type, c);
insert_edge_below(edge, edge->fTop, c);
insert_edge_above(edge, edge->fBottom, c);
edge->insertBelow(edge->fTop, c);
edge->insertAbove(edge->fBottom, c);
edge->fWinding *= windingScale;
merge_collinear_edges(edge, nullptr, nullptr, c);
return edge;
@ -1181,8 +1175,8 @@ static void merge_sort(VertexList* vertices) {
}
#if TRIANGULATOR_LOGGING
static void dump_mesh(const VertexList& mesh) {
for (Vertex* v = mesh.fHead; v; v = v->fNext) {
void VertexList::dump() {
for (Vertex* v = fHead; v; v = v->fNext) {
TESS_LOG("vertex %g (%g, %g) alpha %d", v->fID, v->fPoint.fX, v->fPoint.fY, v->fAlpha);
if (Vertex* p = v->fPartner) {
TESS_LOG(", partner %g (%g, %g) alpha %d\n",
@ -1256,16 +1250,12 @@ static void validate_edge_list(EdgeList* edges, const Comparator& c) {
// Stage 4: Simplify the mesh by inserting new vertices at intersecting edges.
static bool connected(Vertex* v) {
return v->fFirstEdgeAbove || v->fFirstEdgeBelow;
}
GrTriangulator::SimplifyResult GrTriangulator::simplify(VertexList* mesh, const Comparator& c) {
TESS_LOG("simplifying complex polygons\n");
EdgeList activeEdges;
auto result = SimplifyResult::kAlreadySimple;
for (Vertex* v = mesh->fHead; v != nullptr; v = v->fNext) {
if (!connected(v)) {
if (!v->isConnected()) {
continue;
}
Edge* leftEnclosingEdge;
@ -1308,11 +1298,11 @@ GrTriangulator::SimplifyResult GrTriangulator::simplify(VertexList* mesh, const
validate_edge_list(&activeEdges, c);
#endif
for (Edge* e = v->fFirstEdgeAbove; e; e = e->fNextEdgeAbove) {
remove_edge(e, &activeEdges);
activeEdges.remove(e);
}
Edge* leftEdge = leftEnclosingEdge;
for (Edge* e = v->fFirstEdgeBelow; e; e = e->fNextEdgeBelow) {
insert_edge(e, leftEdge, &activeEdges);
activeEdges.insert(e, leftEdge);
leftEdge = e;
}
}
@ -1331,7 +1321,7 @@ Poly* GrTriangulator::tessellate(const VertexList& vertices, const Comparator&)
EdgeList activeEdges;
Poly* polys = nullptr;
for (Vertex* v = vertices.fHead; v != nullptr; v = v->fNext) {
if (!connected(v)) {
if (!v->isConnected()) {
continue;
}
#if TRIANGULATOR_LOGGING
@ -1374,7 +1364,7 @@ Poly* GrTriangulator::tessellate(const VertexList& vertices, const Comparator&)
}
for (Edge* e = v->fFirstEdgeAbove; e != v->fLastEdgeAbove; e = e->fNextEdgeAbove) {
Edge* rightEdge = e->fNextEdgeAbove;
remove_edge(e, &activeEdges);
activeEdges.remove(e);
if (e->fRightPoly) {
e->fRightPoly->addEdge(e, kLeft_Side, fAlloc);
}
@ -1382,7 +1372,7 @@ Poly* GrTriangulator::tessellate(const VertexList& vertices, const Comparator&)
rightEdge->fLeftPoly->addEdge(e, kRight_Side, fAlloc);
}
}
remove_edge(v->fLastEdgeAbove, &activeEdges);
activeEdges.remove(v->fLastEdgeAbove);
if (!v->fFirstEdgeBelow) {
if (leftPoly && rightPoly && leftPoly != rightPoly) {
SkASSERT(leftPoly->fPartner == nullptr && rightPoly->fPartner == nullptr);
@ -1413,10 +1403,10 @@ Poly* GrTriangulator::tessellate(const VertexList& vertices, const Comparator&)
}
Edge* leftEdge = v->fFirstEdgeBelow;
leftEdge->fLeftPoly = leftPoly;
insert_edge(leftEdge, leftEnclosingEdge, &activeEdges);
activeEdges.insert(leftEdge, leftEnclosingEdge);
for (Edge* rightEdge = leftEdge->fNextEdgeBelow; rightEdge;
rightEdge = rightEdge->fNextEdgeBelow) {
insert_edge(rightEdge, leftEdge, &activeEdges);
activeEdges.insert(rightEdge, leftEdge);
int winding = leftEdge->fLeftPoly ? leftEdge->fLeftPoly->fWinding : 0;
winding += leftEdge->fWinding;
if (winding != 0) {
@ -1447,7 +1437,7 @@ void GrAATriangulator::removeNonBoundaryEdges(const VertexList& mesh) {
TESS_LOG("removing non-boundary edges\n");
EdgeList activeEdges;
for (Vertex* v = mesh.fHead; v != nullptr; v = v->fNext) {
if (!connected(v)) {
if (!v->isConnected()) {
continue;
}
Edge* leftEnclosingEdge;
@ -1457,10 +1447,10 @@ void GrAATriangulator::removeNonBoundaryEdges(const VertexList& mesh) {
apply_fill_type(fPath.getFillType(), leftEnclosingEdge->fWinding);
for (Edge* e = v->fFirstEdgeAbove; e;) {
Edge* next = e->fNextEdgeAbove;
remove_edge(e, &activeEdges);
activeEdges.remove(e);
bool filled = apply_fill_type(fPath.getFillType(), e->fWinding);
if (filled == prevFilled) {
disconnect(e);
e->disconnect();
}
prevFilled = filled;
e = next;
@ -1470,7 +1460,7 @@ void GrAATriangulator::removeNonBoundaryEdges(const VertexList& mesh) {
if (prev) {
e->fWinding += prev->fWinding;
}
insert_edge(e, prev, &activeEdges);
activeEdges.insert(e, prev);
prev = e;
}
}
@ -1499,8 +1489,8 @@ void GrAATriangulator::simplifyBoundary(EdgeList* boundary, const Comparator& c)
get_edge_normal(e, &normal);
constexpr double kQuarterPixelSq = 0.25f * 0.25f;
if (prev == next) {
remove_edge(prevEdge, boundary);
remove_edge(e, boundary);
boundary->remove(prevEdge);
boundary->remove(e);
prevEdge = boundary->fTail;
e = boundary->fHead;
if (prevEdge) {
@ -1513,9 +1503,9 @@ void GrAATriangulator::simplifyBoundary(EdgeList* boundary, const Comparator& c)
join->fLine.normalize();
join->fLine = join->fLine * join->fWinding;
}
insert_edge(join, e, boundary);
remove_edge(prevEdge, boundary);
remove_edge(e, boundary);
boundary->insert(join, e);
boundary->remove(prevEdge);
boundary->remove(e);
if (join->fLeft && join->fRight) {
prevEdge = join->fLeft;
e = join;
@ -1618,7 +1608,7 @@ bool GrAATriangulator::collapseOverlapRegions(VertexList* mesh, const Comparator
SSVertexMap ssVertices;
SSEdgeList ssEdges;
for (Vertex* v = mesh->fHead; v != nullptr; v = v->fNext) {
if (!connected(v)) {
if (!v->isConnected()) {
continue;
}
Edge* leftEnclosingEdge;
@ -1626,7 +1616,7 @@ bool GrAATriangulator::collapseOverlapRegions(VertexList* mesh, const Comparator
find_enclosing_edges(v, &activeEdges, &leftEnclosingEdge, &rightEnclosingEdge);
for (Edge* e = v->fLastEdgeAbove; e && e != leftEnclosingEdge;) {
Edge* prev = e->fPrevEdgeAbove ? e->fPrevEdgeAbove : leftEnclosingEdge;
remove_edge(e, &activeEdges);
activeEdges.remove(e);
bool leftOverlap = prev && is_overlap_edge(prev);
bool rightOverlap = is_overlap_edge(e);
bool isOuterBoundary = e->fType == EdgeType::kOuter &&
@ -1637,7 +1627,7 @@ bool GrAATriangulator::collapseOverlapRegions(VertexList* mesh, const Comparator
if (leftOverlap && rightOverlap) {
TESS_LOG("found interior overlap edge %g -> %g, disconnecting\n",
e->fTop->fID, e->fBottom->fID);
disconnect(e);
e->disconnect();
} else if (leftOverlap || rightOverlap) {
TESS_LOG("found overlap edge %g -> %g%s\n",
e->fTop->fID, e->fBottom->fID,
@ -1658,7 +1648,7 @@ bool GrAATriangulator::collapseOverlapRegions(VertexList* mesh, const Comparator
ssPrev->fNext = ssNext->fPrev = ssEdge;
this->makeEvent(ssEdge, &events);
if (!isOuterBoundary) {
disconnect(e);
e->disconnect();
}
}
e = prev;
@ -1668,7 +1658,7 @@ bool GrAATriangulator::collapseOverlapRegions(VertexList* mesh, const Comparator
if (prev) {
e->fWinding += prev->fWinding;
}
insert_edge(e, prev, &activeEdges);
activeEdges.insert(e, prev);
prev = e;
}
}
@ -1893,7 +1883,7 @@ void GrAATriangulator::extractBoundary(EdgeList* boundary, Edge* e) {
down = true;
}
}
disconnect(e);
e->disconnect();
e = next;
} while (e && (down ? e->fTop : e->fBottom) != start);
}

View File

@ -232,6 +232,7 @@ struct GrTriangulator::Vertex {
#if TRIANGULATOR_LOGGING
float fID; // Identifier used for logging.
#endif
bool isConnected() const { return this->fFirstEdgeAbove || this->fFirstEdgeBelow; }
};
struct GrTriangulator::VertexList {
@ -261,6 +262,9 @@ struct GrTriangulator::VertexList {
fHead->fPrev = fTail;
}
}
#if TRIANGULATOR_LOGGING
void dump();
#endif
};
// A line equation in implicit form. fA * x + fB * y + fC = 0, for all points (x, y) on the line.
@ -357,6 +361,9 @@ struct GrTriangulator::Edge {
bool isRightOf(Vertex* v) const { return fLine.dist(v->fPoint) < 0.0; }
bool isLeftOf(Vertex* v) const { return fLine.dist(v->fPoint) > 0.0; }
void recompute() { fLine = Line(fTop, fBottom); }
void insertAbove(Vertex*, const Comparator&);
void insertBelow(Vertex*, const Comparator&);
void disconnect();
bool intersect(const Edge& other, SkPoint* p, uint8_t* alpha = nullptr) const;
};
@ -365,6 +372,7 @@ struct GrTriangulator::EdgeList {
Edge* fHead;
Edge* fTail;
void insert(Edge* edge, Edge* prev, Edge* next);
void insert(Edge* edge, Edge* prev);
void append(Edge* e) { insert(e, fTail, nullptr); }
void remove(Edge* edge);
void removeAll() {