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