Open Bug 1697097 Opened 4 years ago Updated 2 years ago

[CSS Transforms] glitchy transforms

Categories

(Core :: Graphics: WebRender, defect)

Firefox 86
defect

Tracking

()

Tracking Status
firefox88 --- affected

People

(Reporter: trusktr, Unassigned)

References

(Blocks 1 open bug)

Details

Attachments

(2 files)

Attached video Glitchy Firefox

User Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.182 Safari/537.36

Steps to reproduce:

Got to http://lume.io

The 3D scene if very simple. Firefox can't display it correctly.

Actual results:

The L and E letters in the "LUME" word glitch at certain angles. Also the cube sides appear to be invisible at certain angles, showing the inside of the cube erroneously.

Expected results:

It works fine in Google Chrome, try it there.

I attached a video of each.

Attached video Chrome with no glitches

This really detracts from CSS 3D being a valuable API for web developers to use. I wouldn't doubt people skip using CSS 3D due to these issues.

Component: Untriaged → CSS Transitions and Animations
Product: Firefox → Core

I can reproduce with WebRender and Software-Webrender, but not with D3D11.

Component: CSS Transitions and Animations → Graphics: WebRender
Status: UNCONFIRMED → NEW
Ever confirmed: true

Reproduced with Mac and Windows. Not a recent regression, reproduces at least up to FF70.

Flags: needinfo?(dmalyshau)
Severity: -- → S3
Assignee: nobody → dmalyshau
Flags: needinfo?(dmalyshau)
(
    location: Dynamic(
     texture_id: (2295),
     rect: (
      origin: (0, 0),
      size: (1589, 255),
     ),
    ),
    children: [],
    kind: Picture((
     pic_index: (0),
     can_merge: false,
     content_origin: (86, 0),
     surface_spatial_node_index: (12),
     device_pixel_scale: (1.1142381, ()),
     batch_filter: None,
     scissor_rect: None,
     valid_rect: None,
    )),
    free_after: (4),
    render_on: (5),
    uv_rect_handle: (
     location: Some((
      block_index: (3640),
      epoch: (1792),
     )),
    ),
    cache_handle: None,
    uv_rect_kind: Quad(
     top_left: (-0.05412209, 0, 0, 1),
     top_right: (0.9998112, 0, 0, 1),
     bottom_left: (-0.05412209, 0.99888176, 0, 1),
     bottom_right: (0.9998112, 0.99888176, 0, 1),
    ),
   ),// [11]

Part of the problem is the device-pixel ratio, and its interaction with content_origin. In one of the captures I'm looking at, the rendering omits precisely a part of the image that's 86-pixels wide (equals to the content_origin).

Started looking at this again. The content origin is produced by get_raster_rects, which does complex jumping between spaces. We might be stretching the API constraints for using the SpaceMapper here. The map, and the low level project_rect has an expectation that the source volume is 2D, and it produces the target bounding box in 2D. This breaks when we start chaining them: if you need to jump from A to B, and you insert C in the middle, jumping through A -> B -> C, then you'd have an implicit assumption that the transformation is flattened at B. However, I don't think we are checking for this appropriately in get_raster_rects. This results in the actual transformations disagreeing with the estimated raster rects.

The pic_clip_rect appears to be too tight, trying to see if it's related to this issue of transitive mappings or not.

Coming back to this. We have the following chain of transformations:

  1. Primitive: SNI=12, CS=7
  2. Picture: SNI=12, CS=7
  3. Surface: SNI=6, CS=1
  4. World: SNI=0, CS=0

Note: SNI = "spatial node index", CS = "coordinate space"

First, we compute the local rect, and we transform it into the picture space (so, Primitive -> Picture):

let local_bounding_rect = local_prim_rect.intersection(&local_clip_rect)?;
let mut pic_clip_rect = prim_to_pic_mapper.map(&local_bounding_rect)?;

Then, we take this picture rect, and we transform it into the world space (Surface -> World):

raster_config.clipped_bounding_rect = map_surface_to_world
                    .map(&prim_instance.vis.clip_chain.pic_clip_rect)

So it looks like we aren't applying the Picture -> Surface transformation anywhere?

Ugh, we have this confusion of Picture space vs Surface space in many places, which isn't manifested in the type system. As such, build_clip_chain_instance arguments talk about the picture space: prim_to_pic_mapper and pic_to_world_mapper. This function is called in 2 places, one of them passes map_local_to_surface and map_surface_to_world, the other passes pic_state.map_local_to_pic and pic_state.map_pic_to_world.

The bug assignee is inactive on Bugzilla, so the assignee is being reset.

Assignee: dmalyshau → nobody
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: