azul_webrender_api/
display_item_cache.rs1use crate::display_item::*;
6use crate::display_list::*;
7use malloc_size_of::{MallocSizeOf, MallocSizeOfOps};
8
9#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
10pub struct CachedDisplayItem {
11 item: DisplayItem,
12 data: Vec<u8>,
13}
14
15impl CachedDisplayItem {
16 pub fn display_item(&self) -> &DisplayItem {
17 &self.item
18 }
19
20 pub fn data_as_item_range<T>(&self) -> ItemRange<T> {
21 ItemRange::new(&self.data)
22 }
23}
24
25impl MallocSizeOf for CachedDisplayItem {
26 fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
27 self.data.size_of(ops)
28 }
29}
30
31impl From<DisplayItemRef<'_, '_>> for CachedDisplayItem {
32 fn from(item_ref: DisplayItemRef) -> Self {
33 let item = item_ref.item();
34
35 match item {
36 DisplayItem::Text(..) => CachedDisplayItem {
37 item: *item,
38 data: item_ref.glyphs().bytes().to_vec(),
39 },
40 _ => CachedDisplayItem {
41 item: *item,
42 data: Vec::new(),
43 },
44 }
45 }
46}
47
48#[derive(Clone, Deserialize, MallocSizeOf, Serialize)]
49struct CacheEntry {
50 items: Vec<CachedDisplayItem>,
51 occupied: bool,
52}
53
54#[derive(Clone, Deserialize, MallocSizeOf, Serialize)]
55pub struct DisplayItemCache {
56 entries: Vec<CacheEntry>,
57}
58
59impl DisplayItemCache {
60 fn add_item(&mut self, key: ItemKey, item: CachedDisplayItem) {
61 let mut entry = &mut self.entries[key as usize];
62 entry.items.push(item);
63 entry.occupied = true;
64 }
65
66 fn clear_entry(&mut self, key: ItemKey) {
67 let mut entry = &mut self.entries[key as usize];
68 entry.items.clear();
69 entry.occupied = false;
70 }
71
72 fn grow_if_needed(&mut self, capacity: usize) {
73 if capacity > self.entries.len() {
74 self.entries.resize_with(capacity, || CacheEntry {
75 items: Vec::new(),
76 occupied: false,
77 });
78 }
79 }
80
81 pub fn get_items(&self, key: ItemKey) -> &[CachedDisplayItem] {
82 let entry = &self.entries[key as usize];
83 debug_assert!(entry.occupied);
84 entry.items.as_slice()
85 }
86
87 pub fn new() -> Self {
88 Self {
89 entries: Vec::new(),
90 }
91 }
92
93 pub fn update(&mut self, display_list: &BuiltDisplayList) {
94 self.grow_if_needed(display_list.cache_size());
95
96 let mut iter = display_list.extra_data_iter();
97 let mut current_key: Option<ItemKey> = None;
98 loop {
99 let item = match iter.next() {
100 Some(item) => item,
101 None => break,
102 };
103
104 if let DisplayItem::RetainedItems(key) = item.item() {
105 current_key = Some(*key);
106 self.clear_entry(*key);
107 continue;
108 }
109
110 let key = current_key.expect("Missing RetainedItems marker");
111 let cached_item = CachedDisplayItem::from(item);
112 self.add_item(key, cached_item);
113 }
114 }
115}