WebAssembly / WebAssembly/wasi-webgpu

Include timestamp in `frame-event` to allow throttled rendering

Open
#60 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

Often times for animations you want to be able to throttle rendering at some specific speed (ex: 60fps). However, there is no clear way to achieve this with wasi-gfx

Notably, the get-frame returns an empty object

subscribe-frame: func() -> pollable;
get-frame: func() -> option<frame-event>;

record frame-event {
  /// TODO: This field doesn't mean anything.
  /// Can't have empty record. Would like to have a way around this.
  nothing: bool,
}

Notably, from a Javascript host, you actually can get the timestamp from requestAnimationFrame as the first argument to the callback as per the docs

subscribeFrame() {
    const pollable = new Pollable();
    const onFrame = () => { // <- note: timestamp argument ignored
        this.frameEvent = {
            nothing: false,
        };
        pollable.resolve(); // <- we could be passing the timestamp in here
        requestAnimationFrame(onFrame);
    };
    requestAnimationFrame(onFrame);
    return pollable;
}

Without the timestamp argument, requestAnimationFrame will run depending on the user's monitor's refresh rate (so your animation may run over 2x faster for some users!)

Alternative solution

Although from the Javascript host the timestamp is easy to get, maybe that's not the same for every host (although it would be a bit surprising to have a host that can't tell its own clock time)

An alternative, to ensure the host has a clock functionality, would be to rely on wasi-clocks. Although this works, there are two issues with this:

  1. Hard hit desired fps. requestAnimationFrame for example runs depending on the user's monitor, so if you want your animation to run at 20fps, it won't work well if the user's monitor is 144hz as 144 is not a multiple of 20. This means you need to round, causing some frames to be slightly longer/shorter than others
  2. Hard to synchronize updates between multiple wasi-gfx apps running. requestAnimationFrame gives the same timestamp to all listeners, whereas wasi-clock skews based on render time of other apps (ex: imagine you have two apps A and B. A takes 5ms to render. That means that B's wasi-clock will be 5ms later than what A saw)

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 subscribe-frame, get-frame, and frame-event definitions, then inspect the JavaScript requestAnimationFrame host path shown in the issue. Determine how the timestamp should be represented and propagated so throttled rendering and synchronized listeners are supported. Done means frame events expose the host-provided timestamp consistently.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript
Domain
api, computer-graphics
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
42/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.