GrTessellator (AA): null GrGeometryProcessor crash fix.
Add a null-check on geometry processor creation.
Add a test which exercises it: AA tessellator, with a non-invertible
matrix and a fragment processor which needs local coords (e.g., linear
gradient).
BUG=691902
Change-Id: I005b893aed58d3ad2500c41501045ac94b0b4b95
Reviewed-on: https://skia-review.googlesource.com/8462
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Stephen White <senorblanco@chromium.org>
diff --git a/src/gpu/ops/GrTessellatingPathRenderer.cpp b/src/gpu/ops/GrTessellatingPathRenderer.cpp
index 6ebffca..3acb091 100644
--- a/src/gpu/ops/GrTessellatingPathRenderer.cpp
+++ b/src/gpu/ops/GrTessellatingPathRenderer.cpp
@@ -297,6 +297,9 @@
fViewMatrix);
}
}
+ if (!gp.get()) {
+ return;
+ }
if (fAntiAlias) {
this->drawAA(target, gp.get());
} else {
diff --git a/tests/TessellatingPathRendererTests.cpp b/tests/TessellatingPathRendererTests.cpp
index 90d2ba5..f429df3 100644
--- a/tests/TessellatingPathRendererTests.cpp
+++ b/tests/TessellatingPathRendererTests.cpp
@@ -12,6 +12,7 @@
#if SK_SUPPORT_GPU
#include "GrContext.h"
#include "ops/GrTessellatingPathRenderer.h"
+#include "SkGradientShader.h"
/*
* These tests pass by not crashing, hanging or asserting in Debug.
@@ -249,12 +250,39 @@
return path;
}
-static void test_path(GrResourceProvider* rp, GrRenderTargetContext* renderTargetContext,
- const SkPath& path) {
+// A simple concave path. Test this with a non-invertible matrix.
+static SkPath create_path_17() {
+ SkPath path;
+ path.moveTo(20, 20);
+ path.lineTo(80, 20);
+ path.lineTo(30, 30);
+ path.lineTo(20, 80);
+ return path;
+}
+
+static sk_sp<GrFragmentProcessor> create_linear_gradient_processor(GrContext* ctx) {
+ SkPoint pts[2] = { {0, 0}, {1, 1} };
+ SkColor colors[2] = { SK_ColorGREEN, SK_ColorBLUE };
+ sk_sp<SkShader> shader = SkGradientShader::MakeLinear(
+ pts, colors, nullptr, SK_ARRAY_COUNT(colors), SkShader::kClamp_TileMode);
+ SkShader::AsFPArgs args(
+ ctx, &SkMatrix::I(), &SkMatrix::I(), SkFilterQuality::kLow_SkFilterQuality, nullptr);
+ return shader->asFragmentProcessor(args);
+}
+
+static void test_path(GrResourceProvider* rp,
+ GrRenderTargetContext* renderTargetContext,
+ const SkPath& path,
+ const SkMatrix& matrix = SkMatrix::I(),
+ GrAAType aaType = GrAAType::kNone,
+ sk_sp<GrFragmentProcessor> fp = nullptr) {
GrTessellatingPathRenderer tess;
GrPaint paint;
paint.setXPFactory(GrPorterDuffXPFactory::Get(SkBlendMode::kSrc));
+ if (fp) {
+ paint.addColorFragmentProcessor(fp);
+ }
GrNoClip noClip;
GrStyle style(SkStrokeRec::kFill_InitStyle);
@@ -264,9 +292,9 @@
&GrUserStencilSettings::kUnused,
renderTargetContext,
&noClip,
- &SkMatrix::I(),
+ &matrix,
&shape,
- GrAAType::kNone,
+ aaType,
false};
tess.drawPath(args);
}
@@ -303,5 +331,8 @@
test_path(rp, rtc.get(), create_path_14());
test_path(rp, rtc.get(), create_path_15());
test_path(rp, rtc.get(), create_path_16());
+ SkMatrix nonInvertibleMatrix = SkMatrix::MakeScale(0, 0);
+ sk_sp<GrFragmentProcessor> fp(create_linear_gradient_processor(ctx));
+ test_path(rp, rtc.get(), create_path_17(), nonInvertibleMatrix, GrAAType::kCoverage, fp);
}
#endif