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