Join GitHub today
GitHub is home to over 50 million developers working together to host and review code, manage projects, and build software together.
Sign upMajor refactoring of how clips are processed down the pipeline #512
Conversation
|
Now that I think of it, this might be incorrect. I'm borrowing the |
|
I rewrote the code to solve the concern by cloning the aux lists into the |
|
At the moment, I try do avoid passing the auxiliary lists around to many APIs, and instead resolve them all at one part of the frame. This has the added advantage that we only resolve items from the auxiliary lists when they first come on screen, avoiding a large upfront cost for a new scene. Is it possible do just make clips work the same way as all the other primitives, or does something prevent that? |
|
|
|
Redesigned the whole thing after talking to @glennw . The auxiliary lists are no longer accessed at all during the primitive population, and are only passed down (by reference, no cloning) during the frame building. This is also an optimization, since we only resolve the aux lists for visible primitives now. |
| @@ -58,15 +58,38 @@ pub struct PrimitiveCacheInfo { | |||
| pub key: PrimitiveCacheKey, | |||
| } | |||
|
|
|||
| #[derive(Debug)] | |||
| pub enum PrimitiveClipInfo { | |||
This comment has been minimized.
This comment has been minimized.
glennw
Nov 3, 2016
Member
Is the idea here that it gets resolved from Complex / Region to GpuAddress? Would it make more sense to split into a "source" and "resolved" field perhaps?
This comment has been minimized.
This comment has been minimized.
kvark
Nov 3, 2016
Author
Member
Yes, that's the idea. The reason I decided not to have separate fields for source/resolved is because they are mutually exclusive (or at least, the source make no sense once the resolved is set), which is reflected here by the use of enum. I agree this is probably the most controversial aspect of this PR, just not seeing a better solution at the moment.
This comment has been minimized.
This comment has been minimized.
glennw
Nov 3, 2016
Member
OK, I think that's fine - we might like to make some of the conditions marked as unreachable!() or something like that (e.g. if the non-resolved type gets encountered after it should always have been resolved). But no need to do that now.
| } | ||
|
|
||
| impl PrimitiveClipInfo { | ||
| pub fn is_clipped(&self) -> bool { |
This comment has been minimized.
This comment has been minimized.
glennw
Nov 3, 2016
Member
Will this return true even for a rectangular clip only? (If so, that will prevent occlusion culling where it is being used).
This comment has been minimized.
This comment has been minimized.
kvark
Nov 3, 2016
Author
Member
You are right, this part doesn't seem right. If it's called after after the prepare_* body (and I think it does), the only variant here would be GpuAddress. Will be fixed in a minute.
| auxiliary_lists: &AuxiliaryLists) -> bool { | ||
| let metadata = &mut self.cpu_metadata[prim_index.0]; | ||
| debug_assert!(metadata.need_to_build_cache); | ||
| metadata.need_to_build_cache = false; | ||
|
|
||
| if let Some(mask_key) = metadata.mask_image { | ||
| let tex_cache = resource_cache.get_image(mask_key, ImageRendering::Auto, frame_id); | ||
| let clip_data_mask = match metadata.clip_info.as_ref() { |
This comment has been minimized.
This comment has been minimized.
glennw
Nov 3, 2016
Member
Does this mean that we'll end up with a complex clip region enabled when the clip region is a simple rect with zero radius? If so, that will introduce a lot more expensive clip shaders than needed.
This comment has been minimized.
This comment has been minimized.
kvark
Nov 3, 2016
Author
Member
I don't think we handled the zero radius anywhere except this piece:
if scrollbar_prim.border_radius == 0.0 {
- self.prim_store.set_complex_clip(scrollbar_prim.prim_index, None);
+ self.prim_store.unset_complex_clip(scrollbar_prim.prim_index)
} else {The general case of no ComplexClipRegion given is handled below, here:
let clip_data = match clips.len() {
0 if clip_region.image_mask.is_none() => None,So I don't think this PR changes the logic in a way that makes the shaders more expensive.
This comment has been minimized.
This comment has been minimized.
|
@kvark I ran the mozilla css tests subset with this patch - border_radius_clip_a.html fails but everything else passes. Could you take a look at that failure when you have time? |
|
@glennw I was also checking the tests, saw that one, and confirmed it happens without this PR equally. |
|
Generally looks good to me - this fits in quite well with the rest of the items that use ItemRange. Just need to get the test failures sorted and then this should be good to go. |
|
|
9a44521
to
c553d77
…eparation to multiple transformed clip support. Removed MaskImageSource, introduced PrimitiveClipSource to the metadata. Avoided cloning the auxiliary lists map.
|
@bors-servo r+ |
|
|
|
|
Major refactoring of how clips are processed down the pipeline This moves the clipping hack down the road (from `Frame` to `FrameBuilder`), allowing to eventually implement multiple transformed clips properly (#498), as discussed on IRC with @glennw . <!-- 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/512) <!-- Reviewable:end -->
|
Looks good, thanks! |
kvark commentedNov 1, 2016
•
edited by larsbergstrom
This moves the clipping hack down the road (from
FrametoFrameBuilder), allowing to eventually implement multiple transformed clips properly (#498), as discussed on IRC with @glennw .This change is