aboutsummaryrefslogtreecommitdiffstats
path: root/components
diff options
context:
space:
mode:
authorMartin Robinson <mrobinson@igalia.com>2015-01-06 10:18:32 -0800
committerMartin Robinson <mrobinson@igalia.com>2015-01-08 12:11:21 -0800
commitd93b80608f677c62add3efaa1c32b6fd429a0803 (patch)
tree2dfe8ccd904dd7bb04a07e05b1ebcf8eaed31885 /components
parent1458709247586fcb3c14cd9132b735ff3080bf07 (diff)
downloadservo-d93b80608f677c62add3efaa1c32b6fd429a0803.tar.gz
servo-d93b80608f677c62add3efaa1c32b6fd429a0803.zip
Combine all pipeline status trackers into a single struct
This will make it easier to organize and clean up this information during pipeline shutdown.
Diffstat (limited to 'components')
-rw-r--r--components/compositing/compositor.rs114
1 files changed, 64 insertions, 50 deletions
diff --git a/components/compositing/compositor.rs b/components/compositing/compositor.rs
index f9cd4f1007e..9c5d9c9c790 100644
--- a/components/compositing/compositor.rs
+++ b/components/compositing/compositor.rs
@@ -64,6 +64,9 @@ pub struct IOCompositor<Window: WindowMethods> {
/// The root pipeline.
root_pipeline: Option<CompositionPipeline>,
+ /// Tracks details about each active pipeline that the compositor knows about.
+ pipeline_details: HashMap<PipelineId, PipelineDetails>,
+
/// The canvas to paint a page.
scene: Scene<CompositorData>,
@@ -102,12 +105,6 @@ pub struct IOCompositor<Window: WindowMethods> {
/// The time of the last zoom action has started.
zoom_time: f64,
- /// Current display/reflow status of each pipeline.
- ready_states: HashMap<PipelineId, ReadyState>,
-
- /// Current paint status of each pipeline.
- paint_states: HashMap<PipelineId, PaintState>,
-
/// Whether the page being rendered has loaded completely.
/// Differs from ReadyState because we can finish loading (ready)
/// many times for a single page.
@@ -130,9 +127,6 @@ pub struct IOCompositor<Window: WindowMethods> {
/// Pending scroll events.
pending_scroll_events: Vec<ScrollEvent>,
-
- /// PaintTask channels that we know about, used to return unused buffers.
- paint_channels: HashMap<PipelineId, PaintChan>,
}
pub struct ScrollEvent {
@@ -159,6 +153,27 @@ struct HitTestResult {
point: TypedPoint2D<LayerPixel, f32>,
}
+struct PipelineDetails {
+ /// The status of this pipeline's ScriptTask.
+ ready_state: ReadyState,
+
+ /// The status of this pipeline's PaintTask.
+ paint_state: PaintState,
+
+ /// The channel to this pipeline's PaintTask,
+ paint_task_channel: Option<PaintChan>,
+}
+
+impl PipelineDetails {
+ fn new() -> PipelineDetails {
+ PipelineDetails {
+ ready_state: ReadyState::Blank,
+ paint_state: PaintState::Painting,
+ paint_task_channel: None,
+ }
+ }
+}
+
impl<Window: WindowMethods> IOCompositor<Window> {
fn new(window: Rc<Window>,
sender: Box<CompositorProxy+Send>,
@@ -178,6 +193,7 @@ impl<Window: WindowMethods> IOCompositor<Window> {
port: receiver,
context: None,
root_pipeline: None,
+ pipeline_details: HashMap::new(),
scene: Scene::new(Rect {
origin: Point2D::zero(),
size: window_size.as_f32(),
@@ -192,8 +208,6 @@ impl<Window: WindowMethods> IOCompositor<Window> {
viewport_zoom: ScaleFactor(1.0),
zoom_action: false,
zoom_time: 0f64,
- ready_states: HashMap::new(),
- paint_states: HashMap::new(),
got_load_complete_message: false,
got_set_frame_tree_message: false,
constellation_chan: constellation_chan,
@@ -202,7 +216,6 @@ impl<Window: WindowMethods> IOCompositor<Window> {
fragment_point: None,
outstanding_paint_msgs: 0,
last_composite_time: 0,
- paint_channels: HashMap::new(),
}
}
@@ -347,7 +360,7 @@ impl<Window: WindowMethods> IOCompositor<Window> {
}
(Msg::PaintTaskExited(pipeline_id), ShutdownState::NotShuttingDown) => {
- if self.paint_channels.remove(&pipeline_id).is_none() {
+ if self.pipeline_details.remove(&pipeline_id).is_none() {
panic!("Saw PaintTaskExited message from an unknown pipeline!");
}
}
@@ -362,14 +375,7 @@ impl<Window: WindowMethods> IOCompositor<Window> {
}
fn change_ready_state(&mut self, pipeline_id: PipelineId, ready_state: ReadyState) {
- match self.ready_states.entry(pipeline_id) {
- Occupied(entry) => {
- *entry.into_mut() = ready_state;
- }
- Vacant(entry) => {
- entry.set(ready_state);
- }
- }
+ self.get_or_create_pipeline_details(pipeline_id).ready_state = ready_state;
self.window.set_ready_state(self.get_earliest_pipeline_ready_state());
// If we're painting in headless mode, schedule a recomposite.
@@ -379,27 +385,29 @@ impl<Window: WindowMethods> IOCompositor<Window> {
}
fn get_earliest_pipeline_ready_state(&self) -> ReadyState {
- if self.ready_states.len() == 0 {
+ if self.pipeline_details.len() == 0 {
return ReadyState::Blank;
}
- return self.ready_states.values().fold(ReadyState::FinishedLoading,
- |a, &b| cmp::min(a, b));
-
+ return self.pipeline_details.values().fold(ReadyState::FinishedLoading,
+ |v, ref details| {
+ cmp::min(v, details.ready_state)
+ });
}
fn change_paint_state(&mut self, pipeline_id: PipelineId, paint_state: PaintState) {
- match self.paint_states.entry(pipeline_id) {
- Occupied(entry) => {
- *entry.into_mut() = paint_state;
- }
- Vacant(entry) => {
- entry.set(paint_state);
- }
- }
-
+ self.get_or_create_pipeline_details(pipeline_id).paint_state = paint_state;
self.window.set_paint_state(paint_state);
}
+ pub fn get_or_create_pipeline_details<'a>(&'a mut self,
+ pipeline_id: PipelineId)
+ -> &'a mut PipelineDetails {
+ if !self.pipeline_details.contains_key(&pipeline_id) {
+ self.pipeline_details.insert(pipeline_id, PipelineDetails::new());
+ }
+ return self.pipeline_details.get_mut(&pipeline_id).unwrap();
+ }
+
fn change_page_title(&mut self, _: PipelineId, title: Option<String>) {
self.window.set_page_title(title);
}
@@ -409,10 +417,12 @@ impl<Window: WindowMethods> IOCompositor<Window> {
}
fn all_pipelines_in_idle_paint_state(&self) -> bool {
- if self.ready_states.len() == 0 {
+ if self.pipeline_details.len() == 0 {
return false;
}
- return self.paint_states.values().all(|&value| value == PaintState::Idle);
+ return self.pipeline_details.values().all(|ref details| {
+ details.paint_state == PaintState::Idle
+ });
}
fn has_paint_msg_tracking(&self) -> bool {
@@ -485,9 +495,9 @@ impl<Window: WindowMethods> IOCompositor<Window> {
layer_properties,
WantsScrollEventsFlag::WantsScrollEvents,
opts::get().tile_size);
- if !self.paint_channels.contains_key(&pipeline.id) {
- self.paint_channels.insert(pipeline.id, pipeline.paint_chan.clone());
- }
+
+ self.get_or_create_pipeline_details(pipeline.id).paint_task_channel =
+ Some(pipeline.paint_chan.clone());
// All root layers mask to bounds.
*root_layer.masks_to_bounds.borrow_mut() = true;
@@ -504,10 +514,6 @@ impl<Window: WindowMethods> IOCompositor<Window> {
frame_tree: &SendableFrameTree,
frame_rect: Option<TypedRect<PagePx, f32>>)
-> Rc<Layer<CompositorData>> {
- // Initialize the ReadyState and PaintState for this pipeline.
- self.ready_states.insert(frame_tree.pipeline.id, ReadyState::Blank);
- self.paint_states.insert(frame_tree.pipeline.id, PaintState::Painting);
-
let root_layer = self.create_root_layer_for_pipeline_and_rect(&frame_tree.pipeline,
frame_rect);
for kid in frame_tree.children.iter() {
@@ -660,16 +666,24 @@ impl<Window: WindowMethods> IOCompositor<Window> {
new_layer_buffer_set: Box<LayerBufferSet>,
epoch: Epoch) {
match self.find_layer_with_pipeline_and_layer_id(pipeline_id, layer_id) {
- Some(layer) => self.assign_painted_buffers_to_layer(layer, new_layer_buffer_set, epoch),
- None => {
- match self.paint_channels.entry(pipeline_id) {
- Occupied(entry) => {
+ Some(layer) => {
+ self.assign_painted_buffers_to_layer(layer, new_layer_buffer_set, epoch);
+ return;
+ }
+ None => {}
+ }
+
+ match self.pipeline_details.entry(pipeline_id) {
+ Occupied(entry) => {
+ match entry.get().paint_task_channel {
+ Some(ref channel) => {
let message = PaintMsg::UnusedBuffer(new_layer_buffer_set.buffers);
- let _ = entry.get().send_opt(message);
- },
- Vacant(_) => panic!("Received a buffer from an unknown pipeline!"),
+ let _ = channel.send_opt(message);
+ }
+ None => panic!("Received buffers for an uninitialized pipeline!"),
}
}
+ Vacant(_) => panic!("Received buffers for an unknown pipeline!"),
}
}