From 854019d58a760e9e8c1d2a77f00901b8575b9ae3 Mon Sep 17 00:00:00 2001 From: Nicolas Silva Date: Wed, 8 Aug 2018 15:13:12 +0200 Subject: [PATCH 1/2] Add a sanity check for render task sizes. --- webrender/src/render_task.rs | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/webrender/src/render_task.rs b/webrender/src/render_task.rs index b6913c7b36..18d307d9b1 100644 --- a/webrender/src/render_task.rs +++ b/webrender/src/render_task.rs @@ -32,10 +32,19 @@ use tiling::{RenderTargetKind}; #[cfg(feature = "pathfinder")] use webrender_api::DevicePixel; +const RENDER_TASK_SIZE_SANITY_CHECK: i32 = 16000; const FLOATS_PER_RENDER_TASK_INFO: usize = 8; pub const MAX_BLUR_STD_DEVIATION: f32 = 4.0; pub const MIN_DOWNSCALING_RT_SIZE: i32 = 128; +fn render_task_sanity_check(size: &DeviceIntSize) { + if size.width > RENDER_TASK_SIZE_SANITY_CHECK || + size.height > RENDER_TASK_SIZE_SANITY_CHECK { + error!("Attempting to create a render task of size {}x{}", size.width, size.height); + panic!(); + } +} + #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] #[cfg_attr(feature = "capture", derive(Serialize))] #[cfg_attr(feature = "replay", derive(Deserialize))] @@ -335,6 +344,7 @@ impl RenderTask { } pub fn new_readback(screen_rect: DeviceIntRect) -> Self { + render_task_sanity_check(&screen_rect.size); RenderTask { children: Vec::new(), location: RenderTaskLocation::Dynamic(None, Some(screen_rect.size)), @@ -370,6 +380,8 @@ impl RenderTask { size.width += padding.horizontal(); size.height += padding.vertical(); + render_task_sanity_check(&size); + RenderTask { children, location: RenderTaskLocation::Dynamic(None, Some(size)), @@ -458,6 +470,8 @@ impl RenderTask { } } + render_task_sanity_check(&outer_rect.size); + RenderTask { children, location: RenderTaskLocation::Dynamic(None, Some(outer_rect.size)), @@ -475,6 +489,8 @@ impl RenderTask { size: DeviceIntSize, clip_data_address: GpuCacheAddress, ) -> Self { + render_task_sanity_check(&size); + RenderTask { children: Vec::new(), location: RenderTaskLocation::Dynamic(None, Some(size)), @@ -536,6 +552,8 @@ impl RenderTask { downscaling_src_task_id = render_tasks.add(downscaling_task); } + render_task_sanity_check(&adjusted_blur_target_size); + let blur_task_v = RenderTask { children: vec![downscaling_src_task_id], location: RenderTaskLocation::Dynamic(None, Some(adjusted_blur_target_size)), @@ -569,6 +587,8 @@ impl RenderTask { size: DeviceIntSize, instances: Vec, ) -> Self { + render_task_sanity_check(&size); + RenderTask { children: Vec::new(), location: RenderTaskLocation::Dynamic(None, Some(size)), @@ -585,6 +605,8 @@ impl RenderTask { src_task_id: RenderTaskId, target_size: DeviceIntSize, ) -> Self { + render_task_sanity_check(&target_size); + RenderTask { children: vec![src_task_id], location: RenderTaskLocation::Dynamic(None, Some(target_size)), From 2dd663e3a959657d6069c5c52ed7abb89d37eb24 Mon Sep 17 00:00:00 2001 From: Nicolas Silva Date: Thu, 9 Aug 2018 18:27:00 +0200 Subject: [PATCH 2/2] Move the render task sanity checks in constructors. --- webrender/src/render_task.rs | 140 ++++++++++++++++++----------------- 1 file changed, 74 insertions(+), 66 deletions(-) diff --git a/webrender/src/render_task.rs b/webrender/src/render_task.rs index 18d307d9b1..bfadd357b4 100644 --- a/webrender/src/render_task.rs +++ b/webrender/src/render_task.rs @@ -322,6 +322,24 @@ pub struct RenderTask { } impl RenderTask { + #[inline] + pub fn with_dynamic_location( + size: DeviceIntSize, + children: Vec, + kind: RenderTaskKind, + clear_mode: ClearMode, + ) -> Self { + render_task_sanity_check(&size); + + RenderTask { + location: RenderTaskLocation::Dynamic(None, Some(size)), + children, + kind, + clear_mode, + saved_index: None, + } + } + pub fn new_picture( location: RenderTaskLocation, prim_index: PrimitiveIndex, @@ -329,9 +347,20 @@ impl RenderTask { children: Vec, uv_rect_kind: UvRectKind, ) -> Self { + let size = match location { + RenderTaskLocation::Dynamic(_, Some(size)) => Some(size), + RenderTaskLocation::Fixed(rect) => Some(rect.size), + RenderTaskLocation::TextureCache(_, _, rect) => Some(rect.size), + _ => None, + }; + + if let Some(size) = size { + render_task_sanity_check(&size); + } + RenderTask { - children, location, + children, kind: RenderTaskKind::Picture(PictureTask { prim_index, content_origin, @@ -344,14 +373,12 @@ impl RenderTask { } pub fn new_readback(screen_rect: DeviceIntRect) -> Self { - render_task_sanity_check(&screen_rect.size); - RenderTask { - children: Vec::new(), - location: RenderTaskLocation::Dynamic(None, Some(screen_rect.size)), - kind: RenderTaskKind::Readback(screen_rect), - clear_mode: ClearMode::Transparent, - saved_index: None, - } + RenderTask::with_dynamic_location( + screen_rect.size, + Vec::new(), + RenderTaskKind::Readback(screen_rect), + ClearMode::Transparent, + ) } pub fn new_blit( @@ -380,18 +407,15 @@ impl RenderTask { size.width += padding.horizontal(); size.height += padding.vertical(); - render_task_sanity_check(&size); - - RenderTask { + RenderTask::with_dynamic_location( + size, children, - location: RenderTaskLocation::Dynamic(None, Some(size)), - kind: RenderTaskKind::Blit(BlitTask { + RenderTaskKind::Blit(BlitTask { source, padding: *padding, }), - clear_mode: ClearMode::Transparent, - saved_index: None, - } + ClearMode::Transparent, + ) } pub fn new_mask( @@ -470,36 +494,30 @@ impl RenderTask { } } - render_task_sanity_check(&outer_rect.size); - - RenderTask { + RenderTask::with_dynamic_location( + outer_rect.size, children, - location: RenderTaskLocation::Dynamic(None, Some(outer_rect.size)), - kind: RenderTaskKind::CacheMask(CacheMaskTask { + RenderTaskKind::CacheMask(CacheMaskTask { actual_rect: outer_rect, clips, coordinate_system_id: prim_coordinate_system_id, }), - clear_mode: ClearMode::One, - saved_index: None, - } + ClearMode::One, + ) } pub fn new_rounded_rect_mask( size: DeviceIntSize, clip_data_address: GpuCacheAddress, ) -> Self { - render_task_sanity_check(&size); - - RenderTask { - children: Vec::new(), - location: RenderTaskLocation::Dynamic(None, Some(size)), - kind: RenderTaskKind::ClipRegion(ClipRegionTask { + RenderTask::with_dynamic_location( + size, + Vec::new(), + RenderTaskKind::ClipRegion(ClipRegionTask { clip_data_address, }), - clear_mode: ClearMode::One, - saved_index: None, - } + ClearMode::One, + ) } // Construct a render task to apply a blur to a primitive. @@ -552,52 +570,45 @@ impl RenderTask { downscaling_src_task_id = render_tasks.add(downscaling_task); } - render_task_sanity_check(&adjusted_blur_target_size); - - let blur_task_v = RenderTask { - children: vec![downscaling_src_task_id], - location: RenderTaskLocation::Dynamic(None, Some(adjusted_blur_target_size)), - kind: RenderTaskKind::VerticalBlur(BlurTask { + let blur_task_v = RenderTask::with_dynamic_location( + adjusted_blur_target_size, + vec![downscaling_src_task_id], + RenderTaskKind::VerticalBlur(BlurTask { blur_std_deviation: adjusted_blur_std_deviation, target_kind, uv_rect_handle: GpuCacheHandle::new(), uv_rect_kind, }), clear_mode, - saved_index: None, - }; + ); let blur_task_v_id = render_tasks.add(blur_task_v); - RenderTask { - children: vec![blur_task_v_id], - location: RenderTaskLocation::Dynamic(None, Some(adjusted_blur_target_size)), - kind: RenderTaskKind::HorizontalBlur(BlurTask { + RenderTask::with_dynamic_location( + adjusted_blur_target_size, + vec![blur_task_v_id], + RenderTaskKind::HorizontalBlur(BlurTask { blur_std_deviation: adjusted_blur_std_deviation, target_kind, uv_rect_handle: GpuCacheHandle::new(), uv_rect_kind, }), clear_mode, - saved_index: None, - } + ) } pub fn new_border( size: DeviceIntSize, instances: Vec, ) -> Self { - render_task_sanity_check(&size); - - RenderTask { - children: Vec::new(), - location: RenderTaskLocation::Dynamic(None, Some(size)), - kind: RenderTaskKind::Border(BorderTask { + RenderTask::with_dynamic_location( + size, + Vec::new(), + RenderTaskKind::Border(BorderTask { instances, }), - clear_mode: ClearMode::Transparent, - saved_index: None, - } + ClearMode::Transparent, + ) } pub fn new_scaling( @@ -605,18 +616,15 @@ impl RenderTask { src_task_id: RenderTaskId, target_size: DeviceIntSize, ) -> Self { - render_task_sanity_check(&target_size); - - RenderTask { - children: vec![src_task_id], - location: RenderTaskLocation::Dynamic(None, Some(target_size)), - kind: RenderTaskKind::Scaling(target_kind), - clear_mode: match target_kind { + RenderTask::with_dynamic_location( + target_size, + vec![src_task_id], + RenderTaskKind::Scaling(target_kind), + match target_kind { RenderTargetKind::Color => ClearMode::Transparent, RenderTargetKind::Alpha => ClearMode::One, }, - saved_index: None, - } + ) } #[cfg(feature = "pathfinder")]