- GrGLPath: Fix hitting an assert when a style applies a path effect that results in an empty path

- Add rendering test for the empty path case

Bug: skia:10909
Change-Id: I19188c58d4ee0841e441c33f4c1a5ed27dc2fd25
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/332736
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Brian Salomon <bsalomon@google.com>
This commit is contained in:
kcbanner 2020-11-06 10:05:24 -05:00 committed by Skia Commit-Bot
parent 1448eb979d
commit 4eb7c23d52
3 changed files with 54 additions and 24 deletions

View File

@ -17,6 +17,7 @@ Amazon, Inc <*@amazon.com>
Anthony Catel <paraboul@gmail.com>
ARM <*@arm.com>
Bharat Ahuja <ahujabharat93@gmail.com>
Casey Banner <kcbanner@gmail.com>
Dawson Coleman <dawsonmcoleman@gmail.com>
Deepak Mohan <hop2deep@gmail.com>
Ehsan Akhgari <ehsan.akhgari@gmail.com>

View File

@ -600,6 +600,28 @@ DEF_SIMPLE_GM(thin_aa_dash_lines, canvas, 330, 110) {
}
}
DEF_SIMPLE_GM(path_effect_empty_result, canvas, 100, 100) {
SkPaint p;
p.setStroke(true);
p.setStrokeWidth(1);
SkPath path;
float r = 70;
float l = 70;
float t = 70;
float b = 70;
path.moveTo(l, t);
path.lineTo(r, t);
path.lineTo(r, b);
path.lineTo(l, b);
path.close();
float dashes[] = {2.f, 2.f};
p.setPathEffect(SkDashPathEffect::Make(dashes, 2, 0.f));
canvas->drawPath(path, p);
}
//////////////////////////////////////////////////////////////////////////////
DEF_GM(return new DashingGM;)

View File

@ -286,36 +286,43 @@ GrGLPath::GrGLPath(GrGLGpu* gpu, const SkPath& origSkPath, const GrStyle& style)
stroke = style.strokeRec();
}
bool didInit = false;
if (stroke.needToApply() && stroke.getCap() != SkPaint::kButt_Cap) {
// Skia stroking and NVPR stroking differ with respect to stroking
// end caps of empty subpaths.
// Convert stroke to fill if path contains empty subpaths.
didInit = InitPathObjectPathDataCheckingDegenerates(gpu, fPathID, *skPath);
if (!didInit) {
if (!tmpPath.isValid()) {
tmpPath.init();
// applyPathEffectToPath could have generated an empty path
if (skPath->isEmpty()) {
InitPathObjectEmptyPath(gpu, fPathID);
fShouldStroke = false;
fShouldFill = false;
} else {
bool didInit = false;
if (stroke.needToApply() && stroke.getCap() != SkPaint::kButt_Cap) {
// Skia stroking and NVPR stroking differ with respect to stroking
// end caps of empty subpaths.
// Convert stroke to fill if path contains empty subpaths.
didInit = InitPathObjectPathDataCheckingDegenerates(gpu, fPathID, *skPath);
if (!didInit) {
if (!tmpPath.isValid()) {
tmpPath.init();
}
SkAssertResult(stroke.applyToPath(tmpPath.get(), *skPath));
skPath = tmpPath.get();
stroke.setFillStyle();
}
SkAssertResult(stroke.applyToPath(tmpPath.get(), *skPath));
skPath = tmpPath.get();
stroke.setFillStyle();
}
}
if (!didInit) {
InitPathObjectPathData(gpu, fPathID, *skPath);
}
if (!didInit) {
InitPathObjectPathData(gpu, fPathID, *skPath);
}
fShouldStroke = stroke.needToApply();
fShouldFill = stroke.isFillStyle() ||
fShouldStroke = stroke.needToApply();
fShouldFill = stroke.isFillStyle() ||
stroke.getStyle() == SkStrokeRec::kStrokeAndFill_Style;
fFillType = convert_skpath_filltype(skPath->getFillType());
fBounds = skPath->getBounds();
SkScalar radius = stroke.getInflationRadius();
fBounds.outset(radius, radius);
if (fShouldStroke) {
InitPathObjectStroke(gpu, fPathID, stroke);
fFillType = convert_skpath_filltype(skPath->getFillType());
fBounds = skPath->getBounds();
SkScalar radius = stroke.getInflationRadius();
fBounds.outset(radius, radius);
if (fShouldStroke) {
InitPathObjectStroke(gpu, fPathID, stroke);
}
}
}