makepad_platform/
pass.rs

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            //kind: LiveTypeKind::Object,
93            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}