Closed Bug 967671 Opened 10 years ago Closed 10 years ago

Scrolling start page and then snapping metroFx causes vertical black bar

Categories

(Firefox for Metro Graveyard :: Firefox Start, defect, P1)

x86_64
Windows 8.1
defect

Tracking

(firefox28 verified, firefox29 verified, firefox30 verified, b2g-v1.3 fixed)

VERIFIED FIXED
Firefox 30
Tracking Status
firefox28 --- verified
firefox29 --- verified
firefox30 --- verified
b2g-v1.3 --- fixed

People

(Reporter: TimAbraldes, Assigned: jimm)

References

Details

(Whiteboard: [release28] p=8 s=it-30c-29a-28b.1 r=ff28)

Attachments

(5 files, 2 obsolete files)

Attached image scrollStartSnapBug.png
STR:
  1. Scroll the metroFx start page all the way to the right
  2. Snap metroFx to the left of the screen

Attached screenshot shows what my screen looks like after following the STR above.
Whiteboard: [triage] → [triage] [defect] p=0
Attached image snapped.png
Whiteboard: [triage] [defect] p=0 → p=0
Whiteboard: p=0 → [release28] p=0
Whiteboard: [release28] p=0 → [release28] p=8
Whiteboard: [release28] p=8 → [release28] p=8 r=ff28
The black bar width is equal to the distance scrolled.
Attached patch debug patch (obsolete) — Splinter Review
debug output when scrolling ~150 px to the right, then snap another app into view, cutting our view in half:

mozilla::widget::winrt::FrameworkView::OnWindowSizeChanged
Resize: 0.000000 0.000000 945.000000 1080.000000
APZC: 0EDDC370 got a NotifyLayersUpdated with aIsFirstPaint=0: i=(8 4) cb=(0 0 945 984) dp=(-149.067 0.000 2224.000 705.000) v=(0.000 0.000 1376.000 705.000) s=(0.000 0.000) sr=(0.000 0.000 1376.000 1537.900) z=(1.395 1.000 1.000 1.395) 0
apzc.js SizeChanged 
port: 677 774 
displayPort: 0 0 812.4 928.8 
APZC: 0EDDC370 got a NotifyLayersUpdated with aIsFirstPaint=0: i=(8 4) cb=(0 0 945 984) dp=(0.000 0.000 812.400 928.800) v=(0.000 0.000 1376.000 705.000) s=(0.000 0.000) sr=(0.000 0.000 1376.000 1537.900) z=(1.395 1.000 1.000 1.395) 0
APZC: 0EDDC370 got a NotifyLayersUpdated with aIsFirstPaint=0: i=(8 4) cb=(0 0 945 984) dp=(0.000 0.000 812.400 928.800) v=(0.000 0.000 677.000 705.000) s=(0.000 0.000) sr=(0.000 0.000 677.000 3257.900) z=(1.395 1.000 1.000 1.395) 0
APZC: Calculated displayport as (-149.066589 0.000000 677.000000 2467.500000) from velocity (0.000000 0.000000) paint time 33.766003 metrics: i=(8 4) cb=(0 0 945 984) dp=(-149.067 0.000 2224.000 705.000) v=(0.000 0.000 677.000 705.000) s=(149.067 0.000) sr=(0.000 0.000 677.000 3257.900) z=(1.395 1.000 1.000 1.395) 0

I'm wondering about that first calculated display port of (-149.066589 0.000000 677.000000 2467.500000). The -149 represents the amount content is offset to the left, and also corresponds to the width of the black bar on the right. It appears the origin we compose to is off.

kats, anything stand out to you as being wrong here?
Flags: needinfo?(bugmail.mozilla)
Attached image ~150px scroll
Hmm, I commented our our display port setting up in apzc.js to see if it was playing into this, and it didn't have any effect.
There's a few odd things in the dump you pasted in comment 4. For one thing all the NotifyLayersUpdated say s=(0.000 0.000) which means layout thinks the scroll offset is at 0,0. The "Calculated displayport" line however says s=(149.067 0.000) which means the APZ thinks the scroll offset is at x=149.067. It is computing the displayport accordingly (dp's x is -149.067) so that the displayport extends all the way to the left edge of the about:start page.

Given that the displayport is already at -149.067 in the first NotifyLayersUpdated, that means that APZ must already have requested that displayport before, presumably along with the 149.067 scroll offset. But layout didn't "accept" that scroll offset, or maybe it accepted it and then clobbered it with something else without notifying APZ. Either way the fact that the scroll offsets are out of sync seems wrong.

I would stick a breakpoint or logging at http://mxr.mozilla.org/mozilla-central/source/layout/generic/nsGfxScrollFrame.cpp#1995 and record all the calls made there, to see who's calling it and with what scroll offset.
Flags: needinfo?(bugmail.mozilla)
When we flip to this snapped mode, layout of the start page changes. The page loses its horizontal scroll and scrolls vertically instead. I'll try to catch that transition in some debug output plus the gfx scroll frame info.
Ok, that explains the changes in the scrollable rect (the "sr" values in the dump above). However at some point layout clamps the scroll position to 0,0 (which sounds reasonable if the layout changes) but doesn't inform the APZ. Specifically, the code at [1] needs to get executed but doesn't.

[1] http://mxr.mozilla.org/mozilla-central/source/layout/base/nsDisplayList.cpp?rev=319abcb8c59e#646
Kats, could Bug #964140 be related to this issue? Rather then staying in snapped view, I moved fxmetro back to full view and refreshed the screen while it was scrolled all the way to the right side. Refreshing the screen would produce a vertical black bar. Sometimes I was able to get the vertical black bar by simply scrolling to the right and refreshing (without going into snapped view and then full view)
It's possible, yeah. It certainly sounds like the root cause might be the same.
(In reply to Kartikaya Gupta (email:kats@mozilla.com) from comment #9)
> Ok, that explains the changes in the scrollable rect (the "sr" values in the
> dump above). However at some point layout clamps the scroll position to 0,0
> (which sounds reasonable if the layout changes) but doesn't inform the APZ.
> Specifically, the code at [1] needs to get executed but doesn't.
> 
> [1]
> http://mxr.mozilla.org/mozilla-central/source/layout/base/nsDisplayList.
> cpp?rev=319abcb8c59e#646

This coded isn't getting called because scrollableFrame->OriginOfLastScroll() returns null after a reflow. I think we just need to take that valid pointer check out, although I'm not sure about side effects.

last scroll origin: apz
APZC: 0A8AAA90 got a NotifyLayersUpdated with aIsFirstPaint=0: i=(5 2) cb=(0 0 1920 984) dp=(-184.900 0.000 2224.000 705.000) v=(0.000 0.000 1376.000 705.000) s=(184.900 0.000) sr=(0.000 0.000 2224.000 705.000) z=(1.395 1.000 1.000 1.395) u=(0 4294967296)
mozilla::widget::winrt::FrameworkView::OnWindowActivated
Resize: 0.000000 0.000000 1920.000000 1080.000000
RecordFrameMetrics  scroll overflow: x:0 y:0  rect: 0.000000,0.000000 2224.000000,705.000000  position: 0.000000,0.000000
last scroll origin: apz
APZC: 0A8AAA90 got a NotifyLayersUpdated with aIsFirstPaint=0: i=(5 2) cb=(0 0 1920 984) dp=(-184.900 0.000 2224.000 705.000) v=(0.000 0.000 1376.000 705.000) s=(184.900 0.000) sr=(0.000 0.000 2224.000 705.000) z=(1.395 1.000 1.000 1.395) u=(0 4294967296)

mozilla::widget::winrt::FrameworkView::OnWindowSizeChanged
Resize: 0.000000 0.000000 945.000000 1080.000000
viewstate change event fired, about:start layout updated. 

RecordFrameMetrics  scroll overflow: x:1 y:1  rect: 0.000000,0.000000 1376.000000,1537.900024  position: 0.000000,0.000000
last scroll origin: unknown
APZC: 0A8AAA90 got a NotifyLayersUpdated with aIsFirstPaint=0: i=(5 2) cb=(0 0 945 984) dp=(-184.900 0.000 2224.000 705.000) v=(0.000 0.000 1376.000 705.000) s=(0.000 0.000) sr=(0.000 0.000 1376.000 1537.900) z=(1.395 1.000 1.000 1.395) u=(0 4294967296)

RecordFrameMetrics  scroll overflow: x:1 y:1  rect: 0.000000,0.000000 1376.000000,1537.900024  position: 0.000000,0.000000
last scroll origin: unknown
APZC: 0A8AAA90 got a NotifyLayersUpdated with aIsFirstPaint=0: i=(5 2) cb=(0 0 945 984) dp=(-184.900 0.000 2224.000 705.000) v=(0.000 0.000 1376.000 705.000) s=(0.000 0.000) sr=(0.000 0.000 1376.000 1537.900) z=(1.395 1.000 1.000 1.395) u=(0 4294967296)
RecordFrameMetrics  scroll overflow: x:1 y:1  rect: 0.000000,0.000000 677.000000,3257.899902  position: 0.000000,0.000000

APZC: Calculated displayport as (-184.899979 0.000000 677.000000 2467.500000) from velocity (0.000000 0.000000) paint time 37.151878 metrics: i=(5 2) cb=(0 0 945 984) dp=(-184.900 0.000 2224.000 705.000) v=(0.000 0.000 677.000 705.000) s=(184.900 0.000) sr=(0.000 0.000 677.000 3257.900) z=(1.395 1.000 1.000 1.395) u=(0 759607606732914688)
Attached patch fix (obsolete) — Splinter Review
This gets set to null here - 

http://mxr.mozilla.org/mozilla-central/source/layout/generic/nsGfxScrollFrame.h#308

and when we create the frame. It gets set to something valid in ScrollToImpl. So it seems we should update the offsets when it's null in nsDisplayList.
Attachment #8375535 - Flags: review?(bugmail.mozilla)
Attachment #8374832 - Attachment is obsolete: true
Blocks: 964140
Comment on attachment 8375535 [details] [diff] [review]
fix

Review of attachment 8375535 [details] [diff] [review]:
-----------------------------------------------------------------

::: layout/base/nsDisplayList.cpp
@@ +641,5 @@
>      // If the frame was scrolled since the last layers update, and by
>      // something other than the APZ code, we want to tell the APZ to update
>      // its scroll offset.
>      nsIAtom* originOfLastScroll = scrollableFrame->OriginOfLastScroll();
> +    if (!originOfLastScroll || originOfLastScroll != nsGkAtoms::apz) {

I don't think this is right. In particular if we're in a stable state (i.e. page is loaded, nobody's scrolling anything) and there's some sort of animation going on the page, then layout is going to keep painting each frame of animation, and all of those will send scroll offset updates to APZ. That means if you start panning, there will be noticeable jitter and jumpiness in that scenario.

I think a better solution might be to initialize mOriginOfLastScroll in nsGfxScrollFrame to something that's non-null. nsGkAtoms::other is fine. Can you check if that fixes the problem?
Attachment #8375535 - Flags: review?(bugmail.mozilla) → review-
(In reply to Jim Mathies [:jimm] from comment #13)
> This gets set to null here - 
> 
> http://mxr.mozilla.org/mozilla-central/source/layout/generic/
> nsGfxScrollFrame.h#308
> 
> and when we create the frame.

Note that the line you pointed out above only ever gets called when APZ acknowledges a scroll offset update, which based on the data you're showing me, I don't think is happening. So it's more likely that the frame is destroyed and re-created, and mOriginOfLastScroll gets reset as a result. That's why I think initializing it to something non-null should also fix the problem, and with fewer side-effects.
Attached patch fix v.2Splinter Review
That works too.
Assignee: nobody → jmathies
Attachment #8375553 - Flags: review?(bugmail.mozilla)
Attachment #8375535 - Attachment is obsolete: true
Comment on attachment 8375553 [details] [diff] [review]
fix v.2

Review of attachment 8375553 [details] [diff] [review]:
-----------------------------------------------------------------

r=me but this will require an additional change in APZC::NotifyLayersUpdated, which I'll put up in a second.

Also, would like tn to review the nsGfxScrollFrame change as well. In a nutshell what's happening is that the window resizes, so the scrollframe helper is destroyed and recreated (perhaps the scrollframe itself is destroyed and recreated?). The scroll offset is therefore reset, and so is originOfLastScroll. The scrollId hasn't changed but the scroll offset effectively has, so we need to notify the APZ. Note that this means the first time a scroll frame appears we will also send the scroll offset update to APZ, which is fine because in this case we take the entire FrameMetrics anyway. The patch I will attach will ensure that the acknowledgement is sent even in this case.
Attachment #8375553 - Flags: review?(tnikkel)
Attachment #8375553 - Flags: review?(bugmail.mozilla)
Attachment #8375553 - Flags: review+
This patch is good to have regardless of the other patch. But if we go with that fix then it becomes more likely we'll need this patch to avoid regressions.
Attachment #8375575 - Flags: review?(botond)
(Note: I haven't even compiled the above patch. It would be good to push both together to try to ensure nothing breaks).
Did you need to split that out? Looks like you have two aLayerMetrics.GetScrollOffsetUpdated() if blocks, one right after the other.
(In reply to Jim Mathies [:jimm] from comment #20)
> Did you need to split that out? Looks like you have two
> aLayerMetrics.GetScrollOffsetUpdated() if blocks, one right after the other.

oh, nm, that first one is nested inside something else.
Attachment #8375575 - Flags: review?(botond) → review+
(In reply to Kartikaya Gupta (email:kats@mozilla.com) from comment #19)
> (Note: I haven't even compiled the above patch. It would be good to push
> both together to try to ensure nothing breaks).

I have both patches applied locally, everything looks ok.
Attachment #8375553 - Flags: review?(tnikkel) → review+
Kats, do you think this will be ok to uplift to aurora so we can get it out a bit sooner? (Beta seems a bit risky to me.)
Flags: needinfo?(bugmail.mozilla)
Status: NEW → ASSIGNED
Priority: -- → P1
QA Contact: jbecerra
Whiteboard: [release28] p=8 r=ff28 → [release28] p=8 s=it-30c-29a-28b.1 r=ff28
https://hg.mozilla.org/mozilla-central/rev/fbcd1f3a1703
https://hg.mozilla.org/mozilla-central/rev/af48e36fd5a3
Status: ASSIGNED → RESOLVED
Closed: 10 years ago
Resolution: --- → FIXED
Target Milestone: --- → Firefox 30
Yeah I'm fine with uplifting to Aurora and actually even Beta. Note that only attachment 8375553 [details] [diff] [review] should be uplifted; the other patch is dependent on bug 963278 which was never uplifted. I looked at the code currently on beta and I'm around 95% sure that just uplifting the one patch won't cause issues. I'll leave it up to you decide how far you want to uplift it.
Flags: needinfo?(bugmail.mozilla)
I can confirm this issue is no longer reproducing on latest Nightly (build ID: 20140217030202).
Comment on attachment 8375553 [details] [diff] [review]
fix v.2

[Approval Request Comment]
Bug caused by (feature/regressing bug #): unknown
User impact if declined: corner case rendering bug when resizing the main browser view.
Testing completed (on m-c, etc.): yes
Risk to taking this patch (and alternatives if risky): kats seems positive there's little risk, I'll take his word for it. :)
String or IDL/UUID changes made by this patch: none
Attachment #8375553 - Flags: approval-mozilla-beta?
Attachment #8375553 - Flags: approval-mozilla-aurora?
Attachment #8375553 - Flags: approval-mozilla-beta?
Attachment #8375553 - Flags: approval-mozilla-beta+
Attachment #8375553 - Flags: approval-mozilla-aurora?
Attachment #8375553 - Flags: approval-mozilla-aurora+
(In reply to Jim Mathies [:jimm] from comment #25)
> https://hg.mozilla.org/integration/mozilla-inbound/rev/af48e36fd5a3

Please make sure you copy the commit message and author from the patch next time! :)
(In reply to Phil Ringnalda (:philor) from comment #27)
> https://hg.mozilla.org/mozilla-central/rev/fbcd1f3a1703


This is the only checkin to uplift.
Keywords: verifyme
Mozilla/5.0 (Windows NT 6.3; rv:28.0) Gecko/20100101 Firefox/28.0
Mozilla/5.0 (Windows NT 6.3; rv:29.0) Gecko/20100101 Firefox/29.0

Verified as fixed on Firefox 28 beta 4 (build ID: 20140218122424) and on latest Aurora (build ID: 20140219004002).
Status: RESOLVED → VERIFIED
Keywords: verifyme
Note that the second patch on this bug (attachment 8375575 [details] [diff] [review]) got uplifted into 1.3 as part of the uplift of bug 980679, in this cset:

https://hg.mozilla.org/releases/mozilla-b2g28_v1_3/rev/ab227cdd984c
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: