- From: Jan Linnebank <jan@linnebank.nl>
- Date: Mon, 18 Jul 2011 01:32:06 +0200
- To: public-web-perf@w3.org
- Message-ID: <4E2370F6.6030502@linnebank.nl>
If strictly following the iOS approach, at least one more thing is
needed: a way to signal when a frame-drawing is ready for display. In
iOS they have 'presentRenderBuffer()
<http://developer.apple.com/library/ios/#documentation/OpenGLES/Reference/EAGLContext_ClassRef/Reference/EAGLContext.html>',
in OpenGL libs this is done with a call to 'swapBuffers()' etc.
Such a method could be part of the Animator (or CADisplayLink in iOS
speak).
However, this is perhaps unnecessarily low-level.
Maybe more convenient would be if we're able to say something like 'I
want the frame I just drew to be displayed after <n> display-refreshes
after the display-refresh of the last displayed frame . (The
full-framerate case would thus have n=1).
That's similar to what I proposed in one of my previous mails, with the
'skip-frames' return-value.
Regards,
Jan
On 17-7-2011 23:05, Jan Linnebank wrote:
> To the editors:
>
> I stumble upon the way iOS does things.
>
> This is just what we (everyone?) need. Nothing more, nothing less.
>
> Please just copy it and you're done. ;-)
>
> Almost identical to the Animator that I sketched. Just the right level
> of abstraction. All low level primitives (to build upon), with higher
> level state-handling for convenience.
>
> http://developer.apple.com/library/ios/#documentation/QuartzCore/Reference/CADisplayLink_ClassRef/Reference/Reference.html
>
>
> Thank you,
>
> Jan
>
>
> On 17-7-2011 19:56, Jan Linnebank wrote:
>> In reply to myself:
>>
>> Actually it doesn't need not be the callback return that determines
>> when the frame is drawn; rendering might happen async in the
>> background, for example in WebGL, so can extend past the time the
>> callback returns.
>> So if the callback returns before the display-refresh, the rendering
>> might still be finished too late for it.
>>
>> So the actual issue is:
>>
>> "What about *frame-drawing* finishing too late for display-refresh?"
>>
>> Now wildly assuming the frame would just be displayed at the first
>> possible display-refresh after it's done rendering, this would
>> emphasize another issue: It is unknown beforehand when a frame is
>> actually displayed. Which, if not tackled somehow, would prevent
>> smooth animations. Frame-drawing code not knowing for which moment in
>> time ahead to draw the frame, results in well-known artifacts like
>> jumps and stuttering.
>>
>> A good solution is, for a given animation-sequence, to lower the
>> animation-frame-rate to a constant divider of the actual
>> display-refresh-rate. The divider is determined by the maximum number
>> of display-refreshes any frame-drawing took, recently. This way,
>> everything is still running vsync, while even the longest lasting
>> frame-drawings fit in the custom frame-interval. Buffer-swaps of
>> shorter-lasting frame drawings are delayed to align the same
>> frame-interval. This way the moment of display is known beforehand
>> again, allowing for proper animation.
>>
>> Only when a new maximum frame-draw refresh-span is reached a 'sync
>> error' (slight hick-up) might be visible. (But some determination
>> (calibration) of the max refresh-span might even be possible to do
>> 'invisibly' beforehand.)
>>
>> So we need a way to *delay the display* of the shorter lasting
>> frame-drawings so they align to the chosen frame-interval. The actual
>> display is in the realm of the user-agent, there's no way yet to
>> reliably influence that in user-code, so we need an extension in the
>> API: A return-value of the callback-function could be supported,
>> specifying how many extra display-refreshes need to be *skipped*
>> before actually displaying. ('undefined' would default to zero).
>>
>> This is most flexible and keeps options open for users to program
>> their own adaptive frame-rate housekeeping. (or create nice little
>> libraries for that).
>>
>> Additionaly some support could be baked-in for the most common cases.
>> For example, some lightweight Animator object, which
>> increases/decreases the refresh-skips to fit the max encountered
>> frame refresh-span during some recent period. It would be possible
>> and advisable to users to use different Animator objects if they
>> expect different frame-drawing workload characteristics, thus
>> frame-rates, for different parts of their animations. (Even
>> simultaneously).
>> 'requestAnimationFrame()' would be a method of Animator. (maybe
>> simply named 'requestFrame()' in that case)
>> (Or perhaps the registration of the animation-callback-function
>> should stay active until unregistered, and not need to be issued for
>> each frame. Furthermore, it only needs to be one, a delegate.)
>>
>> Another advantage of such an Animator object dialogue is that a
>> method or callback-param like 'lastFrameTime' could be supported (we
>> need this ;-), since it is clear to which frame callback we are
>> referring (in contrast to a Window scoped implicit Animator having
>> multiple different clients/callback functions running at the same
>> time). It provides a clear, animation-scoped 'dialogue'.
>> On the other hand, when callback-functions would stick to the
>> Window-object until deregistered, such multi-callbacks spanning
>> dialogues could be supported as well, but that would change
>> programming style (negatively perhaps) a bit.
>>
>> Using something like the Animator keeps the measurement of a suitable
>> frame-interval out of the user's hands. However, since different
>> strategies and definitions for a 'suitable' frame-interval exist, and
>> depend on the user's intents, this should perhaps be an additional,
>> not the only way of controlling framerate. The Animator could just as
>> well be implemented as user-code.
>>
>> So far my thoughts, I may diverge completely from you intentions, and
>> browser reality, but perhaps this aligns or comes to use in one way
>> or the other.
>>
>> Regards,
>>
>> Jan Linnebank
>>
>>
>>
>>
>> On 16-7-2011 4:51, Jan Linnebank wrote:
>>> Regarding "Timing control for script-based animations, W3C Editor’s
>>> Draft 27 June 2011"
>>>
>>> WHAT WITH PAINT-CALLBACKS FINISHING TOO LATE FOR SCHEDULED
>>> DISPLAY-REFRESH
>>>
>>> To the editors,
>>>
>>>
>>> What would happen when a user's frame-callback doesn't return in
>>> time for the frame to be actually displayed on it's scheduled
>>> display-refresh?
>>>
>>> Will it just be displayed on a later display-refresh?
>>>
>>> Will the user have access to the timestamp of that actual later
>>> display-refresh (perhaps as extra param in the next callback, e.g.
>>> 'lastRefreshTime')?
>>> Or will that timestamp simply be determinable by subtracting the
>>> refresh-interval from the timestamp of the next
>>> requestAnimationFrame callback?
>>> (The latter two questions motivated again with regard to
>>> psychological reaction-time related experiments.)
>>>
>>> Regards,
>>>
>>> Jan Linnebank
>>>
>>> at UvA NeuroTest B.V.
>>
>>
>>
>
Received on Sunday, 17 July 2011 23:32:26 UTC