frazzle
frazzle5w ago

Deno BYOW help with macOS [Solved] and X11

https://github.com/fazil47/deno_winit I'm trying to make Deno binding for winit for using WebGPU, it's working for Wayland and Windows but not for macOS and X11.
GitHub
GitHub - fazil47/deno_winit
Contribute to fazil47/deno_winit development by creating an account on GitHub.
6 Replies
frazzle
frazzle5w ago
This is the setup code in Rust (in src/lib.rs):
match window.raw_window_handle() {
raw_window_handle::RawWindowHandle::Win32(handle) => setup_func(
handle.hwnd,
handle.hinstance,
window.inner_size().width,
window.inner_size().height,
),
raw_window_handle::RawWindowHandle::AppKit(handle) => setup_func(
handle.ns_view,
null::<ffi::c_void>() as *mut ffi::c_void,
window.inner_size().width,
window.inner_size().height,
),
_ => (),
}

if let raw_window_handle::RawWindowHandle::Wayland(window_handle) = window.raw_window_handle() {
match window.raw_display_handle() {
raw_window_handle::RawDisplayHandle::Wayland(display_handle) => setup_func(
window_handle.surface,
display_handle.display,
window.inner_size().width,
window.inner_size().height,
),
_ => (),
}
} else if let raw_window_handle::RawWindowHandle::Xlib(window_handle) =
window.raw_window_handle()
{
match window.raw_display_handle() {
raw_window_handle::RawDisplayHandle::Xlib(display_handle) => {
setup_func(
window_handle.window as *mut ffi::c_void,
display_handle.display,
window.inner_size().width,
window.inner_size().height,
);
}
_ => (),
}
}
match window.raw_window_handle() {
raw_window_handle::RawWindowHandle::Win32(handle) => setup_func(
handle.hwnd,
handle.hinstance,
window.inner_size().width,
window.inner_size().height,
),
raw_window_handle::RawWindowHandle::AppKit(handle) => setup_func(
handle.ns_view,
null::<ffi::c_void>() as *mut ffi::c_void,
window.inner_size().width,
window.inner_size().height,
),
_ => (),
}

if let raw_window_handle::RawWindowHandle::Wayland(window_handle) = window.raw_window_handle() {
match window.raw_display_handle() {
raw_window_handle::RawDisplayHandle::Wayland(display_handle) => setup_func(
window_handle.surface,
display_handle.display,
window.inner_size().width,
window.inner_size().height,
),
_ => (),
}
} else if let raw_window_handle::RawWindowHandle::Xlib(window_handle) =
window.raw_window_handle()
{
match window.raw_display_handle() {
raw_window_handle::RawDisplayHandle::Xlib(display_handle) => {
setup_func(
window_handle.window as *mut ffi::c_void,
display_handle.display,
window.inner_size().width,
window.inner_size().height,
);
}
_ => (),
}
}
And these are the callback in Deno (in mod.ts),
let surface: Deno.UnsafeWindowSurface | null = null;
let context: GPUCanvasContext | null = null;
const setupFunctionCallback = new Deno.UnsafeCallback(
{ parameters: ["pointer", "pointer", "u32", "u32"], result: "void" },
(winHandle, displayHandle, width, height) => {
if (!this.system) {
console.error("System not supported.");
return;
}

surface = new Deno.UnsafeWindowSurface(
this.system,
winHandle,
displayHandle
);
context = surface.getContext("webgpu");
context.configure({
device,
format: this.presentationFormat,
width,
height,
});
this.setupFunction(device, context);
}
);

const drawFunctionCallback = new Deno.UnsafeCallback(
{ parameters: [], result: "void" },
() => {
if (!surface) {
console.error("Surface not initialized.");
return;
}

if (!context) {
console.error("Context not initialized.");
return;
}

this.drawFunction(device, context);
surface.present();
}
);
let surface: Deno.UnsafeWindowSurface | null = null;
let context: GPUCanvasContext | null = null;
const setupFunctionCallback = new Deno.UnsafeCallback(
{ parameters: ["pointer", "pointer", "u32", "u32"], result: "void" },
(winHandle, displayHandle, width, height) => {
if (!this.system) {
console.error("System not supported.");
return;
}

surface = new Deno.UnsafeWindowSurface(
this.system,
winHandle,
displayHandle
);
context = surface.getContext("webgpu");
context.configure({
device,
format: this.presentationFormat,
width,
height,
});
this.setupFunction(device, context);
}
);

const drawFunctionCallback = new Deno.UnsafeCallback(
{ parameters: [], result: "void" },
() => {
if (!surface) {
console.error("Surface not initialized.");
return;
}

if (!context) {
console.error("Context not initialized.");
return;
}

this.drawFunction(device, context);
surface.present();
}
);
This is the from the Deno.UnsafeWindowSurface doc:
| system | winHandle | displayHandle |
| ----------------- | ------------- | --------------- |
| "cocoa" (macOS) | `NSView*` | - |
| "win32" (Windows) | `HWND` | `HINSTANCE` |
| "x11" (Linux) | Xlib `Window` | Xlib `Display*` |
| "wayland" (Linux) | `wl_surface*` | `wl_display*` |
| system | winHandle | displayHandle |
| ----------------- | ------------- | --------------- |
| "cocoa" (macOS) | `NSView*` | - |
| "win32" (Windows) | `HWND` | `HINSTANCE` |
| "x11" (Linux) | Xlib `Window` | Xlib `Display*` |
| "wayland" (Linux) | `wl_surface*` | `wl_display*` |
For macOS, I'm passing in handle.ns_view for the window handle and a null pointer for the display handle but I think the draw function callback is being called before the setup function and nothing gets drawn to the window. When I pass in handle.ns_window for the window handle and handle.ns_view for the display handle it does work except it doesn't redraw properly when the window is resized. @divy what am I doing wrong? For X11 I have to check again, the window doesn't even spawn but that could be because I'm not using winit correctly.
frazzle
frazzle5w ago
This is what it looks like when it works correctly:
No description
Deno AI Helper
I wasn't able to find the answer to your question in the official Deno documentation. However, based on your message, it seems like you are working on Deno bindings for winit to use WebGPU and are experiencing issues specifically with macOS and X11. Without more specific details or error messages, it's difficult to provide targeted advice. However, here are a few general suggestions that might help: 1. Ensure that you have the necessary dependencies and development tools installed for macOS and X11. This might include XQuartz for X11 support on macOS. 2. Check if there are any platform-specific configurations or conditional compilation flags that need to be set for macOS and X11. 3. Look for any existing issues or pull requests on the deno_winit repository that might be related to macOS or X11 support. Please note that this advice is not based on the Deno documentation, and I recommend double-checking the accuracy of the advice given. If you continue to experience issues, you might want to reach out to the maintainers of the deno_winit repository or seek assistance from the community on platforms like GitHub or Deno-related forums.
divy
divy5w ago
ns_window is the window handle and ns_view is the display handle. on resize, you need to recreate the surface
frazzle
frazzle4w ago
on resize, you need to recreate the surface
This didn't work either, is this a macOS only limitation? works fine on Windows and Wayland. This is what I did:
WindowEvent::Resized(size) => {
match window.raw_window_handle() {
raw_window_handle::RawWindowHandle::AppKit(handle) => setup_func(
handle.ns_window,
handle.ns_view,
window.inner_size().width,
window.inner_size().height,
),
_ => (),
}
resize_func(size.width, size.height);
}
WindowEvent::Resized(size) => {
match window.raw_window_handle() {
raw_window_handle::RawWindowHandle::AppKit(handle) => setup_func(
handle.ns_window,
handle.ns_view,
window.inner_size().width,
window.inner_size().height,
),
_ => (),
}
resize_func(size.width, size.height);
}
setup_func recreates the WebGPU surface. Worked when I recreated the surface and called the redraw function in the resize callback @divy @crowlKats is it possible to make a headless WebGPU surface and then render it to a texture? I wanted to use three.js with RTT
crowlKats
crowlKats4w ago
once we have offscreencanvas, you could use that
More Posts
How can I add a flag into Deno Deploy in production?Hi, I am wondering how do I add a flag in production on Deno deploy if I want to enable a certain flUploading Files to S3 Bucket usign deno-s3-lite-clientHello, I have been trying to make a file upload controller with deno's s3 lite client but I am facinDeno.cron errorHi I keep having an error on deno deploy where my cron job doesn't seem to execute well in productioHow to rewrite this: `import * as base32 from "jsr:@std/encoding@0.224.3/base32.ts";`I am migrating std from /x and I ran into this issue. What the correct way to import just base32.ts.Default export has no call signaturesI'm trying to import the default export from `npm:@feathersjs/express`, but Deno complains that the Catch/handle WebSocketStream connection reset errorHow/where to catch this error? I am using `WebSocketStream` and catching on `wss.opened` and on `wssdeno_kv_oauth + hono how to fetch data from google profile: state, plans, method names changing.In code examples i found in internet, used methods which already not the part of deno_kv_oauth. 1. Class properties being reset to undefinedWhy is this happening? I have stepped through the debugger and no matter what, if I set a property iCheck if class instance is instance of provided typeI have a function that dynamically loads a folder with ts files, initiates the classes in them and Error upgrading headlessuiHello! I'm trying to upgrade headlessui/react to version 2.0.4 and running into an error. ``` error