Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

On using MozAfterPaint properly

145 views
Skip to first unread message

Mike Conley

unread,
Apr 15, 2016, 1:49:08 PM4/15/16
to Mozilla dev-platform mailing list mailing list
Hello dev-platform,

TL;DR: MozAfterPaint and nsIDOMWindowUtils has been given some extra stuff
to make it easier to be sure that something you care about has been
painted. This is good, at the very least, for Talos tests.

Full-details:

I've recently made a change to MozAfterPaint that some of you might find
interesting. This is particularly interesting for people who work on or
with Talos tests where those tests are measuring how long until something
is presented to the user.

Traditionally, MozAfterPaint has been used by Talos tests[1] to "stop a
stopwatch" that's been ticking since some action started. For example, for
the tpaint Talos test[2], the stopwatch is started, and a new window is
opened up. Once the content in the new window sees the MozAfterPaint event,
we assume the content has been displayed to the user, and we stop the
stopwatch.

Note that MozAfterPaint is fired after both paint _and_ composition, so it
truly does mean "presented to the user"[3].

Now that we live in an OMTC world, there are complications. Specifically,
there are opportunities for a MozAfterPaint handler to hear a MozAfterPaint
that it doesn't actually care about.

Let me give you an example.

Suppose I'm writing a talos test that is measuring how long it takes for
something to paint after I've clicked some node with id="target". Normally,
I'd set up my MozAfterPaint handler, start the stopwatch, fire a click
event at the target, and wait for the MozAfterPaint in order to stop the
stopwatch. The problem is that there's the possibility that a composite was
underway while I was running my Talos script. That means that after I've
set my MozAfterPaint handler, I might hear a MozAfterPaint event before
layout and graphics have had a chance to react to my click on the target
element.

The fact that this is all kind of non-deterministic makes it a bit worse.
Sometimes we'll see the result we want, and sometimes, we'll see very short
results from our stopwatch due to an earlier composite that was in progress
when we ran our script.

To combat this, I've added the following:

1) An unsigned long long property to nsIDOMWindowUtils giving the last
transaction id that was sent to the compositor
2) An unsigned long long property on the MozAfterPaint event exposing which
transaction id this MozAfterPaint is for

To go back to our example, this means that what I should do is, before
starting the stopwatch, I should figure out what the lastTransactionId was
for the window I'm in, and remember it. When my MozAfterPaint event handler
runs, I should ensure that the transactionId on the event is _greater_ than
the lastTransactionId I had recorded earlier. It might not be exactly 1
value above. We just know it'll be greater. If it's greater, then we _know_
that whatever action we took when clicking the target, if it should cause a
paint, should have been included in this composite.

So that's that. Gory details are in bug 1264409. I've also filed bug
1264798 to investigate adding the composite end time in the MozAfterPaint
event for greater accuracy.

-Mike

[1]: It's also periodically used by front-end code to defer some activity
until something has been presented to the user.
[2]: https://wiki.mozilla.org/Buildbot/Talos/Tests#tpaint
[3]: The fact that it's called MozAfterPaint is probably for historical
reasons. It should probably be renamed to MozAfterPresented or something.
Meh.
0 new messages