Bug 1722838 - Add DisplayListPayload struct r=jrmuizel,gfx-reviewers,nical
authorGlenn Watson <git@intuitionlibrary.com>
Thu, 29 Jul 2021 20:23:30 +0000
changeset 587045 18d3ab530ed7ffa04ee9978f8ee9779887765f4a
parent 587044 52cc9f22fbd8c82337f859f5c53455d006576c4d
child 587046 efe0ed0e5769b3c69861928ebbd297e8e631b03a
push id38655
push usernerli@mozilla.com
push dateFri, 30 Jul 2021 03:38:17 +0000
treeherdermozilla-central@d7b25de9e739 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjrmuizel, gfx-reviewers, nical
bugs1722838
milestone92.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1722838 - Add DisplayListPayload struct r=jrmuizel,gfx-reviewers,nical Although this currently only contains the existing data u8 vec of serialized bytes, it will allow us to expand this structure in future to contain other byte arrays. This will be used for storing other payload information, such as interned primitive types or data updates. Differential Revision: https://phabricator.services.mozilla.com/D121160
gfx/webrender_bindings/src/bindings.rs
gfx/wr/webrender_api/src/display_list.rs
--- a/gfx/webrender_bindings/src/bindings.rs
+++ b/gfx/webrender_bindings/src/bindings.rs
@@ -1839,18 +1839,21 @@ pub extern "C" fn wr_transaction_set_dis
 ) {
     let color = if background.a == 0.0 { None } else { Some(background) };
 
     // See the documentation of set_display_list in api.rs. I don't think
     // it makes a difference in gecko at the moment(until APZ is figured out)
     // but I suppose it is a good default.
     let preserve_frame_state = true;
 
-    let dl_vec = dl_data.flush_into_vec();
-    let dl = BuiltDisplayList::from_data(dl_vec, dl_descriptor);
+    let payload = DisplayListPayload {
+        data: dl_data.flush_into_vec(),
+    };
+
+    let dl = BuiltDisplayList::from_data(payload, dl_descriptor);
 
     txn.set_display_list(epoch, color, viewport_size, (pipeline_id, dl), preserve_frame_state);
 }
 
 #[no_mangle]
 pub extern "C" fn wr_transaction_set_document_view(txn: &mut Transaction, doc_rect: &DeviceIntRect) {
     txn.set_document_view(*doc_rect);
 }
@@ -3765,18 +3768,18 @@ pub extern "C" fn wr_dump_serialized_dis
 #[no_mangle]
 pub unsafe extern "C" fn wr_api_finalize_builder(
     state: &mut WrState,
     dl_descriptor: &mut BuiltDisplayListDescriptor,
     dl_data: &mut WrVecU8,
 ) {
     let frame_builder = mem::replace(&mut state.frame_builder, WebRenderFrameBuilder::new(state.pipeline_id));
     let (_, dl) = frame_builder.dl_builder.finalize();
-    let (data, descriptor) = dl.into_data();
-    *dl_data = WrVecU8::from_vec(data);
+    let (payload, descriptor) = dl.into_data();
+    *dl_data = WrVecU8::from_vec(payload.data);
     *dl_descriptor = descriptor;
 }
 
 #[repr(C)]
 pub struct HitResult {
     pipeline_id: WrPipelineId,
     scroll_id: u64,
     hit_info: u16,
--- a/gfx/wr/webrender_api/src/display_list.rs
+++ b/gfx/wr/webrender_api/src/display_list.rs
@@ -102,21 +102,32 @@ where
 pub struct TempFilterData<'a> {
     pub func_types: ItemRange<'a, di::ComponentTransferFuncType>,
     pub r_values: ItemRange<'a, f32>,
     pub g_values: ItemRange<'a, f32>,
     pub b_values: ItemRange<'a, f32>,
     pub a_values: ItemRange<'a, f32>,
 }
 
+#[derive(Default, Clone)]
+pub struct DisplayListPayload {
+    /// Serde encoded bytes. Mostly DisplayItems, but some mixed in slices.
+    pub data: Vec<u8>,
+}
+
+impl MallocSizeOf for DisplayListPayload {
+    fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
+        self.data.size_of(ops)
+    }
+}
+
 /// A display list.
-#[derive(Clone, Default)]
+#[derive(Default, Clone)]
 pub struct BuiltDisplayList {
-    /// Serde encoded bytes. Mostly DisplayItems, but some mixed in slices.
-    data: Vec<u8>,
+    payload: DisplayListPayload,
     descriptor: BuiltDisplayListDescriptor,
 }
 
 #[repr(C)]
 #[derive(Copy, Clone, Deserialize, Serialize)]
 pub enum GeckoDisplayListType {
   None,
   Partial(f64),
@@ -188,17 +199,17 @@ impl DisplayListWithCache {
 
     pub fn data(&self) -> &[u8] {
         self.display_list.data()
     }
 }
 
 impl MallocSizeOf for DisplayListWithCache {
     fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
-        self.display_list.data.size_of(ops) + self.cache.size_of(ops)
+        self.display_list.payload.size_of(ops) + self.cache.size_of(ops)
     }
 }
 
 #[cfg(feature = "serialize")]
 impl Serialize for DisplayListWithCache {
     fn serialize<S: Serializer>(
         &self,
         serializer: S
@@ -368,34 +379,40 @@ enum Peek {
 pub struct AuxIter<'a, T> {
     item: T,
     data: &'a [u8],
     size: usize,
 //    _boo: PhantomData<T>,
 }
 
 impl BuiltDisplayList {
-    pub fn from_data(data: Vec<u8>, descriptor: BuiltDisplayListDescriptor) -> Self {
-        BuiltDisplayList { data, descriptor }
+    pub fn from_data(
+        payload: DisplayListPayload,
+        descriptor: BuiltDisplayListDescriptor,
+    ) -> Self {
+        BuiltDisplayList {
+            payload,
+            descriptor,
+        }
     }
 
-    pub fn into_data(self) -> (Vec<u8>, BuiltDisplayListDescriptor) {
-        (self.data, self.descriptor)
+    pub fn into_data(self) -> (DisplayListPayload, BuiltDisplayListDescriptor) {
+        (self.payload, self.descriptor)
     }
 
     pub fn data(&self) -> &[u8] {
-        &self.data[..]
+        &self.payload.data[..]
     }
 
     pub fn item_slice(&self) -> &[u8] {
-        &self.data[..self.descriptor.extra_data_offset]
+        &self.payload.data[..self.descriptor.extra_data_offset]
     }
 
     pub fn extra_slice(&self) -> &[u8] {
-        &self.data[self.descriptor.extra_data_offset..]
+        &self.payload.data[self.descriptor.extra_data_offset..]
     }
 
     pub fn descriptor(&self) -> &BuiltDisplayListDescriptor {
         &self.descriptor
     }
 
     pub fn set_send_time_ns(&mut self, time: u64) {
         self.descriptor.send_start_time = time;
@@ -949,17 +966,19 @@ impl<'de> Deserialize<'de> for BuiltDisp
 
         // Add `DisplayItem::max_size` zone of zeroes to the end of display list
         // so there is at least this amount available in the display list during
         // serialization.
         ensure_red_zone::<di::DisplayItem>(&mut data);
         let extra_data_offset = data.len();
 
         Ok(BuiltDisplayList {
-            data,
+            payload: DisplayListPayload {
+                data,
+            },
             descriptor: BuiltDisplayListDescriptor {
                 gecko_display_list_type: GeckoDisplayListType::None,
                 builder_start_time: 0,
                 builder_finish_time: 1,
                 send_start_time: 1,
                 total_clip_nodes,
                 total_spatial_nodes,
                 extra_data_offset,
@@ -985,17 +1004,17 @@ pub enum DisplayListSection {
     ExtraData,
     /// Temporary buffer: contains the data for pending item group. Flushed to
     /// one of the buffers above, after item grouping finishes.
     Chunk,
 }
 
 #[derive(Clone)]
 pub struct DisplayListBuilder {
-    pub data: Vec<u8>,
+    payload: DisplayListPayload,
     pub pipeline_id: PipelineId,
 
     extra_data: Vec<u8>,
     pending_chunk: Vec<u8>,
     writing_to_chunk: bool,
 
     next_clip_index: usize,
     next_spatial_index: usize,
@@ -1015,17 +1034,19 @@ impl DisplayListBuilder {
 
     pub fn with_capacity(
         pipeline_id: PipelineId,
         capacity: usize,
     ) -> Self {
         let start_time = precise_time_ns();
 
         DisplayListBuilder {
-            data: Vec::with_capacity(capacity),
+            payload: DisplayListPayload {
+                data: Vec::with_capacity(capacity),
+            },
             pipeline_id,
 
             extra_data: Vec::new(),
             pending_chunk: Vec::new(),
             writing_to_chunk: false,
 
             next_clip_index: FIRST_CLIP_NODE_INDEX,
             next_spatial_index: FIRST_SPATIAL_NODE_INDEX,
@@ -1043,28 +1064,28 @@ impl DisplayListBuilder {
     ///
     /// * Doesn't support popping clips that were pushed before the save.
     /// * Doesn't support nested saves.
     /// * Must call `clear_save()` if the restore becomes unnecessary.
     pub fn save(&mut self) {
         assert!(self.save_state.is_none(), "DisplayListBuilder doesn't support nested saves");
 
         self.save_state = Some(SaveState {
-            dl_len: self.data.len(),
+            dl_len: self.payload.data.len(),
             next_clip_index: self.next_clip_index,
             next_spatial_index: self.next_spatial_index,
             next_clip_chain_id: self.next_clip_chain_id,
         });
     }
 
     /// Restores the state of the builder to when `save()` was last called.
     pub fn restore(&mut self) {
         let state = self.save_state.take().expect("No save to restore DisplayListBuilder from");
 
-        self.data.truncate(state.dl_len);
+        self.payload.data.truncate(state.dl_len);
         self.next_clip_index = state.next_clip_index;
         self.next_spatial_index = state.next_spatial_index;
         self.next_clip_chain_id = state.next_clip_chain_id;
     }
 
     /// Discards the builder's save (indicating the attempted operation was successful).
     pub fn clear_save(&mut self) {
         self.save_state.take().expect("No save to clear in DisplayListBuilder");
@@ -1086,35 +1107,35 @@ impl DisplayListBuilder {
         indent: usize,
         range: Range<Option<usize>>,
         mut sink: W,
     ) -> usize
     where
         W: Write
     {
         let mut temp = BuiltDisplayList::default();
-        ensure_red_zone::<di::DisplayItem>(&mut self.data);
-        temp.descriptor.extra_data_offset = self.data.len();
-        mem::swap(&mut temp.data, &mut self.data);
+        ensure_red_zone::<di::DisplayItem>(&mut self.payload.data);
+        temp.descriptor.extra_data_offset = self.payload.data.len();
+        mem::swap(&mut temp.payload, &mut self.payload);
 
         let mut index: usize = 0;
         {
             let mut cache = DisplayItemCache::new();
             cache.update(&temp);
             let mut iter = temp.iter_with_cache(&cache);
             while let Some(item) = iter.next_raw() {
                 if index >= range.start.unwrap_or(0) && range.end.map_or(true, |e| index < e) {
                     writeln!(sink, "{}{:?}", "  ".repeat(indent), item.item()).unwrap();
                 }
                 index += 1;
             }
         }
 
-        self.data = temp.data;
-        strip_red_zone::<di::DisplayItem>(&mut self.data);
+        self.payload = temp.payload;
+        strip_red_zone::<di::DisplayItem>(&mut self.payload.data);
         index
     }
 
     /// Print the display items in the list to stdout.
     pub fn dump_serialized_display_list(&mut self) {
         self.serialized_content_buffer = Some(String::new());
     }
 
@@ -1135,17 +1156,17 @@ impl DisplayListBuilder {
         }
     }
 
     fn buffer_from_section(
         &mut self,
         section: DisplayListSection
     ) -> &mut Vec<u8> {
         match section {
-            DisplayListSection::Data => &mut self.data,
+            DisplayListSection::Data => &mut self.payload.data,
             DisplayListSection::ExtraData => &mut self.extra_data,
             DisplayListSection::Chunk => &mut self.pending_chunk,
         }
     }
 
     #[inline]
     pub fn push_item_to_section(
         &mut self,
@@ -1942,17 +1963,17 @@ impl DisplayListBuilder {
     pub fn cancel_item_group(&mut self, discard: bool) {
         debug_assert!(self.writing_to_chunk);
         self.writing_to_chunk = false;
 
         if discard {
             self.pending_chunk.clear();
         } else {
             // Push pending chunk to data section.
-            self.data.append(&mut self.pending_chunk);
+            self.payload.data.append(&mut self.pending_chunk);
         }
     }
 
     pub fn push_reuse_items(&mut self, key: di::ItemKey) {
         self.push_item_to_section(
             &di::DisplayItem::ReuseItems(key),
             DisplayListSection::Data
         );
@@ -1975,36 +1996,36 @@ impl DisplayListBuilder {
         if let Some(content) = self.serialized_content_buffer.take() {
             println!("-- WebRender display list for {:?} --\n{}",
                 self.pipeline_id, content);
         }
 
         // Add `DisplayItem::max_size` zone of zeroes to the end of display list
         // so there is at least this amount available in the display list during
         // serialization.
-        ensure_red_zone::<di::DisplayItem>(&mut self.data);
+        ensure_red_zone::<di::DisplayItem>(&mut self.payload.data);
 
-        let extra_data_offset = self.data.len();
+        let extra_data_offset = self.payload.data.len();
 
         if self.extra_data.len() > 0 {
             ensure_red_zone::<di::DisplayItem>(&mut self.extra_data);
-            self.data.extend(self.extra_data);
+            self.payload.data.extend(self.extra_data);
         }
 
         let end_time = precise_time_ns();
         (
             self.pipeline_id,
             BuiltDisplayList {
                 descriptor: BuiltDisplayListDescriptor {
                     gecko_display_list_type: GeckoDisplayListType::None,
                     builder_start_time: self.builder_start_time,
                     builder_finish_time: end_time,
                     send_start_time: end_time,
                     total_clip_nodes: self.next_clip_index,
                     total_spatial_nodes: self.next_spatial_index,
                     cache_size: self.cache_size,
                     extra_data_offset,
                 },
-                data: self.data,
+                payload: self.payload,
             },
         )
     }
 }