mirror of
https://github.com/servo/servo.git
synced 2025-07-24 15:50:21 +01:00
Introduce a RwData struct.
This commit is contained in:
parent
b8d8505463
commit
3f4c734cf4
1 changed files with 78 additions and 82 deletions
|
@ -311,6 +311,36 @@ impl<'a> DerefMut for RWGuard<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct RwData<'a, 'b: 'a> {
|
||||||
|
rw_data: &'b Arc<Mutex<LayoutTaskData>>,
|
||||||
|
possibly_locked_rw_data: &'a mut Option<MutexGuard<'b, LayoutTaskData>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
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,
|
fn add_font_face_rules(stylesheet: &Stylesheet,
|
||||||
device: &Device,
|
device: &Device,
|
||||||
font_cache_task: &FontCacheTask,
|
font_cache_task: &FontCacheTask,
|
||||||
|
@ -432,8 +462,13 @@ impl LayoutTask {
|
||||||
|
|
||||||
/// Starts listening on the port.
|
/// Starts listening on the port.
|
||||||
fn start(self) {
|
fn start(self) {
|
||||||
let mut possibly_locked_rw_data = Some((*self.rw_data).lock().unwrap());
|
let rw_data = self.rw_data.clone();
|
||||||
while self.handle_request(&mut possibly_locked_rw_data) {
|
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.
|
// Loop indefinitely.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -463,9 +498,7 @@ impl LayoutTask {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Receives and dispatches messages from the script and constellation tasks
|
/// Receives and dispatches messages from the script and constellation tasks
|
||||||
fn handle_request<'a>(&'a self,
|
fn handle_request<'a, 'b>(&self, possibly_locked_rw_data: &mut RwData<'a, 'b>) -> bool {
|
||||||
possibly_locked_rw_data: &mut Option<MutexGuard<'a, LayoutTaskData>>)
|
|
||||||
-> bool {
|
|
||||||
enum Request {
|
enum Request {
|
||||||
FromPipeline(LayoutControlMsg),
|
FromPipeline(LayoutControlMsg),
|
||||||
FromScript(Msg),
|
FromScript(Msg),
|
||||||
|
@ -521,7 +554,7 @@ impl LayoutTask {
|
||||||
self.repaint(possibly_locked_rw_data)
|
self.repaint(possibly_locked_rw_data)
|
||||||
},
|
},
|
||||||
Request::FromFontCache => {
|
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);
|
rw_data.outstanding_web_fonts.fetch_sub(1, Ordering::SeqCst);
|
||||||
font_context::invalidate_font_caches();
|
font_context::invalidate_font_caches();
|
||||||
self.script_chan.send(ConstellationControlMsg::WebFontLoaded(self.id)).unwrap();
|
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<MutexGuard<'a, LayoutTaskData>>)
|
|
||||||
-> 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<MutexGuard<'a, LayoutTaskData>>,
|
|
||||||
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
|
/// Repaint the scene, without performing style matching. This is typically
|
||||||
/// used when an image arrives asynchronously and triggers a relayout and
|
/// used when an image arrives asynchronously and triggers a relayout and
|
||||||
/// repaint.
|
/// repaint.
|
||||||
/// TODO: In the future we could detect if the image size hasn't changed
|
/// TODO: In the future we could detect if the image size hasn't changed
|
||||||
/// since last time and avoid performing a complete layout pass.
|
/// since last time and avoid performing a complete layout pass.
|
||||||
fn repaint<'a>(&'a self,
|
fn repaint<'a, 'b>(&self, possibly_locked_rw_data: &mut RwData<'a, 'b>) -> bool {
|
||||||
possibly_locked_rw_data: &mut Option<MutexGuard<'a, LayoutTaskData>>) -> bool {
|
let mut rw_data = possibly_locked_rw_data.lock();
|
||||||
let mut rw_data = self.lock_rw_data(possibly_locked_rw_data);
|
|
||||||
|
|
||||||
let reflow_info = Reflow {
|
let reflow_info = Reflow {
|
||||||
goal: ReflowGoal::ForDisplay,
|
goal: ReflowGoal::ForDisplay,
|
||||||
|
@ -584,11 +590,10 @@ impl LayoutTask {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Receives and dispatches messages from other tasks.
|
/// Receives and dispatches messages from other tasks.
|
||||||
fn handle_request_helper<'a>(&'a self,
|
fn handle_request_helper<'a, 'b>(&self,
|
||||||
request: Msg,
|
request: Msg,
|
||||||
possibly_locked_rw_data: &mut Option<MutexGuard<'a,
|
possibly_locked_rw_data: &mut RwData<'a, 'b>)
|
||||||
LayoutTaskData>>)
|
-> bool {
|
||||||
-> bool {
|
|
||||||
match request {
|
match request {
|
||||||
Msg::AddStylesheet(style_info) => {
|
Msg::AddStylesheet(style_info) => {
|
||||||
self.handle_add_stylesheet(style_info, possibly_locked_rw_data)
|
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);
|
self.collect_reports(reports_chan, possibly_locked_rw_data);
|
||||||
},
|
},
|
||||||
Msg::GetCurrentEpoch(sender) => {
|
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();
|
sender.send(rw_data.epoch).unwrap();
|
||||||
},
|
},
|
||||||
Msg::GetWebFontLoadState(sender) => {
|
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);
|
let outstanding_web_fonts = rw_data.outstanding_web_fonts.load(Ordering::SeqCst);
|
||||||
sender.send(outstanding_web_fonts != 0).unwrap();
|
sender.send(outstanding_web_fonts != 0).unwrap();
|
||||||
},
|
},
|
||||||
|
@ -645,13 +650,13 @@ impl LayoutTask {
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
fn collect_reports<'a>(&'a self,
|
fn collect_reports<'a, 'b>(&self,
|
||||||
reports_chan: ReportsChan,
|
reports_chan: ReportsChan,
|
||||||
possibly_locked_rw_data: &mut Option<MutexGuard<'a, LayoutTaskData>>) {
|
possibly_locked_rw_data: &mut RwData<'a, 'b>) {
|
||||||
let mut reports = vec![];
|
let mut reports = vec![];
|
||||||
|
|
||||||
// FIXME(njn): Just measuring the display tree for now.
|
// 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();
|
let stacking_context = rw_data.stacking_context.as_ref();
|
||||||
reports.push(Report {
|
reports.push(Report {
|
||||||
path: path![format!("url({})", self.url), "layout-task", "display-list"],
|
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
|
/// 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.
|
/// received. A pong is immediately sent on the given response channel.
|
||||||
fn prepare_to_exit<'a>(&'a self,
|
fn prepare_to_exit<'a, 'b>(&self,
|
||||||
response_chan: Sender<()>,
|
response_chan: Sender<()>,
|
||||||
possibly_locked_rw_data: &mut Option<MutexGuard<'a, LayoutTaskData>>) {
|
possibly_locked_rw_data: &mut RwData<'a, 'b>) {
|
||||||
response_chan.send(()).unwrap();
|
response_chan.send(()).unwrap();
|
||||||
loop {
|
loop {
|
||||||
match self.port.recv().unwrap() {
|
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)
|
/// Shuts down the layout task now. If there are any DOM nodes left, layout will now (safely)
|
||||||
/// crash.
|
/// crash.
|
||||||
fn exit_now<'a>(&'a self,
|
fn exit_now<'a, 'b>(&self, possibly_locked_rw_data: &mut RwData<'a, 'b>) {
|
||||||
possibly_locked_rw_data: &mut Option<MutexGuard<'a, LayoutTaskData>>) {
|
|
||||||
{
|
{
|
||||||
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 {
|
if let Some(ref mut traversal) = (&mut *rw_data).parallel_traversal {
|
||||||
traversal.shutdown()
|
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();
|
let (response_chan, response_port) = ipc::channel().unwrap();
|
||||||
|
@ -747,14 +751,13 @@ impl LayoutTask {
|
||||||
response_port.recv().unwrap()
|
response_port.recv().unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_add_stylesheet<'a>(&'a self,
|
fn handle_add_stylesheet<'a, 'b>(&self,
|
||||||
stylesheet: Arc<Stylesheet>,
|
stylesheet: Arc<Stylesheet>,
|
||||||
possibly_locked_rw_data:
|
possibly_locked_rw_data: &mut RwData<'a, 'b>) {
|
||||||
&mut Option<MutexGuard<'a, LayoutTaskData>>) {
|
|
||||||
// Find all font-face rules and notify the font cache of them.
|
// Find all font-face rules and notify the font cache of them.
|
||||||
// GWTODO: Need to handle unloading web fonts.
|
// 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) {
|
if stylesheet.is_effective_for_device(&rw_data.stylist.device) {
|
||||||
add_font_face_rules(&*stylesheet,
|
add_font_face_rules(&*stylesheet,
|
||||||
&rw_data.stylist.device,
|
&rw_data.stylist.device,
|
||||||
|
@ -763,16 +766,14 @@ impl LayoutTask {
|
||||||
&rw_data.outstanding_web_fonts);
|
&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.
|
/// Sets quirks mode for the document, causing the quirks mode stylesheet to be used.
|
||||||
fn handle_set_quirks_mode<'a>(&'a self,
|
fn handle_set_quirks_mode<'a, 'b>(&self, possibly_locked_rw_data: &mut RwData<'a, 'b>) {
|
||||||
possibly_locked_rw_data:
|
let mut rw_data = possibly_locked_rw_data.lock();
|
||||||
&mut Option<MutexGuard<'a, LayoutTaskData>>) {
|
|
||||||
let mut rw_data = self.lock_rw_data(possibly_locked_rw_data);
|
|
||||||
rw_data.stylist.set_quirks_mode(true);
|
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<FlowRef> {
|
fn try_get_layout_root(&self, node: LayoutNode) -> Option<FlowRef> {
|
||||||
|
@ -1084,10 +1085,9 @@ impl LayoutTask {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The high-level routine that performs layout tasks.
|
/// The high-level routine that performs layout tasks.
|
||||||
fn handle_reflow<'a>(&'a self,
|
fn handle_reflow<'a, 'b>(&self,
|
||||||
data: &ScriptReflow,
|
data: &ScriptReflow,
|
||||||
possibly_locked_rw_data: &mut Option<MutexGuard<'a, LayoutTaskData>>) {
|
possibly_locked_rw_data: &mut RwData<'a, 'b>) {
|
||||||
|
|
||||||
// Make sure that every return path from this method joins the script task,
|
// Make sure that every return path from this method joins the script task,
|
||||||
// otherwise the script task will panic.
|
// otherwise the script task will panic.
|
||||||
struct AutoJoinScriptTask<'a> { data: &'a ScriptReflow };
|
struct AutoJoinScriptTask<'a> { data: &'a ScriptReflow };
|
||||||
|
@ -1110,7 +1110,7 @@ impl LayoutTask {
|
||||||
node.dump();
|
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)
|
let stylesheets: Vec<&Stylesheet> = data.document_stylesheets.iter().map(|entry| &**entry)
|
||||||
.collect();
|
.collect();
|
||||||
let stylesheets_changed = data.stylesheets_changed;
|
let stylesheets_changed = data.stylesheets_changed;
|
||||||
|
@ -1232,11 +1232,11 @@ impl LayoutTask {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_visible_rects<'a>(&'a self,
|
fn set_visible_rects<'a, 'b>(&self,
|
||||||
new_visible_rects: Vec<(LayerId, Rect<Au>)>,
|
new_visible_rects: Vec<(LayerId, Rect<Au>)>,
|
||||||
possibly_locked_rw_data: &mut Option<MutexGuard<'a, LayoutTaskData>>)
|
possibly_locked_rw_data: &mut RwData<'a, 'b>)
|
||||||
-> bool {
|
-> bool {
|
||||||
let mut rw_data = self.lock_rw_data(possibly_locked_rw_data);
|
let mut rw_data = possibly_locked_rw_data.lock();
|
||||||
|
|
||||||
// First, determine if we need to regenerate the display lists. This will happen if the
|
// 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
|
// layers have moved more than `DISPLAY_PORT_THRESHOLD_SIZE_FACTOR` away from their last
|
||||||
|
@ -1289,10 +1289,8 @@ impl LayoutTask {
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
fn tick_all_animations<'a>(&'a self,
|
fn tick_all_animations<'a, 'b>(&self, possibly_locked_rw_data: &mut RwData<'a, 'b>) {
|
||||||
possibly_locked_rw_data: &mut Option<MutexGuard<'a,
|
let mut rw_data = possibly_locked_rw_data.lock();
|
||||||
LayoutTaskData>>) {
|
|
||||||
let mut rw_data = self.lock_rw_data(possibly_locked_rw_data);
|
|
||||||
animation::tick_all_animations(self, &mut rw_data)
|
animation::tick_all_animations(self, &mut rw_data)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1324,10 +1322,8 @@ impl LayoutTask {
|
||||||
&mut layout_context);
|
&mut layout_context);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn reflow_with_newly_loaded_web_font<'a>(
|
fn reflow_with_newly_loaded_web_font<'a, 'b>(&self, possibly_locked_rw_data: &mut RwData<'a, 'b>) {
|
||||||
&'a self,
|
let mut rw_data = possibly_locked_rw_data.lock();
|
||||||
possibly_locked_rw_data: &mut Option<MutexGuard<'a, LayoutTaskData>>) {
|
|
||||||
let mut rw_data = self.lock_rw_data(possibly_locked_rw_data);
|
|
||||||
font_context::invalidate_font_caches();
|
font_context::invalidate_font_caches();
|
||||||
|
|
||||||
let reflow_info = Reflow {
|
let reflow_info = Reflow {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue