diff --git a/modules/canvaskit/CHANGELOG.md b/modules/canvaskit/CHANGELOG.md index 0c9b0a808b..a826dd56e1 100644 --- a/modules/canvaskit/CHANGELOG.md +++ b/modules/canvaskit/CHANGELOG.md @@ -48,6 +48,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - `CanvasKit.LTRBiRect` and `CanvasKit.XYWHiRect` as helpers to create SkIRects. + - `SkCanvas.drawRect4f` as a somewhat experimental way to have array-free APIs for clients that + already have their own representation of Rect. This is experimental because we don't know + if it's faster/better under real-world use and because we don't want to commit to having these + for all Rect APIs (and for similar types) until it has baked in a bit. ## [0.17.3] - 2020-08-05 diff --git a/modules/canvaskit/canvaskit_bindings.cpp b/modules/canvaskit/canvaskit_bindings.cpp index 6c9fd29792..ffef32bc19 100644 --- a/modules/canvaskit/canvaskit_bindings.cpp +++ b/modules/canvaskit/canvaskit_bindings.cpp @@ -1053,6 +1053,12 @@ EMSCRIPTEN_BINDINGS(Skia) { const SkRect* rect = reinterpret_cast(fPtr); self.drawRect(*rect, paint); })) + .function("drawRect4f", optional_override([](SkCanvas& self, SkScalar left, SkScalar top, + SkScalar right, SkScalar bottom, + const SkPaint paint)->void { + const SkRect rect = SkRect::MakeLTRB(left, top, right, bottom); + self.drawRect(rect, paint); + })) .function("_drawShadow", optional_override([](SkCanvas& self, const SkPath& path, const SkPoint3& zPlaneParams, const SkPoint3& lightPos, SkScalar lightRadius, diff --git a/modules/canvaskit/externs.js b/modules/canvaskit/externs.js index 9cd13bba8c..0f978e76d3 100644 --- a/modules/canvaskit/externs.js +++ b/modules/canvaskit/externs.js @@ -209,6 +209,7 @@ var CanvasKit = { drawParagraph: function() {}, drawPath: function() {}, drawPicture: function() {}, + drawRect4f: function() {}, drawText: function() {}, drawTextBlob: function() {}, drawVertices: function() {}, diff --git a/modules/canvaskit/tests/canvas.spec.js b/modules/canvaskit/tests/canvas.spec.js index f12ba2d035..e581d7187a 100644 --- a/modules/canvaskit/tests/canvas.spec.js +++ b/modules/canvaskit/tests/canvas.spec.js @@ -259,7 +259,7 @@ describe('Canvas Behavior', () => { paint.setColorFilter(lerp) canvas.drawRect(CanvasKit.LTRBRect(50, 10, 100, 60), paint); paint.setColorFilter(red) - canvas.drawRect(CanvasKit.LTRBRect(90, 10, 140, 60), paint); + canvas.drawRect4f(90, 10, 140, 60, paint); const r = CanvasKit.SkColorMatrix.rotated(0, .707, -.707); const b = CanvasKit.SkColorMatrix.rotated(2, .5, .866); diff --git a/tools/perf-canvaskit-puppeteer/canvas_perf.html b/tools/perf-canvaskit-puppeteer/canvas_perf.html index 48a927239c..c0368b11b7 100644 --- a/tools/perf-canvaskit-puppeteer/canvas_perf.html +++ b/tools/perf-canvaskit-puppeteer/canvas_perf.html @@ -79,15 +79,23 @@ document.getElementById('start_bench').addEventListener('click', async () => { window._perfData = {}; - // canvas_perf.js should have defined a single object called tests that is an array of - // objects having: + // canvas_perf.js should have defined an array called tests whose objects have: // setup: A function called once before testing begins, it is expected to make its // own canvas and put it in ctx. // test: A function called to draw one frame // teardown: A function called after testing finishes // description: A human readable description // perfkey: A key used to save the results in perf.skia.org. - for (const t of tests) { + // + // For quick local bench testing, there is also an array called onlytests. This way + // a developer can replace tests.push with onlytests.push to just run one or two + // performance benchmarks they care about. + let testsToRun = tests; + if (onlytests.length) { + testsToRun = onlytests; + } + + for (const t of testsToRun) { let ctx = { 'surface': surface, 'files': externalFiles, diff --git a/tools/perf-canvaskit-puppeteer/canvas_perf.js b/tools/perf-canvaskit-puppeteer/canvas_perf.js index e08b5905db..81853a6387 100644 --- a/tools/perf-canvaskit-puppeteer/canvas_perf.js +++ b/tools/perf-canvaskit-puppeteer/canvas_perf.js @@ -1,3 +1,4 @@ +const onlytests = []; const tests = []; // In all tests, the canvas is 600 by 600 px. // tests should NOT call ctx.surface.flush() @@ -93,6 +94,80 @@ tests.push({ perfKey: 'canvas_drawRRect', }); +tests.push({ + description: 'Draw 10K colored rects', + setup: function(CanvasKit, ctx) { + ctx.canvas = ctx.surface.getCanvas(); + + ctx.paint = new CanvasKit.SkPaint(); + ctx.paint.setAntiAlias(true); + ctx.paint.setStyle(CanvasKit.PaintStyle.Fill); + }, + test: function(CanvasKit, ctx) { + for (let i=0; i<10000; i++) { + const x = Math.random()*550; + const y = Math.random()*550; + ctx.paint.setColor(randomColorTwo(CanvasKit, 1, 2)); + ctx.canvas.drawRect(CanvasKit.LTRBRect(x, y, x+50, y+50), ctx.paint); + } + }, + teardown: function(CanvasKit, ctx) { + ctx.paint.delete(); + }, + perfKey: 'canvas_drawRect', +}); + +tests.push({ + description: "Draw 10K colored rects with malloc'd rect", + setup: function(CanvasKit, ctx) { + ctx.canvas = ctx.surface.getCanvas(); + + ctx.paint = new CanvasKit.SkPaint(); + ctx.paint.setAntiAlias(true); + ctx.paint.setStyle(CanvasKit.PaintStyle.Fill); + ctx.rect = CanvasKit.Malloc(Float32Array, 4); + }, + test: function(CanvasKit, ctx) { + for (let i=0; i<10000; i++) { + ctx.paint.setColor(randomColorTwo(CanvasKit, 1, 2)); + const ta = ctx.rect.toTypedArray(); + ta[0] = Math.random()*550; // x + ta[1] = Math.random()*550; // y + ta[2] = ta[0] + 50; + ta[3] = ta[1] + 50; + ctx.canvas.drawRect(ta, ctx.paint); + } + }, + teardown: function(CanvasKit, ctx) { + ctx.paint.delete(); + CanvasKit.Free(ctx.rect); + }, + perfKey: 'canvas_drawRect_malloc', +}); + +tests.push({ + description: 'Draw 10K colored rects using 4 float API', + setup: function(CanvasKit, ctx) { + ctx.canvas = ctx.surface.getCanvas(); + + ctx.paint = new CanvasKit.SkPaint(); + ctx.paint.setAntiAlias(true); + ctx.paint.setStyle(CanvasKit.PaintStyle.Fill); + }, + test: function(CanvasKit, ctx) { + for (let i=0; i<10000; i++) { + const x = Math.random()*550; + const y = Math.random()*550; + ctx.paint.setColor(randomColorTwo(CanvasKit, 1, 2)); + ctx.canvas.drawRect4f(x, y, x+50, y+50, ctx.paint); + } + }, + teardown: function(CanvasKit, ctx) { + ctx.paint.delete(); + }, + perfKey: 'canvas_drawRect4f', +}); + tests.push({ description: 'Compute tonal colors', setup: function(CanvasKit, ctx) {},