Checkerboarding is frequent and covers sticky elements in specific test case
Categories
(Core :: Panning and Zooming, defect, P3)
Tracking
()
People
(Reporter: fabioturrin, Assigned: kats)
References
()
Details
(Whiteboard: [gfx-noted])
Attachments
(2 files)
47 bytes,
text/x-phabricator-request
|
Details | Review | |
Bug 1424714 - Add a test to ensure sticky position items don't checkerboard unnecessarily. r?mstange
47 bytes,
text/x-phabricator-request
|
Details | Review |
Comment 1•8 years ago
|
||
Reporter | ||
Comment 2•8 years ago
|
||
Assignee | ||
Comment 3•8 years ago
|
||
Assignee | ||
Comment 4•5 years ago
|
||
I'll try to look at this in the near future (this week)
Assignee | ||
Comment 5•5 years ago
|
||
I started looking into this and I'm pretty sure (as alluded in various other bugs that I can't claim to fully understand) the scrolled-clip property for the sticky container layer is wrong. For this test case the clip and scrolled-clip are the same. I think that means that as the grid scrolls, the scrolled-clip will shift too and therefore ends up clipping the sticky item which isn't moving as the grid scrolls. The code in AsyncCompositionManager keeps the clip in place for sticky items (it goes into the mFixedClip part of the ClipParts) but the scrolled clip gets adjusted by the async transform (since it is in the mScrolledClip part of the ClipParts) and then they get intersected.
The scrolled-clip and clip are both set to the displayport, but I think it makes more sense to set the scrolled-clip to something larger - specifically, the entire range of positions that the sticky position can be in. Something like union(initial_position, final_position)
where the initial_position
and final_position
are determined by the scroll range. Or maybe we can drop the scrolled-clip entirely, but I'm not sure if that would run afoul of the requirements listed in this comment (because I don't fully understand the comment yet).
Comment 6•5 years ago
|
||
(In reply to Kartikaya Gupta (email:kats@mozilla.com) from comment #5)
For this test case the clip and scrolled-clip are the same. I think that means that as the grid scrolls, the scrolled-clip will shift too and therefore ends up clipping the sticky item which isn't moving as the grid scrolls. The code in AsyncCompositionManager keeps the clip in place for sticky items (it goes into the mFixedClip part of the ClipParts) but the scrolled clip gets adjusted by the async transform (since it is in the mScrolledClip part of the ClipParts) and then they get intersected.
That sounds like the same diagnosis as in bug 1548397 comment 5, suggesting the same root cause!
Assignee | ||
Comment 7•5 years ago
|
||
I tried taking out the the "if sticky position" part of the clause here. That removes the scrolled-clip from the sticky container layer and does fix the problem, but it breaks the position-sticky-scrolled-clip-1.html testcase. Examining that testcase leads me to believe that there are at least some scenarios where it makes sense for the sticky-pos layer to have a scrolled-clip (that testcase being one such scenario). Thinking more about what the right answer here is...
Comment 8•5 years ago
|
||
I'm cheering for you, kats. I had the checkerboarding problem in mind when I implemented this, but I couldn't think of a better solution. But I'm sure a solution exists.
Assignee | ||
Comment 9•5 years ago
|
||
If you couldn't think of a better solution I'm not sure I will be able to either. What I'm thinking right now is that basically we want to keep the existing behaviour exactly as-is, except in the case where the scrolled-clip assigned to the sticky position container is the displayport of the containing scrollframe. If there's anything other clips that get introduced in between the containing scrollframe and the sticky item, then we want to use those clips. This would take care of the position-sticky-scrolled-clip-1.html testcase, because in that case there's a div in between with its own clip.
In terms of implementing this in the code, one approach might be to set a flag on the scrolledRectClipState
here that basically says "we're clipping to the displayport". When we generate nsDisplayStickyContainer we'd walk up the stack of DisplayListClipState::AutoSaveRestore
instances. If we find an instance that has a clip set on it (pretty much where mUsed
gets set to true) before we find an instance that has the "clipping to displayport" flag set on it, then we know that there's a clip being applied to the sticky container that we need to keep. If we hit the "clipping to displayport" flag then we know we can use a different rect.
I'll try implementing this and see what breaks.
Assignee | ||
Comment 10•5 years ago
|
||
I have a WIP at https://treeherder.mozilla.org/#/jobs?repo=try&group_state=expanded&revision=128dd5e5a1628073a6706be7b97e35b62bbf2b83 that seems to pass tests and also fixes the problem. But it's pretty ugly. Will try to figure out a slightly cleaner way of propagating the necessary information.
Assignee | ||
Comment 12•5 years ago
|
||
(In reply to Kartikaya Gupta (email:kats@mozilla.com) from comment #11)
The WIP also seems to fix bug 1548397.
Sorry, it doesn't fix that bug. I was testing incorrectly.
Assignee | ||
Comment 13•5 years ago
|
||
https://treeherder.mozilla.org/#/jobs?repo=try&group_state=expanded&revision=e2d2d9a58e17a79862dafe9b4bd64316e4892aa9 has cleaned up patches and a testcase. The fix definitely feels like hackery but I expect that it will evolve as I look into other related bugs (bug 1548397 being the first one).
Assignee | ||
Comment 14•5 years ago
|
||
Sigh. Test is failing on Android, looks like it's not checkerboarding in the "test" case at all, which is kind of weird. Will need to investigate.
Assignee | ||
Comment 15•5 years ago
|
||
Apparently the async-displayport properties in reftests end up changing the critical displayport on android, while the non-critical displayport is still unaffected. That seems to be the cause of the test failure.
Assignee | ||
Comment 16•5 years ago
|
||
The displayport clip that is applied to sticky items from the enclosing
scrollframe can cause sticky items to checkerboard even when they might
reasonably be left visible. This is because the displayport clip moves as
the enclosing scrollframe is scrolled, but sticky items may remain fixed
during such scrolling. The displayport clip can therefore clip out sticky
items even if they are "stuck" and should be user-visible.
This patch sets a flag to identify when a sticky item is being clipped by
the displayport clip, and ensures that it doesn't actually get clipped. In
the case where other clips are being applied to the sticky item, we leave the
clips unaffected. This allows for other enclosing elements to clip the sticky
item as before.
Assignee | ||
Comment 17•5 years ago
|
||
Depends on D68582
Comment 18•5 years ago
|
||
Comment 19•5 years ago
|
||
bugherder |
https://hg.mozilla.org/mozilla-central/rev/840f340afe5a
https://hg.mozilla.org/mozilla-central/rev/925ec3ed99a4
Updated•5 years ago
|
Reporter | ||
Comment 20•5 years ago
|
||
Thanks for working on it.
Unfortunately, with my nightly 77.0a1 (2020-05-04) (64 bit) On Windows 10 64bit, the bug is still there, although it seems slightly improved.
The demo is the same as the first post:
https://codepen.io/bludev/pen/BmpwPP
Assignee | ||
Comment 21•5 years ago
|
||
If you can make a standalone test case (i.e. not one on codepen, which tends to introduce all sorts of other elements and nested scrollframes that impact scrolling behaviour) and file a new bug with that I can take a look. Thanks!
Reporter | ||
Comment 22•5 years ago
|
||
I've submitted a new bug with attached demo. Thanks!
Description
•