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

[css-animationworklet] Sending data to animators in worklet from main thread #869

Open
majido opened this issue Mar 27, 2019 · 3 comments

Comments

Projects
None yet
2 participants
@majido
Copy link
Contributor

commented Mar 27, 2019

Many useful effects running inside animation worklet may need to know about specific values from main thread, e.g., size of window or bounding client rects of various objects.

We allow such data to be sent when worklet animation (via options property) is being constructed. However this is limited since these values may change during the lifetime of the animation (e.g., window resize). Currently in these cases one has to cancel the current animation and create a new one. This does not work well and can cause jusmp if the animation has internal state.

A simple logical extension is to allow options to be updated. Here is a proposal that achieves this:

In Animation Worklet context:

registerAnimator('abc', class {
  constructor(options) {
    this.options = options;
  }
  optionsChanged(options) {
    this.options = options;
    // TODO figure out if this should also implicitly invalidated the animation such that animate() is always called or alternatively we have a way to request one frame!
  }
  animate(time, effect) {
    // uses options.height as needed
  }
});

In document context:

let options = { height: top.innerHeight };
const animation = new WorkletAnimation('abc', keyframe, options);
animation.play()

window.addEventListener('resize', e => {
  options.height = top.innerHeight;
  animation.updateOptions(options); 
});

Why method instead of a property?
This means we don't need to keep the options as a live object. This is similar to other Web-animation APIs.

@majido

This comment has been minimized.

Copy link
Contributor Author

commented Mar 27, 2019

An alternative approach is is support postMessage on WorkletAnimation. AudioWorklet has taken this approach.

Using postMessage has a few advantages:

  • Well known semantic and API
  • Support transfers in addition to sending copies
  • Can be used as a bi-directional channel i.e., send data from worklet to main

There are however several concern with using postMessage:

  1. Its semantic may require that we always keep the animator instance alive so that it can receive the message. (Our current implementation in Chrome currently keeps animator instances alive but spec allows animator instances to be torn down at any time).

  2. We want to ensure that the data sent by main thread is processed before the next animation frame so that animation can respond to it appropriately. Not clear if this is possible with postMessage.

@majido

This comment has been minimized.

Copy link
Contributor Author

commented Mar 27, 2019

Thinking about this a bit more I believe we should limit this type of API to StatefulAnimator. (This may make the postMessage case more appealing)

First it is not clear to me why a stateless animator needs to receive "options" given that its output should only be dependent on its animate() input currentTime. Therefore for StatelessAnimator if options has changed on main thread, the animation should be restarted (cancel/play) without any visual glitch

More over it is not clear how this can be implemented properly for stateless animators where this may be different between calling optionsChanged and animate.

@majido majido changed the title [css-animationworklet] Allow sending data to animators in worklet from main thread [css-animationworklet] Sending data to animators in worklet from main thread Mar 27, 2019

@css-meeting-bot

This comment has been minimized.

Copy link
Member

commented Jun 7, 2019

The Houdini Task Force just discussed Sending data to animators in worklet from main thread (here since it is closely related to the above), and agreed to the following:

  • RESOLVED: Add input properties, expose for the target, should work for input right now. And we'll pursue events / message channel later for output.
The full IRC log of that discussion <iank_> Topic: Sending data to animators in worklet from main thread (here since it is closely related to the above)
<TabAtkins> github: https://github.com//issues/869
<iank_> majidvp: Similar issue as previous issue, we want to get some data from the main thread to the animation thread. We have this at startup with the options bag.
<iank_> majidvp: The issue is that there might be new data on the main thread that affect the animation, e.g. sizes of elements change.
<TabAtkins> q+
<iank_> majidvp: One idea is that do allow the options to be mutable, the main thread can up date the uptions, and it'll update the options on the animation thread.
<iank_> majidvp: The other options is using a postmessage port with the animator.
<iank_> flackr: If we want harmonize with css - we could do this with a property map.
<iank_> TabAtkins: Yes .
<iank_> flackr: There are several elements in play, and could read properties out of those elements.
<iank_> TabAtkins: When the animate() function get called, are there element references?
<iank_> majidvp: No the effect has a target, we don't expose that right now, but we could expose a styleMap.
<iank_> TabAtkins: You'd want to limit the number of properties.
<iank_> flackr: You could just expose all the same properties?
<iank_> hober: I agree.
<iank_> TabAtkins: Seems like we just want to expose inputProperties on the target for the effect? It doesn't let you pass information out however.
<iank_> majidvp: There are usecases for more stateful effects, and this stage I'm fine with not solving this.
<iank_> majidvp: These usecases are more important once you feed input events into animation worklet. But we don't have this yet, so its not pressing.
<iank_> bkardell_: A message channel is good for JS, but not good for CSS?
<flackr> iank_: another option is event dispatching
<Rossen_> q?
<TabAtkins> ack
<TabAtkins> zakim, ack
<Zakim> I don't understand 'ack', TabAtkins
<TabAtkins> q-
<Rossen_> ack TabAtkins
<iank_> majidvp: Output could be events which fits nicely with the animations API.
<iank_> majidvp: postmessage is more generic, but has its own lifetime concerns, but you might not want to commit to that.
<iank_> TabAtkins: Add input properties, expose for the target, should work for input right now. And we'll pursue events / message channel later for output.
<iank_> Proposal: Add input properties, expose for the target, should work for input right now. And we'll pursue events / message channel later for output.
<iank_> RESOLVED: Add input properties, expose for the target, should work for input right now. And we'll pursue events / message channel later for output.
<iank_> break 15 mins.
<emilio> ScribeNick: emilio
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.