Skip to content

Commit

Permalink
GrTessellator: two fixes for boundary simplification artifacts.
Browse files Browse the repository at this point in the history
The "pointy vertex" test was only considering the distance from the
next (outgoing) edge to the previous point. It must also consider the
distance from the previous (incoming) edge to the next point. If
either are less than a quarter pixel, the vertex is considered pointy
and should be removed. (884166)

Also (887103), when an interior region was completely removed due to
boundary simplification, it would leave a degenerate edge consisting
of the same vertex. So avoid introducing a join edge when prev == next.

Bug: 884166, 887103
Change-Id: I7f1d5b98e418d8f2a1c11643259d3cd74d08f286
Reviewed-on: https://skia-review.googlesource.com/157220
Commit-Queue: Stephen White <senorblanco@chromium.org>
Reviewed-by: Robert Phillips <robertphillips@google.com>
  • Loading branch information
SenorBlanco authored and Skia Commit-Bot committed Sep 26, 2018
1 parent 5ea41fc commit cfe1264
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 3 deletions.
28 changes: 28 additions & 0 deletions gm/crbug_884166.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*
* Copyright 2018 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/

#include "gm.h"
#include "SkCanvas.h"
#include "SkPath.h"

DEF_SIMPLE_GM(crbug_884166, canvas, 300, 300) {
SkPaint paint;

paint.setAntiAlias(true);
paint.setStyle(SkPaint::kFill_Style);

SkPath path;
path.moveTo(153.25, 280.75);
path.lineTo(161.75, 281.75);
path.lineTo(164.25, 282.00);
path.lineTo( 0.00, 276.00);
path.lineTo(161.50, 0.00);
path.lineTo(286.25, 231.25);
path.lineTo(163.75, 282.00);
path.lineTo(150.00, 280.00);
canvas->drawPath(path, paint);
}
31 changes: 31 additions & 0 deletions gm/crbug_887103.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*
* Copyright 2018 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/

#include "gm.h"
#include "SkCanvas.h"
#include "SkPath.h"

DEF_SIMPLE_GM(crbug_887103, canvas, 520, 520) {
SkPaint paint;

paint.setAntiAlias(true);
paint.setStyle(SkPaint::kFill_Style);

SkPath path;
path.moveTo(510, 20);
path.lineTo(500, 20);
path.lineTo(510, 500);

path.moveTo(500, 20);
path.lineTo(510, 500);
path.lineTo(500, 510);

path.moveTo(500, 30);
path.lineTo(510, 10);
path.lineTo( 10, 30);
canvas->drawPath(path, paint);
}
2 changes: 2 additions & 0 deletions gn/gm.gni
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,8 @@ gm_sources = [
"$_gm/crbug_691386.cpp",
"$_gm/crbug_788500.cpp",
"$_gm/crbug_847759.cpp",
"$_gm/crbug_884166.cpp",
"$_gm/crbug_887103.cpp",
"$_gm/croppedrects.cpp",
"$_gm/crosscontextimage.cpp",
"$_gm/cubicpaths.cpp",
Expand Down
8 changes: 5 additions & 3 deletions src/gpu/GrTessellator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1724,11 +1724,13 @@ void simplify_boundary(EdgeList* boundary, Comparator& c, SkArenaAlloc& alloc) {
for (Edge* e = boundary->fHead; e != nullptr;) {
Vertex* prev = prevEdge->fWinding == 1 ? prevEdge->fTop : prevEdge->fBottom;
Vertex* next = e->fWinding == 1 ? e->fBottom : e->fTop;
double dist = e->dist(prev->fPoint);
double distPrev = e->dist(prev->fPoint);
double distNext = prevEdge->dist(next->fPoint);
SkVector normal;
get_edge_normal(e, &normal);
double denom = 0.0625f;
if (prevNormal.dot(normal) < 0.0 && (dist * dist) <= denom) {
constexpr double kQuarterPixelSq = 0.25f * 0.25f;
if (prev != next && prevNormal.dot(normal) < 0.0 &&
(distPrev * distPrev <= kQuarterPixelSq || distNext * distNext <= kQuarterPixelSq)) {
Edge* join = new_edge(prev, next, Edge::Type::kInner, c, alloc);
if (prev->fPoint != next->fPoint) {
join->fLine.normalize();
Expand Down

0 comments on commit cfe1264

Please sign in to comment.