Closed Bug 1267438 Opened 9 years ago Closed 9 years ago

Make the representation of clips in the Layers API more flexible

Categories

(Core :: Graphics: Layers, defect)

defect
Not set
normal

Tracking

()

RESOLVED FIXED
mozilla49
Tracking Status
firefox49 --- fixed

People

(Reporter: botond, Assigned: botond)

References

Details

(Keywords: correctness, Whiteboard: [gfx-noted])

Attachments

(13 files)

58 bytes, text/x-review-board-request
mstange
: review+
Details
58 bytes, text/x-review-board-request
mstange
: review+
Details
58 bytes, text/x-review-board-request
kats
: review+
Details
58 bytes, text/x-review-board-request
mstange
: review+
Details
58 bytes, text/x-review-board-request
mstange
: review+
Details
58 bytes, text/x-review-board-request
mstange
: review+
Details
58 bytes, text/x-review-board-request
mstange
: review+
Details
58 bytes, text/x-review-board-request
mstange
: review+
Details
58 bytes, text/x-review-board-request
mstange
: review+
Details
58 bytes, text/x-review-board-request
mstange
: review+
Details
58 bytes, text/x-review-board-request
mstange
: review+
Details
58 bytes, text/x-review-board-request
mstange
: review+
Details
8.88 KB, patch
kats
: review+
Details | Diff | Splinter Review
We currently represent scroll clips in the Layers API by each ScrollMetadata having an optional clip rect, called its scroll clip, which is considered to be scrolled by all scroll frames above it. In addition, a layer can be marked as "fixed" with respect to a scroll frame (to implement position:fixed and background-attachment:fixed), and fixed layers have an additional flag, "is clip fixed", that governs whether the clips are also fixed. This flag applies to all clips. As a result, we cannot represent layers which are fixed and which have some clips that are fixed and some clips that scroll. Such layers come up when e.g. position:fixed is combined with the "clip" property, as in bug 1214146. To fix this, we propose changing the representation of clip rects in the Layers API. We will store, on each Layer, a list of clip rects, and for each clip rect, an associated scroll id (which could be NULL_SCROLL_ID) which represents the bottommost scroll id that scrolls that clip. In additional, we will retain the optional "fixed with respect to scroll id" annotation. However, there will be no "is clip fixed" annotation; whether a clip is fixed will be determined for each clip by its associated scroll id.
Keywords: correctness
Whiteboard: [gfx-noted]
(In reply to Botond Ballo [:botond] from comment #0) > We will store, on each Layer, a list of clip rects, and for each clip rect, > an associated scroll id (which could be NULL_SCROLL_ID) which represents the > bottommost scroll id that scrolls that clip. In additional, we will retain > the optional "fixed with respect to scroll id" annotation. However, there > will be no "is clip fixed" annotation; whether a clip is fixed will be > determined for each clip by its associated scroll id. It turns out this representation makes the compositor-side code more convoluted than it needs to be, so Markus and I agreed to change tack slightly: we'll keep optional scroll clips stored in ScrollMetadatas, with the (unchanged) interpretation that they apply on top of the corresponding scroll transform, but we'll add a (single) optional scroll clip to the Layer as well, to represent a clip that is scrolled by all scroll frames associated with the layer. The "is clip fixed" annotation is still going away; if a Layer is fixed, its regular clip will always be fixed, and its scroll clip will always scroll. Layout can populate the two clips as needed to get the desired behaviour.
Here are some WIP patches; not ready for review yet. Rough outline of the remaining patches: - Use the additional scroll clip on the compositor side (during hit testing tree construction and AsyncCompositionManager) - Populate the new scroll clip on the Layout side instead of having a regular clip with isClipFixed=false - Remove isClipFixed
Blocks: 1269537
After some discussion with Markus today, we decided that "scroll clip" is a misleading name for the clip we're adding. Accordingly, I'm going to rename the type LayerScrollClip to LayerClip, and the new clip we're adding (which is still of type LayerClip) to "scrolled clip".
Summary: Make the representation of scroll clips in the Layers API more flexible → Make the representation of clips in the Layers API more flexible
Attachment #8747308 - Attachment description: MozReview Request: Bug 1267438 - Group ScrollMetadata's optional clip rect and mask layer index into a LayerScrollClip structure. r=mstange → MozReview Request: Bug 1267438 - Group ScrollMetadata's optional clip rect and mask layer index into a LayerClip structure. r=mstange
Attachment #8747310 - Attachment description: MozReview Request: Bug 1267438 - Give layers an (optional) additional scroll clip that is scrolled by all scroll frames associated with the layer. r=mstange → MozReview Request: Bug 1267438 - Give layers an optional scrolled clip that is scrolled by all scroll frames associated with the layer. r=mstange
Comment on attachment 8747307 [details] MozReview Request: Bug 1267438 - Use IntersectMaybeRects() in Layer::GetCombinedClipRect(). r=mstange Review request updated; see interdiff: https://reviewboard.mozilla.org/r/49825/diff/1-2/
Comment on attachment 8747308 [details] MozReview Request: Bug 1267438 - Group ScrollMetadata's optional clip rect and mask layer index into a LayerClip structure. r=mstange Review request updated; see interdiff: https://reviewboard.mozilla.org/r/49827/diff/1-2/
Comment on attachment 8747309 [details] MozReview Request: Bug 1267438 - Do not propagate the scroll clip to APZC's copy of ScrollMetadata. r=kats Review request updated; see interdiff: https://reviewboard.mozilla.org/r/49829/diff/1-2/
Comment on attachment 8747310 [details] MozReview Request: Bug 1267438 - Give layers an optional scrolled clip that is scrolled by all scroll frames associated with the layer. r=mstange Review request updated; see interdiff: https://reviewboard.mozilla.org/r/49831/diff/1-2/
The updated patch series implements the API change. Try push: https://treeherder.mozilla.org/#/jobs?repo=try&revision=9ee9661c8b74 Before posting the series for review, I'd like to see the Try push passing. In addition, the two patches marked "[WIP]" need some cleanup.
Oops, I used Maybe::emplace() improperly in one place. https://treeherder.mozilla.org/#/jobs?repo=try&revision=b4524431f971
There are also some async-scrolling reftest failures that I need to investigate.
(In reply to Botond Ballo [:botond] from comment #21) > There are also some async-scrolling reftest failures that I need to investigate. The problem is that there is a second codepath in Layout, added in bug 1216580, that propagates the clip on a fixed background item to a layer, which I wasn't aware of, which also needs to be changed to use the scrolled clip.
Attachment #8748937 - Attachment description: MozReview Request: [WIP] Bug 1267438 - During AlignFixedAndStickyLayers, only un-adjust the fixed portion of a layer's clip rect. r=mstange → MozReview Request: Bug 1267438 - During AlignFixedAndStickyLayers, only un-adjust the fixed portion of a layer's clip rect. r=mstange
Attachment #8748938 - Attachment description: MozReview Request: [WIP] Bug 1267438 - Use the scrolled clip in AsyncCompositionManager. r=mstange → MozReview Request: Bug 1267438 - Use the scrolled clip in AsyncCompositionManager. r=mstange
Attachment #8749898 - Flags: review?(mstange)
Attachment #8747310 - Flags: review?(mstange)
Attachment #8748935 - Flags: review?(mstange)
Attachment #8748936 - Flags: review?(mstange)
Attachment #8748937 - Flags: review?(mstange)
Attachment #8748938 - Flags: review?(mstange)
Attachment #8748939 - Flags: review?(mstange)
Attachment #8748940 - Flags: review?(mstange)
Attachment #8748941 - Flags: review?(mstange)
Comment on attachment 8747310 [details] MozReview Request: Bug 1267438 - Give layers an optional scrolled clip that is scrolled by all scroll frames associated with the layer. r=mstange Review request updated; see interdiff: https://reviewboard.mozilla.org/r/49831/diff/2-3/
Comment on attachment 8748935 [details] MozReview Request: Bug 1267438 - Use the layer's scrolled clip during compositor hit testing. r=mstange Review request updated; see interdiff: https://reviewboard.mozilla.org/r/50617/diff/1-2/
Comment on attachment 8748936 [details] MozReview Request: Bug 1267438 - Factor out a helper function to check if a layer is fixed or sticky. r=mstange Review request updated; see interdiff: https://reviewboard.mozilla.org/r/50619/diff/1-2/
Comment on attachment 8748937 [details] MozReview Request: Bug 1267438 - During AlignFixedAndStickyLayers, only un-adjust the fixed portion of a layer's clip rect. r=mstange Review request updated; see interdiff: https://reviewboard.mozilla.org/r/50621/diff/1-2/
Comment on attachment 8748938 [details] MozReview Request: Bug 1267438 - Use the scrolled clip in AsyncCompositionManager. r=mstange Review request updated; see interdiff: https://reviewboard.mozilla.org/r/50623/diff/1-2/
Comment on attachment 8748939 [details] MozReview Request: Bug 1267438 - For fixed backgrounds, use the scrolled clip rather than the isClipFixed=false annotation. r=mstange Review request updated; see interdiff: https://reviewboard.mozilla.org/r/50625/diff/1-2/
Comment on attachment 8748940 [details] MozReview Request: Bug 1267438 - Remove the (no longer used) isClipFixed=false annotation. r=mstange Review request updated; see interdiff: https://reviewboard.mozilla.org/r/50627/diff/1-2/
Comment on attachment 8748941 [details] MozReview Request: Bug 1267438 - Remove the redundant aTransformAffectsLayerClip argument to AlignFixedAndStickyLayers. r=mstange Review request updated; see interdiff: https://reviewboard.mozilla.org/r/50629/diff/1-2/
Attachment #8747307 - Flags: review?(mstange)
Attachment #8747308 - Flags: review?(mstange)
Attachment #8747309 - Flags: review?(bugmail.mozilla)
I updated the patches for fix the reftest failures, cleaned them up, and posted for review. Some commentary: Part 1 Refactors Layer::GetCombinedClipRect() to use IntersectMaybeRects(), in preparation for eventually combining the scrolled clip there as well. Part 2 Groups the optional clip rect and mask layer index in ScrollMetadata into a LayerClip structure, in preparation for reusing this structure for the layer's scrolled clip. Note that the mask layer index is still optional inside the structure, because we can have a clip without a mask layer. Part 3 Stops propagating ScrollMetadata's scroll clip to APZC. This reflects the fact the different layers scrolled by the same scroll frame can have different scroll clips, but we have only one APZC per scroll frame, so it makes so sense for APZC to use per-layer properties from ScrollMetadata. (It already wasn't using the scroll clip.) In the future, we'd like to separate the per-layer properties out more clearly. Part 4 Introduces the scrolled clip to the Layers API, without using it yet on either side of the API. Part 5 Uses the scrolled clip during compositor hit testing. Note that as per bug 1269537, the treatment of clips during compositor hit testing is wrong; this patch ignores that problem for the time being, leaving a proper fix for bug 1269537. Part 6 Factors out a helper function for determining if a layer is fixed or sticky. When I wrote this, I expected to use it later in the patch series (to condition the use of ClipParts on the layer being fixed or sticky), but ended up not using it (and just using ClipParts unconditionally). I kept the refactoring because I think it's still nice. Part 7 Modifies ApplyAsyncContentTransformToTree to split the shadow clip into two parts, a fixed part and a scrolled part, and have AlignFixedAndStickyLayers only adjust the fixed part. Technically, the old behaviour of adjusting both parts was wrong, but since bug 1231538, layer structures that triggers the wrongness never occur (and before bug 12315387, rendering of such layer structures was wrong anyways), so this is just a refactoring. However, not adjusting the scrolled part of the clip becomes important once we start including the layer's scrolled clip in it. I realize that I'm overloading the term "scrolled clip" to mean both the layer property, and one of the clip parts; if you have a suggestion for another name for the clip part, let me know. Part 8 Uses the layer's scrolled clip as part of the scrolled part of the shadow clip in AsyncCompositionManager. The corresponding mask layer, if present, is handled as well. One thing I wasn't sure about is whether the Render phase of composition requires any changes for the new mask layer. I don't think so, as it's part of mAncestorMaskLayers, and those are looped over in the Render phase, but I could be wrong. Part 9 Modifies the Layout side of the Layers API to allow adding ancestor mask layers from places other than SetupScrollMetadata, in anticipation of adding the mask layer for the scrolled clip. Part 10 Modifies Layout to represent the clip for a fixed background layer as a scrolled clip rather than using a regular clip and setting the isClipFixed=false annotation. Part 11 Removes the isClipFixed=false annotation, which is no longer used, from both layout and compositor code. Part 12 Simplifies AlignFixedAndStickyLayers a bit by removing the aTransformAffectsLayerClip parameter. The rationale here is that, now that isClipFixed is removed, the only time this would be false is if we don't have a clip rect yet at this point, in which case there's nothing to adjust anyways.
Attachment #8747309 - Flags: review?(bugmail.mozilla) → review+
Comment on attachment 8747309 [details] MozReview Request: Bug 1267438 - Do not propagate the scroll clip to APZC's copy of ScrollMetadata. r=kats https://reviewboard.mozilla.org/r/49829/#review48093
Comment on attachment 8747307 [details] MozReview Request: Bug 1267438 - Use IntersectMaybeRects() in Layer::GetCombinedClipRect(). r=mstange https://reviewboard.mozilla.org/r/49825/#review48181
Attachment #8747307 - Flags: review?(mstange) → review+
Comment on attachment 8747308 [details] MozReview Request: Bug 1267438 - Group ScrollMetadata's optional clip rect and mask layer index into a LayerClip structure. r=mstange https://reviewboard.mozilla.org/r/49827/#review48185
Attachment #8747308 - Flags: review?(mstange) → review+
Comment on attachment 8747310 [details] MozReview Request: Bug 1267438 - Give layers an optional scrolled clip that is scrolled by all scroll frames associated with the layer. r=mstange https://reviewboard.mozilla.org/r/49831/#review48195
Attachment #8747310 - Flags: review?(mstange) → review+
Comment on attachment 8748935 [details] MozReview Request: Bug 1267438 - Use the layer's scrolled clip during compositor hit testing. r=mstange https://reviewboard.mozilla.org/r/50617/#review48197
Attachment #8748935 - Flags: review?(mstange) → review+
Attachment #8748936 - Flags: review?(mstange) → review+
Comment on attachment 8748936 [details] MozReview Request: Bug 1267438 - Factor out a helper function to check if a layer is fixed or sticky. r=mstange https://reviewboard.mozilla.org/r/50619/#review48199
Comment on attachment 8748937 [details] MozReview Request: Bug 1267438 - During AlignFixedAndStickyLayers, only un-adjust the fixed portion of a layer's clip rect. r=mstange https://reviewboard.mozilla.org/r/50621/#review48223 Looks good. I'd prefer the life cycle of the clip parts cache to be a little more explicit, though. E.g. you could have it as a local variable in TransformShadowTree and it as an argument to the functions that need it. Otherwise casual readers of AsyncCompositionManager.h might get alarmed about there being raw Layer* pointers in the cache's keys.
Attachment #8748937 - Flags: review?(mstange) → review+
Comment on attachment 8748938 [details] MozReview Request: Bug 1267438 - Use the scrolled clip in AsyncCompositionManager. r=mstange https://reviewboard.mozilla.org/r/50623/#review48227
Attachment #8748938 - Flags: review?(mstange) → review+
Attachment #8749898 - Flags: review?(mstange) → review+
Comment on attachment 8749898 [details] MozReview Request: Bug 1267438 - Support adding ancestor mask layers from places other than SetupScrollingMetadata. r=mstange https://reviewboard.mozilla.org/r/51237/#review48229 ::: layout/base/FrameLayerBuilder.cpp:5103 (Diff revision 1) > } else { > NS_ASSERTION(oldLayer->GetType() == Layer::TYPE_CONTAINER, > "Wrong layer type"); > containerLayer = static_cast<ContainerLayer*>(oldLayer); > containerLayer->SetMaskLayer(nullptr); > + containerLayer->SetAncestorMaskLayers({}); Cool!
Comment on attachment 8748939 [details] MozReview Request: Bug 1267438 - For fixed backgrounds, use the scrolled clip rather than the isClipFixed=false annotation. r=mstange https://reviewboard.mozilla.org/r/50625/#review48239 ::: layout/base/FrameLayerBuilder.cpp:4048 (Diff revision 2) > + if (shouldFixToViewport) { > + ownLayer->SetScrolledClip(Nothing()); > + } else { > + ownLayer->SetClipRect(Nothing()); > + } I'm not a fan of this. Can we, before we go into the if (layerClip.HasClip()), just set both to Nothing()? We really only want at most one of the two to be non-Nothing. The code you have here would break that invariant if it ever reused an existing ownLayer with a different shouldFixToViewport value. I don't think that can happen, but let's do the safe thing anyway.
Attachment #8748939 - Flags: review?(mstange) → review+
Comment on attachment 8748940 [details] MozReview Request: Bug 1267438 - Remove the (no longer used) isClipFixed=false annotation. r=mstange https://reviewboard.mozilla.org/r/50627/#review48243
Attachment #8748940 - Flags: review?(mstange) → review+
Comment on attachment 8748941 [details] MozReview Request: Bug 1267438 - Remove the redundant aTransformAffectsLayerClip argument to AlignFixedAndStickyLayers. r=mstange https://reviewboard.mozilla.org/r/50629/#review48245
Attachment #8748941 - Flags: review?(mstange) → review+
Thanks for the reviews! Addressed review comments, rebased, and landed.
Flags: needinfo?(botond)
(In reply to Ryan VanderMeulen [:RyanVM] from comment #48) > Android R2 has been permafailing since this landed: > https://treeherder.mozilla.org/logviewer.html#?job_id=27546122&repo=mozilla- > inbound That's definitely caused by my patches. Sorry about that! I have a theory about what's causing the failure, testing it now.
(In reply to Botond Ballo [:botond] from comment #49) > I have a theory about what's causing the failure, testing it now. I pushed an attempted fix to Try [1], but some Android reftests are still failing. Let's just back this out so the tree can reopen. [1] https://treeherder.mozilla.org/#/jobs?repo=try&revision=87b69e5c7727
Flags: needinfo?(botond)
I'm pretty sure the remaining failures are related to the special-casing of UsesContainerScrolling() (which is only true on Android) here: https://dxr.mozilla.org/mozilla-central/rev/043082cb7bd8490c60815f67fbd1f33323ad7663/gfx/layers/composite/AsyncCompositionManager.cpp#902
(In reply to Botond Ballo [:botond] from comment #52) > I'm pretty sure the remaining failures are related to the special-casing of > UsesContainerScrolling() (which is only true on Android) here: > https://dxr.mozilla.org/mozilla-central/rev/ > 043082cb7bd8490c60815f67fbd1f33323ad7663/gfx/layers/composite/ > AsyncCompositionManager.cpp#902 I tried removing that special-casing, but not only did that not fix the remaining reftest failures, it broke other things [1], so red herring, I guess. [1] https://treeherder.mozilla.org/#/jobs?repo=try&revision=b97e86f1b159
All right, I debugged this and have things passing locally. There were two problems: - The code in ApplyAsyncContentTransformToTree that detected whether the clip has changed, in the sense of a shadow clip distinct from the layer clip needing to be set, failed to take into consideration the presence of a scrolled clip. (This was the fix I pushed in comment 50.) - While addressing Markus' review comment about having the ClipPartsCache live in TransformShadowTree() and passing it around rather than having it be a field of AsyncCompositionManager, I made the ClipPartsCache argument to AlignFixedAndStickyLayers optional (because TransformScrollableLayer() also calls it), defaulting it to nullptr, but then forgot to pass in a non-nullptr argument at the ApplyAsyncContentTransformToTree call site. Silly me! Try push for updated patches: https://treeherder.mozilla.org/#/jobs?repo=try&revision=cde6eea6a00d
(In reply to Botond Ballo [:botond] from comment #54) > Try push for updated patches: > > https://treeherder.mozilla.org/#/jobs?repo=try&revision=cde6eea6a00d ^ Looking good, relanded.
This is some minor cleanup to AsyncCompositionManager, applying on top of bug 1227231, which I intend to land as a follow-up after this and bug 1227231 land: - Removes an outdated comment - Moves the declaration of the ClipPartsCache object from TransformShadwoTree() to ApplyAsyncContentTransformToTree(), since - as of bug 1227231 - the latter is no longer recursive. - Makes better use of Maybe, assigning directly to the object inside when we know there is one rather than assigning to the Maybe.
Attachment #8751514 - Flags: review?(bugmail.mozilla)
Comment on attachment 8751514 [details] [diff] [review] Some minor follow-up cleanup Review of attachment 8751514 [details] [diff] [review]: ----------------------------------------------------------------- Seems straightforward enough.
Attachment #8751514 - Flags: review?(bugmail.mozilla) → review+
Depends on: 1272525
(In reply to Botond Ballo [:botond] from comment #57) > This is some minor cleanup to AsyncCompositionManager, applying on top of > bug 1227231, which I intend to land as a follow-up after this and bug > 1227231 land Group-landed with bug 1270902.
Blocks: 1278656
No longer blocks: 1278656
Depends on: 1285619
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: