Bug 1661135 - Use primitive's spatial node rather than its picture's when deciding raster space. r=gw

When zooming, webrender overrides the raster space used to render text, so that
we do not expensively rerasterize the glyphs for every fractional change in zoom
level. Previously we chose to do this when any ancestor of the picture's spatial
node was being zoomed. This worked on most pages, because the scroll frame which
is used as the main picture caching slice is a descendent of the zooming
reference frame.

However, on pages without a scrollable frame, or for fixed-position content, the
picture's spatial node will not be a descendent of the zooming reference
frame. This meant that we did not detect that we were zooming and rendered the
text in screen raster space rather than the overridden local space, leading to
poor zooming performance.

To fix this, check whether the primitive's spatial node (rather than the
picture's) is a descendent of the zooming frame.

Differential Revision: https://phabricator.services.mozilla.com/D88474
This commit is contained in:
Jamie Nicol 2020-08-27 20:04:11 +00:00
Родитель f1b7a3ca58
Коммит b1d6fddf77
2 изменённых файлов: 15 добавлений и 8 удалений

Просмотреть файл

@ -4750,16 +4750,20 @@ impl PicturePrimitive {
}
}
/// Gets the raster space to use when rendering the picture.
/// Usually this would be the requested raster space. However, if the
/// picture's spatial node or one of its ancestors is being pinch zoomed
/// Gets the raster space to use when rendering a primitive in this picture.
/// Usually this would be the picture's requested raster space. However, if
/// the primitive's spatial node or one of its ancestors is being pinch zoomed
/// then we round it. This prevents us rasterizing glyphs for every minor
/// change in zoom level, as that would be too expensive.
pub fn get_raster_space(&self, spatial_tree: &SpatialTree) -> RasterSpace {
let spatial_node = &spatial_tree.spatial_nodes[self.spatial_node_index.0 as usize];
if spatial_node.is_ancestor_or_self_zooming() {
pub fn get_raster_space_for_prim(
&self,
prim_spatial_node_index: SpatialNodeIndex,
spatial_tree: &SpatialTree,
) -> RasterSpace {
let prim_spatial_node = &spatial_tree.spatial_nodes[prim_spatial_node_index.0 as usize];
if prim_spatial_node.is_ancestor_or_self_zooming() {
let scale_factors = spatial_tree
.get_relative_transform(self.spatial_node_index, ROOT_SPATIAL_NODE_INDEX)
.get_relative_transform(prim_spatial_node_index, ROOT_SPATIAL_NODE_INDEX)
.scale_factors();
// Round the scale up to the nearest power of 2, but don't exceed 8.

Просмотреть файл

@ -364,7 +364,10 @@ fn prepare_interned_prim_for_render(
let prim_offset = prim_data.common.prim_rect.origin.to_vector() - run.reference_frame_relative_offset;
let pic = &store.pictures[pic_context.pic_index.0];
let raster_space = pic.get_raster_space(frame_context.spatial_tree);
let raster_space = pic.get_raster_space_for_prim(
prim_spatial_node_index,
frame_context.spatial_tree
);
let surface = &frame_state.surfaces[pic_context.surface_index.0];
let prim_info = &scratch.prim_info[prim_instance.visibility_info.0 as usize];
let root_scaling_factor = match pic.raster_config {