rg3d/renderer/cache/
geometry.rs

1use crate::core::parking_lot::Mutex;
2use crate::core::sparse::SparseBuffer;
3use crate::{
4    core::scope_profile,
5    engine::resource_manager::DEFAULT_RESOURCE_LIFETIME,
6    renderer::{
7        cache::CacheEntry,
8        framework::{
9            geometry_buffer::{GeometryBuffer, GeometryBufferKind},
10            state::PipelineState,
11        },
12    },
13    scene::mesh::surface::SurfaceData,
14};
15use std::sync::Arc;
16
17#[derive(Default)]
18pub struct GeometryCache {
19    buffer: SparseBuffer<CacheEntry<GeometryBuffer>>,
20}
21
22impl GeometryCache {
23    pub fn get<'a>(
24        &'a mut self,
25        state: &mut PipelineState,
26        data: &Arc<Mutex<SurfaceData>>,
27    ) -> &'a mut GeometryBuffer {
28        scope_profile!();
29
30        let data = data.lock();
31        let data_hash = data.content_hash();
32
33        if self.buffer.is_index_valid(&data.cache_entry) {
34            let entry = self.buffer.get_mut(&data.cache_entry).unwrap();
35
36            if data_hash != entry.value_hash {
37                // Content has changed, upload new content.
38                entry.set_buffer_data(state, 0, data.vertex_buffer.raw_data());
39                entry
40                    .bind(state)
41                    .set_triangles(data.geometry_buffer.triangles_ref());
42
43                entry.value_hash = data_hash;
44            }
45
46            entry.time_to_live = DEFAULT_RESOURCE_LIFETIME;
47            entry
48        } else {
49            let geometry_buffer =
50                GeometryBuffer::from_surface_data(&*data, GeometryBufferKind::StaticDraw, state);
51
52            let index = self.buffer.spawn(CacheEntry {
53                value: geometry_buffer,
54                time_to_live: DEFAULT_RESOURCE_LIFETIME,
55                value_hash: data_hash,
56            });
57
58            data.cache_entry.set(index.get());
59
60            self.buffer.get_mut(&index).unwrap()
61        }
62    }
63
64    pub fn update(&mut self, dt: f32) {
65        scope_profile!();
66
67        for entry in self.buffer.iter_mut() {
68            entry.time_to_live -= dt;
69        }
70
71        for i in 0..self.buffer.len() {
72            if let Some(entry) = self.buffer.get_raw(i) {
73                if entry.time_to_live <= 0.0 {
74                    self.buffer.free_raw(i);
75                }
76            }
77        }
78    }
79
80    pub fn clear(&mut self) {
81        self.buffer.clear();
82    }
83}