Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make stacking context clipping explicit #2600

Merged

Conversation

@mrobinson
Copy link
Member

mrobinson commented Apr 2, 2018

Instead of relying on the combination of a stacking contexts which
render to intermediate surfaces and the PushStackingContext's clip node,
add an explicit clipping node parameter for stacking contexts. This is
necessary, because currently stacking context clipping is done by always
rendering to an intermediate surface. Once we support merging stacking
context and contained item clip chains we can remove this and the extra
parameter.


This change is Reviewable

@mrobinson mrobinson requested a review from glennw Apr 2, 2018
@mrobinson mrobinson force-pushed the mrobinson:explicit-stacking-context-clipping branch from 06a6964 to 667b368 Apr 2, 2018
@mrobinson
Copy link
Member Author

mrobinson commented Apr 2, 2018

The Gecko try job for this change is here: https://treeherder.mozilla.org/#/jobs?repo=try&revision=653eda9276eb3ecaede897f2f98e6263a69ca4b5&selectedJob=171426186

Looks like there are some intermittent failures and one newly passing test.

@mrobinson mrobinson force-pushed the mrobinson:explicit-stacking-context-clipping branch from 667b368 to 8e98097 Apr 2, 2018
@glennw
Copy link
Member

glennw commented Apr 2, 2018

Reviewed 24 of 24 files at r1.
Review status: all files reviewed at latest revision, all discussions resolved.


webrender/src/batch.rs, line 680 at r1 (raw file):

                                let source_id = cache_task_id;

                                match picture.composite_mode.expect("bug: only composites here") {

This change will mean the catch-all _ at the bottom of this match executes if a bug occurs and we get here without a composite mode. Is there a specific reason to remove the expect here?


webrender/src/display_list_flattener.rs, line 1201 at r1 (raw file):

            frame_output_pipeline_id,
            true,
            clipping_node.is_some(),

We should perhaps test here (well, later probably) if the clipping node actually applies any useful clips? This would avoid doing redundant render work if the client supplies a clip node that has no effect.

If we did something like that, we'd probably check during the picture prepare each frame if the clip node applies to this Picture, and select at that point whether to use an intermediate surface.

We can do that as a follow up optimization later though - this will definitely let us do some testing in Gecko and make sure it works as we want the API to.


webrender/src/picture.rs, line 204 at r1 (raw file):

        if self.can_draw_directly_to_parent_surface() {
            if !self.force_intermediate_surface {

Should this bool check just be added to the can_draw_directly_to_parent_surface method?


webrender/src/picture.rs, line 373 at r1 (raw file):

                prim_screen_rect.clipped
            }
            None =>unreachable!("None case not handled by can_draw_directly_to_parent_surface."),

nit: space


webrender/src/prim_store.rs, line 1050 at r1 (raw file):

            apply_local_clip_rect,
        );
        picture.force_intermediate_surface = force_intermediate_surface;

Should we just push this through the new_image method rather than making it a mut variable here and setting it?


wrench/reftests/filters/blend-clipped.png, line 0 at r1 (raw file):
Is this just a change to the crop dimensions or was the content affected too?


Comments from Reviewable

Copy link
Member

glennw left a comment

Generally this looks great! I added some comments in reviewable.

@bors-servo
Copy link
Contributor

bors-servo commented Apr 3, 2018

The latest upstream changes (presumably #2601) made this pull request unmergeable. Please resolve the merge conflicts.

@mrobinson
Copy link
Member Author

mrobinson commented Apr 3, 2018

Thanks for the review! I've answered you comments below and updated the PR.


Review status: all files reviewed at latest revision, 6 unresolved discussions, some commit checks failed.


webrender/src/batch.rs, line 680 at r1 (raw file):

Previously, glennw (Glenn Watson) wrote…

This change will mean the catch-all _ at the bottom of this match executes if a bug occurs and we get here without a composite mode. Is there a specific reason to remove the expect here?

The issue is that now even Pictures without a composition mode might have a surface assigned. This code was expecting that to never happen. Unless there is a better way to handle this, I can maintain the runtime check is by adding an assertion like:

                                assert!(
                                    picture.composite_mode.is_some() ||
                                    picture.force_intermediate_surface
                                );

webrender/src/display_list_flattener.rs, line 1201 at r1 (raw file):

Previously, glennw (Glenn Watson) wrote…

We should perhaps test here (well, later probably) if the clipping node actually applies any useful clips? This would avoid doing redundant render work if the client supplies a clip node that has no effect.

If we did something like that, we'd probably check during the picture prepare each frame if the clip node applies to this Picture, and select at that point whether to use an intermediate surface.

We can do that as a follow up optimization later though - this will definitely let us do some testing in Gecko and make sure it works as we want the API to.

That's correct. Right now the clips are applied twice, which in our rendering model could even affect the output. Eventually I think we will need to append the two clip chains on all items in the stacking context (while perhaps removing duplicate clips). In the end, this should remove the need to force the use of an intermediate surface.

This may require us to revisit how clips are applied in WebRender, in general.


webrender/src/picture.rs, line 204 at r1 (raw file):

Previously, glennw (Glenn Watson) wrote…

Should this bool check just be added to the can_draw_directly_to_parent_surface method?

Yes, this made the code quite a bit simpler!


webrender/src/picture.rs, line 373 at r1 (raw file):

Previously, glennw (Glenn Watson) wrote…

nit: space

This should be fixed with the previous change,


webrender/src/prim_store.rs, line 1050 at r1 (raw file):

Previously, glennw (Glenn Watson) wrote…

Should we just push this through the new_image method rather than making it a mut variable here and setting it?

Done.


wrench/reftests/filters/blend-clipped.png, line at r1 (raw file):

Previously, glennw (Glenn Watson) wrote…

Is this just a change to the crop dimensions or was the content affected too?

The content was affected here as well.


Comments from Reviewable

@mrobinson mrobinson force-pushed the mrobinson:explicit-stacking-context-clipping branch from 8e98097 to 7cd5b93 Apr 3, 2018
@glennw
Copy link
Member

glennw commented Apr 3, 2018

Review status: 20 of 24 files reviewed at latest revision, 2 unresolved discussions.


webrender/src/batch.rs, line 680 at r1 (raw file):

Previously, mrobinson (Martin Robinson) wrote…

The issue is that now even Pictures without a composition mode might have a surface assigned. This code was expecting that to never happen. Unless there is a better way to handle this, I can maintain the runtime check is by adding an assertion like:

                                assert!(
                                    picture.composite_mode.is_some() ||
                                    picture.force_intermediate_surface
                                );

Ah, I see. I inverted that logic a bit in 6b63b20, which is merging now. That will unfortunately conflict with your change, but perhaps the logic there might work a bit better with your change now (it inverts the composite mode / surface check). Or does that complicate things further?


webrender/src/display_list_flattener.rs, line 1201 at r1 (raw file):

Previously, mrobinson (Martin Robinson) wrote…

That's correct. Right now the clips are applied twice, which in our rendering model could even affect the output. Eventually I think we will need to append the two clip chains on all items in the stacking context (while perhaps removing duplicate clips). In the end, this should remove the need to force the use of an intermediate surface.

This may require us to revisit how clips are applied in WebRender, in general.

In theory, it's possible to avoid having clips applied twice, by having a different clip chain applied to the stacking context from the one that is set on primitives within the stacking context, isn't it? I thought the idea was that the caller could then choose whether to specify a clip-chain for the stacking context AND/OR the primitive as they want to. Or is my conceptual model of how this works not right?


Comments from Reviewable

@bors-servo
Copy link
Contributor

bors-servo commented Apr 3, 2018

The latest upstream changes (presumably #2588) made this pull request unmergeable. Please resolve the merge conflicts.

@glennw
Copy link
Member

glennw commented Apr 4, 2018

r=me btw, once rebased and the questions above are covered.

@mrobinson mrobinson force-pushed the mrobinson:explicit-stacking-context-clipping branch from 7cd5b93 to 762d6a9 Apr 4, 2018
@bors-servo
Copy link
Contributor

bors-servo commented Apr 4, 2018

The latest upstream changes (presumably #2609) made this pull request unmergeable. Please resolve the merge conflicts.

@mrobinson mrobinson force-pushed the mrobinson:explicit-stacking-context-clipping branch from 762d6a9 to 8f35949 Apr 4, 2018
Instead of relying on the combination of a stacking contexts which
render to intermediate surfaces and the PushStackingContext's clip node,
add an explicit clipping node parameter for stacking contexts. This is
necessary, because currently stacking context clipping is done by always
rendering to an intermediate surface. Once we support merging stacking
context and contained item clip chains we can remove this and the extra
parameter.
@mrobinson mrobinson force-pushed the mrobinson:explicit-stacking-context-clipping branch from 8f35949 to 5e42243 Apr 4, 2018
@mrobinson
Copy link
Member Author

mrobinson commented Apr 4, 2018

Review status: 17 of 24 files reviewed at latest revision, 2 unresolved discussions.


webrender/src/batch.rs, line 680 at r1 (raw file):

Previously, glennw (Glenn Watson) wrote…

Ah, I see. I inverted that logic a bit in 6b63b20, which is merging now. That will unfortunately conflict with your change, but perhaps the logic there might work a bit better with your change now (it inverts the composite mode / surface check). Or does that complicate things further?

I think it works a bit better with your change from 6b63b20. Hopefully we can remove this completely in the future


webrender/src/display_list_flattener.rs, line 1201 at r1 (raw file):

Previously, glennw (Glenn Watson) wrote…

In theory, it's possible to avoid having clips applied twice, by having a different clip chain applied to the stacking context from the one that is set on primitives within the stacking context, isn't it? I thought the idea was that the caller could then choose whether to specify a clip-chain for the stacking context AND/OR the primitive as they want to. Or is my conceptual model of how this works not right?

Oh I definitely want to preserve the functionality where when the stacking context and primitives are assigned different clip chains they both clip the primitive. This is how things work after this change.

What I mean by avoiding double clipping is to handle the situation where, for instance, the stacking context clip chain is a subset of the primitive clip chain. In this example, the stacking context clip chain would be ignored completely. It would be great to have this de-duplication done on a per-clip basis while processing primitive runs.


Comments from Reviewable

@mrobinson
Copy link
Member Author

mrobinson commented Apr 4, 2018

@bors-servo r=glennw

@bors-servo
Copy link
Contributor

bors-servo commented Apr 4, 2018

📌 Commit 5e42243 has been approved by glennw

@bors-servo
Copy link
Contributor

bors-servo commented Apr 4, 2018

Testing commit 5e42243 with merge 5922781...

bors-servo added a commit that referenced this pull request Apr 4, 2018
…=glennw

Make stacking context clipping explicit

Instead of relying on the combination of a stacking contexts which
render to intermediate surfaces and the PushStackingContext's clip node,
add an explicit clipping node parameter for stacking contexts. This is
necessary, because currently stacking context clipping is done by always
rendering to an intermediate surface. Once we support merging stacking
context and contained item clip chains we can remove this and the extra
parameter.

<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/webrender/2600)
<!-- Reviewable:end -->
@bors-servo
Copy link
Contributor

bors-servo commented Apr 4, 2018

☀️ Test successful - status-appveyor, status-taskcluster
Approved by: glennw
Pushing 5922781 to master...

@bors-servo bors-servo merged commit 5e42243 into servo:master Apr 4, 2018
3 of 4 checks passed
3 of 4 checks passed
code-review/reviewable 7 files, 2 discussions left (glennw)
Details
Taskcluster (pull_request) TaskGroup: success
Details
continuous-integration/appveyor/pr AppVeyor build succeeded
Details
homu Test successful
Details
@glennw
Copy link
Member

glennw commented Apr 4, 2018

@staktrace Heads up for public API change. Passing None for the new parameter to push_stacking_context will retain current behaviour.

Gankra added a commit to Gankra/webrender that referenced this pull request Apr 11, 2018
servo#2600 made it possible to correctly express this. I had to make the test a bit fuzzy
since the reference uses floating point color, while the test uses integer color.
They're visually indistinguishable, though.
Gankra added a commit to Gankra/webrender that referenced this pull request Apr 11, 2018
This was made possible by servo#2600. I had to make the test a bit fuzzy
since the reference uses floating point color, while the test uses integer color.
They're visually indistinguishable, though.
bors-servo added a commit that referenced this pull request Apr 11, 2018
add reftest for mask clips on stacking contexts, closes #1957

This was made possible by #2600. I had to make the test a bit fuzzy
since the reference uses floating point color, while the test uses integer color.
They're visually indistinguishable, though.

<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/webrender/2646)
<!-- Reviewable:end -->
@mrobinson mrobinson deleted the mrobinson:explicit-stacking-context-clipping branch Apr 26, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked issues

Successfully merging this pull request may close these issues.

None yet

3 participants
You can’t perform that action at this time.