[CSS Transforms] glitchy transforms
Categories
(Core :: Graphics: WebRender, defect)
Tracking
()
Tracking | Status | |
---|---|---|
firefox88 | --- | affected |
People
(Reporter: trusktr, Unassigned)
References
(Blocks 1 open bug)
Details
Attachments
(2 files)
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.
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.
Updated•4 years ago
|
Comment 3•4 years ago
|
||
I can reproduce with WebRender and Software-Webrender, but not with D3D11.
Updated•4 years ago
|
Comment 4•4 years ago
|
||
Reproduced with Mac and Windows. Not a recent regression, reproduces at least up to FF70.
Updated•4 years ago
|
Updated•4 years ago
|
Comment 5•4 years ago
|
||
(
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).
Updated•4 years ago
|
Comment 6•3 years ago
|
||
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.
Comment 7•3 years ago
|
||
The pic_clip_rect
appears to be too tight, trying to see if it's related to this issue of transitive mappings or not.
Comment 8•3 years ago
|
||
Coming back to this. We have the following chain of transformations:
- Primitive: SNI=12, CS=7
- Picture: SNI=12, CS=7
- Surface: SNI=6, CS=1
- 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?
Comment 9•3 years ago
|
||
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
.
Comment 10•2 years ago
|
||
The bug assignee is inactive on Bugzilla, so the assignee is being reset.
Description
•