Node Bindings - Support for runtimes without external buffers

117 views
Skip to first unread message

Leon Koole

unread,
Jan 14, 2025, 4:33:27 PMJan 14
to Dawn Graphics
Hey everyone,

From the Node-API documentation: Some runtimes other than Node.js have dropped support for external buffers. On runtimes other than Node.js this method may return napi_no_external_buffers_allowed to indicate that external buffers are not supported. This is also the case for Electron, which follows Chromium doing the same.

Due to this, the node bindings for Dawn do not work in Electron. Building dawn.node with NODE_API_NO_EXTERNAL_BUFFERS_ALLOWED defined shows the culprit: https://dawn.googlesource.com/dawn/+/refs/heads/chromium/6536/src/dawn/node/binding/GPUBuffer.cpp#147. This method is not defined when no external buffers are allowed.

I've attempted to patch this myself, however, I have no knowledge of cpp and ended up with only a half working solution. I'm assuming something like a memcpy is needed to get the buffer into the V8 memory cage, but can not figure out how to get this working properly. I'm willing to continue looking into this further though if it's worthwhile.

I'm curious if this is something that is worth fixing. While the problem seems to be a few lines, and it would be great if Electron users could also use dawn, I can understand not wanting to have any code that essentially only works around Electron's limitations in dawn.node.

Cheers,
Leon

Gregg Tavares

unread,
Jan 14, 2025, 4:45:21 PMJan 14
to Leon Koole, Dawn Graphics
Can you just use webgpu directly in Electron? You shouldn't need the node bindings at all.

--
You received this message because you are subscribed to the Google Groups "Dawn Graphics" group.
To unsubscribe from this group and stop receiving emails from it, send an email to dawn-graphic...@googlegroups.com.
To view this discussion visit https://groups.google.com/d/msgid/dawn-graphics/42c8ea57-c481-4763-a3f1-86f456751fa0n%40googlegroups.com.

Leon Koole

unread,
Jan 14, 2025, 5:49:06 PMJan 14
to Dawn Graphics
Accidentally replied in private  here is my reply once again:

That would work well if the results of the WebGPU computations would be used within the browser window. In this case however, WebGPU is used to do complex calculations in Node, and Electron is just used to render an UI to control these computations.

It's possible to use WebGPU in the Electron BrowserWindow, however this would mean that all computation needs to be done in there, then passed from the GPU to the BrowserWindow, then from the BrowserWindow to Node over IPC. Using Electron this way to do the GPU compute causes a huge amount of overhead, especially when passing large buffers around at high rates, which is exactly the kind of data WebGPU is great for. Also, any lag in the BrowserWindow also causes lag in the buffers being passed through here.

Op dinsdag 14 januari 2025 om 22:45:21 UTC+1 schreef gm...@google.com:

Gregg Tavares

unread,
Jan 14, 2025, 6:23:42 PMJan 14
to Leon Koole, Dawn Graphics
On Tue, Jan 14, 2025 at 2:49 PM Leon Koole <koole...@gmail.com> wrote:
Accidentally replied in private  here is my reply once again:

That would work well if the results of the WebGPU computations would be used within the browser window. In this case however, WebGPU is used to do complex calculations in Node, and Electron is just used to render an UI to control these computations.

It's possible to use WebGPU in the Electron BrowserWindow, however this would mean that all computation needs to be done in there, then passed from the GPU to the BrowserWindow, then from the BrowserWindow to Node over IPC. Using Electron this way to do the GPU compute causes a huge amount of overhead, especially when passing large buffers around at high rates, which is exactly the kind of data WebGPU is great for. Also, any lag in the BrowserWindow also causes lag in the buffers being passed through here.


You can enable all of node in a BrowserWindow with `nodeIntegration: true` and then you don't need to IPC over to the main process.

AFAIK, the only reason this is discouraged is because many Electron apps use online resources (like scripts from CDNs) etc.... As long as you don't do that it's fine to integrate node into the BrowserWindow at which point you should be able to use all the node APIs. I've shipped several Electron apps this way as UIs on top of command line utils. They don't call out to the main process, they use the node API directly, spawning processes (child_process), using fs, etc...

 
Op dinsdag 14 januari 2025 om 22:45:21 UTC+1 schreef gm...@google.com:
Can you just use webgpu directly in Electron? You shouldn't need the node bindings at all.

On Tue, Jan 14, 2025 at 1:33 PM Leon Koole <koole...@gmail.com> wrote:
Hey everyone,

From the Node-API documentation: Some runtimes other than Node.js have dropped support for external buffers. On runtimes other than Node.js this method may return napi_no_external_buffers_allowed to indicate that external buffers are not supported. This is also the case for Electron, which follows Chromium doing the same.

Due to this, the node bindings for Dawn do not work in Electron. Building dawn.node with NODE_API_NO_EXTERNAL_BUFFERS_ALLOWED defined shows the culprit: https://dawn.googlesource.com/dawn/+/refs/heads/chromium/6536/src/dawn/node/binding/GPUBuffer.cpp#147. This method is not defined when no external buffers are allowed.

I've attempted to patch this myself, however, I have no knowledge of cpp and ended up with only a half working solution. I'm assuming something like a memcpy is needed to get the buffer into the V8 memory cage, but can not figure out how to get this working properly. I'm willing to continue looking into this further though if it's worthwhile.

I'm curious if this is something that is worth fixing. While the problem seems to be a few lines, and it would be great if Electron users could also use dawn, I can understand not wanting to have any code that essentially only works around Electron's limitations in dawn.node.

Cheers,
Leon

--
You received this message because you are subscribed to the Google Groups "Dawn Graphics" group.
To unsubscribe from this group and stop receiving emails from it, send an email to dawn-graphic...@googlegroups.com.
To view this discussion visit https://groups.google.com/d/msgid/dawn-graphics/42c8ea57-c481-4763-a3f1-86f456751fa0n%40googlegroups.com.

--
You received this message because you are subscribed to the Google Groups "Dawn Graphics" group.
To unsubscribe from this group and stop receiving emails from it, send an email to dawn-graphic...@googlegroups.com.

Gregg Tavares

unread,
Jan 14, 2025, 6:26:02 PMJan 14
to Leon Koole, Dawn Graphics
I should add, even if you do want to use online resources, you can spawn 2 BrowserWindows, one with node integrated (for doing GPU work with all the node APIs available), one without (for a UI). 

Kai Ninomiya

unread,
Jan 14, 2025, 9:18:25 PMJan 14
to Gregg Tavares, Leon Koole, Dawn Graphics
I think the only way we could do things without support for external buffers would involve large memory copies. It might be somewhat self-defeating, but probably not too bad. Certainly it would at least paper over the issue.

Could you file a bug on https://crbug.com/dawn/new? If you can provide repro instructions that would be very helpful, though I can't promise when we might be able to work on this.

-Kai (he/they)


Leon Koole

unread,
Jan 15, 2025, 6:54:07 AMJan 15
to Dawn Graphics
> You can enable all of node in a BrowserWindow with `nodeIntegration: true` and then you don't need to IPC over to the main process.
> I should add, even if you do want to use online resources, you can spawn 2 BrowserWindows, one with node integrated (for doing GPU work with all the node APIs available), one without (for a UI). 

I appreciate the suggestions! I can rewrite the application to make use of a second BrowserWindow for GPU work if other fixes do not work out. However this still seems like a workaround, spawning an essentially otherwise empty complete browser window just to do GPU work. Using the same window for UI and compute also is still an option, but would tie all the backend logic to the UI performance, which is why I would also consider this a non optimal workaround. My preferred solution is still to be able to use WebGPU headlessly, even in electron applications.

> I think the only way we could do things without support for external buffers would involve large memory copies. It might be somewhat self-defeating, but probably not too bad. Certainly it would at least paper over the issue.

I'm afraid that's the only way too. I think most users would still prefer that when running dawn in electron, it would fallback to making these large memory copies, as opposed to not working at all ;)
I will file an issue for this with instructions. I can completely understand it not being a priority though, but I appreciate it being looked at.

For others running into this, my (pretty bad) patch for now has been to replace the culprit in GPUBuffer.cpp:
auto array_buffer = Napi::ArrayBuffer::New(env, ptr, s);
with the following:
auto array_buffer = Napi::ArrayBuffer::New(env, s);
std::memcpy(array_buffer.Data(), ptr, s);

This is not a proper solution, as it breaks some previously working code regarding the creation of buffers with initial data, but this is easily worked around in a few lines of JS. Other than that, it seems this small patch results in otherwise perfectly working dawn.node in Electron.
Op woensdag 15 januari 2025 om 03:18:25 UTC+1 schreef kai...@google.com:

Corentin Wallez

unread,
Jan 15, 2025, 7:45:35 AMJan 15
to Leon Koole, Dawn Graphics
The patch to fix this entirely including for mappedAtCreation and writable buffers (memcpy on unmap) should be somewhat small, care to make a change upstream? I can help review it and find any other changes that would be needed.

Cheers,

Corentin

Leon Koole

unread,
Jan 17, 2025, 5:57:18 AMJan 17
to Dawn Graphics
> Could you file a bug on https://crbug.com/dawn/new? If you can provide repro instructions that would be very helpful, though I can't promise when we might be able to work on this.

I've created an issue at https://issues.chromium.org/issues/390443244

> The patch to fix this entirely including for mappedAtCreation and writable buffers (memcpy on unmap) should be somewhat small, care to make a change upstream? I can help review it and find any other changes that would be needed.

I am unfortunately not familiar with C++, so this will take some time from my side to figure out, if I can make it work at all. I've requested help from some people a bit more familiar with the language, and will update you here if I get it to a state where the change can be made upstream.
Op woensdag 15 januari 2025 om 13:45:35 UTC+1 schreef cwa...@google.com:
Reply all
Reply to author
Forward
0 new messages