Skip to content

Include timestamp in frame-event to allow throttled rendering #60

@SebastienGllmt

Description

@SebastienGllmt

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)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions