1/**************************************************************************/
2/* editor_profiler.h */
3/**************************************************************************/
4/* This file is part of: */
5/* GODOT ENGINE */
6/* https://godotengine.org */
7/**************************************************************************/
8/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
9/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
10/* */
11/* Permission is hereby granted, free of charge, to any person obtaining */
12/* a copy of this software and associated documentation files (the */
13/* "Software"), to deal in the Software without restriction, including */
14/* without limitation the rights to use, copy, modify, merge, publish, */
15/* distribute, sublicense, and/or sell copies of the Software, and to */
16/* permit persons to whom the Software is furnished to do so, subject to */
17/* the following conditions: */
18/* */
19/* The above copyright notice and this permission notice shall be */
20/* included in all copies or substantial portions of the Software. */
21/* */
22/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
23/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
24/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
25/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
26/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
27/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
28/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
29/**************************************************************************/
30
31#ifndef EDITOR_PROFILER_H
32#define EDITOR_PROFILER_H
33
34#include "scene/gui/box_container.h"
35#include "scene/gui/button.h"
36#include "scene/gui/label.h"
37#include "scene/gui/option_button.h"
38#include "scene/gui/spin_box.h"
39#include "scene/gui/split_container.h"
40#include "scene/gui/texture_rect.h"
41#include "scene/gui/tree.h"
42
43class ImageTexture;
44
45class EditorProfiler : public VBoxContainer {
46 GDCLASS(EditorProfiler, VBoxContainer);
47
48public:
49 struct Metric {
50 bool valid = false;
51
52 int frame_number = 0;
53 float frame_time = 0;
54 float process_time = 0;
55 float physics_time = 0;
56 float physics_frame_time = 0;
57
58 struct Category {
59 StringName signature;
60 String name;
61 float total_time = 0; //total for category
62
63 struct Item {
64 StringName signature;
65 String name;
66 String script;
67 int line = 0;
68 float self = 0;
69 float total = 0;
70 int calls = 0;
71 };
72
73 Vector<Item> items;
74 };
75
76 Vector<Category> categories;
77
78 HashMap<StringName, Category *> category_ptrs;
79 HashMap<StringName, Category::Item *> item_ptrs;
80 };
81
82 enum DisplayMode {
83 DISPLAY_FRAME_TIME,
84 DISPLAY_AVERAGE_TIME,
85 DISPLAY_FRAME_PERCENT,
86 DISPLAY_PHYSICS_FRAME_PERCENT,
87 };
88
89 enum DisplayTime {
90 DISPLAY_TOTAL_TIME,
91 DISPLAY_SELF_TIME,
92 };
93
94private:
95 Button *activate = nullptr;
96 Button *clear_button = nullptr;
97 TextureRect *graph = nullptr;
98 Ref<ImageTexture> graph_texture;
99 Vector<uint8_t> graph_image;
100 Tree *variables = nullptr;
101 HSplitContainer *h_split = nullptr;
102
103 HashSet<StringName> plot_sigs;
104
105 OptionButton *display_mode = nullptr;
106 OptionButton *display_time = nullptr;
107
108 SpinBox *cursor_metric_edit = nullptr;
109
110 Vector<Metric> frame_metrics;
111 int total_metrics = 0;
112 int last_metric = -1;
113
114 int max_functions = 0;
115
116 bool updating_frame = false;
117
118 int hover_metric = -1;
119
120 float graph_height = 1.0f;
121
122 bool seeking = false;
123
124 Timer *frame_delay = nullptr;
125 Timer *plot_delay = nullptr;
126
127 void _update_button_text();
128 void _update_frame();
129
130 void _activate_pressed();
131 void _clear_pressed();
132
133 String _get_time_as_text(const Metric &m, float p_time, int p_calls);
134
135 void _make_metric_ptrs(Metric &m);
136 void _item_edited();
137
138 void _update_plot();
139
140 void _graph_tex_mouse_exit();
141
142 void _graph_tex_draw();
143 void _graph_tex_input(const Ref<InputEvent> &p_ev);
144
145 Color _get_color_from_signature(const StringName &p_signature) const;
146
147 void _cursor_metric_changed(double);
148
149 void _combo_changed(int);
150
151 Metric _get_frame_metric(int index);
152
153protected:
154 void _notification(int p_what);
155 static void _bind_methods();
156
157public:
158 void add_frame_metric(const Metric &p_metric, bool p_final = false);
159 void set_enabled(bool p_enable, bool p_clear = true);
160 void set_pressed(bool p_pressed);
161 bool is_profiling();
162 bool is_seeking() { return seeking; }
163 void disable_seeking();
164
165 void clear();
166
167 Vector<Vector<String>> get_data_as_csv() const;
168
169 EditorProfiler();
170};
171
172#endif // EDITOR_PROFILER_H
173