1use crate::{
2 makepad_live_compiler::{
3 LiveType,
4 LiveNode,
5 LiveModuleId,
6 LiveTypeInfo,
7 LiveNodeSliceApi
8 },
9 makepad_live_tokenizer::{LiveErrorOrigin, live_error_origin},
10 makepad_live_id::*,
11 makepad_math::*,
12 id_pool::*,
13 area::Area,
14 window::WindowId,
15 os::CxOsPass,
16 cx::Cx,
17 draw_list::DrawListId,
18 live_traits::*,
19 texture::{
20 Texture,
21 }
22};
23
24#[derive(Debug)]
25pub struct Pass(PoolId);
26
27#[derive(Clone, Copy, Debug, PartialEq)]
28pub struct PassId(pub (crate) usize);
29
30impl Pass {
31}
32
33#[derive(Default)]
34pub struct CxPassPool(pub (crate) IdPool<CxPass>);
35impl CxPassPool {
36 fn alloc(&mut self) -> Pass {
37 Pass(self.0.alloc())
38 }
39
40 pub fn id_iter(&self) -> PassIterator {
41 PassIterator {
42 cur: 0,
43 len: self.0.pool.len()
44 }
45 }
46}
47
48pub struct PassIterator {
49 cur: usize,
50 len: usize
51}
52
53impl Iterator for PassIterator {
54 type Item = PassId;
55 fn next(&mut self) -> Option<Self::Item> {
56 if self.cur >= self.len {
57 return None;
58 }
59 let cur = self.cur;
60 self.cur += 1;
61 Some(PassId(cur))
62 }
63}
64
65impl std::ops::Index<PassId> for CxPassPool {
66 type Output = CxPass;
67 fn index(&self, index: PassId) -> &Self::Output {
68 &self.0.pool[index.0].item
69 }
70}
71
72impl std::ops::IndexMut<PassId> for CxPassPool {
73 fn index_mut(&mut self, index: PassId) -> &mut Self::Output {
74 &mut self.0.pool[index.0].item
75 }
76}
77
78impl LiveHook for Pass {}
79impl LiveNew for Pass {
80 fn live_design_with(_cx:&mut Cx){}
81 fn new(cx: &mut Cx) -> Self {
82 let pass = cx.passes.alloc();
83 pass
84 }
85
86 fn live_type_info(_cx: &mut Cx) -> LiveTypeInfo {
87 LiveTypeInfo {
88 module_id: LiveModuleId::from_str(&module_path!()).unwrap(),
89 live_type: LiveType::of::<Self>(),
90 fields: Vec::new(),
91 live_ignore: true,
92 type_name: id_lut!(Pass)
94 }
95 }
96}
97
98impl LiveApply for Pass {
99
100 fn apply(&mut self, cx: &mut Cx, apply: &mut Apply, start_index: usize, nodes: &[LiveNode]) -> usize {
101
102 if !nodes[start_index].value.is_structy_type() {
103 cx.apply_error_wrong_type_for_struct(live_error_origin!(), start_index, nodes, live_id!(View));
104 return nodes.skip_node(start_index);
105 }
106
107 let mut index = start_index + 1;
108 loop {
109 if nodes[index].value.is_close() {
110 index += 1;
111 break;
112 }
113 match nodes[index].id {
114 live_id!(clear_color) => cx.passes[self.pass_id()].clear_color = LiveNew::new_apply_mut_index(cx, apply, &mut index, nodes),
115 live_id!(dont_clear) => cx.passes[self.pass_id()].dont_clear = LiveNew::new_apply_mut_index(cx, apply, &mut index, nodes),
116 _ => {
117 cx.apply_error_no_matching_field(live_error_origin!(), index, nodes);
118 index = nodes.skip_node(index);
119 }
120 }
121 }
122 return index;
123 }
124}
125
126impl Pass {
127 pub fn id_equals(&self, id:usize)->bool{
128 self.0.id == id
129 }
130
131 pub fn new_with_name(cx: &mut Cx, name:&str) -> Self {
132 let pass = cx.passes.alloc();
133 pass.set_pass_name(cx, name);
134 pass
135 }
136
137 pub fn pass_id(&self) -> PassId {PassId(self.0.id)}
138
139
140 pub fn set_as_xr_pass(&self, cx: &mut Cx) {
141 let cxpass = &mut cx.passes[self.pass_id()];
142 cxpass.parent = CxPassParent::Xr;
143 }
144
145 pub fn set_pass_parent(&self, cx: &mut Cx, pass: &Pass) {
146 let cxpass = &mut cx.passes[self.pass_id()];
147 cxpass.parent = CxPassParent::Pass(pass.pass_id());
148 }
149
150 pub fn set_pass_name(&self, cx: &mut Cx, name: &str) {
151 let cxpass = &mut cx.passes[self.pass_id()];
152 cxpass.debug_name = name.to_string();
153 }
154
155 pub fn pass_name<'a>(&self, cx: &'a mut Cx)->&'a str{
156 let cxpass = &mut cx.passes[self.pass_id()];
157 &cxpass.debug_name
158 }
159
160 pub fn set_size(&self, cx: &mut Cx, pass_size: DVec2) {
161 let mut pass_size = pass_size;
162 if pass_size.x < 1.0 {pass_size.x = 1.0};
163 if pass_size.y < 1.0 {pass_size.y = 1.0};
164 let cxpass = &mut cx.passes[self.pass_id()];
165 cxpass.pass_rect = Some(CxPassRect::Size(pass_size));
166 }
167
168 pub fn size(&self, cx: &mut Cx)->Option<DVec2> {
169 let cxpass = &mut cx.passes[self.pass_id()];
170 if let Some(CxPassRect::Size(size)) = &cxpass.pass_rect{
171 return Some(*size)
172 }
173 None
174 }
175
176 pub fn set_window_clear_color(&self, cx: &mut Cx, clear_color: Vec4) {
177 let cxpass = &mut cx.passes[self.pass_id()];
178 cxpass.clear_color = clear_color;
179 }
180
181 pub fn clear_color_textures(&self, cx: &mut Cx) {
182 let cxpass = &mut cx.passes[self.pass_id()];
183 cxpass.color_textures.truncate(0);
184 }
185
186 pub fn add_color_texture(&self, cx: &mut Cx, texture: &Texture, clear_color: PassClearColor) {
187 let cxpass = &mut cx.passes[self.pass_id()];
188 cxpass.color_textures.push(CxPassColorTexture {
189 texture: texture.clone(),
190 clear_color: clear_color
191 })
192 }
193
194 pub fn set_color_texture(&self, cx: &mut Cx, texture: &Texture, clear_color: PassClearColor) {
195 let cxpass = &mut cx.passes[self.pass_id()];
196 if cxpass.color_textures.len()!=0{
197 cxpass.color_textures[0] = CxPassColorTexture {
198 texture: texture.clone(),
199 clear_color: clear_color
200 }
201 }
202 else{
203 cxpass.color_textures.push(CxPassColorTexture {
204 texture: texture.clone(),
205 clear_color: clear_color
206 })
207 }
208 }
209
210 pub fn set_depth_texture(&self, cx: &mut Cx, texture: &Texture, clear_depth: PassClearDepth) {
211 let cxpass = &mut cx.passes[self.pass_id()];
212 cxpass.depth_texture = Some(texture.clone());
213 cxpass.clear_depth = clear_depth;
214 }
215
216 pub fn set_debug(&mut self, cx: &mut Cx, debug: bool) {
217 let cxpass = &mut cx.passes[self.pass_id()];
218 cxpass.debug = debug;
219 }
220
221
222 pub fn set_dpi_factor(&mut self, cx: &mut Cx, dpi: f64) {
223 let cxpass = &mut cx.passes[self.pass_id()];
224 cxpass.dpi_factor = Some(dpi);
225 }
226
227}
228
229#[derive(Clone)]
230pub enum PassClearColor {
231 InitWith(Vec4),
232 ClearWith(Vec4)
233}
234
235impl Default for PassClearColor {
236 fn default() -> Self {
237 Self::ClearWith(Vec4::default())
238 }
239}
240
241#[derive(Clone)]
242pub enum PassClearDepth {
243 InitWith(f32),
244 ClearWith(f32)
245}
246
247#[derive(Clone)]
248pub struct CxPassColorTexture {
249 pub clear_color: PassClearColor,
250 pub texture: Texture
251}
252
253#[derive(Default, Clone)]
254#[repr(C)]
255pub struct PassUniforms {
256 pub camera_projection: Mat4,
257 pub camera_projection_r: Mat4,
258 pub camera_view: Mat4,
259 pub camera_view_r: Mat4,
260 pub depth_projection: Mat4,
261 pub depth_projection_r: Mat4,
262 pub depth_view: Mat4,
263 pub depth_view_r: Mat4,
264 pub camera_inv: Mat4,
265 pub dpi_factor: f32,
266 pub dpi_dilate: f32,
267 pub time: f32,
268 pub pad2: f32
269}
270
271impl PassUniforms {
272 pub fn as_slice(&self) -> &[f32; std::mem::size_of::<PassUniforms>() >> 2] {
273 unsafe {std::mem::transmute(self)}
274 }
275}
276
277
278#[derive(Clone)]
279pub enum CxPassRect {
280 Area(Area),
281 AreaOrigin(Area, DVec2),
282 Size(DVec2)
283}
284
285#[derive(Clone)]
286pub struct CxPass {
287 pub debug: bool,
288 pub debug_name: String,
289 pub color_textures: Vec<CxPassColorTexture>,
290 pub depth_texture: Option<Texture>,
291 pub clear_depth: PassClearDepth,
292 pub dont_clear: bool,
293 pub depth_init: f64,
294 pub clear_color: Vec4,
295 pub dpi_factor: Option<f64>,
296 pub main_draw_list_id: Option<DrawListId>,
297 pub parent: CxPassParent,
298 pub paint_dirty: bool,
299 pub pass_rect: Option<CxPassRect>,
300 pub view_shift: DVec2,
301 pub view_scale: DVec2,
302 pub pass_uniforms: PassUniforms,
303 pub zbias_step: f32,
304 pub os: CxOsPass,
305}
306
307impl Default for CxPass {
308 fn default() -> Self {
309 CxPass {
310 debug: false,
311 dont_clear: false,
312 debug_name: String::new(),
313 zbias_step: 0.001,
314 pass_uniforms: PassUniforms::default(),
315 color_textures: Vec::new(),
316 depth_texture: None,
317 dpi_factor: None,
318 clear_depth: PassClearDepth::ClearWith(1.0),
319 clear_color: Vec4::default(),
320 depth_init: 1.0,
321 main_draw_list_id: None,
322 view_shift: dvec2(0.0,0.0),
323 view_scale: dvec2(1.0,1.0),
324 parent: CxPassParent::None,
325 paint_dirty: false,
326 pass_rect: None,
327 os: CxOsPass::default()
328 }
329 }
330}
331
332#[derive(Clone, Debug)]
333pub enum CxPassParent {
334 Xr,
335 Window(WindowId),
336 Pass(PassId),
337 None
338}
339
340impl CxPass {
341 pub fn set_time(&mut self, time: f32) {
342 self.pass_uniforms.time = time;
343 }
344
345 pub fn set_dpi_factor(&mut self, dpi_factor: f64) {
346 let dpi_dilate = (2. - dpi_factor).max(0.).min(1.);
347 self.pass_uniforms.dpi_factor = dpi_factor as f32;
348 self.pass_uniforms.dpi_dilate = dpi_dilate as f32;
349 }
350
351 pub fn set_ortho_matrix(&mut self, offset: DVec2, size: DVec2) {
352
353 let offset = offset + self.view_shift;
354 let size = size * self.view_scale;
355
356 let ortho = Mat4::ortho(
357 offset.x as f32,
358 (offset.x + size.x) as f32,
359 offset.y as f32,
360 (offset.y + size.y) as f32,
361 100.,
362 -100.,
363 1.0,
364 1.0
365 );
366 self.pass_uniforms.camera_projection = ortho;
367 self.pass_uniforms.camera_view = Mat4::identity();
368 }
369}