Out-of-flow positioned elements cannot escape composited border-radius mask |
||||||
Issue descriptionChrome Version: M57 OS: All Open attached test case. The green rect should not be clipped at all, yet somehow it is clipped by the rounded corner but not the straight edge. What is the expected result? The green rect should be a rect (unclipped) and the blue one should be clipped. What happens instead? Before https://crrev.com/d3ba7664a7ebc6e74861602eb9696c7ca0a4ed2e the blue and the green are unclipped. After, the blue is properly clipped but the green is chopped in the corner.
,
Jan 5 2017
The case in comment 0 is because the descendant is a stacking child, due to the opacity. Therefore it's a descendant in the graphics layer tree, and as trchen mentioned this means that the masking for the ancestor affects it.
,
Jan 5 2017
Another case to consider is a non-stacking child which has no compositing trigger: <div style="width:300px; height:200px; border:1px dashed black; border-radius:50px; overflow:hidden;"> <div style="position:absolute; left: 250px; width:100px; height:100px; background:green; "></div> </div> I think the child div in the above example will be clipped by the mask.
,
Jan 5 2017
#1: The nine-piece effect is due to GL texture clamping I believe. We have a render surface that's bigger than the mask texture, and the mask sample points outside of the texture extent just get get clamped to the texture edge. IMO the right thing to do is to use GL_CLAMP_TO_BORDER for mask textures with transparent border color.
,
Jan 11 2017
As I'm currently working on mask tiling, I came across this test case. With my patch, both rects are clipped by the mask. Is it supposed to be so?
,
Jan 11 2017
Yes, both should be clipped because they are both children of the overflow-hidden border-radius div.
,
Jan 12 2017
To be clear, absolute-positioned children do escape ancestor border-radius clip if the clipping ancestor is not in the containing block chain. Just that if there is an ancestor stacking context that needs to be clipped, it is very difficult to implement clip escaping in this case. So no, only descendants that are positioned by the clipping element shall be clipped by the border-radius by CSS spec. But yes, from the perspective of cc, both layer needs to be masked by the border-radius because that's what blink told it to do.
,
Feb 9 2017
Just to be clear on this, both the example in comments #0 and #3 should have the blue rect clipped and the green one unclipped, because the absolute position escapes the overflow clip. Comment #2 is related to how we build the layer tree, not how it should be rendered, right? I can't find anything that talks about stacking contexts affecting the behavior of absolute elements with overflow. Or does the stacking context change the containing block, in which case the absolute should also move when opacity is added. And the texture issue in comment #4 is unrelated but a bug? It shows up because the ancestor rectangular clip is not applied to the absolute positioned element but the mask is?
,
Feb 10 2017
> Just to be clear on this, both the example in comments #0 and #3 should have the blue rect clipped and the green one unclipped, because the absolute position escapes the overflow clip. Correct. > Comment #2 is related to how we build the layer tree, not how it should be rendered, right? I can't find anything that talks about stacking contexts affecting the behavior of absolute elements with overflow. Or does the stacking context change the containing block, in which case the absolute should also move when opacity is added. Creation of stacking context does not imply containing block for all descendants nor the opposite. Thus the two notorious CSS corner cases: "D paints into A but not positioned by A" and "D is positioned by A but does not paint into A". Most of --enable-prefer-compositing-to-lcd-text bugs are related to one of these corner cases. There are some spec efforts to eliminate these corner cases, but I'm afraid we're too late. It will break too many websites if opacity implies containing block. Also all vendors verbally agreed filter should imply containing block. Mozilla took the train, but others just wave hands and watched. Poor Mozilla. :( Another approach is to apply overflow clip at stacking context level. That will break even more websites. > And the texture issue in comment #4 is unrelated but a bug? It shows up because the ancestor rectangular clip is not applied to the absolute positioned element but the mask is? Yes, it is a GL renderer bug that caused mask layer effectively extends its edge pixel to infinite. sunxd@'s tiled mask mode will automatically fix that. I also have a WIP that will fix single texture masks.
,
May 26 2018
@trchen, please verify that this bug is fixed by BlinkGenPropertyTrees.
,
May 26 2018
Issue 827870 has been merged into this issue.
,
May 26 2018
,
May 29 2018
Re #10: Yes --enable-blink-gen-property-trees fixed it.
,
Sep 13
I'm leaving the team thus re-assigning bugs. |
||||||
►
Sign in to add a comment |
||||||
Comment 1 by schenney@chromium.org
, Jan 5 2017