diff --git a/gfx/wr/webrender/src/picture.rs b/gfx/wr/webrender/src/picture.rs index 32601d41695a..1951ed4dd207 100644 --- a/gfx/wr/webrender/src/picture.rs +++ b/gfx/wr/webrender/src/picture.rs @@ -5941,16 +5941,26 @@ impl PicturePrimitive { false }; + let surface_to_parent_transform = frame_context.spatial_tree + .get_relative_transform(surface_spatial_node_index, parent_raster_node_index); + // Check if there is perspective or if an SVG filter is applied, and thus whether a new // rasterization root should be established. - let establishes_raster_root = has_svg_filter || frame_context.spatial_tree - .get_relative_transform(surface_spatial_node_index, parent_raster_node_index) - .is_perspective(); + let establishes_raster_root = has_svg_filter || surface_to_parent_transform.is_perspective(); - let raster_spatial_node_index = if establishes_raster_root { - surface_spatial_node_index + let (raster_spatial_node_index, device_pixel_scale) = if establishes_raster_root { + // If a raster root is established, this surface should be scaled based on the scale factors of the surface raster to parent raster transform. + // This scaling helps ensure that the content in this surface does not become blurry or pixelated when composited in the parent surface. + let scale_factors = surface_to_parent_transform.scale_factors(); + + // Pick the largest scale factor of the transform for the scaling factor. + // Currently, we ensure that the scaling factor is >= 1.0 as a smaller scale factor can result in blurry output. + let scaling_factor = scale_factors.0.max(scale_factors.1).max(1.0); + + let device_pixel_scale = frame_context.global_device_pixel_scale * Scale::new(scaling_factor); + (surface_spatial_node_index, device_pixel_scale) } else { - parent_raster_node_index + (parent_raster_node_index, frame_context.global_device_pixel_scale) }; let scale_factors = frame_context @@ -6002,7 +6012,7 @@ impl PicturePrimitive { inflation_factor, frame_context.global_screen_world_rect, &frame_context.spatial_tree, - frame_context.global_device_pixel_scale, + device_pixel_scale, scale_factors, ); diff --git a/gfx/wr/wrench/reftests/filters/svg-filter-blur-transforms.png b/gfx/wr/wrench/reftests/filters/svg-filter-blur-transforms.png index 65a448e773b6..7bd8b5c4b67d 100644 Binary files a/gfx/wr/wrench/reftests/filters/svg-filter-blur-transforms.png and b/gfx/wr/wrench/reftests/filters/svg-filter-blur-transforms.png differ diff --git a/gfx/wr/wrench/reftests/transforms/raster-root-scaling-ref.yaml b/gfx/wr/wrench/reftests/transforms/raster-root-scaling-ref.yaml new file mode 100644 index 000000000000..5088e017566f --- /dev/null +++ b/gfx/wr/wrench/reftests/transforms/raster-root-scaling-ref.yaml @@ -0,0 +1,10 @@ + +# Tests that surfaces created by raster roots are scaled based on the surface to parent transform. +--- +root: + items: + - type: stacking-context + bounds: [0, 0, 0, 0] + items: + - image: checkerboard(2, 16, 16) + bounds: [0, 0, 260, 260] diff --git a/gfx/wr/wrench/reftests/transforms/raster-root-scaling.yaml b/gfx/wr/wrench/reftests/transforms/raster-root-scaling.yaml new file mode 100644 index 000000000000..3a592635a3d8 --- /dev/null +++ b/gfx/wr/wrench/reftests/transforms/raster-root-scaling.yaml @@ -0,0 +1,16 @@ +# Tests that surfaces created by raster roots are scaled based on the surface to parent transform. +--- +root: + items: + - type: stacking-context + bounds: [0, 0, 0, 0] + # Force WebRender to form a raster root + transform: perspective(1000) + items: + - type: stacking-context + bounds: [0, 0, 0, 0] + transform-style: preserve-3d + transform: scale(10,10) + items: + - image: checkerboard(2, 16, 16) + bounds: [0, 0, 26, 26] diff --git a/gfx/wr/wrench/reftests/transforms/reftest.list b/gfx/wr/wrench/reftests/transforms/reftest.list index f1f9191bb921..30abfcdf29ce 100644 --- a/gfx/wr/wrench/reftests/transforms/reftest.list +++ b/gfx/wr/wrench/reftests/transforms/reftest.list @@ -48,3 +48,4 @@ skip_on(android) fuzzy-range(<=3,*3077,<=10,*133,<=93,*490) == raster_root_A_819 skip_on(android) fuzzy(60,917) == raster_root_B_8192.yaml raster_root_B_ref.yaml # Make sure we don't panic != raster-root-large-mask.yaml blank.yaml +skip_on(android) == raster-root-scaling.yaml raster-root-scaling-ref.yaml