[canvaskit] Expose Malloc to save copies in some places

By adding in the check to copy1dArray, some places get the benefit
for free.

Change-Id: I12e230465737dc6276feb02ddb37e3c417777055
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/249878
Reviewed-by: Kevin Lubick <kjlubick@google.com>
This commit is contained in:
Kevin Lubick 2019-10-22 09:04:32 -04:00
parent f3f8ac37e4
commit e25df6cf78
4 changed files with 73 additions and 0 deletions

View File

@ -5,6 +5,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [Unreleased]
### Added
- Experimental `CanvasKit.Malloc`, which can be used to create a
TypedArray backed by the C++ WASM memory. This can save a copy in some cases
(e.g. SkColorFilter.MakeMatrix). This is an advanced feature, so use it with care.
## [0.8.0] - 2019-10-21

View File

@ -59,6 +59,8 @@ var CanvasKit = {
/** @return {RadialCanvasGradient} */
MakeTwoPointConicalGradientShader: function() {},
MakeWebGLCanvasSurface: function() {},
/** @return {TypedArray} */
Malloc: function() {},
/** @return {TonalColors} */
computeTonalColors: function() {},
currentContext: function() {},

View File

@ -70,6 +70,10 @@ function copy1dArray(arr, dest, ptr) {
if (!arr || !arr.length) {
return nullptr;
}
// This was created with CanvasKit.Malloc, so it's already been copied.
if (arr['_ck']) {
return arr.byteOffset;
}
if (!ptr) {
ptr = CanvasKit._malloc(arr.length * dest.BYTES_PER_ELEMENT);
}
@ -394,3 +398,27 @@ CanvasKit.RSXFormBuilder = CanvasKit.FourFloatArrayHelper;
* the array every time.
*/
CanvasKit.SkColorBuilder = CanvasKit.OneUIntArrayHelper;
/**
* Malloc returns a TypedArray backed by the C++ memory of the
* given length. It should only be used by advanced users who
* can manage memory and initialize values properly. When used
* correctly, it can save copying of data between JS and C++.
* When used incorrectly, it can lead to memory leaks.
*
* const ta = CanvasKit.Malloc(Float32Array, 20);
* // store data into ta
* const cf = CanvasKit.SkColorFilter.MakeMatrix(ta);
* // MakeMatrix cleans up the ptr automatically.
*
* @param {TypedArray} typedArray - constructor for the typedArray.
* @param {number} len - number of elements to store.
*/
CanvasKit.Malloc = function(typedArray, len) {
var byteLen = len * typedArray.BYTES_PER_ELEMENT;
var ptr = CanvasKit._malloc(byteLen);
var ta = new typedArray(CanvasKit.buffer, ptr, len);
// add a marker that this was allocated in C++ land
ta['_ck'] = true;
return ta;
}

View File

@ -313,6 +313,8 @@ describe('CanvasKit\'s Canvas Behavior', function() {
cm = CanvasKit.SkColorMatrix.concat(cm, b);
CanvasKit.SkColorMatrix.postTranslate(cm, 20, 0, -10, 0);
console.log(cm);
const mat = CanvasKit.SkColorFilter.MakeMatrix(cm);
const final = CanvasKit.SkColorFilter.MakeCompose(mat, lerp);
@ -332,4 +334,41 @@ describe('CanvasKit\'s Canvas Behavior', function() {
}));
});
it('can use Malloc to save a copy', function(done) {
LoadCanvasKit.then(catchException(done, () => {
const surface = CanvasKit.MakeCanvasSurface('test');
expect(surface).toBeTruthy('Could not make surface')
if (!surface) {
done();
return;
}
const canvas = surface.getCanvas();
const path = starPath(CanvasKit);
const paint = new CanvasKit.SkPaint();
const src = [
0.8, 0.45, 2, 0, 20,
0.53, -0.918, 0.566, 0, 0,
0.53, -0.918, -0.566, 0, -10,
0, 0, 0, 0.8, 0,
]
const cm = new CanvasKit.Malloc(Float32Array, 20);
for (i in src) {
cm[i] = src[i];
}
const final = CanvasKit.SkColorFilter.MakeMatrix(cm);
paint.setColorFilter(final)
canvas.drawRect(CanvasKit.LTRBRect(10, 70, 140, 120), paint);
surface.flush();
path.delete();
paint.delete();
final.delete();
reportSurface(surface, 'colorfilters_malloc_canvas', done);
}));
});
});