GrTessellator: refactor, cleanup, add logging.

No user-visible effect.

Bug: skia:
Change-Id: Ibdc31027f51e5fff6b1a22de8de9441d7bd80b90
Reviewed-on: https://skia-review.googlesource.com/86561
Reviewed-by: Jim Van Verth <jvanverth@google.com>
Commit-Queue: Stephen White <senorblanco@chromium.org>
This commit is contained in:
Stephen White 2017-12-18 10:52:44 -05:00 committed by Skia Commit-Bot
parent 28f89389f0
commit 95152e1c83

View File

@ -215,9 +215,9 @@ inline void* emit_vertex(Vertex* v, const AAParams* aaParams, void* data) {
}
void* emit_triangle(Vertex* v0, Vertex* v1, Vertex* v2, const AAParams* aaParams, void* data) {
LOG("emit_triangle (%g, %g) %d\n", v0->fPoint.fX, v0->fPoint.fY, v0->fAlpha);
LOG(" (%g, %g) %d\n", v1->fPoint.fX, v1->fPoint.fY, v1->fAlpha);
LOG(" (%g, %g) %d\n", v2->fPoint.fX, v2->fPoint.fY, v2->fAlpha);
LOG("emit_triangle %g (%g, %g) %d\n", v0->fID, v0->fPoint.fX, v0->fPoint.fY, v0->fAlpha);
LOG(" %g (%g, %g) %d\n", v1->fID, v1->fPoint.fX, v1->fPoint.fY, v1->fAlpha);
LOG(" %g (%g, %g) %d\n", v2->fID, v2->fPoint.fX, v2->fPoint.fY, v2->fAlpha);
#if TESSELLATOR_WIREFRAME
data = emit_vertex(v0, aaParams, data);
data = emit_vertex(v1, aaParams, data);
@ -293,7 +293,7 @@ struct Line {
}
// Compute the intersection of two (infinite) Lines.
bool intersect(const Line& other, SkPoint* point) {
bool intersect(const Line& other, SkPoint* point) const {
double denom = fA * other.fB - fB * other.fA;
if (denom == 0.0) {
return false;
@ -379,7 +379,7 @@ struct Edge {
void recompute() {
fLine = Line(fTop, fBottom);
}
bool intersect(const Edge& other, SkPoint* p, uint8_t* alpha = nullptr) {
bool intersect(const Edge& other, SkPoint* p, uint8_t* alpha = nullptr) const {
LOG("intersecting %g -> %g with %g -> %g\n",
fTop->fID, fBottom->fID,
other.fTop->fID, other.fBottom->fID);
@ -1090,6 +1090,38 @@ bool out_of_range_and_collinear(const SkPoint& p, Edge* edge, Comparator& c) {
return false;
}
Vertex* create_sorted_vertex(const SkPoint& p, uint8_t alpha, VertexList* mesh,
Vertex* reference, Comparator& c, SkArenaAlloc& alloc) {
Vertex* prevV = reference;
while (prevV && c.sweep_lt(p, prevV->fPoint)) {
prevV = prevV->fPrev;
}
Vertex* nextV = prevV ? prevV->fNext : mesh->fHead;
while (nextV && c.sweep_lt(nextV->fPoint, p)) {
prevV = nextV;
nextV = nextV->fNext;
}
Vertex* v;
if (prevV && coincident(prevV->fPoint, p)) {
v = prevV;
} else if (nextV && coincident(nextV->fPoint, p)) {
v = nextV;
} else {
v = alloc.make<Vertex>(p, alpha);
#if LOGGING_ENABLED
if (!prevV) {
v->fID = mesh->fHead->fID - 1.0f;
} else if (!nextV) {
v->fID = mesh->fTail->fID + 1.0f;
} else {
v->fID = (prevV->fID + nextV->fID) * 0.5f;
}
#endif
mesh->insert(v, prevV, nextV);
}
return v;
}
bool check_for_intersection(Edge* edge, Edge* other, EdgeList* activeEdges, Vertex** current,
VertexList* mesh, Comparator& c, SkArenaAlloc& alloc) {
if (!edge || !other) {
@ -1121,29 +1153,7 @@ bool check_for_intersection(Edge* edge, Edge* other, EdgeList* activeEdges, Vert
} else if (p == other->fBottom->fPoint) {
v = other->fBottom;
} else {
Vertex* prevV = top;
Vertex* nextV = top ? top->fNext : mesh->fHead;
while (nextV && c.sweep_lt(nextV->fPoint, p)) {
prevV = nextV;
nextV = nextV->fNext;
}
if (prevV && coincident(prevV->fPoint, p)) {
v = prevV;
} else if (nextV && coincident(nextV->fPoint, p)) {
v = nextV;
} else {
v = alloc.make<Vertex>(p, alpha);
#if LOGGING_ENABLED
if (!prevV) {
v->fID = mesh->fHead->fID - 1.0f;
} else if (!nextV) {
v->fID = mesh->fTail->fID + 1.0f;
} else {
v->fID = (prevV->fID + nextV->fID) * 0.5f;
}
#endif
mesh->insert(v, prevV, nextV);
}
v = create_sorted_vertex(p, alpha, mesh, top, c, alloc);
}
rewind(activeEdges, current, top ? top : v, c);
split_edge(edge, v, activeEdges, current, c, alloc);
@ -1283,6 +1293,25 @@ void merge_sort(VertexList* vertices) {
sorted_merge<sweep_lt>(&front, &back, vertices);
}
void dump_mesh(const VertexList& mesh) {
#if LOGGING_ENABLED
for (Vertex* v = mesh.fHead; v; v = v->fNext) {
LOG("vertex %g (%g, %g) alpha %d", v->fID, v->fPoint.fX, v->fPoint.fY, v->fAlpha);
if (Vertex* p = v->fPartner) {
LOG(", partner %g (%g, %g) alpha %d\n", p->fID, p->fPoint.fX, p->fPoint.fY, p->fAlpha);
} else {
LOG(", null partner\n");
}
for (Edge* e = v->fFirstEdgeAbove; e; e = e->fNextEdgeAbove) {
LOG(" edge %g -> %g, winding %d\n", e->fTop->fID, e->fBottom->fID, e->fWinding);
}
for (Edge* e = v->fFirstEdgeBelow; e; e = e->fNextEdgeBelow) {
LOG(" edge %g -> %g, winding %d\n", e->fTop->fID, e->fBottom->fID, e->fWinding);
}
}
#endif
}
// Stage 4: Simplify the mesh by inserting new vertices at intersecting edges.
void simplify(VertexList* mesh, Comparator& c, SkArenaAlloc& alloc) {
@ -1390,7 +1419,7 @@ bool is_complex(const VertexList& vertices) {
// Stage 5: Tessellate the simplified mesh into monotone polygons.
Poly* tessellate(const VertexList& vertices, SkArenaAlloc& alloc) {
LOG("tessellating simple polygons\n");
LOG("\ntessellating simple polygons\n");
EdgeList activeEdges;
Poly* polys = nullptr;
for (Vertex* v = vertices.fHead; v != nullptr; v = v->fNext) {
@ -1658,6 +1687,7 @@ void stroke_boundary(EdgeList* boundary, VertexList* innerMesh, VertexList* oute
}
void extract_boundary(EdgeList* boundary, Edge* e, SkPath::FillType fillType, SkArenaAlloc& alloc) {
LOG("\nextracting boundary\n");
bool down = apply_fill_type(fillType, e->fWinding);
while (e) {
e->fWinding = down ? 1 : -1;
@ -1758,10 +1788,15 @@ Poly* contours_to_polys(VertexList* contours, int contourCnt, SkPath::FillType f
if (is_complex(innerMesh) || is_complex(*outerMesh)) {
LOG("found complex mesh; taking slow path\n");
VertexList aaMesh;
LOG("\ninner mesh after:\n");
dump_mesh(innerMesh);
LOG("\nouter mesh after:\n");
dump_mesh(*outerMesh);
connect_partners(outerMesh, c, alloc);
sorted_merge(&innerMesh, outerMesh, &aaMesh, c);
merge_coincident_vertices(&aaMesh, c, alloc);
simplify(&aaMesh, c, alloc);
dump_mesh(aaMesh);
outerMesh->fHead = outerMesh->fTail = nullptr;
return tessellate(aaMesh, alloc);
} else {