diff --git a/webrender/src/render_backend.rs b/webrender/src/render_backend.rs index fce29f9310..401ea7e6da 100644 --- a/webrender/src/render_backend.rs +++ b/webrender/src/render_backend.rs @@ -188,7 +188,8 @@ impl RenderBackend { loop { auxiliary_data = self.payload_rx.recv_payload().unwrap(); { - if auxiliary_data.epoch == epoch { + if auxiliary_data.epoch == epoch && + auxiliary_data.pipeline_id == pipeline_id { break } } diff --git a/webrender_traits/src/api.rs b/webrender_traits/src/api.rs index 92b6f5c1d3..74d480efd0 100644 --- a/webrender_traits/src/api.rs +++ b/webrender_traits/src/api.rs @@ -315,7 +315,12 @@ impl RenderApi { preserve_frame_state); self.api_sender.send(msg).unwrap(); - self.payload_sender.send_payload(Payload{epoch: epoch, display_list_data: dl_data, auxiliary_lists_data: aux_data}).unwrap(); + self.payload_sender.send_payload(Payload { + epoch: epoch, + pipeline_id: pipeline_id, + display_list_data: dl_data, + auxiliary_lists_data: aux_data + }).unwrap(); } /// Scrolls the scrolling layer under the `cursor` diff --git a/webrender_traits/src/channel.rs b/webrender_traits/src/channel.rs index 776c87184b..7f705389fc 100644 --- a/webrender_traits/src/channel.rs +++ b/webrender_traits/src/channel.rs @@ -4,33 +4,52 @@ use byteorder::{LittleEndian, WriteBytesExt, ReadBytesExt}; use std::io::{Cursor, Read}; -use api::Epoch; +use api::{Epoch, PipelineId}; use std::mem; #[derive(Clone)] pub struct Payload { + /// An epoch used to get the proper payload for a pipeline id frame request. + /// + /// TODO(emilio): Is this still relevant? We send the messages for the same + /// pipeline in order, so we shouldn't need it. Seems like this was only + /// wallpapering (in most cases) the underlying problem in #991. pub epoch: Epoch, + /// A pipeline id to key the payload with, along with the epoch. + pub pipeline_id: PipelineId, pub display_list_data: Vec, pub auxiliary_lists_data: Vec } impl Payload { + /// Convert the payload to a raw byte vector, in order for it to be + /// efficiently shared via shmem, for example. + /// + /// TODO(emilio, #1049): Consider moving the IPC boundary to the + /// constellation in Servo and remove this complexity from WR. pub fn to_data(&self) -> Vec { let mut data = Vec::with_capacity(mem::size_of::() + + 2 * mem::size_of::() + mem::size_of::() + self.display_list_data.len() + mem::size_of::() + self.auxiliary_lists_data.len()); data.write_u32::(self.epoch.0).unwrap(); + data.write_u32::(self.pipeline_id.0).unwrap(); + data.write_u32::(self.pipeline_id.1).unwrap(); data.write_u64::(self.display_list_data.len() as u64).unwrap(); data.extend_from_slice(&self.display_list_data); data.write_u64::(self.auxiliary_lists_data.len() as u64).unwrap(); data.extend_from_slice(&self.auxiliary_lists_data); data } + + /// Deserializes the given payload from a raw byte vector. pub fn from_data(data: Vec) -> Payload { let mut payload_reader = Cursor::new(&data[..]); let epoch = Epoch(payload_reader.read_u32::().unwrap()); + let pipeline_id = PipelineId(payload_reader.read_u32::().unwrap(), + payload_reader.read_u32::().unwrap()); let dl_size = payload_reader.read_u64::().unwrap() as usize; let mut built_display_list_data = vec![0; dl_size]; @@ -40,17 +59,22 @@ impl Payload { let mut auxiliary_lists_data = vec![0; aux_size]; payload_reader.read_exact(&mut auxiliary_lists_data[..]).unwrap(); - Payload{ epoch: epoch, display_list_data: built_display_list_data, - auxiliary_lists_data: auxiliary_lists_data } + Payload { + epoch: epoch, + pipeline_id: pipeline_id, + display_list_data: built_display_list_data, + auxiliary_lists_data: auxiliary_lists_data, + } } } -// A helper to handle the interface difference between -// IpcBytesSender and Sender> +/// A helper to handle the interface difference between IpcBytesSender and +/// Sender>. pub trait PayloadSenderHelperMethods { fn send_payload(&self, data: Payload) -> Result<(), Error>; } + pub trait PayloadReceiverHelperMethods { fn recv_payload(&self) -> Result; }