Measure layout queries blocked by ongoing layout

This commit is contained in:
Philipp Albrecht 2019-03-25 22:39:41 +01:00 committed by pylbrecht
parent a74f5222db
commit 858011c513
9 changed files with 73 additions and 6 deletions

View file

@ -92,7 +92,7 @@ use net_traits::{ReferrerPolicy, ResourceThreads};
use num_traits::ToPrimitive;
use profile_traits::ipc as ProfiledIpc;
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::rpc::{ContentBoxResponse, ContentBoxesResponse, LayoutRPC};
use script_layout_interface::rpc::{
@ -117,7 +117,7 @@ use std::fs;
use std::io::{stderr, stdout, Write};
use std::mem;
use std::rc::Rc;
use std::sync::atomic::Ordering;
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::{Arc, Mutex};
use style::dom::OpaqueNode;
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.
/// It is used to avoid sending idle message more than once, which is unneccessary.
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 {
@ -1558,6 +1562,12 @@ impl Window {
}
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(
ReflowGoal::LayoutQuery(query_msg, time::precise_time_ns()),
ReflowReason::Query,
@ -2023,6 +2033,7 @@ impl Window {
microtask_queue: Rc<MicrotaskQueue>,
webrender_document: DocumentId,
webrender_api_sender: RenderApiSender,
layout_is_busy: Arc<AtomicBool>,
) -> DomRoot<Self> {
let layout_rpc: Box<dyn LayoutRPC + Send> = {
let (rpc_send, rpc_recv) = unbounded();
@ -2095,6 +2106,7 @@ impl Window {
exists_mut_observer: Cell::new(false),
webrender_api_sender,
has_sent_idle_message: Cell::new(false),
layout_is_busy,
});
unsafe { WindowBinding::Wrap(runtime.cx(), win) }

View file

@ -144,6 +144,7 @@ use std::option::Option;
use std::ptr;
use std::rc::Rc;
use std::result::Result;
use std::sync::atomic::AtomicBool;
use std::sync::Arc;
use std::thread;
use std::time::{Duration, SystemTime};
@ -202,6 +203,8 @@ struct InProgressLoad {
navigation_start_precise: u64,
/// For cancelling the fetch
canceller: FetchCanceller,
/// Flag to indicate if the layout thread is busy handling a request.
layout_is_busy: Arc<AtomicBool>,
}
impl InProgressLoad {
@ -216,6 +219,7 @@ impl InProgressLoad {
window_size: WindowSizeData,
url: ServoUrl,
origin: MutableOrigin,
layout_is_busy: Arc<AtomicBool>,
) -> InProgressLoad {
let current_time = get_time();
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_precise: navigation_start_precise,
canceller: Default::default(),
layout_is_busy: layout_is_busy,
}
}
}
@ -702,6 +707,7 @@ impl ScriptThreadFactory for ScriptThread {
let opener = state.opener;
let mem_profiler_chan = state.mem_profiler_chan.clone();
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());
@ -722,6 +728,7 @@ impl ScriptThreadFactory for ScriptThread {
window_size,
load_data.url.clone(),
origin,
layout_is_busy,
);
script_thread.pre_page_load(new_load, load_data);
@ -2025,6 +2032,8 @@ impl ScriptThread {
let layout_pair = unbounded();
let layout_chan = layout_pair.0.clone();
let layout_is_busy = Arc::new(AtomicBool::new(false));
let msg = message::Msg::CreateLayoutThread(LayoutThreadInit {
id: new_pipeline_id,
url: load_data.url.clone(),
@ -2043,6 +2052,7 @@ impl ScriptThread {
self.control_chan.clone(),
load_data.url.clone(),
),
layout_is_busy: layout_is_busy.clone(),
});
// Pick a layout thread, any layout thread
@ -2076,6 +2086,7 @@ impl ScriptThread {
window_size,
load_data.url.clone(),
origin,
layout_is_busy.clone(),
);
if load_data.url.as_str() == "about:blank" {
self.start_page_load_about_blank(new_load, load_data.js_eval_result);
@ -2872,6 +2883,7 @@ impl ScriptThread {
self.microtask_queue.clone(),
self.webrender_document,
self.webrender_api_sender.clone(),
incomplete.layout_is_busy,
);
// Initialize the browsing context for the window.