mirror of
https://github.com/servo/servo.git
synced 2025-07-22 23:03:42 +01:00
Send information to script as part of finishing layout.
This avoids the need for multiple layout RPC operations immediately following return of control to script. This means that layout and script can continue to operate in parallel at this point, rather than one potentially waiting on the shared mutex to be unlocked.
This commit is contained in:
parent
c3b9714ab7
commit
9134918844
5 changed files with 60 additions and 51 deletions
|
@ -81,7 +81,8 @@ use profile_traits::mem::{self, Report, ReportKind, ReportsChan};
|
|||
use profile_traits::time::{self, TimerMetadata, profile};
|
||||
use profile_traits::time::{TimerMetadataFrameType, TimerMetadataReflowType};
|
||||
use script::layout_wrapper::{ServoLayoutElement, ServoLayoutDocument, ServoLayoutNode};
|
||||
use script_layout_interface::message::{Msg, NewLayoutThreadInfo, Reflow, ReflowQueryType, ScriptReflow};
|
||||
use script_layout_interface::message::{Msg, NewLayoutThreadInfo, Reflow, ReflowQueryType};
|
||||
use script_layout_interface::message::{ScriptReflow, ReflowComplete};
|
||||
use script_layout_interface::reporter::CSSErrorReporter;
|
||||
use script_layout_interface::rpc::{LayoutRPC, MarginStyleResponse, NodeOverflowResponse, OffsetParentResponse};
|
||||
use script_layout_interface::rpc::TextIndexResponse;
|
||||
|
@ -292,6 +293,37 @@ impl LayoutThreadFactory for LayoutThread {
|
|||
}
|
||||
}
|
||||
|
||||
struct ScriptReflowResult {
|
||||
script_reflow: ScriptReflow,
|
||||
result: RefCell<Option<ReflowComplete>>,
|
||||
}
|
||||
|
||||
impl Deref for ScriptReflowResult {
|
||||
type Target = ScriptReflow;
|
||||
fn deref(&self) -> &ScriptReflow {
|
||||
&self.script_reflow
|
||||
}
|
||||
}
|
||||
|
||||
impl ScriptReflowResult {
|
||||
fn new(script_reflow: ScriptReflow) -> ScriptReflowResult {
|
||||
ScriptReflowResult {
|
||||
script_reflow: script_reflow,
|
||||
result: RefCell::new(Some(Default::default())),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for ScriptReflowResult {
|
||||
fn drop(&mut self) {
|
||||
self.script_reflow.script_join_chan.send(
|
||||
self.result
|
||||
.borrow_mut()
|
||||
.take()
|
||||
.unwrap()).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
/// The `LayoutThread` `rw_data` lock must remain locked until the first reflow,
|
||||
/// as RPC calls don't make sense until then. Use this in combination with
|
||||
/// `LayoutThread::lock_rw_data` and `LayoutThread::return_rw_data`.
|
||||
|
@ -476,9 +508,7 @@ impl LayoutThread {
|
|||
margin_style_response: MarginStyleResponse::empty(),
|
||||
stacking_context_scroll_offsets: HashMap::new(),
|
||||
text_index_response: TextIndexResponse(None),
|
||||
pending_images: vec![],
|
||||
nodes_from_point_response: vec![],
|
||||
newly_transitioning_nodes: vec![],
|
||||
})),
|
||||
error_reporter: CSSErrorReporter {
|
||||
pipelineid: id,
|
||||
|
@ -616,10 +646,11 @@ impl LayoutThread {
|
|||
Box<LayoutRPC + Send>).unwrap();
|
||||
},
|
||||
Msg::Reflow(data) => {
|
||||
let mut data = ScriptReflowResult::new(data);
|
||||
profile(time::ProfilerCategory::LayoutPerform,
|
||||
self.profiler_metadata(),
|
||||
self.time_profiler_chan.clone(),
|
||||
|| self.handle_reflow(&data, possibly_locked_rw_data));
|
||||
|| self.handle_reflow(&mut data, possibly_locked_rw_data));
|
||||
},
|
||||
Msg::TickAnimations => self.tick_all_animations(possibly_locked_rw_data),
|
||||
Msg::SetStackingContextScrollStates(new_scroll_states) => {
|
||||
|
@ -955,7 +986,7 @@ impl LayoutThread {
|
|||
|
||||
/// The high-level routine that performs layout threads.
|
||||
fn handle_reflow<'a, 'b>(&mut self,
|
||||
data: &ScriptReflow,
|
||||
data: &mut ScriptReflowResult,
|
||||
possibly_locked_rw_data: &mut RwData<'a, 'b>) {
|
||||
let document = unsafe { ServoLayoutNode::new(&data.document) };
|
||||
let document = document.as_document().unwrap();
|
||||
|
@ -1240,24 +1271,26 @@ impl LayoutThread {
|
|||
|
||||
self.respond_to_query_if_necessary(&data.query_type,
|
||||
&mut *rw_data,
|
||||
&mut layout_context);
|
||||
&mut layout_context,
|
||||
data.result.borrow_mut().as_mut().unwrap());
|
||||
}
|
||||
|
||||
fn respond_to_query_if_necessary(&self,
|
||||
query_type: &ReflowQueryType,
|
||||
rw_data: &mut LayoutThreadData,
|
||||
context: &mut LayoutContext) {
|
||||
context: &mut LayoutContext,
|
||||
reflow_result: &mut ReflowComplete) {
|
||||
let pending_images = match context.pending_images {
|
||||
Some(ref pending) => std_mem::replace(&mut *pending.lock().unwrap(), vec![]),
|
||||
None => vec![],
|
||||
};
|
||||
rw_data.pending_images = pending_images;
|
||||
reflow_result.pending_images = pending_images;
|
||||
|
||||
let newly_transitioning_nodes = match context.newly_transitioning_nodes {
|
||||
Some(ref nodes) => std_mem::replace(&mut *nodes.lock().unwrap(), vec![]),
|
||||
None => vec![],
|
||||
};
|
||||
rw_data.newly_transitioning_nodes = newly_transitioning_nodes;
|
||||
reflow_result.newly_transitioning_nodes = newly_transitioning_nodes;
|
||||
|
||||
let mut root_flow = match self.root_flow.borrow().clone() {
|
||||
Some(root_flow) => root_flow,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue