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 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 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 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 }
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}