From 3a51eac38e611f45b60dce056f968483ae831fb5 Mon Sep 17 00:00:00 2001 From: Nicolas Silva Date: Tue, 17 Sep 2019 09:20:03 +0000 Subject: [PATCH] Bug 1581058 - Rename a lot of scene building related structures. r=gw Differential Revision: https://phabricator.services.mozilla.com/D45853 --HG-- rename : gfx/wr/webrender/src/display_list_flattener.rs => gfx/wr/webrender/src/scene_building.rs extra : moz-landing-system : lando --- gfx/wr/webrender/src/border.rs | 4 +- gfx/wr/webrender/src/box_shadow.rs | 4 +- gfx/wr/webrender/src/frame_builder.rs | 200 +++++------------- gfx/wr/webrender/src/lib.rs | 2 +- gfx/wr/webrender/src/prim_store/borders.rs | 2 +- gfx/wr/webrender/src/prim_store/gradient.rs | 2 +- gfx/wr/webrender/src/prim_store/image.rs | 2 +- gfx/wr/webrender/src/prim_store/line_dec.rs | 2 +- gfx/wr/webrender/src/prim_store/mod.rs | 6 +- gfx/wr/webrender/src/prim_store/picture.rs | 2 +- gfx/wr/webrender/src/prim_store/text_run.rs | 2 +- gfx/wr/webrender/src/render_backend.rs | 154 ++++++-------- gfx/wr/webrender/src/scene.rs | 90 +++++++- gfx/wr/webrender/src/scene_builder_thread.rs | 75 ++----- ...ay_list_flattener.rs => scene_building.rs} | 84 ++++---- 15 files changed, 275 insertions(+), 356 deletions(-) rename gfx/wr/webrender/src/{display_list_flattener.rs => scene_building.rs} (98%) diff --git a/gfx/wr/webrender/src/border.rs b/gfx/wr/webrender/src/border.rs index a277ee427ddb..d3c4bab55020 100644 --- a/gfx/wr/webrender/src/border.rs +++ b/gfx/wr/webrender/src/border.rs @@ -7,7 +7,7 @@ use api::{NormalBorder as ApiNormalBorder, RepeatMode}; use api::units::*; use crate::ellipse::Ellipse; use euclid::vec2; -use crate::display_list_flattener::DisplayListFlattener; +use crate::scene_building::SceneBuilder; use crate::gpu_types::{BorderInstance, BorderSegment, BrushFlags}; use crate::prim_store::{BorderSegmentInfo, BrushSegment, NinePatchDescriptor}; use crate::prim_store::{EdgeAaSegmentMask, ScrollNodeAndClipChain}; @@ -208,7 +208,7 @@ pub fn ensure_no_corner_overlap( } } -impl<'a> DisplayListFlattener<'a> { +impl<'a> SceneBuilder<'a> { pub fn add_normal_border( &mut self, info: &LayoutPrimitiveInfo, diff --git a/gfx/wr/webrender/src/box_shadow.rs b/gfx/wr/webrender/src/box_shadow.rs index a95340b26514..124d44d5de38 100644 --- a/gfx/wr/webrender/src/box_shadow.rs +++ b/gfx/wr/webrender/src/box_shadow.rs @@ -6,7 +6,7 @@ use api::{BorderRadius, BoxShadowClipMode, ClipMode, ColorF, PrimitiveKeyKind}; use api::MAX_BLUR_RADIUS; use api::units::*; use crate::clip::{ClipItemKey, ClipItemKeyKind}; -use crate::display_list_flattener::DisplayListFlattener; +use crate::scene_building::SceneBuilder; use crate::gpu_cache::GpuCacheHandle; use crate::gpu_types::BoxShadowStretchMode; use crate::prim_store::ScrollNodeAndClipChain; @@ -68,7 +68,7 @@ pub struct BoxShadowCacheKey { pub br_bottom_left: DeviceIntSize, } -impl<'a> DisplayListFlattener<'a> { +impl<'a> SceneBuilder<'a> { pub fn add_box_shadow( &mut self, clip_and_scroll: ScrollNodeAndClipChain, diff --git a/gfx/wr/webrender/src/frame_builder.rs b/gfx/wr/webrender/src/frame_builder.rs index 8bb045ed2745..8077cd1dfeaa 100644 --- a/gfx/wr/webrender/src/frame_builder.rs +++ b/gfx/wr/webrender/src/frame_builder.rs @@ -6,23 +6,17 @@ use api::{ColorF, DebugFlags, DocumentLayer, FontRenderMode, PremultipliedColorF use api::{PipelineId}; use api::units::*; use crate::batch::{BatchBuilder, AlphaBatchBuilder, AlphaBatchContainer}; -use crate::clip::{ClipDataStore, ClipStore, ClipChainStack}; +use crate::clip::{ClipStore, ClipChainStack}; use crate::clip_scroll_tree::{ClipScrollTree, ROOT_SPATIAL_NODE_INDEX, SpatialNodeIndex}; use crate::debug_render::DebugItem; -use crate::display_list_flattener::{DisplayListFlattener}; use crate::gpu_cache::{GpuCache, GpuCacheHandle}; use crate::gpu_types::{PrimitiveHeaders, TransformPalette, UvRectKind, ZBufferIdGenerator}; use crate::gpu_types::TransformData; -use crate::hit_test::{HitTester, HitTestingScene}; -#[cfg(feature = "replay")] -use crate::hit_test::HitTestingSceneStats; use crate::internal_types::{FastHashMap, PlaneSplitter, SavedTargetIndex}; use crate::picture::{PictureUpdateState, SurfaceInfo, ROOT_SURFACE_INDEX, SurfaceIndex, RecordedDirtyRegion}; use crate::picture::{RetainedTiles, TileCacheInstance, DirtyRegion, SurfaceRenderTasks, SubpixelMode}; -use crate::prim_store::{PrimitiveStore, SpaceMapper, PictureIndex, PrimitiveDebugId, PrimitiveScratchBuffer}; +use crate::prim_store::{SpaceMapper, PictureIndex, PrimitiveDebugId, PrimitiveScratchBuffer}; use crate::prim_store::{DeferredResolve, PrimitiveVisibilityMask}; -#[cfg(feature = "replay")] -use crate::prim_store::{PrimitiveStoreStats}; use crate::profiler::{FrameProfileCounters, GpuCacheProfileCounters, TextureCacheProfileCounters}; use crate::render_backend::{DataStores, FrameStamp, FrameId}; use crate::render_target::{RenderTarget, PictureCacheTarget, TextureCacheRenderTarget}; @@ -31,8 +25,7 @@ use crate::render_task_graph::{RenderTaskId, RenderTaskGraph, RenderTaskGraphCou use crate::render_task_graph::{RenderPassKind, RenderPass}; use crate::render_task::{RenderTask, RenderTaskLocation, RenderTaskKind}; use crate::resource_cache::{ResourceCache}; -use crate::scene::{ScenePipeline, SceneProperties}; -use crate::scene_builder_thread::DocumentStats; +use crate::scene::{BuiltScene, ScenePipeline, SceneProperties}; use crate::segment::SegmentBuilder; use std::{f32, mem}; use std::sync::Arc; @@ -106,20 +99,12 @@ impl FrameGlobalResources { } } -/// A builder structure for `render_task_graph::Frame` +/// Produces the frames that are sent to the renderer. #[cfg_attr(feature = "capture", derive(Serialize))] pub struct FrameBuilder { - output_rect: DeviceIntRect, - background_color: Option, - root_pic_index: PictureIndex, /// Cache of surface tiles from the previous frame builder /// that can optionally be consumed by this frame builder. pending_retained_tiles: RetainedTiles, - pub prim_store: PrimitiveStore, - pub clip_store: ClipStore, - #[cfg_attr(feature = "capture", serde(skip))] //TODO - pub hit_testing_scene: Arc, - pub config: FrameBuilderConfig, pub globals: FrameGlobalResources, } @@ -212,82 +197,17 @@ pub struct PictureState { } impl FrameBuilder { - #[cfg(feature = "replay")] - pub fn empty() -> Self { + pub fn new() -> Self { FrameBuilder { - hit_testing_scene: Arc::new(HitTestingScene::new(&HitTestingSceneStats::empty())), - prim_store: PrimitiveStore::new(&PrimitiveStoreStats::empty()), - clip_store: ClipStore::new(), - output_rect: DeviceIntRect::zero(), - background_color: None, - root_pic_index: PictureIndex(0), pending_retained_tiles: RetainedTiles::new(), globals: FrameGlobalResources::empty(), - config: FrameBuilderConfig { - default_font_render_mode: FontRenderMode::Mono, - dual_source_blending_is_enabled: true, - dual_source_blending_is_supported: false, - chase_primitive: ChasePrimitive::Nothing, - enable_picture_caching: false, - testing: false, - gpu_supports_fast_clears: false, - gpu_supports_advanced_blend: false, - advanced_blend_is_coherent: false, - batch_lookback_count: 0, - background_color: None, - }, } } /// Provide any cached surface tiles from the previous frame builder /// to a new frame builder. These will be consumed or dropped the /// first time a new frame builder creates a frame. - pub fn set_retained_resources( - &mut self, - retained_tiles: RetainedTiles, - globals: FrameGlobalResources, - ) { - assert!(self.pending_retained_tiles.caches.is_empty()); - self.pending_retained_tiles = retained_tiles; - self.globals = globals; - } - - pub fn with_display_list_flattener( - output_rect: DeviceIntRect, - background_color: Option, - flattener: DisplayListFlattener, - ) -> Self { - FrameBuilder { - hit_testing_scene: Arc::new(flattener.hit_testing_scene), - prim_store: flattener.prim_store, - clip_store: flattener.clip_store, - root_pic_index: flattener.root_pic_index, - output_rect, - background_color, - pending_retained_tiles: RetainedTiles::new(), - config: flattener.config, - globals: FrameGlobalResources::empty(), - } - } - - /// Get the memory usage statistics to pre-allocate for the next scene. - pub fn get_stats(&self) -> DocumentStats { - DocumentStats { - prim_store_stats: self.prim_store.get_stats(), - hit_test_stats: self.hit_testing_scene.get_stats(), - } - } - - /// Destroy an existing frame builder. This is called just before - /// a frame builder is replaced with a newly built scene. - pub fn destroy( - self, - retained_tiles: &mut RetainedTiles, - ) -> FrameGlobalResources { - self.prim_store.destroy( - retained_tiles, - ); - + pub fn set_retained_resources(&mut self, retained_tiles: RetainedTiles) { // In general, the pending retained tiles are consumed by the frame // builder the first time a frame is built after a new scene has // arrived. However, if two scenes arrive in quick succession, the @@ -296,18 +216,15 @@ impl FrameBuilder { // be lost, causing a full invalidation of the entire screen. To // avoid this, if there are still pending tiles, include them in // the retained tiles passed to the next frame builder. - retained_tiles.merge(self.pending_retained_tiles); - - self.globals + self.pending_retained_tiles.merge(retained_tiles); } /// Compute the contribution (bounding rectangles, and resources) of layers and their /// primitives in screen space. fn build_layer_screen_rects_and_cull_layers( &mut self, + scene: &mut BuiltScene, global_screen_world_rect: WorldRect, - clip_scroll_tree: &ClipScrollTree, - pipelines: &FastHashMap>, resource_cache: &mut ResourceCache, gpu_cache: &mut GpuCache, render_tasks: &mut RenderTaskGraph, @@ -323,34 +240,34 @@ impl FrameBuilder { ) -> Option { profile_scope!("cull"); - if self.prim_store.pictures.is_empty() { + if scene.prim_store.pictures.is_empty() { return None } scratch.begin_frame(); - let root_spatial_node_index = clip_scroll_tree.root_reference_frame_index(); + let root_spatial_node_index = scene.clip_scroll_tree.root_reference_frame_index(); const MAX_CLIP_COORD: f32 = 1.0e9; let frame_context = FrameBuildingContext { global_device_pixel_scale, scene_properties, - pipelines, + pipelines: &scene.src.pipelines, global_screen_world_rect, - clip_scroll_tree, + clip_scroll_tree: &scene.clip_scroll_tree, max_local_clip: LayoutRect::new( LayoutPoint::new(-MAX_CLIP_COORD, -MAX_CLIP_COORD), LayoutSize::new(2.0 * MAX_CLIP_COORD, 2.0 * MAX_CLIP_COORD), ), debug_flags, - fb_config: &self.config, + fb_config: &scene.config, }; let root_render_task = RenderTask::new_picture( - RenderTaskLocation::Fixed(self.output_rect), - self.output_rect.size.to_f32(), - self.root_pic_index, + RenderTaskLocation::Fixed(scene.output_rect), + scene.output_rect.size.to_f32(), + scene.root_pic_index, DeviceIntPoint::zero(), UvRectKind::Rect, ROOT_SPATIAL_NODE_INDEX, @@ -368,7 +285,7 @@ impl FrameBuilder { ROOT_SPATIAL_NODE_INDEX, 0.0, global_screen_world_rect, - clip_scroll_tree, + &scene.clip_scroll_tree, global_device_pixel_scale, ); surfaces.push(root_surface); @@ -387,11 +304,11 @@ impl FrameBuilder { // be rendered this frame. PictureUpdateState::update_all( surfaces, - self.root_pic_index, - &mut self.prim_store.pictures, + scene.root_pic_index, + &mut scene.prim_store.pictures, &frame_context, gpu_cache, - &self.clip_store, + &scene.clip_store, data_stores, ); @@ -400,18 +317,18 @@ impl FrameBuilder { let visibility_context = FrameVisibilityContext { global_device_pixel_scale, - clip_scroll_tree, + clip_scroll_tree: &scene.clip_scroll_tree, global_screen_world_rect, surfaces, debug_flags, scene_properties, - config: &self.config, + config: &scene.config, }; let mut visibility_state = FrameVisibilityState { resource_cache, gpu_cache, - clip_store: &mut self.clip_store, + clip_store: &mut scene.clip_store, scratch, tile_cache: None, retained_tiles: &mut retained_tiles, @@ -420,8 +337,8 @@ impl FrameBuilder { render_tasks, }; - self.prim_store.update_visibility( - self.root_pic_index, + scene.prim_store.update_visibility( + scene.root_pic_index, ROOT_SURFACE_INDEX, &global_screen_world_rect, &visibility_context, @@ -432,7 +349,7 @@ impl FrameBuilder { let mut frame_state = FrameBuildingState { render_tasks, profile_counters, - clip_store: &mut self.clip_store, + clip_store: &mut scene.clip_store, resource_cache, gpu_cache, transforms: transform_palette, @@ -460,11 +377,11 @@ impl FrameBuilder { ); frame_state.push_dirty_region(default_dirty_region); - let (pic_context, mut pic_state, mut prim_list) = self + let (pic_context, mut pic_state, mut prim_list) = scene .prim_store - .pictures[self.root_pic_index.0] + .pictures[scene.root_pic_index.0] .take_context( - self.root_pic_index, + scene.root_pic_index, WorldRect::max_rect(), root_spatial_node_index, root_spatial_node_index, @@ -478,7 +395,7 @@ impl FrameBuilder { { profile_marker!("PreparePrims"); - self.prim_store.prepare_primitives( + scene.prim_store.prepare_primitives( &mut prim_list, &pic_context, &mut pic_state, @@ -489,7 +406,7 @@ impl FrameBuilder { ); } - let pic = &mut self.prim_store.pictures[self.root_pic_index.0]; + let pic = &mut scene.prim_store.pictures[scene.root_pic_index.0]; pic.restore_context( prim_list, pic_context, @@ -512,11 +429,10 @@ impl FrameBuilder { pub fn build( &mut self, + scene: &mut BuiltScene, resource_cache: &mut ResourceCache, gpu_cache: &mut GpuCache, stamp: FrameStamp, - clip_scroll_tree: &mut ClipScrollTree, - pipelines: &FastHashMap>, global_device_pixel_scale: DevicePixelScale, layer: DocumentLayer, device_origin: DeviceIntPoint, @@ -535,20 +451,20 @@ impl FrameBuilder { let mut profile_counters = FrameProfileCounters::new(); profile_counters .total_primitives - .set(self.prim_store.prim_count()); + .set(scene.prim_store.prim_count()); resource_cache.begin_frame(stamp); gpu_cache.begin_frame(stamp); self.globals.update(gpu_cache); - clip_scroll_tree.update_tree( + scene.clip_scroll_tree.update_tree( pan, global_device_pixel_scale, scene_properties, ); - let mut transform_palette = clip_scroll_tree.build_transform_palette(); - self.clip_store.clear_old_instances(); + let mut transform_palette = scene.clip_scroll_tree.build_transform_palette(); + scene.clip_store.clear_old_instances(); let mut render_tasks = RenderTaskGraph::new( stamp.frame_id(), @@ -556,13 +472,12 @@ impl FrameBuilder { ); let mut surfaces = Vec::new(); - let output_size = self.output_rect.size.to_i32(); - let screen_world_rect = (self.output_rect.to_f32() / global_device_pixel_scale).round_out(); + let output_size = scene.output_rect.size.to_i32(); + let screen_world_rect = (scene.output_rect.to_f32() / global_device_pixel_scale).round_out(); let main_render_task_id = self.build_layer_screen_rects_and_cull_layers( + scene, screen_world_rect, - clip_scroll_tree, - pipelines, resource_cache, gpu_cache, &mut render_tasks, @@ -588,24 +503,24 @@ impl FrameBuilder { passes = render_tasks.generate_passes( main_render_task_id, output_size, - self.config.gpu_supports_fast_clears, + scene.config.gpu_supports_fast_clears, ); // Used to generated a unique z-buffer value per primitive. let mut z_generator = ZBufferIdGenerator::new(layer); - let use_dual_source_blending = self.config.dual_source_blending_is_enabled && - self.config.dual_source_blending_is_supported; + let use_dual_source_blending = scene.config.dual_source_blending_is_enabled && + scene.config.dual_source_blending_is_supported; for pass in &mut passes { let mut ctx = RenderTargetContext { global_device_pixel_scale, - prim_store: &self.prim_store, + prim_store: &scene.prim_store, resource_cache, use_dual_source_blending, - use_advanced_blending: self.config.gpu_supports_advanced_blend, - break_advanced_blend_batches: !self.config.advanced_blend_is_coherent, - batch_lookback_count: self.config.batch_lookback_count, - clip_scroll_tree, + use_advanced_blending: scene.config.gpu_supports_advanced_blend, + break_advanced_blend_batches: !scene.config.advanced_blend_is_coherent, + batch_lookback_count: scene.config.batch_lookback_count, + clip_scroll_tree: &scene.clip_scroll_tree, data_stores, surfaces: &surfaces, scratch, @@ -619,7 +534,7 @@ impl FrameBuilder { gpu_cache, &mut render_tasks, &mut deferred_resolves, - &self.clip_store, + &scene.clip_store, &mut transform_palette, &mut prim_headers, &mut z_generator, @@ -646,12 +561,12 @@ impl FrameBuilder { resource_cache.end_frame(texture_cache_profile); Frame { - content_origin: self.output_rect.origin, + content_origin: scene.output_rect.origin, device_rect: DeviceIntRect::new( device_origin, - self.output_rect.size, + scene.output_rect.size, ), - background_color: self.background_color, + background_color: scene.background_color, layer, profile_counters, passes, @@ -666,19 +581,6 @@ impl FrameBuilder { debug_items: mem::replace(&mut scratch.debug_items, Vec::new()), } } - - pub fn create_hit_tester( - &mut self, - clip_scroll_tree: &ClipScrollTree, - clip_data_store: &ClipDataStore, - ) -> HitTester { - HitTester::new( - Arc::clone(&self.hit_testing_scene), - clip_scroll_tree, - &self.clip_store, - clip_data_store, - ) - } } /// Processes this pass to prepare it for rendering. diff --git a/gfx/wr/webrender/src/lib.rs b/gfx/wr/webrender/src/lib.rs index d9e52dd2084e..e2d239ce23f0 100644 --- a/gfx/wr/webrender/src/lib.rs +++ b/gfx/wr/webrender/src/lib.rs @@ -88,7 +88,6 @@ mod debug_render; #[cfg(feature = "debugger")] mod debug_server; mod device; -mod display_list_flattener; mod ellipse; mod filterdata; mod frame_builder; @@ -116,6 +115,7 @@ mod renderer; mod resource_cache; mod scene; mod scene_builder_thread; +mod scene_building; mod screen_capture; mod segment; mod shade; diff --git a/gfx/wr/webrender/src/prim_store/borders.rs b/gfx/wr/webrender/src/prim_store/borders.rs index 6ccf4d540cee..10ecd86ba6f5 100644 --- a/gfx/wr/webrender/src/prim_store/borders.rs +++ b/gfx/wr/webrender/src/prim_store/borders.rs @@ -6,7 +6,7 @@ use api::{NormalBorder, PremultipliedColorF, Shadow}; use api::units::*; use crate::border::create_border_segments; use crate::border::NormalBorderAu; -use crate::display_list_flattener::{CreateShadow, IsVisible}; +use crate::scene_building::{CreateShadow, IsVisible}; use crate::frame_builder::{FrameBuildingState}; use crate::gpu_cache::{GpuCache, GpuDataRequest}; use crate::intern; diff --git a/gfx/wr/webrender/src/prim_store/gradient.rs b/gfx/wr/webrender/src/prim_store/gradient.rs index 18f4f839ffd8..70479ca12fc9 100644 --- a/gfx/wr/webrender/src/prim_store/gradient.rs +++ b/gfx/wr/webrender/src/prim_store/gradient.rs @@ -7,7 +7,7 @@ use api::{ PremultipliedColorF, LineOrientation, }; use api::units::{LayoutPoint, LayoutSize, LayoutVector2D}; -use crate::display_list_flattener::IsVisible; +use crate::scene_building::IsVisible; use euclid::approxeq::ApproxEq; use crate::frame_builder::FrameBuildingState; use crate::gpu_cache::{GpuCacheHandle, GpuDataRequest}; diff --git a/gfx/wr/webrender/src/prim_store/image.rs b/gfx/wr/webrender/src/prim_store/image.rs index 93c23ae686a1..d33dc5244621 100644 --- a/gfx/wr/webrender/src/prim_store/image.rs +++ b/gfx/wr/webrender/src/prim_store/image.rs @@ -8,7 +8,7 @@ use api::{ PremultipliedColorF, Shadow, YuvColorSpace, ColorRange, YuvFormat, }; use api::units::*; -use crate::display_list_flattener::{CreateShadow, IsVisible}; +use crate::scene_building::{CreateShadow, IsVisible}; use crate::frame_builder::FrameBuildingState; use crate::gpu_cache::{GpuCache, GpuDataRequest}; use crate::intern::{Internable, InternDebug, Handle as InternHandle}; diff --git a/gfx/wr/webrender/src/prim_store/line_dec.rs b/gfx/wr/webrender/src/prim_store/line_dec.rs index 24393738d2b3..1dbda9a5a562 100644 --- a/gfx/wr/webrender/src/prim_store/line_dec.rs +++ b/gfx/wr/webrender/src/prim_store/line_dec.rs @@ -7,7 +7,7 @@ use api::{ LineOrientation, LineStyle, PremultipliedColorF, Shadow, }; use api::units::{Au, LayoutSizeAu, LayoutVector2D}; -use crate::display_list_flattener::{CreateShadow, IsVisible}; +use crate::scene_building::{CreateShadow, IsVisible}; use crate::frame_builder::{FrameBuildingState}; use crate::gpu_cache::GpuDataRequest; use crate::intern; diff --git a/gfx/wr/webrender/src/prim_store/mod.rs b/gfx/wr/webrender/src/prim_store/mod.rs index 62f2fff3e3df..db3d938ab688 100644 --- a/gfx/wr/webrender/src/prim_store/mod.rs +++ b/gfx/wr/webrender/src/prim_store/mod.rs @@ -15,7 +15,7 @@ use crate::clip_scroll_tree::{ROOT_SPATIAL_NODE_INDEX, ClipScrollTree, Coordinat use crate::clip::{ClipDataStore, ClipNodeFlags, ClipChainId, ClipChainInstance, ClipItemKind}; use crate::debug_colors; use crate::debug_render::DebugItem; -use crate::display_list_flattener::{CreateShadow, IsVisible}; +use crate::scene_building::{CreateShadow, IsVisible}; use euclid::{SideOffsets2D, Transform3D, Rect, Scale, Size2D, Point2D}; use euclid::approxeq::ApproxEq; use crate::frame_builder::{FrameBuildingContext, FrameBuildingState, PictureContext, PictureState}; @@ -1840,7 +1840,7 @@ impl PrimitiveStore { /// Destroy an existing primitive store. This is called just before /// a primitive store is replaced with a newly built scene. pub fn destroy( - mut self, + &mut self, retained_tiles: &mut RetainedTiles, ) { for pic in &mut self.pictures { @@ -4082,7 +4082,7 @@ fn update_opacity_binding( } /// Trait for primitives that are directly internable. -/// see DisplayListFlattener::add_primitive

+/// see SceneBuilder::add_primitive

pub trait InternablePrimitive: intern::Internable + Sized { /// Build a new key from self with `info`. fn into_key( diff --git a/gfx/wr/webrender/src/prim_store/picture.rs b/gfx/wr/webrender/src/prim_store/picture.rs index 16c2cd30588b..1b8a608f16f1 100644 --- a/gfx/wr/webrender/src/prim_store/picture.rs +++ b/gfx/wr/webrender/src/prim_store/picture.rs @@ -7,7 +7,7 @@ use api::{ PropertyBinding, PropertyBindingId, CompositeOperator, }; use api::units::{Au, LayoutSize, LayoutVector2D}; -use crate::display_list_flattener::IsVisible; +use crate::scene_building::IsVisible; use crate::filterdata::SFilterData; use crate::intern::ItemUid; use crate::intern::{Internable, InternDebug, Handle as InternHandle}; diff --git a/gfx/wr/webrender/src/prim_store/text_run.rs b/gfx/wr/webrender/src/prim_store/text_run.rs index 9eb0100233bd..cda289bb9273 100644 --- a/gfx/wr/webrender/src/prim_store/text_run.rs +++ b/gfx/wr/webrender/src/prim_store/text_run.rs @@ -4,7 +4,7 @@ use api::{ColorF, GlyphInstance, RasterSpace, Shadow}; use api::units::{DevicePixelScale, LayoutToWorldTransform, LayoutVector2D}; -use crate::display_list_flattener::{CreateShadow, IsVisible}; +use crate::scene_building::{CreateShadow, IsVisible}; use crate::frame_builder::FrameBuildingState; use crate::glyph_rasterizer::{FontInstance, FontTransform, GlyphKey, FONT_SIZE_LIMIT}; use crate::gpu_cache::GpuCache; diff --git a/gfx/wr/webrender/src/render_backend.rs b/gfx/wr/webrender/src/render_backend.rs index ba1f010e5a48..06a4f66e73c7 100644 --- a/gfx/wr/webrender/src/render_backend.rs +++ b/gfx/wr/webrender/src/render_backend.rs @@ -13,7 +13,7 @@ use api::{ApiMsg, BuiltDisplayList, ClearCache, DebugCommand, DebugFlags}; use api::{BuiltDisplayListIter, DisplayItem}; use api::{DocumentId, DocumentLayer, ExternalScrollId, FrameMsg, HitTestFlags, HitTestResult}; use api::{IdNamespace, MemoryReport, PipelineId, RenderNotifier, SceneMsg, ScrollClamping}; -use api::{ScrollLocation, ScrollNodeState, TransactionMsg, ResourceUpdate, BlobImageKey}; +use api::{ScrollLocation, TransactionMsg, ResourceUpdate, BlobImageKey}; use api::{NotificationRequest, Checkpoint}; use api::{ClipIntern, FilterDataIntern, PrimitiveKeyKind}; use api::units::*; @@ -22,7 +22,7 @@ use api::channel::{MsgReceiver, MsgSender, Payload}; use api::CaptureBits; #[cfg(feature = "replay")] use api::CapturedDocument; -use crate::clip_scroll_tree::{SpatialNodeIndex, ClipScrollTree}; +use crate::clip_scroll_tree::SpatialNodeIndex; #[cfg(feature = "debugger")] use crate::debug_server; use crate::frame_builder::{FrameBuilder, FrameBuilderConfig}; @@ -45,7 +45,7 @@ use crate::resource_cache::ResourceCache; use crate::resource_cache::PlainCacheOwn; #[cfg(any(feature = "capture", feature = "replay"))] use crate::resource_cache::PlainResources; -use crate::scene::{Scene, SceneProperties}; +use crate::scene::{BuiltScene, SceneProperties}; use crate::scene_builder_thread::*; #[cfg(feature = "serialize")] use serde::{Serialize, Deserialize}; @@ -328,30 +328,27 @@ impl DataStores { } struct Document { - // The id of this document + /// The id of this document id: DocumentId, - // The latest built scene, usable to build frames. - // received from the scene builder thread. - scene: Scene, - // Temporary list of removed pipelines received from the scene builder - // thread and forwarded to the renderer. + /// Temporary list of removed pipelines received from the scene builder + /// thread and forwarded to the renderer. removed_pipelines: Vec<(PipelineId, DocumentId)>, view: DocumentView, - /// The ClipScrollTree for this document which tracks SpatialNodes, ClipNodes, and ClipChains. - /// This is stored here so that we are able to preserve scrolling positions between rendered - /// frames. - clip_scroll_tree: ClipScrollTree, - /// The id and time of the current frame. stamp: FrameStamp, - // the `Option` here is only to deal with borrow checker - frame_builder: Option, - // A set of pipelines that the caller has requested be - // made available as output textures. + /// The latest built scene, usable to build frames. + /// received from the scene builder thread. + scene: BuiltScene, + + /// The builder object that prodces frames, kept around to preserve some retained state. + frame_builder: FrameBuilder, + + /// A set of pipelines that the caller has requested be + /// made available as output textures. output_pipelines: FastHashSet, /// A data structure to allow hit testing against rendered frames. This is updated @@ -367,8 +364,8 @@ struct Document { frame_is_valid: bool, hit_tester_is_valid: bool, rendered_frame_is_valid: bool, - // We track this information to be able to display debugging information from the - // renderer. + /// We track this information to be able to display debugging information from the + /// renderer. has_built_scene: bool, data_stores: DataStores, @@ -391,7 +388,6 @@ impl Document { ) -> Self { Document { id, - scene: Scene::new(), removed_pipelines: Vec::new(), view: DocumentView { device_rect: size.into(), @@ -401,9 +397,9 @@ impl Document { pinch_zoom_factor: 1.0, device_pixel_ratio: default_device_pixel_ratio, }, - clip_scroll_tree: ClipScrollTree::new(), stamp: FrameStamp::first(id), - frame_builder: None, + scene: BuiltScene::empty(), + frame_builder: FrameBuilder::new(), output_pipelines: FastHashSet::default(), hit_tester: None, dynamic_properties: SceneProperties::new(), @@ -418,7 +414,7 @@ impl Document { } fn can_render(&self) -> bool { - self.frame_builder.is_some() && self.scene.has_root_pipeline() + self.scene.src.has_root_pipeline() } fn has_pixels(&self) -> bool { @@ -431,7 +427,7 @@ impl Document { ) -> DocumentOps { match message { FrameMsg::UpdateEpoch(pipeline_id, epoch) => { - self.scene.update_epoch(pipeline_id, epoch); + self.scene.src.update_epoch(pipeline_id, epoch); } FrameMsg::Scroll(delta, cursor) => { profile_scope!("Scroll"); @@ -498,7 +494,7 @@ impl Document { } FrameMsg::GetScrollNodeState(tx) => { profile_scope!("GetScrollNodeState"); - tx.send(self.get_scroll_node_state()).unwrap(); + tx.send(self.scene.clip_scroll_tree.get_scroll_node_state()).unwrap(); } FrameMsg::UpdateDynamicProperties(property_bindings) => { self.dynamic_properties.set_properties(property_bindings); @@ -513,7 +509,7 @@ impl Document { } } FrameMsg::SetIsTransformPinchZooming(is_zooming, animation_id) => { - let node = self.clip_scroll_tree.spatial_nodes.iter_mut() + let node = self.scene.clip_scroll_tree.spatial_nodes.iter_mut() .find(|node| node.is_transform_bound_to_property(animation_id)); if let Some(node) = node { if node.is_pinch_zooming != is_zooming { @@ -544,13 +540,11 @@ impl Document { "First frame increment must happen before build_frame()"); let frame = { - let frame_builder = self.frame_builder.as_mut().unwrap(); - let frame = frame_builder.build( + let frame = self.frame_builder.build( + &mut self.scene, resource_cache, gpu_cache, self.stamp, - &mut self.clip_scroll_tree, - &self.scene.pipelines, accumulated_scale_factor, self.view.layer, self.view.device_rect.origin, @@ -563,10 +557,7 @@ impl Document { &mut self.render_task_counters, debug_flags, ); - self.hit_tester = Some(frame_builder.create_hit_tester( - &self.clip_scroll_tree, - &self.data_stores.clip, - )); + self.hit_tester = Some(self.scene.create_hit_tester(&self.data_stores.clip)); frame }; @@ -583,35 +574,30 @@ impl Document { } fn rebuild_hit_tester(&mut self) { - if let Some(ref mut frame_builder) = self.frame_builder { - let accumulated_scale_factor = self.view.accumulated_scale_factor(); - let pan = self.view.pan.to_f32() / accumulated_scale_factor; + let accumulated_scale_factor = self.view.accumulated_scale_factor(); + let pan = self.view.pan.to_f32() / accumulated_scale_factor; - self.clip_scroll_tree.update_tree( + self.scene.clip_scroll_tree.update_tree( pan, accumulated_scale_factor, &self.dynamic_properties, ); - self.hit_tester = Some(frame_builder.create_hit_tester( - &self.clip_scroll_tree, - &self.data_stores.clip, - )); - self.hit_tester_is_valid = true; - } + self.hit_tester = Some(self.scene.create_hit_tester(&self.data_stores.clip)); + self.hit_tester_is_valid = true; } pub fn updated_pipeline_info(&mut self) -> PipelineInfo { let removed_pipelines = self.removed_pipelines.take_and_preallocate(); PipelineInfo { - epochs: self.scene.pipeline_epochs.iter() + epochs: self.scene.src.pipeline_epochs.iter() .map(|(&pipeline_id, &epoch)| ((pipeline_id, self.id), epoch)).collect(), removed_pipelines, } } pub fn discard_frame_state_for_pipeline(&mut self, pipeline_id: PipelineId) { - self.clip_scroll_tree + self.scene.clip_scroll_tree .discard_frame_state_for_pipeline(pipeline_id); } @@ -621,7 +607,7 @@ impl Document { scroll_location: ScrollLocation, scroll_node_index: Option, ) -> bool { - self.clip_scroll_tree.scroll_nearest_scrolling_ancestor(scroll_location, scroll_node_index) + self.scene.clip_scroll_tree.scroll_nearest_scrolling_ancestor(scroll_location, scroll_node_index) } /// Returns true if the node actually changed position or false otherwise. @@ -631,46 +617,37 @@ impl Document { id: ExternalScrollId, clamp: ScrollClamping ) -> bool { - self.clip_scroll_tree.scroll_node(origin, id, clamp) - } - - pub fn get_scroll_node_state(&self) -> Vec { - self.clip_scroll_tree.get_scroll_node_state() + self.scene.clip_scroll_tree.scroll_node(origin, id, clamp) } pub fn new_async_scene_ready( &mut self, - mut built_scene: BuiltScene, + built_scene: BuiltScene, recycler: &mut Recycler, ) { - self.scene = built_scene.scene; self.frame_is_valid = false; self.hit_tester_is_valid = false; - // Give the old frame builder a chance to destroy any resources. + // Give the old scene a chance to destroy any resources. // Right now, all this does is build a hash map of any cached - // surface tiles, that can be provided to the next frame builder. + // surface tiles, that can be provided to the next scene. + // TODO(nical) - It's a bit awkward how these retained tiles live + // in the scene's prim store then temporarily in the frame builder + // and then presumably back in the prim store during the next frame + // build. let mut retained_tiles = RetainedTiles::new(); - if let Some(frame_builder) = self.frame_builder.take() { - let globals = frame_builder.destroy( - &mut retained_tiles, - ); + self.scene.prim_store.destroy(&mut retained_tiles); + let old_scrolling_states = self.scene.clip_scroll_tree.drain(); - // Provide any cached tiles from the previous frame builder to - // the newly built one. - built_scene.frame_builder.set_retained_resources( - retained_tiles, - globals, - ); - } + self.scene = built_scene; - self.frame_builder = Some(built_scene.frame_builder); + // Provide any cached tiles from the previous scene to + // the newly built one. + self.frame_builder.set_retained_resources(retained_tiles); self.scratch.recycle(recycler); - let old_scrolling_states = self.clip_scroll_tree.drain(); - self.clip_scroll_tree = built_scene.clip_scroll_tree; - self.clip_scroll_tree.finalize_and_apply_pending_scroll_offsets(old_scrolling_states); + self.scene.clip_scroll_tree.finalize_and_apply_pending_scroll_offsets(old_scrolling_states); } } @@ -1152,15 +1129,15 @@ impl RenderBackend { for (id, doc) in &self.documents { let captured = CapturedDocument { document_id: *id, - root_pipeline_id: doc.scene.root_pipeline_id, + root_pipeline_id: doc.scene.src.root_pipeline_id, }; tx.send(captured).unwrap(); // notify the active recorder if let Some(ref mut r) = self.recorder { - let pipeline_id = doc.scene.root_pipeline_id.unwrap(); - let epoch = doc.scene.pipeline_epochs[&pipeline_id]; - let pipeline = &doc.scene.pipelines[&pipeline_id]; + let pipeline_id = doc.scene.src.root_pipeline_id.unwrap(); + let epoch = doc.scene.src.pipeline_epochs[&pipeline_id]; + let pipeline = &doc.scene.src.pipelines[&pipeline_id]; let scene_msg = SceneMsg::SetDisplayList { list_descriptor: pipeline.display_list.descriptor().clone(), epoch, @@ -1630,7 +1607,7 @@ impl RenderBackend { for (_, doc) in &self.documents { let mut debug_doc = debug_server::TreeNode::new("document"); - for (_, pipeline) in &doc.scene.pipelines { + for (_, pipeline) in &doc.scene.src.pipelines { let mut debug_dl = debug_server::TreeNode::new("display-list"); self.traverse_items(&mut pipeline.display_list.iter(), &mut debug_dl); debug_doc.add_child(debug_dl); @@ -1657,7 +1634,7 @@ impl RenderBackend { let debug_node = debug_server::TreeNode::new("document clip-scroll tree"); let mut builder = debug_server::TreeNodeBuilder::new(debug_node); - doc.clip_scroll_tree.print_with(&mut builder); + doc.scene.clip_scroll_tree.print_with(&mut builder); debug_root.add(builder.build()); } @@ -1671,9 +1648,7 @@ impl RenderBackend { let op = ops.size_of_op; report.gpu_cache_metadata = self.gpu_cache.size_of(ops); for (_id, doc) in &self.documents { - if let Some(ref fb) = doc.frame_builder { - report.clip_stores += fb.clip_store.size_of(ops); - } + report.clip_stores += doc.scene.clip_store.size_of(ops); report.hit_testers += doc.hit_tester.size_of(ops); doc.data_stores.report_memory(ops, &mut report) @@ -1734,7 +1709,7 @@ impl RenderBackend { debug!("\tdocument {:?}", id); if config.bits.contains(CaptureBits::SCENE) { let file_name = format!("scene-{}-{}", id.namespace_id.0, id.id); - config.serialize(&doc.scene, file_name); + config.serialize(&doc.scene.src, file_name); } if config.bits.contains(CaptureBits::FRAME) { let rendered_document = doc.build_frame( @@ -1754,9 +1729,9 @@ impl RenderBackend { let file_name = format!("frame-{}-{}", id.namespace_id.0, id.id); config.serialize(&rendered_document.frame, file_name); let file_name = format!("clip-scroll-{}-{}", id.namespace_id.0, id.id); - config.serialize_tree(&doc.clip_scroll_tree, file_name); + config.serialize_tree(&doc.scene.clip_scroll_tree, file_name); let file_name = format!("builder-{}-{}", id.namespace_id.0, id.id); - config.serialize(doc.frame_builder.as_ref().unwrap(), file_name); + config.serialize(&doc.frame_builder, file_name); let file_name = format!("scratch-{}-{}", id.namespace_id.0, id.id); config.serialize(&doc.scratch, file_name); let file_name = format!("properties-{}-{}", id.namespace_id.0, id.id); @@ -1826,6 +1801,7 @@ impl RenderBackend { profile_counters: &mut BackendProfileCounters, ) { use crate::capture::CaptureConfig; + use crate::scene::Scene; debug!("capture: loading {:?}", root); let backend = CaptureConfig::deserialize::(root, "backend") @@ -1871,14 +1847,16 @@ impl RenderBackend { let data_stores = CaptureConfig::deserialize::(root, &data_stores_name) .expect(&format!("Unable to open {}.ron", data_stores_name)); + let mut built_scene = BuiltScene::empty(); + built_scene.src = scene; + let doc = Document { id, - scene: scene.clone(), + scene: built_scene, removed_pipelines: Vec::new(), view: view.clone(), - clip_scroll_tree: ClipScrollTree::new(), stamp: FrameStamp::first(id), - frame_builder: Some(FrameBuilder::empty()), + frame_builder: FrameBuilder::new(), output_pipelines: FastHashSet::default(), dynamic_properties: SceneProperties::new(), hit_tester: None, @@ -1920,7 +1898,7 @@ impl RenderBackend { scenes_to_build.push(LoadScene { document_id: id, - scene: doc.scene.clone(), + scene: doc.scene.src.clone(), view: view.clone(), config: self.frame_config.clone(), output_pipelines: doc.output_pipelines.clone(), diff --git a/gfx/wr/webrender/src/scene.rs b/gfx/wr/webrender/src/scene.rs index a907c0b58fb4..31a82a7f24a1 100644 --- a/gfx/wr/webrender/src/scene.rs +++ b/gfx/wr/webrender/src/scene.rs @@ -2,10 +2,15 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -use api::{BuiltDisplayList, ColorF, DynamicProperties, Epoch}; +use api::{BuiltDisplayList, ColorF, DynamicProperties, Epoch, FontRenderMode}; use api::{PipelineId, PropertyBinding, PropertyBindingId, MixBlendMode, StackingContext}; -use api::units::{LayoutSize, LayoutTransform}; +use api::units::*; +use crate::clip::{ClipStore, ClipDataStore}; +use crate::clip_scroll_tree::ClipScrollTree; +use crate::frame_builder::{ChasePrimitive, FrameBuilderConfig}; +use crate::hit_test::{HitTester, HitTestingScene, HitTestingSceneStats}; use crate::internal_types::FastHashMap; +use crate::prim_store::{PrimitiveStore, PrimitiveStoreStats, PictureIndex}; use std::sync::Arc; /// Stores a map of the animated property bindings for the current display list. These @@ -207,3 +212,84 @@ impl StackingContextHelpers for StackingContext { } } } + + +/// WebRender's internal representation of the scene. +pub struct BuiltScene { + /// The scene this object was built from. + pub src: Scene, + pub output_rect: DeviceIntRect, + pub background_color: Option, + pub root_pic_index: PictureIndex, + pub prim_store: PrimitiveStore, + pub clip_store: ClipStore, + pub config: FrameBuilderConfig, + pub clip_scroll_tree: ClipScrollTree, + pub hit_testing_scene: Arc, +} + +impl BuiltScene { + pub fn empty() -> Self { + BuiltScene { + src: Scene::new(), + output_rect: DeviceIntRect::zero(), + background_color: None, + root_pic_index: PictureIndex(0), + prim_store: PrimitiveStore::new(&PrimitiveStoreStats::empty()), + clip_store: ClipStore::new(), + clip_scroll_tree: ClipScrollTree::new(), + hit_testing_scene: Arc::new(HitTestingScene::new(&HitTestingSceneStats::empty())), + config: FrameBuilderConfig { + default_font_render_mode: FontRenderMode::Mono, + dual_source_blending_is_enabled: true, + dual_source_blending_is_supported: false, + chase_primitive: ChasePrimitive::Nothing, + enable_picture_caching: false, + testing: false, + gpu_supports_fast_clears: false, + gpu_supports_advanced_blend: false, + advanced_blend_is_coherent: false, + batch_lookback_count: 0, + background_color: None, + }, + } + } + + /// Get the memory usage statistics to pre-allocate for the next scene. + pub fn get_stats(&self) -> SceneStats { + SceneStats { + prim_store_stats: self.prim_store.get_stats(), + hit_test_stats: self.hit_testing_scene.get_stats(), + } + } + + pub fn create_hit_tester( + &mut self, + clip_data_store: &ClipDataStore, + ) -> HitTester { + HitTester::new( + Arc::clone(&self.hit_testing_scene), + &self.clip_scroll_tree, + &self.clip_store, + clip_data_store, + ) + } +} + +/// Stores the allocation sizes of various arrays in the built +/// scene. This is retrieved from the current frame builder +/// and used to reserve an approximately correct capacity of +/// the arrays for the next scene that is getting built. +pub struct SceneStats { + pub prim_store_stats: PrimitiveStoreStats, + pub hit_test_stats: HitTestingSceneStats, +} + +impl SceneStats { + pub fn empty() -> Self { + SceneStats { + prim_store_stats: PrimitiveStoreStats::empty(), + hit_test_stats: HitTestingSceneStats::empty(), + } + } +} diff --git a/gfx/wr/webrender/src/scene_builder_thread.rs b/gfx/wr/webrender/src/scene_builder_thread.rs index 1ffb541c21ca..d0c53abc0e81 100644 --- a/gfx/wr/webrender/src/scene_builder_thread.rs +++ b/gfx/wr/webrender/src/scene_builder_thread.rs @@ -10,14 +10,11 @@ use api::channel::MsgSender; use api::units::LayoutSize; #[cfg(feature = "capture")] use crate::capture::CaptureConfig; -use crate::frame_builder::{FrameBuilderConfig, FrameBuilder}; -use crate::clip_scroll_tree::ClipScrollTree; -use crate::display_list_flattener::DisplayListFlattener; -use crate::hit_test::HitTestingSceneStats; +use crate::frame_builder::FrameBuilderConfig; +use crate::scene_building::SceneBuilder; use crate::intern::{Internable, Interner, UpdateList}; use crate::internal_types::{FastHashMap, FastHashSet}; use malloc_size_of::{MallocSizeOf, MallocSizeOfOps}; -use crate::prim_store::PrimitiveStoreStats; use crate::prim_store::backdrop::Backdrop; use crate::prim_store::borders::{ImageBorder, NormalBorderPrim}; use crate::prim_store::gradient::{LinearGradient, RadialGradient}; @@ -28,7 +25,7 @@ use crate::prim_store::text_run::TextRun; use crate::resource_cache::{AsyncBlobImageInfo, FontInstanceMap}; use crate::render_backend::DocumentView; use crate::renderer::{PipelineInfo, SceneBuilderHooks}; -use crate::scene::Scene; +use crate::scene::{Scene, BuiltScene, SceneStats}; use std::iter; use std::sync::mpsc::{channel, Receiver, Sender}; use std::mem::replace; @@ -130,12 +127,6 @@ pub struct LoadScene { pub interners: Interners, } -pub struct BuiltScene { - pub scene: Scene, - pub frame_builder: FrameBuilder, - pub clip_scroll_tree: ClipScrollTree, -} - // Message from render backend to scene builder. pub enum SceneBuilderRequest { Transactions(Vec>), @@ -228,24 +219,6 @@ macro_rules! declare_interners { enumerate_interners!(declare_interners); -/// Stores the allocation sizes of various arrays in the frame -/// builder. This is retrieved from the current frame builder -/// and used to reserve an approximately correct capacity of -/// the arrays for the next scene that is getting built. -pub struct DocumentStats { - pub prim_store_stats: PrimitiveStoreStats, - pub hit_test_stats: HitTestingSceneStats, -} - -impl DocumentStats { - pub fn empty() -> DocumentStats { - DocumentStats { - prim_store_stats: PrimitiveStoreStats::empty(), - hit_test_stats: HitTestingSceneStats::empty(), - } - } -} - // A document in the scene builder contains the current scene, // as well as a persistent clip interner. This allows clips // to be de-duplicated, and persisted in the GPU cache between @@ -253,7 +226,7 @@ impl DocumentStats { struct Document { scene: Scene, interners: Interners, - doc_stats: DocumentStats, + stats: SceneStats, } impl Document { @@ -261,7 +234,7 @@ impl Document { Document { scene, interners: Interners::default(), - doc_stats: DocumentStats::empty(), + stats: SceneStats::empty(), } } } @@ -398,30 +371,19 @@ impl SceneBuilderThread { let mut interner_updates = None; if item.scene.has_root_pipeline() { - let mut clip_scroll_tree = ClipScrollTree::new(); - let mut new_scene = Scene::new(); - - let frame_builder = DisplayListFlattener::create_frame_builder( + built_scene = Some(SceneBuilder::build( &item.scene, - &mut clip_scroll_tree, item.font_instances, &item.view, &item.output_pipelines, &self.config, - &mut new_scene, &mut item.interners, - &DocumentStats::empty(), - ); + &SceneStats::empty(), + )); interner_updates = Some( item.interners.end_frame_and_get_pending_updates() ); - - built_scene = Some(BuiltScene { - scene: new_scene, - frame_builder, - clip_scroll_tree, - }); } self.documents.insert( @@ -429,7 +391,7 @@ impl SceneBuilderThread { Document { scene: item.scene, interners: item.interners, - doc_stats: DocumentStats::empty(), + stats: SceneStats::empty(), }, ); @@ -493,34 +455,25 @@ impl SceneBuilderThread { let mut interner_updates = None; if scene.has_root_pipeline() { if let Some(request) = txn.request_scene_build.take() { - let mut clip_scroll_tree = ClipScrollTree::new(); - let mut new_scene = Scene::new(); - - let frame_builder = DisplayListFlattener::create_frame_builder( + let built = SceneBuilder::build( &scene, - &mut clip_scroll_tree, request.font_instances, &request.view, &request.output_pipelines, &self.config, - &mut new_scene, &mut doc.interners, - &doc.doc_stats, + &doc.stats, ); // Update the allocation stats for next scene - doc.doc_stats = frame_builder.get_stats(); + doc.stats = built.get_stats(); // Retrieve the list of updates from the clip interner. interner_updates = Some( doc.interners.end_frame_and_get_pending_updates() ); - built_scene = Some(BuiltScene { - scene: new_scene, - frame_builder, - clip_scroll_tree, - }); + built_scene = Some(built); } } @@ -564,7 +517,7 @@ impl SceneBuilderThread { .filter(|txn| txn.built_scene.is_some()) .map(|txn| { txn.built_scene.as_ref().unwrap() - .scene.pipeline_epochs.iter() + .src.pipeline_epochs.iter() .zip(iter::repeat(txn.document_id)) .map(|((&pipeline_id, &epoch), document_id)| ((pipeline_id, document_id), epoch)) }).flatten().collect(), diff --git a/gfx/wr/webrender/src/display_list_flattener.rs b/gfx/wr/webrender/src/scene_building.rs similarity index 98% rename from gfx/wr/webrender/src/display_list_flattener.rs rename to gfx/wr/webrender/src/scene_building.rs index c82ee9a1b757..0761ebd34dc4 100644 --- a/gfx/wr/webrender/src/display_list_flattener.rs +++ b/gfx/wr/webrender/src/scene_building.rs @@ -14,7 +14,7 @@ use api::{ClipMode, PrimitiveKeyKind, TransformStyle, YuvColorSpace, ColorRange, use api::units::*; use crate::clip::{ClipChainId, ClipRegion, ClipItemKey, ClipStore, ClipItemKeyKind, ClipDataHandle, ClipNodeKind}; use crate::clip_scroll_tree::{ROOT_SPATIAL_NODE_INDEX, ClipScrollTree, SpatialNodeIndex}; -use crate::frame_builder::{ChasePrimitive, FrameBuilder, FrameBuilderConfig}; +use crate::frame_builder::{ChasePrimitive, FrameBuilderConfig}; use crate::glyph_rasterizer::FontInstance; use crate::hit_test::{HitTestingItem, HitTestingScene}; use crate::image::simplify_repeated_primitive; @@ -37,8 +37,8 @@ use crate::prim_store::picture::{Picture, PictureCompositeKey, PictureKey}; use crate::prim_store::text_run::TextRun; use crate::render_backend::{DocumentView}; use crate::resource_cache::{FontInstanceMap, ImageRequest}; -use crate::scene::{Scene, StackingContextHelpers}; -use crate::scene_builder_thread::{DocumentStats, Interners}; +use crate::scene::{Scene, BuiltScene, SceneStats, StackingContextHelpers}; +use crate::scene_builder_thread::Interners; use crate::spatial_node::{StickyFrameInfo, ScrollFrameKind}; use std::{f32, mem, usize, ops}; use std::collections::vec_deque::VecDeque; @@ -239,15 +239,12 @@ impl CompositeOps { } /// A structure that converts a serialized display list into a form that WebRender -/// can use to later build a frame. This structure produces a FrameBuilder. Public -/// members are typically those that are destructured into the FrameBuilder. -pub struct DisplayListFlattener<'a> { - /// The scene that we are currently flattening. +/// can use to later build a frame. This structure produces a BuiltScene. Public +/// members are typically those that are destructured into the BuiltScene. +pub struct SceneBuilder<'a> { + /// The scene that we are currently building. scene: &'a Scene, - /// The ClipScrollTree that we are currently building during flattening. - clip_scroll_tree: &'a mut ClipScrollTree, - /// The map of all font instances. font_instances: FontInstanceMap, @@ -255,7 +252,7 @@ pub struct DisplayListFlattener<'a> { /// output textures. output_pipelines: &'a FastHashSet, - /// The data structure that converting between ClipId/SpatialId and the various + /// The data structure that converts between ClipId/SpatialId and the various /// index types that the ClipScrollTree uses. id_to_index_mapper: NodeIdToIndexMapper, @@ -268,6 +265,9 @@ pub struct DisplayListFlattener<'a> { /// The stack keeping track of the root clip chains associated with pipelines. pipeline_clip_chain_stack: Vec, + /// The ClipScrollTree that we are currently building during building. + pub clip_scroll_tree: ClipScrollTree, + /// The store of primitives. pub prim_store: PrimitiveStore, @@ -284,7 +284,7 @@ pub struct DisplayListFlattener<'a> { /// Reference to the set of data that is interned across display lists. interners: &'a mut Interners, - /// The root picture index for this flattener. This is the picture + /// The root picture index for this builder. This is the picture /// to start the culling phase from. pub root_pic_index: PictureIndex, @@ -295,22 +295,20 @@ pub struct DisplayListFlattener<'a> { external_scroll_mapper: ScrollOffsetMapper, /// If true, a stacking context with create_tile_cache set to true was found - /// during flattening. + /// during building. found_explicit_tile_cache: bool, } -impl<'a> DisplayListFlattener<'a> { - pub fn create_frame_builder( +impl<'a> SceneBuilder<'a> { + pub fn build( scene: &Scene, - clip_scroll_tree: &mut ClipScrollTree, font_instances: FontInstanceMap, view: &DocumentView, output_pipelines: &FastHashSet, frame_builder_config: &FrameBuilderConfig, - new_scene: &mut Scene, interners: &mut Interners, - doc_stats: &DocumentStats, - ) -> FrameBuilder { + stats: &SceneStats, + ) -> BuiltScene { // We checked that the root pipeline is available on the render backend. let root_pipeline_id = scene.root_pipeline_id.unwrap(); let root_pipeline = scene.pipelines.get(&root_pipeline_id).unwrap(); @@ -319,18 +317,18 @@ impl<'a> DisplayListFlattener<'a> { .background_color .and_then(|color| if color.a > 0.0 { Some(color) } else { None }); - let mut flattener = DisplayListFlattener { + let mut builder = SceneBuilder { scene, - clip_scroll_tree, + clip_scroll_tree: ClipScrollTree::new(), font_instances, config: *frame_builder_config, output_pipelines, id_to_index_mapper: NodeIdToIndexMapper::default(), - hit_testing_scene: HitTestingScene::new(&doc_stats.hit_test_stats), + hit_testing_scene: HitTestingScene::new(&stats.hit_test_stats), pending_shadow_items: VecDeque::new(), sc_stack: Vec::new(), pipeline_clip_chain_stack: vec![ClipChainId::NONE], - prim_store: PrimitiveStore::new(&doc_stats.prim_store_stats), + prim_store: PrimitiveStore::new(&stats.prim_store_stats), clip_store: ClipStore::new(), interners, root_pic_index: PictureIndex(0), @@ -341,7 +339,7 @@ impl<'a> DisplayListFlattener<'a> { let device_pixel_scale = view.accumulated_scale_factor_for_snapping(); - flattener.push_root( + builder.push_root( root_pipeline_id, &root_pipeline.viewport_size, &root_pipeline.content_size, @@ -359,7 +357,7 @@ impl<'a> DisplayListFlattener<'a> { // Note that we don't do this for iframes, even if they're pipeline // roots, because they should be entirely contained within a stacking // context, and we probably wouldn't crash if they weren't. - flattener.push_stacking_context( + builder.push_stacking_context( root_pipeline.pipeline_id, CompositeOps::default(), TransformStyle::Flat, @@ -372,25 +370,27 @@ impl<'a> DisplayListFlattener<'a> { device_pixel_scale, ); - flattener.flatten_items( + builder.flatten_items( &mut root_pipeline.display_list.iter(), root_pipeline.pipeline_id, true, ); - flattener.pop_stacking_context(); + builder.pop_stacking_context(); - debug_assert!(flattener.sc_stack.is_empty()); + debug_assert!(builder.sc_stack.is_empty()); - new_scene.root_pipeline_id = Some(root_pipeline_id); - new_scene.pipeline_epochs = scene.pipeline_epochs.clone(); - new_scene.pipelines = scene.pipelines.clone(); - - FrameBuilder::with_display_list_flattener( - view.device_rect.size.into(), + BuiltScene { + src: scene.clone(), + output_rect: view.device_rect.size.into(), background_color, - flattener, - ) + hit_testing_scene: Arc::new(builder.hit_testing_scene), + clip_scroll_tree: builder.clip_scroll_tree, + prim_store: builder.prim_store, + clip_store: builder.clip_store, + root_pic_index: builder.root_pic_index, + config: builder.config, + } } /// Retrieve the current offset to allow converting a stacking context @@ -1006,7 +1006,7 @@ impl<'a> DisplayListFlattener<'a> { let snap_to_device = &mut self.sc_stack.last_mut().unwrap().snap_to_device; snap_to_device.set_target_spatial_node( spatial_node_index, - self.clip_scroll_tree, + &self.clip_scroll_tree, ); let bounds = snap_to_device.snap_rect( @@ -1101,7 +1101,7 @@ impl<'a> DisplayListFlattener<'a> { let snap_to_device = &mut self.sc_stack.last_mut().unwrap().snap_to_device; snap_to_device.set_target_spatial_node( clip_and_scroll.spatial_node_index, - self.clip_scroll_tree + &self.clip_scroll_tree ); let clip_rect = common.clip_rect.translate(current_offset); @@ -1125,7 +1125,7 @@ impl<'a> DisplayListFlattener<'a> { let snap_to_device = &mut self.sc_stack.last_mut().unwrap().snap_to_device; snap_to_device.set_target_spatial_node( target_spatial_node, - self.clip_scroll_tree + &self.clip_scroll_tree ); snap_to_device.snap_rect(rect) } @@ -2340,7 +2340,7 @@ impl<'a> DisplayListFlattener<'a> { spatial_node_index, ROOT_SPATIAL_NODE_INDEX, device_pixel_scale, - self.clip_scroll_tree, + &self.clip_scroll_tree, ); let content_size = snap_to_device.snap_size(content_size); @@ -2381,7 +2381,7 @@ impl<'a> DisplayListFlattener<'a> { let snap_to_device = &mut self.sc_stack.last_mut().unwrap().snap_to_device; snap_to_device.set_target_spatial_node( spatial_node_index, - self.clip_scroll_tree, + &self.clip_scroll_tree, ); let snapped_clip_rect = snap_to_device.snap_rect(&clip_region.main); @@ -2713,7 +2713,7 @@ impl<'a> DisplayListFlattener<'a> { let snap_to_device = &mut self.sc_stack.last_mut().unwrap().snap_to_device; snap_to_device.set_target_spatial_node( pending_primitive.clip_and_scroll.spatial_node_index, - self.clip_scroll_tree + &self.clip_scroll_tree, ); // Offset the local rect and clip rect by the shadow offset. The pending