diff --git a/Cargo.lock b/Cargo.lock index e37f883e38..7e1dd0c3ac 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -21,8 +21,8 @@ dependencies = [ "serde_json 0.9.8 (registry+https://github.com/rust-lang/crates.io-index)", "servo-glutin 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)", - "webrender 0.24.0", - "webrender_traits 0.25.0", + "webrender 0.25.0", + "webrender_traits 0.26.0", "yaml-rust 0.3.4 (git+https://github.com/vvuk/yaml-rust)", ] @@ -886,7 +886,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "webrender" -version = "0.24.0" +version = "0.25.0" dependencies = [ "angle 0.1.2 (git+https://github.com/servo/angle?branch=servo)", "app_units 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -909,12 +909,12 @@ dependencies = [ "thread_profiler 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "threadpool 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)", - "webrender_traits 0.25.0", + "webrender_traits 0.26.0", ] [[package]] name = "webrender_traits" -version = "0.25.0" +version = "0.26.0" dependencies = [ "app_units 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -947,8 +947,8 @@ dependencies = [ "euclid 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "gleam 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "servo-glutin 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", - "webrender 0.24.0", - "webrender_traits 0.25.0", + "webrender 0.25.0", + "webrender_traits 0.26.0", ] [[package]] diff --git a/webrender/Cargo.toml b/webrender/Cargo.toml index fe01433b37..ef576dde0c 100644 --- a/webrender/Cargo.toml +++ b/webrender/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "webrender" -version = "0.24.0" +version = "0.25.0" authors = ["Glenn Watson "] license = "MPL-2.0" repository = "https://github.com/servo/webrender" diff --git a/webrender/src/clip_scroll_node.rs b/webrender/src/clip_scroll_node.rs index ed6a3c07ea..1adf6a2cdb 100644 --- a/webrender/src/clip_scroll_node.rs +++ b/webrender/src/clip_scroll_node.rs @@ -13,7 +13,7 @@ use util::TransformedRect; use webrender_traits::{ClipRegion, LayerPixel, LayerPoint, LayerRect, LayerSize}; use webrender_traits::{LayerToScrollTransform, LayerToWorldTransform, PipelineId}; use webrender_traits::{ScrollEventPhase, ScrollLayerId, ScrollLayerRect, ScrollLocation}; -use webrender_traits::{ServoScrollRootId, WorldPoint, WorldPoint4D}; +use webrender_traits::{WorldPoint, WorldPoint4D}; #[cfg(target_os = "macos")] const CAN_OVERSCROLL: bool = true; @@ -38,17 +38,12 @@ pub struct ClipInfo { /// which depends on the screen rectangle and the transformation of all of /// the parents. pub xf_rect: Option, - - /// An external identifier that is used to scroll this clipping node - /// from the API. - pub scroll_root_id: Option, } impl ClipInfo { pub fn new(clip_region: &ClipRegion, clip_store: &mut VertexDataStore, - packed_layer_index: PackedLayerIndex, - scroll_root_id: Option) + packed_layer_index: PackedLayerIndex,) -> ClipInfo { // We pass true here for the MaskCacheInfo because this type of // mask needs an extra clip for the clip rectangle. @@ -58,7 +53,6 @@ impl ClipInfo { clip_source: clip_source, packed_layer_index: packed_layer_index, xf_rect: None, - scroll_root_id: scroll_root_id, } } @@ -195,6 +189,15 @@ impl ClipScrollNode { } pub fn set_scroll_origin(&mut self, origin: &LayerPoint) -> bool { + match self.node_type { + NodeType::ReferenceFrame(_) => { + warn!("Tried to scroll a reference frame."); + return false; + } + NodeType::Clip(_) => {} + }; + + let scrollable_height = self.scrollable_height(); let scrollable_width = self.scrollable_width(); if scrollable_height <= 0. && scrollable_width <= 0. { diff --git a/webrender/src/clip_scroll_tree.rs b/webrender/src/clip_scroll_tree.rs index 4e3d7df17c..541ab7db9b 100644 --- a/webrender/src/clip_scroll_tree.rs +++ b/webrender/src/clip_scroll_tree.rs @@ -7,15 +7,14 @@ use fnv::FnvHasher; use std::collections::{HashMap, HashSet}; use std::hash::BuildHasherDefault; use webrender_traits::{LayerPoint, LayerRect, LayerToScrollTransform, LayerToWorldTransform}; -use webrender_traits::{PipelineId, ScrollEventPhase, ScrollLayerId, ScrollLayerInfo}; -use webrender_traits::{ScrollLayerRect, ScrollLayerState, ScrollLocation, ServoScrollRootId}; -use webrender_traits::{WorldPoint, as_scroll_parent_rect}; +use webrender_traits::{PipelineId, ScrollEventPhase, ScrollLayerId, ScrollLayerRect}; +use webrender_traits::{ScrollLayerState, ScrollLocation, WorldPoint, as_scroll_parent_rect}; pub type ScrollStates = HashMap>; pub struct ClipScrollTree { pub nodes: HashMap>, - pub pending_scroll_offsets: HashMap<(PipelineId, ServoScrollRootId), LayerPoint>, + pub pending_scroll_offsets: HashMap, /// The ScrollLayerId of the currently scrolling node. Used to allow the same /// node to scroll even if a touch operation leaves the boundaries of that node. @@ -90,7 +89,7 @@ impl ClipScrollTree { } } - if let ScrollLayerInfo::ReferenceFrame(_) = scroll_layer_id.info { + if scroll_layer_id.is_reference_frame() { return None; } @@ -109,15 +108,10 @@ impl ClipScrollTree { pub fn get_scroll_node_state(&self) -> Vec { let mut result = vec![]; - for (_, node) in self.nodes.iter() { + for (id, node) in self.nodes.iter() { match node.node_type { - NodeType::Clip(ref info) if info.scroll_root_id.is_some() => { - result.push(ScrollLayerState { - pipeline_id: node.pipeline_id, - scroll_root_id: info.scroll_root_id.unwrap(), - scroll_offset: node.scrolling.offset, - }) - } + NodeType::Clip(_) => result.push( + ScrollLayerState { id: *id, scroll_offset: node.scrolling.offset }), _ => {}, } } @@ -129,7 +123,7 @@ impl ClipScrollTree { let mut scroll_states = HashMap::with_hasher(Default::default()); for (layer_id, old_node) in &mut self.nodes.drain() { - if !self.pipelines_to_discard.contains(&layer_id.pipeline_id) { + if !self.pipelines_to_discard.contains(&layer_id.pipeline_id()) { scroll_states.insert(layer_id, old_node.scrolling); } } @@ -138,40 +132,24 @@ impl ClipScrollTree { scroll_states } - pub fn scroll_nodes(&mut self, - origin: LayerPoint, - pipeline_id: PipelineId, - scroll_root_id: ServoScrollRootId) - -> bool { - if self.nodes.is_empty() { - self.pending_scroll_offsets.insert((pipeline_id, scroll_root_id), origin); + pub fn scroll_nodes(&mut self, origin: LayerPoint, id: ScrollLayerId) -> bool { + if id.is_reference_frame() { + warn!("Tried to scroll a reference frame."); return false; } - let origin = LayerPoint::new(origin.x.max(0.0), origin.y.max(0.0)); - - let mut scrolled_a_node = false; - let mut found_node = false; - for (layer_id, node) in self.nodes.iter_mut() { - if layer_id.pipeline_id != pipeline_id { - continue; - } - - match node.node_type { - NodeType::Clip(ref info) if info.scroll_root_id != Some(scroll_root_id) => continue, - NodeType::ReferenceFrame(..) => continue, - NodeType::Clip(_) => {}, - } - - found_node = true; - scrolled_a_node |= node.set_scroll_origin(&origin); + if self.nodes.is_empty() { + self.pending_scroll_offsets.insert(id, origin); + return false; } - if !found_node { - self.pending_scroll_offsets.insert((pipeline_id, scroll_root_id), origin); + let origin = LayerPoint::new(origin.x.max(0.0), origin.y.max(0.0)); + if let Some(node) = self.nodes.get_mut(&id) { + return node.set_scroll_origin(&origin); } - scrolled_a_node + self.pending_scroll_offsets.insert(id, origin); + false } pub fn scroll(&mut self, @@ -244,37 +222,7 @@ impl ClipScrollTree { scroll_layer_id }; - // TODO(mrobinson): Once we remove the concept of shared scroll root ids we can remove - // this entirely and just scroll the node based on the ScrollLayerId. - let scroll_root_id = { - let node = self.nodes.get_mut(&scroll_layer_id).unwrap(); - let scroll_root_id = match node.node_type { - NodeType::Clip(ref info) => info.scroll_root_id, - NodeType::ReferenceFrame(..) => unreachable!("Tried to scroll a reference frame."), - }; - - if scroll_root_id.is_none() { - return node.scroll(scroll_location, phase); - } - - scroll_root_id - }; - - let mut scrolled_a_node = false; - for (layer_id, node) in self.nodes.iter_mut() { - if layer_id.pipeline_id != scroll_layer_id.pipeline_id { - continue; - } - - match node.node_type { - NodeType::Clip(ref info) if info.scroll_root_id == scroll_root_id => { } - _ => continue, - } - - let scrolled_this_node = node.scroll(scroll_location, phase); - scrolled_a_node = scrolled_a_node || scrolled_this_node; - } - scrolled_a_node + self.nodes.get_mut(&scroll_layer_id).unwrap().scroll(scroll_location, phase) } pub fn update_all_node_transforms(&mut self, pan: LayerPoint) { @@ -351,16 +299,7 @@ impl ClipScrollTree { node.finalize(&scrolling_state); - let scroll_root_id = match node.node_type { - NodeType::Clip(ref info) if info.scroll_root_id.is_some() => - info.scroll_root_id.unwrap(), - _ => continue, - }; - - - let pipeline_id = scroll_layer_id.pipeline_id; - if let Some(pending_offset) = - self.pending_scroll_offsets.remove(&(pipeline_id, scroll_root_id)) { + if let Some(pending_offset) = self.pending_scroll_offsets.remove(&scroll_layer_id) { node.set_scroll_origin(&pending_offset); } } @@ -373,10 +312,9 @@ impl ClipScrollTree { pipeline_id: PipelineId, parent_id: Option) -> ScrollLayerId { - let reference_frame_id = ScrollLayerId { - pipeline_id: pipeline_id, - info: ScrollLayerInfo::ReferenceFrame(self.current_reference_frame_id), - }; + + let reference_frame_id = + ScrollLayerId::ReferenceFrame(self.current_reference_frame_id, pipeline_id); self.current_reference_frame_id += 1; let node = ClipScrollNode::new_reference_frame(parent_id, @@ -403,7 +341,7 @@ impl ClipScrollTree { self.pipelines_to_discard.insert(pipeline_id); match self.current_scroll_layer_id { - Some(id) if id.pipeline_id == pipeline_id => self.current_scroll_layer_id = None, + Some(id) if id.pipeline_id() == pipeline_id => self.current_scroll_layer_id = None, _ => {} } } diff --git a/webrender/src/frame.rs b/webrender/src/frame.rs index d5c1f421fa..0d8ed3cf01 100644 --- a/webrender/src/frame.rs +++ b/webrender/src/frame.rs @@ -20,8 +20,8 @@ use webrender_traits::{AuxiliaryLists, ClipDisplayItem, ClipRegion, ColorF, Devi use webrender_traits::{DeviceUintSize, DisplayItem, Epoch, FilterOp, ImageDisplayItem, LayerPoint}; use webrender_traits::{LayerRect, LayerSize, LayerToScrollTransform, LayoutTransform}; use webrender_traits::{MixBlendMode, PipelineId, ScrollEventPhase, ScrollLayerId}; -use webrender_traits::{ScrollLayerState, ScrollLocation, ScrollPolicy, ServoScrollRootId}; -use webrender_traits::{SpecificDisplayItem, StackingContext, TileOffset, WorldPoint}; +use webrender_traits::{ScrollLayerState, ScrollLocation, ScrollPolicy, SpecificDisplayItem}; +use webrender_traits::{StackingContext, TileOffset, WorldPoint}; #[derive(Copy, Clone, PartialEq, PartialOrd, Debug)] pub struct FrameId(pub u32); @@ -231,12 +231,8 @@ impl Frame { } /// Returns true if any nodes actually changed position or false otherwise. - pub fn scroll_nodes(&mut self, - origin: LayerPoint, - pipeline_id: PipelineId, - scroll_root_id: ServoScrollRootId) - -> bool { - self.clip_scroll_tree.scroll_nodes(origin, pipeline_id, scroll_root_id) + pub fn scroll_nodes(&mut self, origin: LayerPoint, id: ScrollLayerId) -> bool { + self.clip_scroll_tree.scroll_nodes(origin, id) } /// Returns true if any nodes actually changed position or false otherwise. @@ -349,7 +345,6 @@ impl Frame { pipeline_id, &clip_rect, &item.content_size, - item.scroll_root_id, clip, &mut self.clip_scroll_tree); @@ -522,7 +517,6 @@ impl Frame { pipeline_id, &LayerRect::new(LayerPoint::zero(), iframe_rect.size), &iframe_clip.main.size, - Some(ServoScrollRootId(0)), iframe_clip, &mut self.clip_scroll_tree); diff --git a/webrender/src/frame_builder.rs b/webrender/src/frame_builder.rs index 704d226eab..51ab2f3e99 100644 --- a/webrender/src/frame_builder.rs +++ b/webrender/src/frame_builder.rs @@ -33,8 +33,7 @@ use webrender_traits::{BoxShadowClipMode, ClipRegion, ColorF, DeviceIntPoint, De use webrender_traits::{DeviceIntSize, DeviceUintRect, DeviceUintSize, ExtendMode, FontKey}; use webrender_traits::{FontRenderMode, GlyphOptions, ImageKey, ImageRendering, ItemRange}; use webrender_traits::{LayerPoint, LayerRect, LayerSize, LayerToScrollTransform, PipelineId}; -use webrender_traits::{RepeatMode, ScrollLayerId, ServoScrollRootId, TileOffset, WebGLContextId}; -use webrender_traits::YuvColorSpace; +use webrender_traits::{RepeatMode, ScrollLayerId, TileOffset, WebGLContextId, YuvColorSpace}; #[derive(Debug, Clone)] struct ImageBorderSegment { @@ -309,7 +308,6 @@ impl FrameBuilder { pipeline_id, &viewport_rect, content_size, - Some(ServoScrollRootId(0)), &ClipRegion::simple(&viewport_rect), clip_scroll_tree); topmost_scroll_layer_id @@ -321,13 +319,11 @@ impl FrameBuilder { pipeline_id: PipelineId, local_viewport_rect: &LayerRect, content_size: &LayerSize, - scroll_root_id: Option, clip_region: &ClipRegion, clip_scroll_tree: &mut ClipScrollTree) { let clip_info = ClipInfo::new(clip_region, &mut self.prim_store.gpu_data32, - PackedLayerIndex(self.packed_layers.len()), - scroll_root_id); + PackedLayerIndex(self.packed_layers.len())); let node = ClipScrollNode::new(pipeline_id, parent_id, local_viewport_rect, diff --git a/webrender/src/render_backend.rs b/webrender/src/render_backend.rs index e83bfd2cbd..84cc5883fb 100644 --- a/webrender/src/render_backend.rs +++ b/webrender/src/render_backend.rs @@ -260,12 +260,12 @@ impl RenderBackend { None => self.notify_compositor_of_new_scroll_frame(false), } } - ApiMsg::ScrollLayersWithScrollId(origin, pipeline_id, scroll_root_id) => { - profile_scope!("ScrollLayersWithScrollId"); + ApiMsg::ScrollLayerWithId(origin, id) => { + profile_scope!("ScrollLayerWithScrollId"); let frame = { let counters = &mut profile_counters.texture_cache; profile_counters.total_time.profile(|| { - if self.frame.scroll_nodes(origin, pipeline_id, scroll_root_id) { + if self.frame.scroll_nodes(origin, id) { Some(self.render(counters)) } else { None diff --git a/webrender_traits/Cargo.toml b/webrender_traits/Cargo.toml index b695dfd257..5b14e03b70 100644 --- a/webrender_traits/Cargo.toml +++ b/webrender_traits/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "webrender_traits" -version = "0.25.0" +version = "0.26.0" authors = ["Glenn Watson "] license = "MPL-2.0" repository = "https://github.com/servo/webrender" diff --git a/webrender_traits/src/api.rs b/webrender_traits/src/api.rs index c0b21ac859..15a3f545d2 100644 --- a/webrender_traits/src/api.rs +++ b/webrender_traits/src/api.rs @@ -6,14 +6,12 @@ use byteorder::{LittleEndian, WriteBytesExt}; use channel::{self, MsgSender, PayloadHelperMethods, PayloadSender}; use offscreen_gl_context::{GLContextAttributes, GLLimits}; use std::cell::Cell; -use {ColorF, ImageDescriptor}; -use {FontKey, ImageKey, NativeFontHandle, ServoScrollRootId}; -use {GlyphKey, GlyphDimensions, ImageData, WebGLContextId, WebGLCommand}; -use {DeviceIntSize, LayoutPoint, LayoutSize, WorldPoint}; -use {DeviceIntPoint, DeviceUintRect, DeviceUintSize, LayoutTransform}; -use {BuiltDisplayList, BuiltDisplayListDescriptor, AuxiliaryLists, AuxiliaryListsDescriptor}; use std::fmt; use std::marker::PhantomData; +use {AuxiliaryLists, AuxiliaryListsDescriptor, BuiltDisplayList, BuiltDisplayListDescriptor}; +use {ColorF, DeviceIntPoint, DeviceIntSize, DeviceUintRect, DeviceUintSize, FontKey}; +use {GlyphDimensions, GlyphKey, ImageData, ImageDescriptor, ImageKey, LayoutPoint, LayoutSize}; +use {LayoutTransform, NativeFontHandle, ScrollLayerId, WebGLCommand, WebGLContextId, WorldPoint}; pub type TileSize = u16; @@ -48,7 +46,7 @@ pub enum ApiMsg { SetRootPipeline(PipelineId), SetWindowParameters(DeviceUintSize, DeviceUintRect), Scroll(ScrollLocation, WorldPoint, ScrollEventPhase), - ScrollLayersWithScrollId(LayoutPoint, PipelineId, ServoScrollRootId), + ScrollLayerWithId(LayoutPoint, ScrollLayerId), TickScrollingBounce, TranslatePointToLayerSpace(WorldPoint, MsgSender<(LayoutPoint, PipelineId)>), GetScrollLayerState(MsgSender>), @@ -79,7 +77,7 @@ impl fmt::Debug for ApiMsg { &ApiMsg::SetRootDisplayList(..) => { write!(f, "ApiMsg::SetRootDisplayList") } &ApiMsg::SetRootPipeline(..) => { write!(f, "ApiMsg::SetRootPipeline") } &ApiMsg::Scroll(..) => { write!(f, "ApiMsg::Scroll") } - &ApiMsg::ScrollLayersWithScrollId(..) => { write!(f, "ApiMsg::ScrollLayersWithScrollId") } + &ApiMsg::ScrollLayerWithId(..) => { write!(f, "ApiMsg::ScrollLayerWithId") } &ApiMsg::TickScrollingBounce => { write!(f, "ApiMsg::TickScrollingBounce") } &ApiMsg::TranslatePointToLayerSpace(..) => { write!(f, "ApiMsg::TranslatePointToLayerSpace") } &ApiMsg::GetScrollLayerState(..) => { write!(f, "ApiMsg::GetScrollLayerState") } @@ -310,11 +308,8 @@ impl RenderApi { self.api_sender.send(msg).unwrap(); } - pub fn scroll_layers_with_scroll_root_id(&self, - new_scroll_origin: LayoutPoint, - pipeline_id: PipelineId, - scroll_root_id: ServoScrollRootId) { - let msg = ApiMsg::ScrollLayersWithScrollId(new_scroll_origin, pipeline_id, scroll_root_id); + pub fn scroll_layer_with_id(&self, new_scroll_origin: LayoutPoint, id: ScrollLayerId) { + let msg = ApiMsg::ScrollLayerWithId(new_scroll_origin, id); self.api_sender.send(msg).unwrap(); } @@ -436,8 +431,7 @@ pub enum ScrollEventPhase { #[derive(Clone, Deserialize, Serialize)] pub struct ScrollLayerState { - pub pipeline_id: PipelineId, - pub scroll_root_id: ServoScrollRootId, + pub id: ScrollLayerId, pub scroll_offset: LayoutPoint, } diff --git a/webrender_traits/src/display_item.rs b/webrender_traits/src/display_item.rs index 1d97a89335..e562249c55 100644 --- a/webrender_traits/src/display_item.rs +++ b/webrender_traits/src/display_item.rs @@ -46,7 +46,6 @@ pub struct ClipDisplayItem { pub content_size: LayoutSize, pub id: ScrollLayerId, pub parent_id: ScrollLayerId, - pub scroll_root_id: Option, } #[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)] @@ -509,48 +508,45 @@ impl ComplexClipRegion { } } -#[repr(C)] -#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)] -pub struct ServoScrollRootId(pub usize); - #[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)] -pub struct ScrollLayerId { - pub pipeline_id: PipelineId, - pub info: ScrollLayerInfo, +pub enum ScrollLayerId { + Clip(usize, PipelineId), + ClipExternalId(usize, PipelineId), + ReferenceFrame(usize, PipelineId), } impl ScrollLayerId { pub fn root_scroll_layer(pipeline_id: PipelineId) -> ScrollLayerId { - ScrollLayerId { - pipeline_id: pipeline_id, - info: ScrollLayerInfo::Scrollable(0), - } + ScrollLayerId::Clip(0, pipeline_id) } pub fn root_reference_frame(pipeline_id: PipelineId) -> ScrollLayerId { - ScrollLayerId { - pipeline_id: pipeline_id, - info: ScrollLayerInfo::ReferenceFrame(0), + ScrollLayerId::ReferenceFrame(0, pipeline_id) + } + + pub fn new(id: usize, pipeline_id: PipelineId) -> ScrollLayerId { + ScrollLayerId::ClipExternalId(id, pipeline_id) + } + + pub fn pipeline_id(&self) -> PipelineId { + match *self { + ScrollLayerId::Clip(_, pipeline_id) => pipeline_id, + ScrollLayerId::ClipExternalId(_, pipeline_id) => pipeline_id, + ScrollLayerId::ReferenceFrame(_, pipeline_id) => pipeline_id, } } pub fn is_reference_frame(&self) -> bool { - match self.info { - ScrollLayerInfo::Scrollable(..) => false, - ScrollLayerInfo::ReferenceFrame(..) => true, + match *self { + ScrollLayerId::ReferenceFrame(..) => true, + _ => false, } } - pub fn new(pipeline_id: PipelineId, index: usize) -> ScrollLayerId { - ScrollLayerId { - pipeline_id: pipeline_id, - info: ScrollLayerInfo::Scrollable(index), + pub fn external_id(&self) -> Option { + match *self { + ScrollLayerId::ClipExternalId(id, _) => Some(id), + _ => None, } } } - -#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)] -pub enum ScrollLayerInfo { - Scrollable(usize), - ReferenceFrame(usize), -} diff --git a/webrender_traits/src/display_list.rs b/webrender_traits/src/display_list.rs index 2f25385e8f..eff999ab17 100644 --- a/webrender_traits/src/display_list.rs +++ b/webrender_traits/src/display_list.rs @@ -11,8 +11,8 @@ use {FontKey, GlyphInstance, GlyphOptions, Gradient, GradientDisplayItem, Gradie use {IframeDisplayItem, ImageDisplayItem, ImageKey, ImageMask, ImageRendering, ItemRange}; use {LayoutPoint, LayoutRect, LayoutSize, LayoutTransform, MixBlendMode, PipelineId}; use {PropertyBinding, PushStackingContextDisplayItem, RadialGradient, RadialGradientDisplayItem}; -use {RectangleDisplayItem, ScrollLayerId, ScrollPolicy, ServoScrollRootId, SpecificDisplayItem}; -use {StackingContext, TextDisplayItem, WebGLContextId, WebGLDisplayItem, YuvColorSpace}; +use {RectangleDisplayItem, ScrollLayerId, ScrollPolicy, SpecificDisplayItem, StackingContext}; +use {TextDisplayItem, WebGLContextId, WebGLDisplayItem, YuvColorSpace}; use YuvImageDisplayItem; #[derive(Clone, Deserialize, Serialize)] @@ -341,17 +341,20 @@ impl DisplayListBuilder { pub fn define_clip(&mut self, clip: ClipRegion, content_size: LayoutSize, - scroll_root_id: Option) + id: Option) -> ScrollLayerId { - let scroll_layer_id = self.next_scroll_layer_id; - self.next_scroll_layer_id += 1; + let id = match id { + Some(id) => id, + None => { + self.next_scroll_layer_id += 1; + ScrollLayerId::Clip(self.next_scroll_layer_id - 1, self.pipeline_id) + } + }; - let id = ScrollLayerId::new(self.pipeline_id, scroll_layer_id); let item = SpecificDisplayItem::Clip(ClipDisplayItem { content_size: content_size, id: id, parent_id: *self.clip_stack.last().unwrap(), - scroll_root_id: scroll_root_id, }); self.push_item(item, clip.main, clip); @@ -361,8 +364,8 @@ impl DisplayListBuilder { pub fn push_scroll_layer(&mut self, clip: ClipRegion, content_size: LayoutSize, - scroll_root_id: Option) { - let id = self.define_clip(clip, content_size, scroll_root_id); + id: Option) { + let id = self.define_clip(clip, content_size, id); self.clip_stack.push(id); } diff --git a/wrench/src/wrench.rs b/wrench/src/wrench.rs index ab11c0d8ca..c80dcc9cd2 100644 --- a/wrench/src/wrench.rs +++ b/wrench/src/wrench.rs @@ -364,8 +364,7 @@ impl Wrench { pub fn send_lists(&mut self, frame_number: u32, display_list: DisplayListBuilder, - scroll_offsets: &HashMap) { - let pipeline_id = display_list.pipeline_id; + scroll_offsets: &HashMap) { let root_background_color = Some(ColorF::new(1.0, 1.0, 1.0, 1.0)); self.api.set_root_display_list(root_background_color, Epoch(frame_number), @@ -373,10 +372,8 @@ impl Wrench { display_list.finalize(), false); - for (scroll_root_id, offset) in scroll_offsets { - self.api.scroll_layers_with_scroll_root_id(*offset, - pipeline_id, - *scroll_root_id); + for (id, offset) in scroll_offsets { + self.api.scroll_layer_with_id(*offset, *id); } self.api.generate_frame(None); diff --git a/wrench/src/yaml_frame_reader.rs b/wrench/src/yaml_frame_reader.rs index f635bdf039..ff99db820c 100644 --- a/wrench/src/yaml_frame_reader.rs +++ b/wrench/src/yaml_frame_reader.rs @@ -49,15 +49,7 @@ pub struct YamlFrameReader { /// A HashMap of offsets which specify what scroll offsets particular /// scroll layers should be initialized with. - scroll_offsets: HashMap, - - /// A HashMap of offsets which specify what scroll offsets particular - /// scroll layers should be initialized with. - clip_id_mapping: HashMap, - - /// Current scroll root id used to generate new scroll root ids - /// for scroll layers. - current_scroll_root_id: usize, + scroll_offsets: HashMap, } impl YamlFrameReader { @@ -72,8 +64,6 @@ impl YamlFrameReader { queue_depth: 1, include_only: vec![], scroll_offsets: HashMap::new(), - clip_id_mapping: HashMap::new(), - current_scroll_root_id: 1, } } @@ -93,7 +83,6 @@ impl YamlFrameReader { pub fn reset(&mut self) { self.scroll_offsets.clear(); - self.clip_id_mapping.clear(); } pub fn build(&mut self, wrench: &mut Wrench) { @@ -583,7 +572,7 @@ impl YamlFrameReader { let yaml_clip_id = item["clip_id"].as_i64(); if let Some(yaml_id) = yaml_clip_id { - let id = self.clip_id_mapping[&(yaml_id as u32)]; + let id = ScrollLayerId::new(yaml_id as usize, self.builder().pipeline_id); self.builder().push_clip_id(id); } @@ -592,7 +581,7 @@ impl YamlFrameReader { "image" => self.handle_image(wrench, &full_clip_region, &item), "text" | "glyphs" => self.handle_text(wrench, &full_clip_region, &item), "scroll_layer" => self.add_scroll_layer_from_yaml(wrench, &item), - "clip" => { self.add_clip_from_yaml(wrench, &item); } + "clip" => { self.handle_clip_from_yaml(wrench, &item); } "border" => self.handle_border(wrench, &full_clip_region, &item), "gradient" => self.handle_gradient(wrench, &full_clip_region, &item), "radial_gradient" => self.handle_radial_gradient(wrench, &full_clip_region, &item), @@ -609,7 +598,7 @@ impl YamlFrameReader { } pub fn add_scroll_layer_from_yaml(&mut self, wrench: &mut Wrench, yaml: &Yaml) { - let id = self.add_clip_from_yaml(wrench, yaml); + let id = self.handle_clip_from_yaml(wrench, yaml); self.builder().push_clip_id(id); if !yaml["items"].is_badvalue() { @@ -618,25 +607,22 @@ impl YamlFrameReader { self.builder().pop_clip_id(); } - pub fn add_clip_from_yaml(&mut self, wrench: &mut Wrench, yaml: &Yaml) -> ScrollLayerId { + pub fn handle_clip_from_yaml(&mut self, wrench: &mut Wrench, yaml: &Yaml) -> ScrollLayerId { let bounds = yaml["bounds"].as_rect().expect("scroll layer must have bounds"); let content_size = yaml["content-size"].as_size() .expect("scroll layer must have content size"); let clip = self.to_clip_region(&yaml["clip"], &bounds, wrench) .unwrap_or(ClipRegion::simple(&bounds)); + let id = yaml["id"].as_i64().map(|id| + ScrollLayerId::new(id as usize, self.builder().pipeline_id)); + + let id = self.builder().define_clip(clip, content_size, id); - let scroll_root_id = ServoScrollRootId(self.current_scroll_root_id); if let Some(size) = yaml["scroll-offset"].as_point() { - let entry = self.scroll_offsets.entry(scroll_root_id).or_insert_with(LayerPoint::zero); - *entry = LayerPoint::new(size.x, size.y); + self.scroll_offsets.insert(id, LayerPoint::new(size.x, size.y)); } - let id = self.builder().define_clip(clip, content_size, Some(scroll_root_id)); - if let Some(yaml_id) = yaml["id"].as_i64() { - assert!(!self.clip_id_mapping.contains_key(&(yaml_id as u32))); - self.clip_id_mapping.insert(yaml_id as u32, id); - } - return id + id } pub fn add_stacking_context_from_yaml(&mut self, @@ -670,9 +656,8 @@ impl YamlFrameReader { if is_root { if let Some(size) = yaml["scroll-offset"].as_point() { - let entry = self.scroll_offsets.entry(ServoScrollRootId(0)) - .or_insert_with(LayerPoint::zero); - *entry = LayerPoint::new(size.x, size.y); + let id = ScrollLayerId::root_scroll_layer(self.builder().pipeline_id); + self.scroll_offsets.insert(id, LayerPoint::new(size.x, size.y)); } } diff --git a/wrench/src/yaml_frame_writer.rs b/wrench/src/yaml_frame_writer.rs index 969084b4b5..7221a5d61f 100644 --- a/wrench/src/yaml_frame_writer.rs +++ b/wrench/src/yaml_frame_writer.rs @@ -18,6 +18,7 @@ use super::CURRENT_FRAME_NUMBER; use time; use webrender; use webrender_traits::*; +use webrender_traits::SpecificDisplayItem::*; use yaml_helper::{mix_blend_mode_to_string, scroll_policy_to_string}; use yaml_rust::{Yaml, YamlEmitter}; @@ -66,14 +67,6 @@ fn color_node(parent: &mut Table, key: &str, value: ColorF) { yaml_node(parent, key, Yaml::String(color_to_string(value))); } -fn clip_id_node(parent: &mut Table, key: &str, clip_id: &ScrollLayerId) { - if let ScrollLayerInfo::Scrollable(id) = clip_id.info { - usize_node(parent, key, id); - return; - } - unreachable!("Should not have ReferenceFrame ids in the display list."); -} - fn point_node(parent: &mut Table, key: &str, value: &TypedPoint2D) { f32_vec_node(parent, key, &[value.x, value.y]); } @@ -332,7 +325,7 @@ impl YamlFrameWriter { let mut root_dl_table = new_table(); { let mut iter = dl.all_display_items().iter(); - self.write_dl(&mut root_dl_table, &mut iter, &aux); + self.write_display_list(&mut root_dl_table, &mut iter, &aux, &mut ClipIdMapper::new()); } @@ -360,7 +353,7 @@ impl YamlFrameWriter { let dl = scene.display_lists.get(&pipeline_id).unwrap(); let aux = scene.pipeline_auxiliary_lists.get(&pipeline_id).unwrap(); let mut iter = dl.iter(); - self.write_dl(&mut pipeline, &mut iter, &aux); + self.write_display_list(&mut pipeline, &mut iter, &aux, &mut ClipIdMapper::new()); pipelines.push(Yaml::Hash(pipeline)); } @@ -497,16 +490,16 @@ impl YamlFrameWriter { } } - fn write_dl_items(&mut self, - list: &mut Vec, - dl_iter: &mut slice::Iter, - aux: &AuxiliaryLists) { - use webrender_traits::SpecificDisplayItem::*; - while let Some(ref base) = dl_iter.next() { + fn write_display_list_items(&mut self, + list: &mut Vec, + list_iterator: &mut slice::Iter, + aux: &AuxiliaryLists, + clip_id_mapper: &mut ClipIdMapper) { + while let Some(ref base) = list_iterator.next() { let mut v = new_table(); rect_node(&mut v, "bounds", &base.rect); yaml_node(&mut v, "clip", self.make_clip_node(&base.clip, aux)); - clip_id_node(&mut v, "clip_id", &base.scroll_layer_id); + usize_node(&mut v, "clip_id", clip_id_mapper.map(&base.scroll_layer_id)); match base.item { Rectangle(item) => { @@ -741,12 +734,12 @@ impl YamlFrameWriter { PushStackingContext(item) => { str_node(&mut v, "type", "stacking_context"); write_sc(&mut v, &item.stacking_context); - self.write_dl(&mut v, dl_iter, aux); + self.write_display_list(&mut v, list_iterator, aux, clip_id_mapper); }, Clip(item) => { str_node(&mut v, "type", "clip"); size_node(&mut v, "content-size", &item.content_size); - clip_id_node(&mut v, "id", &item.id); + usize_node(&mut v, "id", clip_id_mapper.add_id(item.id)); } PopStackingContext => return, } @@ -756,9 +749,13 @@ impl YamlFrameWriter { } } - fn write_dl(&mut self, parent: &mut Table, dl_iter: &mut slice::Iter, aux: &AuxiliaryLists) { + fn write_display_list(&mut self, + parent: &mut Table, + list_iterator: &mut slice::Iter, + aux: &AuxiliaryLists, + clip_id_mapper: &mut ClipIdMapper) { let mut list = vec![]; - self.write_dl_items(&mut list, dl_iter, aux); + self.write_display_list_items(&mut list, list_iterator, aux, clip_id_mapper); parent.insert(Yaml::String("items".to_owned()), Yaml::Array(list)); } } @@ -843,3 +840,29 @@ impl webrender::ApiRecordingReceiver for YamlFrameWriterReceiver { } } } + +/// This structure allows mapping both Clip and ClipExternalId ScrollLayerIds +/// onto one set of numeric ids. This prevents ids from clashing in the yaml output. +struct ClipIdMapper { + hash_map: HashMap, + current_clip_id: usize, +} + +impl ClipIdMapper { + fn new() -> ClipIdMapper { + ClipIdMapper { + hash_map: HashMap::new(), + current_clip_id: 1, + } + } + + fn add_id(&mut self, id: ScrollLayerId) -> usize { + self.hash_map.insert(id, self.current_clip_id); + self.current_clip_id += 1; + self.current_clip_id - 1 + } + + fn map(&self, id: &ScrollLayerId) -> usize { + *self.hash_map.get(id).unwrap() + } +}