Skip to content

Use segments when drawing clip masks, decouple from tiles. #696

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

Merged
merged 1 commit into from
Jan 10, 2017

Conversation

glennw
Copy link
Member

@glennw glennw commented Jan 10, 2017

This change is Reviewable

@glennw
Copy link
Member Author

glennw commented Jan 10, 2017

@kvark This implements the clip mask changes we discussed earlier. Instead of applying the more general optimization, it just handles the common case of a single complex rect, and draws the corners only in this case. But this PR is easily extendable to the general case, either as a follow up or before merging.

This code passes the tests, and is fast, but I'm not super happy with it. Subjectively, it feels much more complicated than the other method to me. It is also less efficient in the common case, since the rectangle clip shader has to evaluate all four clip corners, whereas with the other method it only handles one clip corner at a time.

But anyway, I'm interested to hear your thoughts, and specifically (a) if you agree that this code solution is more complicated than the other option and (b) if you can think of a nicer / cleaner way to implement this functionality.

@glennw
Copy link
Member Author

glennw commented Jan 10, 2017

@kvark Hmmm, it probably has to be this way actually, since I think the other method can suffer from double AA issues at the edges of clip corners. Need to think about that a bit more, but it may rule out the other method anyway.

@kvark
Copy link
Member

kvark commented Jan 10, 2017

I'm not completely following you on AA issues, but you are making a good point for me on this part. If we are talking about MSAA, then in your approach we'd only need to super-sample the corner draws, while the main draw call of the primitive would use regular multi-sample. That is going to be much faster than my approach, which would need to super-sample the whole mask. This concern only applies to MSAA though, which I'm not sure is what you were referring to.

Copy link
Member

@kvark kvark left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@glennw thanks for putting this together!

(a) if you agree that this code solution is more complicated than the other option

I don't see where this would be more complicated than the other option, because at the current state it hasn't even diverged from that other option. The approaches work differently for complex and/or transformed masks, while this case you optimized here should be treated equally well by both.

(note: I don't assume you mean #695 here since it is incomplete and cuts down more stuff than we can afford)

(b) if you can think of a nicer / cleaner way to implement this functionality.

I think we'd need to dig deeper before looking for a way to refactor it. So far it looks fine, but the complexity is expected to come from us actually stopping allocating that inner rectangle.

P.S.: the "request changes" status here is not for actual changes as it is to get some answers

let mut geometry_kind = MaskGeometryKind::Default;

if inner_rect.is_some() && clips.len() == 1 {
let &(ref sc_index, ref clip_info) = clips.first().unwrap();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: clips[0] would do

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

match mask_opt {
MaskResult::Outside => {
// Primitive is completely clipped out.
prim_metadata.clip_task = None;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

doesn't this mean that there is no clipping for this primitive?
where do you actually cull this primitive?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

}
}
}
&PrimitiveRunCmd::PopStackingContext => {
let sc_index = *layer_stack.last().unwrap();
let layer = &mut self.layer_store[sc_index.0];
if layer.is_visible() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the push stuff is using a different check - can_contribute_to_scene(), so there might be a bug here

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

@@ -129,17 +129,16 @@ impl ComplexClipRegion {
}

//TODO: move to `util` module?
/// Return a maximum aligned rectangle that is fully inside the clip region.
/// Return an aligned rectangle that is fully inside the clip region.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why is k removed from here?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I use the inner rect to generate the vertices for the corners in the vertex shader - so it needs to extend to the radius for this technique. I think that is fine now, for the way inner_rect is now used. But perhaps in the future we could add a mode to get_inner_rect to optionally get the maximal inner rect, if that's useful elsewhere?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense, yeah. I was just shocked by the removal of my carefully computed mathematical constant that was supposed to optimize everything :)

@glennw glennw force-pushed the remove-clip-tiles2 branch from e4e17a3 to 422862a Compare January 10, 2017 20:46
@glennw
Copy link
Member Author

glennw commented Jan 10, 2017

@kvark OK, comments addressed and [wip] removed. Thanks!

@glennw glennw changed the title [wip] Use segments when drawing clip masks, decouple from tiles. Use segments when drawing clip masks, decouple from tiles. Jan 10, 2017
@kvark
Copy link
Member

kvark commented Jan 10, 2017

Thanks @glennw , :shipit: :)
@bors-servo r+

@bors-servo
Copy link
Contributor

📌 Commit 422862a has been approved by kvark

@bors-servo
Copy link
Contributor

⚡ Test exempted - status

@bors-servo bors-servo merged commit 422862a into servo:master Jan 10, 2017
bors-servo pushed a commit that referenced this pull request Jan 10, 2017
Use segments when drawing clip masks, decouple from tiles.

<!-- 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/696)
<!-- Reviewable:end -->
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants