Pass CTM to path effects (experimental)
Add an overload to SkPathEffect that can be used when the CTM is known
at the callsite. GPU callsites are not handled here, that will be
tackled in a separate CL.
Path effects must implement the filterPath virtual that accepts the CTM,
although they are not obligated to use it. If a path effect does
use the CTM, the output geometry must be in the original coordinate
space, not device space.
Bug: skia:11957
Change-Id: I01615985599fe2736de954bb10dac881b0554ae7
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/420239
Commit-Queue: Tyler Denniston <tdenniston@google.com>
Reviewed-by: Mike Reed <reed@google.com>
diff --git a/BUILD.gn b/BUILD.gn
index f8f71e0..4f56077 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -1428,6 +1428,7 @@
"src/core/SkMatrix.cpp",
"src/core/SkOpts.cpp",
"src/core/SkPaint.cpp",
+ "src/core/SkPaintPriv.cpp",
"src/core/SkPath.cpp",
"src/core/SkPathBuilder.cpp",
"src/core/SkPathEffect.cpp",
diff --git a/bench/PathBench.cpp b/bench/PathBench.cpp
index a2da0e2..9225a4d 100644
--- a/bench/PathBench.cpp
+++ b/bench/PathBench.cpp
@@ -994,7 +994,7 @@
6222222.5f, 28333.334f, 0.0f, 0.0f, 1.0f);
for (int i = 0; i < loops; ++i) {
SkPath dst;
- paint.getFillPath(path, &dst, nullptr, SkDraw::ComputeResScaleForStroking(mtx));
+ paint.getFillPath(path, &dst, nullptr, SkPaintPriv::ComputeResScaleForStroking(mtx));
}
}
diff --git a/gm/patheffects.cpp b/gm/patheffects.cpp
index aabe3de..801ef71 100644
--- a/gm/patheffects.cpp
+++ b/gm/patheffects.cpp
@@ -288,3 +288,124 @@
canvas->translate(0, 150);
}
}
+
+//////////////////////////////////////////////////////////////////////////////
+
+#include "include/core/SkStrokeRec.h"
+#include "src/core/SkPathEffectBase.h"
+
+namespace {
+/**
+ * Example path effect using CTM. This "strokes" a single line segment with some stroke width,
+ * and then inflates the result by some number of pixels.
+ */
+class StrokeLineInflated : public SkPathEffectBase {
+public:
+ StrokeLineInflated(float strokeWidth, float pxInflate)
+ : fRadius(strokeWidth / 2.f), fPxInflate(pxInflate) {}
+
+ bool onNeedsCTM() const final { return true; }
+
+ bool onFilterPath(SkPath* dst,
+ const SkPath& src,
+ SkStrokeRec* rec,
+ const SkRect* cullR,
+ const SkMatrix& ctm) const final {
+ SkASSERT(src.countPoints() == 2);
+ const SkPoint pts[2] = {src.getPoint(0), src.getPoint(1)};
+
+ SkMatrix invCtm;
+ if (!ctm.invert(&invCtm)) {
+ return false;
+ }
+
+ // For a line segment, we can just map the (scaled) normal vector to pixel-space,
+ // increase its length by the desired number of pixels, and then map back to canvas space.
+ SkPoint n = {pts[0].fY - pts[1].fY, pts[1].fX - pts[0].fX};
+ if (!n.setLength(fRadius)) {
+ return false;
+ }
+
+ SkPoint mappedN = ctm.mapVector(n.fX, n.fY);
+ if (!mappedN.setLength(mappedN.length() + fPxInflate)) {
+ return false;
+ }
+ n = invCtm.mapVector(mappedN.fX, mappedN.fY);
+
+ dst->moveTo(pts[0] + n);
+ dst->lineTo(pts[1] + n);
+ dst->lineTo(pts[1] - n);
+ dst->lineTo(pts[0] - n);
+ dst->close();
+
+ rec->setFillStyle();
+
+ return true;
+ }
+
+protected:
+ void flatten(SkWriteBuffer&) const final {}
+
+private:
+ SK_FLATTENABLE_HOOKS(StrokeLineInflated)
+
+ bool computeFastBounds(SkRect* bounds) const final { return false; }
+
+ const float fRadius;
+ const float fPxInflate;
+};
+
+sk_sp<SkFlattenable> StrokeLineInflated::CreateProc(SkReadBuffer&) { return nullptr; }
+
+} // namespace
+
+class CTMPathEffectGM : public skiagm::GM {
+protected:
+ SkString onShortName() override { return SkString("ctmpatheffect"); }
+
+ SkISize onISize() override { return SkISize::Make(800, 600); }
+
+ // TODO: ctm-aware path effects are currently CPU only
+ DrawResult onGpuSetup(GrDirectContext* dctx, SkString*) override {
+ return dctx == nullptr ? DrawResult::kOk : DrawResult::kSkip;
+ }
+
+ void onDraw(SkCanvas* canvas) override {
+ const float strokeWidth = 16;
+ const float pxInflate = 0.5f;
+ sk_sp<SkPathEffect> pathEffect(new StrokeLineInflated(strokeWidth, pxInflate));
+
+ SkPath path;
+ path.moveTo(100, 100);
+ path.lineTo(200, 200);
+
+ // Draw the inflated path, and a scaled version, in blue.
+ SkPaint paint;
+ paint.setAntiAlias(true);
+ paint.setColor(SkColorSetA(SK_ColorBLUE, 0xff));
+ paint.setPathEffect(pathEffect);
+ canvas->drawPath(path, paint);
+ canvas->save();
+ canvas->translate(150, 0);
+ canvas->scale(2.5, 0.5f);
+ canvas->drawPath(path, paint);
+ canvas->restore();
+
+ // Draw the regular stroked version on top in green.
+ // The inflated version should be visible underneath as a blue "border".
+ paint.setPathEffect(nullptr);
+ paint.setStyle(SkPaint::kStroke_Style);
+ paint.setStrokeWidth(strokeWidth);
+ paint.setColor(SkColorSetA(SK_ColorGREEN, 0xff));
+ canvas->drawPath(path, paint);
+ canvas->save();
+ canvas->translate(150, 0);
+ canvas->scale(2.5, 0.5f);
+ canvas->drawPath(path, paint);
+ canvas->restore();
+ }
+
+private:
+ using INHERITED = GM;
+};
+DEF_GM(return new CTMPathEffectGM;)
diff --git a/include/core/SkPaint.h b/include/core/SkPaint.h
index aa58b80..9ecc0c1 100644
--- a/include/core/SkPaint.h
+++ b/include/core/SkPaint.h
@@ -21,6 +21,7 @@
struct SkRect;
class SkImageFilter;
class SkMaskFilter;
+class SkMatrix;
class SkPath;
class SkPathEffect;
class SkShader;
@@ -404,6 +405,9 @@
bool getFillPath(const SkPath& src, SkPath* dst, const SkRect* cullRect,
SkScalar resScale = 1) const;
+ bool getFillPath(const SkPath& src, SkPath* dst, const SkRect* cullRect,
+ const SkMatrix& ctm) const;
+
/** Returns the filled equivalent of the stroked path.
Replaces dst with the src path modified by SkPathEffect and style stroke.
diff --git a/include/core/SkPathEffect.h b/include/core/SkPathEffect.h
index 1228de0..abb370c 100644
--- a/include/core/SkPathEffect.h
+++ b/include/core/SkPathEffect.h
@@ -86,6 +86,13 @@
*/
bool filterPath(SkPath* dst, const SkPath& src, SkStrokeRec*, const SkRect* cullR) const;
+ /** Version of filterPath that can be called when the CTM is known. */
+ bool filterPath(SkPath* dst, const SkPath& src, SkStrokeRec*, const SkRect* cullR,
+ const SkMatrix& ctm) const;
+
+ /** True if this path effect requires a valid CTM */
+ bool needsCTM() const;
+
static sk_sp<SkPathEffect> Deserialize(const void* data, size_t size,
const SkDeserialProcs* procs = nullptr);
diff --git a/infra/bots/gen_tasks_logic/dm_flags.go b/infra/bots/gen_tasks_logic/dm_flags.go
index a6a8fad..6dbe81d 100644
--- a/infra/bots/gen_tasks_logic/dm_flags.go
+++ b/infra/bots/gen_tasks_logic/dm_flags.go
@@ -740,6 +740,7 @@
badSerializeGMs = append(badSerializeGMs, "compositor_quads_shader")
badSerializeGMs = append(badSerializeGMs, "wacky_yuv_formats_qtr")
badSerializeGMs = append(badSerializeGMs, "runtime_effect_image")
+ badSerializeGMs = append(badSerializeGMs, "ctmpatheffect")
// This GM forces a path to be convex. That property doesn't survive
// serialization.
diff --git a/infra/bots/tasks.json b/infra/bots/tasks.json
index 9c55bee..9a0164e 100755
--- a/infra/bots/tasks.json
+++ b/infra/bots/tasks.json
@@ -40358,7 +40358,7 @@
"skia/infra/bots/run_recipe.py",
"${ISOLATED_OUTDIR}",
"test",
- "{\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"buildbucket_build_id\":\"<(BUILDBUCKET_BUILD_ID)\",\"buildername\":\"Test-Debian10-Clang-GCE-CPU-AVX2-x86_64-Debug-All-BonusConfigs\",\"dm_flags\":\"[\\\"dm\\\",\\\"--nameByHash\\\",\\\"--key\\\",\\\"arch\\\",\\\"x86_64\\\",\\\"compiler\\\",\\\"Clang\\\",\\\"configuration\\\",\\\"Debug\\\",\\\"cpu_or_gpu\\\",\\\"CPU\\\",\\\"cpu_or_gpu_value\\\",\\\"AVX2\\\",\\\"extra_config\\\",\\\"BonusConfigs\\\",\\\"model\\\",\\\"GCE\\\",\\\"os\\\",\\\"Debian10\\\",\\\"style\\\",\\\"default\\\",\\\"--randomProcessorTest\\\",\\\"--nogpu\\\",\\\"--config\\\",\\\"g8\\\",\\\"565\\\",\\\"pic-8888\\\",\\\"serialize-8888\\\",\\\"f16\\\",\\\"srgb\\\",\\\"esrgb\\\",\\\"narrow\\\",\\\"enarrow\\\",\\\"p3\\\",\\\"ep3\\\",\\\"rec2020\\\",\\\"erec2020\\\",\\\"--src\\\",\\\"tests\\\",\\\"gm\\\",\\\"image\\\",\\\"colorImage\\\",\\\"--skip\\\",\\\"f16\\\",\\\"_\\\",\\\"_\\\",\\\"dstreadshuffle\\\",\\\"g8\\\",\\\"image\\\",\\\"_\\\",\\\"_\\\",\\\"g8\\\",\\\"colorImage\\\",\\\"_\\\",\\\"_\\\",\\\"_\\\",\\\"image\\\",\\\"gen_platf\\\",\\\"error\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"strict_constraint_batch_no_red_allowed\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"strict_constraint_no_red_allowed\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"fast_constraint_red_is_allowed\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"c_gms\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"colortype\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"colortype_xfermodes\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"drawfilter\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"fontmgr_bounds_0.75_0\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"fontmgr_bounds_1_-0.25\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"fontmgr_bounds\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"fontmgr_match\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"fontmgr_iter\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"imagemasksubset\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"wacky_yuv_formats_domain\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"imagemakewithfilter\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"imagemakewithfilter_crop\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"imagemakewithfilter_crop_ref\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"imagemakewithfilter_ref\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"bitmapfilters\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"bitmapshaders\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"convex_poly_clip\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"extractalpha\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"filterbitmap_checkerboard_32_32_g8\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"filterbitmap_image_mandrill_64\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"shadows\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"simpleaaclip_aaclip\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"composeshader_bitmap\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"scaled_tilemodes_npot\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"scaled_tilemodes\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"typefacerendering_pfaMac\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"parsedpaths\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"ImageGeneratorExternal_rect\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"ImageGeneratorExternal_shader\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"shadow_utils\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"persp_images\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"all_bitmap_configs\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"makecolorspace\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"readpixels\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"draw_image_set_rect_to_rect\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"draw_image_set_alpha_only\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"compositor_quads_shader\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"wacky_yuv_formats_qtr\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"runtime_effect_image\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"analytic_antialias_convex\\\",\\\"pic-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"drawfilter\\\",\\\"pic-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"image-cacherator-from-picture\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"image-cacherator-from-picture\\\",\\\"pic-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"image-cacherator-from-raster\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"image-cacherator-from-raster\\\",\\\"pic-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"image-cacherator-from-ctable\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"image-cacherator-from-ctable\\\",\\\"pic-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"complexclip4_bw\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"complexclip4_bw\\\",\\\"pic-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"blurrect_compare\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"blurrect_compare\\\",\\\"pic-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"complexclip4_aa\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"complexclip4_aa\\\",\\\"pic-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"blurrect_compare\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"blurrect_compare\\\",\\\"pic-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"p3\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"p3\\\",\\\"pic-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"blurrect_compare\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"blurrect_compare\\\",\\\"pic-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"async_rescale_and_read_text_up_large\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"async_rescale_and_read_text_up_large\\\",\\\"pic-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"blurrect_compare\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"blurrect_compare\\\",\\\"pic-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"async_rescale_and_read_text_up\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"async_rescale_and_read_text_up\\\",\\\"pic-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"blurrect_compare\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"blurrect_compare\\\",\\\"pic-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"async_rescale_and_read_text_down\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"async_rescale_and_read_text_down\\\",\\\"pic-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"blurrect_compare\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"blurrect_compare\\\",\\\"pic-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"async_rescale_and_read_dog_up\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"async_rescale_and_read_dog_up\\\",\\\"pic-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"blurrect_compare\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"blurrect_compare\\\",\\\"pic-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"async_rescale_and_read_dog_down\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"async_rescale_and_read_dog_down\\\",\\\"pic-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"blurrect_compare\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"blurrect_compare\\\",\\\"pic-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"async_rescale_and_read_rose\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"async_rescale_and_read_rose\\\",\\\"pic-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"blurrect_compare\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"blurrect_compare\\\",\\\"pic-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"async_rescale_and_read_no_bleed\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"async_rescale_and_read_no_bleed\\\",\\\"pic-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"blurrect_compare\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"blurrect_compare\\\",\\\"pic-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"async_rescale_and_read_alpha_type\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"async_rescale_and_read_alpha_type\\\",\\\"pic-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"blurrect_compare\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"blurrect_compare\\\",\\\"--nonativeFonts\\\",\\\"--verbose\\\"]\",\"dm_properties\":\"{\\\"buildbucket_build_id\\\":\\\"<(BUILDBUCKET_BUILD_ID)\\\",\\\"builder\\\":\\\"Test-Debian10-Clang-GCE-CPU-AVX2-x86_64-Debug-All-BonusConfigs\\\",\\\"gitHash\\\":\\\"<(REVISION)\\\",\\\"issue\\\":\\\"<(ISSUE)\\\",\\\"patch_storage\\\":\\\"<(PATCH_STORAGE)\\\",\\\"patchset\\\":\\\"<(PATCHSET)\\\",\\\"swarming_bot_id\\\":\\\"${SWARMING_BOT_ID}\\\",\\\"swarming_task_id\\\":\\\"${SWARMING_TASK_ID}\\\",\\\"task_id\\\":\\\"<(TASK_ID)\\\"}\",\"do_upload\":\"true\",\"gold_hashes_url\":\"https://storage.googleapis.com/skia-infra-gm/hash_files/gold-prod-hashes.txt\",\"gs_bucket\":\"skia-infra-gm\",\"images\":\"true\",\"patch_issue\":\"<(ISSUE_INT)\",\"patch_ref\":\"<(PATCH_REF)\",\"patch_repo\":\"<(PATCH_REPO)\",\"patch_set\":\"<(PATCHSET_INT)\",\"patch_storage\":\"<(PATCH_STORAGE)\",\"repository\":\"<(REPO)\",\"resources\":\"true\",\"revision\":\"<(REVISION)\",\"skps\":\"true\",\"svgs\":\"true\",\"swarm_out_dir\":\"test\",\"task_id\":\"<(TASK_ID)\"}",
+ "{\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"buildbucket_build_id\":\"<(BUILDBUCKET_BUILD_ID)\",\"buildername\":\"Test-Debian10-Clang-GCE-CPU-AVX2-x86_64-Debug-All-BonusConfigs\",\"dm_flags\":\"[\\\"dm\\\",\\\"--nameByHash\\\",\\\"--key\\\",\\\"arch\\\",\\\"x86_64\\\",\\\"compiler\\\",\\\"Clang\\\",\\\"configuration\\\",\\\"Debug\\\",\\\"cpu_or_gpu\\\",\\\"CPU\\\",\\\"cpu_or_gpu_value\\\",\\\"AVX2\\\",\\\"extra_config\\\",\\\"BonusConfigs\\\",\\\"model\\\",\\\"GCE\\\",\\\"os\\\",\\\"Debian10\\\",\\\"style\\\",\\\"default\\\",\\\"--randomProcessorTest\\\",\\\"--nogpu\\\",\\\"--config\\\",\\\"g8\\\",\\\"565\\\",\\\"pic-8888\\\",\\\"serialize-8888\\\",\\\"f16\\\",\\\"srgb\\\",\\\"esrgb\\\",\\\"narrow\\\",\\\"enarrow\\\",\\\"p3\\\",\\\"ep3\\\",\\\"rec2020\\\",\\\"erec2020\\\",\\\"--src\\\",\\\"tests\\\",\\\"gm\\\",\\\"image\\\",\\\"colorImage\\\",\\\"--skip\\\",\\\"f16\\\",\\\"_\\\",\\\"_\\\",\\\"dstreadshuffle\\\",\\\"g8\\\",\\\"image\\\",\\\"_\\\",\\\"_\\\",\\\"g8\\\",\\\"colorImage\\\",\\\"_\\\",\\\"_\\\",\\\"_\\\",\\\"image\\\",\\\"gen_platf\\\",\\\"error\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"strict_constraint_batch_no_red_allowed\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"strict_constraint_no_red_allowed\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"fast_constraint_red_is_allowed\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"c_gms\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"colortype\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"colortype_xfermodes\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"drawfilter\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"fontmgr_bounds_0.75_0\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"fontmgr_bounds_1_-0.25\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"fontmgr_bounds\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"fontmgr_match\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"fontmgr_iter\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"imagemasksubset\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"wacky_yuv_formats_domain\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"imagemakewithfilter\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"imagemakewithfilter_crop\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"imagemakewithfilter_crop_ref\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"imagemakewithfilter_ref\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"bitmapfilters\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"bitmapshaders\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"convex_poly_clip\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"extractalpha\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"filterbitmap_checkerboard_32_32_g8\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"filterbitmap_image_mandrill_64\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"shadows\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"simpleaaclip_aaclip\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"composeshader_bitmap\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"scaled_tilemodes_npot\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"scaled_tilemodes\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"typefacerendering_pfaMac\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"parsedpaths\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"ImageGeneratorExternal_rect\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"ImageGeneratorExternal_shader\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"shadow_utils\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"persp_images\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"all_bitmap_configs\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"makecolorspace\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"readpixels\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"draw_image_set_rect_to_rect\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"draw_image_set_alpha_only\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"compositor_quads_shader\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"wacky_yuv_formats_qtr\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"runtime_effect_image\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"ctmpatheffect\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"analytic_antialias_convex\\\",\\\"pic-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"drawfilter\\\",\\\"pic-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"image-cacherator-from-picture\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"image-cacherator-from-picture\\\",\\\"pic-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"image-cacherator-from-raster\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"image-cacherator-from-raster\\\",\\\"pic-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"image-cacherator-from-ctable\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"image-cacherator-from-ctable\\\",\\\"pic-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"complexclip4_bw\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"complexclip4_bw\\\",\\\"pic-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"blurrect_compare\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"blurrect_compare\\\",\\\"pic-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"complexclip4_aa\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"complexclip4_aa\\\",\\\"pic-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"blurrect_compare\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"blurrect_compare\\\",\\\"pic-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"p3\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"p3\\\",\\\"pic-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"blurrect_compare\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"blurrect_compare\\\",\\\"pic-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"async_rescale_and_read_text_up_large\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"async_rescale_and_read_text_up_large\\\",\\\"pic-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"blurrect_compare\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"blurrect_compare\\\",\\\"pic-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"async_rescale_and_read_text_up\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"async_rescale_and_read_text_up\\\",\\\"pic-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"blurrect_compare\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"blurrect_compare\\\",\\\"pic-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"async_rescale_and_read_text_down\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"async_rescale_and_read_text_down\\\",\\\"pic-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"blurrect_compare\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"blurrect_compare\\\",\\\"pic-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"async_rescale_and_read_dog_up\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"async_rescale_and_read_dog_up\\\",\\\"pic-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"blurrect_compare\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"blurrect_compare\\\",\\\"pic-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"async_rescale_and_read_dog_down\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"async_rescale_and_read_dog_down\\\",\\\"pic-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"blurrect_compare\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"blurrect_compare\\\",\\\"pic-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"async_rescale_and_read_rose\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"async_rescale_and_read_rose\\\",\\\"pic-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"blurrect_compare\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"blurrect_compare\\\",\\\"pic-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"async_rescale_and_read_no_bleed\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"async_rescale_and_read_no_bleed\\\",\\\"pic-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"blurrect_compare\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"blurrect_compare\\\",\\\"pic-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"async_rescale_and_read_alpha_type\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"async_rescale_and_read_alpha_type\\\",\\\"pic-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"blurrect_compare\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"blurrect_compare\\\",\\\"--nonativeFonts\\\",\\\"--verbose\\\"]\",\"dm_properties\":\"{\\\"buildbucket_build_id\\\":\\\"<(BUILDBUCKET_BUILD_ID)\\\",\\\"builder\\\":\\\"Test-Debian10-Clang-GCE-CPU-AVX2-x86_64-Debug-All-BonusConfigs\\\",\\\"gitHash\\\":\\\"<(REVISION)\\\",\\\"issue\\\":\\\"<(ISSUE)\\\",\\\"patch_storage\\\":\\\"<(PATCH_STORAGE)\\\",\\\"patchset\\\":\\\"<(PATCHSET)\\\",\\\"swarming_bot_id\\\":\\\"${SWARMING_BOT_ID}\\\",\\\"swarming_task_id\\\":\\\"${SWARMING_TASK_ID}\\\",\\\"task_id\\\":\\\"<(TASK_ID)\\\"}\",\"do_upload\":\"true\",\"gold_hashes_url\":\"https://storage.googleapis.com/skia-infra-gm/hash_files/gold-prod-hashes.txt\",\"gs_bucket\":\"skia-infra-gm\",\"images\":\"true\",\"patch_issue\":\"<(ISSUE_INT)\",\"patch_ref\":\"<(PATCH_REF)\",\"patch_repo\":\"<(PATCH_REPO)\",\"patch_set\":\"<(PATCHSET_INT)\",\"patch_storage\":\"<(PATCH_STORAGE)\",\"repository\":\"<(REPO)\",\"resources\":\"true\",\"revision\":\"<(REVISION)\",\"skps\":\"true\",\"svgs\":\"true\",\"swarm_out_dir\":\"test\",\"task_id\":\"<(TASK_ID)\"}",
"skia"
],
"dependencies": [
@@ -41107,7 +41107,7 @@
"skia/infra/bots/run_recipe.py",
"${ISOLATED_OUTDIR}",
"test",
- "{\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"buildbucket_build_id\":\"<(BUILDBUCKET_BUILD_ID)\",\"buildername\":\"Test-Debian10-Clang-GCE-CPU-AVX2-x86_64-Release-All-BonusConfigs\",\"dm_flags\":\"[\\\"dm\\\",\\\"--nameByHash\\\",\\\"--key\\\",\\\"arch\\\",\\\"x86_64\\\",\\\"compiler\\\",\\\"Clang\\\",\\\"configuration\\\",\\\"Release\\\",\\\"cpu_or_gpu\\\",\\\"CPU\\\",\\\"cpu_or_gpu_value\\\",\\\"AVX2\\\",\\\"extra_config\\\",\\\"BonusConfigs\\\",\\\"model\\\",\\\"GCE\\\",\\\"os\\\",\\\"Debian10\\\",\\\"style\\\",\\\"default\\\",\\\"--randomProcessorTest\\\",\\\"--nogpu\\\",\\\"--config\\\",\\\"g8\\\",\\\"565\\\",\\\"pic-8888\\\",\\\"serialize-8888\\\",\\\"f16\\\",\\\"srgb\\\",\\\"esrgb\\\",\\\"narrow\\\",\\\"enarrow\\\",\\\"p3\\\",\\\"ep3\\\",\\\"rec2020\\\",\\\"erec2020\\\",\\\"--src\\\",\\\"tests\\\",\\\"gm\\\",\\\"image\\\",\\\"colorImage\\\",\\\"--skip\\\",\\\"f16\\\",\\\"_\\\",\\\"_\\\",\\\"dstreadshuffle\\\",\\\"g8\\\",\\\"image\\\",\\\"_\\\",\\\"_\\\",\\\"g8\\\",\\\"colorImage\\\",\\\"_\\\",\\\"_\\\",\\\"_\\\",\\\"image\\\",\\\"gen_platf\\\",\\\"error\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"strict_constraint_batch_no_red_allowed\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"strict_constraint_no_red_allowed\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"fast_constraint_red_is_allowed\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"c_gms\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"colortype\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"colortype_xfermodes\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"drawfilter\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"fontmgr_bounds_0.75_0\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"fontmgr_bounds_1_-0.25\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"fontmgr_bounds\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"fontmgr_match\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"fontmgr_iter\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"imagemasksubset\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"wacky_yuv_formats_domain\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"imagemakewithfilter\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"imagemakewithfilter_crop\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"imagemakewithfilter_crop_ref\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"imagemakewithfilter_ref\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"bitmapfilters\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"bitmapshaders\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"convex_poly_clip\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"extractalpha\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"filterbitmap_checkerboard_32_32_g8\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"filterbitmap_image_mandrill_64\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"shadows\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"simpleaaclip_aaclip\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"composeshader_bitmap\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"scaled_tilemodes_npot\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"scaled_tilemodes\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"typefacerendering_pfaMac\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"parsedpaths\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"ImageGeneratorExternal_rect\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"ImageGeneratorExternal_shader\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"shadow_utils\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"persp_images\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"all_bitmap_configs\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"makecolorspace\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"readpixels\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"draw_image_set_rect_to_rect\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"draw_image_set_alpha_only\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"compositor_quads_shader\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"wacky_yuv_formats_qtr\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"runtime_effect_image\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"analytic_antialias_convex\\\",\\\"pic-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"drawfilter\\\",\\\"pic-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"image-cacherator-from-picture\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"image-cacherator-from-picture\\\",\\\"pic-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"image-cacherator-from-raster\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"image-cacherator-from-raster\\\",\\\"pic-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"image-cacherator-from-ctable\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"image-cacherator-from-ctable\\\",\\\"pic-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"complexclip4_bw\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"complexclip4_bw\\\",\\\"pic-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"blurrect_compare\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"blurrect_compare\\\",\\\"pic-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"complexclip4_aa\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"complexclip4_aa\\\",\\\"pic-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"blurrect_compare\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"blurrect_compare\\\",\\\"pic-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"p3\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"p3\\\",\\\"pic-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"blurrect_compare\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"blurrect_compare\\\",\\\"pic-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"async_rescale_and_read_text_up_large\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"async_rescale_and_read_text_up_large\\\",\\\"pic-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"blurrect_compare\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"blurrect_compare\\\",\\\"pic-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"async_rescale_and_read_text_up\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"async_rescale_and_read_text_up\\\",\\\"pic-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"blurrect_compare\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"blurrect_compare\\\",\\\"pic-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"async_rescale_and_read_text_down\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"async_rescale_and_read_text_down\\\",\\\"pic-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"blurrect_compare\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"blurrect_compare\\\",\\\"pic-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"async_rescale_and_read_dog_up\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"async_rescale_and_read_dog_up\\\",\\\"pic-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"blurrect_compare\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"blurrect_compare\\\",\\\"pic-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"async_rescale_and_read_dog_down\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"async_rescale_and_read_dog_down\\\",\\\"pic-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"blurrect_compare\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"blurrect_compare\\\",\\\"pic-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"async_rescale_and_read_rose\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"async_rescale_and_read_rose\\\",\\\"pic-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"blurrect_compare\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"blurrect_compare\\\",\\\"pic-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"async_rescale_and_read_no_bleed\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"async_rescale_and_read_no_bleed\\\",\\\"pic-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"blurrect_compare\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"blurrect_compare\\\",\\\"pic-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"async_rescale_and_read_alpha_type\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"async_rescale_and_read_alpha_type\\\",\\\"pic-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"blurrect_compare\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"blurrect_compare\\\",\\\"--nonativeFonts\\\",\\\"--verbose\\\"]\",\"dm_properties\":\"{\\\"buildbucket_build_id\\\":\\\"<(BUILDBUCKET_BUILD_ID)\\\",\\\"builder\\\":\\\"Test-Debian10-Clang-GCE-CPU-AVX2-x86_64-Release-All-BonusConfigs\\\",\\\"gitHash\\\":\\\"<(REVISION)\\\",\\\"issue\\\":\\\"<(ISSUE)\\\",\\\"patch_storage\\\":\\\"<(PATCH_STORAGE)\\\",\\\"patchset\\\":\\\"<(PATCHSET)\\\",\\\"swarming_bot_id\\\":\\\"${SWARMING_BOT_ID}\\\",\\\"swarming_task_id\\\":\\\"${SWARMING_TASK_ID}\\\",\\\"task_id\\\":\\\"<(TASK_ID)\\\"}\",\"do_upload\":\"true\",\"gold_hashes_url\":\"https://storage.googleapis.com/skia-infra-gm/hash_files/gold-prod-hashes.txt\",\"gs_bucket\":\"skia-infra-gm\",\"images\":\"true\",\"patch_issue\":\"<(ISSUE_INT)\",\"patch_ref\":\"<(PATCH_REF)\",\"patch_repo\":\"<(PATCH_REPO)\",\"patch_set\":\"<(PATCHSET_INT)\",\"patch_storage\":\"<(PATCH_STORAGE)\",\"repository\":\"<(REPO)\",\"resources\":\"true\",\"revision\":\"<(REVISION)\",\"skps\":\"true\",\"svgs\":\"true\",\"swarm_out_dir\":\"test\",\"task_id\":\"<(TASK_ID)\"}",
+ "{\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"buildbucket_build_id\":\"<(BUILDBUCKET_BUILD_ID)\",\"buildername\":\"Test-Debian10-Clang-GCE-CPU-AVX2-x86_64-Release-All-BonusConfigs\",\"dm_flags\":\"[\\\"dm\\\",\\\"--nameByHash\\\",\\\"--key\\\",\\\"arch\\\",\\\"x86_64\\\",\\\"compiler\\\",\\\"Clang\\\",\\\"configuration\\\",\\\"Release\\\",\\\"cpu_or_gpu\\\",\\\"CPU\\\",\\\"cpu_or_gpu_value\\\",\\\"AVX2\\\",\\\"extra_config\\\",\\\"BonusConfigs\\\",\\\"model\\\",\\\"GCE\\\",\\\"os\\\",\\\"Debian10\\\",\\\"style\\\",\\\"default\\\",\\\"--randomProcessorTest\\\",\\\"--nogpu\\\",\\\"--config\\\",\\\"g8\\\",\\\"565\\\",\\\"pic-8888\\\",\\\"serialize-8888\\\",\\\"f16\\\",\\\"srgb\\\",\\\"esrgb\\\",\\\"narrow\\\",\\\"enarrow\\\",\\\"p3\\\",\\\"ep3\\\",\\\"rec2020\\\",\\\"erec2020\\\",\\\"--src\\\",\\\"tests\\\",\\\"gm\\\",\\\"image\\\",\\\"colorImage\\\",\\\"--skip\\\",\\\"f16\\\",\\\"_\\\",\\\"_\\\",\\\"dstreadshuffle\\\",\\\"g8\\\",\\\"image\\\",\\\"_\\\",\\\"_\\\",\\\"g8\\\",\\\"colorImage\\\",\\\"_\\\",\\\"_\\\",\\\"_\\\",\\\"image\\\",\\\"gen_platf\\\",\\\"error\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"strict_constraint_batch_no_red_allowed\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"strict_constraint_no_red_allowed\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"fast_constraint_red_is_allowed\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"c_gms\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"colortype\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"colortype_xfermodes\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"drawfilter\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"fontmgr_bounds_0.75_0\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"fontmgr_bounds_1_-0.25\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"fontmgr_bounds\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"fontmgr_match\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"fontmgr_iter\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"imagemasksubset\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"wacky_yuv_formats_domain\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"imagemakewithfilter\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"imagemakewithfilter_crop\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"imagemakewithfilter_crop_ref\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"imagemakewithfilter_ref\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"bitmapfilters\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"bitmapshaders\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"convex_poly_clip\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"extractalpha\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"filterbitmap_checkerboard_32_32_g8\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"filterbitmap_image_mandrill_64\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"shadows\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"simpleaaclip_aaclip\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"composeshader_bitmap\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"scaled_tilemodes_npot\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"scaled_tilemodes\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"typefacerendering_pfaMac\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"parsedpaths\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"ImageGeneratorExternal_rect\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"ImageGeneratorExternal_shader\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"shadow_utils\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"persp_images\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"all_bitmap_configs\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"makecolorspace\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"readpixels\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"draw_image_set_rect_to_rect\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"draw_image_set_alpha_only\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"compositor_quads_shader\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"wacky_yuv_formats_qtr\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"runtime_effect_image\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"ctmpatheffect\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"analytic_antialias_convex\\\",\\\"pic-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"drawfilter\\\",\\\"pic-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"image-cacherator-from-picture\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"image-cacherator-from-picture\\\",\\\"pic-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"image-cacherator-from-raster\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"image-cacherator-from-raster\\\",\\\"pic-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"image-cacherator-from-ctable\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"image-cacherator-from-ctable\\\",\\\"pic-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"complexclip4_bw\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"complexclip4_bw\\\",\\\"pic-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"blurrect_compare\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"blurrect_compare\\\",\\\"pic-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"complexclip4_aa\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"complexclip4_aa\\\",\\\"pic-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"blurrect_compare\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"blurrect_compare\\\",\\\"pic-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"p3\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"p3\\\",\\\"pic-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"blurrect_compare\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"blurrect_compare\\\",\\\"pic-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"async_rescale_and_read_text_up_large\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"async_rescale_and_read_text_up_large\\\",\\\"pic-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"blurrect_compare\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"blurrect_compare\\\",\\\"pic-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"async_rescale_and_read_text_up\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"async_rescale_and_read_text_up\\\",\\\"pic-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"blurrect_compare\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"blurrect_compare\\\",\\\"pic-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"async_rescale_and_read_text_down\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"async_rescale_and_read_text_down\\\",\\\"pic-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"blurrect_compare\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"blurrect_compare\\\",\\\"pic-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"async_rescale_and_read_dog_up\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"async_rescale_and_read_dog_up\\\",\\\"pic-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"blurrect_compare\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"blurrect_compare\\\",\\\"pic-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"async_rescale_and_read_dog_down\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"async_rescale_and_read_dog_down\\\",\\\"pic-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"blurrect_compare\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"blurrect_compare\\\",\\\"pic-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"async_rescale_and_read_rose\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"async_rescale_and_read_rose\\\",\\\"pic-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"blurrect_compare\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"blurrect_compare\\\",\\\"pic-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"async_rescale_and_read_no_bleed\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"async_rescale_and_read_no_bleed\\\",\\\"pic-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"blurrect_compare\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"blurrect_compare\\\",\\\"pic-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"async_rescale_and_read_alpha_type\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"async_rescale_and_read_alpha_type\\\",\\\"pic-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"blurrect_compare\\\",\\\"serialize-8888\\\",\\\"gm\\\",\\\"_\\\",\\\"blurrect_compare\\\",\\\"--nonativeFonts\\\",\\\"--verbose\\\"]\",\"dm_properties\":\"{\\\"buildbucket_build_id\\\":\\\"<(BUILDBUCKET_BUILD_ID)\\\",\\\"builder\\\":\\\"Test-Debian10-Clang-GCE-CPU-AVX2-x86_64-Release-All-BonusConfigs\\\",\\\"gitHash\\\":\\\"<(REVISION)\\\",\\\"issue\\\":\\\"<(ISSUE)\\\",\\\"patch_storage\\\":\\\"<(PATCH_STORAGE)\\\",\\\"patchset\\\":\\\"<(PATCHSET)\\\",\\\"swarming_bot_id\\\":\\\"${SWARMING_BOT_ID}\\\",\\\"swarming_task_id\\\":\\\"${SWARMING_TASK_ID}\\\",\\\"task_id\\\":\\\"<(TASK_ID)\\\"}\",\"do_upload\":\"true\",\"gold_hashes_url\":\"https://storage.googleapis.com/skia-infra-gm/hash_files/gold-prod-hashes.txt\",\"gs_bucket\":\"skia-infra-gm\",\"images\":\"true\",\"patch_issue\":\"<(ISSUE_INT)\",\"patch_ref\":\"<(PATCH_REF)\",\"patch_repo\":\"<(PATCH_REPO)\",\"patch_set\":\"<(PATCHSET_INT)\",\"patch_storage\":\"<(PATCH_STORAGE)\",\"repository\":\"<(REPO)\",\"resources\":\"true\",\"revision\":\"<(REVISION)\",\"skps\":\"true\",\"svgs\":\"true\",\"swarm_out_dir\":\"test\",\"task_id\":\"<(TASK_ID)\"}",
"skia"
],
"dependencies": [
diff --git a/modules/sksg/src/SkSGGeometryEffect.cpp b/modules/sksg/src/SkSGGeometryEffect.cpp
index e66bbf1..9f1c129 100644
--- a/modules/sksg/src/SkSGGeometryEffect.cpp
+++ b/modules/sksg/src/SkSGGeometryEffect.cpp
@@ -64,6 +64,7 @@
if (const auto trim = SkTrimPathEffect::Make(fStart, fStop, fMode)) {
SkStrokeRec rec(SkStrokeRec::kHairline_InitStyle);
+ SkASSERT(!trim->needsCTM());
SkAssertResult(trim->filterPath(&path, path, &rec, nullptr));
}
@@ -121,6 +122,7 @@
if (const auto dash_patheffect = make_dash(fIntervals, fPhase)) {
SkStrokeRec rec(SkStrokeRec::kHairline_InitStyle);
+ SkASSERT(!dash_patheffect->needsCTM());
dash_patheffect->filterPath(&path, path, &rec, nullptr);
}
@@ -132,6 +134,7 @@
if (const auto round = SkCornerPathEffect::Make(fRadius)) {
SkStrokeRec rec(SkStrokeRec::kHairline_InitStyle);
+ SkASSERT(!round->needsCTM());
SkAssertResult(round->filterPath(&path, path, &rec, nullptr));
}
diff --git a/src/core/SkDraw.cpp b/src/core/SkDraw.cpp
index 4d84ce4..5bc2c8b 100644
--- a/src/core/SkDraw.cpp
+++ b/src/core/SkDraw.cpp
@@ -804,19 +804,6 @@
this->drawPath(path, paint, nullptr, true);
}
-SkScalar SkDraw::ComputeResScaleForStroking(const SkMatrix& matrix) {
- // Not sure how to handle perspective differently, so we just don't try (yet)
- SkScalar sx = SkPoint::Length(matrix[SkMatrix::kMScaleX], matrix[SkMatrix::kMSkewY]);
- SkScalar sy = SkPoint::Length(matrix[SkMatrix::kMSkewX], matrix[SkMatrix::kMScaleY]);
- if (SkScalarsAreFinite(sx, sy)) {
- SkScalar scale = std::max(sx, sy);
- if (scale > 0) {
- return scale;
- }
- }
- return 1;
-}
-
void SkDraw::drawDevPath(const SkPath& devPath, const SkPaint& paint, bool drawCoverage,
SkBlitter* customBlitter, bool doFill) const {
if (SkPathPriv::TooBigForMath(devPath)) {
@@ -950,7 +937,7 @@
cullRectPtr = &cullRect;
}
doFill = paint->getFillPath(*pathPtr, tmpPath, cullRectPtr,
- ComputeResScaleForStroking(fMatrixProvider->localToDevice()));
+ fMatrixProvider->localToDevice());
pathPtr = tmpPath;
}
diff --git a/src/core/SkDraw.h b/src/core/SkDraw.h
index 7d1eb0d..c08554e 100644
--- a/src/core/SkDraw.h
+++ b/src/core/SkDraw.h
@@ -122,8 +122,6 @@
static RectType ComputeRectType(const SkRect&, const SkPaint&, const SkMatrix&,
SkPoint* strokeSize);
- static SkScalar ComputeResScaleForStroking(const SkMatrix& );
-
private:
void drawBitmapAsMask(const SkBitmap&, const SkSamplingOptions&, const SkPaint&) const;
void drawFixedVertices(const SkVertices* vertices,
diff --git a/src/core/SkPaint.cpp b/src/core/SkPaint.cpp
index 1f37738..0fc25b1 100644
--- a/src/core/SkPaint.cpp
+++ b/src/core/SkPaint.cpp
@@ -374,11 +374,17 @@
bool SkPaint::getFillPath(const SkPath& src, SkPath* dst, const SkRect* cullRect,
SkScalar resScale) const {
+ return this->getFillPath(src, dst, cullRect, SkMatrix::Scale(resScale, resScale));
+}
+
+bool SkPaint::getFillPath(const SkPath& src, SkPath* dst, const SkRect* cullRect,
+ const SkMatrix& ctm) const {
if (!src.isFinite()) {
dst->reset();
return false;
}
+ const SkScalar resScale = SkPaintPriv::ComputeResScaleForStroking(ctm);
SkStrokeRec rec(*this, resScale);
#if defined(SK_BUILD_FOR_FUZZER)
@@ -391,7 +397,7 @@
const SkPath* srcPtr = &src;
SkPath tmpPath;
- if (fPathEffect && fPathEffect->filterPath(&tmpPath, src, &rec, cullRect)) {
+ if (fPathEffect && fPathEffect->filterPath(&tmpPath, src, &rec, cullRect, ctm)) {
srcPtr = &tmpPath;
}
diff --git a/src/core/SkPaintPriv.cpp b/src/core/SkPaintPriv.cpp
index a29e3cb..e6d4f94 100644
--- a/src/core/SkPaintPriv.cpp
+++ b/src/core/SkPaintPriv.cpp
@@ -106,3 +106,16 @@
p->setColorFilter(nullptr);
}
}
+
+SkScalar SkPaintPriv::ComputeResScaleForStroking(const SkMatrix& matrix) {
+ // Not sure how to handle perspective differently, so we just don't try (yet)
+ SkScalar sx = SkPoint::Length(matrix[SkMatrix::kMScaleX], matrix[SkMatrix::kMSkewY]);
+ SkScalar sy = SkPoint::Length(matrix[SkMatrix::kMSkewX], matrix[SkMatrix::kMScaleY]);
+ if (SkScalarsAreFinite(sx, sy)) {
+ SkScalar scale = std::max(sx, sy);
+ if (scale > 0) {
+ return scale;
+ }
+ }
+ return 1;
+}
diff --git a/src/core/SkPaintPriv.h b/src/core/SkPaintPriv.h
index 443e29a..f344797 100644
--- a/src/core/SkPaintPriv.h
+++ b/src/core/SkPaintPriv.h
@@ -73,6 +73,8 @@
// Since we may be filtering now, we need to know what color space to filter in,
// typically the color space of the device we're drawing into.
static void RemoveColorFilter(SkPaint*, SkColorSpace* dstCS);
+
+ static SkScalar ComputeResScaleForStroking(const SkMatrix&);
};
#endif
diff --git a/src/core/SkPathEffect.cpp b/src/core/SkPathEffect.cpp
index 3eb95b5..e2e3c72 100644
--- a/src/core/SkPathEffect.cpp
+++ b/src/core/SkPathEffect.cpp
@@ -15,11 +15,16 @@
bool SkPathEffect::filterPath(SkPath* dst, const SkPath& src, SkStrokeRec* rec,
const SkRect* bounds) const {
+ return this->filterPath(dst, src, rec, bounds, SkMatrix::I());
+}
+
+bool SkPathEffect::filterPath(SkPath* dst, const SkPath& src, SkStrokeRec* rec,
+ const SkRect* bounds, const SkMatrix& ctm) const {
SkPath tmp, *tmpDst = dst;
if (dst == &src) {
tmpDst = &tmp;
}
- if (as_PEB(this)->onFilterPath(tmpDst, src, rec, bounds)) {
+ if (as_PEB(this)->onFilterPath(tmpDst, src, rec, bounds, ctm)) {
if (dst == &src) {
*dst = tmp;
}
@@ -37,6 +42,10 @@
return as_PEB(this)->onAsADash(info);
}
+bool SkPathEffect::needsCTM() const {
+ return as_PEB(this)->onNeedsCTM();
+}
+
///////////////////////////////////////////////////////////////////////////////
/** \class SkPairPathEffect
@@ -90,14 +99,14 @@
: INHERITED(outer, inner) {}
bool onFilterPath(SkPath* dst, const SkPath& src, SkStrokeRec* rec,
- const SkRect* cullRect) const override {
+ const SkRect* cullRect, const SkMatrix& ctm) const override {
SkPath tmp;
const SkPath* ptr = &src;
- if (fPE1->filterPath(&tmp, src, rec, cullRect)) {
+ if (fPE1->filterPath(&tmp, src, rec, cullRect, ctm)) {
ptr = &tmp;
}
- return fPE0->filterPath(dst, *ptr, rec, cullRect);
+ return fPE0->filterPath(dst, *ptr, rec, cullRect, ctm);
}
SK_FLATTENABLE_HOOKS(SkComposePathEffect)
@@ -151,10 +160,10 @@
: INHERITED(first, second) {}
bool onFilterPath(SkPath* dst, const SkPath& src, SkStrokeRec* rec,
- const SkRect* cullRect) const override {
+ const SkRect* cullRect, const SkMatrix& ctm) const override {
// use bit-or so that we always call both, even if the first one succeeds
- return fPE0->filterPath(dst, src, rec, cullRect) |
- fPE1->filterPath(dst, src, rec, cullRect);
+ return fPE0->filterPath(dst, src, rec, cullRect, ctm) |
+ fPE1->filterPath(dst, src, rec, cullRect, ctm);
}
SK_FLATTENABLE_HOOKS(SkSumPathEffect)
diff --git a/src/core/SkPathEffectBase.h b/src/core/SkPathEffectBase.h
index efc2c53..93feea2 100644
--- a/src/core/SkPathEffectBase.h
+++ b/src/core/SkPathEffectBase.h
@@ -90,7 +90,19 @@
kSkPathEffect_Type, data, size, procs).release()));
}
- virtual bool onFilterPath(SkPath*, const SkPath&, SkStrokeRec*, const SkRect*) const = 0;
+ /**
+ * Filter the input path.
+ *
+ * The CTM parameter is provided for path effects that can use the information.
+ * The output of path effects must always be in the original (input) coordinate system,
+ * regardless of whether the path effect uses the CTM or not.
+ */
+ virtual bool onFilterPath(SkPath*, const SkPath&, SkStrokeRec*, const SkRect*,
+ const SkMatrix& /* ctm */) const = 0;
+
+ /** Path effects *requiring* a valid CTM should override to return true. */
+ virtual bool onNeedsCTM() const { return false; }
+
virtual bool onAsPoints(PointData*, const SkPath&, const SkStrokeRec&, const SkMatrix&,
const SkRect*) const {
return false;
diff --git a/src/core/SkScalerContext.cpp b/src/core/SkScalerContext.cpp
index 9134aee..08c1b96 100644
--- a/src/core/SkScalerContext.cpp
+++ b/src/core/SkScalerContext.cpp
@@ -745,7 +745,7 @@
if (fPathEffect) {
SkPath effectPath;
- if (fPathEffect->filterPath(&effectPath, localPath, &rec, nullptr)) {
+ if (fPathEffect->filterPath(&effectPath, localPath, &rec, nullptr, matrix)) {
localPath.swap(effectPath);
}
}
diff --git a/src/effects/Sk1DPathEffect.cpp b/src/effects/Sk1DPathEffect.cpp
index 0110725..44787a0 100644
--- a/src/effects/Sk1DPathEffect.cpp
+++ b/src/effects/Sk1DPathEffect.cpp
@@ -20,7 +20,8 @@
class Sk1DPathEffect : public SkPathEffectBase {
public:
protected:
- bool onFilterPath(SkPath* dst, const SkPath& src, SkStrokeRec*, const SkRect*) const override {
+ bool onFilterPath(SkPath* dst, const SkPath& src, SkStrokeRec*, const SkRect*,
+ const SkMatrix&) const override {
SkPathMeasure meas(src, false);
do {
int governor = MAX_REASONABLE_ITERATIONS;
@@ -92,9 +93,9 @@
}
bool onFilterPath(SkPath* dst, const SkPath& src, SkStrokeRec* rec,
- const SkRect* cullRect) const override {
+ const SkRect* cullRect, const SkMatrix& ctm) const override {
rec->setFillStyle();
- return this->INHERITED::onFilterPath(dst, src, rec, cullRect);
+ return this->INHERITED::onFilterPath(dst, src, rec, cullRect, ctm);
}
SkScalar begin(SkScalar contourLength) const override {
diff --git a/src/effects/Sk2DPathEffect.cpp b/src/effects/Sk2DPathEffect.cpp
index cca33db..c7e8d04 100644
--- a/src/effects/Sk2DPathEffect.cpp
+++ b/src/effects/Sk2DPathEffect.cpp
@@ -64,7 +64,7 @@
}
bool onFilterPath(SkPath* dst, const SkPath& src, SkStrokeRec* rec,
- const SkRect* cullRect) const override {
+ const SkRect* cullRect, const SkMatrix&) const override {
if (!fMatrixIsInvertible) {
return false;
}
@@ -115,8 +115,8 @@
}
bool onFilterPath(SkPath* dst, const SkPath& src, SkStrokeRec* rec,
- const SkRect* cullRect) const override {
- if (this->INHERITED::onFilterPath(dst, src, rec, cullRect)) {
+ const SkRect* cullRect, const SkMatrix& ctm) const override {
+ if (this->INHERITED::onFilterPath(dst, src, rec, cullRect, ctm)) {
rec->setStrokeStyle(fWidth);
return true;
}
diff --git a/src/effects/SkCornerPathEffect.cpp b/src/effects/SkCornerPathEffect.cpp
index ce25bad..620e30f 100644
--- a/src/effects/SkCornerPathEffect.cpp
+++ b/src/effects/SkCornerPathEffect.cpp
@@ -33,7 +33,8 @@
SkASSERT(radius > 0);
}
- bool onFilterPath(SkPath* dst, const SkPath& src, SkStrokeRec*, const SkRect*) const override {
+ bool onFilterPath(SkPath* dst, const SkPath& src, SkStrokeRec*, const SkRect*,
+ const SkMatrix&) const override {
if (fRadius <= 0) {
return false;
}
diff --git a/src/effects/SkDashImpl.h b/src/effects/SkDashImpl.h
index fbb343c..8439ca0 100644
--- a/src/effects/SkDashImpl.h
+++ b/src/effects/SkDashImpl.h
@@ -17,7 +17,8 @@
protected:
~SkDashImpl() override;
void flatten(SkWriteBuffer&) const override;
- bool onFilterPath(SkPath* dst, const SkPath& src, SkStrokeRec*, const SkRect*) const override;
+ bool onFilterPath(SkPath* dst, const SkPath& src, SkStrokeRec*, const SkRect*,
+ const SkMatrix&) const override;
bool onAsPoints(PointData* results, const SkPath& src, const SkStrokeRec&, const SkMatrix&,
const SkRect*) const override;
diff --git a/src/effects/SkDashPathEffect.cpp b/src/effects/SkDashPathEffect.cpp
index d392dc2..0886784 100644
--- a/src/effects/SkDashPathEffect.cpp
+++ b/src/effects/SkDashPathEffect.cpp
@@ -40,7 +40,7 @@
}
bool SkDashImpl::onFilterPath(SkPath* dst, const SkPath& src, SkStrokeRec* rec,
- const SkRect* cullRect) const {
+ const SkRect* cullRect, const SkMatrix&) const {
return SkDashPath::InternalFilter(dst, src, rec, cullRect, fIntervals, fCount,
fInitialDashLength, fInitialDashIndex, fIntervalLength);
}
diff --git a/src/effects/SkDiscretePathEffect.cpp b/src/effects/SkDiscretePathEffect.cpp
index cc2f49b..a57a67f 100644
--- a/src/effects/SkDiscretePathEffect.cpp
+++ b/src/effects/SkDiscretePathEffect.cpp
@@ -74,7 +74,7 @@
}
bool onFilterPath(SkPath* dst, const SkPath& src, SkStrokeRec* rec,
- const SkRect*) const override {
+ const SkRect*, const SkMatrix&) const override {
bool doFill = rec->isFillStyle();
SkPathMeasure meas(src, doFill);
diff --git a/src/effects/SkOpPE.h b/src/effects/SkOpPE.h
index 03d14d3..11c968f 100644
--- a/src/effects/SkOpPE.h
+++ b/src/effects/SkOpPE.h
@@ -18,7 +18,8 @@
protected:
void flatten(SkWriteBuffer&) const override;
- bool onFilterPath(SkPath* dst, const SkPath& src, SkStrokeRec*, const SkRect*) const override;
+ bool onFilterPath(SkPath* dst, const SkPath& src, SkStrokeRec*, const SkRect*,
+ const SkMatrix&) const override;
private:
SK_FLATTENABLE_HOOKS(SkOpPE)
@@ -38,7 +39,8 @@
protected:
void flatten(SkWriteBuffer&) const override;
- bool onFilterPath(SkPath* dst, const SkPath& src, SkStrokeRec*, const SkRect*) const override;
+ bool onFilterPath(SkPath* dst, const SkPath& src, SkStrokeRec*, const SkRect*,
+ const SkMatrix&) const override;
private:
SK_FLATTENABLE_HOOKS(SkMatrixPE)
@@ -61,7 +63,8 @@
protected:
void flatten(SkWriteBuffer&) const override;
- bool onFilterPath(SkPath* dst, const SkPath& src, SkStrokeRec*, const SkRect*) const override;
+ bool onFilterPath(SkPath* dst, const SkPath& src, SkStrokeRec*, const SkRect*,
+ const SkMatrix&) const override;
private:
SK_FLATTENABLE_HOOKS(SkStrokePE)
@@ -82,7 +85,8 @@
protected:
void flatten(SkWriteBuffer&) const override;
- bool onFilterPath(SkPath* dst, const SkPath& src, SkStrokeRec*, const SkRect*) const override;
+ bool onFilterPath(SkPath* dst, const SkPath& src, SkStrokeRec*, const SkRect*,
+ const SkMatrix&) const override;
private:
SK_FLATTENABLE_HOOKS(SkStrokeAndFillPE)
diff --git a/src/effects/SkOpPathEffect.cpp b/src/effects/SkOpPathEffect.cpp
index c44ca06..dd9a978 100644
--- a/src/effects/SkOpPathEffect.cpp
+++ b/src/effects/SkOpPathEffect.cpp
@@ -21,17 +21,17 @@
: fOne(std::move(one)), fTwo(std::move(two)), fOp(op) {}
bool SkOpPE::onFilterPath(SkPath* dst, const SkPath& src, SkStrokeRec* rec,
- const SkRect* cull) const {
+ const SkRect* cull, const SkMatrix& ctm) const {
SkPath one, two;
if (fOne) {
- if (!fOne->filterPath(&one, src, rec, cull)) {
+ if (!fOne->filterPath(&one, src, rec, cull, ctm)) {
return false;
}
} else {
one = src;
}
if (fTwo) {
- if (!fTwo->filterPath(&two, src, rec, cull)) {
+ if (!fTwo->filterPath(&two, src, rec, cull, ctm)) {
return false;
}
} else {
@@ -111,7 +111,8 @@
SkASSERT(matrix.isFinite());
}
-bool SkMatrixPE::onFilterPath(SkPath* dst, const SkPath& src, SkStrokeRec*, const SkRect*) const {
+bool SkMatrixPE::onFilterPath(SkPath* dst, const SkPath& src, SkStrokeRec*, const SkRect*,
+ const SkMatrix&) const {
src.transform(fMatrix, dst);
return true;
}
@@ -139,7 +140,8 @@
SkStrokePE::SkStrokePE(SkScalar width, SkPaint::Join join, SkPaint::Cap cap, SkScalar miter)
: fWidth(width), fMiter(miter), fJoin(join), fCap(cap) {}
-bool SkStrokePE::onFilterPath(SkPath* dst, const SkPath& src, SkStrokeRec*, const SkRect*) const {
+bool SkStrokePE::onFilterPath(SkPath* dst, const SkPath& src, SkStrokeRec*, const SkRect*,
+ const SkMatrix&) const {
SkStrokeRec rec(SkStrokeRec::kFill_InitStyle);
rec.setStrokeStyle(fWidth);
rec.setStrokeParams(fCap, fJoin, fMiter);
@@ -195,7 +197,7 @@
}
bool SkStrokeAndFillPE::onFilterPath(SkPath* dst, const SkPath& src, SkStrokeRec* rec,
- const SkRect*) const {
+ const SkRect*, const SkMatrix&) const {
// This one is weird, since we exist to allow this paint-style to go away. If we see it,
// just let the normal machine run its course.
if (rec->getStyle() == SkStrokeRec::kStrokeAndFill_Style) {
diff --git a/src/effects/SkTrimPE.h b/src/effects/SkTrimPE.h
index 3dd320e..4aa9420 100644
--- a/src/effects/SkTrimPE.h
+++ b/src/effects/SkTrimPE.h
@@ -17,7 +17,8 @@
protected:
void flatten(SkWriteBuffer&) const override;
- bool onFilterPath(SkPath* dst, const SkPath& src, SkStrokeRec*, const SkRect*) const override;
+ bool onFilterPath(SkPath* dst, const SkPath& src, SkStrokeRec*, const SkRect*,
+ const SkMatrix&) const override;
private:
SK_FLATTENABLE_HOOKS(SkTrimPE)
diff --git a/src/effects/SkTrimPathEffect.cpp b/src/effects/SkTrimPathEffect.cpp
index 7c91491..51307f6 100644
--- a/src/effects/SkTrimPathEffect.cpp
+++ b/src/effects/SkTrimPathEffect.cpp
@@ -48,7 +48,8 @@
SkTrimPE::SkTrimPE(SkScalar startT, SkScalar stopT, SkTrimPathEffect::Mode mode)
: fStartT(startT), fStopT(stopT), fMode(mode) {}
-bool SkTrimPE::onFilterPath(SkPath* dst, const SkPath& src, SkStrokeRec*, const SkRect*) const {
+bool SkTrimPE::onFilterPath(SkPath* dst, const SkPath& src, SkStrokeRec*, const SkRect*,
+ const SkMatrix&) const {
if (fStartT >= fStopT) {
SkASSERT(fMode == SkTrimPathEffect::Mode::kNormal);
return true;
diff --git a/src/gpu/GrStyle.cpp b/src/gpu/GrStyle.cpp
index caf361b..1d5a48b 100644
--- a/src/gpu/GrStyle.cpp
+++ b/src/gpu/GrStyle.cpp
@@ -130,10 +130,15 @@
if (!fPathEffect) {
return false;
}
+
+ // TODO: [skbug.com/11957] Plumb CTM callers and pass it to filterPath().
+ SkASSERT(!fPathEffect->needsCTM());
+
if (SkPathEffect::kDash_DashType == fDashInfo.fType) {
// We apply the dash ourselves here rather than using the path effect. This is so that
// we can control whether the dasher applies the strokeRec for special cases. Our keying
// depends on the strokeRec being applied separately.
+ SkASSERT(!fPathEffect->needsCTM()); // Make sure specified PE doesn't need CTM
SkScalar phase = fDashInfo.fPhase;
const SkScalar* intervals = fDashInfo.fIntervals.get();
int intervalCnt = fDashInfo.fIntervals.count();
diff --git a/src/gpu/GrTestUtils.cpp b/src/gpu/GrTestUtils.cpp
index fbc7f03..328f664 100644
--- a/src/gpu/GrTestUtils.cpp
+++ b/src/gpu/GrTestUtils.cpp
@@ -292,8 +292,8 @@
&fInitialDashIndex, &fIntervalLength, &fPhase);
}
- bool TestDashPathEffect::onFilterPath(SkPath* dst, const SkPath& src, SkStrokeRec* rec,
- const SkRect* cullRect) const {
+bool TestDashPathEffect::onFilterPath(SkPath* dst, const SkPath& src, SkStrokeRec* rec,
+ const SkRect* cullRect, const SkMatrix&) const {
return SkDashPath::InternalFilter(dst, src, rec, cullRect, fIntervals.get(), fCount,
fInitialDashLength, fInitialDashIndex, fIntervalLength);
}
diff --git a/src/gpu/GrTestUtils.h b/src/gpu/GrTestUtils.h
index 1b177a8..59575e4 100644
--- a/src/gpu/GrTestUtils.h
+++ b/src/gpu/GrTestUtils.h
@@ -77,7 +77,8 @@
const char* getTypeName() const override { return nullptr; }
protected:
- bool onFilterPath(SkPath* dst, const SkPath&, SkStrokeRec* , const SkRect*) const override;
+ bool onFilterPath(SkPath* dst, const SkPath&, SkStrokeRec* , const SkRect*,
+ const SkMatrix&) const override;
DashType onAsADash(DashInfo* info) const override;
private:
diff --git a/tests/GrStyledShapeTest.cpp b/tests/GrStyledShapeTest.cpp
index 895d482..28fe88b 100644
--- a/tests/GrStyledShapeTest.cpp
+++ b/tests/GrStyledShapeTest.cpp
@@ -1169,7 +1169,7 @@
protected:
bool onFilterPath(SkPath* dst, const SkPath& src, SkStrokeRec*,
- const SkRect* cullR) const override {
+ const SkRect* cullR, const SkMatrix&) const override {
dst->reset();
dst->addRRect(RRect());
return true;
@@ -1254,7 +1254,7 @@
protected:
bool onFilterPath(SkPath* dst, const SkPath& src, SkStrokeRec*,
- const SkRect* cullR) const override {
+ const SkRect* cullR, const SkMatrix&) const override {
*dst = src;
// To avoid triggering data-based keying of paths with few verbs we add many segments.
for (int i = 0; i < 100; ++i) {
@@ -1302,7 +1302,7 @@
protected:
bool onFilterPath(SkPath* dst, const SkPath& src, SkStrokeRec* strokeRec,
- const SkRect* cullR) const override {
+ const SkRect* cullR, const SkMatrix&) const override {
*dst = src;
strokeRec->setHairlineStyle();
return true;
@@ -1386,7 +1386,7 @@
const char* getTypeName() const override { return nullptr; }
protected:
bool onFilterPath(SkPath* dst, const SkPath& src, SkStrokeRec*,
- const SkRect* cullR) const override {
+ const SkRect* cullR, const SkMatrix&) const override {
dst->reset();
if (fInvert) {
dst->toggleInverseFillType();
@@ -1475,7 +1475,7 @@
const char* getTypeName() const override { return nullptr; }
protected:
bool onFilterPath(SkPath* dst, const SkPath& src, SkStrokeRec*,
- const SkRect* cullR) const override {
+ const SkRect* cullR, const SkMatrix&) const override {
return false;
}
private: