From: Stephen White Date: Mon, 30 Jan 2017 19:31:31 +0000 (-0500) Subject: GrTessellator (AA): improve AA quality for near-overlapping paths. X-Git-Tag: accepted/tizen/5.0/unified/20181102.025319~55^2~578 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=56158ae600a73ac2e74f5a5862de0fab466b52b6;p=platform%2Fupstream%2FlibSkiaSharp.git GrTessellator (AA): improve AA quality for near-overlapping paths. When path features are very close together, the outer contours can overlap. This causes the connector edges (the ones joining the inner and outer vertices) to intersect other edges. Lerping the alpha along the connector edge gives us a good approximation of the coverage at that point. BUG=skia: Change-Id: I56bcc570fc185344c5f84d11ef995d3940a08793 Reviewed-on: https://skia-review.googlesource.com/7701 Reviewed-by: Brian Salomon Commit-Queue: Stephan White --- diff --git a/src/gpu/GrTessellator.cpp b/src/gpu/GrTessellator.cpp index 981f11b..9b7aed0 100644 --- a/src/gpu/GrTessellator.cpp +++ b/src/gpu/GrTessellator.cpp @@ -365,7 +365,7 @@ struct Edge { void recompute() { fLine = Line(fTop, fBottom); } - bool intersect(const Edge& other, SkPoint* p) { + bool intersect(const Edge& other, SkPoint* p, uint8_t* alpha = nullptr) { LOG("intersecting %g -> %g with %g -> %g\n", fTop->fID, fBottom->fID, other.fTop->fID, other.fBottom->fID); @@ -390,6 +390,15 @@ struct Edge { SkASSERT(s >= 0.0 && s <= 1.0); p->fX = SkDoubleToScalar(fTop->fPoint.fX - s * fLine.fB); p->fY = SkDoubleToScalar(fTop->fPoint.fY + s * fLine.fA); + if (alpha) { + if (fType == Type::kInner || other.fType == Type::kInner) { + *alpha = 255; + } else if (fType == Type::kOuter && other.fType == Type::kOuter) { + *alpha = 0; + } else { + *alpha = (1.0 - s) * fTop->fAlpha + s * fBottom->fAlpha; + } + } return true; } }; @@ -1066,7 +1075,7 @@ void merge_vertices(Vertex* src, Vertex* dst, VertexList* mesh, Comparator& c, } uint8_t max_edge_alpha(Edge* a, Edge* b) { - if (a->fType == Edge::Type::kInner && b->fType == Edge::Type::kInner) { + if (a->fType == Edge::Type::kInner || b->fType == Edge::Type::kInner) { return 255; } else if (a->fType == Edge::Type::kOuter && b->fType == Edge::Type::kOuter) { return 0; @@ -1078,11 +1087,12 @@ uint8_t max_edge_alpha(Edge* a, Edge* b) { Vertex* check_for_intersection(Edge* edge, Edge* other, EdgeList* activeEdges, Comparator& c, SkChunkAlloc& alloc) { - SkPoint p; if (!edge || !other) { return nullptr; } - if (edge->intersect(*other, &p)) { + SkPoint p; + uint8_t alpha; + if (edge->intersect(*other, &p, &alpha)) { Vertex* v; LOG("found intersection, pt is %g, %g\n", p.fX, p.fY); if (p == edge->fTop->fPoint || c.sweep_lt(p, edge->fTop->fPoint)) { @@ -1111,7 +1121,6 @@ Vertex* check_for_intersection(Edge* edge, Edge* other, EdgeList* activeEdges, C } else if (coincident(nextV->fPoint, p)) { v = nextV; } else { - uint8_t alpha = max_edge_alpha(edge, other); v = ALLOC_NEW(Vertex, (p, alpha), alloc); LOG("inserting between %g (%g, %g) and %g (%g, %g)\n", prevV->fID, prevV->fPoint.fX, prevV->fPoint.fY,