Bug 1664101 Comment 10 Edit History

Note: The actual edited comment in the bug view page will always show the original commenter’s name and original timestamp.

Here is what seems to be happening during frames where the fixed elements checkerboard:

  * Due to fast scrolling, there is a large (transient) async translation between the visual and layout scroll offset. For example, the layout scroll offset (where we last painted) may be at y=2000, and the visual scroll offset (where we are currently compositing) may be at y=5000.
  * A paint happens, at a time when APZ has already sent a repaint request reflecting the y=5000 visual offset, but the main thread has not yet processed this repaint request. (The repaint request is sitting behind the paint in the event queue, as described in bug 1242609 comment 2.)
  * The main thread [peeks](https://searchfox.org/mozilla-central/rev/d410917833190ee08a62b38f8f9de65cea1e661b/layout/base/nsRefreshDriver.cpp#2015) at the pending repaint request before painting, so it knows to paint a display port that reflects the fact we're compositing at y=5000. However, the layout scroll offset is still at y=2000 (it won't be updated until the repaint request is actually processed).
  * As a result, the display port rect computed at painting time, which is interpreted as being relative to the layout scroll offset, is something like y=3000, minus any display port margin -- so let's say we had a top=500 margin, it would be y=2500. This is then added to the layout scroll offset of y=2000 to produce y=4500, which is the document-relative offset where we actually start painting (appropriate for compositing around y=5000).
  * The problem occurs when we apply this display port rect to fixed content. Fixed content is fixed to the layout viewport, so naively, applying that same y=2500 display port rect to the fixed content should work. Indeed, it works in cases where you're zoomed in, and there's a **non-transient** y=3000 offset between the visual and layout viewports; in such a case, we really do want to start painting the fixed content at something like y=2500 to reflect that we're only compositing a part of it that starts at y=3000.
  * However, in a case like this where there is a **transient** y=3000 offset, this logic results in the display port rect clipping out parts of the fixed content that are actually visible (in this case, all of it).
Here is what seems to be happening during frames where the fixed elements checkerboard:

  * Due to fast scrolling, there is a large (transient) async translation between the visual and layout scroll offset. For example, the layout scroll offset (where we last painted) may be at y=2000, and the visual scroll offset (where we are currently compositing) may be at y=5000.
  * A paint happens, at a time when APZ has already sent a repaint request reflecting the y=5000 visual offset, but the main thread has not yet processed this repaint request. (The repaint request is sitting behind the paint in the event queue, as described in bug 1242609 comment 2.)
  * The main thread [peeks](https://searchfox.org/mozilla-central/rev/d410917833190ee08a62b38f8f9de65cea1e661b/layout/base/nsRefreshDriver.cpp#2015) at the pending repaint request before painting, so it knows to paint a display port that reflects the fact we're compositing at y=5000. However, the layout scroll offset is still at y=2000 (it won't be updated until the repaint request is actually processed).
  * As a result, the display port rect computed at painting time, which is interpreted as being relative to the layout scroll offset, is something like y=3000, minus any display port margin -- so let's say we had a top=500 margin, it would be y=2500. This is then added to the layout scroll offset of y=2000 to produce y=4500, which is the document-relative offset where we actually start painting (appropriate for compositing around y=5000).
  * The problem occurs when we apply this display port rect to fixed content. Fixed content is fixed to the layout viewport, so naively, applying that same y=2500 display port rect to the fixed content should work. Indeed, it works in cases where you're zoomed in, and there's a **non-transient** y=3000 offset between the visual and layout viewports; in such a case, we really do want to start painting the fixed content at something like y=2500 to reflect that we're only compositing a part of it that starts at y=3000. (This is the sort of case bug 1529892 intended to address: painting at y=0 in such a case ended up painting a very large texture and OOMing at high zoom levels.)
  * However, in a case like this where there is a **transient** y=3000 offset, this logic results in the display port rect clipping out parts of the fixed content that are actually visible (in this case, all of it).

Back to Bug 1664101 Comment 10