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
This commit is contained in:
Nicolas Silva 2019-09-17 09:20:03 +00:00
Родитель 823e2e6a75
Коммит 3a51eac38e
15 изменённых файлов: 275 добавлений и 356 удалений

Просмотреть файл

@ -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,

Просмотреть файл

@ -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,

Просмотреть файл

@ -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<ColorF>,
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<HitTestingScene>,
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<ColorF>,
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<PipelineId, Arc<ScenePipeline>>,
resource_cache: &mut ResourceCache,
gpu_cache: &mut GpuCache,
render_tasks: &mut RenderTaskGraph,
@ -323,34 +240,34 @@ impl FrameBuilder {
) -> Option<RenderTaskId> {
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<PipelineId, Arc<ScenePipeline>>,
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.

Просмотреть файл

@ -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;

Просмотреть файл

@ -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;

Просмотреть файл

@ -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};

Просмотреть файл

@ -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};

Просмотреть файл

@ -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;

Просмотреть файл

@ -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<P>
/// see SceneBuilder::add_primitive<P>
pub trait InternablePrimitive: intern::Internable<InternData = PrimitiveSceneData> + Sized {
/// Build a new key from self with `info`.
fn into_key(

Просмотреть файл

@ -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};

Просмотреть файл

@ -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;

Просмотреть файл

@ -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<FrameBuilder>,
// 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<PipelineId>,
/// 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<SpatialNodeIndex>,
) -> 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<ScrollNodeState> {
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::<PlainRenderBackend, _>(root, "backend")
@ -1871,14 +1847,16 @@ impl RenderBackend {
let data_stores = CaptureConfig::deserialize::<DataStores, _>(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(),

Просмотреть файл

@ -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<ColorF>,
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<HitTestingScene>,
}
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(),
}
}
}

Просмотреть файл

@ -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<Box<Transaction>>),
@ -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(),

Просмотреть файл

@ -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<PipelineId>,
/// 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<ClipChainId>,
/// 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<PipelineId>,
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