Bug 1559861: WR - Scale picture tasks based on their surface to parent transform scale factors r=gw,Bert

This patch adjusts the device pixel scale for raster root surfaces so that the surface's content is not
pixelated/blurred when it is composited into its parent surface where a transform scales up the surface.

This only fixes the referenced bug when WebRender is used.

Differential Revision: https://phabricator.services.mozilla.com/D75236
This commit is contained in:
cbrewster 2020-05-20 17:19:06 +00:00
parent e67d8e1da9
commit df02aa6efc
5 changed files with 44 additions and 7 deletions

View File

@ -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,
);

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.7 KiB

After

Width:  |  Height:  |  Size: 6.0 KiB

View File

@ -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]

View File

@ -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]

View File

@ -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