rg3d/renderer/cache/
geometry.rs1use 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 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}