Reputation: 150
I'm developing a 2D graphics rendering application in a web page using the canvaskit library (https://www.npmjs.com/package/canvaskit-wasm). I've encountered a confusing issue when creating path objects and calling the toCmds()
method repeatedly. For example:
for (let i = 0; i < 800000; i++) {
let path = new CK.Path();
path = path.addRRect([0, 0, 25401, 26116, 160, 160, 160, 160, 160, 160, 160, 160]);
path.toCmds();
}
This code snippet causes a binding error with a null pointer, and the specific error message is as follows:
BindingError {name: 'BindingError', message: 'parameter 0 has unknown type 0', stack: 'BindingError: parameter 0 has unknown type 0\n a…/canvaskit.debug.wasm:wasm-function[307]:0x2752f)'} message: "parameter 0 has unknown type 0" name: "BindingError" stack: "BindingError: parameter 0 has unknown type 0\n at BindingError.
After debugging, it appears that the glue code in JavaScript receives a null pointer when trying to retrieve the return value passed from wasm to js inside the toCmds method. Additionally, if the addRect/addPath operation remains unchanged in each iteration of the loop, the timing (the value of i in the for loop) at which toCmds starts throwing the error is always the same. However, if the content of addPath is changed, the value of i at which the error occurs in the for loop changes. This seems to be an issue caused by wasm memory not being released. So, I added a path.delete operation in the code, like this:
for (let i = 0; i < 800000; i++) {
let path = new CK.Path();
path = path.addRRect([0, 0, 25401, 26116, 160, 160, 160, 160, 160, 160, 160, 160]);
path.toCmds();
path.delete();
}
The error is resolved after adding the delete operation, confirming that the error was indeed caused by a memory issue. However, what confuses me is that only the toCmds method triggers this memory problem. If I use other methods, such as toSVGString, even without the delete operation, executing it many times does not cause an out-of-memory error. For example:
for (let i = 0; i < 800000; i++) {
let path = new CK.Path();
path = path.addRRect([0, 0, 25401, 26116, 160, 160, 160, 160, 160, 160, 160, 160]);
path.toSVGString();
}
So, my question is, why does the toCmds method cause this memory issue? If I don't perform the delete() method, are there any other ways to use the toCmds method correctly?
Upvotes: 0
Views: 42