1use std::hash;
6use crate::gpu_cache::{GpuCache, GpuCacheHandle};
7use crate::gpu_cache::GpuDataRequest;
8use crate::intern;
9use api::ComponentTransferFuncType;
10
11
12pub type FilterDataHandle = intern::Handle<FilterDataIntern>;
13
14#[derive(Debug, Clone, MallocSizeOf, PartialEq)]
15#[cfg_attr(feature = "capture", derive(Serialize))]
16#[cfg_attr(feature = "replay", derive(Deserialize))]
17pub enum SFilterDataComponent {
18 Identity,
19 Table(Vec<f32>),
20 Discrete(Vec<f32>),
21 Linear(f32, f32),
22 Gamma(f32, f32, f32),
23}
24
25impl Eq for SFilterDataComponent {}
26
27impl hash::Hash for SFilterDataComponent {
28 fn hash<H: hash::Hasher>(&self, state: &mut H) {
29 match self {
30 SFilterDataComponent::Identity => {
31 0.hash(state);
32 }
33 SFilterDataComponent::Table(values) => {
34 1.hash(state);
35 values.len().hash(state);
36 for val in values {
37 val.to_bits().hash(state);
38 }
39 }
40 SFilterDataComponent::Discrete(values) => {
41 2.hash(state);
42 values.len().hash(state);
43 for val in values {
44 val.to_bits().hash(state);
45 }
46 }
47 SFilterDataComponent::Linear(a, b) => {
48 3.hash(state);
49 a.to_bits().hash(state);
50 b.to_bits().hash(state);
51 }
52 SFilterDataComponent::Gamma(a, b, c) => {
53 4.hash(state);
54 a.to_bits().hash(state);
55 b.to_bits().hash(state);
56 c.to_bits().hash(state);
57 }
58 }
59 }
60}
61
62impl SFilterDataComponent {
63 pub fn to_int(&self) -> u32 {
64 match self {
65 SFilterDataComponent::Identity => 0,
66 SFilterDataComponent::Table(_) => 1,
67 SFilterDataComponent::Discrete(_) => 2,
68 SFilterDataComponent::Linear(_, _) => 3,
69 SFilterDataComponent::Gamma(_, _, _) => 4,
70 }
71 }
72
73 pub fn from_functype_values(
74 func_type: ComponentTransferFuncType,
75 values: &[f32],
76 ) -> SFilterDataComponent {
77 match func_type {
78 ComponentTransferFuncType::Identity => SFilterDataComponent::Identity,
79 ComponentTransferFuncType::Table => SFilterDataComponent::Table(values.to_vec()),
80 ComponentTransferFuncType::Discrete => SFilterDataComponent::Discrete(values.to_vec()),
81 ComponentTransferFuncType::Linear => SFilterDataComponent::Linear(values[0], values[1]),
82 ComponentTransferFuncType::Gamma => SFilterDataComponent::Gamma(values[0], values[1], values[2]),
83 }
84 }
85}
86
87#[derive(Debug, Clone, MallocSizeOf, PartialEq, Eq, Hash)]
88#[cfg_attr(feature = "capture", derive(Serialize))]
89#[cfg_attr(feature = "replay", derive(Deserialize))]
90pub struct SFilterData {
91 pub r_func: SFilterDataComponent,
92 pub g_func: SFilterDataComponent,
93 pub b_func: SFilterDataComponent,
94 pub a_func: SFilterDataComponent,
95}
96
97#[derive(Debug, Clone, MallocSizeOf, PartialEq, Eq, Hash)]
98#[cfg_attr(feature = "capture", derive(Serialize))]
99#[cfg_attr(feature = "replay", derive(Deserialize))]
100pub struct SFilterDataKey {
101 pub data: SFilterData,
102}
103
104impl intern::InternDebug for SFilterDataKey {}
105
106#[derive(Debug)]
107#[cfg_attr(feature = "capture", derive(Serialize))]
108#[cfg_attr(feature = "replay", derive(Deserialize))]
109#[derive(MallocSizeOf)]
110pub struct SFilterDataTemplate {
111 pub data: SFilterData,
112 pub gpu_cache_handle: GpuCacheHandle,
113}
114
115impl From<SFilterDataKey> for SFilterDataTemplate {
116 fn from(item: SFilterDataKey) -> Self {
117 SFilterDataTemplate {
118 data: item.data,
119 gpu_cache_handle: GpuCacheHandle::new(),
120 }
121 }
122}
123
124impl SFilterData {
125 pub fn is_identity(&self) -> bool {
126 self.r_func == SFilterDataComponent::Identity
127 && self.g_func == SFilterDataComponent::Identity
128 && self.b_func == SFilterDataComponent::Identity
129 && self.a_func == SFilterDataComponent::Identity
130 }
131
132 pub fn update(&self, mut request: GpuDataRequest) {
133 push_component_transfer_data(&self.r_func, &mut request);
134 push_component_transfer_data(&self.g_func, &mut request);
135 push_component_transfer_data(&self.b_func, &mut request);
136 push_component_transfer_data(&self.a_func, &mut request);
137 assert!(!self.is_identity());
138 }
139}
140
141impl SFilterDataTemplate {
142 pub fn update(
147 &mut self,
148 gpu_cache: &mut GpuCache,
149 ) {
150 if let Some(request) = gpu_cache.request(&mut self.gpu_cache_handle) {
151 self.data.update(request);
152 }
153 }
154}
155
156#[derive(Copy, Clone, Debug, MallocSizeOf)]
157#[cfg_attr(any(feature = "serde"), derive(Deserialize, Serialize))]
158pub enum FilterDataIntern {}
159
160impl intern::Internable for FilterDataIntern {
161 type Key = SFilterDataKey;
162 type StoreData = SFilterDataTemplate;
163 type InternData = ();
164 const PROFILE_COUNTER: usize = crate::profiler::INTERNED_FILTER_DATA;
165}
166
167fn push_component_transfer_data(
168 func_comp: &SFilterDataComponent,
169 request: &mut GpuDataRequest,
170) {
171 match func_comp {
172 SFilterDataComponent::Identity => {}
173 SFilterDataComponent::Table(values) |
174 SFilterDataComponent::Discrete(values) => {
175 assert!(values.len() > 0);
177 for i in 0 .. 64 {
178 let mut arr = [0.0 ; 4];
179 for j in 0 .. 4 {
180 if (values.len() == 1) || (i == 63 && j == 3) {
181 arr[j] = values[values.len()-1];
182 } else {
183 let c = ((4*i + j) as f32)/255.0;
184 match func_comp {
185 SFilterDataComponent::Table(_) => {
186 let n = (values.len()-1) as f32;
187 let k = (n * c).floor() as u32;
188 let ku = k as usize;
189 assert!(ku < values.len()-1);
190 arr[j] = values[ku] + (c*n - (k as f32)) * (values[ku+1] - values[ku]);
191 }
192 SFilterDataComponent::Discrete(_) => {
193 let n = values.len() as f32;
194 let k = (n * c).floor() as usize;
195 assert!(k < values.len());
196 arr[j] = values[k];
197 }
198 SFilterDataComponent::Identity |
199 SFilterDataComponent::Linear(_,_) |
200 SFilterDataComponent::Gamma(_,_,_) => {
201 unreachable!();
202 }
203 }
204
205 }
206 }
207
208 request.push(arr);
209 }
210 }
211 SFilterDataComponent::Linear(a, b) => {
212 request.push([*a, *b, 0.0, 0.0]);
213 }
214 SFilterDataComponent::Gamma(a, b, c) => {
215 request.push([*a, *b, *c, 0.0]);
216 }
217 }
218}