De-@mut pipeline

This commit is contained in:
Lars Bergstrom 2014-02-11 14:30:30 -06:00
parent 20bbf6a859
commit 683c2fada1
4 changed files with 104 additions and 153 deletions

View file

@ -25,6 +25,7 @@ use servo_util::time::ProfilerChan;
use servo_util::url::parse_url; use servo_util::url::parse_url;
use servo_util::task::spawn_named; use servo_util::task::spawn_named;
use std::hashmap::{HashMap, HashSet}; use std::hashmap::{HashMap, HashSet};
use std::rc::Rc;
use std::util::replace; use std::util::replace;
use std::io; use std::io;
use std::libc; use std::libc;
@ -36,7 +37,7 @@ pub struct Constellation {
compositor_chan: CompositorChan, compositor_chan: CompositorChan,
resource_task: ResourceTask, resource_task: ResourceTask,
image_cache_task: ImageCacheTask, image_cache_task: ImageCacheTask,
pipelines: HashMap<PipelineId, @mut Pipeline>, pipelines: HashMap<PipelineId, Rc<Pipeline>>,
navigation_context: NavigationContext, navigation_context: NavigationContext,
priv next_pipeline_id: PipelineId, priv next_pipeline_id: PipelineId,
pending_frames: ~[FrameChange], pending_frames: ~[FrameChange],
@ -48,8 +49,8 @@ pub struct Constellation {
/// Stores the Id of the outermost frame's pipeline, along with a vector of children frames /// Stores the Id of the outermost frame's pipeline, along with a vector of children frames
struct FrameTree { struct FrameTree {
pipeline: @mut Pipeline, pipeline: Rc<Pipeline>,
parent: Option<@mut Pipeline>, parent: Option<Rc<Pipeline>>,
children: ~[ChildFrameTree], children: ~[ChildFrameTree],
} }
@ -60,7 +61,7 @@ impl Clone for FrameTree {
child_frame_tree.clone() child_frame_tree.clone()
}); });
FrameTree { FrameTree {
pipeline: self.pipeline, pipeline: self.pipeline.clone(),
parent: self.parent.clone(), parent: self.parent.clone(),
children: children.collect(), children: children.collect(),
} }
@ -110,14 +111,14 @@ enum ReplaceResult {
impl FrameTree { impl FrameTree {
fn contains(@mut self, id: PipelineId) -> bool { fn contains(@mut self, id: PipelineId) -> bool {
self.iter().any(|frame_tree| { self.iter().any(|frame_tree| {
id == frame_tree.pipeline.id id == frame_tree.pipeline.borrow().id
}) })
} }
/// Returns the frame tree whose key is id /// Returns the frame tree whose key is id
fn find(@mut self, id: PipelineId) -> Option<@mut FrameTree> { fn find(@mut self, id: PipelineId) -> Option<@mut FrameTree> {
self.iter().find(|frame_tree| { self.iter().find(|frame_tree| {
id == frame_tree.pipeline.id id == frame_tree.pipeline.borrow().id
}) })
} }
@ -126,9 +127,9 @@ impl FrameTree {
fn replace_child(@mut self, id: PipelineId, new_child: @mut FrameTree) -> ReplaceResult { fn replace_child(@mut self, id: PipelineId, new_child: @mut FrameTree) -> ReplaceResult {
for frame_tree in self.iter() { for frame_tree in self.iter() {
let mut child = frame_tree.children.mut_iter() let mut child = frame_tree.children.mut_iter()
.find(|child| child.frame_tree.pipeline.id == id); .find(|child| child.frame_tree.pipeline.borrow().id == id);
for child in child.mut_iter() { for child in child.mut_iter() {
new_child.parent = child.frame_tree.parent; new_child.parent = child.frame_tree.parent.clone();
return ReplacedNode(replace(&mut child.frame_tree, new_child)); return ReplacedNode(replace(&mut child.frame_tree, new_child));
} }
} }
@ -137,7 +138,7 @@ impl FrameTree {
fn to_sendable(&self) -> SendableFrameTree { fn to_sendable(&self) -> SendableFrameTree {
let sendable_frame_tree = SendableFrameTree { let sendable_frame_tree = SendableFrameTree {
pipeline: self.pipeline.to_sendable(), pipeline: self.pipeline.borrow().to_sendable(),
children: self.children.iter().map(|frame_tree| frame_tree.to_sendable()).collect(), children: self.children.iter().map(|frame_tree| frame_tree.to_sendable()).collect(),
}; };
sendable_frame_tree sendable_frame_tree
@ -220,7 +221,7 @@ impl NavigationContext {
/// Loads a new set of page frames, returning all evicted frame trees /// Loads a new set of page frames, returning all evicted frame trees
pub fn load(&mut self, frame_tree: @mut FrameTree) -> ~[@mut FrameTree] { pub fn load(&mut self, frame_tree: @mut FrameTree) -> ~[@mut FrameTree] {
debug!("navigating to {:?}", frame_tree.pipeline.id); debug!("navigating to {:?}", frame_tree.pipeline.borrow().id);
let evicted = replace(&mut self.next, ~[]); let evicted = replace(&mut self.next, ~[]);
if self.current.is_some() { if self.current.is_some() {
self.previous.push(self.current.take_unwrap()); self.previous.push(self.current.take_unwrap());
@ -376,7 +377,7 @@ impl Constellation {
fn handle_exit(&self) { fn handle_exit(&self) {
for (_id, ref pipeline) in self.pipelines.iter() { for (_id, ref pipeline) in self.pipelines.iter() {
pipeline.exit(); pipeline.borrow().exit();
} }
self.image_cache_task.exit(); self.image_cache_task.exit();
self.resource_task.send(resource_task::Exit); self.resource_task.send(resource_task::Exit);
@ -406,53 +407,55 @@ impl Constellation {
self.pipelines.remove(&pipeline_id); self.pipelines.remove(&pipeline_id);
let new_id = self.get_next_pipeline_id(); let new_id = self.get_next_pipeline_id();
let pipeline = @mut Pipeline::create(new_id, let pipeline = Pipeline::create(new_id,
subpage_id, subpage_id,
self.chan.clone(), self.chan.clone(),
self.compositor_chan.clone(), self.compositor_chan.clone(),
self.image_cache_task.clone(), self.image_cache_task.clone(),
self.resource_task.clone(), self.resource_task.clone(),
self.profiler_chan.clone(), self.profiler_chan.clone(),
self.window_size, self.window_size,
self.opts.clone()); self.opts.clone());
self.pipelines.insert(new_id, pipeline);
let url = parse_url("about:failure", None); let url = parse_url("about:failure", None);
pipeline.load(url); pipeline.load(url);
let pipeline_wrapped = Rc::from_send(pipeline);
self.pending_frames.push(FrameChange{ self.pending_frames.push(FrameChange{
before: Some(pipeline_id), before: Some(pipeline_id),
after: @mut FrameTree { after: Rc::from_send(FrameTree {
pipeline: pipeline, pipeline: pipeline_wrapped.clone(),
parent: None, parent: None,
children: ~[], children: ~[],
}, }),
navigation_type: constellation_msg::Navigate, navigation_type: constellation_msg::Navigate,
}); });
self.pipelines.insert(pipeline_id, pipeline_wrapped);
} }
fn handle_init_load(&mut self, url: Url) { fn handle_init_load(&mut self, url: Url) {
let pipeline = @mut Pipeline::create(self.get_next_pipeline_id(), let pipeline = Pipeline::create(self.get_next_pipeline_id(),
None, None,
self.chan.clone(), self.chan.clone(),
self.compositor_chan.clone(), self.compositor_chan.clone(),
self.image_cache_task.clone(), self.image_cache_task.clone(),
self.resource_task.clone(), self.resource_task.clone(),
self.profiler_chan.clone(), self.profiler_chan.clone(),
self.window_size, self.window_size,
self.opts.clone()); self.opts.clone());
pipeline.load(url); pipeline.load(url);
let pipeline_wrapped = Rc::from_send(pipeline);
self.pending_frames.push(FrameChange { self.pending_frames.push(FrameChange {
before: None, before: None,
after: @mut FrameTree { after: @mut FrameTree {
pipeline: pipeline, pipeline: pipeline_wrapped.clone(),
parent: None, parent: None,
children: ~[], children: ~[],
}, },
navigation_type: constellation_msg::Load, navigation_type: constellation_msg::Load,
}); });
self.pipelines.insert(pipeline.id, pipeline); self.pipelines.insert(pipeline_wrapped.borrow().id, pipeline_wrapped);
} }
fn handle_frame_rect_msg(&mut self, pipeline_id: PipelineId, subpage_id: SubpageId, rect: Rect<f32>) { fn handle_frame_rect_msg(&mut self, pipeline_id: PipelineId, subpage_id: SubpageId, rect: Rect<f32>) {
@ -461,7 +464,7 @@ impl Constellation {
// Returns true if a child frame tree's subpage id matches the given subpage id // Returns true if a child frame tree's subpage id matches the given subpage id
let subpage_eq = |child_frame_tree: & &mut ChildFrameTree| { let subpage_eq = |child_frame_tree: & &mut ChildFrameTree| {
child_frame_tree.frame_tree.pipeline.subpage_id.expect("Constellation: child_frame_tree.frame_tree.pipeline.borrow().subpage_id.expect("Constellation:
child frame does not have a subpage id. This should not be possible.") child frame does not have a subpage id. This should not be possible.")
== subpage_id == subpage_id
}; };
@ -472,18 +475,21 @@ impl Constellation {
let update_child_rect = |child_frame_tree: &mut ChildFrameTree, is_active: bool| { let update_child_rect = |child_frame_tree: &mut ChildFrameTree, is_active: bool| {
child_frame_tree.rect = Some(rect.clone()); child_frame_tree.rect = Some(rect.clone());
let pipeline = &child_frame_tree.frame_tree.pipeline; let pipeline = &child_frame_tree.frame_tree.pipeline;
if !already_sent.contains(&pipeline.id) { if !already_sent.contains(&pipeline.borrow().id) {
let Size2D { width, height } = rect.size; let Size2D { width, height } = rect.size;
if is_active { if is_active {
let pipeline = pipeline.borrow();
pipeline.script_chan.send(ResizeMsg(pipeline.id, Size2D { pipeline.script_chan.send(ResizeMsg(pipeline.id, Size2D {
width: width as uint, width: width as uint,
height: height as uint height: height as uint
})); }));
self.compositor_chan.send(SetLayerClipRect(pipeline.id, rect)); self.compositor_chan.send(SetLayerClipRect(pipeline.id, rect));
} else { } else {
let pipeline = pipeline.borrow();
pipeline.script_chan.send(ResizeInactiveMsg(pipeline.id, pipeline.script_chan.send(ResizeInactiveMsg(pipeline.id,
Size2D(width as uint, height as uint))); Size2D(width as uint, height as uint)));
} }
let pipeline = pipeline.borrow();
already_sent.insert(pipeline.id); already_sent.insert(pipeline.id);
} }
}; };
@ -544,18 +550,18 @@ impl Constellation {
// Compare the pipeline's url to the new url. If the origin is the same, // Compare the pipeline's url to the new url. If the origin is the same,
// then reuse the script task in creating the new pipeline // then reuse the script task in creating the new pipeline
let source_pipeline = *self.pipelines.find(&source_pipeline_id).expect("Constellation: let source_pipeline = self.pipelines.find(&source_pipeline_id).expect("Constellation:
source Id of LoadIframeUrlMsg does have an associated pipeline in source Id of LoadIframeUrlMsg does have an associated pipeline in
constellation. This should be impossible."); constellation. This should be impossible.").clone();
let source_url = source_pipeline.url.clone().expect("Constellation: LoadUrlIframeMsg's let source_url = source_pipeline.borrow().url.get().clone().expect("Constellation: LoadUrlIframeMsg's
source's Url is None. There should never be a LoadUrlIframeMsg from a pipeline source's Url is None. There should never be a LoadUrlIframeMsg from a pipeline
that was never given a url to load."); that was never given a url to load.");
let same_script = (source_url.host == url.host && let same_script = (source_url.host == url.host &&
source_url.port == url.port) && sandbox == IFrameUnsandboxed; source_url.port == url.port) && sandbox == IFrameUnsandboxed;
// FIXME(tkuehn): Need to follow the standardized spec for checking same-origin // FIXME(tkuehn): Need to follow the standardized spec for checking same-origin
let pipeline = @mut if same_script { let pipeline = if same_script {
debug!("Constellation: loading same-origin iframe at {:?}", url); debug!("Constellation: loading same-origin iframe at {:?}", url);
// Reuse the script task if same-origin url's // Reuse the script task if same-origin url's
Pipeline::with_script(next_pipeline_id, Pipeline::with_script(next_pipeline_id,
@ -565,7 +571,7 @@ impl Constellation {
self.image_cache_task.clone(), self.image_cache_task.clone(),
self.profiler_chan.clone(), self.profiler_chan.clone(),
self.opts.clone(), self.opts.clone(),
source_pipeline) source_pipeline.clone())
} else { } else {
debug!("Constellation: loading cross-origin iframe at {:?}", url); debug!("Constellation: loading cross-origin iframe at {:?}", url);
// Create a new script task if not same-origin url's // Create a new script task if not same-origin url's
@ -582,18 +588,19 @@ impl Constellation {
debug!("Constellation: sending load msg to pipeline {:?}", pipeline.id); debug!("Constellation: sending load msg to pipeline {:?}", pipeline.id);
pipeline.load(url); pipeline.load(url);
let pipeline_wrapped = Rc::from_send(pipeline);
let rect = self.pending_sizes.pop(&(source_pipeline_id, subpage_id)); let rect = self.pending_sizes.pop(&(source_pipeline_id, subpage_id));
for frame_tree in frame_trees.iter() { for frame_tree in frame_trees.iter() {
frame_tree.children.push(ChildFrameTree { frame_tree.children.push(ChildFrameTree {
frame_tree: @mut FrameTree { frame_tree: @mut FrameTree {
pipeline: pipeline, pipeline: pipeline_wrapped.clone(),
parent: Some(source_pipeline), parent: Some(source_pipeline.clone()),
children: ~[], children: ~[],
}, },
rect: rect, rect: rect,
}); });
} }
self.pipelines.insert(pipeline.id, pipeline); self.pipelines.insert(pipeline_wrapped.borrow().id, pipeline_wrapped);
} }
fn handle_load_url_msg(&mut self, source_id: PipelineId, url: Url) { fn handle_load_url_msg(&mut self, source_id: PipelineId, url: Url) {
@ -620,31 +627,32 @@ impl Constellation {
// changes would be overriden by changing the subframe associated with source_id. // changes would be overriden by changing the subframe associated with source_id.
let parent = source_frame.parent.clone(); let parent = source_frame.parent.clone();
let subpage_id = source_frame.pipeline.subpage_id; let subpage_id = source_frame.pipeline.borrow().subpage_id;
let next_pipeline_id = self.get_next_pipeline_id(); let next_pipeline_id = self.get_next_pipeline_id();
let pipeline = @mut Pipeline::create(next_pipeline_id, let pipeline = Pipeline::create(next_pipeline_id,
subpage_id, subpage_id,
self.chan.clone(), self.chan.clone(),
self.compositor_chan.clone(), self.compositor_chan.clone(),
self.image_cache_task.clone(), self.image_cache_task.clone(),
self.resource_task.clone(), self.resource_task.clone(),
self.profiler_chan.clone(), self.profiler_chan.clone(),
self.window_size, self.window_size,
self.opts.clone()); self.opts.clone());
pipeline.load(url); pipeline.load(url);
let pipeline_wrapped = Rc::from_send(pipeline);
self.pending_frames.push(FrameChange{ self.pending_frames.push(FrameChange{
before: Some(source_id), before: Some(source_id),
after: @mut FrameTree { after: @mut FrameTree {
pipeline: pipeline, pipeline: pipeline_wrapped.clone(),
parent: parent, parent: parent,
children: ~[], children: ~[],
}, },
navigation_type: constellation_msg::Load, navigation_type: constellation_msg::Load,
}); });
self.pipelines.insert(pipeline.id, pipeline); self.pipelines.insert(pipeline_wrapped.borrow().id, pipeline_wrapped);
} }
fn handle_navigate_msg(&mut self, direction: constellation_msg::NavigationDirection) { fn handle_navigate_msg(&mut self, direction: constellation_msg::NavigationDirection) {
@ -662,7 +670,7 @@ impl Constellation {
} else { } else {
let old = self.current_frame().get_ref(); let old = self.current_frame().get_ref();
for frame in old.iter() { for frame in old.iter() {
frame.pipeline.revoke_paint_permission(); frame.pipeline.borrow().revoke_paint_permission();
} }
} }
self.navigation_context.forward() self.navigation_context.forward()
@ -674,7 +682,7 @@ impl Constellation {
} else { } else {
let old = self.current_frame().get_ref(); let old = self.current_frame().get_ref();
for frame in old.iter() { for frame in old.iter() {
frame.pipeline.revoke_paint_permission(); frame.pipeline.borrow().revoke_paint_permission();
} }
} }
self.navigation_context.back() self.navigation_context.back()
@ -683,7 +691,7 @@ impl Constellation {
for frame in destination_frame.iter() { for frame in destination_frame.iter() {
let pipeline = &frame.pipeline; let pipeline = &frame.pipeline;
pipeline.reload(); pipeline.borrow().reload();
} }
self.grant_paint_permission(destination_frame, constellation_msg::Navigate); self.grant_paint_permission(destination_frame, constellation_msg::Navigate);
@ -701,7 +709,7 @@ impl Constellation {
// impossible to occur. // impossible to occur.
if current_frame.contains(pipeline_id) { if current_frame.contains(pipeline_id) {
for frame in current_frame.iter() { for frame in current_frame.iter() {
frame.pipeline.grant_paint_permission(); frame.pipeline.borrow().grant_paint_permission();
} }
return; return;
} }
@ -711,14 +719,14 @@ impl Constellation {
// If it is not found, it simply means that this pipeline will not receive // If it is not found, it simply means that this pipeline will not receive
// permission to paint. // permission to paint.
let pending_index = self.pending_frames.iter().rposition(|frame_change| { let pending_index = self.pending_frames.iter().rposition(|frame_change| {
frame_change.after.pipeline.id == pipeline_id frame_change.after.pipeline.borrow().id == pipeline_id
}); });
for &pending_index in pending_index.iter() { for &pending_index in pending_index.iter() {
let frame_change = self.pending_frames.swap_remove(pending_index); let frame_change = self.pending_frames.swap_remove(pending_index);
let to_add = frame_change.after; let to_add = frame_change.after;
// Create the next frame tree that will be given to the compositor // Create the next frame tree that will be given to the compositor
let next_frame_tree = match to_add.parent { let next_frame_tree = match to_add.parent.clone() {
None => to_add, // to_add is the root None => to_add, // to_add is the root
Some(_parent) => @mut (*self.current_frame().unwrap()).clone(), Some(_parent) => @mut (*self.current_frame().unwrap()).clone(),
}; };
@ -734,14 +742,14 @@ impl Constellation {
frame not contained in the current frame. This is a bug"); frame not contained in the current frame. This is a bug");
for frame in to_revoke.iter() { for frame in to_revoke.iter() {
frame.pipeline.revoke_paint_permission(); frame.pipeline.borrow().revoke_paint_permission();
} }
// If to_add is not the root frame, then replace revoked_frame with it. // If to_add is not the root frame, then replace revoked_frame with it.
// This conveniently keeps scissor rect size intact. // This conveniently keeps scissor rect size intact.
if to_add.parent.is_some() { if to_add.parent.is_some() {
debug!("Constellation: replacing {:?} with {:?} in {:?}", debug!("Constellation: replacing {:?} with {:?} in {:?}",
revoke_id, to_add.pipeline.id, next_frame_tree.pipeline.id); revoke_id, to_add.pipeline.borrow().id, next_frame_tree.pipeline.borrow().id);
next_frame_tree.replace_child(revoke_id, to_add); next_frame_tree.replace_child(revoke_id, to_add);
} }
} }
@ -750,10 +758,10 @@ impl Constellation {
// Add to_add to parent's children, if it is not the root // Add to_add to parent's children, if it is not the root
let parent = &to_add.parent; let parent = &to_add.parent;
for parent in parent.iter() { for parent in parent.iter() {
let subpage_id = to_add.pipeline.subpage_id.expect("Constellation: let subpage_id = to_add.pipeline.borrow().subpage_id.expect("Constellation:
Child frame's subpage id is None. This should be impossible."); Child frame's subpage id is None. This should be impossible.");
let rect = self.pending_sizes.pop(&(parent.id, subpage_id)); let rect = self.pending_sizes.pop(&(parent.borrow().id, subpage_id));
let parent = next_frame_tree.find(parent.id).expect( let parent = next_frame_tree.find(parent.borrow().id).expect(
"Constellation: pending frame has a parent frame that is not "Constellation: pending frame has a parent frame that is not
active. This is a bug."); active. This is a bug.");
parent.children.push(ChildFrameTree { parent.children.push(ChildFrameTree {
@ -771,16 +779,18 @@ impl Constellation {
/// Called when the window is resized. /// Called when the window is resized.
fn handle_resized_window_msg(&mut self, new_size: Size2D<uint>) { fn handle_resized_window_msg(&mut self, new_size: Size2D<uint>) {
let mut already_seen = HashSet::new(); let mut already_seen = HashSet::new();
for &@FrameTree { pipeline: pipeline, .. } in self.current_frame().iter() { for frame_tree in self.current_frame().iter() {
debug!("constellation sending resize message to active frame"); debug!("constellation sending resize message to active frame");
let pipeline = frame_tree.pipeline.borrow();
pipeline.script_chan.try_send(ResizeMsg(pipeline.id, new_size)); pipeline.script_chan.try_send(ResizeMsg(pipeline.id, new_size));
already_seen.insert(pipeline.id); already_seen.insert(pipeline.id);
} }
for frame_tree in self.navigation_context.previous.iter() for frame_tree in self.navigation_context.previous.iter()
.chain(self.navigation_context.next.iter()) { .chain(self.navigation_context.next.iter()) {
let pipeline = &frame_tree.pipeline; let pipeline = &frame_tree.pipeline;
if !already_seen.contains(&pipeline.id) { if !already_seen.contains(&pipeline.borrow().id) {
debug!("constellation sending resize message to inactive frame"); debug!("constellation sending resize message to inactive frame");
let pipeline = pipeline.borrow();
pipeline.script_chan.try_send(ResizeInactiveMsg(pipeline.id, new_size)); pipeline.script_chan.try_send(ResizeInactiveMsg(pipeline.id, new_size));
already_seen.insert(pipeline.id); already_seen.insert(pipeline.id);
} }
@ -792,7 +802,8 @@ impl Constellation {
let frame_tree = change.after; let frame_tree = change.after;
if frame_tree.parent.is_none() { if frame_tree.parent.is_none() {
debug!("constellation sending resize message to pending outer frame"); debug!("constellation sending resize message to pending outer frame");
frame_tree.pipeline.script_chan.send(ResizeMsg(frame_tree.pipeline.id, new_size)) let pipeline = frame_tree.pipeline.borrow();
pipeline.script_chan.send(ResizeMsg(pipeline.id, new_size))
} }
} }
@ -803,7 +814,8 @@ impl Constellation {
fn close_pipelines(&mut self, frame_tree: @mut FrameTree) { fn close_pipelines(&mut self, frame_tree: @mut FrameTree) {
// TODO(tkuehn): should only exit once per unique script task, // TODO(tkuehn): should only exit once per unique script task,
// and then that script task will handle sub-exits // and then that script task will handle sub-exits
for @FrameTree { pipeline, .. } in frame_tree.iter() { for frame_tree in frame_tree.iter() {
let pipeline = frame_tree.pipeline.borrow();
pipeline.exit(); pipeline.exit();
self.pipelines.remove(&pipeline.id); self.pipelines.remove(&pipeline.id);
} }
@ -811,7 +823,7 @@ impl Constellation {
fn handle_evicted_frames(&mut self, evicted: ~[@mut FrameTree]) { fn handle_evicted_frames(&mut self, evicted: ~[@mut FrameTree]) {
for &frame_tree in evicted.iter() { for &frame_tree in evicted.iter() {
if !self.navigation_context.contains(frame_tree.pipeline.id) { if !self.navigation_context.contains(frame_tree.pipeline.borrow().id) {
self.close_pipelines(frame_tree); self.close_pipelines(frame_tree);
} else { } else {
self.handle_evicted_frames(frame_tree.children.iter() self.handle_evicted_frames(frame_tree.children.iter()
@ -844,7 +856,7 @@ impl Constellation {
match port.recv_opt() { match port.recv_opt() {
Some(()) => { Some(()) => {
for frame in frame_tree.iter() { for frame in frame_tree.iter() {
frame.pipeline.grant_paint_permission(); frame.pipeline.borrow().grant_paint_permission();
} }
} }
None => {} // message has been discarded, probably shutting down None => {} // message has been discarded, probably shutting down

View file

@ -19,6 +19,8 @@ use servo_msg::constellation_msg::{ConstellationChan, Failure, PipelineId, Subpa
use servo_net::image_cache_task::ImageCacheTask; use servo_net::image_cache_task::ImageCacheTask;
use servo_net::resource_task::ResourceTask; use servo_net::resource_task::ResourceTask;
use servo_util::time::ProfilerChan; use servo_util::time::ProfilerChan;
use std::cell::RefCell;
use std::rc::Rc;
/// A uniquely-identifiable pipeline of script task, layout task, and render task. /// A uniquely-identifiable pipeline of script task, layout task, and render task.
pub struct Pipeline { pub struct Pipeline {
@ -30,7 +32,7 @@ pub struct Pipeline {
layout_shutdown_port: Port<()>, layout_shutdown_port: Port<()>,
render_shutdown_port: Port<()>, render_shutdown_port: Port<()>,
/// The most recently loaded url /// The most recently loaded url
url: Option<Url>, url: RefCell<Option<Url>>,
} }
/// The subset of the pipeline that is needed for layer composition. /// The subset of the pipeline that is needed for layer composition.
@ -51,7 +53,7 @@ impl Pipeline {
image_cache_task: ImageCacheTask, image_cache_task: ImageCacheTask,
profiler_chan: ProfilerChan, profiler_chan: ProfilerChan,
opts: Opts, opts: Opts,
script_pipeline: &Pipeline) script_pipeline: Rc<Pipeline>)
-> Pipeline { -> Pipeline {
let (layout_port, layout_chan) = LayoutChan::new(); let (layout_port, layout_chan) = LayoutChan::new();
let (render_port, render_chan) = RenderChan::new(); let (render_port, render_chan) = RenderChan::new();
@ -77,7 +79,7 @@ impl Pipeline {
layout_chan.clone(), layout_chan.clone(),
constellation_chan, constellation_chan,
failure, failure,
script_pipeline.script_chan.clone(), script_pipeline.borrow().script_chan.clone(),
render_chan.clone(), render_chan.clone(),
image_cache_task.clone(), image_cache_task.clone(),
opts.clone(), opts.clone(),
@ -85,16 +87,16 @@ impl Pipeline {
layout_shutdown_chan); layout_shutdown_chan);
let new_layout_info = NewLayoutInfo { let new_layout_info = NewLayoutInfo {
old_id: script_pipeline.id.clone(), old_id: script_pipeline.borrow().id.clone(),
new_id: id, new_id: id,
layout_chan: layout_chan.clone(), layout_chan: layout_chan.clone(),
}; };
script_pipeline.script_chan.send(AttachLayoutMsg(new_layout_info)); script_pipeline.borrow().script_chan.send(AttachLayoutMsg(new_layout_info));
Pipeline::new(id, Pipeline::new(id,
subpage_id, subpage_id,
script_pipeline.script_chan.clone(), script_pipeline.borrow().script_chan.clone(),
layout_chan, layout_chan,
render_chan, render_chan,
layout_shutdown_port, layout_shutdown_port,
@ -180,12 +182,12 @@ impl Pipeline {
render_chan: render_chan, render_chan: render_chan,
layout_shutdown_port: layout_shutdown_port, layout_shutdown_port: layout_shutdown_port,
render_shutdown_port: render_shutdown_port, render_shutdown_port: render_shutdown_port,
url: None, url: RefCell::new(None),
} }
} }
pub fn load(&mut self, url: Url) { pub fn load(&self, url: Url) {
self.url = Some(url.clone()); self.url.set(Some(url.clone()));
self.script_chan.send(LoadMsg(self.id, url)); self.script_chan.send(LoadMsg(self.id, url));
} }
@ -198,8 +200,8 @@ impl Pipeline {
self.render_chan.try_send(PaintPermissionRevoked); self.render_chan.try_send(PaintPermissionRevoked);
} }
pub fn reload(&mut self) { pub fn reload(&self) {
self.url.clone().map(|url| { self.url.get().clone().map(|url| {
self.load(url); self.load(url);
}); });
} }

View file

@ -1,59 +0,0 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
//! A windowing implementation using shared OpenGL textures.
///
/// In this setup, Servo renders to an OpenGL texture and uses IPC to share that texture with
/// another application. It also uses IPC to handle events.
///
/// This is designed for sandboxing scenarios which the OpenGL graphics driver is either sandboxed
/// along with the Servo process or trusted. If the OpenGL driver itself is untrusted, then this
/// windowing implementation is not appropriate.
use windowing::{CompositeCallback, LoadUrlCallback, ResizeCallback};
use geom::size::Size2D;
use sharegl::base::ShareContext;
use sharegl::platform::Context;
/// A structure responsible for setting up and tearing down the entire windowing system.
pub struct Application;
impl ApplicationMethods for Application {
pub fn new() -> Application {
Application
}
}
/// The type of a window.
pub struct Window(Context);
impl WindowingMethods<Application> for Window {
/// Creates a new window.
pub fn new(_: &Application) -> @mut Window {
let share_context: Context = ShareContext::new(Size2D(800, 600));
println(format!("Sharing ID is {:d}", share_context.id()));
@mut Window(share_context)
}
/// Returns the size of the window.
pub fn size(&mut self) -> Size2D<f32> {
Size2D(800.0, 600.0)
}
/// Presents the window to the screen (perhaps by page flipping).
pub fn present(&mut self) {
(*self).flush();
}
/// Registers a callback to run when a resize event occurs.
pub fn set_resize_callback(&mut self, _: ResizeCallback) {}
/// Registers a callback to run when a new URL is to be loaded.
pub fn set_load_url_callback(&mut self, _: LoadUrlCallback) {}
/// Returns the next event.
pub fn check_loop(@mut self) -> bool { false }
}

View file

@ -4,19 +4,15 @@
//! Platform-specific functionality for Servo. //! Platform-specific functionality for Servo.
#[cfg(not(shared_gl_windowing), target_os="android")] #[cfg(target_os="android")]
pub use platform::common::glut_windowing::{Application, Window}; pub use platform::common::glut_windowing::{Application, Window};
#[cfg(not(shared_gl_windowing), not(target_os="android"))] #[cfg(not(target_os="android"))]
pub use platform::common::glfw_windowing::{Application, Window}; pub use platform::common::glfw_windowing::{Application, Window};
#[cfg(shared_gl_windowing)]
pub use platform::common::shared_gl_windowing::{Application, Window};
pub mod common { pub mod common {
#[cfg(not(shared_gl_windowing), target_os="android")] #[cfg(target_os="android")]
pub mod glut_windowing; pub mod glut_windowing;
#[cfg(not(shared_gl_windowing), not(target_os="android"))] #[cfg(not(target_os="android"))]
pub mod glfw_windowing; pub mod glfw_windowing;
#[cfg(shared_gl_windowing)]
pub mod shared_gl_windowing;
} }