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

Optimize box shadows - only apply blurs where they can affect the shadow. #1896

Merged
merged 2 commits into from Oct 20, 2017

Conversation

@glennw
Copy link
Member

glennw commented Oct 19, 2017

Add support for regions to blur render tasks. These allow render tasks
to specify one or more regions where the blur should be applied. If
no blur region is supplied, the entire render task is blurred.

Also start expanding the Picture struct, with methods to prepare
it for rendering etc.

Finally, add the basic infrastructure for render tasks to specify
what color they should be cleared to. This allows tasks to specify
a non-default color, if required. This is useful for inset shadows
where we will avoid blurring the inside of the shadow rect.

For outset box shadows with a large blur radius and/or border radius
this patch makes them ~3-4x faster than previously. A follow up will
be to add the same blur regions for inset box shadows.


This change is Reviewable

…dow.

Add support for regions to blur render tasks. These allow render tasks
to specifiy one or more regions where the blur should be applied. If
no blur region is supplied, the entire render task is blurred.

Also start expanding the Picture struct, with methods to prepare
it for rendering etc.

Finally, add the basic infrastructure for render tasks to specify
what color they should be cleared to. This allows tasks to specify
a non-default color, if required. This is useful for inset shadows
where we will avoid blurring the inside of the shadow rect.

For outset box shadows with a large blur radius and/or border radius
this patch makes them ~3-4x faster than previously. A follow up will
be to add the same blur regions for inset box shadows.
@glennw
Copy link
Member Author

glennw commented Oct 19, 2017

r? @kvark

I still need to do a try run and WPT tests - but it should be OK to review this when you have time.

@kvark
Copy link
Member

kvark commented Oct 19, 2017

Reviewed 9 of 9 files at r1.
Review status: all files reviewed at latest revision, 8 unresolved discussions.


webrender/src/frame_builder.rs, line 581 at r1 (raw file):

        // Borrowcheck dance
        let mut shadows = mem::replace(&mut self.shadow_prim_stack, Vec::new());

I'm quite surprised to see this. If we just iterated on self.shadow_prim_stack.drain(..) it wouldn't prevent us to use the prim_store. Could this dance be a leftover from the previous code?


webrender/src/frame_builder.rs, line 590 at r1 (raw file):

                let metadata = &mut self.prim_store.cpu_metadata[prim_index.0];
                let prim = &self.prim_store.cpu_pictures[metadata.cpu_prim_index.0];
                let shadow = prim.as_text_shadow();

all shadows are considered to be text shadows now?


webrender/src/frame_builder.rs, line 1364 at r1 (raw file):

                    let pic_rect = shadow_rect.inflate(blur_offset, blur_offset);
                    let blur_range = 3.0 * blur_radius;

what is 3.0 here? would be nice to make it a constant with a comment on top


webrender/src/frame_builder.rs, line 1385 at r1 (raw file):

                    ) * 3.0;

                    blur_regions.push(LayerRect::from_floats(0.0, 0.0, tl.width, tl.height));

should we detect intersections here to avoid extra work on pixels covered by multiple regions?


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

        shadow: Shadow,
    },
    BoxShadow {

that's what I've been thinking of when reviewing the previous version of the PR, nice one!


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

            PrimitiveKind::Picture => {
                self.cpu_pictures[metadata.cpu_prim_index.0]
                    .prepare_for_render(

neat!


webrender/src/renderer.rs, line 2923 at r1 (raw file):

                let (rect, _) = task.get_target_rect();
                self.device
                    .clear_target_rect(Some(zero_color), None, rect);

so we clear on top of the previous clear here?


webrender/src/tiling.rs, line 1908 at r1 (raw file):

        } else {
            for region in &self.regions {
                instances.push(BlurInstance {

nit: could create a single BlurInstance before the branch, then doing BlurInstance { region, .. blur_instance } here


Comments from Reviewable

@kvark
Copy link
Member

kvark commented Oct 19, 2017

For outset box shadows with a large blur radius and/or border radius
this patch makes them ~3-4x faster than previously.

curious, what exactly made this case faster?


Review status: all files reviewed at latest revision, 8 unresolved discussions.


Comments from Reviewable

@glennw
Copy link
Member Author

glennw commented Oct 20, 2017

Review status: 7 of 9 files reviewed at latest revision, 8 unresolved discussions.


webrender/src/frame_builder.rs, line 581 at r1 (raw file):

Previously, kvark (Dzmitry Malyshau) wrote…

I'm quite surprised to see this. If we just iterated on self.shadow_prim_stack.drain(..) it wouldn't prevent us to use the prim_store. Could this dance be a leftover from the previous code?

It's the borrow on self for the call to add_primitive_to_draw_list() that is the problem. This could definitely be restructured and tidied up in the future though...


webrender/src/frame_builder.rs, line 590 at r1 (raw file):

Previously, kvark (Dzmitry Malyshau) wrote…

all shadows are considered to be text shadows now?

For now, yes. The box shadows don't currently make use of the offset field in Shadow. So to avoid confusion I'm not using the Shadow struct. We might end up changing how this works in the future though.


webrender/src/frame_builder.rs, line 1364 at r1 (raw file):

Previously, kvark (Dzmitry Malyshau) wrote…

what is 3.0 here? would be nice to make it a constant with a comment on top

Done.


webrender/src/renderer.rs, line 2923 at r1 (raw file):

Previously, kvark (Dzmitry Malyshau) wrote…

so we clear on top of the previous clear here?

Yea. We might like to do something smarter here in the future.


webrender/src/tiling.rs, line 1908 at r1 (raw file):

Previously, kvark (Dzmitry Malyshau) wrote…

nit: could create a single BlurInstance before the branch, then doing BlurInstance { region, .. blur_instance } here

Done.


Comments from Reviewable

@glennw
Copy link
Member Author

glennw commented Oct 20, 2017

@kvark The speed win comes because we only run the blur shader along the edges and corners of the mask rect. This won't be important once we have proper segmenting of the box shadows into a 9-patch (or even just a single corner in the case of uniform border radii), but it's a good win in the interim.

I think the review comments are all addressed now.

WPT tests on Servo are good and Gecko try run looks green:

https://hg.mozilla.org/try/rev/d23b7c67075bf7d553dbad12fd0b7390f4bfcc77
https://treeherder.mozilla.org/#/jobs?repo=try&revision=d23b7c67075bf7d553dbad12fd0b7390f4bfcc77

@glennw glennw removed the status: blocked label Oct 20, 2017
@kvark
Copy link
Member

kvark commented Oct 20, 2017

Reviewed 2 of 2 files at r2.
Review status: all files reviewed at latest revision, 3 unresolved discussions.


Comments from Reviewable

@kvark
Copy link
Member

kvark commented Oct 20, 2017

thank you!
@bors-servo r+

@bors-servo
Copy link
Contributor

bors-servo commented Oct 20, 2017

📌 Commit 764178a has been approved by kvark

@bors-servo
Copy link
Contributor

bors-servo commented Oct 20, 2017

Testing commit 764178a with merge 9e1180d...

bors-servo added a commit that referenced this pull request Oct 20, 2017
Optimize box shadows - only apply blurs where they can affect the shadow.

Add support for regions to blur render tasks. These allow render tasks
to specify one or more regions where the blur should be applied. If
no blur region is supplied, the entire render task is blurred.

Also start expanding the Picture struct, with methods to prepare
it for rendering etc.

Finally, add the basic infrastructure for render tasks to specify
what color they should be cleared to. This allows tasks to specify
a non-default color, if required. This is useful for inset shadows
where we will avoid blurring the inside of the shadow rect.

For outset box shadows with a large blur radius and/or border radius
this patch makes them ~3-4x faster than previously. A follow up will
be to add the same blur regions for inset box shadows.

<!-- 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/1896)
<!-- Reviewable:end -->
@bors-servo
Copy link
Contributor

bors-servo commented Oct 20, 2017

☀️ Test successful - status-appveyor, status-travis
Approved by: kvark
Pushing 9e1180d to master...

@bors-servo bors-servo merged commit 764178a into servo:master Oct 20, 2017
4 of 5 checks passed
4 of 5 checks passed
code-review/reviewable 3 discussions left (glennw, kvark)
Details
Taskcluster (pull_request) TaskGroup: success
Details
continuous-integration/appveyor/pr AppVeyor build succeeded
Details
continuous-integration/travis-ci/pr The Travis CI build passed
Details
homu Test successful
Details
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

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