makepad_platform/
debug.rs

1use std::cell::RefCell;
2use std::rc::Rc;
3use crate::makepad_math::{Rect, Vec4, DVec2};
4use crate::cx::Cx;
5use crate::area::Area;
6use crate::draw_list::DrawListId;
7use std::fmt::Write;
8
9#[derive(Clone, Default)]
10pub struct DebugInner {
11    pub areas: Vec<(Area, DVec2, DVec2, Vec4)>,
12    pub rects: Vec<(Rect,  Vec4)>,
13    pub points: Vec<(DVec2, Vec4)>,
14    pub labels: Vec<(DVec2, Vec4, String)>,
15    pub marker: u64,
16}
17
18#[derive(Clone, Default)]
19pub struct Debug(Rc<RefCell<DebugInner >>);
20
21impl Debug {
22
23    pub fn marker(&self)->u64{
24        let inner = self.0.borrow();
25        inner.marker
26    }
27    
28    pub fn set_marker(&mut self, v:u64){
29        let mut inner = self.0.borrow_mut();
30        inner.marker = v
31    }
32    
33    pub fn point(&self, p: DVec2, color: Vec4) {
34        let mut inner = self.0.borrow_mut();
35        inner.points.push((p, color));
36    }
37    
38    pub fn label(&self, p: DVec2, color: Vec4, label:String) {
39        let mut inner = self.0.borrow_mut();
40        inner.labels.push((p, color,label));
41    }
42    
43    pub fn rect(&self, p: Rect, color: Vec4) {
44        let mut inner = self.0.borrow_mut();
45        inner.rects.push((p, color));
46    }
47    
48    pub fn area(&self, area:Area, color: Vec4) {
49        let mut inner = self.0.borrow_mut();
50        inner.areas.push((area, DVec2::default(),DVec2::default(), color));
51    }
52    
53    pub fn area_offset(&self, area:Area, tl:DVec2, br:DVec2, color: Vec4) {
54        let mut inner = self.0.borrow_mut();
55        inner.areas.push((area,tl,br,color));
56    }
57            
58    pub fn has_data(&self)->bool{
59        let inner = self.0.borrow();
60        !inner.points.is_empty() || !inner.rects.is_empty() || !inner.labels.is_empty() || !inner.areas.is_empty()
61    }
62    
63    pub fn take_rects(&self)->Vec<(Rect, Vec4)>{
64        let mut inner = self.0.borrow_mut();
65        let mut swap = Vec::new();
66        std::mem::swap(&mut swap, &mut inner.rects);
67        swap
68    }
69
70    pub fn take_points(&self)->Vec<(DVec2, Vec4)>{
71        let mut inner = self.0.borrow_mut();
72        let mut swap = Vec::new();
73        std::mem::swap(&mut swap, &mut inner.points);
74        swap
75    }
76
77    pub fn take_labels(&self)->Vec<(DVec2, Vec4, String)>{
78        let mut inner = self.0.borrow_mut();
79        let mut swap = Vec::new();
80        std::mem::swap(&mut swap, &mut inner.labels);
81        swap
82    }
83    
84    pub fn take_areas(&self)->Vec<(Area, DVec2, DVec2, Vec4)>{
85        let mut inner = self.0.borrow_mut();
86        let mut swap = Vec::new();
87        std::mem::swap(&mut swap, &mut inner.areas);
88        swap
89    }
90}
91
92impl Cx{
93    
94    pub fn debug_draw_tree(&self, dump_instances: bool, draw_list_id: DrawListId) {
95        fn debug_draw_tree_recur(cx: &Cx, dump_instances: bool, s: &mut String, draw_list_id: DrawListId, depth: usize) {
96            //if draw_list_id >= cx.draw_lists.len() {
97            //    writeln!(s, "---------- Drawlist still empty ---------").unwrap();
98            //    return
99            //}
100            let mut indent = String::new();
101            for _i in 0..depth {
102                indent.push_str("|   ");
103            }
104            let draw_items_len = cx.draw_lists[draw_list_id].draw_items.len();
105            //if draw_list_id == 0 {
106            //    writeln!(s, "---------- Begin Debug draw tree for redraw_id: {} ---------", cx.redraw_id).unwrap();
107            // }
108            //let rect = cx.draw_lists[draw_list_id].rect;
109            //let scroll = cx.draw_lists[draw_list_id].get_local_scroll();
110            writeln!(
111                s,
112                "{}{} {:?}: len:{}",
113                indent,
114                cx.draw_lists[draw_list_id].debug_id,
115                draw_list_id,
116                draw_items_len,
117            ).unwrap();
118            indent.push_str("  ");
119            let mut indent = String::new();
120            for _i in 0..depth + 1 {
121                indent.push_str("|   ");
122            }
123            for draw_item_id in 0..draw_items_len {
124                if let Some(sub_list_id) = cx.draw_lists[draw_list_id].draw_items[draw_item_id].sub_list() {
125                    debug_draw_tree_recur(cx, dump_instances, s, sub_list_id, depth + 1);
126                }
127                else {
128                    let cxview = &cx.draw_lists[draw_list_id];
129                    let darw_item = &cxview.draw_items[draw_item_id];
130                    let draw_call = darw_item.draw_call().unwrap();
131                    let sh = &cx.draw_shaders.shaders[draw_call.draw_shader.draw_shader_id];
132                    let slots = sh.mapping.instances.total_slots;
133                    let instances = darw_item.instances.as_ref().unwrap().len() / slots;
134                    writeln!(
135                        s,
136                        "{}{}({}) sid:{} inst:{}",
137                        indent,
138                        draw_call.options.debug_id.unwrap_or(sh.class_prop),
139                        sh.type_name,
140                        draw_call.draw_shader.draw_shader_id,
141                        instances,
142                    ).unwrap();
143                    // lets dump the instance geometry
144                    if dump_instances {
145                        for inst in 0..instances.min(1) {
146                            let mut out = String::new();
147                            let mut off = 0;
148                            for input in &sh.mapping.instances.inputs {
149                                let buf = darw_item.instances.as_ref().unwrap();
150                                match input.slots {
151                                    1 => out.push_str(&format!("{}:{} ", input.id, buf[inst * slots + off])),
152                                    2 => out.push_str(&format!("{}:v2({},{}) ", input.id, buf[inst * slots + off], buf[inst * slots + 1 + off])),
153                                    3 => out.push_str(&format!("{}:v3({},{},{}) ", input.id, buf[inst * slots + off], buf[inst * slots + 1 + off], buf[inst * slots + 1 + off])),
154                                    4 => out.push_str(&format!("{}:v4({},{},{},{}) ", input.id, buf[inst * slots + off], buf[inst * slots + 1 + off], buf[inst * slots + 2 + off], buf[inst * slots + 3 + off])),
155                                    _ => {}
156                                }
157                                off += input.slots;
158                            }
159                            writeln!(s, "  {}instance {}: {}", indent, inst, out).unwrap();
160                        }
161                    }
162                }
163            }
164            //if draw_list_id == 0 {
165            //    writeln!(s, "---------- End Debug draw tree for redraw_id: {} ---------", cx.redraw_id).unwrap();
166            //}
167        }
168        
169        let mut s = String::new();
170        debug_draw_tree_recur(self, dump_instances, &mut s, draw_list_id, 0);
171        log!("{}", s);
172    }
173
174}