node-sdl
node-sdl copied to clipboard
Boost performance?
Is there a way to boost performance for the canvas version? Or should I choose WebGL instead?
From my personal experience, using @kmamal/gl will be the best choice, although it's harder to use and require knowledge about shader and stuff like that, but you can get way better performance using it. Beside from some GC and memory leak issue you may encounter, it's pretty good!
Also I don't think you can make canvas faster (~~I tried that~~), because most of the Canvas that runs on Node.js are often written in other language (If I'm not mistaken), and I assume they also need to copy the pixel buffer to Node.js, and then node-sdl need to copy it again to sdl, which is definitely not fast.
I think I could make canvas write to the window directly, eliminating some of the buffer copying. I'll keep this issue open to track that effort.
There's also a chance that you are doing something weird with your code that needlessly reduces performance. I'd be happy to have a look if you are able to upload the repo.
Failing that, switching to webgl/gpu is always an option, and there are libraries that make working with them much easier.
@LmanTW do you think the memory leak you encountered was a bug in kmamal/gl?
There's also a chance that you are doing something weird with your code that needlessly reduces performance. I'd be happy to have a look if you are able to upload the repo.
Simply, it's just the same 59-60 fps just like an empty canvas on HTML page. But in the code it's just clear the canvas and draw a rectangle, and input check
kmamal
I think it was because I keep using gl.createBuffer() when I want to do gl.bindBuffer and gl.bufferData, and I fixed it by just using the same buffer instead of keep creating new buffers.
Now I think about it it's quite silly, so I don't think it's an issue in kmamal/gl, I was just using it in a wrong way.
I just found out that skia-canvas actually supports rendering the canvas to an OS window. It also has some window events like mousemove, keydown, input, etc...
I just found out that skia-canvas actually supports rendering the canvas to an OS window. It also has some window events like
mousemove,keydown,input, etc...
Interesting
Also https://github.com/Brooooooklyn/canvas is node bindings for skia-canvas. Just tested it with this node-sdl package and it works like champ!
I'm even getting decent fps on a bunch of these cheap Anbernic retro game devices (arm64 chips with 1g ram, running knulli linux)
after some testing, it seems that @napi-rs/canvas is quite a bit faster than skia-canvas
One thing to make sure is that when you're calling window.render do this:
window.render(width, height, stride, 'rgba32', Buffer.from(imageData.data.buffer));
and NOT
window.render(width, height, stride, 'rgba32', Buffer.from(imageData.data));
HUGE performance difference between those two. The latter does a memory copy that is very slow and gets worse in high resolutions.
once this gets resolved, performance with this library + @napi-rs/canvas is going to be fantastic: https://github.com/Brooooooklyn/canvas/issues/972
@kmamal really greatful to you for working on this library I'm able to do JS game dev on retro handheld devices now: https://www.youtube.com/watch?v=osJsBRPSrM4
- I've made the windows use streaming textures for rendering which should be a bit faster than what was happening before.
- I played around with
@napi-rs/canvasand it's very fast. I am now using this lib in examples instead of plaincanvas. - I tried to get the
canvaslib to render directly to windows. It worked, but it was still much slower than just using@napi-rs/canvaswith the buffer copying. - I would like to also get
@napi-rs/canvasto render directly to the window, but it's written in Rust which I've never used. This will have to wait.
Is anyone still facing serious performance issues? Let me know if you do, otherwise this issue is on hold for now.
@napi-rs/canvas is indeed faster, but it starts to have noticeable performance issues when rendering to big screens. 2k resolutions seem to be extremely slow when rendering canvas's buffer to screen.
I still think gl is the best option to make this work for games, else canvas would only be fit for things that don't require constant rerendering.
Is using setTimeout(0) in an infinite loop still the recommended way to draw every frame? I want to do animation and motion using @napi-rs/canvas, and when using this code with setTimeout(0):
window.render(pixelWidth, pixelHeight, pixelWidth * 4, 'rgba32', canvas.data(), {
scaling: 'linear',
dstRect: { x: 0, y: 0, width: pixelWidth, height: pixelHeight },
})
the FPS I'm seeing fluctuates a lot around at 60. At times it even goes to 70 or reduces to 30. If I use skia-canvas' own Window, I get a proper 60±1 FPS.
Am I doing something wrong here? Or is this expected?
@ajitid I can't reproduce that on my system so I'm splitting it into a new issue.