Closed Bug 1363060 Opened 4 years ago Closed 4 years ago

DisplayItemLayers with mPostScale are broken

Categories

(Core :: Graphics: WebRender, defect, P3)

defect

Tracking

()

RESOLVED WONTFIX

People

(Reporter: rhunt, Unassigned)

References

Details

(Whiteboard: [gfx-noted])

The reftest radial-shape-closest-side-1a.html is failing with WR gradients enabled. [1] The problem is that the reference uses a scale (-moz-transform:scale) and the scale is being added to the display item layer, and display item layer's don't handle transforms.

Here is a layer tree dump of the radial-shape-closest-side-1-ref.html:

WebRenderLayerManager (0x7ff0809bb5c0) --- in content order
  WebRenderContainerLayer (0x7ff04ae72c08) [visible=< (x=0, y=0, w=800, h=1000); >] [opaqueContent]
    WebRenderPaintedLayer (0x7ff04aeea008) [clip=(x=0, y=0, w=0, h=0)] [not visible]
    WebRenderColorLayer (0x7ff04aeea408) [visible=< (x=0, y=0, w=800, h=10); (x=0, y=10, w=10, h=200); (x=210, y=10, w=10, h=200); (x=420, y=10, w=380, h=200); (x=0, y=210, w=800, h=10); (x=0, y=220, w=10, h=200); (x=210, y=220, w=10, h=200); (x=420, y=220, w=380, h=200); (x=0, y=420, w=800, h=580); >] [opaqueContent] [color=rgba(255, 255, 255, 1.000000)] [bounds=(x=0, y=0, w=800, h=1000)]
    WebRenderDisplayItemLayer (0x7ff04b99d808) [clip=(x=10, y=10, w=200, h=200)] [visible=< (x=10, y=10, w=200, h=200); >] [itype type=TYPE_UNKNOWN]
    WebRenderDisplayItemLayer (0x7ff04b9a3c08) [clip=(x=220, y=10, w=200, h=200)] [visible=< (x=220, y=10, w=200, h=200); >] [itype type=TYPE_UNKNOWN]
    WebRenderDisplayItemLayer (0x7ff04b9a4408) [clip=(x=10, y=220, w=200, h=200)] [visible=< (x=10, y=220, w=200, h=200); >] [itype type=TYPE_UNKNOWN]
    WebRenderDisplayItemLayer (0x7ff062f50808) [clip=(x=220, y=220, w=200, h=200)] [visible=< (x=220, y=220, w=200, h=200); >] [itype type=TYPE_UNKNOWN]
    WebRenderContainerLayer (0x7ff064281808) [clip=(x=0, y=0, w=800, h=1000)] [transform=[ 1 0; 0 2; 10 430; ]] [visible=< (x=0, y=0, w=200, h=200); >] [preScale=1, 0.5]
      WebRenderDisplayItemLayer (0x7ff04aee8408) [clip=(x=0, y=0, w=200, h=200)] [postScale=1, 2] [visible=< (x=0, y=0, w=200, h=100); >] [itype type=TYPE_UNKNOWN]
    WebRenderContainerLayer (0x7ff04aee8808) [clip=(x=0, y=0, w=800, h=1000)] [transform=[ 1 0; 0 2; 220 430; ]] [visible=< (x=0, y=0, w=200, h=200); >] [preScale=1, 0.5]
      WebRenderDisplayItemLayer (0x7ff04aee8c08) [clip=(x=0, y=0, w=200, h=200)] [postScale=1, 2] [visible=< (x=0, y=0, w=200, h=100); >] [itype type=TYPE_UNKNOWN]
    WebRenderContainerLayer (0x7ff04aee9008) [clip=(x=0, y=0, w=800, h=1000)] [transform=[ 2 0; 0 1; 10 640; ]] [visible=< (x=0, y=0, w=200, h=200); >] [preScale=0.5, 1]
      WebRenderDisplayItemLayer (0x7ff04aee9408) [clip=(x=0, y=0, w=200, h=200)] [postScale=2, 1] [visible=< (x=0, y=0, w=100, h=200); >] [itype type=TYPE_UNKNOWN]
    WebRenderContainerLayer (0x7ff04aee9808) [clip=(x=0, y=0, w=800, h=1000)] [transform=[ 2 0; 0 1; 220 640; ]] [visible=< (x=0, y=0, w=200, h=200); >] [preScale=0.5, 1]
      WebRenderDisplayItemLayer (0x7ff04aee9c08) [clip=(x=0, y=0, w=200, h=200)] [postScale=2, 1] [visible=< (x=0, y=0, w=100, h=200); >] [itype type=TYPE_UNKNOWN]

The problem is the postScale applied to the WebRenderDisplayItemLayer. There seems to be a preScale attached to the parent container layer that actually cancels it out, with a transform that does the scaling?

It seems like the solution is to apply the scaling only to the WebRenderContainerLayer.

[1] https://hg.mozilla.org/mozilla-central/raw-file/tip/layout/tools/reftest/reftest-analyzer.xhtml#logurl=https://queue.taskcluster.net/v1/task/S0_ZNRJbStS8_eX5vCwrrg/runs/0/artifacts/public/logs/live_backing.log&only_show_unexpected=1
Matt, do you know why the layer tree is being built this way or have any recommendations?

I should add the link to the reference source [1].

[1] http://searchfox.org/mozilla-central/source/layout/reftests/css-gradients/radial-shape-closest-side-1-ref.html
Flags: needinfo?(matt.woodrow)
We actively try to propagate the scaling components of transforms down to leaf layers (by applying an inverse scale to the layer that introduces the transform, and then putting the scale back on the leaves.

The code for that is here: http://searchfox.org/mozilla-central/source/layout/painting/FrameLayerBuilder.cpp#5380

The idea being that if the scale ends up on a rasterized layer (PaintedLayer), then we can apply it as a change in resolution while rasterizing, rather than scaling during compositing.

This lets us avoid scaling artifacts on a lot of content, and looks nicer :)

There's also a lot of extra complexity in that function to deal with frequently changing scales (we don't want to re-rasterize on every frame of an animation), complex transforms and other edges cases.

In a WR world where there isn't any rasterization done on the content side, this approach might not make sense. Or you could just make WebRenderDisplayItemLayer take the scale into account.
Flags: needinfo?(matt.woodrow)
Duplicate of this bug: 1366395
This bug is specific to the "layers" mode of WR which we're not going to ship. I don't think this problem will exist in the layers-free world, so I'm closing this bug as WONTFIX. Feel free to reopen if I'm wrong.
Status: NEW → RESOLVED
Closed: 4 years ago
Resolution: --- → WONTFIX
You need to log in before you can comment on or make changes to this bug.