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 upSupport arbitrary rasterization coordinate roots. #3030
Conversation
|
r? @kvark This needs some more code documentation - but I thought I'd open the PR now anyway, and work on the remaining bits tomorrow. This fixes a lot of real world pages that have 3d transforms on them. Try run: There are 2 FAILs in R6 that I need to look into, and 1 new PASS in Wr1. (I'll do a full try run on all platforms once I resolve those 2 FAILs tomorrow). |
|
(includes the fix in #3029) |
|
My overall impression is a bit of worry about complexity. We are getting another space (yes, I asked for this back in the day, nobody else to blame here :) ) and an extra indirection to think about (primitive -> surface/picture -> raster -> world) instead of (primitive -> picture -> world). The mutability of transform palette passed around in a lot of places is not making the code simpler either.
I'm trying to understand why exactly this change fixes a large number of real world pages. I thought that the previous approach, conceptually, would only have troubles on supporting 3D -> 2D -> 3D nested chains. Are those used often in practice? If you are thinking of a wider (and simpler) set of cases, do you know why the PR makes them better, i.e. what was wrong with the previous approach?
webrender/res/brush_blend.glsl, line 37 at r1 (raw file):
where did the snapping go? webrender/res/brush_blend.glsl, line 42 at r1 (raw file):
we are missing the webrender/res/brush_image.glsl, line 156 at r1 (raw file):
why is non-perspective interpolation removed for brushes? webrender/res/clip_shared.glsl, line 82 at r1 (raw file):
could you clarify this part? We are snapping based on clip transform but then applying the primitive transform. Will it end up badly snapped in some cases then? webrender/res/clip_shared.glsl, line 83 at r1 (raw file):
we can't do this, unless you know that W is always positive webrender/res/cs_clip_box_shadow.glsl, line 63 at r1 (raw file):
I know this is copied from the old code, but do we have a guarantee that Z is positive here? webrender/res/ps_split_composite.glsl, line 78 at r1 (raw file):
we need to multiply the offset by webrender/res/ps_split_composite.glsl, line 82 at r1 (raw file):
what's the guarantee that we aren't going to be rendering outside of the task bounds? webrender/res/ps_split_composite.glsl, line 99 at r1 (raw file):
can we use webrender/src/batch.rs, line 9 at r1 (raw file):
I find it a bit worrying that batching now depends on CST webrender/src/batch.rs, line 1723 at r1 (raw file):
why do we need to mutate it here? webrender/src/gpu_types.rs, line 432 at r1 (raw file):
reads a bit weird that it's called webrender/src/gpu_types.rs, line 465 at r1 (raw file):
now I see why the mutable state is needed webrender/src/gpu_types.rs, line 599 at r1 (raw file):
we can webrender/src/picture.rs, line 42 at r1 (raw file):
nit: not clear if webrender/src/picture.rs, line 240 at r1 (raw file):
uh, I'm getting a little lost here. If this primitive spawns a surface, wouldn't the rasterized space match the surface space? webrender/src/picture.rs, line 268 at r1 (raw file):
of all the spatial node indices in scope, why do we choose webrender/src/picture.rs, line 419 at r1 (raw file):
there is quite a bit of common code between this and webrender/src/prim_store.rs, line 2909 at r1 (raw file):
this function gives us a great opportunity to abuse let unclipped_raster_rect = map_to_raster(&pic_rect)?;webrender/src/prim_store.rs, line 2942 at r1 (raw file):
In at least 2 cases the caller only cares about the first result. Can/should we avoid the extra computation in this case? webrender/src/renderer.rs, line 446 at r1 (raw file):
it is rather tempting to reduce the number of attributes by having webrender/src/util.rs, line 68 at r1 (raw file):
what if webrender_api/src/units.rs, line 55 at r1 (raw file):
need to document what this space is about |
|
Note that this will possibly be needed to optimize blur as well, because right now there's no way to render contents at a lower resolution without introducing more transforms, which necessitate stacking contexts and reference frames. |
|
Current try: Down to one failure - working through that now, then will follow up on and address review comments :) |
|
I confirm (by downloading the last try artifact) that the PR fixes https://bugzilla.mozilla.org/show_bug.cgi?id=1487570 |
webrender/res/brush_blend.glsl, line 37 at r1 (raw file): Previously, kvark (Dzmitry Malyshau) wrote…
This was needed when we were deriving the screen UV from the render task device rect. However, we now use the UVs provided by calculate_uv_rect_kind(), which handles the snapping when calculating the UVs. webrender/res/brush_blend.glsl, line 42 at r1 (raw file): Previously, kvark (Dzmitry Malyshau) wrote…
Yes - any pictures that have perspective now form a rasterization root in their local space, so we don't need to apply perspective correction when compositing them. webrender/res/brush_image.glsl, line 156 at r1 (raw file): Previously, kvark (Dzmitry Malyshau) wrote…
Same as above - we only ever composite with source images that were not drawn with perspective now. webrender/res/clip_shared.glsl, line 82 at r1 (raw file): Previously, kvark (Dzmitry Malyshau) wrote…
I think this is wrong, yes - I have left it as is, since it's the same behavior as current (previous code only looked at the clip transform here). But it does seem potentially incorrect to me too, and should be considered as a follow up. webrender/res/clip_shared.glsl, line 83 at r1 (raw file): Previously, kvark (Dzmitry Malyshau) wrote…
I think this is (somewhat) related to the last failure I have in try run - working on a solution to that now. webrender/res/cs_clip_box_shadow.glsl, line 63 at r1 (raw file): Previously, kvark (Dzmitry Malyshau) wrote…
I'm not totally sure - this might be related to the current reftest failure on try. webrender/res/ps_split_composite.glsl, line 78 at r1 (raw file): Previously, kvark (Dzmitry Malyshau) wrote…
dest_origin is already in device pixels. I ran into this because I found the existing code was failing on my hi-dpi screen - this is the fix for that. webrender/res/ps_split_composite.glsl, line 82 at r1 (raw file): Previously, kvark (Dzmitry Malyshau) wrote…
In theory the clip mask generated on the surface handles this, but I want to do some more testing - this might actually be the issue with the failing reftest too. webrender/res/ps_split_composite.glsl, line 99 at r1 (raw file): Previously, kvark (Dzmitry Malyshau) wrote…
Yes, and your comment helped me notice I had the parameter order here wrong (compared to the bilerp above) - fixing this actually fixes most of the last failing reftest I have! webrender/src/batch.rs, line 9 at r1 (raw file): Previously, kvark (Dzmitry Malyshau) wrote…
Yea - it's because of the way we generate relative transforms in the transform palette on demand. A tidier solution, as a follow up, is that the culling and clipping generation code should pre-register all the needed relative transforms. Then they will exist in the transform palette. webrender/src/batch.rs, line 1723 at r1 (raw file): Previously, kvark (Dzmitry Malyshau) wrote…
See above comment about CST - we can fix this as a follow up. webrender/src/gpu_types.rs, line 432 at r1 (raw file): Previously, kvark (Dzmitry Malyshau) wrote…
True, fixed. webrender/src/gpu_types.rs, line 465 at r1 (raw file): Previously, kvark (Dzmitry Malyshau) wrote…
Yea - it's a bit of a hack to get this landed. We can pre-register them in the future as described above. webrender/src/gpu_types.rs, line 599 at r1 (raw file): Previously, kvark (Dzmitry Malyshau) wrote…
Fixed webrender/src/picture.rs, line 42 at r1 (raw file): Previously, kvark (Dzmitry Malyshau) wrote…
Added a comment to clarify. webrender/src/picture.rs, line 240 at r1 (raw file): Previously, kvark (Dzmitry Malyshau) wrote…
Not always - for example, if you have a rotated picture on the main frame, the surface space comes from the picture, but the raster space could be the surface space (if drawing in local space for caching / performance) or the root world space (if drawing in screen space for quality). webrender/src/picture.rs, line 268 at r1 (raw file): Previously, kvark (Dzmitry Malyshau) wrote…
We know that node index 0 is world space - I changed these references to use ROOT_SPATIAL_NODE_INDEX for clarity. webrender/src/picture.rs, line 419 at r1 (raw file): Previously, kvark (Dzmitry Malyshau) wrote…
Agreed, I'll tidy this up a bit. webrender/src/prim_store.rs, line 2909 at r1 (raw file): Previously, kvark (Dzmitry Malyshau) wrote…
Agreed, I'll tidy this up a bit. webrender/src/prim_store.rs, line 2942 at r1 (raw file): Previously, kvark (Dzmitry Malyshau) wrote…
It's not called that often, but I will tidy it up to avoid the extra work in those cases since it's the more common case. webrender/src/renderer.rs, line 446 at r1 (raw file): Previously, kvark (Dzmitry Malyshau) wrote…
Yep, this could definitely be tidied up in a follow up. webrender/src/util.rs, line 68 at r1 (raw file): Previously, kvark (Dzmitry Malyshau) wrote…
That still works? All we're trying to do here is see if it's 1 or very close to 1? webrender_api/src/units.rs, line 55 at r1 (raw file): Previously, kvark (Dzmitry Malyshau) wrote…
Done. |
|
Addressed most of those review comments. Still working on one reftest failure, and then a couple of tidy up comments from above still need to be addressed. |
webrender/res/brush_image.glsl, line 156 at r1 (raw file): Previously, gw3583 (Glenn Watson) wrote…
Hold on. Brush image is our general hammer of drawing image-ish nails, not just compositing. If there is a transformed stacking context with an image in it, we'll still need to draw the brush_image primitive (generated by this image) begin transformed. What am I missing? webrender/res/clip_shared.glsl, line 82 at r1 (raw file): Previously, gw3583 (Glenn Watson) wrote…
please add a TODO comment since we are at it webrender/res/ps_split_composite.glsl, line 78 at r1 (raw file): Previously, gw3583 (Glenn Watson) wrote…
It's in device pixels, but it's not in the homogeneous space, so it will end up divided by webrender/res/ps_split_composite.glsl, line 99 at r1 (raw file): Previously, gw3583 (Glenn Watson) wrote…
yay! glad to help :D webrender/src/picture.rs, line 240 at r1 (raw file): Previously, gw3583 (Glenn Watson) wrote…
Thank you for clarification! So a picture may need to spawn a surface. And then a surface may need to spawn a raster space (if it has perspective component). Correct? webrender/src/picture.rs, line 419 at r1 (raw file): Previously, gw3583 (Glenn Watson) wrote…
this is still TODO, right? webrender/src/util.rs, line 68 at r1 (raw file):
That's what we should be doing, but that's not what the code does :) webrender_api/src/units.rs, line 55 at r1 (raw file): Previously, gw3583 (Glenn Watson) wrote…
I think "screen space" should be replaced by "world space" here to match our strongly typed spaces. |
|
OK, I have a fix for the remaining reftest failure - the fix also resolves the concerns above about clipping outside the boundaries of a plane splitting polygon. I'll tidy up the patch on Monday (the implementation is a bit of a hack, but the result is correct) and post it here. |
This allows us to choose to rasterize any picture in an arbitrary coordinate space. This fixes a large number of real world pages that use 3d transforms. It also simplifies fixing any remaining 3d transform related issues. The initial patch uses this to promote any picture that has perspective into a rasterization root. There are a number of benefits to this: * It simplifies a lot of the math involving plane splitting, since we don't need to deal with splits drawn in screen-space. * It makes caching perspective rendered pictures much easier, since we can cache them between frames even when the root coordinate system is animating the picture (this isn't implemented yet, but is a simple-ish follow up). We can make use of this to render text shadows in local space, as a performance optimization (which can then be cached between frames and display lists). Part of this change involves simplifying the plane splitting code to work in a similar way to traditional brush images. It's likely that in the future we can completely remove ps_split_composite and draw plane splits with brush_image for better batching. Introducing a new coordinate space allows for some more optimal calculations of required raster rectangles, which reduces the number of pixels that we draw for clip masks and transformed pictures, in some cases. Follow ups: * Support arbitrary rasterization scales for raster roots, for better quality / performance. * Support caching of pictures as discussed above.
webrender/res/brush_image.glsl, line 156 at r1 (raw file): Previously, kvark (Dzmitry Malyshau) wrote…
The transform is still applied, but we don't need to specifically correct for perspective interpolation, since the source images from render tasks are no longer drawn with a perspective component. So it's just like drawing a normal image source in perspective. webrender/res/clip_shared.glsl, line 82 at r1 (raw file): Previously, kvark (Dzmitry Malyshau) wrote…
Added a comment. webrender/res/ps_split_composite.glsl, line 78 at r1 (raw file): Previously, kvark (Dzmitry Malyshau) wrote…
Ah, indeed. Fixed! webrender/res/ps_split_composite.glsl, line 99 at r1 (raw file): Previously, kvark (Dzmitry Malyshau) wrote…
Done. webrender/src/picture.rs, line 240 at r1 (raw file): Previously, kvark (Dzmitry Malyshau) wrote…
Yep, exactly :) webrender/src/picture.rs, line 419 at r1 (raw file): Previously, kvark (Dzmitry Malyshau) wrote…
Yep, fixed in the most recent commit. webrender/src/util.rs, line 68 at r1 (raw file): Previously, kvark (Dzmitry Malyshau) wrote…
Ooops! Fixed. webrender_api/src/units.rs, line 55 at r1 (raw file): Previously, kvark (Dzmitry Malyshau) wrote…
Agreed, fixed. |
|
I addressed the remaining review comments, and rebased. I also added a (hopefully) final commit that resolves the remaining reftest failure and comments about clipping on split composite primitives. It's basically a hack / workaround for legacy API issues with the clipping APIs. However, I think it's a reasonable implementation detail for now, that we can tidy up at a later point. Commit note here for details:
I'll kick off an updated try run shortly. Hopefully after that and review of the last two commits, this should be ready to go. Although not ideal, it fixes a heap of existing 3d transform bugs we have. |
|
Try run looks good so far (still in progress): https://treeherder.mozilla.org/#/jobs?repo=try&revision=3e29fc7c6924f333afd5418aed4854ac32255937 1 new PASS in Wr1. Bugzilla bugs that are affected by this change: FIXED: IMPROVED: |
|
Try run looks good. The same new PASS results on Windows, plus a couple unrelated intermittents. re-r? @kvark |
|
I got just a few concerns left. Code is looking great for the most part
webrender/res/clip_shared.glsl, line 83 at r1 (raw file): Previously, gw3583 (Glenn Watson) wrote…
This concern doesn't appear addressed? webrender/src/clip.rs, line 472 at r4 (raw file):
"Check if any this clip node" - something is missing here :) webrender/src/clip.rs, line 1120 at r4 (raw file):
It seems like this would be cleaner if instead of webrender/src/clip.rs, line 1140 at r4 (raw file):
shouldn't this be |
webrender/res/clip_shared.glsl, line 83 at r1 (raw file): Previously, kvark (Dzmitry Malyshau) wrote…
It's addressed by the clip node collector change - we don't rasterize clips across perspective roots now. In fact this means we should be able to simplify this code significantly, but I left this as a follow up, since I want to get this stuff into gecko asap. webrender/src/clip.rs, line 472 at r4 (raw file): Previously, kvark (Dzmitry Malyshau) wrote…
Done. webrender/src/clip.rs, line 1120 at r4 (raw file): Previously, kvark (Dzmitry Malyshau) wrote…
The problem with that is that we also need to signal if the clip completely culled the primitive - I guess we could have Result<Option, ()> or something like that as a follow up? webrender/src/clip.rs, line 1140 at r4 (raw file): Previously, kvark (Dzmitry Malyshau) wrote…
In this case (the complex clip spanning a complex transform), we map both the prim and clip to world space in order to do our trivial clip accept / reject / partial tests. So this transform is used to get the clip inner / outer rects in world space. |
|
@kvark Thanks! Responded to those comments / quesions and pushed an updated commit. |
webrender/res/cs_clip_box_shadow.glsl, line 63 at r1 (raw file): Previously, gw3583 (Glenn Watson) wrote…
Does it mean we are still blocked? |
|
@bors-servo r+ |
|
|
|
@bors-servo r=kvark |
The split composite shader is now quite similar to a normal brush shader (uses prim header, supports normal clip masks etc). The only real difference is that it draws a quad polygon from local points instead of a rectangle. It should be easy to unify this into the brush_image shader in the future. Add a temporary "ClipNodeCollector" interface to correctly handle clips that are ancestors of the current rasterization root. Although it's not enforced by the API, I have verified that any time a clip from a spatial node that is an ancestor of the current rasterization root is applied on all primitives that are part of that picture. This means we can safely apply those clips during compositing of the rasterization root rather than on each individual primitive. This fixes correctness issues with clips across rasterization roots, and is also a quite significant performance win in some cases, since the clip mask is now applied once when the rasterization root is drawn, rather than on each indidvidual primitive. The end result of this is actually quite good - it will allow us to simplify some of the clipping code in the future, and is a performance win. The implementation leaves a lot to be desired, but gets the required result without having to fix up both gecko and wr clipping API mismatches. The long term solution for this is to update gecko and WR to make better use of clip chains on stacking contexts, rather than putting clips from the stacking context on each individual primitive (we have discussed doing this previously, but it's low-ish priority for now given other bugs).
|
@bors-servo r=kvark |
|
Just pushed an amended commit to try and get bors to respond, but no luck so far |
|
@bors-servo r=kvark |
|
|
Support arbitrary rasterization coordinate roots. This allows us to choose to rasterize any picture in an arbitrary coordinate space. This fixes a large number of real world pages that use 3d transforms. It also simplifies fixing any remaining 3d transform related issues. The initial patch uses this to promote any picture that has perspective into a rasterization root. There are a number of benefits to this: * It simplifies a lot of the math involving plane splitting, since we don't need to deal with splits drawn in screen-space. * It makes caching perspective rendered pictures much easier, since we can cache them between frames even when the root coordinate system is animating the picture (this isn't implemented yet, but is a simple-ish follow up). We can make use of this to render text shadows in local space, as a performance optimization (which can then be cached between frames and display lists). Part of this change involves simplifying the plane splitting code to work in a similar way to traditional brush images. It's likely that in the future we can completely remove ps_split_composite and draw plane splits with brush_image for better batching. Introducing a new coordinate space allows for some more optimal calculations of required raster rectangles, which reduces the number of pixels that we draw for clip masks and transformed pictures, in some cases. Follow ups: * Support arbitrary rasterization scales for raster roots, for better quality / performance. * Support caching of pictures as discussed above. <!-- 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/3030) <!-- Reviewable:end -->
|
@bors-servo retry |
Support arbitrary rasterization coordinate roots. This allows us to choose to rasterize any picture in an arbitrary coordinate space. This fixes a large number of real world pages that use 3d transforms. It also simplifies fixing any remaining 3d transform related issues. The initial patch uses this to promote any picture that has perspective into a rasterization root. There are a number of benefits to this: * It simplifies a lot of the math involving plane splitting, since we don't need to deal with splits drawn in screen-space. * It makes caching perspective rendered pictures much easier, since we can cache them between frames even when the root coordinate system is animating the picture (this isn't implemented yet, but is a simple-ish follow up). We can make use of this to render text shadows in local space, as a performance optimization (which can then be cached between frames and display lists). Part of this change involves simplifying the plane splitting code to work in a similar way to traditional brush images. It's likely that in the future we can completely remove ps_split_composite and draw plane splits with brush_image for better batching. Introducing a new coordinate space allows for some more optimal calculations of required raster rectangles, which reduces the number of pixels that we draw for clip masks and transformed pictures, in some cases. Follow ups: * Support arbitrary rasterization scales for raster roots, for better quality / performance. * Support caching of pictures as discussed above. <!-- 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/3030) <!-- Reviewable:end -->
|
|
gw3583 commentedSep 6, 2018
•
edited by larsbergstrom
This allows us to choose to rasterize any picture in an
arbitrary coordinate space.
This fixes a large number of real world pages that use 3d
transforms. It also simplifies fixing any remaining 3d
transform related issues.
The initial patch uses this to promote any picture that has
perspective into a rasterization root.
There are a number of benefits to this:
since we don't need to deal with splits drawn in screen-space.
since we can cache them between frames even when the
root coordinate system is animating the picture (this isn't
implemented yet, but is a simple-ish follow up).
We can make use of this to render text shadows in local space,
as a performance optimization (which can then be cached between
frames and display lists).
Part of this change involves simplifying the plane splitting
code to work in a similar way to traditional brush images. It's
likely that in the future we can completely remove ps_split_composite
and draw plane splits with brush_image for better batching.
Introducing a new coordinate space allows for some more optimal
calculations of required raster rectangles, which reduces the
number of pixels that we draw for clip masks and transformed
pictures, in some cases.
Follow ups:
better quality / performance.
This change is