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

[css-contain][filter-effects] paint containment vs filter effects #6325

Closed
frivoal opened this issue May 31, 2021 · 7 comments
Closed

[css-contain][filter-effects] paint containment vs filter effects #6325

frivoal opened this issue May 31, 2021 · 7 comments

Comments

@frivoal
Copy link
Collaborator

frivoal commented May 31, 2021

The intent of paint containment is (among other things) that:

If the containment box is off-screen or obscured, the UA can directly skip trying to paint its contents, as they’re guaranteed to be off-screen/obscured as well.

That doesn't seem to account for filter effects. If you put a blur filter (for example) on an ancestor of an element of paint containment, it can spread the pixels of the contained element beyond the geometry of that element, with no particular boundary. So the contained element may be off-screen, but you still need to repaint it so that the on-screen pixels of the parent with a filter an be rendered correctly.

Is this OK because filters are a composite-time operation rather than paint-time operation, or something like that?

Is this bad and we somehow forgot to take it into account?

@frivoal frivoal changed the title paint containment vs filter effects [css-contain][filter-effects] paint containment vs filter effects May 31, 2021
@chrishtr
Copy link
Contributor

chrishtr commented Jun 2, 2021

Paint containment is only for the contents, not the element itself. Filters from content will be clipped. So I think it's WAI.

@frivoal
Copy link
Collaborator Author

frivoal commented Jun 3, 2021

Filters from the content will be clipped, but filters from parents will need to take into account changes in the content, even if that content is offscreen, which seems to me to break the guarantee that if some paint-contained element is off-screen, you can skip repainint it even when the content changes.

@chrishtr
Copy link
Contributor

chrishtr commented Jun 8, 2021

Filters from the content will be clipped, but filters from parents will need to take into account changes in the content, even if that content is offscreen,

Why is that? The source rect for the filter takes into account any clipping of content, so the contain:paint clip should prevent this from happening.

@frivoal
Copy link
Collaborator Author

frivoal commented Jun 16, 2021

The source rect for the filter takes into account any clipping of content, so the contain:paint clip should prevent this from happening.

The source rect takes into account clipping, so pixels that would be out of the contained element before filters are applied are clipped and not taken into account by the filter, and that's fine, but the filter itself spreads things around, without being limited to clipping on descendants.

Here, for instance, I have a paint-contained element with a red background, with a blur filter on the parent of the container applied when you hover. Also a blue line overlayed on top to see where the boundaries of the element with containment are. No red leaks out of the contained element normally, but some amount of red can be seen outside of that boundary when you hover and apply the blur filter.

http://software.hixie.ch/utilities/js/live-dom-viewer/?saved=9421

Here, it's the same idea, but nested within an element with overflow hidden with a black border. Things are sized so that the (unblured) red square with paint containment is just out of view. If you hover the document, it gets blurred, and some red can be seen. And if you hover the black bordered box, the red background is changed to blue, and that can be seen too.

http://software.hixie.ch/utilities/js/live-dom-viewer/?saved=9422

So, In that example, I am changing the background color of an off screen element with paint containment, and I still need to re-render it to get the on-screen pixels correct. That seems to defeat the point of paint containment to me.

@frivoal
Copy link
Collaborator Author

frivoal commented Jun 16, 2021

cc: @tabatkins

@chrishtr
Copy link
Contributor

I see, thanks for clarifying your concern.

That seems to defeat the point of paint containment to me.

I don't think it defeats the point. The point is to contain the paint of the contents (i.e. descendants), not the element itself, so that we don't need to render the contents in order to know whether we need to do that work. We just need to determine the paint bounds of the element.

Determining the paint bounds of the contents is quite expensive, whereas determining the paint bounds of the element is not.

@css-meeting-bot
Copy link
Member

The CSS Working Group just discussed CSS Contain, and agreed to the following:

  • RESOLVED: Update spec to acknowledge effects of filters. No other change.
The full IRC log of that discussion <fantasai> Topic: CSS Contain
<fantasai> github: https://github.com//issues/6325
<fantasai> florian: Had not realized earlier, but there's a problem with paint containment
<fantasai> florian: The point of paint containment is to ensure that if anything changes inside an element with paint containment, nothing leaks in terms of changing painting outside it
<fantasai> florian: However, filter-effects, when specified on an ancestor of the contained element,
<fantasai> florian: e.g. consider a large blur radios
<fantasai> florian: In order to calculate the result of pixels outside the box, need to consider the painting of pixels inside the box
<chris> q+
<Rossen_> q
<fantasai> florian: I think there's no infinite-range filter? So maybe you just need to calculate a margin of error to repaint.
<fantasai> chris: FE-flood, which can fill an entire region?
<fantasai> florian: Fills the entire region, but does it take the entire region as input?
<fantasai> chris: no
<fantasai> florian: yeah, that's the trouble. Blur does that.
<fantasai> smfr: Also FE-displacement, which can take arbitrary displacement.
<fantasai> florian: can be arbitrary, but can't be infinite at least
<fantasai> Rossen: ... considering chrishtr's comment
<fantasai> florian: If talking about bg of element or things inside it, issue still applies. Filter on parent will still fetch those
<fantasai> florian: If you have a 15px blur filter on BODY element
<fantasai> florian: and somewhere inside tree have a paint-contained element
<fantasai> florian: then even if it's 3px off-screen, have to repaint it so you know what pixels to spread into the screen area
<fantasai> florian: Because you have a 15px blur on the BODY, know it's within a range
<chris> standard deviation of feGaussianBlur is not bounded, but can't be infinite
<chris> https://drafts.fxtf.org/filter-effects/#element-attrdef-fegaussianblur-stddeviation
<fantasai> florian: but you have to walk up the tree to figure out what filters might apply
<chrishtr> I don't think it's a problem.
<fantasai> smfr: Do any implementers think this is a problem?
<fantasai> Rossen: do you?
<fantasai> smfr: I haven't implemented yet, I think it's fine.
<fantasai> florian: Well, the spec says as soon as element is off-screen can stop painting, that point definitely is not true
<fantasai> chrishtr: Yes, spec will need to be updated to account for filters.
<fantasai> florian: Is that good enough? or do we need to find some other solution
<fantasai> chrishtr: I think it's good enough
<fantasai> Rossen: How about we start with this, and if we find additional evidence we'll come back
<fantasai> florian: Alternative might be to say that paint-contained elements are not taken as input into filters
<fantasai> fantasai: That sounds worse
<fantasai> chrishtr: Sounds weird
<fantasai> chrishtr: Browsers can compute this, don't see a big problem
<fantasai> florian: If you don't think it'll be expensive, then fine
<fantasai> chrishtr: e.g. browser could apply simple heuristic if page doesn't have an any pixel-moving filters on it, then apply reasonable margin, or whatever
<fantasai> fantasai: proposal: update spec to acknowledge effects of filters?
<fantasai> RESOLVED: Update spec to acknowledge effects of filters. No other change.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants