From 36d22d82aa202bb199967e9512281e9a53db42c9 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 21:33:14 +0200 Subject: Adding upstream version 115.7.0esr. Signed-off-by: Daniel Baumann --- gfx/wr/webrender_api/src/display_item_cache.rs | 115 +++++++++++++++++++++++++ 1 file changed, 115 insertions(+) create mode 100644 gfx/wr/webrender_api/src/display_item_cache.rs (limited to 'gfx/wr/webrender_api/src/display_item_cache.rs') diff --git a/gfx/wr/webrender_api/src/display_item_cache.rs b/gfx/wr/webrender_api/src/display_item_cache.rs new file mode 100644 index 0000000000..6cd1eb3e3a --- /dev/null +++ b/gfx/wr/webrender_api/src/display_item_cache.rs @@ -0,0 +1,115 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +use crate::display_item::*; +use crate::display_list::*; +use malloc_size_of::{MallocSizeOf, MallocSizeOfOps}; + +#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)] +pub struct CachedDisplayItem { + item: DisplayItem, + data: Vec, +} + +impl CachedDisplayItem { + pub fn display_item(&self) -> &DisplayItem { + &self.item + } + + pub fn data_as_item_range(&self) -> ItemRange { + ItemRange::new(&self.data) + } +} + +impl MallocSizeOf for CachedDisplayItem { + fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize { + self.data.size_of(ops) + } +} + +impl From> for CachedDisplayItem { + fn from(item_ref: DisplayItemRef) -> Self { + let item = item_ref.item(); + + match item { + DisplayItem::Text(..) => CachedDisplayItem { + item: *item, + data: item_ref.glyphs().bytes().to_vec(), + }, + _ => CachedDisplayItem { + item: *item, + data: Vec::new(), + }, + } + } +} + +#[derive(Clone, Deserialize, MallocSizeOf, Serialize)] +struct CacheEntry { + items: Vec, + occupied: bool, +} + +#[derive(Clone, Deserialize, MallocSizeOf, Serialize)] +pub struct DisplayItemCache { + entries: Vec, +} + +impl DisplayItemCache { + fn add_item(&mut self, key: ItemKey, item: CachedDisplayItem) { + let mut entry = &mut self.entries[key as usize]; + entry.items.push(item); + entry.occupied = true; + } + + fn clear_entry(&mut self, key: ItemKey) { + let mut entry = &mut self.entries[key as usize]; + entry.items.clear(); + entry.occupied = false; + } + + fn grow_if_needed(&mut self, capacity: usize) { + if capacity > self.entries.len() { + self.entries.resize_with(capacity, || CacheEntry { + items: Vec::new(), + occupied: false, + }); + } + } + + pub fn get_items(&self, key: ItemKey) -> &[CachedDisplayItem] { + let entry = &self.entries[key as usize]; + debug_assert!(entry.occupied); + entry.items.as_slice() + } + + pub fn new() -> Self { + Self { + entries: Vec::new(), + } + } + + pub fn update(&mut self, display_list: &BuiltDisplayList) { + self.grow_if_needed(display_list.cache_size()); + + let mut iter = display_list.cache_data_iter(); + let mut current_key: Option = None; + loop { + let item = match iter.next() { + Some(item) => item, + None => break, + }; + + if let DisplayItem::RetainedItems(key) = item.item() { + current_key = Some(*key); + self.clear_entry(*key); + continue; + } + + let key = current_key.expect("Missing RetainedItems marker"); + let cached_item = CachedDisplayItem::from(item); + self.add_item(key, cached_item); + } + } +} -- cgit v1.2.3