From 34e765bf8336bc437a8f3f968b07719b102f1ed1 Mon Sep 17 00:00:00 2001 From: Dzmitry Malyshau Date: Mon, 10 Sep 2018 09:55:28 -0400 Subject: [PATCH] Recording support for loaded captures --- examples/common/boilerplate.rs | 1 - webrender/src/render_backend.rs | 24 ++++++++++++++++++++++++ webrender_api/src/api.rs | 4 ++-- webrender_api/src/channel.rs | 27 ++++++++++++++++----------- 4 files changed, 42 insertions(+), 14 deletions(-) diff --git a/examples/common/boilerplate.rs b/examples/common/boilerplate.rs index 39588a1364..948228b16d 100644 --- a/examples/common/boilerplate.rs +++ b/examples/common/boilerplate.rs @@ -243,7 +243,6 @@ pub fn main_wrapper( 2.0 ), winit::VirtualKeyCode::M => api.notify_memory_pressure(), - #[cfg(feature = "capture")] winit::VirtualKeyCode::C => { let path: PathBuf = "../captures/example".into(); //TODO: switch between SCENE/FRAME capture types diff --git a/webrender/src/render_backend.rs b/webrender/src/render_backend.rs index 63cc470bd3..013e550c89 100644 --- a/webrender/src/render_backend.rs +++ b/webrender/src/render_backend.rs @@ -783,7 +783,31 @@ impl RenderBackend { window_size: doc.view.window_size, }; tx.send(captured).unwrap(); + + // notify the active recorder + if let Some(ref mut r) = self.recorder { + let pipeline_id = doc.scene.root_pipeline_id.unwrap(); + let epoch = doc.scene.pipeline_epochs[&pipeline_id]; + let pipeline = &doc.scene.pipelines[&pipeline_id]; + let scene_msg = SceneMsg::SetDisplayList { + list_descriptor: pipeline.display_list.descriptor().clone(), + epoch, + pipeline_id, + background: pipeline.background_color, + viewport_size: pipeline.viewport_size, + content_size: pipeline.content_size, + preserve_frame_state: false, + }; + let txn = TransactionMsg::scene_message(scene_msg); + r.write_msg(*frame_counter, &ApiMsg::UpdateDocument(*id, txn)); + r.write_payload(*frame_counter, &Payload::construct_data( + epoch, + pipeline_id, + pipeline.display_list.data(), + )); + } } + // Note: we can't pass `LoadCapture` here since it needs to arrive // before the `PublishDocument` messages sent by `load_capture`. return true; diff --git a/webrender_api/src/api.rs b/webrender_api/src/api.rs index 8cd4b160e2..079ae54f56 100644 --- a/webrender_api/src/api.rs +++ b/webrender_api/src/api.rs @@ -382,7 +382,7 @@ impl TransactionMsg { } // TODO: We only need this for a few RenderApi methods which we should remove. - fn frame_message(msg: FrameMsg) -> Self { + pub fn frame_message(msg: FrameMsg) -> Self { TransactionMsg { scene_ops: Vec::new(), frame_ops: vec![msg], @@ -393,7 +393,7 @@ impl TransactionMsg { } } - fn scene_message(msg: SceneMsg) -> Self { + pub fn scene_message(msg: SceneMsg) -> Self { TransactionMsg { scene_ops: vec![msg], frame_ops: Vec::new(), diff --git a/webrender_api/src/channel.rs b/webrender_api/src/channel.rs index 46f0cfcd66..ebc96b6619 100644 --- a/webrender_api/src/channel.rs +++ b/webrender_api/src/channel.rs @@ -24,22 +24,27 @@ pub struct Payload { 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 { + /// This is a helper static method working on a slice. + pub fn construct_data(epoch: Epoch, pipeline_id: PipelineId, dl_data: &[u8]) -> 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::() + 2 * mem::size_of::() + mem::size_of::() + dl_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) + data.write_u32::(epoch.0).unwrap(); + data.write_u32::(pipeline_id.0).unwrap(); + data.write_u32::(pipeline_id.1).unwrap(); + data.write_u64::(dl_data.len() as u64) .unwrap(); - data.extend_from_slice(&self.display_list_data); + data.extend_from_slice(dl_data); data } + /// 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 { + Self::construct_data(self.epoch, self.pipeline_id, &self.display_list_data) + } /// Deserializes the given payload from a raw byte vector. pub fn from_data(data: &[u8]) -> Payload {