[WebRender] blurred content is mispositioned, in abspos within fixedpos
Categories
(Core :: Graphics: WebRender, defect)
Tracking
()
People
(Reporter: dholbert, Assigned: emilio)
References
(Blocks 1 open bug, Regression)
Details
(Keywords: correctness, regression)
Attachments
(5 files)
STR:
- Load attached testcase.
ACTUAL RESULTS:
Blurred red fringe at top left.
EXPECTED RESULTS:
No red fringe. (The red area should be offscreen.)
Firefox Nightly with WebRender enabled gives ACTUAL RESULTS.
If I disable WebRender, I get EXPECTED RESULTS.
Chrome also gives EXPECTED RESULTS.
This was originally reported as https://webcompat.com/issues/56962 (for the blurred top bar at https://goalkicker.com/MySQLBook/ , which is unexpectedly less-blurry at its edges in WebRender-powered Firefox).
Reporter | ||
Comment 1•4 years ago
|
||
Updated•4 years ago
|
Updated•4 years ago
|
Updated•4 years ago
|
Updated•4 years ago
|
Comment 3•4 years ago
|
||
Hi Glenn, can you give a severity rating to this bug? Thank you!
Updated•4 years ago
|
Updated•4 years ago
|
Assignee | ||
Comment 5•4 years ago
|
||
Bug 1706142 has a simpler / more evident test-case.
Updated•3 years ago
|
Comment 6•2 years ago
|
||
I finally got around to looking at this, and I think that the issue lies in either layout or display-list building, rather than webrender.
When I take a capture, I can see that the rectangle in the blur filter has bounds of (-75, -75) to (525, 525). However, it has a clip-chain attached which defines a clip-rect from (0, 0) -> (1920, 1948).
This means that WR clips the size of the surface for the blur target, resulting in no blurred pixels from outside. If I change the clip-rect in the capture file to begin at (-200, -200) it looks as if I would expect it to.
Perhaps Emilio or Timothy might have a better idea where that clip-rect would come from and get attached to that primitive?
Updated•2 years ago
|
Comment 7•2 years ago
|
||
(In reply to Glenn Watson [:gw] from comment #6)
When I take a capture, I can see that the rectangle in the blur filter has bounds of (-75, -75) to (525, 525). However, it has a clip-chain attached which defines a clip-rect from (0, 0) -> (1920, 1948).
This means that WR clips the size of the surface for the blur target, resulting in no blurred pixels from outside. If I change the clip-rect in the capture file to begin at (-200, -200) it looks as if I would expect it to.
It sounds like that clip is probably clipping the whole page (so content doesn't draw outside the content area?) and it's expecting the blur to happen first and then the clip.
Comment 8•2 years ago
|
||
I think that's probably true, but as I understand it currently, there's no way for WR to determine if such a clip is meant to be applied after a blur, or is a genuine per-item clip that should be applied before the blur (the clip in this case is in the same space as the primitive, and is applied to the primitive itself, not the stacking context containing the blur).
Put another way, if you had a page where you set a clip on that item itself in a way that should make it look like the output above, the display list would look the same as it does in this case, I think?
So, if I'm correct in the above (it's subtle enough I might have easily missed something!) then the options are either (a) for Gecko to not set a clip on a primitive like that inside the blur and only set the whole page clip on the blur stacking context or (b) Add something to the WR API to distinguish between where a clip on a primitive should apply if it's part of a filter?
Option (a) sounds better to me, I'm not actually sure how (b) would work yet. But again, I don't know the gecko code well, so maybe (a) isn't easy to do, or there is a better option?
Assignee | ||
Comment 9•2 years ago
|
||
So, (a) does sound correct to me, but I'm confused about where things are going wrong. When I dump the Gecko display list I see:
FixedPosition p=0x7f8e88dcd928 f=0x7f8e88d68010(Block(div)(3)) key=31 bounds(-6385,-6385,30770,30770) componentAlpha(0,0,0,0) clip(0,0,61440,40968) asr() clipChain(0x7f8e88dcd170 <0,0,61440,40968> [root asr]) reuse-state(None) (containerASR ) (scrolltarget 2)
CompositorHitTestInfo p=0x7f8e88dcd020 f=0x7f8e88d68010(Block(div)(3)) key=25 bounds(0,0,0,0) componentAlpha(0,0,0,0) clip() asr() clipChain() hitTestInfo(0x1) hitTestArea(0,0,24000,24000) reuse-state(None)
nsDisplayContainer p=0x7f8e88dcd848 f=0x7f8e88d68158(Block(div)(1)) key=26 bounds(-6385,-6385,30770,30770) componentAlpha(0,0,0,0) clip() asr() clipChain() reuse-state(None)
Filter p=0x7f8e88dcd6c8 f=0x7f8e88d68158(Block(div)(1)) key=30 bounds(-6385,-6385,30770,30770) componentAlpha(0,0,0,0) clip() asr() clipChain() reuse-state(None) effects=(filter)
BackgroundColor p=0x7f8e88dcd468 f=0x7f8e88d68158(Block(div)(1)) key=6 bounds(-3000,-3000,24000,24000) componentAlpha(0,0,0,0) clip() asr() clipChain() uniform (opaque -3000,-3000,24000,24000) hitTestInfo(0x1) hitTestArea(-3000,-3000,24000,24000) reuse-state(None) (rgba 1,1,1,1) backgroundRect(x=-3000, y=-3000, w=24000, h=24000)
That is, the only item with a clip is the FixedPosition
item, which is what I'd expect. However it seems like we propagate the clip somehow when converting the DL to WebRender:
Filter p=0x7faed03d56c8 f=0x7faed0342158(Block(div)(1)) key=30 bounds(-6385,-6385,30770,30770) componentAlpha(0,0,0,0) clip() asr() clipChain() reuse-state(None) effects=(filter)
SetFilterOps
PushStackingContext(PushStackingContextDisplayItem { origin: (0.0, 0.0), spatial_id: SpatialId(2, PipelineId(1, 4)), prim_flags: IS_BACKFACE_VISIBLE, stacking_context: StackingContext { transform_style: Flat, mix_blend_mode: Normal, clip_chain_id: Some(ClipChainId(3, PipelineId(1, 4))), raster_space: Screen, flags: (empty) } })
BackgroundColor p=0x7faed03d55f0 f=0x7faed0342158(Block(div)(1)) key=6 bounds(-3000,-3000,24000,24000) componentAlpha(0,0,0,0) clip() asr() clipChain() uniform (opaque -3000,-3000,24000,24000) hitTestInfo(0x1) hitTestArea(-3000,-3000,24000,24000) reuse-state(None) (rgba 1,1,1,1) backgroundRect(x=-3000, y=-3000, w=24000, h=24000)
HitTest(HitTestDisplayItem { rect: Box2D((-125.0, -125.0), (875.0, 875.0)), clip_chain_id: ClipChainId(3, PipelineId(1, 4)), spatial_id: SpatialId(2, PipelineId(1, 4)), flags: IS_BACKFACE_VISIBLE, tag: (2, 36865) })
Rectangle(RectangleDisplayItem { common: CommonItemProperties { clip_rect: Box2D((-125.0, -125.0), (875.0, 875.0)), clip_chain_id: ClipChainId(3, PipelineId(1, 4)), spatial_id: SpatialId(2, PipelineId(1, 4)), flags: IS_BACKFACE_VISIBLE }, bounds: Box2D((-125.0, -125.0), (875.0, 875.0)), color: Value(ColorF { r: 1.0, g: 1.0, b: 1.0, a: 1.0 }) })
PopStackingContext
PopStackingContext
PopStackingContext
So I think this is a bug with the ClipManager code. In fact, if I remove this chunk of code the test-cases work as expected.
Assignee | ||
Comment 10•2 years ago
|
||
Assignee | ||
Comment 11•2 years ago
|
||
Copying outputs with a null clip input is not sound if one of the other
items expand outside of our bounds, such as in the case of a blur
filter.
Depends on D155240
Comment 12•2 years ago
|
||
Comment 14•2 years ago
|
||
Backed out as requested.
Backout link: https://hg.mozilla.org/integration/autoland/rev/1baa00f0cb239d10044bb1385d993b431ae5b79c
Comment 16•2 years ago
|
||
Assignee | ||
Updated•2 years ago
|
Assignee | ||
Updated•2 years ago
|
Comment 17•2 years ago
|
||
bugherder |
Assignee | ||
Comment 18•2 years ago
|
||
Assignee | ||
Updated•2 years ago
|
Assignee | ||
Updated•2 years ago
|
Comment 19•2 years ago
|
||
Comment 20•2 years ago
|
||
Comment 21•2 years ago
|
||
bugherder |
https://hg.mozilla.org/mozilla-central/rev/06e5cdccdd8c
https://hg.mozilla.org/mozilla-central/rev/68ec3db74342
Updated•2 years ago
|
Description
•