W3C home > Mailing lists > Public > public-web-perf@w3.org > May 2012

Re: Semantics of the time argument on rAF's FrameRequestCallback

From: Nat Duca <nduca@google.com>
Date: Wed, 9 May 2012 17:39:17 -0700
Message-ID: <CAAMsTOvA5P9wGDwAHYvakW=X4=-+gLmNVZiK14KUFsaT5NXURA@mail.gmail.com>
To: Boris Zbarsky <bzbarsky@mit.edu>
Cc: Yehuda Katz <yehuda.katz@jquery.com>, Jatinder Mann <jmann@microsoft.com>, "public-web-perf@w3.org" <public-web-perf@w3.org>
>> function Animation(duration) {
>>    this.startTime = window.performance.now();
>
>
> First bug here.  The right thing to set startTime to in this situation is
> the time of the last refresh tick, not now()....

What do you set it to when you've been idle for a while? The last tick
may be many seconds ago. And, if you say "you must rAF in that case,"
then users of the animation system are going to complain that starting
short 1- or 2- frame animations have too much latency because, if you
start the animation just right after the vsync, then you're going to
have to wait 16ms to start the animation.

So, I still claim that this is correct.

>>       assert(window.performance.now() - a.startTime>= a.duration);
>
>
> If startTime were not tied to now() (which it shouldn't be), this assert
> would be completely nonsensical....

Agreed, but I disagree with your claim that its wrong.

>
>
>>    var a= new Animation(1000.0);
>>    a.addEventListener('animationEnded', function() {
>>       assert(window.performance.now() - a.startTime>= a.duration);
>>       aEnded = true;
>>       checkBothEnded();
>>    });
>>    var b= new Animation(1000.0);
>>    b.addEventListener('animationEnded', function() {
>>       assert(window.performance.now() - b.startTime>= b.duration);
>>       bEnded = true;
>>       checkBothEnded();
>>    });
>>    checkBothEnded() {
>>      if (!checkTaskEnqueued) window.postTask(checkBothEnded);
      checkTaskEnqueued = true;

Oops. :)

>>      assert (aEnded&&  bEnded);
>>    }
>
>
> As written, this will always fail the assert in checkBothEnded, so I assume
> you meant something different from what you wrote.  Not sure what, though.

The point is, if you use window.performance.now() to determine whether
an animation ended, and you have two animations that are ending at
exactly the same time, and the tick happens right on that boundary,
you can get one animation that ended and one animation that didn't
end.

>> I think that this is why most animation systems pass a frame begin
>> time as well as a present time.
>
>
> So in terms of rAF, "present time" would be the animation sample time and
> "frame begin time" would be the time it was before all the code for this
> frame started running?

Sorry, I wasn't precise about definitions. In my notes, "present time"
uses the directx term for Present. That was stupid --- present meant
the time that the content will be visible to the user.

FrameBeginTime is "the time that we began ticking raf."

I have bad terminology here. :'(

> How would having both help the use cases here?
>
>
>> (CVDisplayLink is documented here, though it doesn't explain the
>> rationale for the design:
>>
>> http://developer.apple.com/library/mac/documentation/QuartzCore/Reference/CVDisplayLinkRef/Reference/reference.html#//apple_ref/c/tdef/CVDisplayLinkOutputCallback)
>
>
> This looks like it's passing in an "inOutputTime" which is the animation
> sample time and the "inNow" which is .. not really all that well-defined.
>  Is the same for different output callbacks, or does it increment?

inNow goes up every frame, and is very close to the current system time.
inOutputTime is the time that that any rendered content is going to be
visible to the user.
Received on Thursday, 10 May 2012 00:39:47 UTC

This archive was generated by hypermail 2.3.1 : Tuesday, 6 January 2015 21:04:32 UTC