1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
use rafx_api::RafxResult;
use std::collections::VecDeque;
use std::num::Wrapping;
struct DropSinkResourceInFlight<T> {
_resource: T,
live_until_frame: Wrapping<u32>,
}
pub struct ResourceDropSink<T> {
resources_in_flight: VecDeque<DropSinkResourceInFlight<T>>,
max_in_flight_frames: Wrapping<u32>,
frame_index: Wrapping<u32>,
}
impl<T> ResourceDropSink<T> {
pub fn new(max_in_flight_frames: u32) -> Self {
ResourceDropSink {
resources_in_flight: Default::default(),
max_in_flight_frames: Wrapping(max_in_flight_frames),
frame_index: Wrapping(0),
}
}
pub fn retire(
&mut self,
resource: T,
) {
self.resources_in_flight
.push_back(DropSinkResourceInFlight::<T> {
_resource: resource,
live_until_frame: self.frame_index + self.max_in_flight_frames + Wrapping(1),
});
}
pub fn on_frame_complete(&mut self) -> RafxResult<()> {
self.frame_index += Wrapping(1);
let mut resources_to_drop = 0;
for resource_in_flight in &self.resources_in_flight {
if resource_in_flight.live_until_frame - self.frame_index > Wrapping(std::u32::MAX / 2)
{
resources_to_drop += 1;
} else {
break;
}
}
let resources_to_drop: Vec<_> = self
.resources_in_flight
.drain(0..resources_to_drop)
.collect();
std::mem::drop(resources_to_drop);
Ok(())
}
pub fn destroy(&mut self) -> RafxResult<()> {
for resource in self.resources_in_flight.drain(..) {
std::mem::drop(resource);
}
Ok(())
}
}
impl<T> Drop for ResourceDropSink<T> {
fn drop(&mut self) {
assert!(self.resources_in_flight.is_empty())
}
}