diff --git a/gfx/webrender/src/frame_builder.rs b/gfx/webrender/src/frame_builder.rs index 14436caae8af..7d2887501f57 100644 --- a/gfx/webrender/src/frame_builder.rs +++ b/gfx/webrender/src/frame_builder.rs @@ -12,7 +12,7 @@ use gpu_cache::GpuCache; use gpu_types::{PrimitiveHeaders, TransformPalette, UvRectKind, ZBufferIdGenerator}; use hit_test::{HitTester, HitTestingRun}; use internal_types::{FastHashMap, PlaneSplitter}; -use picture::{PictureSurface, PictureUpdateContext, SurfaceInfo, ROOT_SURFACE_INDEX}; +use picture::{PictureSurface, PictureUpdateContext, SurfaceInfo, ROOT_SURFACE_INDEX, SurfaceIndex}; use prim_store::{PrimitiveStore, SpaceMapper, PictureIndex, PrimitiveDebugId}; use profiler::{FrameProfileCounters, GpuCacheProfileCounters, TextureCacheProfileCounters}; use render_backend::{FrameResources, FrameId}; @@ -100,12 +100,13 @@ pub struct PictureContext { pub raster_space: RasterSpace, pub surface_spatial_node_index: SpatialNodeIndex, pub raster_spatial_node_index: SpatialNodeIndex, + /// The surface that this picture will render on. + pub surface_index: SurfaceIndex, } /// Mutable state of a picture that gets modified when /// the children are processed. pub struct PictureState { - pub tasks: Vec, pub has_non_root_coord_system: bool, pub is_cacheable: bool, pub local_rect_changed: bool, @@ -267,6 +268,7 @@ impl FrameBuilder { self.root_pic_index, root_spatial_node_index, root_spatial_node_index, + ROOT_SURFACE_INDEX, true, &mut frame_state, &frame_context, @@ -289,14 +291,16 @@ impl FrameBuilder { &mut frame_state, ); - let (pic_state, _) = pic.take_state_and_context(); + let child_tasks = frame_state + .surfaces[ROOT_SURFACE_INDEX.0] + .take_render_tasks(); let root_render_task = RenderTask::new_picture( RenderTaskLocation::Fixed(self.screen_rect.to_i32()), self.screen_rect.size.to_f32(), self.root_pic_index, DeviceIntPoint::zero(), - pic_state.tasks, + child_tasks, UvRectKind::Rect, root_spatial_node_index, ); diff --git a/gfx/webrender/src/picture.rs b/gfx/webrender/src/picture.rs index 76b09eb5b425..780c0bc6f88b 100644 --- a/gfx/webrender/src/picture.rs +++ b/gfx/webrender/src/picture.rs @@ -84,6 +84,8 @@ pub struct SurfaceInfo { pub surface_spatial_node_index: SpatialNodeIndex, /// This is set when the render task is created. pub surface: Option, + /// A list of render tasks that are dependencies of this surface. + pub tasks: Vec, } impl SurfaceInfo { @@ -116,8 +118,15 @@ impl SurfaceInfo { surface: None, raster_spatial_node_index, surface_spatial_node_index, + tasks: Vec::new(), } } + + /// Take the set of child render tasks for this surface. This is + /// used when constructing the render task tree. + pub fn take_render_tasks(&mut self) -> Vec { + mem::replace(&mut self.tasks, Vec::new()) + } } #[derive(Debug)] @@ -546,6 +555,7 @@ impl PicturePrimitive { pic_index: PictureIndex, surface_spatial_node_index: SpatialNodeIndex, raster_spatial_node_index: SpatialNodeIndex, + surface_index: SurfaceIndex, parent_allows_subpixel_aa: bool, frame_state: &mut FrameBuildingState, frame_context: &FrameBuildingContext, @@ -557,14 +567,14 @@ impl PicturePrimitive { // Extract the raster and surface spatial nodes from the raster // config, if this picture establishes a surface. Otherwise just // pass in the spatial node indices from the parent context. - let (raster_spatial_node_index, surface_spatial_node_index) = match self.raster_config { + let (raster_spatial_node_index, surface_spatial_node_index, surface_index) = match self.raster_config { Some(ref raster_config) => { let surface = &frame_state.surfaces[raster_config.surface_index.0]; - (surface.raster_spatial_node_index, self.spatial_node_index) + (surface.raster_spatial_node_index, self.spatial_node_index, raster_config.surface_index) } None => { - (raster_spatial_node_index, surface_spatial_node_index) + (raster_spatial_node_index, surface_spatial_node_index, surface_index) } }; @@ -607,7 +617,6 @@ impl PicturePrimitive { }; let state = PictureState { - tasks: Vec::new(), has_non_root_coord_system: false, is_cacheable: true, local_rect_changed: false, @@ -644,6 +653,7 @@ impl PicturePrimitive { raster_space: self.requested_raster_space, raster_spatial_node_index, surface_spatial_node_index, + surface_index, }; let prim_list = mem::replace(&mut self.prim_list, PrimitiveList::empty()); @@ -985,6 +995,7 @@ impl PicturePrimitive { pic_index: PictureIndex, prim_instance: &PrimitiveInstance, prim_local_rect: &LayoutRect, + surface_index: SurfaceIndex, pic_state: &mut PictureState, frame_context: &FrameBuildingContext, frame_state: &mut FrameBuildingState, @@ -1002,16 +1013,19 @@ impl PicturePrimitive { let raster_config = match self.raster_config { Some(ref mut raster_config) => raster_config, None => { - pic_state.tasks.extend(pic_state_for_children.tasks); return true } }; - let surface_info = &mut frame_state.surfaces[raster_config.surface_index.0]; + let (raster_spatial_node_index, child_tasks) = { + let surface_info = &mut frame_state.surfaces[raster_config.surface_index.0]; + (surface_info.raster_spatial_node_index, surface_info.take_render_tasks()) + }; + let surfaces = &mut frame_state.surfaces; let (map_raster_to_world, map_pic_to_raster) = create_raster_mappers( prim_instance.spatial_node_index, - surface_info.raster_spatial_node_index, + raster_spatial_node_index, frame_context, ); @@ -1035,7 +1049,7 @@ impl PicturePrimitive { // Perhaps store the color matrix after the common data, even though // it's not used by that shader. - match raster_config.composite_mode { + let surface = match raster_config.composite_mode { PictureCompositeMode::Filter(FilterOp::Blur(blur_radius)) => { let blur_std_deviation = blur_radius * frame_context.device_pixel_scale.0; let blur_range = (blur_std_deviation * BLUR_SAMPLE_SCALE).ceil() as i32; @@ -1066,14 +1080,14 @@ impl PicturePrimitive { // anyway. In the future we should relax this a bit, so that we can // cache tasks with complex coordinate systems if we detect the // relevant transforms haven't changed from frame to frame. - let surface = if pic_state_for_children.has_non_root_coord_system || - !pic_state_for_children.is_cacheable { + if pic_state_for_children.has_non_root_coord_system || + !pic_state_for_children.is_cacheable { let picture_task = RenderTask::new_picture( RenderTaskLocation::Dynamic(None, device_rect.size), unclipped.size, pic_index, device_rect.origin, - pic_state_for_children.tasks, + child_tasks, uv_rect_kind, pic_context.raster_spatial_node_index, ); @@ -1090,7 +1104,7 @@ impl PicturePrimitive { let render_task_id = frame_state.render_tasks.add(blur_render_task); - pic_state.tasks.push(render_task_id); + surfaces[surface_index.0].tasks.push(render_task_id); PictureSurface::RenderTask(render_task_id) } else { @@ -1124,8 +1138,6 @@ impl PicturePrimitive { None, false, |render_tasks| { - let child_tasks = mem::replace(&mut pic_state_for_children.tasks, Vec::new()); - let picture_task = RenderTask::new_picture( RenderTaskLocation::Dynamic(None, device_rect.size), unclipped.size, @@ -1148,16 +1160,14 @@ impl PicturePrimitive { let render_task_id = render_tasks.add(blur_render_task); - pic_state.tasks.push(render_task_id); + surfaces[surface_index.0].tasks.push(render_task_id); render_task_id } ); PictureSurface::TextureCache(cache_item) - }; - - surface_info.surface = Some(surface); + } } PictureCompositeMode::Filter(FilterOp::DropShadow(offset, blur_radius, color)) => { let blur_std_deviation = blur_radius * frame_context.device_pixel_scale.0; @@ -1188,7 +1198,7 @@ impl PicturePrimitive { unclipped.size, pic_index, device_rect.origin, - pic_state_for_children.tasks, + child_tasks, uv_rect_kind, pic_context.raster_spatial_node_index, ); @@ -1207,8 +1217,7 @@ impl PicturePrimitive { self.secondary_render_task_id = Some(picture_task_id); let render_task_id = frame_state.render_tasks.add(blur_render_task); - pic_state.tasks.push(render_task_id); - surface_info.surface = Some(PictureSurface::RenderTask(render_task_id)); + surfaces[surface_index.0].tasks.push(render_task_id); // If the local rect of the contents changed, force the cache handle // to be invalidated so that the primitive data below will get @@ -1245,6 +1254,8 @@ impl PicturePrimitive { request.push(shadow_rect); request.push([0.0, 0.0, 0.0, 0.0]); } + + PictureSurface::RenderTask(render_task_id) } PictureCompositeMode::MixBlend(..) => { let uv_rect_kind = calculate_uv_rect_kind( @@ -1259,7 +1270,7 @@ impl PicturePrimitive { unclipped.size, pic_index, clipped.origin, - pic_state_for_children.tasks, + child_tasks, uv_rect_kind, pic_context.raster_spatial_node_index, ); @@ -1269,11 +1280,11 @@ impl PicturePrimitive { ); self.secondary_render_task_id = Some(readback_task_id); - pic_state.tasks.push(readback_task_id); + surfaces[surface_index.0].tasks.push(readback_task_id); let render_task_id = frame_state.render_tasks.add(picture_task); - pic_state.tasks.push(render_task_id); - surface_info.surface = Some(PictureSurface::RenderTask(render_task_id)); + surfaces[surface_index.0].tasks.push(render_task_id); + PictureSurface::RenderTask(render_task_id) } PictureCompositeMode::Filter(filter) => { if let FilterOp::ColorMatrix(m) = filter { @@ -1296,14 +1307,14 @@ impl PicturePrimitive { unclipped.size, pic_index, clipped.origin, - pic_state_for_children.tasks, + child_tasks, uv_rect_kind, pic_context.raster_spatial_node_index, ); let render_task_id = frame_state.render_tasks.add(picture_task); - pic_state.tasks.push(render_task_id); - surface_info.surface = Some(PictureSurface::RenderTask(render_task_id)); + surfaces[surface_index.0].tasks.push(render_task_id); + PictureSurface::RenderTask(render_task_id) } PictureCompositeMode::Blit => { let uv_rect_kind = calculate_uv_rect_kind( @@ -1318,16 +1329,18 @@ impl PicturePrimitive { unclipped.size, pic_index, clipped.origin, - pic_state_for_children.tasks, + child_tasks, uv_rect_kind, pic_context.raster_spatial_node_index, ); let render_task_id = frame_state.render_tasks.add(picture_task); - pic_state.tasks.push(render_task_id); - surface_info.surface = Some(PictureSurface::RenderTask(render_task_id)); + surfaces[surface_index.0].tasks.push(render_task_id); + PictureSurface::RenderTask(render_task_id) } - } + }; + + surfaces[raster_config.surface_index.0].surface = Some(surface); true } diff --git a/gfx/webrender/src/prim_store.rs b/gfx/webrender/src/prim_store.rs index 3babf844a091..0c9134c322cf 100644 --- a/gfx/webrender/src/prim_store.rs +++ b/gfx/webrender/src/prim_store.rs @@ -22,7 +22,7 @@ use gpu_types::BrushFlags; use image::{self, Repetition}; use intern; use picture::{ClusterRange, PictureCompositeMode, PicturePrimitive, PictureUpdateContext}; -use picture::{PrimitiveList, SurfaceInfo}; +use picture::{PrimitiveList, SurfaceInfo, SurfaceIndex}; #[cfg(debug_assertions)] use render_backend::FrameId; use render_task::{BlitSource, RenderTask, RenderTaskCacheKey, RenderTaskTree, to_cache_size}; @@ -841,6 +841,7 @@ impl BrushSegment { clip_chain: Option<&ClipChainInstance>, prim_bounding_rect: WorldRect, root_spatial_node_index: SpatialNodeIndex, + surface_index: SurfaceIndex, pic_state: &mut PictureState, frame_context: &FrameBuildingContext, frame_state: &mut FrameBuildingState, @@ -879,7 +880,7 @@ impl BrushSegment { ); let clip_task_id = frame_state.render_tasks.add(clip_task); - pic_state.tasks.push(clip_task_id); + frame_state.surfaces[surface_index.0].tasks.push(clip_task_id); self.clip_task_id = BrushSegmentTaskId::RenderTaskId(clip_task_id); } None => { @@ -2095,6 +2096,7 @@ impl PrimitiveStore { pic_index, pic_context.surface_spatial_node_index, pic_context.raster_spatial_node_index, + pic_context.surface_index, pic_context.allow_subpixel_aa, frame_state, frame_context, @@ -2280,6 +2282,7 @@ impl PrimitiveStore { clipped_world_rect, pic_context.raster_spatial_node_index, &clip_chain, + pic_context.surface_index, pic_state, frame_context, frame_state, @@ -2304,6 +2307,7 @@ impl PrimitiveStore { pic_index, prim_instance, &prim_local_rect, + pic_context.surface_index, pic_state, frame_context, frame_state, @@ -2342,7 +2346,6 @@ impl PrimitiveStore { prim_instance.prepare_interned_prim_for_render( prim_context, pic_context, - pic_state, frame_context, frame_state, &mut self.text_runs, @@ -2355,6 +2358,7 @@ impl PrimitiveStore { prim_local_rect, prim_details, prim_context, + pic_context.surface_index, pic_state, frame_context, frame_state, @@ -2760,6 +2764,7 @@ impl PrimitiveInstance { prim_bounding_rect: WorldRect, prim_context: &PrimitiveContext, prim_clip_chain: &ClipChainInstance, + surface_index: SurfaceIndex, pic_state: &mut PictureState, frame_context: &FrameBuildingContext, frame_state: &mut FrameBuildingState, @@ -2809,6 +2814,7 @@ impl PrimitiveInstance { Some(prim_clip_chain), prim_bounding_rect, root_spatial_node_index, + surface_index, pic_state, frame_context, frame_state, @@ -2840,6 +2846,7 @@ impl PrimitiveInstance { segment_clip_chain.as_ref(), prim_bounding_rect, root_spatial_node_index, + surface_index, pic_state, frame_context, frame_state, @@ -2857,7 +2864,6 @@ impl PrimitiveInstance { &mut self, prim_context: &PrimitiveContext, pic_context: &PictureContext, - pic_state: &mut PictureState, frame_context: &FrameBuildingContext, frame_state: &mut FrameBuildingState, text_runs: &mut [TextRunPrimitive], @@ -2892,6 +2898,7 @@ impl PrimitiveInstance { // based on the current transform? let scale_factor = TypedScale::new(1.0) * frame_context.device_pixel_scale; let task_size = (LayoutSize::from_au(cache_key.size) * scale_factor).ceil().to_i32(); + let surfaces = &mut frame_state.surfaces; // Request a pre-rendered image task. // TODO(gw): This match is a bit untidy, but it should disappear completely @@ -2916,7 +2923,7 @@ impl PrimitiveInstance { LayoutSize::from_au(cache_key.size), ); let task_id = render_tasks.add(task); - pic_state.tasks.push(task_id); + surfaces[pic_context.surface_index.0].tasks.push(task_id); task_id } )); @@ -2975,6 +2982,7 @@ impl PrimitiveInstance { prim_local_rect: LayoutRect, prim_details: &mut PrimitiveDetails, prim_context: &PrimitiveContext, + surface_index: SurfaceIndex, pic_state: &mut PictureState, frame_context: &FrameBuildingContext, frame_state: &mut FrameBuildingState, @@ -3057,6 +3065,7 @@ impl PrimitiveInstance { request, texel_rect: sub_rect, }; + let surfaces = &mut frame_state.surfaces; // Request a pre-rendered image task. *handle = Some(frame_state.resource_cache.request_render_task( @@ -3095,7 +3104,7 @@ impl PrimitiveInstance { let target_to_cache_task_id = render_tasks.add(target_to_cache_task); // Hook this into the render task tree at the right spot. - pic_state.tasks.push(target_to_cache_task_id); + surfaces[surface_index.0].tasks.push(target_to_cache_task_id); // Pass the image opacity, so that the cached render task // item inherits the same opacity properties. @@ -3251,6 +3260,8 @@ impl PrimitiveInstance { // Update the cache key device size based on requested scale. segment.cache_key.size = to_cache_size(segment.local_task_size * scale); + let surfaces = &mut frame_state.surfaces; + segment.handle = Some(frame_state.resource_cache.request_render_task( segment.cache_key.clone(), frame_state.gpu_cache, @@ -3269,7 +3280,7 @@ impl PrimitiveInstance { let task_id = render_tasks.add(task); - pic_state.tasks.push(task_id); + surfaces[surface_index.0].tasks.push(task_id); task_id } @@ -3450,6 +3461,7 @@ impl PrimitiveInstance { prim_bounding_rect: WorldRect, root_spatial_node_index: SpatialNodeIndex, clip_chain: &ClipChainInstance, + surface_index: SurfaceIndex, pic_state: &mut PictureState, frame_context: &FrameBuildingContext, frame_state: &mut FrameBuildingState, @@ -3471,6 +3483,7 @@ impl PrimitiveInstance { prim_bounding_rect, prim_context, &clip_chain, + surface_index, pic_state, frame_context, frame_state, @@ -3508,7 +3521,7 @@ impl PrimitiveInstance { clip_task_id, device_rect); } self.clip_task_id = Some(clip_task_id); - pic_state.tasks.push(clip_task_id); + frame_state.surfaces[surface_index.0].tasks.push(clip_task_id); } } } diff --git a/gfx/webrender/src/render_task.rs b/gfx/webrender/src/render_task.rs index 1cc474fdd679..46780473ef34 100644 --- a/gfx/webrender/src/render_task.rs +++ b/gfx/webrender/src/render_task.rs @@ -1246,9 +1246,9 @@ impl RenderTaskCache { render_tasks: &mut RenderTaskTree, user_data: Option<[f32; 3]>, is_opaque: bool, - mut f: F, + f: F, ) -> Result - where F: FnMut(&mut RenderTaskTree) -> Result { + where F: FnOnce(&mut RenderTaskTree) -> Result { // Get the texture cache handle for this cache key, // or create one. let cache_entries = &mut self.cache_entries; diff --git a/gfx/webrender/src/resource_cache.rs b/gfx/webrender/src/resource_cache.rs index e45b7ee1d82e..058339b75811 100644 --- a/gfx/webrender/src/resource_cache.rs +++ b/gfx/webrender/src/resource_cache.rs @@ -483,8 +483,8 @@ impl ResourceCache { render_tasks: &mut RenderTaskTree, user_data: Option<[f32; 3]>, is_opaque: bool, - mut f: F, - ) -> RenderTaskCacheEntryHandle where F: FnMut(&mut RenderTaskTree) -> RenderTaskId { + f: F, + ) -> RenderTaskCacheEntryHandle where F: FnOnce(&mut RenderTaskTree) -> RenderTaskId { self.cached_render_tasks.request_render_task( key, &mut self.texture_cache, diff --git a/gfx/webrender_bindings/revision.txt b/gfx/webrender_bindings/revision.txt index aa17bbeed250..c89baecadd8d 100644 --- a/gfx/webrender_bindings/revision.txt +++ b/gfx/webrender_bindings/revision.txt @@ -1 +1 @@ -491476874195158449d209195c9fc429422f5d0c +790b76f1547453615262c3037e1fb04bda22fbc8