* This file houses utilities for copying blocks of memory to and from
* the WASM heap.
*/
* 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.
* Any memory allocated by CanvasKit.Malloc needs to be released with CanvasKit.Free.
*
* const mObj = CanvasKit.Malloc(Float32Array, 20);
* Get a TypedArray view around the malloc'd memory (this does not copy anything).
* const ta = mObj.toTypedArray();
* // store data into ta
* const cf = CanvasKit.ColorFilter.MakeMatrix(ta); // mObj could also be used.
*
* // eventually...
* CanvasKit.Free(mObj);
*
* @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);
return {
'_ck': true,
'length': len,
'byteOffset': ptr,
typedArray: null,
'subarray': function(start, end) {
var sa = this['toTypedArray']().subarray(start, end);
sa['_ck'] = true;
return sa;
},
'toTypedArray': function() {
if (this.typedArray && this.typedArray.length) {
return this.typedArray;
}
this.typedArray = new typedArray(CanvasKit.HEAPU8.buffer, ptr, len);
this.typedArray['_ck'] = true;
return this.typedArray;
},
};
};
* Free frees the memory returned by Malloc.
* Any memory allocated by CanvasKit.Malloc needs to be released with CanvasKit.Free.
*/
CanvasKit.Free = function(mallocObj) {
CanvasKit._free(mallocObj['byteOffset']);
mallocObj['byteOffset'] = nullptr;
mallocObj['toTypedArray'] = null;
mallocObj.typedArray = null;
};
function freeArraysThatAreNotMallocedByUsers(ptr, arr) {
if (!wasMalloced(arr)) {
CanvasKit._free(ptr);
}
}
function wasMalloced(obj) {
return obj && obj['_ck'];
}
var _scratch3x3MatrixPtr = nullptr;
var _scratch3x3Matrix;
var _scratch4x4MatrixPtr = nullptr;
var _scratch4x4Matrix;
var _scratchColorPtr = nullptr;
var _scratchColor;
var _scratchFourFloatsA;
var _scratchFourFloatsAPtr = nullptr;
var _scratchFourFloatsB;
var _scratchFourFloatsBPtr = nullptr;
var _scratchThreeFloatsA;
var _scratchThreeFloatsAPtr = nullptr;
var _scratchThreeFloatsB;
var _scratchThreeFloatsBPtr = nullptr;
var _scratchIRect;
var _scratchIRectPtr = nullptr;
var _scratchRRect;
var _scratchRRectPtr = nullptr;
var _scratchRRect2;
var _scratchRRect2Ptr = nullptr;
function copy1dArray(arr, dest, ptr) {
if (!arr || !arr.length) {
return nullptr;
}
if (wasMalloced(arr)) {
return arr.byteOffset;
}
var bytesPerElement = CanvasKit[dest].BYTES_PER_ELEMENT;
if (!ptr) {
ptr = CanvasKit._malloc(arr.length * bytesPerElement);
}
CanvasKit[dest].set(arr, ptr / bytesPerElement);
return ptr;
}
function copyFlexibleColorArray(colors) {
var result = {
colorPtr: nullptr,
count: colors.length,
colorType: CanvasKit.ColorType.RGBA_F32,
};
if (colors instanceof Float32Array) {
result.colorPtr = copy1dArray(colors, 'HEAPF32');
result.count = colors.length / 4;
} else if (colors instanceof Uint32Array) {
result.colorPtr = copy1dArray(colors, 'HEAPU32');
result.colorType = CanvasKit.ColorType.RGBA_8888;
} else if (colors instanceof Array) {
result.colorPtr = copyColorArray(colors);
} else {
throw('Invalid argument to copyFlexibleColorArray, Not a color array '+typeof(colors));
}
return result;
}
function copyColorArray(arr) {
if (!arr || !arr.length) {
return nullptr;
}
var ptr = CanvasKit._malloc(arr.length * 4 * 4);
var idx = 0;
var adjustedPtr = ptr / 4;
for (var r = 0; r < arr.length; r++) {
for (var c = 0; c < 4; c++) {
CanvasKit.HEAPF32[adjustedPtr + idx] = arr[r][c];
idx++;
}
}
return ptr;
}
var defaultPerspective = Float32Array.of(0, 0, 1);
function copy3x3MatrixToWasm(matr) {
if (!matr) {
return nullptr;
}
var wasm3x3Matrix = _scratch3x3Matrix['toTypedArray']();
if (matr.length) {
if (matr.length === 6 || matr.length === 9) {
copy1dArray(matr, 'HEAPF32', _scratch3x3MatrixPtr);
if (matr.length === 6) {
CanvasKit.HEAPF32.set(defaultPerspective, 6 + _scratch3x3MatrixPtr / 4);
}
return _scratch3x3MatrixPtr;
} else if (matr.length === 16) {
wasm3x3Matrix[0] = matr[0];
wasm3x3Matrix[1] = matr[1];
wasm3x3Matrix[2] = matr[3];
wasm3x3Matrix[3] = matr[4];
wasm3x3Matrix[4] = matr[5];
wasm3x3Matrix[5] = matr[7];
wasm3x3Matrix[6] = matr[12];
wasm3x3Matrix[7] = matr[13];
wasm3x3Matrix[8] = matr[15];
return _scratch3x3MatrixPtr;
}
throw 'invalid matrix size';
} else if (matr['m11'] === undefined) {
throw 'invalid matrix argument';
}
wasm3x3Matrix[0] = matr['m11'];
wasm3x3Matrix[1] = matr['m21'];
wasm3x3Matrix[2] = matr['m41'];
wasm3x3Matrix[3] = matr['m12'];
wasm3x3Matrix[4] = matr['m22'];
wasm3x3Matrix[5] = matr['m42'];
wasm3x3Matrix[6] = matr['m14'];
wasm3x3Matrix[7] = matr['m24'];
wasm3x3Matrix[8] = matr['m44'];
return _scratch3x3MatrixPtr;
}
function copy4x4MatrixToWasm(matr) {
if (!matr) {
return nullptr;
}
var wasm4x4Matrix = _scratch4x4Matrix['toTypedArray']();
if (matr.length) {
if (matr.length !== 16 && matr.length !== 6 && matr.length !== 9) {
throw 'invalid matrix size';
}
if (matr.length === 16) {
return copy1dArray(matr, 'HEAPF32', _scratch4x4MatrixPtr);
}
wasm4x4Matrix.fill(0);
wasm4x4Matrix[0] = matr[0];
wasm4x4Matrix[1] = matr[1];
wasm4x4Matrix[3] = matr[2];
wasm4x4Matrix[4] = matr[3];
wasm4x4Matrix[5] = matr[4];
wasm4x4Matrix[7] = matr[5];
wasm4x4Matrix[10] = 1;
wasm4x4Matrix[12] = matr[6];
wasm4x4Matrix[13] = matr[7];
wasm4x4Matrix[15] = matr[8];
if (matr.length === 6) {
wasm4x4Matrix[12]=0;
wasm4x4Matrix[13]=0;
wasm4x4Matrix[15]=1;
}
return _scratch4x4MatrixPtr;
} else if (matr['m11'] === undefined) {
throw 'invalid matrix argument';
}
wasm4x4Matrix[0] = matr['m11'];
wasm4x4Matrix[1] = matr['m21'];
wasm4x4Matrix[2] = matr['m31'];
wasm4x4Matrix[3] = matr['m41'];
wasm4x4Matrix[4] = matr['m12'];
wasm4x4Matrix[5] = matr['m22'];
wasm4x4Matrix[6] = matr['m32'];
wasm4x4Matrix[7] = matr['m42'];
wasm4x4Matrix[8] = matr['m13'];
wasm4x4Matrix[9] = matr['m23'];
wasm4x4Matrix[10] = matr['m33'];
wasm4x4Matrix[11] = matr['m43'];
wasm4x4Matrix[12] = matr['m14'];
wasm4x4Matrix[13] = matr['m24'];
wasm4x4Matrix[14] = matr['m34'];
wasm4x4Matrix[15] = matr['m44'];
return _scratch4x4MatrixPtr;
}
function copy4x4MatrixFromWasm(matrPtr) {
var rv = new Array(16);
for (var i = 0; i < 16; i++) {
rv[i] = CanvasKit.HEAPF32[matrPtr/4 + i];
}
return rv;
}
function copyColorToWasm(color4f, ptr) {
return copy1dArray(color4f, 'HEAPF32', ptr || _scratchColorPtr);
}
function copyColorComponentsToWasm(r, g, b, a) {
var colors = _scratchColor['toTypedArray']();
colors[0] = r;
colors[1] = g;
colors[2] = b;
colors[3] = a;
return _scratchColorPtr;
}
function copyColorToWasmNoScratch(color4f) {
return copy1dArray(color4f, 'HEAPF32');
}
function copyColorFromWasm(colorPtr) {
var rv = new Float32Array(4);
for (var i = 0; i < 4; i++) {
rv[i] = CanvasKit.HEAPF32[colorPtr/4 + i];
}
return rv;
}
function copyRectToWasm(fourFloats, ptr) {
return copy1dArray(fourFloats, 'HEAPF32', ptr || _scratchFourFloatsAPtr);
}
function copyIRectToWasm(fourInts, ptr) {
return copy1dArray(fourInts, 'HEAP32', ptr || _scratchIRectPtr);
}
function copyIRectFromWasm(rectMalloc, outputArray) {
var ta = rectMalloc['toTypedArray']();
if (outputArray) {
outputArray.set(ta);
return outputArray;
}
return ta.slice();
}
function copyRRectToWasm(twelveFloats, ptr) {
return copy1dArray(twelveFloats, 'HEAPF32', ptr || _scratchRRectPtr);
}