GrTessellator: fix event creation for dead boundary edges.
In some cases, an overlap boundary edge can be nulled out by the creation of a skeleton edge. In that case, we should avoid trying to create parallel edge events from that dead edge. This required making the tessellator verb maximum verb count modifiable at runtime for testing, since the test case has more than 10 vertices. Also added more logging. BUG: 966696 Change-Id: I429735999f6297655311485bc68d732b1c48bfce Reviewed-on: https://skia-review.googlesource.com/c/skia/+/216284 Commit-Queue: Stephen White <senorblanco@chromium.org> Reviewed-by: Robert Phillips <robertphillips@google.com>
This commit is contained in:
parent
d0d66fb8be
commit
8a3c059796
@ -538,16 +538,20 @@ void create_event(SSEdge* edge, Vertex* v, SSEdge* other, Vertex* dest, EventLis
|
||||
if (!v->fPartner) {
|
||||
return;
|
||||
}
|
||||
Vertex* top = edge->fEdge->fTop;
|
||||
Vertex* bottom = edge->fEdge->fBottom;
|
||||
if (!top || !bottom ) {
|
||||
return;
|
||||
}
|
||||
Line line = edge->fEdge->fLine;
|
||||
line.fC = -(dest->fPoint.fX * line.fA + dest->fPoint.fY * line.fB);
|
||||
Edge bisector(v, v->fPartner, 1, Edge::Type::kConnector);
|
||||
SkPoint p;
|
||||
uint8_t alpha = dest->fAlpha;
|
||||
if (line.intersect(bisector.fLine, &p) && !c.sweep_lt(p, edge->fEdge->fTop->fPoint) &&
|
||||
c.sweep_lt(p, edge->fEdge->fBottom->fPoint)) {
|
||||
if (line.intersect(bisector.fLine, &p) && !c.sweep_lt(p, top->fPoint) &&
|
||||
c.sweep_lt(p, bottom->fPoint)) {
|
||||
LOG("found p edge event for %g, %g (original %g -> %g), will collapse to %g,%g alpha %d\n",
|
||||
dest->fID, v->fID, edge->fEdge->fTop->fID, edge->fEdge->fBottom->fID, p.fX, p.fY,
|
||||
alpha);
|
||||
dest->fID, v->fID, top->fID, bottom->fID, p.fX, p.fY, alpha);
|
||||
edge->fEvent = alloc.make<Event>(edge, p, alpha);
|
||||
events->push(edge->fEvent);
|
||||
}
|
||||
@ -1501,14 +1505,18 @@ void dump_mesh(const VertexList& mesh) {
|
||||
|
||||
void dump_skel(const SSEdgeList& ssEdges) {
|
||||
#if LOGGING_ENABLED
|
||||
LOG("skeleton:\n");
|
||||
for (SSEdge* edge : ssEdges) {
|
||||
if (edge->fEdge) {
|
||||
LOG("skel edge %g -> %g (original %g -> %g)\n",
|
||||
LOG("skel edge %g -> %g",
|
||||
edge->fPrev->fVertex->fID,
|
||||
edge->fNext->fVertex->fID,
|
||||
edge->fEdge->fTop->fID,
|
||||
edge->fEdge->fBottom->fID);
|
||||
edge->fNext->fVertex->fID);
|
||||
if (edge->fEdge->fTop && edge->fEdge->fBottom) {
|
||||
LOG(" (original %g -> %g)\n",
|
||||
edge->fEdge->fTop->fID,
|
||||
edge->fEdge->fBottom->fID);
|
||||
} else {
|
||||
LOG("\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@ -1950,11 +1958,14 @@ bool collapse_overlap_regions(VertexList* mesh, Comparator& c, SkArenaAlloc& all
|
||||
bool complex = events.size() > 0;
|
||||
|
||||
LOG("\ncollapsing overlap regions\n");
|
||||
LOG("skeleton before:\n");
|
||||
dump_skel(ssEdges);
|
||||
while (events.size() > 0) {
|
||||
Event* event = events.top();
|
||||
events.pop();
|
||||
event->apply(mesh, c, &events, alloc);
|
||||
}
|
||||
LOG("skeleton after:\n");
|
||||
dump_skel(ssEdges);
|
||||
for (SSEdge* edge : ssEdges) {
|
||||
if (Edge* e = edge->fEdge) {
|
||||
|
@ -137,7 +137,8 @@ private:
|
||||
|
||||
} // namespace
|
||||
|
||||
GrTessellatingPathRenderer::GrTessellatingPathRenderer() {
|
||||
GrTessellatingPathRenderer::GrTessellatingPathRenderer()
|
||||
: fMaxVerbCount(GR_AA_TESSELLATOR_MAX_VERB_COUNT) {
|
||||
}
|
||||
|
||||
GrPathRenderer::CanDrawPath
|
||||
@ -161,7 +162,7 @@ GrTessellatingPathRenderer::onCanDrawPath(const CanDrawPathArgs& args) const {
|
||||
// without keys.
|
||||
SkPath path;
|
||||
args.fShape->asPath(&path);
|
||||
if (path.countVerbs() > GR_AA_TESSELLATOR_MAX_VERB_COUNT) {
|
||||
if (path.countVerbs() > fMaxVerbCount) {
|
||||
return CanDrawPath::kNo;
|
||||
}
|
||||
}
|
||||
|
@ -17,6 +17,9 @@
|
||||
class SK_API GrTessellatingPathRenderer : public GrPathRenderer {
|
||||
public:
|
||||
GrTessellatingPathRenderer();
|
||||
#if GR_TEST_UTILS
|
||||
void setMaxVerbCount(int maxVerbCount) { fMaxVerbCount = maxVerbCount; }
|
||||
#endif
|
||||
|
||||
private:
|
||||
CanDrawPath onCanDrawPath(const CanDrawPathArgs&) const override;
|
||||
@ -26,6 +29,7 @@ private:
|
||||
}
|
||||
|
||||
bool onDrawPath(const DrawPathArgs&) override;
|
||||
int fMaxVerbCount;
|
||||
|
||||
typedef GrPathRenderer INHERITED;
|
||||
};
|
||||
|
@ -622,6 +622,23 @@ static SkPath create_path_43() {
|
||||
return path;
|
||||
}
|
||||
|
||||
// Reduction from crbug.com/966696
|
||||
static SkPath create_path_44() {
|
||||
SkPath path;
|
||||
path.moveTo(114.4606170654296875, 186.443878173828125);
|
||||
path.lineTo( 91.5394744873046875, 185.4189453125);
|
||||
path.lineTo(306.45538330078125, 3203.986083984375);
|
||||
path.moveTo(16276206965409972224.0, 815.59393310546875);
|
||||
path.lineTo(-3.541605062372533207e+20, 487.7236328125);
|
||||
path.lineTo(-3.541605062372533207e+20, 168.204071044921875);
|
||||
path.lineTo(16276206965409972224.0, 496.07427978515625);
|
||||
path.moveTo(-3.541605062372533207e+20, 167.00958251953125);
|
||||
path.lineTo(-3.541605062372533207e+20, 488.32086181640625);
|
||||
path.lineTo(16276206965409972224.0, 816.78839111328125);
|
||||
path.lineTo(16276206965409972224.0, 495.47705078125);
|
||||
return path;
|
||||
}
|
||||
|
||||
static std::unique_ptr<GrFragmentProcessor> create_linear_gradient_processor(GrContext* ctx) {
|
||||
|
||||
SkPoint pts[2] = { {0, 0}, {1, 1} };
|
||||
@ -642,6 +659,7 @@ static void test_path(GrContext* ctx,
|
||||
AATypeFlags aaTypeFlags = AATypeFlags::kNone,
|
||||
std::unique_ptr<GrFragmentProcessor> fp = nullptr) {
|
||||
GrTessellatingPathRenderer tess;
|
||||
tess.setMaxVerbCount(100);
|
||||
|
||||
GrPaint paint;
|
||||
paint.setXPFactory(GrPorterDuffXPFactory::Get(SkBlendMode::kSrc));
|
||||
@ -728,4 +746,5 @@ DEF_GPUTEST_FOR_ALL_CONTEXTS(TessellatingPathRendererTests, reporter, ctxInfo) {
|
||||
test_path(ctx, rtc.get(), create_path_41(), SkMatrix(), AATypeFlags::kCoverage);
|
||||
test_path(ctx, rtc.get(), create_path_42());
|
||||
test_path(ctx, rtc.get(), create_path_43(), SkMatrix(), AATypeFlags::kCoverage);
|
||||
test_path(ctx, rtc.get(), create_path_44(), SkMatrix(), AATypeFlags::kCoverage);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user