Pixel-Composer/scripts/panel_profile_render/panel_profile_render.gml
2024-12-07 16:35:29 +07:00

793 lines
No EOL
28 KiB
Text

globalvar PROFILER_STAT, PROFILER_DATA;
PROFILER_STAT = 0;
PROFILER_DATA = [];
function Panel_Profile_Render() : PanelContent() constructor {
title = __txt("Render Profiler");
showHeader = true;
padding = ui(4);
auto_pin = true;
w = ui(800);
h = ui(500);
list_w = ui(300);
detail_w = w - list_w - padding * 2 - ui(8);
content_h = h - ui(40) - padding;
io_label_y = 0;
run = 0;
render_time = 0;
render_drag = false;
report_selecting = noone;
report_clicked = noone;
filter_node = noone;
set_selecting_node = false;
graph_set_latest = noone;
show_io = true;
show_log_level = 1;
filter_list_string = "";
tb_list = new textBox( TEXTBOX_INPUT.text, function(str) /*=>*/ { filter_list_string = str; searchData(); })
.setFont(f_p3)
.setAutoUpdate()
.setEmpty()
filter_content_string = "";
tb_content = new textBox( TEXTBOX_INPUT.text, function(str) /*=>*/ { filter_content_string = str; })
.setFont(f_p3)
.setAutoUpdate()
.setEmpty()
function draw_surface_debug(surf, xx, yy, w, h, color = c_white, alpha = 1) {
if(!is_surface(surf)) {
draw_sprite_stretched_add(THEME.s_box_r2, 1, xx, yy, w, h, c_white, .15);
draw_set_text(f_p3, fa_center, fa_center, COLORS._main_text_sub);
draw_text_add(xx + w / 2, yy + h / 2, string(surf));
return;
}
var sw = surface_get_width(surf);
var sh = surface_get_height(surf);
var sd = surface_get_format(surf);
var ss = min((w - ui(144)) / sw, h / sh);
var sx = xx;
var sy = yy + h / 2 - sh * ss / 2
draw_surface_ext(surf, sx, sy, ss, ss, 0, color, alpha);
draw_sprite_stretched_add(THEME.s_box_r2, 1, sx, sy, sw * ss, sh * ss, c_white, .05);
var _tx = sx + sw * ss + ui(8);
var _ty = yy;
draw_set_text(f_p3, fa_left, fa_top, COLORS._main_text_sub);
draw_text_add(_tx, _ty, $"{surf}"); _ty += ui(16);
draw_text_add(_tx, _ty, $"Dimension : {sw} x {sh}"); _ty += ui(16);
draw_text_add(_tx, _ty, $"Format : {surface_format_string(sd)}"); _ty += ui(16);
draw_text_add(_tx, _ty, $"Size : {sw * sh * surface_format_get_bytes(sd)} bytes"); _ty += ui(16);
}
function searchData() {
for( var i = 0, n = array_length(PROFILER_DATA); i < n; i++ ) {
var _report = PROFILER_DATA[i];
_report.search_res = true;
if(_report.type != "render") continue;
var _node = _report.node;
if(filter_node != noone && filter_node != _node)
_report.search_res = false;
if(filter_list_string != "" && string_pos(string_lower(filter_list_string), string_lower(_report.search_string)) == 0)
_report.search_res = false;
}
}
function onResize() {
padding = in_dialog? ui(4) : ui(8);
list_w = ui(300);
detail_w = w - list_w - padding * 2 - ui(8);
content_h = h - ui(40) - padding;
sc_profile_list.resize(list_w - ui(8), content_h - ui(8));
sc_profile_detail.resize(detail_w - ui(8), content_h - ui(8));
}
function setReport(_report) {
report_selecting = _report;
if(_report == noone) return;
if(_report.type == "render" && set_selecting_node)
PANEL_GRAPH.nodes_selecting = [ _report.node ];
}
count_render_event = 0;
count_message_event = 0;
node_render_time = 0;
node_render_time_type = {};
node_render_rtim_type = {};
node_render_time_amo = {};
node_render_time_type_sorted = [];
pie_selecting = noone;
function summarize() {
count_render_event = 0;
count_message_event = 0;
node_render_time = 0;
node_render_time_type = {};
node_render_rtim_type = {};
node_render_time_amo = {};
node_render_time_type_sorted = [];
for( var i = 0, n = array_length(PROFILER_DATA); i < n; i++ ) {
var _report = PROFILER_DATA[i];
var _rtype = _report.type;
switch(_rtype) {
case "render" :
var _node = _report.node;
var _time = _report.time;
node_render_time += _time;
count_render_event++;
var _typ = instanceof(_node);
node_render_time_type[$ _typ] = struct_try_get(node_render_time_type, _typ, 0) + _time;
node_render_rtim_type[$ _typ] = struct_try_get(node_render_rtim_type, _typ, 0) + _report.renderTime;
node_render_time_amo[$ _typ] = struct_try_get(node_render_time_amo, _typ, 0) + 1;
break;
case "message" : count_message_event++; break;
}
}
var _pr = ds_priority_create();
var _nods = variable_struct_get_names(node_render_time_type);
for( var i = 0, n = array_length(_nods); i < n; i++ ) {
var _typ = _nods[i];
var _c = make_color_hsv(random(255), 160, 160);
ds_priority_add(_pr, [_typ, node_render_time_type[$ _typ], _c], node_render_time_type[$ _typ]);
}
var sz = ds_priority_size(_pr);
var i = 0;
repeat(sz) node_render_time_type_sorted[i++] = ds_priority_delete_max(_pr);
ds_priority_destroy(_pr);
}
sc_profile_list = new scrollPane(list_w - ui(8), content_h - ui(8), function(_y, _m) {
draw_clear_alpha(COLORS.panel_bg_clear_inner, 1);
var _h = ui(8);
var yy = _y;
var _ww = sc_profile_list.surface_w;
var _sh = sc_profile_list.surface_h;
var _hovering = sc_profile_list.hover;
var _wh = ui(24);
gpu_set_texfilter(true);
if(mouse_release(mb_left)) report_clicked = noone;
for( var i = 0, n = array_length(PROFILER_DATA); i < n; i++ ) {
var _report = PROFILER_DATA[i];
var _rtype = _report.type;
var _sel = report_selecting == _report;
var _hov = point_in_rectangle(_m[0], _m[1], 0, yy, _ww, yy + _wh);
var _cy = yy + _wh / 2;
var _draw = _cy > -_wh && _cy < _sh + _wh;
if(_draw && (_hov || _sel)) draw_sprite_stretched_ext(THEME.s_box_r5_clr, 1, 0, yy, _ww, _wh + 1, _sel? CDEF.main_ltgrey : CDEF.main_grey);
if(_rtype == "render") {
if(_report.search_res == false) continue;
var _node = _report.node;
var _text = _node.getFullName();
var cc = COLORS._main_text_sub;
if(report_selecting != noone && report_selecting.node == _report.node)
cc = COLORS._main_text;
if(_sel) cc = COLORS._main_text_accent;
if(_draw) {
draw_set_text(f_p2, fa_left, fa_center, cc);
draw_text_add(ui(8), _cy, $"Render {_text}");
}
} else if(_rtype == "message") {
if(_report.level > show_log_level) continue;
if(_draw) {
var _text = _report.text;
draw_sprite_ext(THEME.noti_icon_log, 0, ui(16), _cy, .75, .75, 0, c_white, 1);
draw_set_text(f_p2, fa_left, fa_center, _sel? COLORS._main_text_accent : COLORS._main_text);
draw_text_add(ui(32), _cy, _text);
}
}
if(_hov) {
if(mouse_press(mb_left, pFOCUS)) {
setReport(_sel? noone : _report);
report_clicked = _report;
} else if(mouse_click(mb_left, pFOCUS) && report_clicked != noone && report_clicked != _report) {
setReport(_report);
report_clicked = _report;
}
}
_h += _wh;
yy += _wh;
}
gpu_set_texfilter(false);
return _h;
});
__sp_ih = 0;
__sp_oh = 0;
sc_profile_detail = new scrollPane(detail_w - ui(8), content_h - ui(8), function(_y, _m) {
draw_clear_alpha(COLORS.panel_bg_clear_inner, 1);
var _h = 0;
var _ww = sc_profile_detail.surface_w;
var _hh = sc_profile_detail.surface_h;
var _hov = sc_profile_detail.hover;
if(report_selecting == noone) {
if(run == 0) {
draw_set_text(f_p2, fa_left, fa_top, COLORS._main_text_sub);
draw_text_add(ui(8), ui(8), $"Press render to start capturing events.");
return 0;
}
var _tx = ui(8);
var _ty = _y + ui(8);
draw_set_text(f_p2, fa_left, fa_top, COLORS._main_text_sub);
draw_text_add(_tx, _ty, $"{count_render_event} render events");
_ty += ui(20); _h += ui(20);
draw_text_add(_tx, _ty, $"Render time : {render_time / 1000}ms ({node_render_time} / {render_time})");
_ty += ui(28); _h += ui(28);
var _a = 90;
var pr = ui(120);
var px = ui(16) + pr;
var py = max(ui(8), _ty) + pr;
var tx_amo = px + pr + ui(32);
var tx_name = tx_amo + ui(40);
var tx_time = tx_name + ui(200);
var tx_per = tx_time + ui(80);
var tx_pern = tx_per + ui(80);
var tx_rtim = tx_pern + ui(80);
draw_set_text(f_p3, fa_left, fa_top, COLORS._main_text_sub);
draw_text_add(tx_name, _ty, "type");
draw_set_halign(fa_right);
draw_text_add(tx_time + ui(80 - 8), _ty, "time (ns)");
draw_text_add(tx_per + ui(80 - 8), _ty, "%");
draw_text_add(tx_pern + ui(80 - 8), _ty, "time/node");
draw_text_add(tx_rtim + ui(80 - 8), _ty, "render");
if(_hov && point_in_rectangle(_m[0], _m[1], tx_name, _ty, tx_time, _ty + ui(19))) TOOLTIP = "Node type";
if(_hov && point_in_rectangle(_m[0], _m[1], tx_time, _ty, tx_per, _ty + ui(19))) TOOLTIP = "Total processing time (including graph propagation, debug data collection)";
if(_hov && point_in_rectangle(_m[0], _m[1], tx_per, _ty, tx_pern, _ty + ui(19))) TOOLTIP = "Total time as percentage";
if(_hov && point_in_rectangle(_m[0], _m[1], tx_pern, _ty, tx_rtim, _ty + ui(19))) TOOLTIP = "Total time per node";
if(_hov && point_in_rectangle(_m[0], _m[1], tx_rtim, _ty, tx_rtim + ui(80), _ty + ui(19))) TOOLTIP = "Processing time";
_ty += ui(20); _h += ui(20);
var _pie_selecting = noone;
for( var i = 0, n = array_length(node_render_time_type_sorted); i < n; i++ ) {
var _timn = node_render_time_type_sorted[i];
var _node = _timn[0];
var _time = _timn[1];
var _colr = _timn[2];
var _as = _time / node_render_time * 360;
var _at = _a + _as;
draw_set_color(_colr);
if(pie_selecting != noone) draw_set_alpha(0.25 + 0.75 * (_node == pie_selecting));
draw_circle_angle(px, py, pr, _a, _at);
draw_set_alpha(1);
_a = _at;
if(_ty >= -16 && _ty <= _hh + 16) {
var _amo = node_render_time_amo[$ _node];
var _rtm = node_render_rtim_type[$ _node];
draw_set_text(f_p3, fa_right, fa_top, COLORS._main_text_sub);
draw_text_add(tx_amo + ui(40 - 8), _ty, _amo);
draw_set_color(_node == pie_selecting? COLORS._main_text_accent : COLORS._main_text);
draw_set_halign(fa_left);
draw_text_add(tx_name, _ty, _node);
draw_set_halign(fa_right);
draw_text_add(tx_time + ui(80 - 8), _ty, _time);
draw_text_add(tx_per + ui(80 - 8), _ty, _time / node_render_time * 100);
draw_text_add(tx_pern + ui(80 - 8), _ty, round(_time / _amo));
draw_text_add(tx_rtim + ui(80 - 8), _ty, _rtm);
if(_hov && point_in_rectangle(_m[0], _m[1], tx_amo, _ty, _ww, _ty + ui(19)))
_pie_selecting = _node;
}
_ty += ui(20); _h += ui(20);
}
pie_selecting = _pie_selecting;
_ty += ui(20); _h += ui(20);
return _h;
}
var _hovering = sc_profile_detail.hover;
var _report = report_selecting;
var _rtype = _report.type;
if(_rtype == "render") {
var _node = _report.node;
var _time = _report.time;
var _inputs = _report.inputs;
var _outputs = _report.outputs;
var _tx = ui(8);
var _ty = _y + ui(8);
draw_set_text(f_p1, fa_left, fa_top, COLORS._main_text);
draw_text_add(_tx, _ty, $"Render {_node.getFullName()}");
_ty += ui(24); _h += ui(24);
draw_set_text(f_p2, fa_left, fa_top, COLORS._main_text_sub);
draw_text_add(_tx, _ty, $"Render time : {_time / 1000}ms ({_time})");
_ty += ui(28); _h += ui(28);
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
var _iw = _ww / 2 - ui(8);
var _ix = ui(8);
var _ox = ui(8) + _iw + ui(4);
var _io_label_y = max(_ty, ui(8));
_ty += ui(28); _h += ui(28);
var _yy = _ty;
var _ih = 0;
var _x0 = _ix;
var _x1 = _ix + _iw;
if(show_io) {
for( var i = 0, n = array_length(_inputs); i < n; i++ ) {
var _j = _node.inputs[i];
var _v = _inputs[i];
var _type = _j.type;
var _wh = ui(20);
if(filter_content_string != "" && string_pos(string_lower(filter_content_string), string_lower(_j.name)) == 0) continue;
draw_set_text(f_p3, fa_left, fa_top, COLORS._main_text_sub);
draw_text_add(_x0, _yy, _j.name);
var _vx = _x0 + ui(8);
var _vy = _yy + ui(16);
var _vw = _iw - ui(16);
switch(_type) {
case VALUE_TYPE.surface :
draw_surface_debug(_v, _vx, _vy, _vw, ui(128));
_wh += ui(128);
break;
default :
var _tx = string(_v);
draw_set_text(f_p2, fa_left, fa_top, COLORS._main_text);
draw_text_ext_add(_vx, _vy, _tx, -1, _vw);
_wh += string_height_ext(_tx, -1, _vw);
break;
}
_yy += _wh + ui(4);
_ih += _wh + ui(4);
}
}
var _fy = io_label_y + ui(28);
var _yy = min(max(_ty, _fy), _ty + max(0, __sp_ih - __sp_oh));
var _oh = 0;
var _x0 = _ox;
var _x1 = _ox + _iw;
if(show_io) {
for( var i = 0, n = array_length(_outputs); i < n; i++ ) {
var _j = _node.outputs[i];
var _v = _outputs[i];
var _type = _j.type;
var _wh = ui(20);
if(filter_content_string != "" && string_pos(string_lower(filter_content_string), string_lower(_j.name)) == 0) continue;
draw_set_text(f_p3, fa_left, fa_top, COLORS._main_text_sub);
draw_text_add(_x0, _yy, _j.name);
var _vx = _x0 + ui(8);
var _vy = _yy + ui(16);
var _vw = _iw - ui(8);
switch(_type) {
case VALUE_TYPE.surface :
draw_surface_debug(_v, _vx, _vy, _vw, ui(128));
_wh += ui(128);
break;
default :
var _tx = string(_v);
draw_set_text(f_p2, fa_left, fa_top, COLORS._main_text);
draw_text_ext_add(_vx, _vy, _tx, -1, _vw);
_wh += string_height_ext(_tx, -1, _vw);
break;
}
_yy += _wh;
_oh += _wh;
}
}
__sp_ih = _ih;
__sp_oh = _oh;
_h += max(_ih, _oh) + ui(8);
_ty += max(_ih, _oh) + ui(8);
io_label_y = min(_io_label_y, _ty - ui(32));
draw_set_color(COLORS.panel_bg_clear_inner);
draw_rectangle(_ix - ui(4), io_label_y - ui(10), _ix + _iw - ui(4), io_label_y + ui(16), false);
draw_rectangle(_ox - ui(4), io_label_y - ui(10), _ox + _iw - ui(4), io_label_y + ui(16), false);
var _hov = _hovering && point_in_rectangle(_m[0], _m[1], 0, io_label_y, _ww, io_label_y + ui(24));
if(_hov && mouse_press(mb_left)) show_io = !show_io;
draw_set_text(f_p2, fa_left, fa_top, COLORS._main_text_sub);
draw_sprite_stretched_ext(THEME.s_box_r5_clr, 1, _ix - ui(4), io_label_y - ui(2), _iw, ui(24), _hov? CDEF.main_ltgrey : CDEF.main_grey);
draw_sprite_ext(THEME.arrow, show_io * 3, _ix + ui(12), io_label_y + ui(10), 1, 1, 0, CDEF.main_grey, 1);
draw_text_add(_ix + ui(28), io_label_y, $"Inputs [{array_length(_inputs)}] {filter_content_string == ""? "" : " (filtered)"}");
draw_sprite_stretched_ext(THEME.s_box_r5_clr, 1, _ox - ui(4), io_label_y - ui(2), _iw, ui(24), _hov? CDEF.main_ltgrey : CDEF.main_grey);
draw_text_add(_ox + ui(8), io_label_y, $"Outputs [{array_length(_outputs)}] {filter_content_string == ""? "" : " (filtered)"}");
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
var _queue = _report.queue;
draw_sprite_stretched_ext(THEME.s_box_r5_clr, 1, ui(4), _ty - ui(2), _ww - ui(12), ui(24), CDEF.main_grey);
draw_set_text(f_p2, fa_left, fa_top, COLORS._main_text_sub);
draw_text_add(ui(16), _ty, $"Current queue [{array_length(_queue)}]");
_ty += ui(32); _h += ui(48);
var _qh = ui(20);
var _qx = ui(8);
var _qy = _ty;
var _qhh = _qh;
_h += _qh + ui(4);
draw_set_text(f_p3, fa_left, fa_center, COLORS._main_text_sub);
for( var i = 0, n = array_length(_queue); i < n; i++ ) {
var _qnode = _queue[i];
var _n = _qnode.getFullName();
var _qw = string_width(_n);
if(_qx + _qw > _ww - ui(12)) {
_qx = ui(8);
_qy += _qh + ui(4);
_h += _qh + ui(4);
_qhh += _qh + ui(4);
}
var cc = COLORS._main_icon;
if(filter_list_string != "" && string_pos(string_lower(filter_list_string), string_lower(_n)) != 0)
cc = COLORS._main_accent;
draw_sprite_stretched_ext(THEME.s_box_r2, 1, _qx, _qy, _qw + ui(12), _qh, cc, .5);
draw_set_color(cc);
draw_text_add(_qx + ui(6), _qy + _qh / 2, _n);
_qx += _qw + ui(12 + 4);
}
_ty += array_length(_queue)? _qhh + ui(16) : ui(4);
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
var _nextx = _report.nextn;
draw_sprite_stretched_ext(THEME.s_box_r5_clr, 1, ui(4), _ty - ui(2), _ww - ui(12), ui(24), CDEF.main_grey);
draw_set_text(f_p2, fa_left, fa_top, COLORS._main_text_sub);
draw_text_add(ui(16), _ty, $"Next queue [{array_length(_nextx)}]");
_ty += ui(32); _h += ui(48);
var _qh = ui(20);
var _qx = ui(8);
var _qy = _ty;
var _qhh = _qh;
_h += _qh + ui(4);
draw_set_text(f_p3, fa_left, fa_center, COLORS._main_text_sub);
for( var i = 0, n = array_length(_nextx); i < n; i++ ) {
var _qnode = _nextx[i];
var _n = _qnode.getFullName();
var _qw = string_width(_n);
if(_qx + _qw > _ww - ui(12)) {
_qx = ui(8);
_qy += _qh + ui(4);
_h += _qh + ui(4);
_qhh += _qh + ui(4);
}
var cc = COLORS._main_icon;
if(filter_list_string != "" && string_pos(string_lower(filter_list_string), string_lower(_n)) != 0)
cc = COLORS._main_accent;
draw_sprite_stretched_ext(THEME.s_box_r2, 1, _qx, _qy, _qw + ui(12), _qh, cc, .5);
draw_set_color(cc);
draw_text_add(_qx + ui(6), _qy + _qh / 2, _n);
_qx += _qw + ui(12 + 4);
}
_ty += array_length(_nextx)? _qhh + ui(16) : ui(4);
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
} else if(_rtype == "message") {
var _mesg = _report.text;
var _node = _report.node;
var _tx = ui(8);
var _ty = ui(8);
draw_set_text(f_p1, fa_left, fa_top, COLORS._main_text);
draw_text_ext_add(ui(8), _ty, _mesg, -1, _ww - ui(16));
_ty += ui(24);
draw_set_text(f_p2, fa_left, fa_top, COLORS._main_text_sub);
draw_text_add(_tx, _ty, $"From : {_node.getFullName()}");
}
return _h;
});
function drawContent(panel) {
draw_clear_alpha(COLORS.panel_bg_clear, 1);
var _pd = padding;
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
var _bs = ui(28);
var _bx = _pd;
var _by = _pd;
if(buttonInstant(THEME.button_hide, _bx, _by, _bs, _bs, [ mx, my ], pFOCUS, pHOVER, "Render all", s_run, 1, COLORS._main_value_positive, 1, 1) == 2) {
PROFILER_STAT = 1;
PROFILER_DATA = [];
setReport(noone);
var _t = get_timer();
Render();
render_time = get_timer() - _t;
summarize();
PROFILER_STAT = 0;
run++;
}
_bx += _bs + ui(2);
if(buttonInstant(THEME.button_hide, _bx, _by, _bs, _bs, [ mx, my ], pFOCUS, pHOVER, "Render partial", s_run_partial, 1, COLORS._main_value_positive, 1, 1) == 2) {
PROFILER_STAT = 1;
PROFILER_DATA = [];
setReport(noone);
var _t = get_timer();
Render(true);
render_time = get_timer() - _t;
summarize();
PROFILER_STAT = 0;
run++;
}
_bx += _bs + ui(4);
var _bxl = _bx;
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
tb_list.setFocusHover(pFOCUS, pHOVER); tb_list.register();
tb_content.setFocusHover(pFOCUS, pHOVER); tb_content.register();
var _bs = ui(28);
var _bx = _pd + list_w - _bs;
var _by = _pd;
if(buttonInstant(THEME.button_hide, _bx, _by, _bs, _bs, [ mx, my ], pFOCUS, pHOVER, $"Log level {show_log_level}", s_filter_log_level, show_log_level, COLORS._main_icon, 1, 1) == 2)
show_log_level = (show_log_level + 1) % 5;
_bx -= _bs + ui(4);
if(report_selecting == noone)
draw_sprite_ext(s_filter_node, 0, _bx + _bs / 2, _by + _bs / 2, 1, 1, 0, COLORS._main_icon, 0.25);
else if(buttonInstant(THEME.button_hide, _bx, _by, _bs, _bs, [ mx, my ], pFOCUS, pHOVER, "Filter node", s_filter_node, 0, filter_node == noone? COLORS._main_icon : COLORS._main_accent, 1, 1) == 2) {
filter_node = filter_node == report_selecting.node? noone : report_selecting.node;
searchData();
}
_bx -= _bs + ui(4);
if(buttonInstant(THEME.button_hide, _bx, _by, _bs, _bs, [ mx, my ], pFOCUS, pHOVER, "Match selecting", s_filter_node_inspector, 0, set_selecting_node? COLORS._main_accent : COLORS._main_icon, 1, 1) == 2)
set_selecting_node = !set_selecting_node;
_bx -= ui(4);
var _tw = _bx - _bxl;
tb_list.draw(_bx - _tw, _by + ui(2), _tw, _bs - ui(4), filter_list_string, [ mx, my ]);
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
var _bs = ui(28);
var _bx = _pd + list_w + ui(8);
var _by = _pd;
draw_sprite_ext(s_filter, 0, _bx + _bs / 2, _by + _bs / 2, 1, 1, 0, COLORS._main_icon, 0.25);
_bx += _bs + ui(4);
tb_content.draw(_bx, _by + ui(2), ui(128), _bs - ui(4), filter_content_string, [ mx, my ]);
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
var _px0 = _bx + ui(128) + ui(32);
var _px1 = w - _pd;
var _py0 = _by + ui(2);
var _py1 = _by + _bs - ui(2);
var _pw = _px1 - _px0;
var _ph = _py1 - _py0;
draw_sprite_stretched_ext(THEME.s_box_r2, 0, _px0, _py0, _pw, _ph, COLORS._main_icon_dark, 1);
var _selected_time = 0;
var _running_time = 0;
for( var i = 0, n = array_length(PROFILER_DATA); i < n; i++ ) {
var _report = PROFILER_DATA[i];
var _rtype = _report.type;
if(_report == report_selecting) _selected_time = _running_time;
if(_rtype == "render") {
var _node = _report.node;
var _time = _report.time;
_running_time += _time;
}
}
if(node_render_time > 0) {
var _running_time = 0;
if(mouse_release(mb_left)) render_drag = false;
for( var i = 0, n = array_length(PROFILER_DATA); i < n; i++ ) {
var _report = PROFILER_DATA[i];
var _rtype = _report.type;
var _rx = _px0 + (_running_time / node_render_time) * _pw;
if(_rtype == "render") {
draw_set_color(COLORS._main_icon);
draw_set_alpha(0.25);
draw_line(_rx, _py0, _rx, _py0 + _ph - 2);
draw_set_alpha(1);
var _time = _report.time;
_running_time += _time;
var _rx1 = _px0 + (_running_time / node_render_time) * _pw;
if((pHOVER && point_in_rectangle(mx, my, _rx, _py0, _rx1, _py1) || (render_drag && mx >= _rx && mx < _rx1))) {
TOOLTIP = $"Render {_report.node.getFullName()}";
if(mouse_click(mb_left, pFOCUS) || render_drag) {
render_drag = true;
setReport(_report);
}
}
if(report_selecting != noone && report_selecting.node == _report.node)
draw_sprite_stretched_ext(THEME.s_box_r2, 0, _rx, _py0, _rx1 - _rx, _ph, COLORS._main_icon, .2);
}
if(_rtype == "message") {
if(_report.level > show_log_level) continue;
draw_set_color(COLORS._main_accent);
if(pHOVER && point_in_rectangle(mx, my, _rx - 4, _py0, _rx + 4, _py1)) {
TOOLTIP = _report.text;
draw_line_width(_rx, _py0, _rx, _py0 + _ph - 2, 2);
} else
draw_line(_rx, _py0, _rx, _py0 + _ph - 2);
}
}
if(report_selecting != noone && report_selecting.type == "render") {
var _time = report_selecting.time;
var _rx = _px0 + (_selected_time / node_render_time) * _pw;
var _rw = (_time / node_render_time) * _pw;
draw_sprite_stretched_ext(THEME.s_box_r2, 0, _rx, _py0, _rw, _ph, COLORS._main_icon, 1);
}
}
draw_sprite_stretched_add(THEME.s_box_r2, 1, _px0, _py0, _pw, _ph, COLORS._main_icon, .3);
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
var ndx = _pd;
var ndy = ui(40);
var ndw = list_w;
var ndh = content_h;
draw_sprite_stretched(THEME.ui_panel_bg, 1, ndx, ndy, ndw, ndh);
sc_profile_list.setFocusHover(pFOCUS, pHOVER);
sc_profile_list.draw(ndx + ui(4), ndy + ui(4), mx - ndx - ui(4), my - ndy - ui(4));
var ndx = _pd + list_w + ui(8);
var ndw = detail_w;
draw_sprite_stretched(THEME.ui_panel_bg, 1, ndx, ndy, ndw, ndh);
sc_profile_detail.setFocusHover(pFOCUS, pHOVER);
sc_profile_detail.draw(ndx + ui(4), ndy + ui(4), mx - ndx - ui(4), my - ndy - ui(4));
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
if(set_selecting_node) {
var _graph = array_empty(PANEL_GRAPH.nodes_selecting)? noone : PANEL_GRAPH.nodes_selecting[0];
if(_graph != noone && graph_set_latest != _graph) {
for( var i = 0, n = array_length(PROFILER_DATA); i < n; i++ ) {
var _report = PROFILER_DATA[i];
if(_report.type == "render" && _report.node == _graph) {
report_selecting = _report;
break;
}
}
}
graph_set_latest = _graph;
}
}
}