Add Perf jobs for PathKit

We have a similar ingestion strategy to Gold.

I tried to use something off the shelf like benchmark.js
but passing the PathKit context into the benchmarks was
non-trivial. Plus, making a basic benchmarking tool
ended up being not too hard.

We should be able to re-use the docker container/aggregator
for CanvasKit too.

Bug: skia:
Change-Id: I613dfc58ea57c31cf71566a8ac55f8df9272ad25
Reviewed-on: https://skia-review.googlesource.com/c/161620
Commit-Queue: Kevin Lubick <kjlubick@google.com>
Reviewed-by: Joe Gregorio <jcgregorio@google.com>
Reviewed-by: Stephan Altmueller <stephana@google.com>
diff --git a/modules/pathkit/perf/effects.bench.js b/modules/pathkit/perf/effects.bench.js
new file mode 100644
index 0000000..d1be9ec
--- /dev/null
+++ b/modules/pathkit/perf/effects.bench.js
@@ -0,0 +1,143 @@
+
+
+describe('PathKit\'s Effects', function() {
+    // Note, don't try to print the PathKit object - it can cause Karma/Jasmine to lock up.
+    var PathKit = null;
+    const LoadPathKit = new Promise(function(resolve, reject) {
+        if (PathKit) {
+            resolve();
+        } else {
+            PathKitInit({
+                locateFile: (file) => '/pathkit/'+file,
+            }).then((_PathKit) => {
+                PathKit = _PathKit;
+                resolve();
+            });
+        }
+    });
+
+    // see https://fiddle.skia.org/c/@discrete_path
+    function drawStar(X=128, Y=128, R=116) {
+        let p = PathKit.NewPath();
+        p.moveTo(X + R, Y);
+        for (let i = 1; i < 8; i++) {
+          let a = 2.6927937 * i;
+          p.lineTo(X + R * Math.cos(a), Y + R * Math.sin(a));
+        }
+        p.closePath();
+        return p;
+    }
+
+    it('effects_dash', function(done) {
+        function setup(ctx) {
+            ctx.path = drawStar();
+        }
+
+        function test(ctx) {
+            let path = ctx.path.copy().dash(10, 3, 1);
+            path.delete();
+        }
+
+        function teardown(ctx) {
+            ctx.path.delete();
+        }
+
+        LoadPathKit.then(() => {
+            benchmarkAndReport('effects_dash', setup, test, teardown).then(() => {
+                done();
+            }).catch(reportError(done));
+        });
+    });
+
+    it('effects_trim', function(done) {
+        function setup(ctx) {
+            ctx.path = drawStar();
+        }
+
+        function test(ctx) {
+            let path = ctx.path.copy().trim(0.25, .8);
+            path.delete();
+        }
+
+        function teardown(ctx) {
+            ctx.path.delete();
+        }
+
+        LoadPathKit.then(() => {
+            benchmarkAndReport('effects_trim', setup, test, teardown).then(() => {
+                done();
+            }).catch(reportError(done));
+        });
+    });
+
+    it('effects_trim_complement', function(done) {
+        function setup(ctx) {
+            ctx.path = drawStar();
+        }
+
+        function test(ctx) {
+            let path = ctx.path.copy().trim(0.25, .8, true);
+            path.delete();
+        }
+
+        function teardown(ctx) {
+            ctx.path.delete();
+        }
+
+        LoadPathKit.then(() => {
+            benchmarkAndReport('effects_trim_complement', setup, test, teardown).then(() => {
+                done();
+            }).catch(reportError(done));
+        });
+    });
+
+    it('effects_transform', function(done) {
+        function setup(ctx) {
+            ctx.path = drawStar();
+        }
+
+        function test(ctx) {
+            let path = ctx.path.copy().transform(3, 0, 0,
+                                             0, 3, 0,
+                                             0, 0, 1);
+            path.delete();
+        }
+
+        function teardown(ctx) {
+            ctx.path.delete();
+        }
+
+        LoadPathKit.then(() => {
+            benchmarkAndReport('effects_transform', setup, test, teardown).then(() => {
+                done();
+            }).catch(reportError(done));
+        });
+    });
+
+    it('effects_stroke', function(done) {
+        function setup(ctx) {
+            ctx.path = drawStar();
+        }
+
+        function test(ctx) {
+            let path = ctx.path.copy().stroke({
+                    width: 15,
+                    join: PathKit.StrokeJoin.BEVEL,
+                    cap: PathKit.StrokeCap.BUTT,
+                    miter_limit: 2,
+                });
+            path.delete();
+        }
+
+        function teardown(ctx) {
+            ctx.path.delete();
+        }
+
+        LoadPathKit.then(() => {
+            benchmarkAndReport('effects_stroke', setup, test, teardown).then(() => {
+                done();
+            }).catch(reportError(done));
+        });
+    });
+
+});
\ No newline at end of file