Thursday, 2 July 2009

Progress

I've submitted all of my compositor phase 1 patches for review. The patches are also published here. 111 files changed, 2573 insertions, 1448 deletions, divided into 39 separate patches over multiple Bugzilla bugs. In theory every one of those steps should build and pass tests, although I haven't actually verified that for all the patches. I managed to break things up pretty well --- the largest patch is only 536 insertions and 75 deletions --- so hopefully that will make reviewing easier.

MQ has been working pretty well for me. I get into a routine of applying all the patches, doing some testing, fixing a number of bugs, and then redistributing the changes across the patches that they logically belong to. I'm not 100% sure this is the most efficient way to work --- sometimes I burn quite a bit of time putting all the changes in just the right places --- but at least it's now possible.

Now it's time to start working on something else. My immediate next task is to restructure the media tests so we can generalize tests across file types and backends; for example, right now we have one set of seeking tests for Ogg and another for Wave, but we should just have a single set of tests parametrized by test files of different types.

After that, I plan to do some cleanup that's enabled by compositor phase 1. In particular, we can move scrolling out of the view system and integrate it all directly into the scrollframes in layout.

After that I plan to work on compositor phase 2. Right now in Gecko whenever something needs to be repainted we make platform-level invalidation requests, the platforrm dispatches paint events and we paint. This often leads to over-frequent painting. For example if there's a script changing the DOM 100 times a second, we'll try to paint 100 times a second if we can keep up, which is a waste of time since most screens only refresh at 60Hz or so. Even worse, if you have that script, and an animated image painting 20 times a second, and a video playing at 25 frames per second, we invalidate them all independently and if your computer is fast enough we'll paint 145 times a second. We need to fix this, and I have a plan.

Part of that plan is to create an internal animation API that various Gecko components (animated images, video, smooth scrolling, SMIL, CSS Transitions, etc) can plug into. But we also recognize that declarative animations will never be expressive enough for all use cases, and there's a lot of existing scripted animation libraries out there, so I have an idea for tying in scripted animations as well. Basically, I would expose the following API:


  1. window.mozRequestAnimationFrame(): Signals that an animation is in progress, and requests that the browser schedule a repaint of the window for the next animation frame, if the window is visible.
  2. The browser will fire a mozBeforePaint event at the window before we repaint it. Animation libraries should register an event handler that checks the current time, and updates the DOM/CSS state to show that point in the animation. If the animation has not ended, the event handler should call window.mozRequestAnimationFrame() again to ensure another frame will be scheduled in a timely manner.

That's it! That API gives the browser control over the frame rate, while allowing JS to do anything it wants in each frame.


10 comments:

  1. I mentioned this in the comments of https://bugzilla.mozilla.org/show_bug.cgi?id=500410
    Feel free to resolve it however best suits.

    ReplyDelete
  2. Why redistribute the changes between the patches and not add yet another patch to the top of the queue? (That's how i understand most of people seem to use MQ)

    ReplyDelete
  3. Jonas Sicking2 July 2009 19:21

    When we fire the 'mozBeforePaint' event, will that event contain a property indicating for what time we're currently painting?
    This might be a good idea since all the eventhandlers we're firing from the various events (mozBeforePaint, scroll, SMIL) involved here could take long enough that if everyone calls Date.now() they'll end up animating to slightly different points in time.

    ReplyDelete
  4. Nice! Keep up the good work!

    ReplyDelete
  5. Robert O'Callahan2 July 2009 22:56

    Diego: because I think it's easier to review one patch that's correct instead of one buggy patch and five bug fix patches on top of it. Or even worse, five buggy patches, and several bug-fixing patches, each one fixing bugs in several of the original patches.
    Jonas: the internal API definitely will. The JS API, I'm not sure. Authors might forget to use it. Ideally we'd hook the JS engine so we can lie about Date.now() :-).

    ReplyDelete
  6. Is finishing bug 130078 considered part of phase 1?

    ReplyDelete
  7. Is finishing bug 215055 considered part of phase 2?

    ReplyDelete
  8. Robert O'Callahan24 July 2009 10:01

    Bug 215055 should be fixed by phase 1 already.

    ReplyDelete
  9. Steven Roussey10 August 2009 21:00

    Will this fix 90268 from 2001?

    ReplyDelete