mirror of
https://github.com/servo/servo.git
synced 2025-08-03 20:50:07 +01:00
Measure layout queries blocked by ongoing layout
This commit is contained in:
parent
a74f5222db
commit
858011c513
9 changed files with 73 additions and 6 deletions
|
@ -40,6 +40,7 @@ use std::env;
|
||||||
use std::ffi::OsStr;
|
use std::ffi::OsStr;
|
||||||
use std::process;
|
use std::process;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
use std::sync::atomic::AtomicBool;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use style_traits::CSSPixel;
|
use style_traits::CSSPixel;
|
||||||
use style_traits::DevicePixel;
|
use style_traits::DevicePixel;
|
||||||
|
@ -528,6 +529,7 @@ impl UnprivilegedPipelineContent {
|
||||||
self.script_chan.clone(),
|
self.script_chan.clone(),
|
||||||
self.load_data.url.clone(),
|
self.load_data.url.clone(),
|
||||||
);
|
);
|
||||||
|
let layout_thread_busy_flag = Arc::new(AtomicBool::new(false));
|
||||||
let layout_pair = STF::create(
|
let layout_pair = STF::create(
|
||||||
InitialScriptState {
|
InitialScriptState {
|
||||||
id: self.id,
|
id: self.id,
|
||||||
|
@ -554,6 +556,7 @@ impl UnprivilegedPipelineContent {
|
||||||
webvr_chan: self.webvr_chan,
|
webvr_chan: self.webvr_chan,
|
||||||
webrender_document: self.webrender_document,
|
webrender_document: self.webrender_document,
|
||||||
webrender_api_sender: self.webrender_api_sender.clone(),
|
webrender_api_sender: self.webrender_api_sender.clone(),
|
||||||
|
layout_is_busy: layout_thread_busy_flag.clone(),
|
||||||
},
|
},
|
||||||
self.load_data.clone(),
|
self.load_data.clone(),
|
||||||
);
|
);
|
||||||
|
@ -576,6 +579,7 @@ impl UnprivilegedPipelineContent {
|
||||||
self.webrender_api_sender,
|
self.webrender_api_sender,
|
||||||
self.webrender_document,
|
self.webrender_document,
|
||||||
paint_time_metrics,
|
paint_time_metrics,
|
||||||
|
layout_thread_busy_flag.clone(),
|
||||||
);
|
);
|
||||||
|
|
||||||
if wait_for_completion {
|
if wait_for_completion {
|
||||||
|
|
|
@ -96,7 +96,7 @@ use std::cell::{Cell, RefCell};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::ops::{Deref, DerefMut};
|
use std::ops::{Deref, DerefMut};
|
||||||
use std::process;
|
use std::process;
|
||||||
use std::sync::atomic::{AtomicUsize, Ordering};
|
use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering};
|
||||||
use std::sync::{Arc, Mutex, MutexGuard};
|
use std::sync::{Arc, Mutex, MutexGuard};
|
||||||
use std::thread;
|
use std::thread;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
@ -244,6 +244,9 @@ pub struct LayoutThread {
|
||||||
|
|
||||||
/// The sizes of all iframes encountered during the last layout operation.
|
/// The sizes of all iframes encountered during the last layout operation.
|
||||||
last_iframe_sizes: RefCell<HashMap<BrowsingContextId, TypedSize2D<f32, CSSPixel>>>,
|
last_iframe_sizes: RefCell<HashMap<BrowsingContextId, TypedSize2D<f32, CSSPixel>>>,
|
||||||
|
|
||||||
|
/// Flag that indicates if LayoutThread is busy handling a request.
|
||||||
|
busy: Arc<AtomicBool>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl LayoutThreadFactory for LayoutThread {
|
impl LayoutThreadFactory for LayoutThread {
|
||||||
|
@ -268,6 +271,7 @@ impl LayoutThreadFactory for LayoutThread {
|
||||||
webrender_api_sender: webrender_api::RenderApiSender,
|
webrender_api_sender: webrender_api::RenderApiSender,
|
||||||
webrender_document: webrender_api::DocumentId,
|
webrender_document: webrender_api::DocumentId,
|
||||||
paint_time_metrics: PaintTimeMetrics,
|
paint_time_metrics: PaintTimeMetrics,
|
||||||
|
busy: Arc<AtomicBool>,
|
||||||
) {
|
) {
|
||||||
thread::Builder::new()
|
thread::Builder::new()
|
||||||
.name(format!("LayoutThread {:?}", id))
|
.name(format!("LayoutThread {:?}", id))
|
||||||
|
@ -305,6 +309,7 @@ impl LayoutThreadFactory for LayoutThread {
|
||||||
webrender_api_sender,
|
webrender_api_sender,
|
||||||
webrender_document,
|
webrender_document,
|
||||||
paint_time_metrics,
|
paint_time_metrics,
|
||||||
|
busy,
|
||||||
);
|
);
|
||||||
|
|
||||||
let reporter_name = format!("layout-reporter-{}", id);
|
let reporter_name = format!("layout-reporter-{}", id);
|
||||||
|
@ -466,6 +471,7 @@ impl LayoutThread {
|
||||||
webrender_api_sender: webrender_api::RenderApiSender,
|
webrender_api_sender: webrender_api::RenderApiSender,
|
||||||
webrender_document: webrender_api::DocumentId,
|
webrender_document: webrender_api::DocumentId,
|
||||||
paint_time_metrics: PaintTimeMetrics,
|
paint_time_metrics: PaintTimeMetrics,
|
||||||
|
busy: Arc<AtomicBool>,
|
||||||
) -> LayoutThread {
|
) -> LayoutThread {
|
||||||
// The device pixel ratio is incorrect (it does not have the hidpi value),
|
// The device pixel ratio is incorrect (it does not have the hidpi value),
|
||||||
// but it will be set correctly when the initial reflow takes place.
|
// but it will be set correctly when the initial reflow takes place.
|
||||||
|
@ -544,6 +550,7 @@ impl LayoutThread {
|
||||||
paint_time_metrics: paint_time_metrics,
|
paint_time_metrics: paint_time_metrics,
|
||||||
layout_query_waiting_time: Histogram::new(),
|
layout_query_waiting_time: Histogram::new(),
|
||||||
last_iframe_sizes: Default::default(),
|
last_iframe_sizes: Default::default(),
|
||||||
|
busy: busy,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -648,7 +655,8 @@ impl LayoutThread {
|
||||||
recv(self.font_cache_receiver) -> msg => { msg.unwrap(); Request::FromFontCache }
|
recv(self.font_cache_receiver) -> msg => { msg.unwrap(); Request::FromFontCache }
|
||||||
};
|
};
|
||||||
|
|
||||||
match request {
|
self.busy.store(true, Ordering::Relaxed);
|
||||||
|
let result = match request {
|
||||||
Request::FromPipeline(LayoutControlMsg::SetScrollStates(new_scroll_states)) => self
|
Request::FromPipeline(LayoutControlMsg::SetScrollStates(new_scroll_states)) => self
|
||||||
.handle_request_helper(
|
.handle_request_helper(
|
||||||
Msg::SetScrollStates(new_scroll_states),
|
Msg::SetScrollStates(new_scroll_states),
|
||||||
|
@ -679,7 +687,9 @@ impl LayoutThread {
|
||||||
.unwrap();
|
.unwrap();
|
||||||
true
|
true
|
||||||
},
|
},
|
||||||
}
|
};
|
||||||
|
self.busy.store(false, Ordering::Relaxed);
|
||||||
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Receives and dispatches messages from other threads.
|
/// Receives and dispatches messages from other threads.
|
||||||
|
@ -861,6 +871,7 @@ impl LayoutThread {
|
||||||
self.webrender_api.clone_sender(),
|
self.webrender_api.clone_sender(),
|
||||||
self.webrender_document,
|
self.webrender_document,
|
||||||
info.paint_time_metrics,
|
info.paint_time_metrics,
|
||||||
|
self.busy.clone(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,7 @@ use profile_traits::{mem, time};
|
||||||
use script_traits::LayoutMsg as ConstellationMsg;
|
use script_traits::LayoutMsg as ConstellationMsg;
|
||||||
use script_traits::{ConstellationControlMsg, LayoutControlMsg};
|
use script_traits::{ConstellationControlMsg, LayoutControlMsg};
|
||||||
use servo_url::ServoUrl;
|
use servo_url::ServoUrl;
|
||||||
|
use std::sync::atomic::AtomicBool;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
// A static method creating a layout thread
|
// A static method creating a layout thread
|
||||||
|
@ -44,5 +45,6 @@ pub trait LayoutThreadFactory {
|
||||||
webrender_api_sender: webrender_api::RenderApiSender,
|
webrender_api_sender: webrender_api::RenderApiSender,
|
||||||
webrender_document: webrender_api::DocumentId,
|
webrender_document: webrender_api::DocumentId,
|
||||||
paint_time_metrics: PaintTimeMetrics,
|
paint_time_metrics: PaintTimeMetrics,
|
||||||
|
busy: Arc<AtomicBool>,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,7 @@ use profile_traits::time::{TimerMetadataFrameType, TimerMetadataReflowType};
|
||||||
use servo_config::opts::OutputOptions;
|
use servo_config::opts::OutputOptions;
|
||||||
use std::borrow::ToOwned;
|
use std::borrow::ToOwned;
|
||||||
use std::cmp::Ordering;
|
use std::cmp::Ordering;
|
||||||
use std::collections::BTreeMap;
|
use std::collections::{BTreeMap, HashMap};
|
||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io::{self, Write};
|
use std::io::{self, Write};
|
||||||
|
@ -171,6 +171,7 @@ pub struct Profiler {
|
||||||
output: Option<OutputOptions>,
|
output: Option<OutputOptions>,
|
||||||
pub last_msg: Option<ProfilerMsg>,
|
pub last_msg: Option<ProfilerMsg>,
|
||||||
trace: Option<TraceDump>,
|
trace: Option<TraceDump>,
|
||||||
|
blocked_layout_queries: HashMap<String, u32>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Profiler {
|
impl Profiler {
|
||||||
|
@ -305,6 +306,7 @@ impl Profiler {
|
||||||
output: output,
|
output: output,
|
||||||
last_msg: None,
|
last_msg: None,
|
||||||
trace: trace,
|
trace: trace,
|
||||||
|
blocked_layout_queries: HashMap::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -345,6 +347,9 @@ impl Profiler {
|
||||||
None => sender.send(ProfilerData::NoRecords).unwrap(),
|
None => sender.send(ProfilerData::NoRecords).unwrap(),
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
ProfilerMsg::BlockedLayoutQuery(url) => {
|
||||||
|
*self.blocked_layout_queries.entry(url).or_insert(0) += 1;
|
||||||
|
},
|
||||||
ProfilerMsg::Exit(chan) => {
|
ProfilerMsg::Exit(chan) => {
|
||||||
heartbeats::cleanup();
|
heartbeats::cleanup();
|
||||||
self.print_buckets();
|
self.print_buckets();
|
||||||
|
@ -411,6 +416,11 @@ impl Profiler {
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
write!(file, "_url\t_blocked layout queries_\n").unwrap();
|
||||||
|
for (url, count) in &self.blocked_layout_queries {
|
||||||
|
write!(file, "{}\t{}\n", url, count).unwrap();
|
||||||
|
}
|
||||||
},
|
},
|
||||||
Some(OutputOptions::Stdout(_)) => {
|
Some(OutputOptions::Stdout(_)) => {
|
||||||
let stdout = io::stdout();
|
let stdout = io::stdout();
|
||||||
|
@ -450,6 +460,12 @@ impl Profiler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
writeln!(&mut lock, "").unwrap();
|
writeln!(&mut lock, "").unwrap();
|
||||||
|
|
||||||
|
writeln!(&mut lock, "_url_\t_blocked layout queries_").unwrap();
|
||||||
|
for (url, count) in &self.blocked_layout_queries {
|
||||||
|
writeln!(&mut lock, "{}\t{}", url, count).unwrap();
|
||||||
|
}
|
||||||
|
writeln!(&mut lock, "").unwrap();
|
||||||
},
|
},
|
||||||
Some(OutputOptions::DB(ref hostname, ref dbname, ref user, ref password)) => {
|
Some(OutputOptions::DB(ref hostname, ref dbname, ref user, ref password)) => {
|
||||||
// Unfortunately, influent does not like hostnames ending with "/"
|
// Unfortunately, influent does not like hostnames ending with "/"
|
||||||
|
|
|
@ -46,6 +46,11 @@ pub enum ProfilerMsg {
|
||||||
),
|
),
|
||||||
/// Message used to force print the profiling metrics
|
/// Message used to force print the profiling metrics
|
||||||
Print,
|
Print,
|
||||||
|
|
||||||
|
// TODO pylbrecht
|
||||||
|
// write meaningful docstring
|
||||||
|
BlockedLayoutQuery(String),
|
||||||
|
|
||||||
/// Tells the profiler to shut down.
|
/// Tells the profiler to shut down.
|
||||||
Exit(IpcSender<()>),
|
Exit(IpcSender<()>),
|
||||||
}
|
}
|
||||||
|
|
|
@ -92,7 +92,7 @@ use net_traits::{ReferrerPolicy, ResourceThreads};
|
||||||
use num_traits::ToPrimitive;
|
use num_traits::ToPrimitive;
|
||||||
use profile_traits::ipc as ProfiledIpc;
|
use profile_traits::ipc as ProfiledIpc;
|
||||||
use profile_traits::mem::ProfilerChan as MemProfilerChan;
|
use profile_traits::mem::ProfilerChan as MemProfilerChan;
|
||||||
use profile_traits::time::ProfilerChan as TimeProfilerChan;
|
use profile_traits::time::{ProfilerChan as TimeProfilerChan, ProfilerMsg};
|
||||||
use script_layout_interface::message::{Msg, QueryMsg, Reflow, ReflowGoal, ScriptReflow};
|
use script_layout_interface::message::{Msg, QueryMsg, Reflow, ReflowGoal, ScriptReflow};
|
||||||
use script_layout_interface::rpc::{ContentBoxResponse, ContentBoxesResponse, LayoutRPC};
|
use script_layout_interface::rpc::{ContentBoxResponse, ContentBoxesResponse, LayoutRPC};
|
||||||
use script_layout_interface::rpc::{
|
use script_layout_interface::rpc::{
|
||||||
|
@ -117,7 +117,7 @@ use std::fs;
|
||||||
use std::io::{stderr, stdout, Write};
|
use std::io::{stderr, stdout, Write};
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::sync::atomic::Ordering;
|
use std::sync::atomic::{AtomicBool, Ordering};
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
use style::dom::OpaqueNode;
|
use style::dom::OpaqueNode;
|
||||||
use style::error_reporting::{ContextualParseError, ParseErrorReporter};
|
use style::error_reporting::{ContextualParseError, ParseErrorReporter};
|
||||||
|
@ -293,6 +293,10 @@ pub struct Window {
|
||||||
/// Indicate whether a SetDocumentStatus message has been sent after a reflow is complete.
|
/// Indicate whether a SetDocumentStatus message has been sent after a reflow is complete.
|
||||||
/// It is used to avoid sending idle message more than once, which is unneccessary.
|
/// It is used to avoid sending idle message more than once, which is unneccessary.
|
||||||
has_sent_idle_message: Cell<bool>,
|
has_sent_idle_message: Cell<bool>,
|
||||||
|
|
||||||
|
/// Flag that indicates if the layout thread is busy handling a request.
|
||||||
|
#[ignore_malloc_size_of = "Arc<T> is hard"]
|
||||||
|
layout_is_busy: Arc<AtomicBool>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Window {
|
impl Window {
|
||||||
|
@ -1558,6 +1562,12 @@ impl Window {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn layout_reflow(&self, query_msg: QueryMsg) -> bool {
|
pub fn layout_reflow(&self, query_msg: QueryMsg) -> bool {
|
||||||
|
if self.layout_is_busy.load(Ordering::Relaxed) {
|
||||||
|
let url = self.get_url().into_string();
|
||||||
|
self.time_profiler_chan()
|
||||||
|
.send(ProfilerMsg::BlockedLayoutQuery(url));
|
||||||
|
}
|
||||||
|
|
||||||
self.reflow(
|
self.reflow(
|
||||||
ReflowGoal::LayoutQuery(query_msg, time::precise_time_ns()),
|
ReflowGoal::LayoutQuery(query_msg, time::precise_time_ns()),
|
||||||
ReflowReason::Query,
|
ReflowReason::Query,
|
||||||
|
@ -2023,6 +2033,7 @@ impl Window {
|
||||||
microtask_queue: Rc<MicrotaskQueue>,
|
microtask_queue: Rc<MicrotaskQueue>,
|
||||||
webrender_document: DocumentId,
|
webrender_document: DocumentId,
|
||||||
webrender_api_sender: RenderApiSender,
|
webrender_api_sender: RenderApiSender,
|
||||||
|
layout_is_busy: Arc<AtomicBool>,
|
||||||
) -> DomRoot<Self> {
|
) -> DomRoot<Self> {
|
||||||
let layout_rpc: Box<dyn LayoutRPC + Send> = {
|
let layout_rpc: Box<dyn LayoutRPC + Send> = {
|
||||||
let (rpc_send, rpc_recv) = unbounded();
|
let (rpc_send, rpc_recv) = unbounded();
|
||||||
|
@ -2095,6 +2106,7 @@ impl Window {
|
||||||
exists_mut_observer: Cell::new(false),
|
exists_mut_observer: Cell::new(false),
|
||||||
webrender_api_sender,
|
webrender_api_sender,
|
||||||
has_sent_idle_message: Cell::new(false),
|
has_sent_idle_message: Cell::new(false),
|
||||||
|
layout_is_busy,
|
||||||
});
|
});
|
||||||
|
|
||||||
unsafe { WindowBinding::Wrap(runtime.cx(), win) }
|
unsafe { WindowBinding::Wrap(runtime.cx(), win) }
|
||||||
|
|
|
@ -144,6 +144,7 @@ use std::option::Option;
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::result::Result;
|
use std::result::Result;
|
||||||
|
use std::sync::atomic::AtomicBool;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::thread;
|
use std::thread;
|
||||||
use std::time::{Duration, SystemTime};
|
use std::time::{Duration, SystemTime};
|
||||||
|
@ -202,6 +203,8 @@ struct InProgressLoad {
|
||||||
navigation_start_precise: u64,
|
navigation_start_precise: u64,
|
||||||
/// For cancelling the fetch
|
/// For cancelling the fetch
|
||||||
canceller: FetchCanceller,
|
canceller: FetchCanceller,
|
||||||
|
/// Flag to indicate if the layout thread is busy handling a request.
|
||||||
|
layout_is_busy: Arc<AtomicBool>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl InProgressLoad {
|
impl InProgressLoad {
|
||||||
|
@ -216,6 +219,7 @@ impl InProgressLoad {
|
||||||
window_size: WindowSizeData,
|
window_size: WindowSizeData,
|
||||||
url: ServoUrl,
|
url: ServoUrl,
|
||||||
origin: MutableOrigin,
|
origin: MutableOrigin,
|
||||||
|
layout_is_busy: Arc<AtomicBool>,
|
||||||
) -> InProgressLoad {
|
) -> InProgressLoad {
|
||||||
let current_time = get_time();
|
let current_time = get_time();
|
||||||
let navigation_start_precise = precise_time_ns();
|
let navigation_start_precise = precise_time_ns();
|
||||||
|
@ -237,6 +241,7 @@ impl InProgressLoad {
|
||||||
navigation_start: (current_time.sec * 1000 + current_time.nsec as i64 / 1000000) as u64,
|
navigation_start: (current_time.sec * 1000 + current_time.nsec as i64 / 1000000) as u64,
|
||||||
navigation_start_precise: navigation_start_precise,
|
navigation_start_precise: navigation_start_precise,
|
||||||
canceller: Default::default(),
|
canceller: Default::default(),
|
||||||
|
layout_is_busy: layout_is_busy,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -702,6 +707,7 @@ impl ScriptThreadFactory for ScriptThread {
|
||||||
let opener = state.opener;
|
let opener = state.opener;
|
||||||
let mem_profiler_chan = state.mem_profiler_chan.clone();
|
let mem_profiler_chan = state.mem_profiler_chan.clone();
|
||||||
let window_size = state.window_size;
|
let window_size = state.window_size;
|
||||||
|
let layout_is_busy = state.layout_is_busy.clone();
|
||||||
|
|
||||||
let script_thread = ScriptThread::new(state, script_port, script_chan.clone());
|
let script_thread = ScriptThread::new(state, script_port, script_chan.clone());
|
||||||
|
|
||||||
|
@ -722,6 +728,7 @@ impl ScriptThreadFactory for ScriptThread {
|
||||||
window_size,
|
window_size,
|
||||||
load_data.url.clone(),
|
load_data.url.clone(),
|
||||||
origin,
|
origin,
|
||||||
|
layout_is_busy,
|
||||||
);
|
);
|
||||||
script_thread.pre_page_load(new_load, load_data);
|
script_thread.pre_page_load(new_load, load_data);
|
||||||
|
|
||||||
|
@ -2025,6 +2032,8 @@ impl ScriptThread {
|
||||||
let layout_pair = unbounded();
|
let layout_pair = unbounded();
|
||||||
let layout_chan = layout_pair.0.clone();
|
let layout_chan = layout_pair.0.clone();
|
||||||
|
|
||||||
|
let layout_is_busy = Arc::new(AtomicBool::new(false));
|
||||||
|
|
||||||
let msg = message::Msg::CreateLayoutThread(LayoutThreadInit {
|
let msg = message::Msg::CreateLayoutThread(LayoutThreadInit {
|
||||||
id: new_pipeline_id,
|
id: new_pipeline_id,
|
||||||
url: load_data.url.clone(),
|
url: load_data.url.clone(),
|
||||||
|
@ -2043,6 +2052,7 @@ impl ScriptThread {
|
||||||
self.control_chan.clone(),
|
self.control_chan.clone(),
|
||||||
load_data.url.clone(),
|
load_data.url.clone(),
|
||||||
),
|
),
|
||||||
|
layout_is_busy: layout_is_busy.clone(),
|
||||||
});
|
});
|
||||||
|
|
||||||
// Pick a layout thread, any layout thread
|
// Pick a layout thread, any layout thread
|
||||||
|
@ -2076,6 +2086,7 @@ impl ScriptThread {
|
||||||
window_size,
|
window_size,
|
||||||
load_data.url.clone(),
|
load_data.url.clone(),
|
||||||
origin,
|
origin,
|
||||||
|
layout_is_busy.clone(),
|
||||||
);
|
);
|
||||||
if load_data.url.as_str() == "about:blank" {
|
if load_data.url.as_str() == "about:blank" {
|
||||||
self.start_page_load_about_blank(new_load, load_data.js_eval_result);
|
self.start_page_load_about_blank(new_load, load_data.js_eval_result);
|
||||||
|
@ -2872,6 +2883,7 @@ impl ScriptThread {
|
||||||
self.microtask_queue.clone(),
|
self.microtask_queue.clone(),
|
||||||
self.webrender_document,
|
self.webrender_document,
|
||||||
self.webrender_api_sender.clone(),
|
self.webrender_api_sender.clone(),
|
||||||
|
incomplete.layout_is_busy,
|
||||||
);
|
);
|
||||||
|
|
||||||
// Initialize the browsing context for the window.
|
// Initialize the browsing context for the window.
|
||||||
|
|
|
@ -19,6 +19,7 @@ use script_traits::{ScrollState, UntrustedNodeAddress, WindowSizeData};
|
||||||
use servo_arc::Arc as ServoArc;
|
use servo_arc::Arc as ServoArc;
|
||||||
use servo_atoms::Atom;
|
use servo_atoms::Atom;
|
||||||
use servo_url::ServoUrl;
|
use servo_url::ServoUrl;
|
||||||
|
use std::sync::atomic::AtomicBool;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use style::context::QuirksMode;
|
use style::context::QuirksMode;
|
||||||
use style::dom::OpaqueNode;
|
use style::dom::OpaqueNode;
|
||||||
|
@ -226,4 +227,5 @@ pub struct LayoutThreadInit {
|
||||||
pub image_cache: Arc<dyn ImageCache>,
|
pub image_cache: Arc<dyn ImageCache>,
|
||||||
pub content_process_shutdown_chan: Option<IpcSender<()>>,
|
pub content_process_shutdown_chan: Option<IpcSender<()>>,
|
||||||
pub paint_time_metrics: PaintTimeMetrics,
|
pub paint_time_metrics: PaintTimeMetrics,
|
||||||
|
pub layout_is_busy: Arc<AtomicBool>,
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,6 +50,7 @@ use servo_url::ImmutableOrigin;
|
||||||
use servo_url::ServoUrl;
|
use servo_url::ServoUrl;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
use std::sync::atomic::AtomicBool;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use style_traits::CSSPixel;
|
use style_traits::CSSPixel;
|
||||||
|
@ -600,6 +601,8 @@ pub struct InitialScriptState {
|
||||||
pub webrender_document: DocumentId,
|
pub webrender_document: DocumentId,
|
||||||
/// FIXME(victor): The Webrender API sender in this constellation's pipeline
|
/// FIXME(victor): The Webrender API sender in this constellation's pipeline
|
||||||
pub webrender_api_sender: RenderApiSender,
|
pub webrender_api_sender: RenderApiSender,
|
||||||
|
/// Flag to indicate if the layout thread is busy handling a request.
|
||||||
|
pub layout_is_busy: Arc<AtomicBool>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This trait allows creating a `ScriptThread` without depending on the `script`
|
/// This trait allows creating a `ScriptThread` without depending on the `script`
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue