From 8f144969b4f5aa3abcf4412847f3f72e25c0db6d Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Thu, 3 Mar 2016 13:02:59 -0800 Subject: [PATCH] Flatten the WebRender API to allow us to use shared memory to transfer display lists. Improves performance significantly. --- Cargo.lock | 2 +- src/batch_builder.rs | 9 ++++-- src/frame.rs | 49 +++++++++++++++++++---------- src/internal_types.rs | 4 ++- src/lib.rs | 1 - src/node_compiler.rs | 26 +++++++++++++--- src/optimizer.rs | 72 ------------------------------------------- src/render_backend.rs | 19 +++++------- src/resource_cache.rs | 7 +++-- src/resource_list.rs | 29 ++++++++++++----- src/scene.rs | 58 ++++++++++++++++++---------------- 11 files changed, 127 insertions(+), 149 deletions(-) delete mode 100644 src/optimizer.rs diff --git a/Cargo.lock b/Cargo.lock index 6ff58b72d1..683f3924b5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -365,7 +365,7 @@ dependencies = [ [[package]] name = "webrender_traits" version = "0.1.0" -source = "git+https://github.com/servo/webrender_traits#2b94ca36e6f5e13abf14d242524b24b9cf0c7c79" +source = "git+https://github.com/servo/webrender_traits#94f16f55e65d735a9c1dc38733937cb2774322e1" dependencies = [ "app_units 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "core-graphics 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/src/batch_builder.rs b/src/batch_builder.rs index 9b5a472fc4..c29cc4cedc 100644 --- a/src/batch_builder.rs +++ b/src/batch_builder.rs @@ -23,10 +23,10 @@ use tessellator::{self, BorderCornerTessellation}; use texture_cache::{TextureCacheItem}; use util; use util::RectVaryings; -use webrender_traits::{ColorF, ImageFormat, BorderStyle, BoxShadowClipMode}; +use webrender_traits::{AuxiliaryLists, ColorF, ImageFormat, BorderStyle, BoxShadowClipMode}; use webrender_traits::{BorderSide, FontKey, GlyphInstance, ImageKey}; use webrender_traits::{BorderDisplayItem, GradientStop, ImageRendering}; -use webrender_traits::{WebGLContextId}; +use webrender_traits::{WebGLContextId, ItemRange}; const BORDER_DASH_SIZE: f32 = 3.0; @@ -525,9 +525,12 @@ impl<'a> BatchBuilder<'a> { rect: &Rect, start_point: &Point2D, end_point: &Point2D, - stops: &[GradientStop], + stops: &ItemRange, + auxiliary_lists: &AuxiliaryLists, resource_cache: &ResourceCache, frame_id: FrameId) { + let stops = auxiliary_lists.gradient_stops(stops); + // Fast paths for axis-aligned gradients: if start_point.x == end_point.x { let rect = Rect::new(Point2D::new(rect.origin.x, start_point.y), diff --git a/src/frame.rs b/src/frame.rs index 72ea0cdfe4..51aa0a2cd8 100644 --- a/src/frame.rs +++ b/src/frame.rs @@ -26,8 +26,9 @@ use std::hash::BuildHasherDefault; use std::mem; use texture_cache::TexturePage; use util; -use webrender_traits::{PipelineId, Epoch, ScrollPolicy, ScrollLayerId, StackingContext}; -use webrender_traits::{FilterOp, ImageFormat, MixBlendMode, StackingLevel, ScrollLayerInfo}; +use webrender_traits::{AuxiliaryLists, PipelineId, Epoch, ScrollPolicy, ScrollLayerId}; +use webrender_traits::{StackingContext, FilterOp, ImageFormat, MixBlendMode, StackingLevel}; +use webrender_traits::{ScrollLayerInfo}; #[derive(Copy, Clone, PartialEq, PartialOrd, Debug)] pub struct FrameId(pub u32); @@ -363,6 +364,9 @@ impl RenderTarget { pub struct Frame { pub layers: HashMap>, pub pipeline_epoch_map: HashMap>, + pub pipeline_auxiliary_lists: HashMap>, pub pending_updates: BatchUpdateList, pub root: Option, pub stacking_context_info: Vec, @@ -374,7 +378,7 @@ pub struct Frame { } enum SceneItemKind<'a> { - StackingContext(&'a SceneStackingContext), + StackingContext(&'a SceneStackingContext, PipelineId), Pipeline(&'a ScenePipeline) } @@ -394,7 +398,7 @@ impl<'a> SceneItemKind<'a> { let mut outlines = Vec::new(); let stacking_context = match *self { - SceneItemKind::StackingContext(stacking_context) => { + SceneItemKind::StackingContext(stacking_context, _) => { &stacking_context.stacking_context } SceneItemKind::Pipeline(pipeline) => { @@ -424,7 +428,7 @@ impl<'a> SceneItemKind<'a> { } StackingLevel::PositionedContent => { let z_index = match item.specific { - SpecificSceneItem::StackingContext(id) => { + SpecificSceneItem::StackingContext(id, _) => { scene.stacking_context_map .get(&id) .unwrap() @@ -486,7 +490,7 @@ impl<'a> SceneItemKind<'a> { trait StackingContextHelpers { fn needs_composition_operation_for_mix_blend_mode(&self) -> bool; - fn composition_operations(&self) -> Vec; + fn composition_operations(&self, auxiliary_lists: &AuxiliaryLists) -> Vec; } impl StackingContextHelpers for StackingContext { @@ -511,12 +515,12 @@ impl StackingContextHelpers for StackingContext { } } - fn composition_operations(&self) -> Vec { + fn composition_operations(&self, auxiliary_lists: &AuxiliaryLists) -> Vec { let mut composition_operations = vec![]; if self.needs_composition_operation_for_mix_blend_mode() { composition_operations.push(CompositionOp::MixBlend(self.mix_blend_mode)); } - for filter in &self.filters { + for filter in auxiliary_lists.filters(&self.filters) { match *filter { FilterOp::Blur(radius) => { composition_operations.push(CompositionOp::Filter(LowLevelFilterOp::Blur( @@ -571,6 +575,7 @@ impl Frame { Frame { pipeline_epoch_map: HashMap::with_hasher(Default::default()), pending_updates: BatchUpdateList::new(), + pipeline_auxiliary_lists: HashMap::with_hasher(Default::default()), root: None, layers: HashMap::with_hasher(Default::default()), stacking_context_info: Vec::new(), @@ -705,6 +710,8 @@ impl Frame { if let Some(root_pipeline) = scene.pipeline_map.get(&root_pipeline_id) { let old_layer_offsets = self.reset(resource_cache); + self.pipeline_auxiliary_lists = scene.pipeline_auxiliary_lists.clone(); + let root_stacking_context = scene.stacking_context_map .get(&root_pipeline.root_stacking_context_id) .unwrap(); @@ -842,13 +849,13 @@ impl Frame { item_index); } } - SpecificSceneItem::StackingContext(id) => { + SpecificSceneItem::StackingContext(id, pipeline_id) => { let stacking_context = context.scene .stacking_context_map .get(&id) .unwrap(); - let child = SceneItemKind::StackingContext(stacking_context); + let child = SceneItemKind::StackingContext(stacking_context, pipeline_id); self.flatten(child, info, context, @@ -914,15 +921,15 @@ impl Frame { level: i32) { let _pf = util::ProfileScope::new(" flatten"); - let (stacking_context, local_clip_rect) = match scene_item { - SceneItemKind::StackingContext(stacking_context) => { + let (stacking_context, local_clip_rect, pipeline_id) = match scene_item { + SceneItemKind::StackingContext(stacking_context, pipeline_id) => { let stacking_context = &stacking_context.stacking_context; let local_clip_rect = parent_info.current_clip_rect .translate(&-stacking_context.bounds.origin) .intersection(&stacking_context.overflow); - (stacking_context, local_clip_rect) + (stacking_context, local_clip_rect, pipeline_id) } SceneItemKind::Pipeline(pipeline) => { self.pipeline_epoch_map.insert(pipeline.pipeline_id, pipeline.epoch); @@ -932,14 +939,19 @@ impl Frame { .unwrap() .stacking_context; - (stacking_context, Some(MAX_RECT)) + (stacking_context, Some(MAX_RECT), pipeline.pipeline_id) } }; if let Some(local_clip_rect) = local_clip_rect { let scene_items = scene_item.collect_scene_items(&context.scene); if !scene_items.is_empty() { - let composition_operations = stacking_context.composition_operations(); + let composition_operations = { + let auxiliary_lists = self.pipeline_auxiliary_lists + .get(&pipeline_id) + .expect("No auxiliary lists?!"); + stacking_context.composition_operations(auxiliary_lists) + }; // Build world space transform let origin = parent_info.offset_from_current_layer + stacking_context.bounds.origin; @@ -1166,12 +1178,13 @@ impl Frame { for (_, layer) in &mut self.layers { let nodes = &mut layer.aabb_tree.nodes; + let pipeline_auxiliary_lists = &self.pipeline_auxiliary_lists; thread_pool.scoped(|scope| { for node in nodes { if node.is_visible && node.compiled_node.is_none() { scope.execute(move || { - node.build_resource_list(resource_cache); + node.build_resource_list(resource_cache, pipeline_auxiliary_lists); }); } } @@ -1211,6 +1224,7 @@ impl Frame { let stacking_context_info = &self.stacking_context_info; let draw_list_groups = &self.draw_list_groups; let frame_id = self.id; + let pipeline_auxiliary_lists = &self.pipeline_auxiliary_lists; thread_pool.scoped(|scope| { for (_, layer) in layers { @@ -1222,7 +1236,8 @@ impl Frame { frame_id, device_pixel_ratio, stacking_context_info, - draw_list_groups); + draw_list_groups, + pipeline_auxiliary_lists); }); } } diff --git a/src/internal_types.rs b/src/internal_types.rs index 584a6ec064..1521f41932 100644 --- a/src/internal_types.rs +++ b/src/internal_types.rs @@ -605,15 +605,17 @@ pub struct StackingContextInfo { pub struct DrawList { pub items: Vec, pub stacking_context_index: Option, + pub pipeline_id: PipelineId, // TODO(gw): Structure squat to remove this field. next_free_id: Option, } impl DrawList { - pub fn new(items: Vec) -> DrawList { + pub fn new(items: Vec, pipeline_id: PipelineId) -> DrawList { DrawList { items: items, stacking_context_index: None, + pipeline_id: pipeline_id, next_free_id: None, } } diff --git a/src/lib.rs b/src/lib.rs index c761807a8c..d3dc7af279 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -19,7 +19,6 @@ mod geometry; mod internal_types; mod layer; mod node_compiler; -mod optimizer; mod profiler; mod render_backend; mod resource_cache; diff --git a/src/node_compiler.rs b/src/node_compiler.rs index f37f1ee249..c41aa07c89 100644 --- a/src/node_compiler.rs +++ b/src/node_compiler.rs @@ -12,7 +12,7 @@ use internal_types::{DrawListGroupId}; use std::hash::BuildHasherDefault; use resource_cache::ResourceCache; use std::collections::HashMap; -use webrender_traits::SpecificDisplayItem; +use webrender_traits::{AuxiliaryLists, PipelineId, SpecificDisplayItem}; pub trait NodeCompiler { fn compile(&mut self, @@ -20,7 +20,12 @@ pub trait NodeCompiler { frame_id: FrameId, device_pixel_ratio: f32, stacking_context_info: &[StackingContextInfo], - draw_list_groups: &HashMap>); + draw_list_groups: &HashMap>, + pipeline_auxiliary_lists: &HashMap>); } impl NodeCompiler for AABBTreeNode { @@ -29,7 +34,12 @@ impl NodeCompiler for AABBTreeNode { frame_id: FrameId, device_pixel_ratio: f32, stacking_context_info: &[StackingContextInfo], - draw_list_groups: &HashMap>) { + draw_list_groups: &HashMap>, + pipeline_auxiliary_lists: &HashMap>) { let mut compiled_node = CompiledNode::new(); let mut vertex_buffer = VertexBuffer::new(); @@ -48,6 +58,9 @@ impl NodeCompiler for AABBTreeNode { if let Some(draw_list_index_buffer) = draw_list_index_buffer { let draw_list = resource_cache.get_draw_list(draw_list_index_buffer.draw_list_id); + let auxiliary_lists = + pipeline_auxiliary_lists.get(&draw_list.pipeline_id) + .expect("No auxiliary lists for pipeline?!"); let StackingContextIndex(stacking_context_id) = draw_list.stacking_context_index.unwrap(); let context = &stacking_context_info[stacking_context_id]; @@ -62,7 +75,8 @@ impl NodeCompiler for AABBTreeNode { if let Some(ref clip_rect) = clip_rect { builder.push_clip_in_rect(clip_rect); - builder.push_complex_clip(&display_item.clip.complex); + builder.push_complex_clip( + auxiliary_lists.complex_clip_regions(&display_item.clip.complex)); match display_item.item { SpecificDisplayItem::WebGL(ref info) => { @@ -80,12 +94,13 @@ impl NodeCompiler for AABBTreeNode { frame_id); } SpecificDisplayItem::Text(ref info) => { + let glyphs = auxiliary_lists.glyph_instances(&info.glyphs); builder.add_text(&display_item.rect, info.font_key, info.size, info.blur_radius, &info.color, - &info.glyphs, + &glyphs, resource_cache, frame_id, device_pixel_ratio); @@ -101,6 +116,7 @@ impl NodeCompiler for AABBTreeNode { &info.start_point, &info.end_point, &info.stops, + auxiliary_lists, resource_cache, frame_id); } diff --git a/src/optimizer.rs b/src/optimizer.rs deleted file mode 100644 index 559f160203..0000000000 --- a/src/optimizer.rs +++ /dev/null @@ -1,72 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * 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/. */ - -//! Display list optimization. -//! -//! This just applies a few heuristics to display lists to reduce performance hazards. - -use euclid::{Point2D, Rect, Size2D}; -use std::mem; -use webrender_traits::{DisplayItem, DisplayListBuilder}; -use webrender_traits::{ImageDisplayItem, SpecificDisplayItem, SpecificDisplayListItem}; - -pub const IMAGE_TILE_THRESHOLD: f32 = 5000.0; - -// TODO(gw): Store in each display list which lists have images, skip this step in common case. -// Or perhaps just do this in DisplayItem::add_image(). -fn optimize_draw_list(draw_list: &mut Vec) { - let old_draw_list = mem::replace(draw_list, Vec::new()); - - for item in old_draw_list.into_iter() { - match item.item { - SpecificDisplayItem::Image(ref image) => { - // Break up large tiled images into smaller ones so that large background images - // won't result in the construction of a whole bunch of needless vertices. - let tile_count = (item.rect.size.width / image.stretch_size.width).ceil() * - (item.rect.size.height / image.stretch_size.height).ceil(); - if tile_count > IMAGE_TILE_THRESHOLD { - let tile_size = (image.stretch_size.width * image.stretch_size.height * - IMAGE_TILE_THRESHOLD).sqrt(); - let tile_size = Size2D::new((tile_size / image.stretch_size.width).ceil() * - image.stretch_size.width, - (tile_size / image.stretch_size.height).ceil() * - image.stretch_size.height); - let mut y = item.rect.origin.y; - while y < item.rect.max_y() { - let mut x = item.rect.origin.x; - while x < item.rect.max_x() { - draw_list.push(DisplayItem { - item: SpecificDisplayItem::Image(ImageDisplayItem { - image_key: image.image_key, - stretch_size: image.stretch_size, - image_rendering: image.image_rendering, - }), - rect: Rect::new(Point2D::new(x, y), tile_size), - clip: item.clip.clone(), - }); - x += tile_size.width; - } - y += tile_size.height; - } - continue - } - } - _ => {} - } - - draw_list.push(item); - } -} - -pub fn optimize_display_list_builder(display_list_builder: &mut DisplayListBuilder) { - for item in &mut display_list_builder.items { - match item.specific { - SpecificDisplayListItem::DrawList(ref mut info) => { - optimize_draw_list(&mut info.items); - } - SpecificDisplayListItem::StackingContext(..) | - SpecificDisplayListItem::Iframe(..) => {} - } - } -} diff --git a/src/render_backend.rs b/src/render_backend.rs index af87ce6b28..0a29355157 100644 --- a/src/render_backend.rs +++ b/src/render_backend.rs @@ -78,7 +78,6 @@ impl RenderBackend { loop { let msg = self.api_rx.recv(); - match msg { Ok(msg) => { match msg { @@ -106,20 +105,14 @@ impl RenderBackend { format, bytes); } - ApiMsg::AddDisplayList(id, - pipeline_id, - epoch, - display_list_builder) => { + ApiMsg::AddDisplayList(id, pipeline_id, epoch, built_display_list) => { self.scene.add_display_list(id, pipeline_id, epoch, - display_list_builder, + built_display_list, &mut self.resource_cache); } - ApiMsg::AddStackingContext(id, - pipeline_id, - epoch, - stacking_context) => { + ApiMsg::AddStackingContext(id, pipeline_id, epoch, stacking_context) => { self.scene.add_stacking_context(id, pipeline_id, epoch, @@ -137,14 +130,16 @@ impl RenderBackend { background_color, epoch, pipeline_id, - viewport_size) => { + viewport_size, + auxiliary_lists) => { let frame = profile_counters.total_time.profile(|| { self.scene.set_root_stacking_context(pipeline_id, epoch, stacking_context_id, background_color, viewport_size, - &mut self.resource_cache); + &mut self.resource_cache, + auxiliary_lists); self.build_scene(); self.render() diff --git a/src/resource_cache.rs b/src/resource_cache.rs index eb1aaaa765..1b4e063664 100644 --- a/src/resource_cache.rs +++ b/src/resource_cache.rs @@ -27,7 +27,7 @@ use std::time::Duration; use texture_cache::{TextureCache, TextureCacheItem, TextureCacheItemId}; use texture_cache::{BorderType, TextureInsertOp}; use webrender_traits::{Epoch, FontKey, ImageKey, ImageFormat, DisplayItem, ImageRendering}; -use webrender_traits::{WebGLContextId}; +use webrender_traits::{PipelineId, WebGLContextId}; static FONT_CONTEXT_COUNT: AtomicUsize = ATOMIC_USIZE_INIT; @@ -361,8 +361,9 @@ impl ResourceCache { return } - pub fn add_draw_list(&mut self, items: Vec) -> DrawListId { - self.draw_lists.insert(DrawList::new(items)) + pub fn add_draw_list(&mut self, items: Vec, pipeline_id: PipelineId) + -> DrawListId { + self.draw_lists.insert(DrawList::new(items, pipeline_id)) } pub fn get_draw_list(&self, draw_list_id: DrawListId) -> &DrawList { diff --git a/src/resource_list.rs b/src/resource_list.rs index f06f984af0..af8d7aba22 100644 --- a/src/resource_list.rs +++ b/src/resource_list.rs @@ -14,8 +14,9 @@ use std::collections::{HashMap, HashSet}; use std::collections::hash_map::Entry::{Occupied, Vacant}; use std::hash::BuildHasherDefault; use tessellator; -use webrender_traits::{BorderRadius, BorderStyle, BoxShadowClipMode, ImageRendering}; -use webrender_traits::{FontKey, ImageFormat, ImageKey, SpecificDisplayItem}; +use webrender_traits::{AuxiliaryLists, BorderRadius, BorderStyle, BoxShadowClipMode}; +use webrender_traits::{FontKey, ImageFormat, ImageKey, ImageRendering, PipelineId}; +use webrender_traits::{SpecificDisplayItem}; type RequiredImageSet = HashSet<(ImageKey, ImageRendering), BuildHasherDefault>; type RequiredGlyphMap = HashMap, BuildHasherDefault>; @@ -143,11 +144,19 @@ impl ResourceList { } pub trait BuildRequiredResources { - fn build_resource_list(&mut self, resource_cache: &ResourceCache); + fn build_resource_list(&mut self, + resource_cache: &ResourceCache, + pipeline_auxiliary_lists: &HashMap>); } impl BuildRequiredResources for AABBTreeNode { - fn build_resource_list(&mut self, resource_cache: &ResourceCache) { + fn build_resource_list(&mut self, + resource_cache: &ResourceCache, + pipeline_auxiliary_lists: &HashMap>) { //let _pf = util::ProfileScope::new(" build_resource_list"); let mut resource_list = ResourceList::new(resource_cache.device_pixel_ratio()); @@ -158,10 +167,15 @@ impl BuildRequiredResources for AABBTreeNode { for index in &draw_list_index_buffer.indices { let DrawListItemIndex(index) = *index; let display_item = &draw_list.items[index as usize]; + let auxiliary_lists = + pipeline_auxiliary_lists.get(&draw_list.pipeline_id) + .expect("No auxiliary lists for pipeline?!"); // Handle border radius for complex clipping regions. - for complex_clip_region in &display_item.clip.complex { - resource_list.add_radius_raster_for_border_radii(&complex_clip_region.radii); + for complex_clip_region in + auxiliary_lists.complex_clip_regions(&display_item.clip.complex) { + resource_list.add_radius_raster_for_border_radii( + &complex_clip_region.radii); } match display_item.item { @@ -169,7 +183,8 @@ impl BuildRequiredResources for AABBTreeNode { resource_list.add_image(info.image_key, info.image_rendering); } SpecificDisplayItem::Text(ref info) => { - for glyph in &info.glyphs { + let glyphs = auxiliary_lists.glyph_instances(&info.glyphs); + for glyph in glyphs { let glyph = Glyph::new(info.size, info.blur_radius, glyph.index); resource_list.add_glyph(info.font_key, glyph); } diff --git a/src/scene.rs b/src/scene.rs index e155baef59..44c4588900 100644 --- a/src/scene.rs +++ b/src/scene.rs @@ -5,12 +5,10 @@ use euclid::Size2D; use fnv::FnvHasher; use internal_types::DrawListId; -use optimizer; use resource_cache::ResourceCache; use std::collections::HashMap; use std::hash::BuildHasherDefault; -use webrender_traits::{PipelineId, Epoch}; -use webrender_traits::{DisplayListBuilder}; +use webrender_traits::{AuxiliaryLists, BuiltDisplayList, ItemRange, PipelineId, Epoch}; use webrender_traits::{ColorF, DisplayListId, StackingContext, StackingContextId}; use webrender_traits::{SpecificDisplayListItem}; use webrender_traits::{StackingLevel, SpecificDisplayItem}; @@ -30,6 +28,9 @@ pub struct Scene { pub root_pipeline_id: Option, pub pipeline_map: HashMap>, pub pipeline_sizes: HashMap>, + pub pipeline_auxiliary_lists: HashMap>, pub display_list_map: HashMap>, pub stacking_context_map: HashMap>, } @@ -37,8 +38,8 @@ pub struct Scene { #[derive(Clone, Debug)] pub enum SpecificSceneItem { DrawList(DrawListId), - StackingContext(StackingContextId), - Iframe(Box), + StackingContext(StackingContextId, PipelineId), + Iframe(IframeInfo), } #[derive(Clone, Debug)] @@ -65,39 +66,39 @@ impl Scene { root_pipeline_id: None, pipeline_sizes: HashMap::new(), pipeline_map: HashMap::with_hasher(Default::default()), + pipeline_auxiliary_lists: HashMap::with_hasher(Default::default()), display_list_map: HashMap::with_hasher(Default::default()), stacking_context_map: HashMap::with_hasher(Default::default()), } } pub fn add_display_list(&mut self, - id: DisplayListId, - pipeline_id: PipelineId, - epoch: Epoch, - mut display_list_builder: DisplayListBuilder, - resource_cache: &mut ResourceCache) { - display_list_builder.finalize(); - optimizer::optimize_display_list_builder(&mut display_list_builder); - - let items = display_list_builder.items.into_iter().map(|item| { + id: DisplayListId, + pipeline_id: PipelineId, + epoch: Epoch, + built_display_list: BuiltDisplayList, + resource_cache: &mut ResourceCache) { + let items = built_display_list.display_list_items().iter().map(|item| { match item.specific { - SpecificDisplayListItem::DrawList(info) => { - let draw_list_id = resource_cache.add_draw_list(info.items); + SpecificDisplayListItem::DrawList(ref info) => { + let draw_list_id = resource_cache.add_draw_list( + built_display_list.display_items(&info.items).to_vec(), + pipeline_id); SceneItem { stacking_level: item.stacking_level, specific: SpecificSceneItem::DrawList(draw_list_id) } } - SpecificDisplayListItem::StackingContext(info) => { + SpecificDisplayListItem::StackingContext(ref info) => { SceneItem { stacking_level: item.stacking_level, - specific: SpecificSceneItem::StackingContext(info.id) + specific: SpecificSceneItem::StackingContext(info.id, pipeline_id) } } - SpecificDisplayListItem::Iframe(info) => { + SpecificDisplayListItem::Iframe(ref info) => { SceneItem { stacking_level: item.stacking_level, - specific: SpecificSceneItem::Iframe(info) + specific: SpecificSceneItem::Iframe(*info) } } } @@ -113,10 +114,10 @@ impl Scene { } pub fn add_stacking_context(&mut self, - id: StackingContextId, - pipeline_id: PipelineId, - epoch: Epoch, - stacking_context: StackingContext) { + id: StackingContextId, + pipeline_id: PipelineId, + epoch: Epoch, + stacking_context: StackingContext) { let stacking_context = SceneStackingContext { pipeline_id: pipeline_id, epoch: epoch, @@ -136,7 +137,10 @@ impl Scene { stacking_context_id: StackingContextId, background_color: ColorF, viewport_size: Size2D, - resource_cache: &mut ResourceCache) { + resource_cache: &mut ResourceCache, + auxiliary_lists: AuxiliaryLists) { + self.pipeline_auxiliary_lists.insert(pipeline_id, auxiliary_lists); + let old_display_list_keys: Vec<_> = self.display_list_map.iter() .filter(|&(_, ref v)| { v.pipeline_id == pipeline_id && @@ -183,7 +187,7 @@ impl Scene { }; let clip = ClipRegion { main: overflow, - complex: vec![], + complex: ItemRange::empty(), }; let root_bg_color_item = DisplayItem { item: SpecificDisplayItem::Rectangle(rectangle_item), @@ -191,7 +195,7 @@ impl Scene { clip: clip, }; - let draw_list_id = resource_cache.add_draw_list(vec![root_bg_color_item]); + let draw_list_id = resource_cache.add_draw_list(vec![root_bg_color_item], pipeline_id); Some(draw_list_id) } else { None