anvilkit_render/renderer/
buffer_pool.rs1use wgpu::{Buffer, BufferUsages, Device};
14
15pub struct BufferPool {
21 available: Vec<(Buffer, u64)>,
23 in_use_count: usize,
25 max_pool_size: usize,
27}
28
29impl BufferPool {
30 pub fn new(max_pool_size: usize) -> Self {
34 Self {
35 available: Vec::new(),
36 in_use_count: 0,
37 max_pool_size,
38 }
39 }
40
41 pub fn acquire(
45 &mut self,
46 device: &Device,
47 min_size: u64,
48 usage: BufferUsages,
49 label: &str,
50 ) -> Buffer {
51 if let Some(idx) = self.available.iter().position(|(_, cap)| *cap >= min_size) {
53 self.in_use_count += 1;
54 return self.available.remove(idx).0;
55 }
56
57 self.in_use_count += 1;
59 device.create_buffer(&wgpu::BufferDescriptor {
60 label: Some(label),
61 size: min_size,
62 usage,
63 mapped_at_creation: false,
64 })
65 }
66
67 pub fn release(&mut self, buffer: Buffer, capacity: u64) {
69 self.in_use_count = self.in_use_count.saturating_sub(1);
70
71 if self.available.len() >= self.max_pool_size {
73 if let Some(min_idx) = self.available.iter()
75 .enumerate()
76 .min_by_key(|(_, (_, cap))| *cap)
77 .map(|(i, _)| i)
78 {
79 if self.available[min_idx].1 < capacity {
80 self.available.remove(min_idx);
82 } else {
83 return;
85 }
86 }
87 }
88
89 self.available.push((buffer, capacity));
90 }
91
92 pub fn available_count(&self) -> usize {
94 self.available.len()
95 }
96
97 pub fn in_use_count(&self) -> usize {
99 self.in_use_count
100 }
101
102 pub fn clear(&mut self) {
104 self.available.clear();
105 self.in_use_count = 0;
106 }
107}
108
109impl Default for BufferPool {
110 fn default() -> Self {
111 Self::new(64)
112 }
113}
114
115#[cfg(test)]
116mod tests {
117 use super::*;
118
119 #[test]
120 fn test_buffer_pool_default() {
121 let pool = BufferPool::default();
122 assert_eq!(pool.available_count(), 0);
123 assert_eq!(pool.in_use_count(), 0);
124 assert_eq!(pool.max_pool_size, 64);
125 }
126
127 #[test]
128 fn test_buffer_pool_custom_size() {
129 let pool = BufferPool::new(16);
130 assert_eq!(pool.max_pool_size, 16);
131 }
132}