Bug 1548405 - Do all resource requests during visibility pass in WR. r=kvark
authorGlenn Watson <github@intuitionlibrary.com>
Thu, 02 May 2019 01:54:32 +0000
changeset 531043 ee9d68e93135dc540dfbee02c4f28c71cd0a127d
parent 531042 849b94e8913547d915ef4e54a0f0f2f479f579d0
child 531044 b035b8bb0f648fce4690472b794899f2622fab70
push id11265
push userffxbld-merge
push dateMon, 13 May 2019 10:53:39 +0000
treeherdermozilla-beta@77e0fe8dbdd3 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskvark
bugs1548405
milestone68.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1548405 - Do all resource requests during visibility pass in WR. r=kvark This builds on earlier patches to move all remaining resource requests to occur during the visibility pass, and change the block on glyph rasterization to occur after the visibility pass. This allows batch generation to occur during the prepare_prims pass, which is useful for generating a batch set per-dirty-region, while only doing a single pass of the picture / primitive tree. Differential Revision: https://phabricator.services.mozilla.com/D29584
gfx/wr/webrender/src/clip.rs
gfx/wr/webrender/src/frame_builder.rs
gfx/wr/webrender/src/prim_store/borders.rs
gfx/wr/webrender/src/prim_store/image.rs
gfx/wr/webrender/src/prim_store/mod.rs
--- a/gfx/wr/webrender/src/clip.rs
+++ b/gfx/wr/webrender/src/clip.rs
@@ -266,16 +266,17 @@ struct ClipNodeInfo {
 impl ClipNodeInfo {
     fn create_instance(
         &self,
         node: &ClipNode,
         clipped_rect: &LayoutRect,
         gpu_cache: &mut GpuCache,
         resource_cache: &mut ResourceCache,
         clip_scroll_tree: &ClipScrollTree,
+        request_resources: bool,
     ) -> ClipNodeInstance {
         // Calculate some flags that are required for the segment
         // building logic.
         let mut flags = match self.conversion {
             ClipSpaceConversion::Local => {
                 ClipNodeFlags::SAME_SPATIAL_NODE | ClipNodeFlags::SAME_COORD_SYSTEM
             }
             ClipSpaceConversion::ScaleOffset(..) => {
@@ -336,28 +337,30 @@ impl ClipNodeInfo {
                         };
                         let tiles = image::tiles(
                             &layout_image_rect,
                             &visible_rect,
                             &device_image_rect,
                             tile_size as i32,
                         );
                         for tile in tiles {
-                            resource_cache.request_image(
-                                request.with_tile(tile.offset),
-                                gpu_cache,
-                            );
+                            if request_resources {
+                                resource_cache.request_image(
+                                    request.with_tile(tile.offset),
+                                    gpu_cache,
+                                );
+                            }
                             mask_tiles.push(VisibleMaskImageTile {
                                 tile_offset: tile.offset,
                                 tile_rect: tile.rect,
                             });
                         }
                     }
                     visible_tiles = Some(mask_tiles);
-                } else {
+                } else if request_resources {
                     resource_cache.request_image(request, gpu_cache);
                 }
             }
         }
 
         ClipNodeInstance {
             handle: self.handle,
             flags,
@@ -584,16 +587,17 @@ impl ClipStore {
         prim_to_pic_mapper: &SpaceMapper<LayoutPixel, PicturePixel>,
         pic_to_world_mapper: &SpaceMapper<PicturePixel, WorldPixel>,
         clip_scroll_tree: &ClipScrollTree,
         gpu_cache: &mut GpuCache,
         resource_cache: &mut ResourceCache,
         device_pixel_scale: DevicePixelScale,
         world_rect: &WorldRect,
         clip_data_store: &mut ClipDataStore,
+        request_resources: bool,
     ) -> Option<ClipChainInstance> {
         let mut local_clip_rect = local_prim_clip_rect;
 
         // Walk the clip chain to build local rects, and collect the
         // smallest possible local/device clip area.
 
         self.clip_node_info.clear();
 
@@ -675,16 +679,17 @@ impl ClipStore {
 
                     // Create the clip node instance for this clip node
                     let instance = node_info.create_instance(
                         node,
                         &local_bounding_rect,
                         gpu_cache,
                         resource_cache,
                         clip_scroll_tree,
+                        request_resources,
                     );
 
                     // As a special case, a partial accept of a clip rect that is
                     // in the same coordinate system as the primitive doesn't need
                     // a clip mask. Instead, it can be handled by the primitive
                     // vertex shader as part of the local clip rect. This is an
                     // important optimization for reducing the number of clip
                     // masks that are allocated on common pages.
--- a/gfx/wr/webrender/src/frame_builder.rs
+++ b/gfx/wr/webrender/src/frame_builder.rs
@@ -306,16 +306,17 @@ impl FrameBuilder {
         profile_counters: &mut FrameProfileCounters,
         global_device_pixel_scale: DevicePixelScale,
         scene_properties: &SceneProperties,
         transform_palette: &mut TransformPalette,
         data_stores: &mut DataStores,
         surfaces: &mut Vec<SurfaceInfo>,
         scratch: &mut PrimitiveScratchBuffer,
         debug_flags: DebugFlags,
+        texture_cache_profile: &mut TextureCacheProfileCounters,
     ) -> Option<RenderTaskId> {
         profile_scope!("cull");
 
         if self.prim_store.pictures.is_empty() {
             return None
         }
 
         scratch.begin_frame();
@@ -401,16 +402,24 @@ impl FrameBuilder {
             self.prim_store.update_visibility(
                 self.root_pic_index,
                 ROOT_SURFACE_INDEX,
                 &visibility_context,
                 &mut visibility_state,
             );
         }
 
+        {
+            profile_marker!("BlockOnResources");
+
+            resource_cache.block_until_all_resources_added(gpu_cache,
+                                                           render_tasks,
+                                                           texture_cache_profile);
+        }
+
         let mut frame_state = FrameBuildingState {
             render_tasks,
             profile_counters,
             clip_store: &mut self.clip_store,
             resource_cache,
             gpu_cache,
             transforms: transform_palette,
             segment_builder: SegmentBuilder::new(),
@@ -548,26 +557,19 @@ impl FrameBuilder {
             &mut profile_counters,
             global_device_pixel_scale,
             scene_properties,
             &mut transform_palette,
             data_stores,
             &mut surfaces,
             scratch,
             debug_flags,
+            texture_cache_profile,
         );
 
-        {
-            profile_marker!("BlockOnResources");
-
-            resource_cache.block_until_all_resources_added(gpu_cache,
-                                                           &mut render_tasks,
-                                                           texture_cache_profile);
-        }
-
         let mut passes;
         let mut deferred_resolves = vec![];
         let mut has_texture_cache_tasks = false;
         let mut prim_headers = PrimitiveHeaders::new();
 
         {
             profile_marker!("Batching");
 
--- a/gfx/wr/webrender/src/prim_store/borders.rs
+++ b/gfx/wr/webrender/src/prim_store/borders.rs
@@ -3,26 +3,26 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 use api::{NormalBorder, PremultipliedColorF, Shadow};
 use api::units::*;
 use border::create_border_segments;
 use border::NormalBorderAu;
 use display_list_flattener::{CreateShadow, IsVisible};
 use frame_builder::{FrameBuildingState};
-use gpu_cache::GpuDataRequest;
+use gpu_cache::{GpuCache, GpuDataRequest};
 use intern;
 use internal_types::LayoutPrimitiveInfo;
 use prim_store::{
     BorderSegmentInfo, BrushSegment, NinePatchDescriptor, PrimKey,
     PrimKeyCommonData, PrimTemplate, PrimTemplateCommonData,
     PrimitiveInstanceKind, PrimitiveOpacity, PrimitiveSceneData,
     PrimitiveStore, InternablePrimitive,
 };
-use resource_cache::ImageRequest;
+use resource_cache::{ImageRequest, ResourceCache};
 use storage;
 
 #[cfg_attr(feature = "capture", derive(Serialize))]
 #[cfg_attr(feature = "replay", derive(Deserialize))]
 #[derive(Debug, Clone, Eq, MallocSizeOf, PartialEq, Hash)]
 pub struct NormalBorderPrim {
     pub border: NormalBorderAu,
     pub widths: LayoutSideOffsetsAu,
@@ -243,28 +243,35 @@ impl ImageBorderData {
             self.write_segment_gpu_blocks(request);
         }
 
         let image_properties = frame_state
             .resource_cache
             .get_image_properties(self.request.key);
 
         common.opacity = if let Some(image_properties) = image_properties {
-            frame_state.resource_cache.request_image(
-                self.request,
-                frame_state.gpu_cache,
-            );
             PrimitiveOpacity {
                 is_opaque: image_properties.descriptor.is_opaque,
             }
         } else {
             PrimitiveOpacity::opaque()
         }
     }
 
+    pub fn request_resources(
+        &mut self,
+        resource_cache: &mut ResourceCache,
+        gpu_cache: &mut GpuCache,
+    ) {
+        resource_cache.request_image(
+            self.request,
+            gpu_cache,
+        );
+    }
+
     fn write_prim_gpu_blocks(
         &self,
         request: &mut GpuDataRequest,
         prim_size: &LayoutSize,
     ) {
         // Border primitives currently used for
         // image borders, and run through the
         // normal brush_image shader.
--- a/gfx/wr/webrender/src/prim_store/image.rs
+++ b/gfx/wr/webrender/src/prim_store/image.rs
@@ -5,30 +5,30 @@
 use api::{
     AlphaType, ColorDepth, ColorF, ColorU,
     ImageKey as ApiImageKey, ImageRendering,
     PremultipliedColorF, Shadow, YuvColorSpace, YuvFormat,
 };
 use api::units::*;
 use display_list_flattener::{CreateShadow, IsVisible};
 use frame_builder::FrameBuildingState;
-use gpu_cache::{GpuDataRequest};
+use gpu_cache::{GpuCache, GpuDataRequest};
 use intern::{Internable, InternDebug, Handle as InternHandle};
 use internal_types::LayoutPrimitiveInfo;
 use prim_store::{
     EdgeAaSegmentMask, OpacityBindingIndex, PrimitiveInstanceKind,
     PrimitiveOpacity, PrimitiveSceneData, PrimKey, PrimKeyCommonData,
     PrimTemplate, PrimTemplateCommonData, PrimitiveStore, SegmentInstanceIndex,
     SizeKey, InternablePrimitive,
 };
 use render_task::{
     BlitSource, RenderTask, RenderTaskCacheEntryHandle, RenderTaskCacheKey,
     RenderTaskCacheKeyKind
 };
-use resource_cache::ImageRequest;
+use resource_cache::{ImageRequest, ResourceCache};
 use util::pack_as_float;
 
 #[derive(Debug)]
 #[cfg_attr(feature = "capture", derive(Serialize))]
 #[cfg_attr(feature = "replay", derive(Deserialize))]
 pub struct VisibleImageTile {
     pub tile_offset: TileOffset,
     pub edge_flags: EdgeAaSegmentMask,
@@ -183,17 +183,16 @@ impl ImageData {
                         debug_assert!(!is_tiled);
                         self.source = ImageSource::Cache {
                             // Size in device-pixels we need to allocate in render task cache.
                             size: rect.size,
                             handle: None,
                         };
                     }
 
-                    let mut request_source_image = false;
                     let mut is_opaque = image_properties.descriptor.is_opaque;
                     let request = ImageRequest {
                         key: self.key,
                         rendering: self.image_rendering,
                         tile: None,
                     };
 
                     // Every frame, for cached items, we need to request the render
@@ -226,20 +225,16 @@ impl ImageData {
                                     size: *size,
                                     kind: RenderTaskCacheKeyKind::Image(image_cache_key),
                                 },
                                 frame_state.gpu_cache,
                                 frame_state.render_tasks,
                                 None,
                                 image_properties.descriptor.is_opaque,
                                 |render_tasks| {
-                                    // We need to render the image cache this frame,
-                                    // so will need access to the source texture.
-                                    request_source_image = true;
-
                                     // Create a task to blit from the texture cache to
                                     // a normal transient render task surface. This will
                                     // copy only the sub-rect, if specified.
                                     let cache_to_target_task = RenderTask::new_blit_with_padding(
                                         inner_size,
                                         &padding,
                                         BlitSource::Image { key: image_cache_key },
                                     );
@@ -254,27 +249,17 @@ impl ImageData {
                                             task_id: cache_to_target_task_id,
                                         },
                                     );
 
                                     render_tasks.add(target_to_cache_task)
                                 }
                             ));
                         }
-                        ImageSource::Default => {
-                            // Normal images just reference the source texture each frame.
-                            request_source_image = true;
-                        }
-                    }
-
-                    if request_source_image && !is_tiled {
-                        frame_state.resource_cache.request_image(
-                            request,
-                            frame_state.gpu_cache,
-                        );
+                        ImageSource::Default => {}
                     }
 
                     if is_opaque {
                         PrimitiveOpacity::from_alpha(self.color.a)
                     } else {
                         PrimitiveOpacity::translucent()
                     }
                 }
@@ -441,30 +426,36 @@ impl YuvImageData {
         &mut self,
         common: &mut PrimTemplateCommonData,
         frame_state: &mut FrameBuildingState,
     ) {
         if let Some(mut request) = frame_state.gpu_cache.request(&mut common.gpu_cache_handle) {
             self.write_prim_gpu_blocks(&mut request);
         };
 
+        common.opacity = PrimitiveOpacity::translucent();
+    }
+
+    pub fn request_resources(
+        &mut self,
+        resource_cache: &mut ResourceCache,
+        gpu_cache: &mut GpuCache,
+    ) {
         let channel_num = self.format.get_plane_num();
         debug_assert!(channel_num <= 3);
         for channel in 0 .. channel_num {
-            frame_state.resource_cache.request_image(
+            resource_cache.request_image(
                 ImageRequest {
                     key: self.yuv_key[channel],
                     rendering: self.image_rendering,
                     tile: None,
                 },
-                frame_state.gpu_cache,
+                gpu_cache,
             );
         }
-
-        common.opacity = PrimitiveOpacity::translucent();
     }
 
     pub fn write_prim_gpu_blocks(&self, request: &mut GpuDataRequest) {
         request.push([
             self.color_depth.rescaling_factor(),
             pack_as_float(self.color_space as u32),
             pack_as_float(self.format as u32),
             0.0
--- a/gfx/wr/webrender/src/prim_store/mod.rs
+++ b/gfx/wr/webrender/src/prim_store/mod.rs
@@ -1926,16 +1926,17 @@ impl PrimitiveStore {
                         &map_local_to_surface,
                         &map_surface_to_world,
                         &frame_context.clip_scroll_tree,
                         frame_state.gpu_cache,
                         frame_state.resource_cache,
                         surface.device_pixel_scale,
                         &frame_context.screen_world_rect,
                         &mut frame_state.data_stores.clip,
+                        true,
                     );
 
                 // Ensure the primitive clip is popped
                 frame_state.clip_chain_stack.pop_clip();
 
                 let clip_chain = match clip_chain {
                     Some(clip_chain) => clip_chain,
                     None => {
@@ -2004,27 +2005,27 @@ impl PrimitiveStore {
                     PrimitiveVisibility {
                         clipped_world_rect,
                         clip_chain,
                         clip_task_index: ClipTaskIndex::INVALID,
                         combined_local_clip_rect,
                     }
                 );
 
+                prim_instance.visibility_info = vis_index;
+
                 self.request_resources_for_prim(
                     prim_instance,
                     surface,
                     raster_space,
+                    &map_local_to_surface,
                     frame_context,
                     frame_state,
                 );
-
-                prim_instance.visibility_info = vis_index;
             }
-
         }
 
         let pic = &mut self.pictures[pic_index.0];
 
         if let Some(RasterConfig { composite_mode: PictureCompositeMode::TileCache { .. }, .. }) = pic.raster_config {
             let mut tile_cache = frame_state.tile_cache.take().unwrap();
 
             // Build the dirty region(s) for this tile cache.
@@ -2038,19 +2039,20 @@ impl PrimitiveStore {
             pic.tile_cache = Some(tile_cache);
         }
 
         pic.prim_list = prim_list;
     }
 
     fn request_resources_for_prim(
         &mut self,
-        prim_instance: &PrimitiveInstance,
+        prim_instance: &mut PrimitiveInstance,
         surface: &SurfaceInfo,
         raster_space: RasterSpace,
+        map_local_to_surface: &SpaceMapper<LayoutPixel, PicturePixel>,
         frame_context: &FrameVisibilityContext,
         frame_state: &mut FrameVisibilityState,
     ) {
         match prim_instance.kind {
             PrimitiveInstanceKind::TextRun { data_handle, run_index, .. } => {
                 let prim_data = &mut frame_state.data_stores.text_run[data_handle];
                 let run = &mut self.text_runs[run_index];
 
@@ -2071,16 +2073,123 @@ impl PrimitiveStore {
                     surface,
                     raster_space,
                     frame_state.resource_cache,
                     frame_state.gpu_cache,
                     frame_state.render_tasks,
                     frame_state.scratch,
                 );
             }
+            PrimitiveInstanceKind::Image { data_handle, image_instance_index, .. } => {
+                let prim_data = &mut frame_state.data_stores.image[data_handle];
+                let common_data = &mut prim_data.common;
+                let image_data = &mut prim_data.kind;
+                let image_instance = &mut self.images[image_instance_index];
+
+                let image_properties = frame_state
+                    .resource_cache
+                    .get_image_properties(image_data.key);
+
+                let request = ImageRequest {
+                    key: image_data.key,
+                    rendering: image_data.image_rendering,
+                    tile: None,
+                };
+
+                match image_properties {
+                    Some(ImageProperties { tiling: None, .. }) => {
+                        frame_state.resource_cache.request_image(
+                            request,
+                            frame_state.gpu_cache,
+                        );
+                    }
+                    Some(ImageProperties { descriptor, tiling: Some(tile_size), .. }) => {
+                        image_instance.visible_tiles.clear();
+                        let device_image_rect = DeviceIntRect::from_size(descriptor.size);
+
+                        // Tighten the clip rect because decomposing the repeated image can
+                        // produce primitives that are partially covering the original image
+                        // rect and we want to clip these extra parts out.
+                        let prim_info = &frame_state.scratch.prim_info[prim_instance.visibility_info.0 as usize];
+                        let prim_rect = LayoutRect::new(
+                            prim_instance.prim_origin,
+                            common_data.prim_size,
+                        );
+                        let tight_clip_rect = prim_info
+                            .combined_local_clip_rect
+                            .intersection(&prim_rect).unwrap();
+                        image_instance.tight_local_clip_rect = tight_clip_rect;
+
+                        let visible_rect = compute_conservative_visible_rect(
+                            &tight_clip_rect,
+                            map_local_to_surface,
+                        );
+
+                        let base_edge_flags = edge_flags_for_tile_spacing(&image_data.tile_spacing);
+
+                        let stride = image_data.stretch_size + image_data.tile_spacing;
+
+                        let repetitions = ::image::repetitions(
+                            &prim_rect,
+                            &visible_rect,
+                            stride,
+                        );
+
+                        for Repetition { origin, edge_flags } in repetitions {
+                            let edge_flags = base_edge_flags | edge_flags;
+
+                            let layout_image_rect = LayoutRect {
+                                origin,
+                                size: image_data.stretch_size,
+                            };
+
+                            let tiles = ::image::tiles(
+                                &layout_image_rect,
+                                &visible_rect,
+                                &device_image_rect,
+                                tile_size as i32,
+                            );
+
+                            for tile in tiles {
+                                frame_state.resource_cache.request_image(
+                                    request.with_tile(tile.offset),
+                                    frame_state.gpu_cache,
+                                );
+
+                                image_instance.visible_tiles.push(VisibleImageTile {
+                                    tile_offset: tile.offset,
+                                    edge_flags: tile.edge_flags & edge_flags,
+                                    local_rect: tile.rect,
+                                    local_clip_rect: tight_clip_rect,
+                                });
+                            }
+                        }
+
+                        if image_instance.visible_tiles.is_empty() {
+                            // Mark as invisible
+                            prim_instance.visibility_info = PrimitiveVisibilityIndex::INVALID;
+                        }
+                    }
+                    None => {}
+                }
+            }
+            PrimitiveInstanceKind::ImageBorder { data_handle, .. } => {
+                let prim_data = &mut frame_state.data_stores.image_border[data_handle];
+                prim_data.kind.request_resources(
+                    frame_state.resource_cache,
+                    frame_state.gpu_cache,
+                );
+            }
+            PrimitiveInstanceKind::YuvImage { data_handle, .. } => {
+                let prim_data = &mut frame_state.data_stores.yuv_image[data_handle];
+                prim_data.kind.request_resources(
+                    frame_state.resource_cache,
+                    frame_state.gpu_cache,
+                );
+            }
             _ => {}
         }
     }
 
     pub fn get_opacity_binding(
         &self,
         opacity_binding_index: OpacityBindingIndex,
     ) -> f32 {
@@ -2704,95 +2813,16 @@ impl PrimitiveStore {
                 let image_instance = &mut self.images[*image_instance_index];
 
                 update_opacity_binding(
                     &mut self.opacity_bindings,
                     image_instance.opacity_binding_index,
                     frame_context.scene_properties,
                 );
 
-                image_instance.visible_tiles.clear();
-
-                let image_properties = frame_state
-                    .resource_cache
-                    .get_image_properties(image_data.key);
-
-                if let Some(ImageProperties { descriptor, tiling: Some(tile_size), .. }) = image_properties {
-                    let device_image_rect = DeviceIntRect::from_size(descriptor.size);
-
-                    // Tighten the clip rect because decomposing the repeated image can
-                    // produce primitives that are partially covering the original image
-                    // rect and we want to clip these extra parts out.
-                    let prim_info = &scratch.prim_info[prim_instance.visibility_info.0 as usize];
-                    let prim_rect = LayoutRect::new(
-                        prim_instance.prim_origin,
-                        common_data.prim_size,
-                    );
-                    let tight_clip_rect = prim_info
-                        .combined_local_clip_rect
-                        .intersection(&prim_rect).unwrap();
-                    image_instance.tight_local_clip_rect = tight_clip_rect;
-
-                    let visible_rect = compute_conservative_visible_rect(
-                        &tight_clip_rect,
-                        &pic_state.map_local_to_pic,
-                    );
-
-                    let base_edge_flags = edge_flags_for_tile_spacing(&image_data.tile_spacing);
-
-                    let stride = image_data.stretch_size + image_data.tile_spacing;
-
-                    let repetitions = ::image::repetitions(
-                        &prim_rect,
-                        &visible_rect,
-                        stride,
-                    );
-
-                    let request = ImageRequest {
-                        key: image_data.key,
-                        rendering: image_data.image_rendering,
-                        tile: None,
-                    };
-
-                    for Repetition { origin, edge_flags } in repetitions {
-                        let edge_flags = base_edge_flags | edge_flags;
-
-                        let layout_image_rect = LayoutRect {
-                            origin,
-                            size: image_data.stretch_size,
-                        };
-
-                        let tiles = ::image::tiles(
-                            &layout_image_rect,
-                            &visible_rect,
-                            &device_image_rect,
-                            tile_size as i32,
-                        );
-
-                        for tile in tiles {
-                            frame_state.resource_cache.request_image(
-                                request.with_tile(tile.offset),
-                                frame_state.gpu_cache,
-                            );
-
-                            image_instance.visible_tiles.push(VisibleImageTile {
-                                tile_offset: tile.offset,
-                                edge_flags: tile.edge_flags & edge_flags,
-                                local_rect: tile.rect,
-                                local_clip_rect: tight_clip_rect,
-                            });
-                        }
-                    }
-
-                    if image_instance.visible_tiles.is_empty() {
-                        // Mark as invisible
-                        prim_instance.visibility_info = PrimitiveVisibilityIndex::INVALID;
-                    }
-                }
-
                 write_segment(
                     image_instance.segment_instance_index,
                     frame_state,
                     &mut scratch.segments,
                     &mut scratch.segment_instances,
                     |request| {
                         image_data.write_prim_gpu_blocks(request);
                     },
@@ -3477,16 +3507,17 @@ impl PrimitiveInstance {
                         &pic_state.map_local_to_pic,
                         &pic_state.map_pic_to_world,
                         &frame_context.clip_scroll_tree,
                         frame_state.gpu_cache,
                         frame_state.resource_cache,
                         device_pixel_scale,
                         &dirty_world_rect,
                         &mut data_stores.clip,
+                        false,
                     );
 
                 let clip_mask_kind = segment.update_clip_task(
                     segment_clip_chain.as_ref(),
                     prim_info.clipped_world_rect,
                     root_spatial_node_index,
                     pic_context.surface_index,
                     pic_state,