[canvaskit] Add drawRect4f as example 'fast path' API
I added 3 tests, one using the drawRect API naively, one using drawRect with a Malloc'd array, and one using the drawRect4f. rough local measurements: - [baseline with tip of tree code]: 50ms - naive drawRect: 40ms - drawRect with malloc: 28ms - drawRect4f: 27ms I also tried the benchmarks locally with taking in paint as a const reference. I did not see any changes, but that could just be small sample size. I plan to land the code as is for now, collect a bit of data in Perf and then try landing the const reference stuff and see if we get something measurable. To aid this, I added in a helper list of tests to only run some benchmarks easily. Change-Id: I790b2d6fc32c125a4d371768fffb19ab22633d4e Reviewed-on: https://skia-review.googlesource.com/c/skia/+/314622 Reviewed-by: Kevin Lubick <kjlubick@google.com>
This commit is contained in:
parent
bdc214a50e
commit
2753b12ff5
@ -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
|
||||
|
||||
|
@ -1053,6 +1053,12 @@ EMSCRIPTEN_BINDINGS(Skia) {
|
||||
const SkRect* rect = reinterpret_cast<const SkRect*>(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,
|
||||
|
@ -209,6 +209,7 @@ var CanvasKit = {
|
||||
drawParagraph: function() {},
|
||||
drawPath: function() {},
|
||||
drawPicture: function() {},
|
||||
drawRect4f: function() {},
|
||||
drawText: function() {},
|
||||
drawTextBlob: function() {},
|
||||
drawVertices: function() {},
|
||||
|
@ -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);
|
||||
|
@ -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,
|
||||
|
@ -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) {},
|
||||
|
Loading…
Reference in New Issue
Block a user