aboutsummaryrefslogtreecommitdiffstats
path: root/components/script/script_thread.rs
diff options
context:
space:
mode:
Diffstat (limited to 'components/script/script_thread.rs')
-rw-r--r--components/script/script_thread.rs119
1 files changed, 103 insertions, 16 deletions
diff --git a/components/script/script_thread.rs b/components/script/script_thread.rs
index 1a45b08e54b..1fe8c47b7bc 100644
--- a/components/script/script_thread.rs
+++ b/components/script/script_thread.rs
@@ -16,6 +16,7 @@
//! takes over the response body. Once parsing is complete, the document lifecycle for loading
//! a page runs its course and the script thread returns to processing events in the main event
//! loop.
+#![feature(box_syntax)]
use bluetooth_traits::BluetoothRequest;
use canvas_traits::webgl::WebGLPipeline;
@@ -74,7 +75,7 @@ use js::jsapi::{JSTracer, SetWindowProxyClass};
use js::jsval::UndefinedValue;
use malloc_size_of::MallocSizeOfOps;
use mem::malloc_size_of_including_self;
-use metrics::PaintTimeMetrics;
+use metrics::{InteractiveWindow, PaintTimeMetrics};
use microtask::{MicrotaskQueue, Microtask};
use msg::constellation_msg::{BrowsingContextId, FrameType, PipelineId, PipelineNamespace, TopLevelBrowsingContextId};
use net_traits::{FetchMetadata, FetchResponseListener, FetchResponseMsg};
@@ -91,7 +92,7 @@ use script_traits::{CompositorEvent, ConstellationControlMsg};
use script_traits::{DiscardBrowsingContext, DocumentActivity, EventResult};
use script_traits::{InitialScriptState, JsEvalResult, LayoutMsg, LoadData};
use script_traits::{MouseButton, MouseEventType, MozBrowserEvent, NewLayoutInfo};
-use script_traits::{PaintMetricType, Painter, ScriptMsg, ScriptThreadFactory};
+use script_traits::{PWMType, Painter, ScriptMsg, ScriptThreadFactory};
use script_traits::{ScriptToConstellationChan, TimerEvent, TimerSchedulerMsg};
use script_traits::{TimerSource, TouchEventType, TouchId, UntrustedNodeAddress};
use script_traits::{UpdatePipelineIdReason, WindowSizeData, WindowSizeType};
@@ -345,6 +346,10 @@ impl Documents {
self.map.get(&pipeline_id).map(|doc| DomRoot::from_ref(&**doc))
}
+ pub fn len(&self) -> usize {
+ self.map.len()
+ }
+
pub fn find_window(&self, pipeline_id: PipelineId) -> Option<DomRoot<Window>> {
self.find_document(pipeline_id).map(|doc| DomRoot::from_ref(doc.window()))
}
@@ -681,7 +686,8 @@ impl ScriptThread {
SCRIPT_THREAD_ROOT.with(|root| {
if let Some(script_thread) = root.get() {
let script_thread = unsafe { &*script_thread };
- script_thread.profile_event(ScriptThreadEventCategory::AttachLayout, || {
+ let p_id = Some(new_layout_info.new_pipeline_id);
+ script_thread.profile_event(ScriptThreadEventCategory::AttachLayout, p_id, || {
script_thread.handle_new_layout(new_layout_info, origin);
})
}
@@ -727,8 +733,8 @@ impl ScriptThread {
pipeline_id: PipelineId,
name: Atom,
properties: Vec<Atom>,
- painter: Box<Painter>,
- ) {
+ painter: Box<Painter>)
+ {
let window = self.documents.borrow().find_window(pipeline_id);
let window = match window {
Some(window) => window,
@@ -840,7 +846,7 @@ impl ScriptThread {
control_chan: state.control_chan,
control_port: control_port,
script_sender: state.script_to_constellation_chan.sender.clone(),
- time_profiler_chan: state.time_profiler_chan,
+ time_profiler_chan: state.time_profiler_chan.clone(),
mem_profiler_chan: state.mem_profiler_chan,
devtools_chan: state.devtools_chan,
@@ -964,7 +970,8 @@ impl ScriptThread {
// child list yet, causing the find() to fail.
FromConstellation(ConstellationControlMsg::AttachLayout(
new_layout_info)) => {
- self.profile_event(ScriptThreadEventCategory::AttachLayout, || {
+ //FIXME there should be a pipeline id
+ self.profile_event(ScriptThreadEventCategory::AttachLayout, None, || {
// If this is an about:blank load, it must share the creator's origin.
// This must match the logic in the constellation when creating a new pipeline
let origin = if new_layout_info.load_data.url.as_str() != "about:blank" {
@@ -986,17 +993,17 @@ impl ScriptThread {
}
FromConstellation(ConstellationControlMsg::Resize(id, size, size_type)) => {
// step 7.7
- self.profile_event(ScriptThreadEventCategory::Resize, || {
+ self.profile_event(ScriptThreadEventCategory::Resize, Some(id), || {
self.handle_resize(id, size, size_type);
})
}
FromConstellation(ConstellationControlMsg::Viewport(id, rect)) => {
- self.profile_event(ScriptThreadEventCategory::SetViewport, || {
+ self.profile_event(ScriptThreadEventCategory::SetViewport, Some(id), || {
self.handle_viewport(id, rect);
})
}
FromConstellation(ConstellationControlMsg::SetScrollState(id, scroll_state)) => {
- self.profile_event(ScriptThreadEventCategory::SetScrollState, || {
+ self.profile_event(ScriptThreadEventCategory::SetScrollState, Some(id), || {
self.handle_set_scroll_state(id, &scroll_state);
})
}
@@ -1051,9 +1058,11 @@ impl ScriptThread {
debug!("Processing events.");
for msg in sequential {
debug!("Processing event {:?}.", msg);
+
let category = self.categorize_msg(&msg);
+ let p_id = self.message_to_pipeline(&msg);
- let result = self.profile_event(category, move || {
+ let result = self.profile_event(category, p_id, move || {
match msg {
FromConstellation(ConstellationControlMsg::ExitScriptThread) => {
self.handle_exit_script_thread_msg();
@@ -1122,7 +1131,7 @@ impl ScriptThread {
MixedMessage::FromImageCache(_) => ScriptThreadEventCategory::ImageCacheMsg,
MixedMessage::FromScript(ref inner_msg) => {
match *inner_msg {
- MainThreadScriptMsg::Common(CommonScriptMsg::Task(category, _)) => {
+ MainThreadScriptMsg::Common(CommonScriptMsg::Task(category, ..)) => {
category
},
MainThreadScriptMsg::RegisterPaintWorklet { .. } => {
@@ -1135,7 +1144,67 @@ impl ScriptThread {
}
}
- fn profile_event<F, R>(&self, category: ScriptThreadEventCategory, f: F) -> R
+ fn message_to_pipeline(&self, msg: &MixedMessage) -> Option<PipelineId> {
+ use script_traits::ConstellationControlMsg::*;
+ match *msg {
+ MixedMessage::FromConstellation(ref inner_msg) => {
+ match *inner_msg {
+ NavigationResponse(id, _) => Some(id),
+ AttachLayout(ref new_layout_info) => Some(new_layout_info.new_pipeline_id),
+ Resize(id, ..) => Some(id),
+ ResizeInactive(id, ..) => Some(id),
+ ExitPipeline(id, ..) => Some(id),
+ ExitScriptThread => None,
+ SendEvent(id, ..) => Some(id),
+ Viewport(id, ..) => Some(id),
+ SetScrollState(id, ..) => Some(id),
+ GetTitle(id) => Some(id),
+ SetDocumentActivity(id, ..) => Some(id),
+ ChangeFrameVisibilityStatus(id, ..) => Some(id),
+ NotifyVisibilityChange(id, ..) => Some(id),
+ Navigate(id, ..) => Some(id),
+ PostMessage(id, ..) => Some(id),
+ MozBrowserEvent(id, ..) => Some(id),
+ UpdatePipelineId(_, _, id, _) => Some(id),
+ FocusIFrame(id, ..) => Some(id),
+ WebDriverScriptCommand(id, ..) => Some(id),
+ TickAllAnimations(id) => Some(id),
+ TransitionEnd(..) => None,
+ WebFontLoaded(id) => Some(id),
+ DispatchIFrameLoadEvent { .. } => None,
+ DispatchStorageEvent(id, ..) => Some(id),
+ ReportCSSError(id, ..) => Some(id),
+ Reload(id, ..) => Some(id),
+ WebVREvents(id, ..) => Some(id),
+ PaintMetric(..) => None,
+ InteractiveMetric(..) => None,
+ }
+ },
+ MixedMessage::FromDevtools(_) => None,
+ MixedMessage::FromScript(ref inner_msg) => {
+ match *inner_msg {
+ MainThreadScriptMsg::Common(CommonScriptMsg::Task(_, _, pipeline_id)) =>
+ pipeline_id,
+ MainThreadScriptMsg::Common(_) => None, //TODO double check
+ MainThreadScriptMsg::ExitWindow(pipeline_id) => Some(pipeline_id),
+ MainThreadScriptMsg::Navigate(pipeline_id, ..) => Some(pipeline_id),
+ MainThreadScriptMsg::WorkletLoaded(pipeline_id) => Some(pipeline_id),
+ MainThreadScriptMsg::RegisterPaintWorklet { pipeline_id, .. } => Some(pipeline_id),
+ MainThreadScriptMsg::DispatchJobQueue { .. } => None,
+ }
+ },
+ MixedMessage::FromImageCache((pipeline_id, _)) => Some(pipeline_id),
+ MixedMessage::FromScheduler(ref timer_event) => {
+ let TimerEvent(source, _) = *timer_event;
+ match source {
+ TimerSource::FromWindow(pipeline_id) => Some(pipeline_id),
+ _ => None
+ }
+ }
+ }
+ }
+
+ fn profile_event<F, R>(&self, category: ScriptThreadEventCategory, p_id: Option<PipelineId>, f: F) -> R
where F: FnOnce() -> R {
if opts::get().profile_script_events {
let profiler_cat = match category {
@@ -1169,7 +1238,24 @@ impl ScriptThread {
ScriptThreadEventCategory::ExitFullscreen => ProfilerCategory::ScriptExitFullscreen,
ScriptThreadEventCategory::PerformanceTimelineTask => ProfilerCategory::ScriptPerformanceEvent,
};
- profile(profiler_cat, None, self.time_profiler_chan.clone(), f)
+
+ let start = precise_time_ns();
+ let t = profile(profiler_cat, None, self.time_profiler_chan.clone(), f);
+ let end = precise_time_ns();
+ debug!("Task {:?} took {}", category, end - start); // TODO do we want to do anything with this?
+
+ for (doc_id, doc) in self.documents.borrow().iter() {
+ match p_id {
+ Some(p_id) => {
+ if p_id == doc_id && end - start > InteractiveWindow::max_task_time() {
+ doc.start_tti()
+ }
+ },
+ _ => ()
+ }
+ doc.check_tti();
+ }
+ t
} else {
f()
}
@@ -1240,6 +1326,7 @@ impl ScriptThread {
self.handle_webvr_events(pipeline_id, events),
ConstellationControlMsg::PaintMetric(pipeline_id, metric_type, metric_value) =>
self.handle_paint_metric(pipeline_id, metric_type, metric_value),
+ ConstellationControlMsg::InteractiveMetric(pipeline_id, metric_value) => (), //TODO
msg @ ConstellationControlMsg::AttachLayout(..) |
msg @ ConstellationControlMsg::Viewport(..) |
msg @ ConstellationControlMsg::SetScrollState(..) |
@@ -1257,7 +1344,7 @@ impl ScriptThread {
MainThreadScriptMsg::ExitWindow(id) => {
self.handle_exit_window_msg(id)
},
- MainThreadScriptMsg::Common(CommonScriptMsg::Task(_, task)) => {
+ MainThreadScriptMsg::Common(CommonScriptMsg::Task(_, task, _)) => {
task.run_box()
}
MainThreadScriptMsg::Common(CommonScriptMsg::CollectReports(chan)) => {
@@ -2563,7 +2650,7 @@ impl ScriptThread {
fn handle_paint_metric(&self,
pipeline_id: PipelineId,
- metric_type: PaintMetricType,
+ metric_type: PWMType,
metric_value: f64) {
let window = self.documents.borrow().find_window(pipeline_id);
if let Some(window) = window {