Closed Bug 1235478 Opened 9 years ago Closed 9 years ago

Do not update nsRefreshDriver::mMostRecentRefresh when nsRefreshDriver::ScheduleViewManagerFlush is called

Categories

(Core :: Layout, defect)

Other Branch
defect
Not set
normal

Tracking

()

RESOLVED FIXED
mozilla47
Tracking Status
firefox47 --- fixed

People

(Reporter: hiro, Assigned: hiro)

References

(Depends on 1 open bug, Blocks 1 open bug)

Details

Attachments

(4 files, 1 obsolete file)

We currently update nsRefreshDriver::mMostRecentRefresh in nsRefreshDriver::EnsureTimerStarted[1]. [1] https://dxr.mozilla.org/mozilla-central/rev/388bdc46ba51ee31da8b8abe977e0ca38d117434/layout/base/nsRefreshDriver.cpp#1195 But in case of EnsureTimerStarted is called from nsRefreshDriver::ScheduleViewManagerFlush we don't need to update mMostRecentRefresh otherwise the painting process caused by ScheduleViewManagerFlush won't be done in the same frame. This issue was found by a test case in bug 1235286 comment #0 (No.7).
EnsureTimerStarted is called from various places without arguments. I am confident that ScheduleViewManagerFlush does not need to update mMostRecentRefresh but I am not sure other callers too. To preserve the behavior of EnsureTimerStarted from the other callers I'd propose here to add a new flag names eNeverAdjustTimer which represents that EnsureTimerStarted does not update mMostRecentRefresh. It's only for ScheduleViewManagerFlush. I'd also propose to rename existing eAdjustingTimer to eForceAdjustTimer for avoiding confusion.
(In reply to Hiroyuki Ikezoe (:hiro) from comment #0) > We currently update nsRefreshDriver::mMostRecentRefresh in > nsRefreshDriver::EnsureTimerStarted[1]. > > [1] > https://dxr.mozilla.org/mozilla-central/rev/ > 388bdc46ba51ee31da8b8abe977e0ca38d117434/layout/base/nsRefreshDriver.cpp#1195 > > But in case of EnsureTimerStarted is called from > nsRefreshDriver::ScheduleViewManagerFlush we don't need to update > mMostRecentRefresh otherwise the painting process caused by > ScheduleViewManagerFlush won't be done in the same frame. > > This issue was found by a test case in bug 1235286 comment #0 (No.7). I'm kind of confused as to what this is supposed to be doing. EnsureTimerStarted() should only be making sure that we start at timer, then when a vsync occurs, we paint. This should update the mMostRecentRefresh time during the tick [1]. Why are there two frames occurring instead? Are we force flushing in addition to scheduling a flush? Otherwise, it looks like ScheduleViewManagerFlush() should still wait for a vsync to flush. [1] https://dxr.mozilla.org/mozilla-central/rev/388bdc46ba51ee31da8b8abe977e0ca38d117434/layout/base/nsRefreshDriver.cpp#1612
Flags: needinfo?(hiikezoe)
(In reply to Mason Chang [:mchang] from comment #5) > (In reply to Hiroyuki Ikezoe (:hiro) from comment #0) > > We currently update nsRefreshDriver::mMostRecentRefresh in > > nsRefreshDriver::EnsureTimerStarted[1]. > > > > [1] > > https://dxr.mozilla.org/mozilla-central/rev/ > > 388bdc46ba51ee31da8b8abe977e0ca38d117434/layout/base/nsRefreshDriver.cpp#1195 > > > > But in case of EnsureTimerStarted is called from > > nsRefreshDriver::ScheduleViewManagerFlush we don't need to update > > mMostRecentRefresh otherwise the painting process caused by > > ScheduleViewManagerFlush won't be done in the same frame. > > > > This issue was found by a test case in bug 1235286 comment #0 (No.7). > > I'm kind of confused as to what this is supposed to be doing. > EnsureTimerStarted() should only be making sure that we start at timer, then > when a vsync occurs, we paint. This should update the mMostRecentRefresh > time during the tick [1]. Why are there two frames occurring instead? For example on non-E10S, consider a style for a element is updated in requestAnimationFrame. 1. content refresh driver's Tick is called. 2. the requestAnimationFrame is called. 3. the style is updated. 4. root refresh driver's ScheduleViewManagerFlush is called. 5. root refresh driver's EnsureTimerStarted is called. 6. root refresh driver's mMostRecentRefresh is updated to the same time as content refresh driver's. 7. root refresh driver's Tick is called. But... 8. skip the process of the root refresh driver's Tick because mMostRecentRefresh equals already to aNowTime. 9. mViewManagerFlushIsPending is still true. Then... 10. painting process will be done in the next tick.
Flags: needinfo?(hiikezoe)
(In reply to Hiroyuki Ikezoe (:hiro) from comment #6) > (In reply to Mason Chang [:mchang] from comment #5) > > (In reply to Hiroyuki Ikezoe (:hiro) from comment #0) > > > We currently update nsRefreshDriver::mMostRecentRefresh in > > > nsRefreshDriver::EnsureTimerStarted[1]. > > > > > > [1] > > > https://dxr.mozilla.org/mozilla-central/rev/ > > > 388bdc46ba51ee31da8b8abe977e0ca38d117434/layout/base/nsRefreshDriver.cpp#1195 > > > > > > But in case of EnsureTimerStarted is called from > > > nsRefreshDriver::ScheduleViewManagerFlush we don't need to update > > > mMostRecentRefresh otherwise the painting process caused by > > > ScheduleViewManagerFlush won't be done in the same frame. > > > > > > This issue was found by a test case in bug 1235286 comment #0 (No.7). > > > > I'm kind of confused as to what this is supposed to be doing. > > EnsureTimerStarted() should only be making sure that we start at timer, then > > when a vsync occurs, we paint. This should update the mMostRecentRefresh > > time during the tick [1]. Why are there two frames occurring instead? > > For example on non-E10S, consider a style for a element is updated in > requestAnimationFrame. > > 1. content refresh driver's Tick is called. > 2. the requestAnimationFrame is called. > 3. the style is updated. > 4. root refresh driver's ScheduleViewManagerFlush is called. > 5. root refresh driver's EnsureTimerStarted is called. > 6. root refresh driver's mMostRecentRefresh is updated to the same time as > content refresh driver's. Shouldn't this prevent this from happening - https://dxr.mozilla.org/mozilla-central/source/layout/base/nsRefreshDriver.cpp?case=true&from=EnsureTimerStarted#1155 The default should be to be passing in no flags and thus that return should occur if it's ticking off an active timer already?. > 7. root refresh driver's Tick is called. But... > 8. skip the process of the root refresh driver's Tick because > mMostRecentRefresh equals already to aNowTime. > 9. mViewManagerFlushIsPending is still true. Then... > 10. painting process will be done in the next tick. Thanks for breaking it down!
Flags: needinfo?(hiikezoe)
(In reply to Mason Chang [:mchang] from comment #7) > (In reply to Hiroyuki Ikezoe (:hiro) from comment #6) > > (In reply to Mason Chang [:mchang] from comment #5) > > > (In reply to Hiroyuki Ikezoe (:hiro) from comment #0) > > > > We currently update nsRefreshDriver::mMostRecentRefresh in > > > > nsRefreshDriver::EnsureTimerStarted[1]. > > > > > > > > [1] > > > > https://dxr.mozilla.org/mozilla-central/rev/ > > > > 388bdc46ba51ee31da8b8abe977e0ca38d117434/layout/base/nsRefreshDriver.cpp#1195 > > > > > > > > But in case of EnsureTimerStarted is called from > > > > nsRefreshDriver::ScheduleViewManagerFlush we don't need to update > > > > mMostRecentRefresh otherwise the painting process caused by > > > > ScheduleViewManagerFlush won't be done in the same frame. > > > > > > > > This issue was found by a test case in bug 1235286 comment #0 (No.7). > > > > > > I'm kind of confused as to what this is supposed to be doing. > > > EnsureTimerStarted() should only be making sure that we start at timer, then > > > when a vsync occurs, we paint. This should update the mMostRecentRefresh > > > time during the tick [1]. Why are there two frames occurring instead? > > > > For example on non-E10S, consider a style for a element is updated in > > requestAnimationFrame. > > > > 1. content refresh driver's Tick is called. > > 2. the requestAnimationFrame is called. > > 3. the style is updated. > > 4. root refresh driver's ScheduleViewManagerFlush is called. > > 5. root refresh driver's EnsureTimerStarted is called. > > 6. root refresh driver's mMostRecentRefresh is updated to the same time as > > content refresh driver's. > > Shouldn't this prevent this from happening - > https://dxr.mozilla.org/mozilla-central/source/layout/base/nsRefreshDriver. > cpp?case=true&from=EnsureTimerStarted#1155 > > The default should be to be passing in no flags and thus that return should > occur if it's ticking off an active timer already?. Oops, I am sorry. I forgot to say an important precondition. That is the root refresh driver is dormant before the content refresh driver's tick. It's very common case on E10S.
Flags: needinfo?(hiikezoe)
(In reply to Hiroyuki Ikezoe (:hiro) from comment #8) > > Shouldn't this prevent this from happening - > > https://dxr.mozilla.org/mozilla-central/source/layout/base/nsRefreshDriver. > > cpp?case=true&from=EnsureTimerStarted#1155 > > > > The default should be to be passing in no flags and thus that return should > > occur if it's ticking off an active timer already?. > > Oops, I am sorry. I forgot to say an important precondition. That is the > root refresh driver is dormant before the content refresh driver's tick. > It's very common case on E10S. I meant non-E10S, of course. But it's common regardless of E10S/non-E10S.
From comment 8, does that mean this can only happen on the first root refresh driver's tick? As in, once the root refresh driver has started to tick as well, the mMostRecentRefresh won't be updated and this problem does not occur?
Flags: needinfo?(hiikezoe)
(In reply to Mason Chang [:mchang] from comment #10) > From comment 8, does that mean this can only happen on the first root > refresh driver's tick? No. Sorry for the confusion. 'dormant' means inactive. If the root refresh driver is active, this problem does not occur.
Flags: needinfo?(hiikezoe)
Comment on attachment 8702806 [details] MozReview Request: Bug 1235478 - Part 1: Rename eAdjustingTimer to eForceAdjustTimer. r=mchang https://reviewboard.mozilla.org/r/29189/#review26313
Attachment #8702806 - Flags: review?(mchang) → review+
Comment on attachment 8702807 [details] MozReview Request: Bug 1235478 - Part 2: Don't update mMostRecentRefresh when nsRefreshDriver::ScheduleViewManagerFlush is called. r=mchang https://reviewboard.mozilla.org/r/29191/#review26315 ::: layout/base/nsRefreshDriver.cpp:1187 (Diff revision 1) > + if (aFlags & eNeverAdjustTimer) { Please put a comment here explaining why this happens. You can put something like "When switching from an inactive timer to an active timer, the root refresh driver is skipped due to being set to the content refresh driver's timestamp".
Attachment #8702807 - Flags: review?(mchang) → review+
Comment on attachment 8702806 [details] MozReview Request: Bug 1235478 - Part 1: Rename eAdjustingTimer to eForceAdjustTimer. r=mchang Review request updated; see interdiff: https://reviewboard.mozilla.org/r/29189/diff/1-2/
Attachment #8702806 - Attachment description: MozReview Request: Bug 1235478 - Part 1: Rename eAdjustingTimer to eForceAdjustTimer. r?mchang → MozReview Request: Bug 1235478 - Part 1: Rename eAdjustingTimer to eForceAdjustTimer. r=mchang
Comment on attachment 8702807 [details] MozReview Request: Bug 1235478 - Part 2: Don't update mMostRecentRefresh when nsRefreshDriver::ScheduleViewManagerFlush is called. r=mchang Review request updated; see interdiff: https://reviewboard.mozilla.org/r/29191/diff/1-2/
Attachment #8702807 - Attachment description: MozReview Request: Bug 1235478 - Part 2: Don't update mMostRecentRefresh when nsRefreshDriver::ScheduleViewManagerFlush is called. r?mchang → MozReview Request: Bug 1235478 - Part 2: Don't update mMostRecentRefresh when nsRefreshDriver::ScheduleViewManagerFlush is called. r=mchang
For reference for myself. Here is a screen shot of reftest-analyzer. Right edges on each '600' - '900' were different. I am still investigating why the difference happens with patches for this bug and why the failure happens only on MacOS 10.10.
Attached patch Use fuzzy-if for the failure reftest (obsolete) (deleted) — Splinter Review
Hello, John san. This patch is the patch what I talked with you this afternoon. It's OK to use fuzzy-if here? What I've been observed about this failure reftest: * This failure can be reproduced only on MacOS 10.10 on try. * This failure can not be reproduced on local MacOS 10.10. (as far as I tried.) * Removing all '東京特許許可局' in the table does not cause the intermittent failure on try. * Removing all words whose font is thinner than 500 does not cause the intermittent failure on try. * Using only one downloadable(mplus-1p-medium) font does not cause the intermittent failure on try. * Replacing mplus-1p-thin and mplus-1p-light with mplus-1p-medium (there are 3 downloadable fonts in the document) does not cause the intermittent failure. I am going to file a new bug for this reftest issue once this patch gets reviewed. Thank you,
Flags: needinfo?(hiikezoe)
Attachment #8709827 - Flags: review?(jdaggett)
Comment on attachment 8709827 [details] [diff] [review] Use fuzzy-if for the failure reftest This is probably fine but I'd like to test this under 10.11 to see if I can reproduce it there. I'll do this tomorrow.
Comment on attachment 8709827 [details] [diff] [review] Use fuzzy-if for the failure reftest Looks fine to me. I tested under OSX 10.11 and the reftest passes. But I do think there's an underlying bug here associated with the load order of fonts. My guess is there an invalidation bug here such that depending upon the load order of fonts, the rendering will change.
Attachment #8709827 - Flags: review?(jd.bugzilla) → review+
Thank you, John-san! The previous patch does not have any spaces between fuzzy-if() and HTTP. This patch fixes it.
Assignee: nobody → hiikezoe
Attachment #8709827 - Attachment is obsolete: true
Attachment #8713586 - Flags: review+
Depends on: 1276160
Depends on: 1328071
Blocks: 1328071
No longer depends on: 1328071
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: