1use crate::*;
3use std::sync::Arc;
4
5#[derive(Clone, Debug, PartialEq)]
7pub struct BackdropCacheKey {
8 pub viewport: Size<DevicePixels>,
10 pub origin: [u32; 2],
12 pub size: [u32; 2],
14 pub filter: [[[f32; 4]; 6]; 2],
16 pub revision: Arc<[(u64, DrawOrder)]>,
18 pub reusable: bool,
20}
21#[derive(Clone, Copy, Default, Debug, PartialEq, Eq)]
23pub struct BackdropCacheStats {
24 pub captures: u64,
26 pub hits: u64,
28}
29#[derive(Default)]
31pub struct BackdropCache {
32 current: Vec<BackdropCacheKey>,
33 retained: Vec<Option<BackdropCacheKey>>,
34 hits: Vec<bool>,
35 context: Vec<u64>,
36 pub stats: BackdropCacheStats,
38}
39impl BackdropCache {
40 pub fn prepare(&mut self, keys: Vec<BackdropCacheKey>, context: &[u64]) {
42 if self.context != context {
43 self.retained.clear();
44 self.context = context.to_vec();
45 }
46 self.retained.resize_with(keys.len(), || None);
47 self.hits = keys
48 .iter()
49 .zip(&self.retained)
50 .map(|(key, old)| key.reusable && old.as_ref() == Some(key))
51 .collect();
52 self.current = keys;
53 }
54 pub fn invalidate(&mut self, index: usize) {
56 if let Some(old) = self.retained.get_mut(index) {
57 *old = None;
58 }
59 if let Some(hit) = self.hits.get_mut(index) {
60 *hit = false;
61 }
62 }
63 pub fn hit(&self, index: usize) -> bool {
65 self.hits[index]
66 }
67 pub fn start(&mut self, index: usize) {
69 if !self.hits[index] {
70 self.retained[index] = None;
71 }
72 }
73 pub fn commit(&mut self, executed: &[usize]) {
75 for &index in executed {
76 if self.hits[index] {
77 self.stats.hits += 1;
78 } else {
79 self.stats.captures += 1;
80 self.retained[index] = self.current[index]
81 .reusable
82 .then(|| self.current[index].clone());
83 }
84 }
85 }
86}