Page MenuHomePhabricator

Bug 1178765 - Part 2: Implement backdrop-filter in WebRender r?gw
ClosedPublic

Authored by cbrewster on Jul 23 2019, 9:01 PM.

Diff Detail

Repository
rMOZILLACENTRAL mozilla-central
Lint
Automatic diff as part of commit; lint not applicable.
Unit
Automatic diff as part of commit; unit tests not applicable.

Event Timeline

cbrewster created this revision.Jul 23 2019, 9:01 PM
Herald added a project: Restricted Project. · View Herald TranscriptJul 23 2019, 9:01 PM
phab-bot requested review of this revision.Jul 23 2019, 9:01 PM
phab-bot changed the visibility from "Custom Policy" to "Public (No Login Required)".
phab-bot changed the edit policy from "Custom Policy" to "Restricted Project (Project)".
phab-bot removed a project: Restricted Project.

Revision updated.

cbrewster retitled this revision from Bug 1178765: Part 2 - Implement backdrop-filter in WebRender to Bug 1178765: Part 2 - Implement backdrop-filter in WebRender r?gw.Jul 25 2019, 10:06 PM
cbrewster edited the summary of this revision. (Show Details)

Revision updated.

Revision updated.

cbrewster added inline comments.Jul 25 2019, 10:36 PM
gfx/wr/wrench/reftests/filters/backdrop-filter-perspective.yaml
20

Unfortunately, the current implementation requires explicitly creating and assigning a new clip for clipping to work properly. This is because we are rendering the filtered backdrop in the backdrop space, but we want to apply a clip that exists in some other space (in this case a new space with a perspective transform).

Revision updated.

Revision updated.

gw added inline comments.Jul 28 2019, 8:17 PM
gfx/wr/webrender/src/clip_scroll_tree.rs
256 ↗(On Diff #138128)

I don't think this is feasible as a general implementation between any two spatial nodes (even if connected). I think it can only be done between surfaces, since we know that at that point the transform hierarchy will be flattened (projected) at those points. Otherwise it's possible to get into situations where we have a series of intermediate transforms without a surface, and projecting them gives incorrect results.

gfx/wr/webrender/src/display_list_flattener.rs
6–7

I haven't reviewed most of this file yet - will come back to it once we discuss some of the other comments and I have a better understanding of the patch details :)

gfx/wr/webrender/src/picture.rs
2236

Let's add some comments on when / why this would be used.

gfx/wr/webrender/src/prim_store/backdrop.rs
18

Probably just lack of understanding the spec / details, but it's not really clear to me why backdrop is a primitive, rather than a property on a stacking context? It seems like that might simplify parts of the implementation / fit in better conceptually, although it's probably just me not understanding the details of the patch yet.

gfx/wr/webrender/src/render_task.rs
334–347

Why is this and what implications does it have for existing code?

cbrewster added inline comments.Jul 29 2019, 12:11 AM
gfx/wr/webrender/src/clip_scroll_tree.rs
256 ↗(On Diff #138128)

Ah good point, I don't think I am actually using this function anymore. I was using this to project the bounding rect of the element with backdrop-filter onto the backdrop; however, I was getting incorrect results, probably due to what you are mentioning here.

I replaced this by using SpaceMapper to project the rect from the backdrop-filter element space to the root space and then from the root space to the backdrop space. Although, projecting between surfaces seems like a more sound approach.

gfx/wr/webrender/src/prim_store/backdrop.rs
18

I think it would be okay to move it to the stacking context in the public API, but internally it seemed simpler to use a primitive. It seems like a common use-case to apply backdrop-filter to an element which has a size but no content. For this, we would need to add a bit of extra logic to the visibility update pass to ensure a picture isn't culled from the scene due to having no child primitives. Primitives also handle a lot of the clipping logic, which would need to be duplicated for clipping the filtered backdrop.

I am open to moving this to the stacking context but it comes with a different set of tradeoffs (maybe better tradeoffs? I'm not sure yet).

gfx/wr/webrender/src/render_task.rs
334–347

Pictures track their render task by keeping the render task ID in its surface's RenderTasks. Currently I don't think we have any cases where the result of a picture task is used multiple times. With this patch we want to use the result twice: once to render the backdrop and a second time to render the filtered backdrop.

If we do end up blitting a dependency, we update the render tasks's dependency to reflect the new id of the blit task, but this does not update the render task ID in a picture's surface. It could be that the solution is to check if the parent task is a picture task and swap out the render task ID on the surface, but I'm not sure of the implications of that, so I added this as a temporary workaround.

cbrewster updated this revision to Diff 138707.Jul 29 2019, 6:02 PM

Revision updated.

cbrewster updated this revision to Diff 138733.Jul 29 2019, 6:17 PM

Revision updated.

cbrewster updated this revision to Diff 140760.Aug 1 2019, 4:38 PM

Revision updated.

gw added a comment.Aug 5 2019, 1:28 AM

I've had a bit of a look through this now, the code changes mostly look good! Having had a read of the spec, it seems possible that we might be able to implement this as a readback style primitive, which might simplify some of the flattening code and/or the API. It's quite likely that I just don't understand the subtleties of the spec + patch - but if we discuss that first, it should help my understanding of the problem space a bit better.

Some other bits and pieces we can use to start discussion tomorrow:

  • What the public API looks like. I _think_ you're probably right to have the internal implementation as a primitive now. But we should go into this in detail, and discuss what the public API should look like.
  • Why we need the filter clip id / bounds, and whether we can improve on that (I guess this is very related to the public API point above).
  • How a 'backdrop root' in the spec relates to the WR-internal concept of when to generate a surface, and whether we can take advantage of this at all to simplify the implementation.

Overall, nice work so far!

gfx/wr/wrench/reftests/filters/backdrop-filter-perspective.yaml
15

Is this still used? I thought we made the capture implicit?

cbrewster updated this revision to Diff 142143.Aug 5 2019, 1:34 AM

Revision updated.

cbrewster marked an inline comment as done.Aug 5 2019, 1:35 AM
cbrewster added inline comments.
gfx/wr/wrench/reftests/filters/backdrop-filter-perspective.yaml
15

Looks like I forgot to remove hits. The capture is implicit now.

cbrewster updated this revision to Diff 142454.Aug 5 2019, 6:11 PM
cbrewster marked an inline comment as done.

Revision updated.

cbrewster updated this revision to Diff 143943.Aug 7 2019, 8:58 PM

Revision updated.

cbrewster updated this revision to Diff 145238.Aug 9 2019, 6:53 PM

Revision updated.

gw accepted this revision.Aug 12 2019, 12:34 AM
gw added inline comments.
gfx/wr/webrender/src/render_task.rs
334–347

Can we add the comment above (or similar) to the source code to describe what's happening here?

This revision is now accepted and ready to land.Aug 12 2019, 12:34 AM
cbrewster updated this revision to Diff 146112.Aug 12 2019, 8:13 PM

Revision updated.

cbrewster retitled this revision from Bug 1178765: Part 2 - Implement backdrop-filter in WebRender r?gw to Bug 1178765 - Part 2: Implement backdrop-filter in WebRender r?gw.Aug 12 2019, 8:13 PM

Revision updated.