Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add rawHandle() API #29

Closed
littledivy opened this issue Dec 28, 2023 · 2 comments
Closed

Add rawHandle() API #29

littledivy opened this issue Dec 28, 2023 · 2 comments

Comments

@littledivy
Copy link

littledivy commented Dec 28, 2023

Ability to retrieve the window and display/instance handles from glfw. Similar to deno_sdl2's Window#rawHandle().

Rust implementation for reference: https://github.com/PistonDevelopers/glfw-rs/blob/2221cf05410c3dd2fac6f711c8f28e072c16f1fb/src/lib.rs#L3518

  /**
   * Return the raw handle of the window.
   *
   * platform: "cocoa" | "win32" | "winrt" | "x11" | "wayland"
   *
   * ```ts
   * const [platform, handle, display] = window.rawHandle();
   * ```
   *
   * on macOS:
   * - platform: "cocoa"
   * - handle: NSWindow
   * - display: NSView
   *
   * on Windows:
   * - platform: "win32" | "winrt"
   * - handle: HWND
   * - display: null | HINSTANCE
   *
   * on Linux:
   * - platform: "x11" | "wayland"
   * - handle: Window
   * - display: Display
   */
  rawHandle(): [string, Deno.PointerValue, Deno.PointerValue | null];

This can be passed to Deno's WebGPU with this proposal: denoland/deno#21713

@load1n9
Copy link
Member

load1n9 commented Dec 28, 2023

Sounds good!

@nhrones
Copy link

nhrones commented Jan 1, 2024

Any progress here? I'm interested in porting my DWM-ReactiveUI framework from Skia-Canvas to WebGPU.

What would it take to use DWM as the BYOW for Deno-WebGPU? Is anyone working on this?

littledivy added a commit to denoland/deno that referenced this issue Jan 19, 2024
This PR contains the implementation of the External webgpu surfaces /
BYOW proposal. BYOW stands for "Bring your own window".

Closes #21713 

Adds `Deno.UnsafeWindowSurface` ( `--unstable-webgpu` API) to the `Deno`
namespace:

```typescript
class UnsafeWindowSurface {
  constructor(
    system: "cocoa" | "x11" | "win32",
    winHandle: Deno.PointerValue,
    displayHandle: Deno.PointerValue | null
  );
  
  getContext(type: "webgpu"): GPUCanvasContext;

  present(): void;
}
```

For the initial pass, I've opted to support the three major windowing
systems. The parameters correspond to the table below:
| system                      | winHandle  | displayHandle |
| -----------------     | ----------   | ------- |
| "cocoa" (macOS)    | `NSView*`       | - |
| "win32" (Windows) | `HWND`         | `HINSTANCE` |
| "x11" (Linux)            | Xlib `Window` | Xlib `Display*` |

Ecosystem support:

- [x] deno_sdl2 (sdl2) -
[mod.ts#L1209](https://github.com/littledivy/deno_sdl2/blob/7e177bc6524750a8849c25ce421798b2e71ec943/mod.ts#L1209)
- [x] dwm (glfw) - deno-windowing/dwm#29
- [ ] pane (winit)

<details>
<summary>Example</summary>

```typescript
// A simple clear screen pass, colors based on mouse position.

import { EventType, WindowBuilder } from "https://deno.land/x/sdl2@0.7.0/mod.ts";

const window = new WindowBuilder("sdl2 + deno + webgpu", 640, 480).build();
const [system, windowHandle, displayHandle] = window.rawHandle();

const adapter = await navigator.gpu.requestAdapter();
const device = await adapter.requestDevice();

const context = Deno.createWindowSurface(system, windowHandle, displayHandle);

context.configure({
  device: device,
  format: "bgra8unorm",
  height: 480,
  width: 640,
});

let r = 0.0;
let g = 0.0;
let b = 0.0;

for (const event of window.events()) {
  if (event.type === EventType.Quit) {
    break;
  } else if (event.type === EventType.Draw) {
    const textureView = context.getCurrentTexture().createView();

    const renderPassDescriptor: GPURenderPassDescriptor = {
      colorAttachments: [
        {
          view: textureView,
          clearValue: { r, g, b, a: 1.0 },
          loadOp: "clear",
          storeOp: "store",
        },
      ],
    };

    const commandEncoder = device.createCommandEncoder();
    const passEncoder = commandEncoder.beginRenderPass(renderPassDescriptor);
    passEncoder.end();

    device.queue.submit([commandEncoder.finish()]);
    Deno.presentGPUCanvasContext(context);
  }

  if (event.type === EventType.MouseMotion) {
    r = event.x / 640;
    g = event.y / 480;
    b = 1.0 - r - g;
  }
}
```

You can find more examples in the linked tracking issue.

</details>

---------

Signed-off-by: Divy Srivastava <dj.srivastava23@gmail.com>
@load1n9 load1n9 closed this as completed Jan 24, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants