Skip to content

Commit afcf7bc

Browse files
author
Glenn Watson
committed
Bug 1761299 - Fix raster spatial node indices being out of sync r=gfx-reviewers,nical
When the max surface size is exceeded, the raster spatial node for a given surface is adjusted in `get_surface_rects`. However a locally cached variable of the old raster spatial node index was being used as a parameter when creating the render task. Instead, only retrieve the raster spatial node after the call to `get_surface_rects`, ensuring that it gets the updated value. Also add support to wrench reftests to set the maximum surface size, so that we can exercise this code path in reftests. Differential Revision: https://phabricator.services.mozilla.com/D142015 [ghsync] From https://hg.mozilla.org/mozilla-central/rev/3b9aede36b948000eee4351484b8bcb88f1e83e0
1 parent 247df7e commit afcf7bc

File tree

11 files changed

+77
-35
lines changed

11 files changed

+77
-35
lines changed

webrender/src/frame_builder.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ pub struct FrameBuilderConfig {
7272
pub background_color: Option<ColorF>,
7373
pub compositor_kind: CompositorKind,
7474
pub tile_size_override: Option<DeviceIntSize>,
75+
pub max_surface_override: Option<usize>,
7576
pub max_depth_ids: i32,
7677
pub max_target_size: i32,
7778
pub force_invalidation: bool,
@@ -525,8 +526,6 @@ impl FrameBuilder {
525526
.pictures[pic_index.0]
526527
.take_context(
527528
*pic_index,
528-
root_spatial_node_index,
529-
root_spatial_node_index,
530529
None,
531530
SubpixelMode::Allow,
532531
&mut frame_state,

webrender/src/picture.rs

Lines changed: 24 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -280,7 +280,7 @@ pub const TILE_SIZE_SCROLLBAR_VERTICAL: DeviceIntSize = DeviceIntSize {
280280

281281
/// The maximum size per axis of a surface,
282282
/// in WorldPixel coordinates.
283-
const MAX_SURFACE_SIZE: f32 = 4096.0;
283+
const MAX_SURFACE_SIZE: usize = 4096;
284284
/// Maximum size of a compositor surface.
285285
const MAX_COMPOSITOR_SURFACES_SIZE: f32 = 8192.0;
286286

@@ -4433,8 +4433,6 @@ impl PicturePrimitive {
44334433
pub fn take_context(
44344434
&mut self,
44354435
pic_index: PictureIndex,
4436-
surface_spatial_node_index: SpatialNodeIndex,
4437-
raster_spatial_node_index: SpatialNodeIndex,
44384436
parent_surface_index: Option<SurfaceIndex>,
44394437
parent_subpixel_mode: SubpixelMode,
44404438
frame_state: &mut FrameBuildingState,
@@ -4451,27 +4449,11 @@ impl PicturePrimitive {
44514449

44524450
profile_scope!("take_context");
44534451

4454-
// Extract the raster and surface spatial nodes from the raster
4455-
// config, if this picture establishes a surface. Otherwise just
4456-
// pass in the spatial node indices from the parent context.
4457-
let (raster_spatial_node_index, surface_spatial_node_index, surface_index) = match self.raster_config {
4458-
Some(ref raster_config) => {
4459-
let surface = &frame_state.surfaces[raster_config.surface_index.0];
4460-
4461-
(
4462-
surface.raster_spatial_node_index,
4463-
self.spatial_node_index,
4464-
raster_config.surface_index,
4465-
)
4466-
}
4467-
None => {
4468-
(
4469-
raster_spatial_node_index,
4470-
surface_spatial_node_index,
4471-
parent_surface_index.expect("bug: no parent"),
4472-
)
4473-
}
4452+
let surface_index = match self.raster_config {
4453+
Some(ref raster_config) => raster_config.surface_index,
4454+
None => parent_surface_index.expect("bug: no parent"),
44744455
};
4456+
let surface_spatial_node_index = frame_state.surfaces[surface_index.0].surface_spatial_node_index;
44754457

44764458
let map_pic_to_world = SpaceMapper::new_with_target(
44774459
frame_context.root_spatial_node_index,
@@ -4809,7 +4791,8 @@ impl PicturePrimitive {
48094791
tile_cache.current_tile_size.to_f32(),
48104792
content_origin,
48114793
surface_spatial_node_index,
4812-
raster_spatial_node_index,
4794+
// raster == surface implicitly for picture cache tiles
4795+
surface_spatial_node_index,
48134796
device_pixel_scale,
48144797
Some(tile_key),
48154798
Some(scissor_rect),
@@ -4950,18 +4933,27 @@ impl PicturePrimitive {
49504933
self.prev_local_rect = local_rect;
49514934
}
49524935

4936+
let max_surface_size = frame_context
4937+
.fb_config
4938+
.max_surface_override
4939+
.unwrap_or(MAX_SURFACE_SIZE) as f32;
4940+
49534941
let surface_rects = match get_surface_rects(
49544942
raster_config.surface_index,
49554943
&raster_config.composite_mode,
49564944
parent_surface_index,
49574945
&mut frame_state.surfaces,
49584946
frame_context.spatial_tree,
4947+
max_surface_size,
49594948
) {
49604949
Some(rects) => rects,
49614950
None => return None,
49624951
};
49634952

4964-
let device_pixel_scale = frame_state.surfaces[raster_config.surface_index.0].device_pixel_scale;
4953+
let (raster_spatial_node_index, device_pixel_scale) = {
4954+
let surface = &frame_state.surfaces[surface_index.0];
4955+
(surface.raster_spatial_node_index, surface.device_pixel_scale)
4956+
};
49654957
let cmd_buffer_builder = CommandBufferBuilder::new_simple(
49664958
surface_rects.clipped_local,
49674959
);
@@ -5412,7 +5404,7 @@ impl PicturePrimitive {
54125404
let context = PictureContext {
54135405
pic_index,
54145406
apply_local_clip_rect: self.apply_local_clip_rect,
5415-
raster_spatial_node_index,
5407+
raster_spatial_node_index: frame_state.surfaces[surface_index.0].raster_spatial_node_index,
54165408
surface_spatial_node_index,
54175409
surface_index,
54185410
dirty_region_count,
@@ -6762,6 +6754,7 @@ fn get_surface_rects(
67626754
parent_surface_index: SurfaceIndex,
67636755
surfaces: &mut [SurfaceInfo],
67646756
spatial_tree: &SpatialTree,
6757+
max_surface_size: f32,
67656758
) -> Option<SurfaceAllocInfo> {
67666759
let parent_surface = &surfaces[parent_surface_index.0];
67676760

@@ -6871,19 +6864,19 @@ fn get_surface_rects(
68716864

68726865
let task_size_f = clipped.size();
68736866

6874-
if task_size_f.width > MAX_SURFACE_SIZE || task_size_f.height > MAX_SURFACE_SIZE {
6867+
if task_size_f.width > max_surface_size || task_size_f.height > max_surface_size {
68756868
let max_dimension = clipped_local.width().max(clipped_local.height()).ceil();
68766869

68776870
surface.raster_spatial_node_index = surface.surface_spatial_node_index;
6878-
surface.device_pixel_scale = Scale::new(MAX_SURFACE_SIZE / max_dimension);
6871+
surface.device_pixel_scale = Scale::new(max_surface_size / max_dimension);
68796872

68806873
clipped = (clipped_local.cast_unit() * surface.device_pixel_scale).round();
68816874
unclipped = unclipped_local.cast_unit() * surface.device_pixel_scale;
68826875
}
68836876

68846877
let task_size = clipped.size().to_i32();
6885-
debug_assert!(task_size.width <= MAX_SURFACE_SIZE as i32);
6886-
debug_assert!(task_size.height <= MAX_SURFACE_SIZE as i32);
6878+
debug_assert!(task_size.width <= max_surface_size as i32);
6879+
debug_assert!(task_size.height <= max_surface_size as i32);
68876880

68886881
let uv_rect_kind = calculate_uv_rect_kind(
68896882
clipped,
@@ -6990,5 +6983,6 @@ fn test_large_surface_scale_1() {
69906983
SurfaceIndex(0),
69916984
&mut surfaces,
69926985
&spatial_tree,
6986+
MAX_SURFACE_SIZE as f32,
69936987
);
69946988
}

webrender/src/prepare.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -148,8 +148,6 @@ fn prepare_prim_for_render(
148148

149149
match pic.take_context(
150150
pic_index,
151-
pic_context.surface_spatial_node_index,
152-
pic_context.raster_spatial_node_index,
153151
Some(pic_context.surface_index),
154152
pic_context.subpixel_mode,
155153
frame_state,

webrender/src/render_api.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -904,6 +904,8 @@ pub enum DebugCommand {
904904
SimulateLongSceneBuild(u32),
905905
/// Set an override tile size to use for picture caches
906906
SetPictureTileSize(Option<DeviceIntSize>),
907+
/// Set an override for max off-screen surface size
908+
SetMaximumSurfaceSize(Option<usize>),
907909
}
908910

909911
/// Message sent by the `RenderApi` to the render backend thread.

webrender/src/render_backend.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -968,6 +968,12 @@ impl RenderBackend {
968968

969969
return RenderBackendStatus::Continue;
970970
}
971+
DebugCommand::SetMaximumSurfaceSize(surface_size) => {
972+
self.frame_config.max_surface_override = surface_size;
973+
self.update_frame_builder_config();
974+
975+
return RenderBackendStatus::Continue;
976+
}
971977
#[cfg(feature = "capture")]
972978
DebugCommand::SaveCapture(root, bits) => {
973979
let output = self.save_capture(root, bits);

webrender/src/renderer/mod.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1180,6 +1180,7 @@ impl Renderer {
11801180
background_color: Some(options.clear_color),
11811181
compositor_kind,
11821182
tile_size_override: None,
1183+
max_surface_override: None,
11831184
max_depth_ids: device.max_depth_ids(),
11841185
max_target_size: max_internal_texture_size,
11851186
force_invalidation: false,
@@ -1659,7 +1660,8 @@ impl Renderer {
16591660
fn handle_debug_command(&mut self, command: DebugCommand) {
16601661
match command {
16611662
DebugCommand::EnableDualSourceBlending(_) |
1662-
DebugCommand::SetPictureTileSize(_) => {
1663+
DebugCommand::SetPictureTileSize(_) |
1664+
DebugCommand::SetMaximumSurfaceSize(_) => {
16631665
panic!("Should be handled by render backend");
16641666
}
16651667
DebugCommand::SaveCapture(..) |

webrender/src/scene.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,7 @@ impl BuiltScene {
325325
background_color: None,
326326
compositor_kind: CompositorKind::default(),
327327
tile_size_override: None,
328+
max_surface_override: None,
328329
max_depth_ids: 0,
329330
max_target_size: 0,
330331
force_invalidation: false,

wrench/reftests/snap/1761299-ref.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
root:
3+
items:
4+
- type: rect
5+
bounds: [0, 0, 512, 128]
6+
color: red

wrench/reftests/snap/1761299.yaml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# verify that the raster spatial node selected when a surface is too large
2+
# is correct propagated to the picture render task
3+
---
4+
root:
5+
items:
6+
- type: stacking-context
7+
filters: [identity]
8+
transform: scale(0.5,1,1)
9+
items:
10+
- type: rect
11+
bounds: [0, 0, 1024, 128]
12+
color: red

wrench/reftests/snap/reftest.list

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,4 @@ platform(linux,mac) == snap.yaml snap.png
33
platform(linux,mac) == preserve-3d.yaml preserve-3d.png
44
fuzzy(128,200) == subpixel-raster-root.yaml subpixel-raster-root-ref.yaml
55
platform(linux,mac) == fractional-filter.yaml fractional-filter-ref.yaml
6+
max_surface_size(256) == 1761299.yaml 1761299.yaml

0 commit comments

Comments
 (0)