WebAssembly / WebAssembly/wasi-webgpu

Hard to differentiate Surface multiple wasi-gfx instances are present

Open
#61 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Rust
Stars
220
Forks
15
PR merge metrics
No merged PRs in 30d

Description

Currently, a Surface is created like this

record create-desc {
    height: option<u32>,
    width: option<u32>,
}
let canvas = surface::Surface::new(surface::CreateDesc {
    height: None,
    width: None,
});

The problem

If you have many different surfaces created (ex: maybe you webpage has multiple apps that use wasi-gfx on it), it's hard to differentiate which surface came from which source

This matters, for example, in the Javascript bindings for wasi-gfx which define surface creation as follows

constructor(desc) {
        this.canvas = document.createElement('canvas');
        this.canvas.style.width = '100svw';
        this.canvas.style.height = '100svh';
        this.canvas.tabIndex = 0;
        Promise.resolve().then(() => {
            const styles = getComputedStyle(this.canvas);
            this.canvas.width = parseInt(styles.getPropertyValue('width'));
            this.canvas.height = parseInt(styles.getPropertyValue('height'));
        });
        document.body.appendChild(this.canvas);
    }

As you can see, there is no id or class set on the HTML element, but it gets added to the page using document.body.appendChild(this.canvas);. That means that if multiple wasi-gfx programs are running, they may all be adding to document.body.appendChild(this.canvas); which no way for you to easily query the DOM to try and apply special properties to different ones

The solution A: add an id field

Instead of somehow making the JS bindings somehow be configurable as to where the Surface gets placed (probably too JS-specific), I think the easiest thing is to add an id field to create-desc

This way, a host that needs to hook in special behavior to Canvas elements that are created can just override the base Surface

import { Surface as BaseSurface } from './gfx.js';

/** override the base Surface to add custom logic you need on creation
export class Surface extends BaseSurface {
  constructor(desc) {
    super(desc);
    // add some custom logic that depends on desc.id
  }
}

The solution B: something app-specific

The other way I could tackle this is, from my Rust project, add a way to either get the canvas that was added or add a custom function to set the canvas ID from Rust

However, this approach only works if you have the ability to modify all wasi-gfx programs your site is using (which is not always the case)

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the WIT create-desc definition and the JavaScript Surface constructor shown in the issue, then trace how the descriptor reaches each binding. Done means a surface can carry an identifier that host JavaScript customization can use to distinguish its canvas, with the Rust and JavaScript interfaces remaining consistent.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript, rust
Domain
api, web-dev
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.