GrTessellator: yet another out-of-range splitting fix.
It's actually possible for an intersection to be out-of-range on both the intersected edges (e.g., below both bottom points), because floating point. So we need to clamp against both edges. Bug: 846014 Change-Id: I9fe25a1fcd3b5242af7b1ee36b17f1e968aeb836 Reviewed-on: https://skia-review.googlesource.com/132323 Reviewed-by: Brian Salomon <bsalomon@google.com> Commit-Queue: Stephen White <senorblanco@chromium.org>
This commit is contained in:
parent
e2aa7b6a55
commit
e62999f6ef
@ -1175,6 +1175,16 @@ bool nearly_flat(Comparator& c, Edge* edge) {
|
||||
return fabs(primaryDiff) < std::numeric_limits<float>::epsilon();
|
||||
}
|
||||
|
||||
SkPoint clamp(SkPoint p, SkPoint min, SkPoint max, Comparator& c) {
|
||||
if (c.sweep_lt(p, min)) {
|
||||
return min;
|
||||
} else if (c.sweep_lt(max, p)) {
|
||||
return max;
|
||||
} else {
|
||||
return p;
|
||||
}
|
||||
}
|
||||
|
||||
bool check_for_intersection(Edge* edge, Edge* other, EdgeList* activeEdges, Vertex** current,
|
||||
VertexList* mesh, Comparator& c, SkArenaAlloc& alloc) {
|
||||
if (!edge || !other) {
|
||||
@ -1191,15 +1201,13 @@ bool check_for_intersection(Edge* edge, Edge* other, EdgeList* activeEdges, Vert
|
||||
while (top && c.sweep_lt(p, top->fPoint)) {
|
||||
top = top->fPrev;
|
||||
}
|
||||
if (c.sweep_lt(p, edge->fTop->fPoint) && !nearly_flat(c, edge)) {
|
||||
v = edge->fTop;
|
||||
} else if (c.sweep_lt(edge->fBottom->fPoint, p) && !nearly_flat(c, edge)) {
|
||||
v = edge->fBottom;
|
||||
} else if (c.sweep_lt(p, other->fTop->fPoint) && !nearly_flat(c, other)) {
|
||||
v = other->fTop;
|
||||
} else if (c.sweep_lt(other->fBottom->fPoint, p) && !nearly_flat(c, other)) {
|
||||
v = other->fBottom;
|
||||
} else if (p == edge->fTop->fPoint) {
|
||||
if (!nearly_flat(c, edge)) {
|
||||
p = clamp(p, edge->fTop->fPoint, edge->fBottom->fPoint, c);
|
||||
}
|
||||
if (!nearly_flat(c, other)) {
|
||||
p = clamp(p, other->fTop->fPoint, other->fBottom->fPoint, c);
|
||||
}
|
||||
if (p == edge->fTop->fPoint) {
|
||||
v = edge->fTop;
|
||||
} else if (p == edge->fBottom->fPoint) {
|
||||
v = edge->fBottom;
|
||||
|
@ -524,6 +524,17 @@ static SkPath create_path_35() {
|
||||
return path;
|
||||
}
|
||||
|
||||
// Reduction from crbug.com/843135 where an intersection is found
|
||||
// below the bottom of both intersected edges.
|
||||
static SkPath create_path_36() {
|
||||
SkPath path;
|
||||
path.moveTo(-2791476679359332352, 2608107002026524672);
|
||||
path.lineTo( 0, 11.95427703857421875);
|
||||
path.lineTo(-2781824066779086848, 2599088532777598976);
|
||||
path.lineTo( -7772.6875, 7274);
|
||||
return path;
|
||||
}
|
||||
|
||||
static std::unique_ptr<GrFragmentProcessor> create_linear_gradient_processor(GrContext* ctx) {
|
||||
|
||||
SkPoint pts[2] = { {0, 0}, {1, 1} };
|
||||
@ -619,4 +630,5 @@ DEF_GPUTEST_FOR_ALL_CONTEXTS(TessellatingPathRendererTests, reporter, ctxInfo) {
|
||||
test_path(ctx, rtc.get(), create_path_33());
|
||||
test_path(ctx, rtc.get(), create_path_34());
|
||||
test_path(ctx, rtc.get(), create_path_35());
|
||||
test_path(ctx, rtc.get(), create_path_36());
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user