Closed Bug 1661147 Opened 4 years ago Closed 2 years ago

[WebRender] blurred content is mispositioned, in abspos within fixedpos

Categories

(Core :: Graphics: WebRender, defect)

defect

Tracking

()

RESOLVED FIXED
106 Branch
Webcompat Priority P3
Tracking Status
firefox-esr68 --- unaffected
firefox-esr78 --- disabled
firefox-esr91 --- wontfix
firefox-esr102 --- wontfix
firefox79 --- wontfix
firefox80 --- wontfix
firefox81 --- wontfix
firefox82 --- wontfix
firefox104 --- wontfix
firefox105 --- wontfix
firefox106 --- fixed

People

(Reporter: dholbert, Assigned: emilio)

References

(Blocks 1 open bug, Regression)

Details

(Keywords: correctness, regression)

Attachments

(5 files)

Attached file testcase 1

STR:

  1. 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).

Webcompat Priority: --- → ?
Has Regression Range: --- → yes
Has STR: --- → yes
Assignee: nobody → gwatson
Flags: needinfo?(gwatson)

Hi Glenn, can you give a severity rating to this bug? Thank you!

Flags: needinfo?(gwatson)
Severity: -- → S3
Flags: needinfo?(gwatson)

Bug 1706142 has a simpler / more evident test-case.

Webcompat Priority: ? → P3

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?

Flags: needinfo?(tnikkel)
Flags: needinfo?(emilio)
Assignee: gwatson → nobody

(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.

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?

Blocks: 1782834

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: nobody → emilio
Flags: needinfo?(tnikkel)
Flags: needinfo?(emilio)

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

Pushed by ealvarez@mozilla.com:
https://hg.mozilla.org/integration/autoland/rev/5311508efeba
When starting a new list, copy inputs from the stack as well. r=gfx-reviewers,bradwerth
Created web-platform-tests PR https://github.com/web-platform-tests/wpt/pull/35571 for changes under testing/web-platform/tests
Flags: needinfo?(emilio)
Upstream PR was closed without merging
Pushed by ealvarez@mozilla.com:
https://hg.mozilla.org/integration/autoland/rev/8f0010abb113
Tweak / fix the ClipManager logs. r=gfx-reviewers,gw
Flags: needinfo?(emilio)
Keywords: leave-open
Flags: needinfo?(emilio)
Blocks: 1782590
Flags: needinfo?(emilio)
Keywords: leave-open
Pushed by ealvarez@mozilla.com:
https://hg.mozilla.org/integration/autoland/rev/06e5cdccdd8c
Improve ClipManager logs more. r=gfx-reviewers,gw
Pushed by ealvarez@mozilla.com:
https://hg.mozilla.org/integration/autoland/rev/68ec3db74342
When starting a new list, copy inputs from the stack as well. r=gfx-reviewers,bradwerth
Status: NEW → RESOLVED
Closed: 2 years ago
Resolution: --- → FIXED
Target Milestone: --- → 106 Branch
Upstream PR merged by moz-wptsync-bot
Regressions: 1796562
Regressions: 1799216
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: