From ff0acccc061c0894e40bbda4b318bc7ab8615367 Mon Sep 17 00:00:00 2001 From: Ms2ger Date: Fri, 6 Nov 2015 13:10:37 +0100 Subject: [PATCH 01/19] Consolidate ProfilerMetadata and TimerMetadata. There is no good reason to have the two types. This also means that the result of LayoutTask::profiler_metadata no longer borrows the LayoutTask, which I'll need later. --- components/layout/layout_task.rs | 20 +++++++++++--------- components/layout/parallel.rs | 6 +++--- components/profile/time.rs | 11 +++++++++-- components/profile_traits/Cargo.toml | 4 ---- components/profile_traits/time.rs | 21 +++++---------------- components/servo/Cargo.lock | 1 - ports/cef/Cargo.lock | 1 - ports/gonk/Cargo.lock | 1 - 8 files changed, 28 insertions(+), 37 deletions(-) diff --git a/components/layout/layout_task.rs b/components/layout/layout_task.rs index 6347509ad90..a7a39233cc9 100644 --- a/components/layout/layout_task.rs +++ b/components/layout/layout_task.rs @@ -44,7 +44,7 @@ use opaque_node::OpaqueNodeMethods; use parallel::{self, WorkQueueData}; use profile_traits::mem::{self, Report, ReportKind, ReportsChan}; use profile_traits::time::{TimerMetadataFrameType, TimerMetadataReflowType}; -use profile_traits::time::{self, ProfilerMetadata, profile}; +use profile_traits::time::{self, TimerMetadata, profile}; use query::{LayoutRPCImpl, process_content_box_request, process_content_boxes_request}; use query::{MarginPadding, MarginRetrievingFragmentBorderBoxIterator, PositionProperty}; use query::{PositionRetrievingFragmentBorderBoxIterator, Side}; @@ -1434,18 +1434,20 @@ impl LayoutTask { } /// Returns profiling information which is passed to the time profiler. - fn profiler_metadata(&self) -> ProfilerMetadata { - Some((&self.url, - if self.is_iframe { + fn profiler_metadata(&self) -> Option { + Some(TimerMetadata { + url: self.url.serialize(), + iframe: if self.is_iframe { TimerMetadataFrameType::IFrame - } else { + } else { TimerMetadataFrameType::RootWindow - }, - if self.first_reflow.get() { + }, + incremental: if self.first_reflow.get() { TimerMetadataReflowType::FirstReflow - } else { + } else { TimerMetadataReflowType::Incremental - })) + }, + }) } } diff --git a/components/layout/parallel.rs b/components/layout/parallel.rs index eddac889c50..658ce8030d6 100644 --- a/components/layout/parallel.rs +++ b/components/layout/parallel.rs @@ -12,7 +12,7 @@ use context::{LayoutContext, SharedLayoutContext}; use flow::{self, Flow, MutableFlowUtils, PostorderFlowTraversal, PreorderFlowTraversal}; use flow_ref::{self, FlowRef}; use gfx::display_list::OpaqueNode; -use profile_traits::time::{self, ProfilerMetadata, profile}; +use profile_traits::time::{self, TimerMetadata, profile}; use std::mem; use std::sync::atomic::{AtomicIsize, Ordering}; use traversal::PostorderNodeMutTraversal; @@ -465,7 +465,7 @@ pub fn traverse_dom_preorder(root: LayoutNode, pub fn traverse_flow_tree_preorder( root: &mut FlowRef, - profiler_metadata: ProfilerMetadata, + profiler_metadata: Option, time_profiler_chan: time::ProfilerChan, shared_layout_context: &SharedLayoutContext, queue: &mut WorkQueue) { @@ -488,7 +488,7 @@ pub fn traverse_flow_tree_preorder( pub fn build_display_list_for_subtree( root: &mut FlowRef, - profiler_metadata: ProfilerMetadata, + profiler_metadata: Option, time_profiler_chan: time::ProfilerChan, shared_layout_context: &SharedLayoutContext, queue: &mut WorkQueue) { diff --git a/components/profile/time.rs b/components/profile/time.rs index 21acdba8366..aa3fd79199a 100644 --- a/components/profile/time.rs +++ b/components/profile/time.rs @@ -8,6 +8,7 @@ use heartbeats; use ipc_channel::ipc::{self, IpcReceiver}; use profile_traits::energy::{energy_interval_ms, read_energy_uj}; use profile_traits::time::{ProfilerCategory, ProfilerChan, ProfilerMsg, TimerMetadata}; +use profile_traits::time::{TimerMetadataReflowType, TimerMetadataFrameType}; use std::borrow::ToOwned; use std::cmp::Ordering; use std::collections::BTreeMap; @@ -31,8 +32,14 @@ impl Formattable for Option { } else { url }; - let incremental = if meta.incremental { " yes" } else { " no " }; - let iframe = if meta.iframe { " yes" } else { " no " }; + let incremental = match meta.incremental { + TimerMetadataReflowType::Incremental => " yes", + TimerMetadataReflowType::FirstReflow => " no ", + }; + let iframe = match meta.iframe { + TimerMetadataFrameType::RootWindow => " yes", + TimerMetadataFrameType::IFrame => " no ", + }; format!(" {:14} {:9} {:30}", incremental, iframe, url) }, None => diff --git a/components/profile_traits/Cargo.toml b/components/profile_traits/Cargo.toml index 90eb74479d2..e8704ef4757 100644 --- a/components/profile_traits/Cargo.toml +++ b/components/profile_traits/Cargo.toml @@ -13,10 +13,6 @@ energy-profiling = ["energymon", "energy-monitor"] [dependencies.ipc-channel] git = "https://github.com/pcwalton/ipc-channel" -[dependencies.url] -version = "0.2" -features = [ "serde_serialization" ] - [dependencies.energymon] git = "https://github.com/energymon/energymon-rust.git" rev = "eba1d8a" diff --git a/components/profile_traits/time.rs b/components/profile_traits/time.rs index 8cf485348f7..9fa31d69892 100644 --- a/components/profile_traits/time.rs +++ b/components/profile_traits/time.rs @@ -3,18 +3,16 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ extern crate time as std_time; -extern crate url; use energy::read_energy_uj; use ipc_channel::ipc::IpcSender; use self::std_time::precise_time_ns; -use self::url::Url; #[derive(PartialEq, Clone, PartialOrd, Eq, Ord, Deserialize, Serialize)] pub struct TimerMetadata { pub url: String, - pub iframe: bool, - pub incremental: bool, + pub iframe: TimerMetadataFrameType, + pub incremental: TimerMetadataReflowType, } #[derive(Clone, Deserialize, Serialize)] @@ -77,23 +75,20 @@ pub enum ProfilerCategory { ApplicationHeartbeat, } -#[derive(Eq, PartialEq)] +#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Deserialize, Serialize)] pub enum TimerMetadataFrameType { RootWindow, IFrame, } -#[derive(Eq, PartialEq)] +#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Deserialize, Serialize)] pub enum TimerMetadataReflowType { Incremental, FirstReflow, } -pub type ProfilerMetadata<'a> = - Option<(&'a Url, TimerMetadataFrameType, TimerMetadataReflowType)>; - pub fn profile(category: ProfilerCategory, - meta: ProfilerMetadata, + meta: Option, profiler_chan: ProfilerChan, callback: F) -> T @@ -104,12 +99,6 @@ pub fn profile(category: ProfilerCategory, let val = callback(); let end_time = precise_time_ns(); let end_energy = read_energy_uj(); - let meta = meta.map(|(url, iframe, reflow_type)| - TimerMetadata { - url: url.serialize(), - iframe: iframe == TimerMetadataFrameType::IFrame, - incremental: reflow_type == TimerMetadataReflowType::Incremental, - }); profiler_chan.send(ProfilerMsg::Time((category, meta), (start_time, end_time), (start_energy, end_energy))); diff --git a/components/servo/Cargo.lock b/components/servo/Cargo.lock index 701aadc6d36..9d94e5c6038 100644 --- a/components/servo/Cargo.lock +++ b/components/servo/Cargo.lock @@ -1416,7 +1416,6 @@ dependencies = [ "serde 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "serde_macros 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)", - "url 0.2.37 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] diff --git a/ports/cef/Cargo.lock b/ports/cef/Cargo.lock index 819bc11730a..da7ada6517a 100644 --- a/ports/cef/Cargo.lock +++ b/ports/cef/Cargo.lock @@ -1350,7 +1350,6 @@ dependencies = [ "serde 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "serde_macros 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)", - "url 0.2.37 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] diff --git a/ports/gonk/Cargo.lock b/ports/gonk/Cargo.lock index 692d4b39388..dc749c0a1c5 100644 --- a/ports/gonk/Cargo.lock +++ b/ports/gonk/Cargo.lock @@ -1330,7 +1330,6 @@ dependencies = [ "serde 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "serde_macros 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)", - "url 0.2.37 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] From b8d8505463fcb82a3017057ef1fc50f378090b5f Mon Sep 17 00:00:00 2001 From: Ms2ger Date: Fri, 6 Nov 2015 13:13:23 +0100 Subject: [PATCH 02/19] Disentangle the message handling from the receiver selection in LayoutTask::handle_request. This ensures no fields of the LayoutTask are borrowed when calling repaint or handle_request_helper, which I'll need later. --- components/layout/layout_task.rs | 84 +++++++++++++++++++------------- 1 file changed, 51 insertions(+), 33 deletions(-) diff --git a/components/layout/layout_task.rs b/components/layout/layout_task.rs index a7a39233cc9..c36a45b8a7d 100644 --- a/components/layout/layout_task.rs +++ b/components/layout/layout_task.rs @@ -466,49 +466,67 @@ impl LayoutTask { fn handle_request<'a>(&'a self, possibly_locked_rw_data: &mut Option>) -> bool { - let port_from_script = &self.port; - let port_from_pipeline = &self.pipeline_port; - let port_from_image_cache = &self.image_cache_receiver; - let port_from_font_cache = &self.font_cache_receiver; - select! { - msg = port_from_pipeline.recv() => { - match msg.unwrap() { - LayoutControlMsg::SetVisibleRects(new_visible_rects) => { - self.handle_request_helper(Msg::SetVisibleRects(new_visible_rects), - possibly_locked_rw_data) - } - LayoutControlMsg::TickAnimations => { - self.handle_request_helper(Msg::TickAnimations, possibly_locked_rw_data) - } - LayoutControlMsg::GetCurrentEpoch(sender) => { - self.handle_request_helper(Msg::GetCurrentEpoch(sender), - possibly_locked_rw_data) - } - LayoutControlMsg::GetWebFontLoadState(sender) => { - self.handle_request_helper(Msg::GetWebFontLoadState(sender), - possibly_locked_rw_data) - } - LayoutControlMsg::ExitNow => { - self.handle_request_helper(Msg::ExitNow, - possibly_locked_rw_data) - } + enum Request { + FromPipeline(LayoutControlMsg), + FromScript(Msg), + FromImageCache, + FromFontCache, + } + + let request = { + let port_from_script = &self.port; + let port_from_pipeline = &self.pipeline_port; + let port_from_image_cache = &self.image_cache_receiver; + let port_from_font_cache = &self.font_cache_receiver; + select! { + msg = port_from_pipeline.recv() => { + Request::FromPipeline(msg.unwrap()) + }, + msg = port_from_script.recv() => { + Request::FromScript(msg.unwrap()) + }, + msg = port_from_image_cache.recv() => { + msg.unwrap(); + Request::FromImageCache + }, + msg = port_from_font_cache.recv() => { + msg.unwrap(); + Request::FromFontCache } + } + }; + + match request { + Request::FromPipeline(LayoutControlMsg::SetVisibleRects(new_visible_rects)) => { + self.handle_request_helper(Msg::SetVisibleRects(new_visible_rects), + possibly_locked_rw_data) }, - msg = port_from_script.recv() => { - self.handle_request_helper(msg.unwrap(), possibly_locked_rw_data) + Request::FromPipeline(LayoutControlMsg::TickAnimations) => { + self.handle_request_helper(Msg::TickAnimations, possibly_locked_rw_data) }, - msg = port_from_image_cache.recv() => { - msg.unwrap(); + Request::FromPipeline(LayoutControlMsg::GetCurrentEpoch(sender)) => { + self.handle_request_helper(Msg::GetCurrentEpoch(sender), possibly_locked_rw_data) + }, + Request::FromPipeline(LayoutControlMsg::GetWebFontLoadState(sender)) => { + self.handle_request_helper(Msg::GetWebFontLoadState(sender), + possibly_locked_rw_data) + }, + Request::FromPipeline(LayoutControlMsg::ExitNow) => { + self.handle_request_helper(Msg::ExitNow, possibly_locked_rw_data) + }, + Request::FromScript(msg) => { + self.handle_request_helper(msg, possibly_locked_rw_data) + }, + Request::FromImageCache => { self.repaint(possibly_locked_rw_data) }, - msg = port_from_font_cache.recv() => { - msg.unwrap(); + Request::FromFontCache => { let rw_data = self.lock_rw_data(possibly_locked_rw_data); rw_data.outstanding_web_fonts.fetch_sub(1, Ordering::SeqCst); font_context::invalidate_font_caches(); self.script_chan.send(ConstellationControlMsg::WebFontLoaded(self.id)).unwrap(); true - } + }, } } From 3f4c734cf4d7c8b54a2eaf190f8550b8d1a80a0d Mon Sep 17 00:00:00 2001 From: Ms2ger Date: Fri, 6 Nov 2015 11:37:22 +0100 Subject: [PATCH 03/19] Introduce a RwData struct. --- components/layout/layout_task.rs | 160 +++++++++++++++---------------- 1 file changed, 78 insertions(+), 82 deletions(-) diff --git a/components/layout/layout_task.rs b/components/layout/layout_task.rs index c36a45b8a7d..07b84a3505c 100644 --- a/components/layout/layout_task.rs +++ b/components/layout/layout_task.rs @@ -311,6 +311,36 @@ impl<'a> DerefMut for RWGuard<'a> { } } +struct RwData<'a, 'b: 'a> { + rw_data: &'b Arc>, + possibly_locked_rw_data: &'a mut Option>, +} + +impl<'a, 'b: 'a> RwData<'a, 'b> { + /// If no reflow has happened yet, this will just return the lock in + /// `possibly_locked_rw_data`. Otherwise, it will acquire the `rw_data` lock. + /// + /// If you do not wish RPCs to remain blocked, just drop the `RWGuard` + /// returned from this function. If you _do_ wish for them to remain blocked, + /// use `block`. + fn lock(&mut self) -> RWGuard<'b> { + match self.possibly_locked_rw_data.take() { + None => RWGuard::Used(self.rw_data.lock().unwrap()), + Some(x) => RWGuard::Held(x), + } + } + + /// If no reflow has ever been triggered, this will keep the lock, locked + /// (and saved in `possibly_locked_rw_data`). If it has been, the lock will + /// be unlocked. + fn block(&mut self, rw_data: RWGuard<'b>) { + match rw_data { + RWGuard::Used(x) => drop(x), + RWGuard::Held(x) => *self.possibly_locked_rw_data = Some(x), + } + } +} + fn add_font_face_rules(stylesheet: &Stylesheet, device: &Device, font_cache_task: &FontCacheTask, @@ -432,8 +462,13 @@ impl LayoutTask { /// Starts listening on the port. fn start(self) { - let mut possibly_locked_rw_data = Some((*self.rw_data).lock().unwrap()); - while self.handle_request(&mut possibly_locked_rw_data) { + let rw_data = self.rw_data.clone(); + let mut possibly_locked_rw_data = Some(rw_data.lock().unwrap()); + let mut rw_data = RwData { + rw_data: &rw_data, + possibly_locked_rw_data: &mut possibly_locked_rw_data, + }; + while self.handle_request(&mut rw_data) { // Loop indefinitely. } } @@ -463,9 +498,7 @@ impl LayoutTask { } /// Receives and dispatches messages from the script and constellation tasks - fn handle_request<'a>(&'a self, - possibly_locked_rw_data: &mut Option>) - -> bool { + fn handle_request<'a, 'b>(&self, possibly_locked_rw_data: &mut RwData<'a, 'b>) -> bool { enum Request { FromPipeline(LayoutControlMsg), FromScript(Msg), @@ -521,7 +554,7 @@ impl LayoutTask { self.repaint(possibly_locked_rw_data) }, Request::FromFontCache => { - let rw_data = self.lock_rw_data(possibly_locked_rw_data); + let rw_data = possibly_locked_rw_data.lock(); rw_data.outstanding_web_fonts.fetch_sub(1, Ordering::SeqCst); font_context::invalidate_font_caches(); self.script_chan.send(ConstellationControlMsg::WebFontLoaded(self.id)).unwrap(); @@ -530,40 +563,13 @@ impl LayoutTask { } } - /// If no reflow has happened yet, this will just return the lock in - /// `possibly_locked_rw_data`. Otherwise, it will acquire the `rw_data` lock. - /// - /// If you do not wish RPCs to remain blocked, just drop the `RWGuard` - /// returned from this function. If you _do_ wish for them to remain blocked, - /// use `return_rw_data`. - fn lock_rw_data<'a>(&'a self, - possibly_locked_rw_data: &mut Option>) - -> RWGuard<'a> { - match possibly_locked_rw_data.take() { - None => RWGuard::Used((*self.rw_data).lock().unwrap()), - Some(x) => RWGuard::Held(x), - } - } - - /// If no reflow has ever been triggered, this will keep the lock, locked - /// (and saved in `possibly_locked_rw_data`). If it has been, the lock will - /// be unlocked. - fn return_rw_data<'a>(possibly_locked_rw_data: &mut Option>, - rw_data: RWGuard<'a>) { - match rw_data { - RWGuard::Used(x) => drop(x), - RWGuard::Held(x) => *possibly_locked_rw_data = Some(x), - } - } - /// Repaint the scene, without performing style matching. This is typically /// used when an image arrives asynchronously and triggers a relayout and /// repaint. /// TODO: In the future we could detect if the image size hasn't changed /// since last time and avoid performing a complete layout pass. - fn repaint<'a>(&'a self, - possibly_locked_rw_data: &mut Option>) -> bool { - let mut rw_data = self.lock_rw_data(possibly_locked_rw_data); + fn repaint<'a, 'b>(&self, possibly_locked_rw_data: &mut RwData<'a, 'b>) -> bool { + let mut rw_data = possibly_locked_rw_data.lock(); let reflow_info = Reflow { goal: ReflowGoal::ForDisplay, @@ -584,11 +590,10 @@ impl LayoutTask { } /// Receives and dispatches messages from other tasks. - fn handle_request_helper<'a>(&'a self, - request: Msg, - possibly_locked_rw_data: &mut Option>) - -> bool { + fn handle_request_helper<'a, 'b>(&self, + request: Msg, + possibly_locked_rw_data: &mut RwData<'a, 'b>) + -> bool { match request { Msg::AddStylesheet(style_info) => { self.handle_add_stylesheet(style_info, possibly_locked_rw_data) @@ -620,11 +625,11 @@ impl LayoutTask { self.collect_reports(reports_chan, possibly_locked_rw_data); }, Msg::GetCurrentEpoch(sender) => { - let rw_data = self.lock_rw_data(possibly_locked_rw_data); + let rw_data = possibly_locked_rw_data.lock(); sender.send(rw_data.epoch).unwrap(); }, Msg::GetWebFontLoadState(sender) => { - let rw_data = self.lock_rw_data(possibly_locked_rw_data); + let rw_data = possibly_locked_rw_data.lock(); let outstanding_web_fonts = rw_data.outstanding_web_fonts.load(Ordering::SeqCst); sender.send(outstanding_web_fonts != 0).unwrap(); }, @@ -645,13 +650,13 @@ impl LayoutTask { true } - fn collect_reports<'a>(&'a self, - reports_chan: ReportsChan, - possibly_locked_rw_data: &mut Option>) { + fn collect_reports<'a, 'b>(&self, + reports_chan: ReportsChan, + possibly_locked_rw_data: &mut RwData<'a, 'b>) { let mut reports = vec![]; // FIXME(njn): Just measuring the display tree for now. - let rw_data = self.lock_rw_data(possibly_locked_rw_data); + let rw_data = possibly_locked_rw_data.lock(); let stacking_context = rw_data.stacking_context.as_ref(); reports.push(Report { path: path![format!("url({})", self.url), "layout-task", "display-list"], @@ -704,9 +709,9 @@ impl LayoutTask { /// Enters a quiescent state in which no new messages will be processed until an `ExitNow` is /// received. A pong is immediately sent on the given response channel. - fn prepare_to_exit<'a>(&'a self, - response_chan: Sender<()>, - possibly_locked_rw_data: &mut Option>) { + fn prepare_to_exit<'a, 'b>(&self, + response_chan: Sender<()>, + possibly_locked_rw_data: &mut RwData<'a, 'b>) { response_chan.send(()).unwrap(); loop { match self.port.recv().unwrap() { @@ -732,14 +737,13 @@ impl LayoutTask { /// Shuts down the layout task now. If there are any DOM nodes left, layout will now (safely) /// crash. - fn exit_now<'a>(&'a self, - possibly_locked_rw_data: &mut Option>) { + fn exit_now<'a, 'b>(&self, possibly_locked_rw_data: &mut RwData<'a, 'b>) { { - let mut rw_data = self.lock_rw_data(possibly_locked_rw_data); + let mut rw_data = possibly_locked_rw_data.lock(); if let Some(ref mut traversal) = (&mut *rw_data).parallel_traversal { traversal.shutdown() } - LayoutTask::return_rw_data(possibly_locked_rw_data, rw_data); + possibly_locked_rw_data.block(rw_data); } let (response_chan, response_port) = ipc::channel().unwrap(); @@ -747,14 +751,13 @@ impl LayoutTask { response_port.recv().unwrap() } - fn handle_add_stylesheet<'a>(&'a self, - stylesheet: Arc, - possibly_locked_rw_data: - &mut Option>) { + fn handle_add_stylesheet<'a, 'b>(&self, + stylesheet: Arc, + possibly_locked_rw_data: &mut RwData<'a, 'b>) { // Find all font-face rules and notify the font cache of them. // GWTODO: Need to handle unloading web fonts. - let rw_data = self.lock_rw_data(possibly_locked_rw_data); + let rw_data = possibly_locked_rw_data.lock(); if stylesheet.is_effective_for_device(&rw_data.stylist.device) { add_font_face_rules(&*stylesheet, &rw_data.stylist.device, @@ -763,16 +766,14 @@ impl LayoutTask { &rw_data.outstanding_web_fonts); } - LayoutTask::return_rw_data(possibly_locked_rw_data, rw_data); + possibly_locked_rw_data.block(rw_data); } /// Sets quirks mode for the document, causing the quirks mode stylesheet to be used. - fn handle_set_quirks_mode<'a>(&'a self, - possibly_locked_rw_data: - &mut Option>) { - let mut rw_data = self.lock_rw_data(possibly_locked_rw_data); + fn handle_set_quirks_mode<'a, 'b>(&self, possibly_locked_rw_data: &mut RwData<'a, 'b>) { + let mut rw_data = possibly_locked_rw_data.lock(); rw_data.stylist.set_quirks_mode(true); - LayoutTask::return_rw_data(possibly_locked_rw_data, rw_data); + possibly_locked_rw_data.block(rw_data); } fn try_get_layout_root(&self, node: LayoutNode) -> Option { @@ -1084,10 +1085,9 @@ impl LayoutTask { } /// The high-level routine that performs layout tasks. - fn handle_reflow<'a>(&'a self, - data: &ScriptReflow, - possibly_locked_rw_data: &mut Option>) { - + fn handle_reflow<'a, 'b>(&self, + data: &ScriptReflow, + possibly_locked_rw_data: &mut RwData<'a, 'b>) { // Make sure that every return path from this method joins the script task, // otherwise the script task will panic. struct AutoJoinScriptTask<'a> { data: &'a ScriptReflow }; @@ -1110,7 +1110,7 @@ impl LayoutTask { node.dump(); } - let mut rw_data = self.lock_rw_data(possibly_locked_rw_data); + let mut rw_data = possibly_locked_rw_data.lock(); let stylesheets: Vec<&Stylesheet> = data.document_stylesheets.iter().map(|entry| &**entry) .collect(); let stylesheets_changed = data.stylesheets_changed; @@ -1232,11 +1232,11 @@ impl LayoutTask { } } - fn set_visible_rects<'a>(&'a self, - new_visible_rects: Vec<(LayerId, Rect)>, - possibly_locked_rw_data: &mut Option>) - -> bool { - let mut rw_data = self.lock_rw_data(possibly_locked_rw_data); + fn set_visible_rects<'a, 'b>(&self, + new_visible_rects: Vec<(LayerId, Rect)>, + possibly_locked_rw_data: &mut RwData<'a, 'b>) + -> bool { + let mut rw_data = possibly_locked_rw_data.lock(); // First, determine if we need to regenerate the display lists. This will happen if the // layers have moved more than `DISPLAY_PORT_THRESHOLD_SIZE_FACTOR` away from their last @@ -1289,10 +1289,8 @@ impl LayoutTask { true } - fn tick_all_animations<'a>(&'a self, - possibly_locked_rw_data: &mut Option>) { - let mut rw_data = self.lock_rw_data(possibly_locked_rw_data); + fn tick_all_animations<'a, 'b>(&self, possibly_locked_rw_data: &mut RwData<'a, 'b>) { + let mut rw_data = possibly_locked_rw_data.lock(); animation::tick_all_animations(self, &mut rw_data) } @@ -1324,10 +1322,8 @@ impl LayoutTask { &mut layout_context); } - pub fn reflow_with_newly_loaded_web_font<'a>( - &'a self, - possibly_locked_rw_data: &mut Option>) { - let mut rw_data = self.lock_rw_data(possibly_locked_rw_data); + fn reflow_with_newly_loaded_web_font<'a, 'b>(&self, possibly_locked_rw_data: &mut RwData<'a, 'b>) { + let mut rw_data = possibly_locked_rw_data.lock(); font_context::invalidate_font_caches(); let reflow_info = Reflow { From 8674345d6106eb7aef4594f6b1c45f2d2df642b4 Mon Sep 17 00:00:00 2001 From: Ms2ger Date: Fri, 6 Nov 2015 13:15:28 +0100 Subject: [PATCH 04/19] Move LayoutTask::first_reflow out of its Cell. As the LayoutTask is uniquely owned, and we no longer have borrows of its fields hanging around, we can use mutable references to simplify some code. --- components/layout/animation.rs | 2 +- components/layout/layout_task.rs | 31 +++++++++++++++---------------- 2 files changed, 16 insertions(+), 17 deletions(-) diff --git a/components/layout/animation.rs b/components/layout/animation.rs index 7b58e435681..de60a3100be 100644 --- a/components/layout/animation.rs +++ b/components/layout/animation.rs @@ -139,7 +139,7 @@ pub fn recalc_style_for_animations(flow: &mut Flow, } /// Handles animation updates. -pub fn tick_all_animations(layout_task: &LayoutTask, rw_data: &mut LayoutTaskData) { +pub fn tick_all_animations(layout_task: &mut LayoutTask, rw_data: &mut LayoutTaskData) { layout_task.tick_animations(rw_data); layout_task.script_chan diff --git a/components/layout/layout_task.rs b/components/layout/layout_task.rs index 07b84a3505c..0bbfbb71746 100644 --- a/components/layout/layout_task.rs +++ b/components/layout/layout_task.rs @@ -58,7 +58,6 @@ use selectors::parser::PseudoElement; use sequential; use serde_json; use std::borrow::ToOwned; -use std::cell::Cell; use std::collections::HashMap; use std::collections::hash_state::DefaultState; use std::mem::transmute; @@ -219,7 +218,7 @@ pub struct LayoutTask { pub font_cache_task: FontCacheTask, /// Is this the first reflow in this LayoutTask? - pub first_reflow: Cell, + pub first_reflow: bool, /// To receive a canvas renderer associated to a layer, this message is propagated /// to the paint chan @@ -428,7 +427,7 @@ impl LayoutTask { mem_profiler_chan: mem_profiler_chan, image_cache_task: image_cache_task.clone(), font_cache_task: font_cache_task, - first_reflow: Cell::new(true), + first_reflow: true, image_cache_receiver: image_cache_receiver, image_cache_sender: ImageCacheChan(ipc_image_cache_sender), font_cache_receiver: font_cache_receiver, @@ -461,7 +460,7 @@ impl LayoutTask { } /// Starts listening on the port. - fn start(self) { + fn start(mut self) { let rw_data = self.rw_data.clone(); let mut possibly_locked_rw_data = Some(rw_data.lock().unwrap()); let mut rw_data = RwData { @@ -498,7 +497,7 @@ impl LayoutTask { } /// Receives and dispatches messages from the script and constellation tasks - fn handle_request<'a, 'b>(&self, possibly_locked_rw_data: &mut RwData<'a, 'b>) -> bool { + fn handle_request<'a, 'b>(&mut self, possibly_locked_rw_data: &mut RwData<'a, 'b>) -> bool { enum Request { FromPipeline(LayoutControlMsg), FromScript(Msg), @@ -568,7 +567,7 @@ impl LayoutTask { /// repaint. /// TODO: In the future we could detect if the image size hasn't changed /// since last time and avoid performing a complete layout pass. - fn repaint<'a, 'b>(&self, possibly_locked_rw_data: &mut RwData<'a, 'b>) -> bool { + fn repaint<'a, 'b>(&mut self, possibly_locked_rw_data: &mut RwData<'a, 'b>) -> bool { let mut rw_data = possibly_locked_rw_data.lock(); let reflow_info = Reflow { @@ -590,7 +589,7 @@ impl LayoutTask { } /// Receives and dispatches messages from other tasks. - fn handle_request_helper<'a, 'b>(&self, + fn handle_request_helper<'a, 'b>(&mut self, request: Msg, possibly_locked_rw_data: &mut RwData<'a, 'b>) -> bool { @@ -1085,7 +1084,7 @@ impl LayoutTask { } /// The high-level routine that performs layout tasks. - fn handle_reflow<'a, 'b>(&self, + fn handle_reflow<'a, 'b>(&mut self, data: &ScriptReflow, possibly_locked_rw_data: &mut RwData<'a, 'b>) { // Make sure that every return path from this method joins the script task, @@ -1232,7 +1231,7 @@ impl LayoutTask { } } - fn set_visible_rects<'a, 'b>(&self, + fn set_visible_rects<'a, 'b>(&mut self, new_visible_rects: Vec<(LayerId, Rect)>, possibly_locked_rw_data: &mut RwData<'a, 'b>) -> bool { @@ -1289,12 +1288,12 @@ impl LayoutTask { true } - fn tick_all_animations<'a, 'b>(&self, possibly_locked_rw_data: &mut RwData<'a, 'b>) { + fn tick_all_animations<'a, 'b>(&mut self, possibly_locked_rw_data: &mut RwData<'a, 'b>) { let mut rw_data = possibly_locked_rw_data.lock(); animation::tick_all_animations(self, &mut rw_data) } - pub fn tick_animations(&self, rw_data: &mut LayoutTaskData) { + pub fn tick_animations(&mut self, rw_data: &mut LayoutTaskData) { let reflow_info = Reflow { goal: ReflowGoal::ForDisplay, page_clip_rect: MAX_RECT, @@ -1322,7 +1321,7 @@ impl LayoutTask { &mut layout_context); } - fn reflow_with_newly_loaded_web_font<'a, 'b>(&self, possibly_locked_rw_data: &mut RwData<'a, 'b>) { + fn reflow_with_newly_loaded_web_font<'a, 'b>(&mut self, possibly_locked_rw_data: &mut RwData<'a, 'b>) { let mut rw_data = possibly_locked_rw_data.lock(); font_context::invalidate_font_caches(); @@ -1345,7 +1344,7 @@ impl LayoutTask { &mut layout_context); } - fn perform_post_style_recalc_layout_passes<'a>(&'a self, + fn perform_post_style_recalc_layout_passes<'a>(&'a mut self, data: &Reflow, rw_data: &mut LayoutTaskData, layout_context: &mut SharedLayoutContext) { @@ -1398,7 +1397,7 @@ impl LayoutTask { } } - fn perform_post_main_layout_passes<'a>(&'a self, + fn perform_post_main_layout_passes<'a>(&'a mut self, data: &Reflow, rw_data: &mut LayoutTaskData, layout_context: &mut SharedLayoutContext) { @@ -1408,7 +1407,7 @@ impl LayoutTask { &mut root_flow, &mut *layout_context, rw_data); - self.first_reflow.set(false); + self.first_reflow = false; if opts::get().trace_layout { layout_debug::end_trace(); @@ -1456,7 +1455,7 @@ impl LayoutTask { } else { TimerMetadataFrameType::RootWindow }, - incremental: if self.first_reflow.get() { + incremental: if self.first_reflow { TimerMetadataReflowType::FirstReflow } else { TimerMetadataReflowType::Incremental From cc1b7acbe64a10c4d2f181f7989e68eda3fc0db9 Mon Sep 17 00:00:00 2001 From: Ms2ger Date: Fri, 6 Nov 2015 13:34:29 +0100 Subject: [PATCH 05/19] Make LayoutTask::solve_constraints a static method. It does not use self. --- components/layout/layout_task.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/components/layout/layout_task.rs b/components/layout/layout_task.rs index 0bbfbb71746..ca755bfac02 100644 --- a/components/layout/layout_task.rs +++ b/components/layout/layout_task.rs @@ -808,8 +808,7 @@ impl LayoutTask { /// This corresponds to `Reflow()` in Gecko and `layout()` in WebKit/Blink and should be /// benchmarked against those two. It is marked `#[inline(never)]` to aid profiling. #[inline(never)] - fn solve_constraints<'a>(&self, - layout_root: &mut FlowRef, + fn solve_constraints(layout_root: &mut FlowRef, shared_layout_context: &SharedLayoutContext) { let _scope = layout_debug_scope!("solve_constraints"); sequential::traverse_flow_tree_preorder(layout_root, shared_layout_context); @@ -1382,7 +1381,7 @@ impl LayoutTask { match rw_data.parallel_traversal { None => { // Sequential mode. - self.solve_constraints(&mut root_flow, &layout_context) + LayoutTask::solve_constraints(&mut root_flow, &layout_context) } Some(ref mut parallel) => { // Parallel mode. From 49691c1638efd1437edc6aa12a7afd53c0018c20 Mon Sep 17 00:00:00 2001 From: Ms2ger Date: Fri, 6 Nov 2015 13:35:38 +0100 Subject: [PATCH 06/19] Make LayoutTask::solve_constraints_parallel a static method. This matches LayoutTask::solve_constraints, and will be necessary when we borrow parallel_traversal directly from the LayoutTask. --- components/layout/layout_task.rs | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/components/layout/layout_task.rs b/components/layout/layout_task.rs index ca755bfac02..2efed666b25 100644 --- a/components/layout/layout_task.rs +++ b/components/layout/layout_task.rs @@ -819,17 +819,18 @@ impl LayoutTask { /// This corresponds to `Reflow()` in Gecko and `layout()` in WebKit/Blink and should be /// benchmarked against those two. It is marked `#[inline(never)]` to aid profiling. #[inline(never)] - fn solve_constraints_parallel(&self, - traversal: &mut WorkQueue, + fn solve_constraints_parallel(traversal: &mut WorkQueue, layout_root: &mut FlowRef, + profiler_metadata: Option, + time_profiler_chan: time::ProfilerChan, shared_layout_context: &SharedLayoutContext) { let _scope = layout_debug_scope!("solve_constraints_parallel"); // NOTE: this currently computes borders, so any pruning should separate that // operation out. parallel::traverse_flow_tree_preorder(layout_root, - self.profiler_metadata(), - self.time_profiler_chan.clone(), + profiler_metadata, + time_profiler_chan, shared_layout_context, traversal); } @@ -1385,9 +1386,11 @@ impl LayoutTask { } Some(ref mut parallel) => { // Parallel mode. - self.solve_constraints_parallel(parallel, - &mut root_flow, - &*layout_context); + LayoutTask::solve_constraints_parallel(parallel, + &mut root_flow, + self.profiler_metadata(), + self.time_profiler_chan.clone(), + &*layout_context); } } }); From dcea03c2b431c43d72e8112f43391c99d9d8029b Mon Sep 17 00:00:00 2001 From: Ms2ger Date: Fri, 6 Nov 2015 13:37:51 +0100 Subject: [PATCH 07/19] Move parallel_traversal from LayoutTaskData to LayoutTask. --- components/layout/layout_task.rs | 43 +++++++++++++++----------------- 1 file changed, 20 insertions(+), 23 deletions(-) diff --git a/components/layout/layout_task.rs b/components/layout/layout_task.rs index 2efed666b25..c219b10abf3 100644 --- a/components/layout/layout_task.rs +++ b/components/layout/layout_task.rs @@ -113,9 +113,6 @@ pub struct LayoutTaskData { /// Performs CSS selector matching and style resolution. pub stylist: Box, - /// The workers that we use for parallel operation. - pub parallel_traversal: Option>, - /// Starts at zero, and increased by one every time a layout completes. /// This can be used to easily check for invalid stale data. pub generation: u32, @@ -225,6 +222,9 @@ pub struct LayoutTask { pub canvas_layers_receiver: Receiver<(LayerId, IpcSender)>, pub canvas_layers_sender: Sender<(LayerId, IpcSender)>, + /// The workers that we use for parallel operation. + parallel_traversal: Option>, + /// A mutex to allow for fast, read-only RPC of layout's internal data /// structures, while still letting the LayoutTask modify them. /// @@ -434,6 +434,7 @@ impl LayoutTask { font_cache_sender: font_cache_sender, canvas_layers_receiver: canvas_layers_receiver, canvas_layers_sender: canvas_layers_sender, + parallel_traversal: parallel_traversal, rw_data: Arc::new(Mutex::new( LayoutTaskData { root_flow: None, @@ -442,7 +443,6 @@ impl LayoutTask { viewport_size: Size2D::new(Au(0), Au(0)), stacking_context: None, stylist: stylist, - parallel_traversal: parallel_traversal, generation: 0, content_box_response: Rect::zero(), content_boxes_response: Vec::new(), @@ -671,7 +671,7 @@ impl LayoutTask { }); // ... as do each of the LayoutWorkers, if present. - if let Some(ref traversal) = rw_data.parallel_traversal { + if let Some(ref traversal) = self.parallel_traversal { let sizes = traversal.heap_size_of_tls(heap_size_of_local_context); for (i, size) in sizes.iter().enumerate() { reports.push(Report { @@ -708,7 +708,7 @@ impl LayoutTask { /// Enters a quiescent state in which no new messages will be processed until an `ExitNow` is /// received. A pong is immediately sent on the given response channel. - fn prepare_to_exit<'a, 'b>(&self, + fn prepare_to_exit<'a, 'b>(&mut self, response_chan: Sender<()>, possibly_locked_rw_data: &mut RwData<'a, 'b>) { response_chan.send(()).unwrap(); @@ -736,13 +736,9 @@ impl LayoutTask { /// Shuts down the layout task now. If there are any DOM nodes left, layout will now (safely) /// crash. - fn exit_now<'a, 'b>(&self, possibly_locked_rw_data: &mut RwData<'a, 'b>) { - { - let mut rw_data = possibly_locked_rw_data.lock(); - if let Some(ref mut traversal) = (&mut *rw_data).parallel_traversal { - traversal.shutdown() - } - possibly_locked_rw_data.block(rw_data); + fn exit_now<'a, 'b>(&mut self, _: &mut RwData<'a, 'b>) { + if let Some(ref mut traversal) = self.parallel_traversal { + traversal.shutdown() } let (response_chan, response_port) = ipc::channel().unwrap(); @@ -997,15 +993,16 @@ impl LayoutTask { } } - fn compute_abs_pos_and_build_display_list<'a>(&'a self, + fn compute_abs_pos_and_build_display_list<'a>(&'a mut self, data: &Reflow, layout_root: &mut FlowRef, shared_layout_context: &mut SharedLayoutContext, rw_data: &mut LayoutTaskData) { let writing_mode = flow::base(&**layout_root).writing_mode; + let (metadata, sender) = (self.profiler_metadata(), self.time_profiler_chan.clone()); profile(time::ProfilerCategory::LayoutDispListBuild, - self.profiler_metadata(), - self.time_profiler_chan.clone(), + metadata.clone(), + sender.clone(), || { flow::mut_base(flow_ref::deref_mut(layout_root)).stacking_relative_position = LogicalPoint::zero(writing_mode).to_physical(writing_mode, @@ -1014,11 +1011,11 @@ impl LayoutTask { flow::mut_base(flow_ref::deref_mut(layout_root)).clip = ClippingRegion::from_rect(&data.page_clip_rect); - match (&mut rw_data.parallel_traversal, opts::get().parallel_display_list_building) { + match (&mut self.parallel_traversal, opts::get().parallel_display_list_building) { (&mut Some(ref mut traversal), true) => { parallel::build_display_list_for_subtree(layout_root, - self.profiler_metadata(), - self.time_profiler_chan.clone(), + metadata, + sender, shared_layout_context, traversal); } @@ -1183,8 +1180,7 @@ impl LayoutTask { self.time_profiler_chan.clone(), || { // Perform CSS selector matching and flow construction. - let rw_data = &mut *rw_data; - match rw_data.parallel_traversal { + match self.parallel_traversal { None => { sequential::traverse_dom_preorder(node, &shared_layout_context); } @@ -1379,7 +1375,8 @@ impl LayoutTask { self.profiler_metadata(), self.time_profiler_chan.clone(), || { - match rw_data.parallel_traversal { + let profiler_metadata = self.profiler_metadata(); + match self.parallel_traversal { None => { // Sequential mode. LayoutTask::solve_constraints(&mut root_flow, &layout_context) @@ -1388,7 +1385,7 @@ impl LayoutTask { // Parallel mode. LayoutTask::solve_constraints_parallel(parallel, &mut root_flow, - self.profiler_metadata(), + profiler_metadata, self.time_profiler_chan.clone(), &*layout_context); } From be178c0e5e7cf32eac78542975951d8517b0cd61 Mon Sep 17 00:00:00 2001 From: Ms2ger Date: Fri, 6 Nov 2015 13:38:28 +0100 Subject: [PATCH 08/19] Remove unused RwData arguments from LayoutTask::exit_now and LayoutTask::prepare_to_exit. --- components/layout/layout_task.rs | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/components/layout/layout_task.rs b/components/layout/layout_task.rs index c219b10abf3..7faf3a6db77 100644 --- a/components/layout/layout_task.rs +++ b/components/layout/layout_task.rs @@ -636,12 +636,12 @@ impl LayoutTask { self.create_layout_task(info) } Msg::PrepareToExit(response_chan) => { - self.prepare_to_exit(response_chan, possibly_locked_rw_data); + self.prepare_to_exit(response_chan); return false }, Msg::ExitNow => { debug!("layout: ExitNow received"); - self.exit_now(possibly_locked_rw_data); + self.exit_now(); return false } } @@ -708,9 +708,7 @@ impl LayoutTask { /// Enters a quiescent state in which no new messages will be processed until an `ExitNow` is /// received. A pong is immediately sent on the given response channel. - fn prepare_to_exit<'a, 'b>(&mut self, - response_chan: Sender<()>, - possibly_locked_rw_data: &mut RwData<'a, 'b>) { + fn prepare_to_exit(&mut self, response_chan: Sender<()>) { response_chan.send(()).unwrap(); loop { match self.port.recv().unwrap() { @@ -721,7 +719,7 @@ impl LayoutTask { } Msg::ExitNow => { debug!("layout task is exiting..."); - self.exit_now(possibly_locked_rw_data); + self.exit_now(); break } Msg::CollectReports(_) => { @@ -736,7 +734,7 @@ impl LayoutTask { /// Shuts down the layout task now. If there are any DOM nodes left, layout will now (safely) /// crash. - fn exit_now<'a, 'b>(&mut self, _: &mut RwData<'a, 'b>) { + fn exit_now<'a, 'b>(&mut self) { if let Some(ref mut traversal) = self.parallel_traversal { traversal.shutdown() } From 880fb9be0b4c121289be98183bf5dcc10b2d7ea5 Mon Sep 17 00:00:00 2001 From: Ms2ger Date: Fri, 6 Nov 2015 14:53:07 +0100 Subject: [PATCH 09/19] Remove LayoutTaskData::image_cache_task. --- components/layout/layout_task.rs | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/components/layout/layout_task.rs b/components/layout/layout_task.rs index 7faf3a6db77..5f3c3c9a3c0 100644 --- a/components/layout/layout_task.rs +++ b/components/layout/layout_task.rs @@ -97,9 +97,6 @@ pub struct LayoutTaskData { /// The root of the flow tree. pub root_flow: Option, - /// The image cache. - pub image_cache_task: ImageCacheTask, - /// The channel on which messages can be sent to the constellation. pub constellation_chan: ConstellationChan, @@ -425,7 +422,7 @@ impl LayoutTask { paint_chan: paint_chan, time_profiler_chan: time_profiler_chan, mem_profiler_chan: mem_profiler_chan, - image_cache_task: image_cache_task.clone(), + image_cache_task: image_cache_task, font_cache_task: font_cache_task, first_reflow: true, image_cache_receiver: image_cache_receiver, @@ -438,7 +435,6 @@ impl LayoutTask { rw_data: Arc::new(Mutex::new( LayoutTaskData { root_flow: None, - image_cache_task: image_cache_task, constellation_chan: constellation_chan, viewport_size: Size2D::new(Au(0), Au(0)), stacking_context: None, @@ -480,7 +476,7 @@ impl LayoutTask { goal: ReflowGoal) -> SharedLayoutContext { SharedLayoutContext { - image_cache_task: rw_data.image_cache_task.clone(), + image_cache_task: self.image_cache_task.clone(), image_cache_sender: Mutex::new(self.image_cache_sender.clone()), viewport_size: rw_data.viewport_size.clone(), screen_size_changed: screen_size_changed, From bdfa5fe804137cb90036b71729ca5afa4176230c Mon Sep 17 00:00:00 2001 From: Ms2ger Date: Fri, 6 Nov 2015 14:58:24 +0100 Subject: [PATCH 10/19] Move generation from LayoutTaskData to LayoutTask. --- components/layout/layout_task.rs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/components/layout/layout_task.rs b/components/layout/layout_task.rs index 5f3c3c9a3c0..977b573c040 100644 --- a/components/layout/layout_task.rs +++ b/components/layout/layout_task.rs @@ -110,10 +110,6 @@ pub struct LayoutTaskData { /// Performs CSS selector matching and style resolution. pub stylist: Box, - /// Starts at zero, and increased by one every time a layout completes. - /// This can be used to easily check for invalid stale data. - pub generation: u32, - /// A queued response for the union of the content boxes of a node. pub content_box_response: Rect, @@ -222,6 +218,10 @@ pub struct LayoutTask { /// The workers that we use for parallel operation. parallel_traversal: Option>, + /// Starts at zero, and increased by one every time a layout completes. + /// This can be used to easily check for invalid stale data. + generation: u32, + /// A mutex to allow for fast, read-only RPC of layout's internal data /// structures, while still letting the LayoutTask modify them. /// @@ -432,6 +432,7 @@ impl LayoutTask { canvas_layers_receiver: canvas_layers_receiver, canvas_layers_sender: canvas_layers_sender, parallel_traversal: parallel_traversal, + generation: 0, rw_data: Arc::new(Mutex::new( LayoutTaskData { root_flow: None, @@ -439,7 +440,6 @@ impl LayoutTask { viewport_size: Size2D::new(Au(0), Au(0)), stacking_context: None, stylist: stylist, - generation: 0, content_box_response: Rect::zero(), content_boxes_response: Vec::new(), client_rect_response: Rect::zero(), @@ -485,7 +485,7 @@ impl LayoutTask { stylist: StylistWrapper(&*rw_data.stylist), url: (*url).clone(), visible_rects: rw_data.visible_rects.clone(), - generation: rw_data.generation, + generation: self.generation, new_animations_sender: Mutex::new(rw_data.new_animations_sender.clone()), goal: goal, running_animations: rw_data.running_animations.clone(), @@ -1410,7 +1410,7 @@ impl LayoutTask { root_flow.dump(); } - rw_data.generation += 1; + self.generation += 1; } } From 604d1e84002583e648258502b62172a04f78043d Mon Sep 17 00:00:00 2001 From: Ms2ger Date: Fri, 6 Nov 2015 15:05:48 +0100 Subject: [PATCH 11/19] Move new_animations_sender from LayoutTaskData to LayoutTask. --- components/layout/layout_task.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/components/layout/layout_task.rs b/components/layout/layout_task.rs index 977b573c040..e9e705fde85 100644 --- a/components/layout/layout_task.rs +++ b/components/layout/layout_task.rs @@ -131,10 +131,6 @@ pub struct LayoutTaskData { /// Receives newly-discovered animations. pub new_animations_receiver: Receiver, - /// A channel on which new animations that have been triggered by style recalculation can be - /// sent. - pub new_animations_sender: Sender, - /// A counter for epoch messages epoch: Epoch, @@ -222,6 +218,10 @@ pub struct LayoutTask { /// This can be used to easily check for invalid stale data. generation: u32, + /// A channel on which new animations that have been triggered by style recalculation can be + /// sent. + new_animations_sender: Sender, + /// A mutex to allow for fast, read-only RPC of layout's internal data /// structures, while still letting the LayoutTask modify them. /// @@ -433,6 +433,7 @@ impl LayoutTask { canvas_layers_sender: canvas_layers_sender, parallel_traversal: parallel_traversal, generation: 0, + new_animations_sender: new_animations_sender, rw_data: Arc::new(Mutex::new( LayoutTaskData { root_flow: None, @@ -448,7 +449,6 @@ impl LayoutTask { offset_parent_response: OffsetParentResponse::empty(), visible_rects: Arc::new(HashMap::with_hash_state(Default::default())), new_animations_receiver: new_animations_receiver, - new_animations_sender: new_animations_sender, epoch: Epoch(0), outstanding_web_fonts: outstanding_web_fonts_counter, })), @@ -486,7 +486,7 @@ impl LayoutTask { url: (*url).clone(), visible_rects: rw_data.visible_rects.clone(), generation: self.generation, - new_animations_sender: Mutex::new(rw_data.new_animations_sender.clone()), + new_animations_sender: Mutex::new(self.new_animations_sender.clone()), goal: goal, running_animations: rw_data.running_animations.clone(), } From 5e4039d328744bdb7aae2d1c848961dbec2df0a0 Mon Sep 17 00:00:00 2001 From: Ms2ger Date: Fri, 6 Nov 2015 15:10:08 +0100 Subject: [PATCH 12/19] Move new_animations_receiver from LayoutTaskData to LayoutTask. --- components/layout/animation.rs | 8 +++++--- components/layout/layout_task.rs | 12 +++++++----- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/components/layout/animation.rs b/components/layout/animation.rs index de60a3100be..74f4400fc92 100644 --- a/components/layout/animation.rs +++ b/components/layout/animation.rs @@ -14,7 +14,7 @@ use script::layout_interface::Animation; use script_traits::ConstellationControlMsg; use std::collections::HashMap; use std::collections::hash_map::Entry; -use std::sync::mpsc::Sender; +use std::sync::mpsc::{Sender, Receiver}; use std::sync::{Arc, Mutex}; use style::animation::{GetMod, PropertyAnimation}; use style::properties::ComputedValues; @@ -50,9 +50,11 @@ pub fn start_transitions_if_applicable(new_animations_sender: &Mutex, + pipeline_id: PipelineId) { let mut new_running_animations = Vec::new(); - while let Ok(animation) = rw_data.new_animations_receiver.try_recv() { + while let Ok(animation) = new_animations_receiver.try_recv() { new_running_animations.push(animation) } diff --git a/components/layout/layout_task.rs b/components/layout/layout_task.rs index e9e705fde85..637f2ff6f94 100644 --- a/components/layout/layout_task.rs +++ b/components/layout/layout_task.rs @@ -128,9 +128,6 @@ pub struct LayoutTaskData { /// The list of currently-running animations. pub running_animations: Arc>>, - /// Receives newly-discovered animations. - pub new_animations_receiver: Receiver, - /// A counter for epoch messages epoch: Epoch, @@ -222,6 +219,9 @@ pub struct LayoutTask { /// sent. new_animations_sender: Sender, + /// Receives newly-discovered animations. + new_animations_receiver: Receiver, + /// A mutex to allow for fast, read-only RPC of layout's internal data /// structures, while still letting the LayoutTask modify them. /// @@ -434,6 +434,7 @@ impl LayoutTask { parallel_traversal: parallel_traversal, generation: 0, new_animations_sender: new_animations_sender, + new_animations_receiver: new_animations_receiver, rw_data: Arc::new(Mutex::new( LayoutTaskData { root_flow: None, @@ -448,7 +449,6 @@ impl LayoutTask { running_animations: Arc::new(HashMap::new()), offset_parent_response: OffsetParentResponse::empty(), visible_rects: Arc::new(HashMap::with_hash_state(Default::default())), - new_animations_receiver: new_animations_receiver, epoch: Epoch(0), outstanding_web_fonts: outstanding_web_fonts_counter, })), @@ -1340,7 +1340,9 @@ impl LayoutTask { layout_context: &mut SharedLayoutContext) { if let Some(mut root_flow) = rw_data.layout_root() { // Kick off animations if any were triggered, expire completed ones. - animation::update_animation_state(&mut *rw_data, self.id); + animation::update_animation_state(&mut *rw_data, + &self.new_animations_receiver, + self.id); profile(time::ProfilerCategory::LayoutRestyleDamagePropagation, self.profiler_metadata(), From 53da53ef53561fd5921c1ebb1baccf01f440295f Mon Sep 17 00:00:00 2001 From: Ms2ger Date: Fri, 6 Nov 2015 15:16:17 +0100 Subject: [PATCH 13/19] Move outstanding_web_fonts from LayoutTaskData to LayoutTask. --- components/layout/layout_task.rs | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/components/layout/layout_task.rs b/components/layout/layout_task.rs index 637f2ff6f94..91122865c91 100644 --- a/components/layout/layout_task.rs +++ b/components/layout/layout_task.rs @@ -131,9 +131,6 @@ pub struct LayoutTaskData { /// A counter for epoch messages epoch: Epoch, - /// The number of Web fonts that have been requested but not yet loaded. - pub outstanding_web_fonts: Arc, - /// The position and size of the visible rect for each layer. We do not build display lists /// for any areas more than `DISPLAY_PORT_SIZE_FACTOR` screens away from this area. pub visible_rects: Arc, DefaultState>>, @@ -222,6 +219,9 @@ pub struct LayoutTask { /// Receives newly-discovered animations. new_animations_receiver: Receiver, + /// The number of Web fonts that have been requested but not yet loaded. + outstanding_web_fonts: Arc, + /// A mutex to allow for fast, read-only RPC of layout's internal data /// structures, while still letting the LayoutTask modify them. /// @@ -435,6 +435,7 @@ impl LayoutTask { generation: 0, new_animations_sender: new_animations_sender, new_animations_receiver: new_animations_receiver, + outstanding_web_fonts: outstanding_web_fonts_counter, rw_data: Arc::new(Mutex::new( LayoutTaskData { root_flow: None, @@ -450,7 +451,6 @@ impl LayoutTask { offset_parent_response: OffsetParentResponse::empty(), visible_rects: Arc::new(HashMap::with_hash_state(Default::default())), epoch: Epoch(0), - outstanding_web_fonts: outstanding_web_fonts_counter, })), } } @@ -549,8 +549,8 @@ impl LayoutTask { self.repaint(possibly_locked_rw_data) }, Request::FromFontCache => { - let rw_data = possibly_locked_rw_data.lock(); - rw_data.outstanding_web_fonts.fetch_sub(1, Ordering::SeqCst); + let _rw_data = possibly_locked_rw_data.lock(); + self.outstanding_web_fonts.fetch_sub(1, Ordering::SeqCst); font_context::invalidate_font_caches(); self.script_chan.send(ConstellationControlMsg::WebFontLoaded(self.id)).unwrap(); true @@ -624,8 +624,8 @@ impl LayoutTask { sender.send(rw_data.epoch).unwrap(); }, Msg::GetWebFontLoadState(sender) => { - let rw_data = possibly_locked_rw_data.lock(); - let outstanding_web_fonts = rw_data.outstanding_web_fonts.load(Ordering::SeqCst); + let _rw_data = possibly_locked_rw_data.lock(); + let outstanding_web_fonts = self.outstanding_web_fonts.load(Ordering::SeqCst); sender.send(outstanding_web_fonts != 0).unwrap(); }, Msg::CreateLayoutTask(info) => { @@ -752,7 +752,7 @@ impl LayoutTask { &rw_data.stylist.device, &self.font_cache_task, &self.font_cache_sender, - &rw_data.outstanding_web_fonts); + &self.outstanding_web_fonts); } possibly_locked_rw_data.block(rw_data); From e8f31f2ed7cf4be5ac578ce83851e2f7b3ef1c23 Mon Sep 17 00:00:00 2001 From: Ms2ger Date: Fri, 6 Nov 2015 17:13:18 +0100 Subject: [PATCH 14/19] Move root_flow from LayoutTaskData to LayoutTask. --- components/layout/layout_task.rs | 28 ++++++++++------------------ 1 file changed, 10 insertions(+), 18 deletions(-) diff --git a/components/layout/layout_task.rs b/components/layout/layout_task.rs index 91122865c91..2a189e49ce2 100644 --- a/components/layout/layout_task.rs +++ b/components/layout/layout_task.rs @@ -94,9 +94,6 @@ const DISPLAY_PORT_THRESHOLD_SIZE_FACTOR: i32 = 4; /// /// This needs to be protected by a mutex so we can do fast RPCs. pub struct LayoutTaskData { - /// The root of the flow tree. - pub root_flow: Option, - /// The channel on which messages can be sent to the constellation. pub constellation_chan: ConstellationChan, @@ -136,14 +133,6 @@ pub struct LayoutTaskData { pub visible_rects: Arc, DefaultState>>, } -impl LayoutTaskData { - pub fn layout_root(&self) -> Option { - self.root_flow.as_ref().map(|root_flow| { - root_flow.clone() - }) - } -} - /// Information needed by the layout task. pub struct LayoutTask { /// The ID of the pipeline that we belong to. @@ -222,6 +211,9 @@ pub struct LayoutTask { /// The number of Web fonts that have been requested but not yet loaded. outstanding_web_fonts: Arc, + /// The root of the flow tree. + root_flow: Option, + /// A mutex to allow for fast, read-only RPC of layout's internal data /// structures, while still letting the LayoutTask modify them. /// @@ -436,9 +428,9 @@ impl LayoutTask { new_animations_sender: new_animations_sender, new_animations_receiver: new_animations_receiver, outstanding_web_fonts: outstanding_web_fonts_counter, + root_flow: None, rw_data: Arc::new(Mutex::new( LayoutTaskData { - root_flow: None, constellation_chan: constellation_chan, viewport_size: Size2D::new(Au(0), Au(0)), stacking_context: None, @@ -1185,7 +1177,7 @@ impl LayoutTask { }); // Retrieve the (possibly rebuilt) root flow. - rw_data.root_flow = self.try_get_layout_root(node); + self.root_flow = self.try_get_layout_root(node); } // Send new canvas renderers to the paint task @@ -1199,7 +1191,7 @@ impl LayoutTask { &mut rw_data, &mut shared_layout_context); - if let Some(mut root_flow) = rw_data.layout_root() { + if let Some(mut root_flow) = self.root_flow.clone() { match data.query_type { ReflowQueryType::ContentBoxQuery(node) => rw_data.content_box_response = process_content_box_request(node, &mut root_flow), @@ -1294,7 +1286,7 @@ impl LayoutTask { &self.url, reflow_info.goal); - if let Some(mut root_flow) = rw_data.layout_root() { + if let Some(mut root_flow) = self.root_flow.clone() { // Perform an abbreviated style recalc that operates without access to the DOM. let animations = &*rw_data.running_animations; profile(time::ProfilerCategory::LayoutStyleRecalc, @@ -1326,7 +1318,7 @@ impl LayoutTask { reflow_info.goal); // No need to do a style recalc here. - if rw_data.root_flow.as_ref().is_none() { + if self.root_flow.is_none() { return } self.perform_post_style_recalc_layout_passes(&reflow_info, @@ -1338,7 +1330,7 @@ impl LayoutTask { data: &Reflow, rw_data: &mut LayoutTaskData, layout_context: &mut SharedLayoutContext) { - if let Some(mut root_flow) = rw_data.layout_root() { + if let Some(mut root_flow) = self.root_flow.clone() { // Kick off animations if any were triggered, expire completed ones. animation::update_animation_state(&mut *rw_data, &self.new_animations_receiver, @@ -1397,7 +1389,7 @@ impl LayoutTask { rw_data: &mut LayoutTaskData, layout_context: &mut SharedLayoutContext) { // Build the display list if necessary, and send it to the painter. - if let Some(mut root_flow) = rw_data.layout_root() { + if let Some(mut root_flow) = self.root_flow.clone() { self.compute_abs_pos_and_build_display_list(data, &mut root_flow, &mut *layout_context, From ee2b77e8f5bb1a87c97ac639bc99fbdf8c223243 Mon Sep 17 00:00:00 2001 From: Ms2ger Date: Fri, 6 Nov 2015 17:35:39 +0100 Subject: [PATCH 15/19] Move visible_rects from LayoutTaskData to LayoutTask. --- components/layout/layout_task.rs | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/components/layout/layout_task.rs b/components/layout/layout_task.rs index 2a189e49ce2..ee4008ede39 100644 --- a/components/layout/layout_task.rs +++ b/components/layout/layout_task.rs @@ -127,10 +127,6 @@ pub struct LayoutTaskData { /// A counter for epoch messages epoch: Epoch, - - /// The position and size of the visible rect for each layer. We do not build display lists - /// for any areas more than `DISPLAY_PORT_SIZE_FACTOR` screens away from this area. - pub visible_rects: Arc, DefaultState>>, } /// Information needed by the layout task. @@ -214,6 +210,10 @@ pub struct LayoutTask { /// The root of the flow tree. root_flow: Option, + /// The position and size of the visible rect for each layer. We do not build display lists + /// for any areas more than `DISPLAY_PORT_SIZE_FACTOR` screens away from this area. + visible_rects: Arc, DefaultState>>, + /// A mutex to allow for fast, read-only RPC of layout's internal data /// structures, while still letting the LayoutTask modify them. /// @@ -429,6 +429,7 @@ impl LayoutTask { new_animations_receiver: new_animations_receiver, outstanding_web_fonts: outstanding_web_fonts_counter, root_flow: None, + visible_rects: Arc::new(HashMap::with_hash_state(Default::default())), rw_data: Arc::new(Mutex::new( LayoutTaskData { constellation_chan: constellation_chan, @@ -441,7 +442,6 @@ impl LayoutTask { resolved_style_response: None, running_animations: Arc::new(HashMap::new()), offset_parent_response: OffsetParentResponse::empty(), - visible_rects: Arc::new(HashMap::with_hash_state(Default::default())), epoch: Epoch(0), })), } @@ -476,7 +476,7 @@ impl LayoutTask { canvas_layers_sender: Mutex::new(self.canvas_layers_sender.clone()), stylist: StylistWrapper(&*rw_data.stylist), url: (*url).clone(), - visible_rects: rw_data.visible_rects.clone(), + visible_rects: self.visible_rects.clone(), generation: self.generation, new_animations_sender: Mutex::new(self.new_animations_sender.clone()), goal: goal, @@ -1228,7 +1228,7 @@ impl LayoutTask { Size2D::new(rw_data.viewport_size.width * DISPLAY_PORT_THRESHOLD_SIZE_FACTOR, rw_data.viewport_size.height * DISPLAY_PORT_THRESHOLD_SIZE_FACTOR); for &(ref layer_id, ref new_visible_rect) in &new_visible_rects { - match rw_data.visible_rects.get(layer_id) { + match self.visible_rects.get(layer_id) { None => { old_visible_rects.insert(*layer_id, *new_visible_rect); } @@ -1245,7 +1245,7 @@ impl LayoutTask { if !must_regenerate_display_lists { // Update `visible_rects` in case there are new layers that were discovered. - rw_data.visible_rects = Arc::new(old_visible_rects); + self.visible_rects = Arc::new(old_visible_rects); return true } @@ -1253,7 +1253,7 @@ impl LayoutTask { for &(ref layer_id, ref new_visible_rect) in &new_visible_rects { old_visible_rects.insert(*layer_id, *new_visible_rect); } - rw_data.visible_rects = Arc::new(old_visible_rects); + self.visible_rects = Arc::new(old_visible_rects); // Regenerate the display lists. let reflow_info = Reflow { From c469d09543ff8ae94104e499b4347c333fd137bb Mon Sep 17 00:00:00 2001 From: Ms2ger Date: Fri, 6 Nov 2015 17:51:58 +0100 Subject: [PATCH 16/19] Move running_animations from LayoutTaskData to LayoutTask. --- components/layout/animation.rs | 7 ++++--- components/layout/layout_task.rs | 13 +++++++------ 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/components/layout/animation.rs b/components/layout/animation.rs index 74f4400fc92..786c1dba92e 100644 --- a/components/layout/animation.rs +++ b/components/layout/animation.rs @@ -51,6 +51,7 @@ pub fn start_transitions_if_applicable(new_animations_sender: &Mutex>>, new_animations_receiver: &Receiver, pipeline_id: PipelineId) { let mut new_running_animations = Vec::new(); @@ -58,7 +59,7 @@ pub fn update_animation_state(rw_data: &mut LayoutTaskData, new_running_animations.push(animation) } - let mut running_animations_hash = (*rw_data.running_animations).clone(); + let mut running_animations_hash = (**running_animations).clone(); if running_animations_hash.is_empty() && new_running_animations.is_empty() { // Nothing to do. Return early so we don't flood the compositor with @@ -91,10 +92,10 @@ pub fn update_animation_state(rw_data: &mut LayoutTaskData, } } - rw_data.running_animations = Arc::new(running_animations_hash); + *running_animations = Arc::new(running_animations_hash); let animation_state; - if rw_data.running_animations.is_empty() { + if running_animations.is_empty() { animation_state = AnimationState::NoAnimationsPresent; } else { animation_state = AnimationState::AnimationsPresent; diff --git a/components/layout/layout_task.rs b/components/layout/layout_task.rs index ee4008ede39..2b0c3b1f90d 100644 --- a/components/layout/layout_task.rs +++ b/components/layout/layout_task.rs @@ -122,9 +122,6 @@ pub struct LayoutTaskData { /// A queued response for the offset parent/rect of a node. pub offset_parent_response: OffsetParentResponse, - /// The list of currently-running animations. - pub running_animations: Arc>>, - /// A counter for epoch messages epoch: Epoch, } @@ -214,6 +211,9 @@ pub struct LayoutTask { /// for any areas more than `DISPLAY_PORT_SIZE_FACTOR` screens away from this area. visible_rects: Arc, DefaultState>>, + /// The list of currently-running animations. + running_animations: Arc>>, + /// A mutex to allow for fast, read-only RPC of layout's internal data /// structures, while still letting the LayoutTask modify them. /// @@ -430,6 +430,7 @@ impl LayoutTask { outstanding_web_fonts: outstanding_web_fonts_counter, root_flow: None, visible_rects: Arc::new(HashMap::with_hash_state(Default::default())), + running_animations: Arc::new(HashMap::new()), rw_data: Arc::new(Mutex::new( LayoutTaskData { constellation_chan: constellation_chan, @@ -440,7 +441,6 @@ impl LayoutTask { content_boxes_response: Vec::new(), client_rect_response: Rect::zero(), resolved_style_response: None, - running_animations: Arc::new(HashMap::new()), offset_parent_response: OffsetParentResponse::empty(), epoch: Epoch(0), })), @@ -480,7 +480,7 @@ impl LayoutTask { generation: self.generation, new_animations_sender: Mutex::new(self.new_animations_sender.clone()), goal: goal, - running_animations: rw_data.running_animations.clone(), + running_animations: self.running_animations.clone(), } } @@ -1288,7 +1288,7 @@ impl LayoutTask { if let Some(mut root_flow) = self.root_flow.clone() { // Perform an abbreviated style recalc that operates without access to the DOM. - let animations = &*rw_data.running_animations; + let animations = &*self.running_animations; profile(time::ProfilerCategory::LayoutStyleRecalc, self.profiler_metadata(), self.time_profiler_chan.clone(), @@ -1333,6 +1333,7 @@ impl LayoutTask { if let Some(mut root_flow) = self.root_flow.clone() { // Kick off animations if any were triggered, expire completed ones. animation::update_animation_state(&mut *rw_data, + &mut self.running_animations, &self.new_animations_receiver, self.id); From 4c3038f3783f9542f39745e61bca88013e64e6b3 Mon Sep 17 00:00:00 2001 From: Ms2ger Date: Fri, 6 Nov 2015 17:56:02 +0100 Subject: [PATCH 17/19] Pass the constellation_chan to animation::update_animation_state directly. --- components/layout/animation.rs | 12 +++++------- components/layout/layout_task.rs | 2 +- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/components/layout/animation.rs b/components/layout/animation.rs index 786c1dba92e..247765c8d92 100644 --- a/components/layout/animation.rs +++ b/components/layout/animation.rs @@ -9,7 +9,7 @@ use flow::{self, Flow}; use gfx::display_list::OpaqueNode; use incremental::{self, RestyleDamage}; use layout_task::{LayoutTask, LayoutTaskData}; -use msg::constellation_msg::{AnimationState, Msg, PipelineId}; +use msg::constellation_msg::{AnimationState, ConstellationChan, Msg, PipelineId}; use script::layout_interface::Animation; use script_traits::ConstellationControlMsg; use std::collections::HashMap; @@ -50,7 +50,7 @@ pub fn start_transitions_if_applicable(new_animations_sender: &Mutex>>, new_animations_receiver: &Receiver, pipeline_id: PipelineId) { @@ -101,11 +101,9 @@ pub fn update_animation_state(rw_data: &mut LayoutTaskData, animation_state = AnimationState::AnimationsPresent; } - rw_data.constellation_chan - .0 - .send(Msg::ChangeRunningAnimationsState(pipeline_id, animation_state)) - .unwrap(); - + constellation_chan.0 + .send(Msg::ChangeRunningAnimationsState(pipeline_id, animation_state)) + .unwrap(); } /// Recalculates style for a set of animations. This does *not* run with the DOM lock held. diff --git a/components/layout/layout_task.rs b/components/layout/layout_task.rs index 2b0c3b1f90d..c054aa37bb3 100644 --- a/components/layout/layout_task.rs +++ b/components/layout/layout_task.rs @@ -1332,7 +1332,7 @@ impl LayoutTask { layout_context: &mut SharedLayoutContext) { if let Some(mut root_flow) = self.root_flow.clone() { // Kick off animations if any were triggered, expire completed ones. - animation::update_animation_state(&mut *rw_data, + animation::update_animation_state(&self.constellation_chan, &mut self.running_animations, &self.new_animations_receiver, self.id); From dd920a06f31b099c5c5a130d0c12fd8900b3d658 Mon Sep 17 00:00:00 2001 From: Ms2ger Date: Fri, 6 Nov 2015 18:06:18 +0100 Subject: [PATCH 18/19] Move epoch from LayoutTaskData to LayoutTask. --- components/layout/layout_task.rs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/components/layout/layout_task.rs b/components/layout/layout_task.rs index c054aa37bb3..79dbff5be46 100644 --- a/components/layout/layout_task.rs +++ b/components/layout/layout_task.rs @@ -121,9 +121,6 @@ pub struct LayoutTaskData { /// A queued response for the offset parent/rect of a node. pub offset_parent_response: OffsetParentResponse, - - /// A counter for epoch messages - epoch: Epoch, } /// Information needed by the layout task. @@ -214,6 +211,9 @@ pub struct LayoutTask { /// The list of currently-running animations. running_animations: Arc>>, + /// A counter for epoch messages + epoch: Epoch, + /// A mutex to allow for fast, read-only RPC of layout's internal data /// structures, while still letting the LayoutTask modify them. /// @@ -431,6 +431,7 @@ impl LayoutTask { root_flow: None, visible_rects: Arc::new(HashMap::with_hash_state(Default::default())), running_animations: Arc::new(HashMap::new()), + epoch: Epoch(0), rw_data: Arc::new(Mutex::new( LayoutTaskData { constellation_chan: constellation_chan, @@ -442,7 +443,6 @@ impl LayoutTask { client_rect_response: Rect::zero(), resolved_style_response: None, offset_parent_response: OffsetParentResponse::empty(), - epoch: Epoch(0), })), } } @@ -612,8 +612,8 @@ impl LayoutTask { self.collect_reports(reports_chan, possibly_locked_rw_data); }, Msg::GetCurrentEpoch(sender) => { - let rw_data = possibly_locked_rw_data.lock(); - sender.send(rw_data.epoch).unwrap(); + let _rw_data = possibly_locked_rw_data.lock(); + sender.send(self.epoch).unwrap(); }, Msg::GetWebFontLoadState(sender) => { let _rw_data = possibly_locked_rw_data.lock(); @@ -1058,9 +1058,9 @@ impl LayoutTask { debug!("Layout done!"); - rw_data.epoch.next(); + self.epoch.next(); self.paint_chan - .send(LayoutToPaintMsg::PaintInit(rw_data.epoch, paint_layer)) + .send(LayoutToPaintMsg::PaintInit(self.epoch, paint_layer)) .unwrap(); } }); From 1919e1963381f518c7cb59a45303bd0466db034b Mon Sep 17 00:00:00 2001 From: Ms2ger Date: Fri, 6 Nov 2015 18:15:43 +0100 Subject: [PATCH 19/19] Move viewport_size from LayoutTaskData to LayoutTask. --- components/layout/layout_task.rs | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/components/layout/layout_task.rs b/components/layout/layout_task.rs index 79dbff5be46..514e3e71e66 100644 --- a/components/layout/layout_task.rs +++ b/components/layout/layout_task.rs @@ -97,10 +97,6 @@ pub struct LayoutTaskData { /// The channel on which messages can be sent to the constellation. pub constellation_chan: ConstellationChan, - /// The size of the viewport. This may be different from the size of the screen due to viewport - /// constraints. - pub viewport_size: Size2D, - /// The root stacking context. pub stacking_context: Option>, @@ -214,6 +210,10 @@ pub struct LayoutTask { /// A counter for epoch messages epoch: Epoch, + /// The size of the viewport. This may be different from the size of the screen due to viewport + /// constraints. + viewport_size: Size2D, + /// A mutex to allow for fast, read-only RPC of layout's internal data /// structures, while still letting the LayoutTask modify them. /// @@ -432,10 +432,10 @@ impl LayoutTask { visible_rects: Arc::new(HashMap::with_hash_state(Default::default())), running_animations: Arc::new(HashMap::new()), epoch: Epoch(0), + viewport_size: Size2D::new(Au(0), Au(0)), rw_data: Arc::new(Mutex::new( LayoutTaskData { constellation_chan: constellation_chan, - viewport_size: Size2D::new(Au(0), Au(0)), stacking_context: None, stylist: stylist, content_box_response: Rect::zero(), @@ -470,7 +470,7 @@ impl LayoutTask { SharedLayoutContext { image_cache_task: self.image_cache_task.clone(), image_cache_sender: Mutex::new(self.image_cache_sender.clone()), - viewport_size: rw_data.viewport_size.clone(), + viewport_size: self.viewport_size.clone(), screen_size_changed: screen_size_changed, font_cache_task: Mutex::new(self.font_cache_task.clone()), canvas_layers_sender: Mutex::new(self.canvas_layers_sender.clone()), @@ -992,7 +992,7 @@ impl LayoutTask { || { flow::mut_base(flow_ref::deref_mut(layout_root)).stacking_relative_position = LogicalPoint::zero(writing_mode).to_physical(writing_mode, - rw_data.viewport_size); + self.viewport_size); flow::mut_base(flow_ref::deref_mut(layout_root)).clip = ClippingRegion::from_rect(&data.page_clip_rect); @@ -1098,7 +1098,7 @@ impl LayoutTask { let stylesheets_changed = data.stylesheets_changed; let initial_viewport = data.window_size.initial_viewport; - let old_viewport_size = rw_data.viewport_size; + let old_viewport_size = self.viewport_size; let current_screen_size = Size2D::new(Au::from_f32_px(initial_viewport.width.get()), Au::from_f32_px(initial_viewport.height.get())); @@ -1107,7 +1107,7 @@ impl LayoutTask { rw_data.stylist.set_device(device, &stylesheets); let constraints = rw_data.stylist.viewport_constraints().clone(); - rw_data.viewport_size = match constraints { + self.viewport_size = match constraints { Some(ref constraints) => { debug!("Viewport constraints: {:?}", constraints); @@ -1119,7 +1119,7 @@ impl LayoutTask { }; // Handle conditions where the entire flow tree is invalid. - let viewport_size_changed = rw_data.viewport_size != old_viewport_size; + let viewport_size_changed = self.viewport_size != old_viewport_size; if viewport_size_changed { if let Some(constraints) = constraints { // let the constellation know about the viewport constraints @@ -1225,8 +1225,8 @@ impl LayoutTask { let mut must_regenerate_display_lists = false; let mut old_visible_rects = HashMap::with_hash_state(Default::default()); let inflation_amount = - Size2D::new(rw_data.viewport_size.width * DISPLAY_PORT_THRESHOLD_SIZE_FACTOR, - rw_data.viewport_size.height * DISPLAY_PORT_THRESHOLD_SIZE_FACTOR); + Size2D::new(self.viewport_size.width * DISPLAY_PORT_THRESHOLD_SIZE_FACTOR, + self.viewport_size.height * DISPLAY_PORT_THRESHOLD_SIZE_FACTOR); for &(ref layer_id, ref new_visible_rect) in &new_visible_rects { match self.visible_rects.get(layer_id) { None => {